Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

smtphandler.cpp

Go to the documentation of this file.
00001 #warning "TODO: XXX This class needs to be rewritten. XXX"
00002 
00003 #include <qsocket.h>
00004 #include <qtimer.h>
00005 #include <qfile.h>
00006 #include <qdatetime.h>
00007 #include <qdir.h>
00008 #include <qregexp.h>
00009 
00010 #include <qpe/mimetype.h>
00011 #include <qpe/config.h>
00012 
00013 #include <stdlib.h>
00014 
00015 #include "smtphandler.h"
00016 #include "miscfunctions.h"
00017 
00018 SmtpHandler::SmtpHandler(const QString &header, const QString &message, Account &account, const QString &to) 
00019         : QObject(), _header(header), _message(message), _account(account), _to(to)
00020 {
00021         _header.replace(QRegExp("\\n"), "\r\n");
00022         _message.replace(QRegExp("\\n"), "\r\n");
00023         _message.replace(QRegExp("\\r\\n\\.\\r\\n"), "\r\n..\r\n");
00024 
00025 //      _state = account.esmtpAuth() ? Ehlo : Helo;
00026         _state = Helo;
00027 
00028         _socket = new QSocket(this);
00029         connect(_socket, SIGNAL(hostFound()), this, SLOT(hostFound()));
00030         connect(_socket, SIGNAL(connected()), this, SLOT(connected()));
00031         connect(_socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
00032         connect(_socket, SIGNAL(error(int)), this, SLOT(errorHandling(int)));
00033 
00034         _socket->connectToHost(account.smtpServer(), account.smtpPort().toUInt());
00035         emit status(tr("Looking up host..."));
00036 }
00037 
00038 void SmtpHandler::errorHandling(int err)
00039 {
00040         if (err == QSocket::ErrConnectionRefused) {
00041                 emit error(tr("The server refused the connection."));
00042         } else if (err == QSocket::ErrHostNotFound) {
00043                 emit error(tr("Host lookup failed."));
00044         } else if (err == QSocket::ErrSocketRead) {
00045                 emit error(tr("The read from the socket failed for an unknown reason."));
00046         } else {
00047                 emit error(tr("The sending failed for an unknown reason."));
00048         }
00049         stop();
00050 }
00051 
00052 void SmtpHandler::hostFound()
00053 {
00054         emit status(tr("Host found."));
00055 }
00056 
00057 void SmtpHandler::connected()
00058 {
00059         emit status(tr("Connected to %1").arg(_socket->peerName()));
00060 }
00061 
00062 void SmtpHandler::readyRead()
00063 {
00064         if (!_socket->canReadLine()) return;
00065         if (_state == Close) stop();
00066 
00067         QString response = _socket->readLine();
00068         QString temp = response;
00069         temp.truncate(3);
00070         int responseCode = temp.toInt();
00071 
00072 #ifndef QT_NO_DEBUG
00073         qDebug(tr("SMTP > %3").arg(response.stripWhiteSpace()));
00074 #endif
00075 
00076         response.replace(0, 4, "");
00077         response.stripWhiteSpace();
00078 
00079         if (_state == Ehlo && responseCode == 220) {
00080                 QString hostname = getenv("HOSTNAME");
00081                 if (hostname.stripWhiteSpace().isEmpty())
00082                         hostname = "opiemail";
00083 
00084                 emit status(tr("SMTP> EHLO *"));
00085                 sendToSocket(QString("EHLO %1\r\n").arg(hostname));
00086                 _state = Auth;
00087         } else if (_state == Auth && responseCode == 250) {
00088                 QStringList capabilities;
00089                 while (_socket->canReadLine()) {
00090                         QString line = _socket->readLine().stripWhiteSpace();
00091                         capabilities.append(line);
00092                 }
00093                 
00094                 // FIXME: Dirty, quick hack!
00095                 if (!capabilities.grep(QRegExp("^250-AUTH=LOGIN.*CRAM-MD5.*$")).isEmpty()) {
00096 //                      emit errorOccourred(ErrAuthNotSupported);
00097                         _state = Mail;
00098                 } else {
00099                         emit status(tr("SMTP> AUTH CRAM-MD5"));
00100                         sendToSocket("AUTH CRAM-MD5\r\n");
00101                         _state = ReadAuth;
00102                 }
00103         } else if (_state == ReadAuth && responseCode == 334) {
00104                 QString msgId = MiscFunctions::decodeBase64(response);
00105         
00106                 QString authString;
00107                 authString = _account.user() + " " + 
00108                         MiscFunctions::smtpAuthCramMd5(msgId, _account.pass());
00109                 authString = MiscFunctions::encodeBase64(authString);
00110 
00111                 emit status(tr("SMTP> Authenticating"));
00112                 sendToSocket(authString + "\r\n");
00113 
00114                 _state = Mail;
00115         } else if (_state == Helo && responseCode == 220) {
00116                 QString hostname = getenv("HOSTNAME");
00117                 if (hostname.stripWhiteSpace().isEmpty())
00118                         hostname = "opiemail";
00119 
00120                 emit status(tr("SMTP> HELO *"));
00121                 sendToSocket(QString("HELO %1\r\n").arg(hostname));
00122                 _state = Mail;
00123         } else if (_state == Mail && responseCode == 250) {
00124                 emit status(tr("SMTP> MAIL FROM: *"));
00125                 sendToSocket("MAIL FROM: <" + _account.email() + ">\r\n");
00126                 _state = Rcpt;
00127         } else if (_state == Rcpt && responseCode == 250) {
00128                 emit status(tr("SMTP> RCPT TO: *"));
00129                 sendToSocket("RCPT TO: <" + _to + ">\r\n");
00130                 _state = Data;
00131         } else if (_state == Data && responseCode == 250) {
00132                 emit status(tr("SMTP> DATA"));
00133                 sendToSocket("DATA\r\n");
00134                 _state = Body;
00135         } else if (_state == Body && responseCode == 354) {
00136                 emit status(tr("SMTP> Sending data..."));
00137                 sendToSocket(_header + "\r\n" + _message + "\r\n.\r\n", false);
00138                 _state = Quit;
00139         } else if (_state == Quit) {
00140                 emit status(tr("SMTP> QUIT (Done)"));
00141                 sendToSocket("QUIT\r\n");
00142                 _state = Close;
00143         } else if (_state == Close) {
00144 
00145         } else {
00146                 emit error(tr("The server returned an error. This is the message:<br>%1").arg(response));
00147                 stop();
00148         }
00149 }
00150 
00151 void SmtpHandler::sendToSocket(const QString &text, bool log)
00152 {
00153         _socket->writeBlock(text.latin1(), text.length());
00154 
00155         if (log) {
00156 #ifndef QT_NO_DEBUG
00157                 qDebug(tr("SMTP < %3").arg(text.stripWhiteSpace()));
00158 #endif
00159         }
00160 }
00161 
00162 void SmtpHandler::stop()
00163 {
00164         emit finished();
00165         QTimer::singleShot(0, this, SLOT(deleteMe()));
00166 }
00167 
00168 void SmtpHandler::deleteMe()
00169 {
00170         delete this;
00171 }
00172 

Generated on Sat Nov 5 16:18:08 2005 for OPIE by  doxygen 1.4.2