You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
4.3 KiB
182 lines
4.3 KiB
15 years ago
|
/****************************************************************************
|
||
|
**
|
||
|
** This file is a modified version of part of an example program for Qt.
|
||
|
** This file may be used, distributed and modified without limitation.
|
||
|
**
|
||
|
** Don Sanders <sanders@kde.org>
|
||
|
**
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "smtp.h"
|
||
|
|
||
|
#include <qtextstream.h>
|
||
|
#include <qsocket.h>
|
||
|
#include <qtimer.h>
|
||
|
#include <kapplication.h>
|
||
|
#include <kmessagebox.h>
|
||
|
#include <klocale.h>
|
||
|
|
||
|
Smtp::Smtp( const QString &from, const QStringList &to,
|
||
|
const QString &aMessage,
|
||
|
const QString &server,
|
||
|
unsigned short int port )
|
||
|
{
|
||
|
skipReadResponse = false;
|
||
|
mSocket = new QSocket( this );
|
||
|
connect ( mSocket, SIGNAL( readyRead() ),
|
||
|
this, SLOT( readyRead() ) );
|
||
|
connect ( mSocket, SIGNAL( connected() ),
|
||
|
this, SLOT( connected() ) );
|
||
|
connect ( mSocket, SIGNAL( error(int) ),
|
||
|
this, SLOT( socketError(int) ) );
|
||
|
|
||
|
message = aMessage;
|
||
|
|
||
|
this->from = from;
|
||
|
rcpt = to;
|
||
|
state = smtpInit;
|
||
|
command = "";
|
||
|
|
||
|
emit status( i18n( "Connecting to %1" ).arg( server ) );
|
||
|
|
||
|
mSocket->connectToHost( server, port );
|
||
|
t = new QTextStream( mSocket );
|
||
|
t->setEncoding(QTextStream::Latin1);
|
||
|
}
|
||
|
|
||
|
|
||
|
Smtp::~Smtp()
|
||
|
{
|
||
|
if (t)
|
||
|
delete t;
|
||
|
if (mSocket)
|
||
|
delete mSocket;
|
||
|
}
|
||
|
|
||
|
|
||
|
void Smtp::send( const QString &from, const QStringList &to,
|
||
|
const QString &aMessage )
|
||
|
{
|
||
|
skipReadResponse = true;
|
||
|
message = aMessage;
|
||
|
this->from = from;
|
||
|
rcpt = to;
|
||
|
|
||
|
state = smtpMail;
|
||
|
command = "";
|
||
|
readyRead();
|
||
|
}
|
||
|
|
||
|
|
||
|
void Smtp::quit()
|
||
|
{
|
||
|
skipReadResponse = true;
|
||
|
state = smtpQuit;
|
||
|
command = "";
|
||
|
readyRead();
|
||
|
}
|
||
|
|
||
|
|
||
|
void Smtp::connected()
|
||
|
{
|
||
|
emit status( i18n( "Connected to %1" ).arg( mSocket->peerName() ) );
|
||
|
}
|
||
|
|
||
|
void Smtp::socketError(int errorCode)
|
||
|
{
|
||
|
command = "CONNECT";
|
||
|
switch ( errorCode ) {
|
||
|
case QSocket::ErrConnectionRefused:
|
||
|
responseLine = i18n( "Connection refused." );
|
||
|
break;
|
||
|
case QSocket::ErrHostNotFound:
|
||
|
responseLine = i18n( "Host Not Found." );
|
||
|
break;
|
||
|
case QSocket::ErrSocketRead:
|
||
|
responseLine = i18n( "Error reading socket." );
|
||
|
break;
|
||
|
default:
|
||
|
responseLine = i18n( "Internal error, unrecognized error." );
|
||
|
}
|
||
|
QTimer::singleShot( 0, this, SLOT(emitError()) );
|
||
|
}
|
||
|
|
||
|
void Smtp::emitError() {
|
||
|
error( command, responseLine );
|
||
|
}
|
||
|
|
||
|
void Smtp::readyRead()
|
||
|
{
|
||
|
if (!skipReadResponse) {
|
||
|
// SMTP is line-oriented
|
||
|
if ( !mSocket->canReadLine() )
|
||
|
return;
|
||
|
|
||
|
do {
|
||
|
responseLine = mSocket->readLine();
|
||
|
response += responseLine;
|
||
|
} while( mSocket->canReadLine() && responseLine[3] != ' ' );
|
||
|
}
|
||
|
skipReadResponse = false;
|
||
|
|
||
|
if ( state == smtpInit && responseLine[0] == '2' ) {
|
||
|
// banner was okay, let's go on
|
||
|
command = "HELO there";
|
||
|
*t << "HELO there\r\n";
|
||
|
state = smtpMail;
|
||
|
} else if ( state == smtpMail && responseLine[0] == '2' ) {
|
||
|
// HELO response was okay (well, it has to be)
|
||
|
command = "MAIL";
|
||
|
*t << "MAIL FROM: <" << from << ">\r\n";
|
||
|
state = smtpRcpt;
|
||
|
} else if ( state == smtpRcpt && responseLine[0] == '2' && (rcpt.begin() != rcpt.end())) {
|
||
|
command = "RCPT";
|
||
|
*t << "RCPT TO: <" << *(rcpt.begin()) << ">\r\n";
|
||
|
rcpt.remove( rcpt.begin() );
|
||
|
if (rcpt.begin() == rcpt.end())
|
||
|
state = smtpData;
|
||
|
} else if ( state == smtpData && responseLine[0] == '2' ) {
|
||
|
command = "DATA";
|
||
|
*t << "DATA\r\n";
|
||
|
state = smtpBody;
|
||
|
} else if ( state == smtpBody && responseLine[0] == '3' ) {
|
||
|
command = "DATA";
|
||
|
QString seperator = "";
|
||
|
if (message[message.length() - 1] != '\n')
|
||
|
seperator = "\r\n";
|
||
|
*t << message << seperator << ".\r\n";
|
||
|
state = smtpSuccess;
|
||
|
} else if ( state == smtpSuccess && responseLine[0] == '2' ) {
|
||
|
QTimer::singleShot( 0, this, SIGNAL(success()) );
|
||
|
} else if ( state == smtpQuit && responseLine[0] == '2' ) {
|
||
|
command = "QUIT";
|
||
|
*t << "QUIT\r\n";
|
||
|
// here, we just close.
|
||
|
state = smtpClose;
|
||
|
emit status( i18n( "Message sent" ) );
|
||
|
} else if ( state == smtpClose ) {
|
||
|
// we ignore it
|
||
|
} else { // error occurred
|
||
|
QTimer::singleShot( 0, this, SLOT(emitError()) );
|
||
|
state = smtpClose;
|
||
|
}
|
||
|
|
||
|
response = "";
|
||
|
|
||
|
if ( state == smtpClose ) {
|
||
|
delete t;
|
||
|
t = 0;
|
||
|
delete mSocket;
|
||
|
mSocket = 0;
|
||
|
QTimer::singleShot( 0, this, SLOT(deleteMe()) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void Smtp::deleteMe()
|
||
|
{
|
||
|
delete this;
|
||
|
}
|
||
|
|
||
|
#include "smtp.moc"
|