2
* Kscd - A simple cd player for the KDE Project
4
* $Id: smtp.cpp,v 1.14 2001/06/10 12:45:37 dfoerste Exp $
6
* Copyright (c) 1997 Bernd Johannes wuebben@math.cornell.edu
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2, or (at your option)
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
#include <sys/utsname.h>
32
SMTP::SMTP(char *serverhost, unsigned short int port, int timeout)
36
serverHost = serverhost;
38
timeOut = timeout * 1000;
40
// The following defaults are supposed to be overwritten
41
senderAddress = "user@host.ext";
43
recipientAddress = "user@host.ext";
44
messageSubject = "freedb unknown unknown";
45
messageBody = "empty";
55
domainName = uts.nodename;
58
// this is for the HELO
59
if(domainName.isEmpty())
60
domainName = "somemachine.nowhere.org";
62
connect(&connectTimer, SIGNAL(timeout()), this, SLOT(connectTimerTick()));
63
connect(&timeOutTimer, SIGNAL(timeout()), this, SLOT(connectTimedOut()));
64
connect(&interactTimer, SIGNAL(timeout()), this, SLOT(interactTimedOut()));
66
// some sendmail will give 'duplicate helo' error, quick fix for now
67
connect(this, SIGNAL(messageSent()), SLOT(closeConnection()));
80
void SMTP::setServerHost(const QString& serverhost)
82
serverHost = serverhost;
85
void SMTP::setPort(unsigned short int port)
90
void SMTP::setTimeOut(int timeout)
95
void SMTP::setSenderAddress(const QString& sender)
97
senderAddress = sender;
100
void SMTP::setSenderReplyTo(const QString& replyto)
102
senderReplyTo = replyto;
105
void SMTP::setRecipientAddress(const QString& recipient)
107
recipientAddress = recipient;
110
void SMTP::setMessageSubject(const QString& subject)
112
messageSubject = subject;
115
void SMTP::setMessageBody(const QString& message)
117
messageBody = message;
120
void SMTP::openConnection(void)
122
kdDebug() << "started connect timer\n" << endl;
123
connectTimer.start(100, TRUE);
126
void SMTP::closeConnection(void)
131
void SMTP::sendMessage(void)
135
if(state == FINISHED && connected){
136
kdDebug() << "state was == FINISHED\n" << endl;
139
writeString = QString::fromLatin1("helo %1\r\n").arg(domainName);
140
write(sock->socket(), writeString.ascii(), writeString.length());
143
kdDebug() << "enabling read on sock...\n" << endl;
144
interactTimer.start(timeOut, TRUE);
145
sock->enableRead(true);
150
void SMTP::connectTimerTick(void)
153
// timeOutTimer.start(timeOut, TRUE);
155
kdDebug() << "connectTimerTick called...\n" << endl;
162
kdDebug() << "connecting to " << serverHost << ":" << hostPort << " ..... \n" << endl;
163
sock = new KSocket(serverHost.ascii(), hostPort);
165
if(sock == 0L || sock->socket() < 0){
167
kdDebug() << "connection failed!\n" << endl;
168
emit error(CONNECTERROR);
177
connect(sock, SIGNAL(readEvent(KSocket *)), this, SLOT(socketRead(KSocket *)));
178
connect(sock, SIGNAL(closeEvent(KSocket *)), this, SLOT(socketClose(KSocket *)));
179
// sock->enableRead(true);
181
kdDebug() << "connected\n" << endl;
184
void SMTP::connectTimedOut(void)
189
sock->enableRead(false);
190
kdDebug() << "socket connection timed out\n" << endl;
192
emit error(CONNECTTIMEOUT);
195
void SMTP::interactTimedOut(void)
197
interactTimer.stop();
200
sock->enableRead(false);
201
kdDebug() << "time out waiting for server interaction" << endl;
203
emit error(INTERACTTIMEOUT);
206
void SMTP::socketRead(KSocket *socket)
210
kdDebug() << "socketRead() called...\n" << endl;
211
interactTimer.stop();
213
if(socket == 0L || socket->socket() < 0)
215
n = read(socket->socket(), readBuffer, SMTP_READ_BUFFER_SIZE-1 );
216
readBuffer[n] = '\0';
217
lineBuffer += readBuffer;
218
nl = lineBuffer.find('\n');
221
lastLine = lineBuffer.left(nl);
222
lineBuffer = lineBuffer.right(lineBuffer.length() - nl - 1);
223
processLine(&lastLine);
225
interactTimer.start(timeOut, TRUE);
228
void SMTP::socketClose(KSocket *socket)
231
disconnect(sock, SIGNAL(readEvent(KSocket *)), this, SLOT(socketRead(KSocket *)));
232
disconnect(sock, SIGNAL(closeEvent(KSocket *)), this, SLOT(socketClose(KSocket *)));
233
socket->enableRead(false);
234
kdDebug() << "connection terminated\n" << endl;
241
emit connectionClosed();
244
void SMTP::processLine(QString *line)
250
tmpstr = line->left(i);
252
kdDebug() << "warning: SMTP status code longer then 3 digits: " << tmpstr << "\n" << endl;
253
stat = tmpstr.toInt();
254
serverState = (SMTPServerStatus)stat;
257
kdDebug() << "smtp state: [" << stat << "][" << *line << "]\n" << endl;
262
writeString = QString::fromLatin1("helo %1\r\n").arg(domainName);
263
write(sock->socket(), writeString.ascii(), writeString.length());
268
case SUCCESSFUL://250
272
writeString = QString::fromLatin1("mail from: %1\r\n").arg(senderAddress);
273
write(sock->socket(), writeString.ascii(), writeString.length());
277
writeString = QString::fromLatin1("rcpt to: %1\r\n").arg(recipientAddress);
278
write(sock->socket(), writeString.ascii(), writeString.length());
282
writeString = QString::fromLatin1("data\r\n");
283
write(sock->socket(), writeString.ascii(), writeString.length());
288
sock->enableRead(false);
293
kdDebug() << "smtp error (state error): [" << lastState << "]:[" << stat << "][" << *line << "]\n" << endl;
299
case READYDATA: //354
301
// writeString = QString::fromLatin1("Subject: %1\n%2\n.\n").arg(messageSubject).arg(messageBody);
302
writeString = QString::fromLatin1("Subject: %1\r\n").arg(messageSubject);
303
writeString += QString::fromLatin1("From: %1\r\n").arg(senderAddress);
304
kdDebug() << senderReplyTo << endl;
305
if( (senderReplyTo != NULL) && senderReplyTo.contains("@") )
307
writeString += QString::fromLatin1("Reply-To: %1\r\n").arg(senderReplyTo);
309
writeString += QString::fromLatin1("To: %1\r\n\r\n").arg(recipientAddress);
310
writeString += messageBody;
311
writeString += QString::fromLatin1(".\r\n");
312
write(sock->socket(), writeString.ascii(), writeString.length());
316
kdDebug() << "smtp error (command error): [" << lastState << "]:[" << stat << "][" << *line << "]\n" << endl;
322
kdDebug() << "smtp error (unknown user): [" << lastState << "]:[" << stat << "][" << *line << "]\n" << endl;
324
emit error(UNKNOWNUSER);
328
kdDebug() << "unknown response: [" << lastState << "]:[" << stat << "][" << *line << "]\n" << endl;
330
emit error(UNKNOWNRESPONSE);