-rw-r--r-- | noncore/net/mail/libmailwrapper/smtpwrapper.cpp | 24 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/smtpwrapper.h | 1 |
2 files changed, 24 insertions, 1 deletions
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp index 085d5e4..7671133 100644 --- a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp +++ b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp @@ -1,104 +1,105 @@ #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <qdir.h> #include <qt.h> +#include <qmessagebox.h> #include <qpe/config.h> #include <qpe/qcopenvelope_qws.h> #include <libetpan/libetpan.h> #include "smtpwrapper.h" #include "mailwrapper.h" #include "abstractmail.h" #include "logindialog.h" #include "mailtypes.h" //#include "defines.h" #include "sendmailprogress.h" const char* SMTPwrapper::USER_AGENT="OpieMail v0.3"; progressMailSend*SMTPwrapper::sendProgress = 0; SMTPwrapper::SMTPwrapper( Settings *s ) : QObject() { settings = s; Config cfg( "mail" ); cfg.setGroup( "Status" ); m_queuedMail = cfg.readNumEntry( "outgoing", 0 ); emit queuedMails( m_queuedMail ); connect( this, SIGNAL( queuedMails( int ) ), this, SLOT( emitQCop( int ) ) ); } void SMTPwrapper::emitQCop( int queued ) { QCopEnvelope env( "QPE/Pim", "outgoingMails(int)" ); env << queued; } QString SMTPwrapper::mailsmtpError( int errnum ) { switch ( errnum ) { case MAILSMTP_NO_ERROR: return tr( "No error" ); case MAILSMTP_ERROR_UNEXPECTED_CODE: return tr( "Unexpected error code" ); case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE: return tr( "Service not available" ); case MAILSMTP_ERROR_STREAM: return tr( "Stream error" ); case MAILSMTP_ERROR_HOSTNAME: return tr( "gethostname() failed" ); case MAILSMTP_ERROR_NOT_IMPLEMENTED: return tr( "Not implemented" ); case MAILSMTP_ERROR_ACTION_NOT_TAKEN: return tr( "Error, action not taken" ); case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION: return tr( "Data exceeds storage allocation" ); case MAILSMTP_ERROR_IN_PROCESSING: return tr( "Error in processing" ); // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE: // return tr( "Insufficient system storage" ); case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE: return tr( "Mailbox unavailable" ); case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED: return tr( "Mailbox name not allowed" ); case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND: return tr( "Bad command sequence" ); case MAILSMTP_ERROR_USER_NOT_LOCAL: return tr( "User not local" ); case MAILSMTP_ERROR_TRANSACTION_FAILED: return tr( "Transaction failed" ); case MAILSMTP_ERROR_MEMORY: return tr( "Memory error" ); case MAILSMTP_ERROR_CONNECTION_REFUSED: return tr( "Connection refused" ); default: return tr( "Unknown error code" ); } } mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail ) { return mailimf_mailbox_new( strdup( name.latin1() ), strdup( mail.latin1() ) ); } mailimf_address_list *SMTPwrapper::parseAddresses(const QString&addr ) { mailimf_address_list *addresses; if ( addr.isEmpty() ) return NULL; addresses = mailimf_address_list_new_empty(); bool literal_open = false; unsigned int startpos = 0; QStringList list; QString s; unsigned int i = 0; for (; i < addr.length();++i) { switch (addr[i]) { case '\"': literal_open = !literal_open; @@ -461,268 +462,289 @@ clist *SMTPwrapper::createRcptList( mailimf_fields *fields ) { } field = getField( fields, MAILIMF_FIELD_BCC ); if ( field && (field->fld_type == MAILIMF_FIELD_BCC) && field->fld_data.fld_bcc->bcc_addr_list ) { addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list ); } return rcptList; } char *SMTPwrapper::getFrom( mailimf_field *ffrom) { char *from = NULL; if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM) && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) { clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list; clistiter *it; for ( it = clist_begin( cl ); it; it = it->next ) { mailimf_mailbox *mb = (mailimf_mailbox *) it->data; from = strdup( mb->mb_addr_spec ); } } return from; } char *SMTPwrapper::getFrom( mailmime *mail ) { /* no need to delete - its just a pointer to structure content */ mailimf_field *ffrom = 0; ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM ); return getFrom(ffrom); } void SMTPwrapper::progress( size_t current, size_t maximum ) { if (SMTPwrapper::sendProgress) { SMTPwrapper::sendProgress->setSingleMail(current, maximum ); qApp->processEvents(); } } void SMTPwrapper::storeMail(const char*mail, size_t length, const QString&box) { if (!mail) return; QString localfolders = AbstractMail::defaultLocalfolder(); AbstractMail*wrap = AbstractMail::getWrapper(localfolders); wrap->createMbox(box); wrap->storeMessage(mail,length,box); delete wrap; } void SMTPwrapper::smtpSend( mailmime *mail,bool later, SMTPaccount *smtp ) { clist *rcpts = 0; char *from, *data; size_t size; if ( smtp == NULL ) { return; } from = data = 0; mailmessage * msg = 0; msg = mime_message_init(mail); mime_message_set_tmpdir(msg,getenv( "HOME" )); int r = mailmessage_fetch(msg,&data,&size); mime_message_detach_mime(msg); mailmessage_free(msg); if (r != MAIL_NO_ERROR || !data) { if (data) free(data); qDebug("Error fetching mime..."); return; } msg = 0; if (later) { storeMail(data,size,"Outgoing"); if (data) free( data ); Config cfg( "mail" ); cfg.setGroup( "Status" ); cfg.writeEntry( "outgoing", ++m_queuedMail ); emit queuedMails( m_queuedMail ); return; } from = getFrom( mail ); rcpts = createRcptList( mail->mm_data.mm_message.mm_fields ); smtpSend(from,rcpts,data,size,smtp); if (data) { free(data); } if (from) { free(from); } if (rcpts) smtp_address_list_free( rcpts ); } +void SMTPwrapper::storeFailedMail(const char*data,unsigned int size, const char*failuremessage) +{ + if (data) { + storeMail(data,size,"Sendfailed"); + } + if (failuremessage) { + QMessageBox::critical(0,tr("Error sending mail"), + tr("<center>%1</center>").arg(failuremessage)); + } +} + int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMTPaccount *smtp ) { const char *server, *user, *pass; bool ssl; uint16_t port; mailsmtp *session; int err,result; result = 1; server = user = pass = 0; server = smtp->getServer().latin1(); // FIXME: currently only TLS and Plain work. ssl = false; if ( smtp->ConnectionType() == 2 ) { ssl = true; } port = smtp->getPort().toUInt(); session = mailsmtp_new( 20, &progress ); if ( session == NULL ) goto free_mem; qDebug( "Servername %s at port %i", server, port ); if ( ssl ) { qDebug( "SSL session" ); err = mailsmtp_ssl_connect( session, server, port ); } else { qDebug( "No SSL session" ); err = mailsmtp_socket_connect( session, server, port ); } if ( err != MAILSMTP_NO_ERROR ) { qDebug("Error init connection"); + storeFailedMail(data,size,mailsmtpError(err)); result = 0; goto free_mem_session; } err = mailsmtp_init( session ); if ( err != MAILSMTP_NO_ERROR ) { + storeFailedMail(data,size,mailsmtpError(err)); result = 0; goto free_con_session; } qDebug( "INIT OK" ); if ( smtp->getLogin() ) { qDebug("smtp with auth"); if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) { // get'em LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true ); login.show(); if ( QDialog::Accepted == login.exec() ) { // ok user = login.getUser().latin1(); pass = login.getPassword().latin1(); } else { result = 0; goto free_con_session; } } else { user = smtp->getUser().latin1(); pass = smtp->getPassword().latin1(); } qDebug( "session->auth: %i", session->auth); err = mailsmtp_auth( session, (char*)user, (char*)pass ); - if ( err == MAILSMTP_NO_ERROR ) + if ( err == MAILSMTP_NO_ERROR ) { qDebug("auth ok"); + } else { + storeFailedMail(data,size,tr("Authentification failed")); + result = 0; + goto free_con_session; + } qDebug( "Done auth!" ); } else { qDebug("SMTP without auth"); + result = 0; + goto free_con_session; } err = mailsmtp_send( session, from, rcpts, data, size ); if ( err != MAILSMTP_NO_ERROR ) { + storeFailedMail(data,size,mailsmtpError(err)); qDebug("Error sending mail: %s",mailsmtpError(err).latin1()); result = 0; goto free_con_session; } qDebug( "Mail sent." ); storeMail(data,size,"Sent"); free_con_session: mailsmtp_quit( session ); free_mem_session: mailsmtp_free( session ); free_mem: return result; } void SMTPwrapper::sendMail(const Mail&mail,SMTPaccount*aSmtp,bool later ) { mailmime * mimeMail; SMTPaccount *smtp = aSmtp; if (!later && !smtp) { qDebug("Didn't get any send method - giving up"); return; } mimeMail = createMimeMail(mail ); if ( mimeMail == NULL ) { qDebug( "sendMail: error creating mime mail" ); } else { sendProgress = new progressMailSend(); sendProgress->show(); sendProgress->setMaxMails(1); smtpSend( mimeMail,later,smtp); qDebug("Clean up done"); sendProgress->hide(); delete sendProgress; sendProgress = 0; mailmime_free( mimeMail ); } } int SMTPwrapper::sendQueuedMail(AbstractMail*wrap,SMTPaccount*smtp,RecMail*which) { size_t curTok = 0; mailimf_fields *fields = 0; mailimf_field*ffrom = 0; clist *rcpts = 0; char*from = 0; int res = 0; encodedString * data = wrap->fetchRawBody(*which); if (!data) return 0; int err = mailimf_fields_parse( data->Content(), data->Length(), &curTok, &fields ); if (err != MAILIMF_NO_ERROR) { delete data; delete wrap; return 0; } rcpts = createRcptList( fields ); ffrom = getField(fields, MAILIMF_FIELD_FROM ); from = getFrom(ffrom); if (rcpts && from) { res = smtpSend(from,rcpts,data->Content(),data->Length(),smtp ); } if (fields) { mailimf_fields_free(fields); fields = 0; } if (data) { delete data; } if (from) { free(from); } if (rcpts) { smtp_address_list_free( rcpts ); } return res; } /* this is a special fun */ bool SMTPwrapper::flushOutbox(SMTPaccount*smtp) { bool returnValue = true; if (!smtp) return false; QString localfolders = AbstractMail::defaultLocalfolder(); AbstractMail*wrap = AbstractMail::getWrapper(localfolders); if (!wrap) { qDebug("memory error"); return false; } QList<RecMail> mailsToSend; diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.h b/noncore/net/mail/libmailwrapper/smtpwrapper.h index 7dcdbfd..89826d9 100644 --- a/noncore/net/mail/libmailwrapper/smtpwrapper.h +++ b/noncore/net/mail/libmailwrapper/smtpwrapper.h @@ -1,72 +1,73 @@ #ifndef SMTPwrapper_H #define SMTPwrapper_H #include <qpe/applnk.h> #include <qbitarray.h> #include <qdatetime.h> #include <libetpan/clist.h> #include "settings.h" class Mail; class AbstractMail; class RecMail; class Attachment; struct mailimf_fields; struct mailimf_field; struct mailimf_mailbox; struct mailmime; struct mailimf_address_list; class progressMailSend; class SMTPwrapper : public QObject { Q_OBJECT public: SMTPwrapper( Settings *s ); virtual ~SMTPwrapper(){} void sendMail(const Mail& mail,SMTPaccount*smtp,bool later=false ); bool flushOutbox(SMTPaccount*smtp); static progressMailSend*sendProgress; signals: void queuedMails( int ); protected: mailimf_mailbox *newMailbox(const QString&name,const QString&mail ); mailimf_fields *createImfFields(const Mail &mail ); mailmime *createMimeMail(const Mail&mail ); mailimf_address_list *parseAddresses(const QString&addr ); void addFileParts( mailmime *message,const QList<Attachment>&files ); mailmime *buildTxtPart(const QString&str ); mailmime *buildFilePart(const QString&filename,const QString&mimetype,const QString&content); void smtpSend( mailmime *mail,bool later, SMTPaccount *smtp ); clist *createRcptList( mailimf_fields *fields ); static void storeMail(const char*mail, size_t length, const QString&box); static QString mailsmtpError( int err ); static void progress( size_t current, size_t maximum ); static void addRcpts( clist *list, mailimf_address_list *addr_list ); static char *getFrom( mailmime *mail ); static char *getFrom( mailimf_field *ffrom); static mailimf_field *getField( mailimf_fields *fields, int type ); int smtpSend(char*from,clist*rcpts,const char*data,size_t size, SMTPaccount *smtp ); void storeMail(mailmime*mail, const QString&box); Settings *settings; int sendQueuedMail(AbstractMail*wrap,SMTPaccount*smtp,RecMail*which); + void storeFailedMail(const char*data,unsigned int size, const char*failuremessage); int m_queuedMail; static const char* USER_AGENT; protected slots: void emitQCop( int queued ); }; #endif |