• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KIO

  • sources
  • kde-4.12
  • kdelibs
  • kio
  • misc
  • ksendbugmail
smtp.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2000 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
3  Copyright (c) 2000 Stephan Kulow <coolo@kde.org>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2, or (at your option)
8  any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include "smtp.h"
21 
22 #include <sys/utsname.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 
26 #include <kdebug.h>
27 
28 SMTP::SMTP(char *serverhost, unsigned short int port, int timeout)
29 {
30  struct utsname uts;
31 
32  serverHost = serverhost;
33  hostPort = port;
34  timeOut = timeout * 1000;
35 
36  senderAddress = "user@example.net";
37  recipientAddress = "user@example.net";
38  messageSubject = "(no subject)";
39  messageBody = "empty";
40  messageHeader = "";
41 
42  connected = false;
43  finished = false;
44 
45  sock = 0L;
46  state = Init;
47  serverState = None;
48 
49  uname(&uts);
50  domainName = uts.nodename;
51 
52 
53  if(domainName.isEmpty())
54  domainName = "somemachine.example.net";
55 
56  kDebug() << "SMTP object created";
57 
58  connect(&connectTimer, SIGNAL(timeout()), this, SLOT(connectTimerTick()));
59  connect(&timeOutTimer, SIGNAL(timeout()), this, SLOT(connectTimedOut()));
60  connect(&interactTimer, SIGNAL(timeout()), this, SLOT(interactTimedOut()));
61 
62  // some sendmail will give 'duplicate helo' error, quick fix for now
63  connect(this, SIGNAL(messageSent()), SLOT(closeConnection()));
64 }
65 
66 SMTP::~SMTP()
67 {
68  delete sock;
69  sock = 0L;
70  connectTimer.stop();
71  timeOutTimer.stop();
72 }
73 
74 void SMTP::setServerHost(const QString& serverhost)
75 {
76  serverHost = serverhost;
77 }
78 
79 void SMTP::setPort(unsigned short int port)
80 {
81  hostPort = port;
82 }
83 
84 void SMTP::setTimeOut(int timeout)
85 {
86  timeOut = timeout;
87 }
88 
89 void SMTP::setSenderAddress(const QString& sender)
90 {
91  senderAddress = sender;
92  int index = senderAddress.indexOf('<');
93  if (index == -1)
94  return;
95  senderAddress = senderAddress.mid(index + 1);
96  index = senderAddress.indexOf('>');
97  if (index != -1)
98  senderAddress = senderAddress.left(index);
99  senderAddress = senderAddress.simplified();
100  while (1) {
101  index = senderAddress.indexOf(' ');
102  if (index != -1)
103  senderAddress = senderAddress.mid(index + 1); // take one side
104  else
105  break;
106  }
107  index = senderAddress.indexOf('@');
108  if (index == -1)
109  senderAddress.append("@localhost"); // won't go through without a local mail system
110 
111 }
112 
113 void SMTP::setRecipientAddress(const QString& recipient)
114 {
115  recipientAddress = recipient;
116 }
117 
118 void SMTP::setMessageSubject(const QString& subject)
119 {
120  messageSubject = subject;
121 }
122 
123 void SMTP::setMessageBody(const QString& message)
124 {
125  messageBody = message;
126 }
127 
128 void SMTP::setMessageHeader(const QString &header)
129 {
130  messageHeader = header;
131 }
132 
133 void SMTP::openConnection(void)
134 {
135  kDebug() << "started connect timer";
136  connectTimer.setSingleShot(true);
137  connectTimer.start(100);
138 }
139 
140 void SMTP::closeConnection(void)
141 {
142  socketClosed();
143 }
144 
145 void SMTP::sendMessage(void)
146 {
147  if(!connected)
148  connectTimerTick();
149  if(state == Finished && connected){
150  kDebug() << "state was == Finished\n";
151  finished = false;
152  state = In;
153  writeString = QString::fromLatin1("helo %1\r\n").arg(domainName);
154  sock->write(writeString.toLatin1().constData(), writeString.length());
155  }
156  if(connected){
157  kDebug() << "enabling read on sock...\n";
158  interactTimer.setSingleShot(true);
159  interactTimer.start(timeOut);
160  }
161 }
162 
163 void SMTP::connectTimerTick(void)
164 {
165  connectTimer.stop();
166 // timeOutTimer.start(timeOut, true);
167 
168  kDebug() << "connectTimerTick called...";
169 
170  delete sock;
171  sock = 0L;
172 
173  kDebug() << "connecting to " << serverHost << ":" << hostPort << " ..... ";
174  sock = KSocketFactory::connectToHost("smtp", serverHost, hostPort, this);
175 
176  connected = true;
177  finished = false;
178  state = Init;
179  serverState = None;
180 
181  connect(sock, SIGNAL(readyRead()), this, SLOT(socketReadyToRead()));
182  connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), this,
183  SLOT(socketError(QAbstractSocket::SocketError)));
184  connect(sock, SIGNAL(disconnected()), this, SLOT(socketClosed()));
185  timeOutTimer.stop();
186  kDebug() << "connected";
187 }
188 
189 void SMTP::connectTimedOut(void)
190 {
191  timeOutTimer.stop();
192 
193  kDebug() << "socket connection timed out";
194  socketClosed();
195  emit error(ConnectTimeout);
196 }
197 
198 void SMTP::interactTimedOut(void)
199 {
200  interactTimer.stop();
201 
202  kDebug() << "time out waiting for server interaction";
203  socketClosed();
204  emit error(InteractTimeout);
205 }
206 
207 void SMTP::socketReadyToRead()
208 {
209  int n, nl;
210 
211  kDebug() << "socketRead() called...";
212  interactTimer.stop();
213 
214  if (!sock)
215  return;
216 
217  n = sock->read(readBuffer, SMTP_READ_BUFFER_SIZE-1);
218  if (n < 0)
219  return;
220  readBuffer[n] = 0;
221  lineBuffer += readBuffer;
222  nl = lineBuffer.indexOf('\n');
223  if(nl == -1)
224  return;
225  lastLine = lineBuffer.left(nl);
226  lineBuffer = lineBuffer.right(lineBuffer.length() - nl - 1);
227  processLine(&lastLine);
228  if(connected) {
229  interactTimer.setSingleShot(true);
230  interactTimer.start(timeOut);
231  }
232 }
233 
234 void SMTP::socketError(QAbstractSocket::SocketError socketError)
235 {
236  kDebug() << socketError << sock->errorString();
237  Q_UNUSED(socketError);
238  emit error(ConnectError);
239  socketClosed();
240 }
241 
242 void SMTP::socketClosed()
243 {
244  timeOutTimer.stop();
245  kDebug() << "connection terminated";
246  connected = false;
247  if (sock)
248  sock->deleteLater();
249  sock = 0;
250  emit connectionClosed();
251 }
252 
253 void SMTP::processLine(QString *line)
254 {
255  int i, stat;
256  QString tmpstr;
257 
258  i = line->indexOf(' ');
259  tmpstr = line->left(i);
260  if(i > 3)
261  kDebug() << "warning: SMTP status code longer than 3 digits: " << tmpstr;
262  stat = tmpstr.toInt();
263  serverState = (SMTPServerStatus)stat;
264  lastState = state;
265 
266  kDebug() << "smtp state: [" << stat << "][" << *line << "]";
267 
268  switch(stat){
269  case Greet: //220
270  state = In;
271  writeString = QString::fromLatin1("helo %1\r\n").arg(domainName);
272  kDebug() << "out: " << writeString;
273  sock->write(writeString.toLatin1().constData(), writeString.length());
274  break;
275  case Goodbye: //221
276  state = Quit;
277  break;
278  case Successful://250
279  switch(state){
280  case In:
281  state = Ready;
282  writeString = QString::fromLatin1("mail from: %1\r\n").arg(senderAddress);
283  kDebug() << "out: " << writeString;
284  sock->write(writeString.toLatin1().constData(), writeString.length());
285  break;
286  case Ready:
287  state = SentFrom;
288  writeString = QString::fromLatin1("rcpt to: %1\r\n").arg(recipientAddress);
289  kDebug() << "out: " << writeString;
290  sock->write(writeString.toLatin1().constData(), writeString.length());
291  break;
292  case SentFrom:
293  state = SentTo;
294  writeString = QLatin1String("data\r\n");
295  kDebug() << "out: " << writeString;
296  sock->write(writeString.toLatin1().constData(), writeString.length());
297  break;
298  case Data:
299  state = Finished;
300  finished = true;
301  emit messageSent();
302  break;
303  default:
304  state = CError;
305  kDebug() << "smtp error (state error): [" << lastState << "]:[" << stat << "][" << *line << "]";
306  socketClosed();
307  emit error(Command);
308  break;
309  }
310  break;
311  case ReadyData: //354
312  state = Data;
313  writeString = QString::fromLatin1("Subject: %1\r\n").arg(messageSubject);
314  writeString += messageHeader;
315  writeString += "\r\n";
316  writeString += messageBody;
317  writeString += QLatin1String(".\r\n");
318  kDebug() << "out: " << writeString;
319  sock->write(writeString.toLatin1().constData(), writeString.length());
320  break;
321  case Error: //501
322  state = CError;
323  kDebug() << "smtp error (command error): [" << lastState << "]:[" << stat << "][" << *line << "]\n";
324  socketClosed();
325  emit error(Command);
326  break;
327  case Unknown: //550
328  state = CError;
329  kDebug() << "smtp error (unknown user): [" << lastState << "]:[" << stat << "][" << *line << "]";
330  socketClosed();
331  emit error(UnknownUser);
332  break;
333  default:
334  state = CError;
335  kDebug() << "unknown response: [" << lastState << "]:[" << stat << "][" << *line << "]";
336  socketClosed();
337  emit error(UnknownResponse);
338  }
339 }
340 
341 #include "smtp.moc"
SMTP::Unknown
Definition: smtp.h:86
SMTP::setSenderAddress
void setSenderAddress(const QString &sender)
Definition: smtp.cpp:89
kdebug.h
SMTP::UnknownResponse
Definition: smtp.h:108
SMTP::UnknownUser
Definition: smtp.h:109
SMTP::Data
Definition: smtp.h:95
SMTP::Successful
Definition: smtp.h:83
SMTP::setMessageSubject
void setMessageSubject(const QString &subject)
Definition: smtp.cpp:118
SMTP::Ready
Definition: smtp.h:92
SMTP::~SMTP
~SMTP()
Definition: smtp.cpp:66
stat
int stat(const QString &path, KDE_struct_stat *buf)
SMTP::processLine
void processLine(QString *line)
Definition: smtp.cpp:253
SMTP::In
Definition: smtp.h:91
SMTP::ConnectError
Definition: smtp.h:104
SMTP::socketClosed
void socketClosed()
Definition: smtp.cpp:242
SMTP::SMTP
SMTP(char *serverhost=0, unsigned short int port=0, int timeout=DEFAULT_SMTP_TIMEOUT)
Definition: smtp.cpp:28
SMTP::Command
Definition: smtp.h:110
SMTP::Quit
Definition: smtp.h:97
QString
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
SMTP::setMessageHeader
void setMessageHeader(const QString &header)
Definition: smtp.cpp:128
SMTP::setTimeOut
void setTimeOut(int timeout)
Definition: smtp.cpp:84
SMTP::SentTo
Definition: smtp.h:94
SMTP::setMessageBody
void setMessageBody(const QString &message)
Definition: smtp.cpp:123
KSocketFactory::connectToHost
QTcpSocket * connectToHost(const QString &protocol, const QString &host, quint16 port, QObject *parent=0)
SMTP::connectTimerTick
void connectTimerTick()
Definition: smtp.cpp:163
SMTP::openConnection
void openConnection()
Definition: smtp.cpp:133
SMTP::error
void error(int)
SMTP::closeConnection
void closeConnection()
Definition: smtp.cpp:140
SMTP::Init
Definition: smtp.h:90
SMTP::socketError
void socketError(QAbstractSocket::SocketError)
Definition: smtp.cpp:234
SMTP::ReadyData
Definition: smtp.h:84
SMTP::interactTimedOut
void interactTimedOut()
Definition: smtp.cpp:198
SMTP::CError
Definition: smtp.h:99
SMTP::messageSent
void messageSent()
SMTP::SentFrom
Definition: smtp.h:93
SMTP::setServerHost
void setServerHost(const QString &serverhost)
Definition: smtp.cpp:74
SMTP::setRecipientAddress
void setRecipientAddress(const QString &recipient)
Definition: smtp.cpp:113
SMTP::Finished
Definition: smtp.h:96
smtp.h
SMTP::ConnectTimeout
Definition: smtp.h:106
SMTP::Greet
Definition: smtp.h:81
SMTP::connectionClosed
void connectionClosed()
SMTP::Goodbye
Definition: smtp.h:82
SMTP::SMTPServerStatus
SMTPServerStatus
Definition: smtp.h:79
SMTP::connectTimedOut
void connectTimedOut()
Definition: smtp.cpp:189
SMTP::Error
Definition: smtp.h:85
SMTP::None
Definition: smtp.h:80
SMTP::InteractTimeout
Definition: smtp.h:107
SMTP::setPort
void setPort(unsigned short int port)
Definition: smtp.cpp:79
SMTP_READ_BUFFER_SIZE
#define SMTP_READ_BUFFER_SIZE
Definition: smtp.h:55
SMTP::socketReadyToRead
void socketReadyToRead()
Definition: smtp.cpp:207
SMTP::sendMessage
void sendMessage()
Definition: smtp.cpp:145
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:50:03 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal