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

KIO

  • 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
28SMTP::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
66SMTP::~SMTP()
67{
68 delete sock;
69 sock = 0L;
70 connectTimer.stop();
71 timeOutTimer.stop();
72}
73
74void SMTP::setServerHost(const QString& serverhost)
75{
76 serverHost = serverhost;
77}
78
79void SMTP::setPort(unsigned short int port)
80{
81 hostPort = port;
82}
83
84void SMTP::setTimeOut(int timeout)
85{
86 timeOut = timeout;
87}
88
89void 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
113void SMTP::setRecipientAddress(const QString& recipient)
114{
115 recipientAddress = recipient;
116}
117
118void SMTP::setMessageSubject(const QString& subject)
119{
120 messageSubject = subject;
121}
122
123void SMTP::setMessageBody(const QString& message)
124{
125 messageBody = message;
126}
127
128void SMTP::setMessageHeader(const QString &header)
129{
130 messageHeader = header;
131}
132
133void SMTP::openConnection(void)
134{
135 kDebug() << "started connect timer";
136 connectTimer.setSingleShot(true);
137 connectTimer.start(100);
138}
139
140void SMTP::closeConnection(void)
141{
142 socketClosed();
143}
144
145void 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
163void 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
189void SMTP::connectTimedOut(void)
190{
191 timeOutTimer.stop();
192
193 kDebug() << "socket connection timed out";
194 socketClosed();
195 emit error(ConnectTimeout);
196}
197
198void SMTP::interactTimedOut(void)
199{
200 interactTimer.stop();
201
202 kDebug() << "time out waiting for server interaction";
203 socketClosed();
204 emit error(InteractTimeout);
205}
206
207void 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
234void SMTP::socketError(QAbstractSocket::SocketError socketError)
235{
236 kDebug() << socketError << sock->errorString();
237 Q_UNUSED(socketError);
238 emit error(ConnectError);
239 socketClosed();
240}
241
242void 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
253void 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::socketError
void socketError(QAbstractSocket::SocketError)
Definition: smtp.cpp:234
SMTP::setMessageSubject
void setMessageSubject(const QString &subject)
Definition: smtp.cpp:118
SMTP::connectionClosed
void connectionClosed()
SMTP::setMessageBody
void setMessageBody(const QString &message)
Definition: smtp.cpp:123
SMTP::setSenderAddress
void setSenderAddress(const QString &sender)
Definition: smtp.cpp:89
SMTP::socketClosed
void socketClosed()
Definition: smtp.cpp:242
SMTP::socketReadyToRead
void socketReadyToRead()
Definition: smtp.cpp:207
SMTP::setTimeOut
void setTimeOut(int timeout)
Definition: smtp.cpp:84
SMTP::sendMessage
void sendMessage()
Definition: smtp.cpp:145
SMTP::error
void error(int)
SMTP::interactTimedOut
void interactTimedOut()
Definition: smtp.cpp:198
SMTP::setServerHost
void setServerHost(const QString &serverhost)
Definition: smtp.cpp:74
SMTP::SMTPServerStatus
SMTPServerStatus
Definition: smtp.h:79
SMTP::Successful
@ Successful
Definition: smtp.h:83
SMTP::None
@ None
Definition: smtp.h:80
SMTP::ReadyData
@ ReadyData
Definition: smtp.h:84
SMTP::Greet
@ Greet
Definition: smtp.h:81
SMTP::Unknown
@ Unknown
Definition: smtp.h:86
SMTP::Error
@ Error
Definition: smtp.h:85
SMTP::Goodbye
@ Goodbye
Definition: smtp.h:82
SMTP::~SMTP
~SMTP()
Definition: smtp.cpp:66
SMTP::connectTimedOut
void connectTimedOut()
Definition: smtp.cpp:189
SMTP::setRecipientAddress
void setRecipientAddress(const QString &recipient)
Definition: smtp.cpp:113
SMTP::connectTimerTick
void connectTimerTick()
Definition: smtp.cpp:163
SMTP::openConnection
void openConnection()
Definition: smtp.cpp:133
SMTP::processLine
void processLine(QString *line)
Definition: smtp.cpp:253
SMTP::InteractTimeout
@ InteractTimeout
Definition: smtp.h:107
SMTP::Command
@ Command
Definition: smtp.h:110
SMTP::UnknownResponse
@ UnknownResponse
Definition: smtp.h:108
SMTP::ConnectError
@ ConnectError
Definition: smtp.h:104
SMTP::ConnectTimeout
@ ConnectTimeout
Definition: smtp.h:106
SMTP::UnknownUser
@ UnknownUser
Definition: smtp.h:109
SMTP::messageSent
void messageSent()
SMTP::setMessageHeader
void setMessageHeader(const QString &header)
Definition: smtp.cpp:128
SMTP::SMTP
SMTP(char *serverhost=0, unsigned short int port=0, int timeout=DEFAULT_SMTP_TIMEOUT)
Definition: smtp.cpp:28
SMTP::setPort
void setPort(unsigned short int port)
Definition: smtp.cpp:79
SMTP::SentFrom
@ SentFrom
Definition: smtp.h:93
SMTP::Init
@ Init
Definition: smtp.h:90
SMTP::SentTo
@ SentTo
Definition: smtp.h:94
SMTP::Data
@ Data
Definition: smtp.h:95
SMTP::Quit
@ Quit
Definition: smtp.h:97
SMTP::Finished
@ Finished
Definition: smtp.h:96
SMTP::Ready
@ Ready
Definition: smtp.h:92
SMTP::CError
@ CError
Definition: smtp.h:99
SMTP::In
@ In
Definition: smtp.h:91
SMTP::closeConnection
void closeConnection()
Definition: smtp.cpp:140
header
const char header[]
kDebug
#define kDebug
kdebug.h
timeout
int timeout
stat
int stat(const QString &path, KDE_struct_stat *buf)
message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
KSocketFactory::connectToHost
QTcpSocket * connectToHost(const QString &protocol, const QString &host, quint16 port, QObject *parent=0)
smtp.h
SMTP_READ_BUFFER_SIZE
#define SMTP_READ_BUFFER_SIZE
Definition: smtp.h:55
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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