author | alwin <alwin> | 2003-12-22 02:37:35 (UTC) |
---|---|---|
committer | alwin <alwin> | 2003-12-22 02:37:35 (UTC) |
commit | 9e7aafdb7c76d29fee742d53131a73dd60aded2b (patch) (side-by-side diff) | |
tree | e98f9fe1233455f458738acbfd29bac78dd03342 | |
parent | 7c016e1a75970cb7c28d70398ad20c708cdb452b (diff) | |
download | opie-9e7aafdb7c76d29fee742d53131a73dd60aded2b.zip opie-9e7aafdb7c76d29fee742d53131a73dd60aded2b.tar.gz opie-9e7aafdb7c76d29fee742d53131a73dd60aded2b.tar.bz2 |
- storing mails send in outgoing (if queued) or sent (if sent) folder
TODO: flush queue, cleanup SMTP code, select smtp-account if more than
one when flush the outgoing queue
-rw-r--r-- | noncore/net/mail/composemail.cpp | 3 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/mboxwrapper.cpp | 26 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/mboxwrapper.h | 2 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/smtpwrapper.cpp | 59 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/smtpwrapper.h | 6 | ||||
-rw-r--r-- | noncore/net/mail/mboxwrapper.cpp | 26 | ||||
-rw-r--r-- | noncore/net/mail/mboxwrapper.h | 2 | ||||
-rw-r--r-- | noncore/net/mail/smtpwrapper.cpp | 59 | ||||
-rw-r--r-- | noncore/net/mail/smtpwrapper.h | 6 |
9 files changed, 160 insertions, 29 deletions
diff --git a/noncore/net/mail/composemail.cpp b/noncore/net/mail/composemail.cpp index f680f5c..f532815 100644 --- a/noncore/net/mail/composemail.cpp +++ b/noncore/net/mail/composemail.cpp @@ -1,214 +1,215 @@ #include <qt.h> #include <opie/ofiledialog.h> #include <qpe/resource.h> #include <qpe/config.h> #include "composemail.h" #include "smtpwrapper.h" ComposeMail::ComposeMail( Settings *s, QWidget *parent, const char *name, bool modal, WFlags flags ) : ComposeMailUI( parent, name, modal, flags ) { settings = s; Config cfg( "mail" ); cfg.setGroup( "Compose" ); checkBoxLater->setChecked( cfg.readBoolEntry( "sendLater", false ) ); attList->addColumn( tr( "Name" ) ); attList->addColumn( tr( "Size" ) ); QList<Account> accounts = settings->getAccounts(); Account *it; for ( it = accounts.first(); it; it = accounts.next() ) { if ( it->getType().compare( "SMTP" ) == 0 ) { SMTPaccount *smtp = static_cast<SMTPaccount *>(it); fromBox->insertItem( smtp->getMail() ); smtpAccounts.append( smtp ); } } if ( smtpAccounts.count() > 0 ) { fillValues( fromBox->currentItem() ); } else { QMessageBox::information( this, tr( "Problem" ), tr( "<p>Please create an SMTP account first.</p>" ), tr( "Ok" ) ); return; } connect( fromBox, SIGNAL( activated( int ) ), SLOT( fillValues( int ) ) ); connect( toButton, SIGNAL( clicked() ), SLOT( pickAddressTo() ) ); connect( ccButton, SIGNAL( clicked() ), SLOT( pickAddressCC() ) ); connect( bccButton, SIGNAL( clicked() ), SLOT( pickAddressBCC() ) ); connect( replyButton, SIGNAL( clicked() ), SLOT( pickAddressReply() ) ); connect( addButton, SIGNAL( clicked() ), SLOT( addAttachment() ) ); connect( deleteButton, SIGNAL( clicked() ), SLOT( removeAttachment() ) ); } void ComposeMail::pickAddress( QLineEdit *line ) { QString names = AddressPicker::getNames(); if ( line->text().isEmpty() ) { line->setText( names ); } else if ( !names.isEmpty() ) { line->setText( line->text() + ", " + names ); } } void ComposeMail::setTo( const QString & to ) { /* QString toline; QStringList toEntry = to; for ( QStringList::Iterator it = toEntry.begin(); it != toEntry.end(); ++it ) { toline += (*it); } toLine->setText( toline ); */ toLine->setText( to ); } void ComposeMail::setSubject( const QString & subject ) { subjectLine->setText( subject ); } void ComposeMail::setInReplyTo( const QString & messageId ) { } void ComposeMail::setMessage( const QString & text ) { message->setText( text ); } void ComposeMail::pickAddressTo() { pickAddress( toLine ); } void ComposeMail::pickAddressCC() { pickAddress( ccLine ); } void ComposeMail::pickAddressBCC() { pickAddress( bccLine ); } void ComposeMail::pickAddressReply() { pickAddress( replyLine ); } void ComposeMail::fillValues( int current ) { SMTPaccount *smtp = smtpAccounts.at( current ); ccLine->clear(); if ( smtp->getUseCC() ) { ccLine->setText( smtp->getCC() ); } bccLine->clear(); if ( smtp->getUseBCC() ) { bccLine->setText( smtp->getBCC() ); } replyLine->clear(); if ( smtp->getUseReply() ) { replyLine->setText( smtp->getReply() ); } sigMultiLine->setText( smtp->getSignature() ); } void ComposeMail::slotAdjustColumns() { int currPage = tabWidget->currentPageIndex(); tabWidget->showPage( attachTab ); attList->setColumnWidth( 0, attList->visibleWidth() - 80 ); attList->setColumnWidth( 1, 80 ); tabWidget->setCurrentPage( currPage ); } void ComposeMail::addAttachment() { DocLnk lnk = OFileDialog::getOpenFileName( 1, "/" ); if ( !lnk.name().isEmpty() ) { Attachment *att = new Attachment( lnk ); (void) new AttachViewItem( attList, att ); } } void ComposeMail::removeAttachment() { if ( !attList->currentItem() ) { QMessageBox::information( this, tr( "Error" ), tr( "<p>Please select a File.</p>" ), tr( "Ok" ) ); } else { attList->takeItem( attList->currentItem() ); } } void ComposeMail::accept() { if ( checkBoxLater->isChecked() ) { qDebug( "Send later" ); } qDebug( "Sending Mail with " + smtpAccounts.at( fromBox->currentItem() )->getAccountName() ); Mail *mail = new Mail(); SMTPaccount *smtp = smtpAccounts.at( fromBox->currentItem() ); + mail->setMail( smtp->getMail() ); mail->setName( smtp->getName() ); if ( !toLine->text().isEmpty() ) { mail->setTo( toLine->text() ); } else { qDebug( "No Reciever spezified -> returning" ); return; } mail->setCC( ccLine->text() ); mail->setBCC( bccLine->text() ); mail->setReply( replyLine->text() ); mail->setSubject( subjectLine->text() ); QString txt = message->text(); if ( !sigMultiLine->text().isEmpty() ) { txt.append( "\n--\n" ); txt.append( sigMultiLine->text() ); } mail->setMessage( txt ); AttachViewItem *it = (AttachViewItem *) attList->firstChild(); while ( it != NULL ) { mail->addAttachment( it->getAttachment() ); it = (AttachViewItem *) it->itemBelow(); } SMTPwrapper wrapper( settings ); - wrapper.sendMail( *mail ); + wrapper.sendMail( *mail,checkBoxLater->isChecked() ); QDialog::accept(); } AttachViewItem::AttachViewItem( QListView *parent, Attachment *att ) : QListViewItem( parent ) { attachment = att; qDebug( att->getMimeType() ); setPixmap( 0, attachment->getDocLnk().pixmap().isNull() ? Resource::loadPixmap( "UnknownDocument-14" ) : attachment->getDocLnk().pixmap() ); setText( 0, att->getName().isEmpty() ? att->getFileName() : att->getName() ); setText( 1, QString::number( att->getSize() ) ); } diff --git a/noncore/net/mail/libmailwrapper/mboxwrapper.cpp b/noncore/net/mail/libmailwrapper/mboxwrapper.cpp index 7581715..8117cef 100644 --- a/noncore/net/mail/libmailwrapper/mboxwrapper.cpp +++ b/noncore/net/mail/libmailwrapper/mboxwrapper.cpp @@ -1,199 +1,219 @@ #include "mboxwrapper.h" #include "mailtypes.h" #include "mailwrapper.h" -#include "libetpan/libetpan.h" -#include "libetpan/mailstorage.h" +#include <libetpan/libetpan.h> +#include <libetpan/mailstorage.h> #include <qdir.h> MBOXwrapper::MBOXwrapper(const QString & mbox_dir) : Genericwrapper(),MBOXPath(mbox_dir) { QDir dir(MBOXPath); if (!dir.exists()) { dir.mkdir(MBOXPath); } } MBOXwrapper::~MBOXwrapper() { } void MBOXwrapper::listMessages(const QString & mailbox, QList<RecMail> &target ) { mailstorage*storage = mailstorage_new(NULL); QString p = MBOXPath+"/"; p+=mailbox; int r = mbox_mailstorage_init(storage,strdup(p.latin1()),0,0,0); mailfolder*folder; folder = mailfolder_new( storage,strdup(p.latin1()),NULL); r = mailfolder_connect(folder); if (r != MAIL_NO_ERROR) { qDebug("Error initializing mbox"); mailfolder_free(folder); mailstorage_free(storage); return; } mailmessage_list * env_list = 0; r = mailsession_get_messages_list(folder->fld_session,&env_list); if (r != MAIL_NO_ERROR) { qDebug("Error message list"); mailfolder_free(folder); mailstorage_free(storage); return; } r = mailsession_get_envelopes_list(folder->fld_session, env_list); if (r != MAIL_NO_ERROR) { qDebug("Error filling message list"); if (env_list) { mailmessage_list_free(env_list); } mailfolder_free(folder); mailstorage_free(storage); return; } mailimf_references * refs; for(int i = 0 ; i < carray_count(env_list->msg_tab) ; ++i) { mailmessage * msg; QBitArray mFlags(7); msg = (mailmessage*)carray_get(env_list->msg_tab, i); if (msg->msg_fields == NULL) { qDebug("could not fetch envelope of message %i", i); continue; } RecMail * mail = new RecMail(); mail->setWrapper(this); mail_flags * flag_result = 0; r = mailmessage_get_flags(msg,&flag_result); if (r == MAIL_ERROR_NOT_IMPLEMENTED) { - qDebug("flag fetching not implemented"); mFlags.setBit(FLAG_SEEN); } mailimf_single_fields single_fields; mailimf_single_fields_init(&single_fields, msg->msg_fields); mail->setMsgsize(msg->msg_size); mail->setFlags(mFlags); mail->setMbox(mailbox); mail->setNumber(i+1); if (single_fields.fld_subject) mail->setSubject( convert_String(single_fields.fld_subject->sbj_value)); if (single_fields.fld_from) mail->setFrom(parseMailboxList(single_fields.fld_from->frm_mb_list)); if (single_fields.fld_to) mail->setTo( parseAddressList( single_fields.fld_to->to_addr_list ) ); if (single_fields.fld_cc) mail->setCC( parseAddressList( single_fields.fld_cc->cc_addr_list ) ); if (single_fields.fld_bcc) mail->setBcc( parseAddressList( single_fields.fld_bcc->bcc_addr_list ) ); if (single_fields.fld_orig_date) mail->setDate( parseDateTime( single_fields.fld_orig_date->dt_date_time ) ); if (single_fields.fld_message_id->mid_value) mail->setMsgid(QString(single_fields.fld_message_id->mid_value)); refs = single_fields.fld_references; if (refs && refs->mid_list && clist_count(refs->mid_list)) { char * text = (char*)refs->mid_list->first->data; mail->setReplyto(QString(text)); } target.append(mail); } if (env_list) { mailmessage_list_free(env_list); } mailfolder_disconnect(folder); mailfolder_free(folder); mailstorage_free(storage); } QList<Folder>* MBOXwrapper::listFolders() { QList<Folder> * folders = new QList<Folder>(); folders->setAutoDelete( false ); QDir dir(MBOXPath); if (!dir.exists()) return folders; dir.setFilter(QDir::Files|QDir::Writable|QDir::Readable); QStringList entries = dir.entryList(); QStringList::ConstIterator it = entries.begin(); for (;it!=entries.end();++it) { Folder*inb=new Folder(*it,"/"); folders->append(inb); } return folders; } void MBOXwrapper::deleteMail(const RecMail&mail) { mailstorage*storage = mailstorage_new(NULL); QString p = MBOXPath+"/"; p+=mail.getMbox(); mailmessage * msg; int r = mbox_mailstorage_init(storage,strdup(p.latin1()),0,0,0); mailfolder*folder; folder = mailfolder_new( storage,strdup(p.latin1()),NULL); r = mailfolder_connect(folder); if (r != MAIL_NO_ERROR) { qDebug("Error initializing mbox"); mailfolder_free(folder); mailstorage_free(storage); return; } r = mailsession_remove_message(folder->fld_session,mail.getNumber()); if (r != MAIL_NO_ERROR) { qDebug("error deleting mail"); } mailfolder_free(folder); mailstorage_free(storage); } void MBOXwrapper::answeredMail(const RecMail&) { } RecBody MBOXwrapper::fetchBody( const RecMail &mail ) { RecBody body; mailstorage*storage = mailstorage_new(NULL); QString p = MBOXPath+"/"; p+=mail.getMbox(); mailmessage * msg; char*data=0; size_t size; int r = mbox_mailstorage_init(storage,strdup(p.latin1()),0,0,0); mailfolder*folder; folder = mailfolder_new( storage,strdup(p.latin1()),NULL); r = mailfolder_connect(folder); if (r != MAIL_NO_ERROR) { qDebug("Error initializing mbox"); mailfolder_free(folder); mailstorage_free(storage); return body; } r = mailsession_get_message(folder->fld_session, mail.getNumber(), &msg); if (r != MAIL_NO_ERROR) { qDebug("Error fetching mail %i",mail.getNumber()); mailfolder_free(folder); mailstorage_free(storage); return body; } r = mailmessage_fetch(msg,&data,&size); if (r != MAIL_NO_ERROR) { qDebug("Error fetching mail %i",mail.getNumber()); mailfolder_free(folder); mailstorage_free(storage); mailmessage_free(msg); return body; } body = parseMail(msg); mailmessage_fetch_result_free(msg,data); mailfolder_free(folder); mailstorage_free(storage); return body; } void MBOXwrapper::mbox_progress( size_t current, size_t maximum ) { qDebug("MBOX %i von %i",current,maximum); } + +void MBOXwrapper::createFolder(const QString&) +{ +} + +void MBOXwrapper::storeMessage(const char*msg,size_t length, const QString&folder) +{ + QString p = MBOXPath+"/"; + p+=folder; + mailmbox_folder*f = 0; + int r = mailmbox_init(p.latin1(),0,1,0,&f); + if (r != MAIL_NO_ERROR) { + qDebug("Error init folder"); + return; + } + r = mailmbox_append_message(f,msg,length); + if (r != MAIL_NO_ERROR) { + qDebug("Error writing message folder"); + } + mailmbox_done(f); +} diff --git a/noncore/net/mail/libmailwrapper/mboxwrapper.h b/noncore/net/mail/libmailwrapper/mboxwrapper.h index 779dbc8..1bbaf79 100644 --- a/noncore/net/mail/libmailwrapper/mboxwrapper.h +++ b/noncore/net/mail/libmailwrapper/mboxwrapper.h @@ -1,30 +1,32 @@ #ifndef __MBOX_WRAPPER_H #define __MBOX_WRAPPER_H #include "genericwrapper.h" #include <qstring.h> class RecMail; class RecBody; class MBOXwrapper : public Genericwrapper { Q_OBJECT public: MBOXwrapper(const QString & dir); virtual ~MBOXwrapper(); virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); virtual QList<Folder>* listFolders(); virtual void deleteMail(const RecMail&mail); virtual void answeredMail(const RecMail&mail); + virtual void createFolder(const QString&aFolder); + virtual void storeMessage(const char*msg,size_t length, const QString&folder); virtual RecBody fetchBody( const RecMail &mail ); static void mbox_progress( size_t current, size_t maximum ); protected: QString MBOXPath; }; #endif diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp index 162b1b9..a6a46ba 100644 --- a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp +++ b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp @@ -1,604 +1,645 @@ #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <qdir.h> -#include <libetpan/mailmime.h> +#include <libetpan/libetpan.h> +#if 0 #include <libetpan/mailimf.h> #include <libetpan/mailsmtp.h> #include <libetpan/mailstorage.h> #include <libetpan/maildriver.h> +#endif #include "smtpwrapper.h" #include "mailwrapper.h" +#include "mboxwrapper.h" #include "logindialog.h" #include "defines.h" SMTPwrapper::SMTPwrapper( Settings *s ) : QObject() { settings = s; } 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(); QStringList list = QStringList::split( ',', addr ); QStringList::Iterator it; for ( it = list.begin(); it != list.end(); it++ ) { char *str = strdup( (*it).latin1() ); int err = mailimf_address_list_add_parse( addresses, str ); if ( err != MAILIMF_NO_ERROR ) { qDebug( "Error parsing" ); qDebug( *it ); free( str ); } else { qDebug( "Parse success! :)" ); } } return addresses; } mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail ) { mailimf_fields *fields; mailimf_field *xmailer; mailimf_mailbox *sender, *fromBox; mailimf_mailbox_list *from; mailimf_address_list *to, *cc, *bcc, *reply; char *subject = strdup( mail.getSubject().latin1() ); int err; sender = newMailbox( mail.getName(), mail.getMail() ); if ( sender == NULL ) goto err_free; fromBox = newMailbox( mail.getName(), mail.getMail() ); if ( fromBox == NULL ) goto err_free_sender; from = mailimf_mailbox_list_new_empty(); if ( from == NULL ) goto err_free_fromBox; err = mailimf_mailbox_list_add( from, fromBox ); if ( err != MAILIMF_NO_ERROR ) goto err_free_from; to = parseAddresses( mail.getTo() ); if ( to == NULL ) goto err_free_from; cc = parseAddresses( mail.getCC() ); bcc = parseAddresses( mail.getBCC() ); reply = parseAddresses( mail.getReply() ); fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc, NULL, NULL, subject ); if ( fields == NULL ) goto err_free_reply; xmailer = mailimf_field_new_custom( strdup( "User-Agent" ), strdup( USER_AGENT ) ); if ( xmailer == NULL ) goto err_free_fields; err = mailimf_fields_add( fields, xmailer ); if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer; return fields; // Success :) err_free_xmailer: mailimf_field_free( xmailer ); err_free_fields: mailimf_fields_free( fields ); err_free_reply: mailimf_address_list_free( reply ); mailimf_address_list_free( bcc ); mailimf_address_list_free( cc ); mailimf_address_list_free( to ); err_free_from: mailimf_mailbox_list_free( from ); err_free_fromBox: mailimf_mailbox_free( fromBox ); err_free_sender: mailimf_mailbox_free( sender ); err_free: free( subject ); qDebug( "createImfFields - error" ); return NULL; // Error :( } mailmime *SMTPwrapper::buildTxtPart(const QString&str ) { mailmime *txtPart; mailmime_fields *fields; mailmime_content *content; mailmime_parameter *param; char *txt = strdup( str.latin1() ); int err; param = mailmime_parameter_new( strdup( "charset" ), strdup( "iso-8859-1" ) ); if ( param == NULL ) goto err_free; content = mailmime_content_new_with_str( "text/plain" ); if ( content == NULL ) goto err_free_param; err = clist_append( content->ct_parameters, param ); if ( err != MAILIMF_NO_ERROR ) goto err_free_content; fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT ); if ( fields == NULL ) goto err_free_content; txtPart = mailmime_new_empty( content, fields ); if ( txtPart == NULL ) goto err_free_fields; err = mailmime_set_body_text( txtPart, txt, strlen( txt ) ); if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart; return txtPart; // Success :) err_free_txtPart: mailmime_free( txtPart ); err_free_fields: mailmime_fields_free( fields ); err_free_content: mailmime_content_free( content ); err_free_param: mailmime_parameter_free( param ); err_free: free( txt ); qDebug( "buildTxtPart - error" ); return NULL; // Error :( } mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype ) { mailmime * filePart; mailmime_fields * fields; mailmime_content * content; mailmime_parameter * param = NULL; int err; int pos = filename.findRev( '/' ); QString tmp = filename.right( filename.length() - ( pos + 1 ) ); char *name = strdup( tmp.latin1() ); // just filename char *file = strdup( filename.latin1() ); // full name with path char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain fields = mailmime_fields_new_filename( MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name, MAILMIME_MECHANISM_BASE64 ); if ( fields == NULL ) goto err_free; content = mailmime_content_new_with_str( mime ); if ( content == NULL ) goto err_free_fields; if ( mimetype.compare( "text/plain" ) == 0 ) { param = mailmime_parameter_new( strdup( "charset" ), strdup( "iso-8859-1" ) ); if ( param == NULL ) goto err_free_content; err = clist_append( content->ct_parameters, param ); if ( err != MAILIMF_NO_ERROR ) goto err_free_param; } filePart = mailmime_new_empty( content, fields ); if ( filePart == NULL ) goto err_free_param; err = mailmime_set_body_file( filePart, file ); if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart; return filePart; // Success :) err_free_filePart: mailmime_free( filePart ); err_free_param: if ( param != NULL ) mailmime_parameter_free( param ); err_free_content: mailmime_content_free( content ); err_free_fields: mailmime_fields_free( fields ); err_free: free( name ); free( mime ); free( file ); qDebug( "buildFilePart - error" ); return NULL; // Error :( } void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files ) { const Attachment *it; /* work around for the brainfucked qlist which can not act with const values */ for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) { qDebug( "Adding file" ); mailmime *filePart; int err; filePart = buildFilePart( it->getFileName(), it->getMimeType() ); if ( filePart == NULL ) goto err_free; err = mailmime_smart_add_part( message, filePart ); if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart; continue; // Success :) err_free_filePart: mailmime_free( filePart ); err_free: qDebug( "addFileParts: error adding file:" ); qDebug( it->getFileName() ); } } mailmime *SMTPwrapper::createMimeMail(const Mail &mail ) { mailmime *message, *txtPart; mailimf_fields *fields; int err; fields = createImfFields( mail ); if ( fields == NULL ) goto err_free; message = mailmime_new_message_data( NULL ); if ( message == NULL ) goto err_free_fields; mailmime_set_imf_fields( message, fields ); txtPart = buildTxtPart( mail.getMessage() ); if ( txtPart == NULL ) goto err_free_message; err = mailmime_smart_add_part( message, txtPart ); if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart; addFileParts( message, mail.getAttachments() ); return message; // Success :) err_free_txtPart: mailmime_free( txtPart ); err_free_message: mailmime_free( message ); err_free_fields: mailimf_fields_free( fields ); err_free: qDebug( "createMimeMail: error" ); return NULL; // Error :( } mailimf_field *SMTPwrapper::getField( mailimf_fields *fields, int type ) { mailimf_field *field; clistiter *it; it = clist_begin( fields->fld_list ); while ( it ) { field = (mailimf_field *) it->data; if ( field->fld_type == type ) { return field; } it = it->next; } return NULL; } void SMTPwrapper::addRcpts( clist *list, mailimf_address_list *addr_list ) { clistiter *it, *it2; for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) { mailimf_address *addr; addr = (mailimf_address *) it->data; if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) { esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL ); } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) { clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list; for ( it2 = clist_begin( l ); it2; it2 = it2->next ) { mailimf_mailbox *mbox; mbox = (mailimf_mailbox *) it2->data; esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL ); } } } } clist *SMTPwrapper::createRcptList( mailimf_fields *fields ) { clist *rcptList; mailimf_field *field; rcptList = esmtp_address_list_new(); field = getField( fields, MAILIMF_FIELD_TO ); if ( field && (field->fld_type == MAILIMF_FIELD_TO) && field->fld_data.fld_to->to_addr_list ) { addRcpts( rcptList, field->fld_data.fld_to->to_addr_list ); } field = getField( fields, MAILIMF_FIELD_CC ); if ( field && (field->fld_type == MAILIMF_FIELD_CC) && field->fld_data.fld_cc->cc_addr_list ) { addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list ); } 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( mailmime *mail ) { char *from = NULL; mailimf_field *ffrom; ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM ); 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; } SMTPaccount *SMTPwrapper::getAccount(const QString&from ) { SMTPaccount *smtp; QList<Account> list = settings->getAccounts(); Account *it; for ( it = list.first(); it; it = list.next() ) { if ( it->getType().compare( "SMTP" ) == 0 ) { smtp = static_cast<SMTPaccount *>(it); if ( smtp->getMail().compare( from ) == 0 ) { qDebug( "SMTPaccount found for" ); qDebug( from ); return smtp; } } } return NULL; } QString SMTPwrapper::getTmpFile() { int num = 0; QString unique; QDir dir( "/tmp" ); QStringList::Iterator it; QStringList list = dir.entryList( "opiemail-tmp-*" ); do { unique.setNum( num++ ); } while ( list.contains( "opiemail-tmp-" + unique ) > 0 ); return "/tmp/opiemail-tmp-" + unique; } void SMTPwrapper::writeToFile(const QString&file, mailmime *mail ) { FILE *f; int err, col = 0; f = fopen( file.latin1(), "w" ); if ( f == NULL ) { qDebug( "writeToFile: error opening file" ); return; } err = mailmime_write( f, &col, mail ); if ( err != MAILIMF_NO_ERROR ) { fclose( f ); qDebug( "writeToFile: error writing mailmime" ); return; } fclose( f ); } void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size ) { + + QFile msg_cache(file); + QString msg = ""; + msg_cache.open(IO_ReadOnly); + char*message = new char[4096]; + memset(message,0,4096); + while (msg_cache.readBlock(message,4095)>0) { + msg+=message; + memset(message,0,4096); + } + delete message; + *data = (char*)malloc(msg.length()+1*sizeof(char)); + memset(*data,0,msg.length()+1); + memcpy(*data,msg.ascii(),msg.length()); + *size=msg.length(); + +#if 0 char *buf; struct stat st; int fd, count = 0, total = 0; fd = open( file.latin1(), O_RDONLY, 0 ); if ( fd == -1 ) return; if ( fstat( fd, &st ) != 0 ) goto err_close; if ( !st.st_size ) goto err_close; buf = (char *) malloc( st.st_size ); if ( !buf ) goto err_close; while ( ( total < st.st_size ) && ( count >= 0 ) ) { count = read( fd, buf + total, st.st_size - total ); total += count; } if ( count < 0 ) goto err_free; *data = buf; *size = st.st_size; close( fd ); return; // Success :) err_free: free( buf ); err_close: close( fd ); +#endif } void SMTPwrapper::progress( size_t current, size_t maximum ) { qDebug( "Current: %i of %i", current, maximum ); } -void SMTPwrapper::smtpSend( mailmime *mail ) +void SMTPwrapper::storeMail(char*mail, size_t length, const QString&box) +{ + if (!mail) return; + QString localfolders = (QString) getenv( "HOME" ) + QString("/Applications/opiemail/localmail/"); + MBOXwrapper*wrap = new MBOXwrapper(localfolders); + wrap->storeMessage(mail,length,box); + delete wrap; +} + +void SMTPwrapper::smtpSend( mailmime *mail,bool later ) { mailsmtp *session; clist *rcpts; char *from, *data, *server, *user = NULL, *pass = NULL; size_t size; int err; bool ssl; uint16_t port; from = getFrom( mail ); SMTPaccount *smtp = getAccount( from ); if ( smtp == NULL ) { free(from); return; } - server = strdup( smtp->getServer().latin1() ); - ssl = smtp->getSSL(); - port = smtp->getPort().toUInt(); rcpts = createRcptList( mail->mm_data.mm_message.mm_fields ); QString file = getTmpFile(); writeToFile( file, mail ); + readFromFile( file, &data, &size ); QFile f( file ); f.remove(); + storeMail(data,size,(later?"Outgoing":"Sent")); + + if (later) { + smtp_address_list_free( rcpts ); + if (data) free( data ); + if (from) free(from); + return; + } + server = strdup( smtp->getServer().latin1() ); + ssl = smtp->getSSL(); + 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 ) goto free_mem_session; err = mailsmtp_init( session ); if ( err != MAILSMTP_NO_ERROR ) goto free_con_session; qDebug( "INIT OK" ); if ( smtp->getLogin() ) { 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 = strdup( login.getUser().latin1() ); pass = strdup( login.getPassword().latin1() ); } else { goto free_con_session; } } else { user = strdup( smtp->getUser().latin1() ); pass = strdup( smtp->getPassword().latin1() ); } qDebug( "session->auth: %i", session->auth); err = mailsmtp_auth( session, user, pass ); if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok"); qDebug( "Done auth!" ); } err = mailsmtp_send( session, from, rcpts, data, size ); if ( err != MAILSMTP_NO_ERROR ) goto free_con_session; qDebug( "Mail sent." ); free_con_session: mailsmtp_quit( session ); free_mem_session: mailsmtp_free( session ); free_mem: smtp_address_list_free( rcpts ); - free( data ); - free( server ); + if (data) free( data ); + if (from) free(from); + if (server) free( server ); if ( smtp->getLogin() ) { free( user ); free( pass ); } free( from ); } -void SMTPwrapper::sendMail(const Mail&mail ) +void SMTPwrapper::sendMail(const Mail&mail,bool later ) { mailmime *mimeMail; mimeMail = createMimeMail(mail ); if ( mimeMail == NULL ) { qDebug( "sendMail: error creating mime mail" ); } else { - smtpSend( mimeMail ); + smtpSend( mimeMail,later ); mailmime_free( mimeMail ); } } diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.h b/noncore/net/mail/libmailwrapper/smtpwrapper.h index 8fdb07d..41e9a8c 100644 --- a/noncore/net/mail/libmailwrapper/smtpwrapper.h +++ b/noncore/net/mail/libmailwrapper/smtpwrapper.h @@ -1,53 +1,55 @@ #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 Attachment; struct mailimf_fields; struct mailimf_field; struct mailimf_mailbox; struct mailmime; struct mailimf_address_list; class SMTPwrapper : public QObject { Q_OBJECT public: SMTPwrapper( Settings *s ); virtual ~SMTPwrapper(){} - void sendMail(const Mail& mail ); + void sendMail(const Mail& mail,bool later=false ); 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 ); - void smtpSend( mailmime *mail ); + void smtpSend( mailmime *mail,bool later ); mailimf_field *getField( mailimf_fields *fields, int type ); clist *createRcptList( mailimf_fields *fields ); char *getFrom( mailmime *mail ); SMTPaccount *getAccount(const QString&from ); void writeToFile(const QString&file, mailmime *mail ); void readFromFile(const QString&file, char **data, size_t *size ); + void storeMail(char*mail, size_t length, const QString&box); static QString mailsmtpError( int err ); static QString getTmpFile(); static void progress( size_t current, size_t maximum ); static void addRcpts( clist *list, mailimf_address_list *addr_list ); + void storeMail(mailmime*mail, const QString&box); Settings *settings; }; #endif diff --git a/noncore/net/mail/mboxwrapper.cpp b/noncore/net/mail/mboxwrapper.cpp index 7581715..8117cef 100644 --- a/noncore/net/mail/mboxwrapper.cpp +++ b/noncore/net/mail/mboxwrapper.cpp @@ -1,199 +1,219 @@ #include "mboxwrapper.h" #include "mailtypes.h" #include "mailwrapper.h" -#include "libetpan/libetpan.h" -#include "libetpan/mailstorage.h" +#include <libetpan/libetpan.h> +#include <libetpan/mailstorage.h> #include <qdir.h> MBOXwrapper::MBOXwrapper(const QString & mbox_dir) : Genericwrapper(),MBOXPath(mbox_dir) { QDir dir(MBOXPath); if (!dir.exists()) { dir.mkdir(MBOXPath); } } MBOXwrapper::~MBOXwrapper() { } void MBOXwrapper::listMessages(const QString & mailbox, QList<RecMail> &target ) { mailstorage*storage = mailstorage_new(NULL); QString p = MBOXPath+"/"; p+=mailbox; int r = mbox_mailstorage_init(storage,strdup(p.latin1()),0,0,0); mailfolder*folder; folder = mailfolder_new( storage,strdup(p.latin1()),NULL); r = mailfolder_connect(folder); if (r != MAIL_NO_ERROR) { qDebug("Error initializing mbox"); mailfolder_free(folder); mailstorage_free(storage); return; } mailmessage_list * env_list = 0; r = mailsession_get_messages_list(folder->fld_session,&env_list); if (r != MAIL_NO_ERROR) { qDebug("Error message list"); mailfolder_free(folder); mailstorage_free(storage); return; } r = mailsession_get_envelopes_list(folder->fld_session, env_list); if (r != MAIL_NO_ERROR) { qDebug("Error filling message list"); if (env_list) { mailmessage_list_free(env_list); } mailfolder_free(folder); mailstorage_free(storage); return; } mailimf_references * refs; for(int i = 0 ; i < carray_count(env_list->msg_tab) ; ++i) { mailmessage * msg; QBitArray mFlags(7); msg = (mailmessage*)carray_get(env_list->msg_tab, i); if (msg->msg_fields == NULL) { qDebug("could not fetch envelope of message %i", i); continue; } RecMail * mail = new RecMail(); mail->setWrapper(this); mail_flags * flag_result = 0; r = mailmessage_get_flags(msg,&flag_result); if (r == MAIL_ERROR_NOT_IMPLEMENTED) { - qDebug("flag fetching not implemented"); mFlags.setBit(FLAG_SEEN); } mailimf_single_fields single_fields; mailimf_single_fields_init(&single_fields, msg->msg_fields); mail->setMsgsize(msg->msg_size); mail->setFlags(mFlags); mail->setMbox(mailbox); mail->setNumber(i+1); if (single_fields.fld_subject) mail->setSubject( convert_String(single_fields.fld_subject->sbj_value)); if (single_fields.fld_from) mail->setFrom(parseMailboxList(single_fields.fld_from->frm_mb_list)); if (single_fields.fld_to) mail->setTo( parseAddressList( single_fields.fld_to->to_addr_list ) ); if (single_fields.fld_cc) mail->setCC( parseAddressList( single_fields.fld_cc->cc_addr_list ) ); if (single_fields.fld_bcc) mail->setBcc( parseAddressList( single_fields.fld_bcc->bcc_addr_list ) ); if (single_fields.fld_orig_date) mail->setDate( parseDateTime( single_fields.fld_orig_date->dt_date_time ) ); if (single_fields.fld_message_id->mid_value) mail->setMsgid(QString(single_fields.fld_message_id->mid_value)); refs = single_fields.fld_references; if (refs && refs->mid_list && clist_count(refs->mid_list)) { char * text = (char*)refs->mid_list->first->data; mail->setReplyto(QString(text)); } target.append(mail); } if (env_list) { mailmessage_list_free(env_list); } mailfolder_disconnect(folder); mailfolder_free(folder); mailstorage_free(storage); } QList<Folder>* MBOXwrapper::listFolders() { QList<Folder> * folders = new QList<Folder>(); folders->setAutoDelete( false ); QDir dir(MBOXPath); if (!dir.exists()) return folders; dir.setFilter(QDir::Files|QDir::Writable|QDir::Readable); QStringList entries = dir.entryList(); QStringList::ConstIterator it = entries.begin(); for (;it!=entries.end();++it) { Folder*inb=new Folder(*it,"/"); folders->append(inb); } return folders; } void MBOXwrapper::deleteMail(const RecMail&mail) { mailstorage*storage = mailstorage_new(NULL); QString p = MBOXPath+"/"; p+=mail.getMbox(); mailmessage * msg; int r = mbox_mailstorage_init(storage,strdup(p.latin1()),0,0,0); mailfolder*folder; folder = mailfolder_new( storage,strdup(p.latin1()),NULL); r = mailfolder_connect(folder); if (r != MAIL_NO_ERROR) { qDebug("Error initializing mbox"); mailfolder_free(folder); mailstorage_free(storage); return; } r = mailsession_remove_message(folder->fld_session,mail.getNumber()); if (r != MAIL_NO_ERROR) { qDebug("error deleting mail"); } mailfolder_free(folder); mailstorage_free(storage); } void MBOXwrapper::answeredMail(const RecMail&) { } RecBody MBOXwrapper::fetchBody( const RecMail &mail ) { RecBody body; mailstorage*storage = mailstorage_new(NULL); QString p = MBOXPath+"/"; p+=mail.getMbox(); mailmessage * msg; char*data=0; size_t size; int r = mbox_mailstorage_init(storage,strdup(p.latin1()),0,0,0); mailfolder*folder; folder = mailfolder_new( storage,strdup(p.latin1()),NULL); r = mailfolder_connect(folder); if (r != MAIL_NO_ERROR) { qDebug("Error initializing mbox"); mailfolder_free(folder); mailstorage_free(storage); return body; } r = mailsession_get_message(folder->fld_session, mail.getNumber(), &msg); if (r != MAIL_NO_ERROR) { qDebug("Error fetching mail %i",mail.getNumber()); mailfolder_free(folder); mailstorage_free(storage); return body; } r = mailmessage_fetch(msg,&data,&size); if (r != MAIL_NO_ERROR) { qDebug("Error fetching mail %i",mail.getNumber()); mailfolder_free(folder); mailstorage_free(storage); mailmessage_free(msg); return body; } body = parseMail(msg); mailmessage_fetch_result_free(msg,data); mailfolder_free(folder); mailstorage_free(storage); return body; } void MBOXwrapper::mbox_progress( size_t current, size_t maximum ) { qDebug("MBOX %i von %i",current,maximum); } + +void MBOXwrapper::createFolder(const QString&) +{ +} + +void MBOXwrapper::storeMessage(const char*msg,size_t length, const QString&folder) +{ + QString p = MBOXPath+"/"; + p+=folder; + mailmbox_folder*f = 0; + int r = mailmbox_init(p.latin1(),0,1,0,&f); + if (r != MAIL_NO_ERROR) { + qDebug("Error init folder"); + return; + } + r = mailmbox_append_message(f,msg,length); + if (r != MAIL_NO_ERROR) { + qDebug("Error writing message folder"); + } + mailmbox_done(f); +} diff --git a/noncore/net/mail/mboxwrapper.h b/noncore/net/mail/mboxwrapper.h index 779dbc8..1bbaf79 100644 --- a/noncore/net/mail/mboxwrapper.h +++ b/noncore/net/mail/mboxwrapper.h @@ -1,30 +1,32 @@ #ifndef __MBOX_WRAPPER_H #define __MBOX_WRAPPER_H #include "genericwrapper.h" #include <qstring.h> class RecMail; class RecBody; class MBOXwrapper : public Genericwrapper { Q_OBJECT public: MBOXwrapper(const QString & dir); virtual ~MBOXwrapper(); virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); virtual QList<Folder>* listFolders(); virtual void deleteMail(const RecMail&mail); virtual void answeredMail(const RecMail&mail); + virtual void createFolder(const QString&aFolder); + virtual void storeMessage(const char*msg,size_t length, const QString&folder); virtual RecBody fetchBody( const RecMail &mail ); static void mbox_progress( size_t current, size_t maximum ); protected: QString MBOXPath; }; #endif diff --git a/noncore/net/mail/smtpwrapper.cpp b/noncore/net/mail/smtpwrapper.cpp index 162b1b9..a6a46ba 100644 --- a/noncore/net/mail/smtpwrapper.cpp +++ b/noncore/net/mail/smtpwrapper.cpp @@ -1,604 +1,645 @@ #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <qdir.h> -#include <libetpan/mailmime.h> +#include <libetpan/libetpan.h> +#if 0 #include <libetpan/mailimf.h> #include <libetpan/mailsmtp.h> #include <libetpan/mailstorage.h> #include <libetpan/maildriver.h> +#endif #include "smtpwrapper.h" #include "mailwrapper.h" +#include "mboxwrapper.h" #include "logindialog.h" #include "defines.h" SMTPwrapper::SMTPwrapper( Settings *s ) : QObject() { settings = s; } 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(); QStringList list = QStringList::split( ',', addr ); QStringList::Iterator it; for ( it = list.begin(); it != list.end(); it++ ) { char *str = strdup( (*it).latin1() ); int err = mailimf_address_list_add_parse( addresses, str ); if ( err != MAILIMF_NO_ERROR ) { qDebug( "Error parsing" ); qDebug( *it ); free( str ); } else { qDebug( "Parse success! :)" ); } } return addresses; } mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail ) { mailimf_fields *fields; mailimf_field *xmailer; mailimf_mailbox *sender, *fromBox; mailimf_mailbox_list *from; mailimf_address_list *to, *cc, *bcc, *reply; char *subject = strdup( mail.getSubject().latin1() ); int err; sender = newMailbox( mail.getName(), mail.getMail() ); if ( sender == NULL ) goto err_free; fromBox = newMailbox( mail.getName(), mail.getMail() ); if ( fromBox == NULL ) goto err_free_sender; from = mailimf_mailbox_list_new_empty(); if ( from == NULL ) goto err_free_fromBox; err = mailimf_mailbox_list_add( from, fromBox ); if ( err != MAILIMF_NO_ERROR ) goto err_free_from; to = parseAddresses( mail.getTo() ); if ( to == NULL ) goto err_free_from; cc = parseAddresses( mail.getCC() ); bcc = parseAddresses( mail.getBCC() ); reply = parseAddresses( mail.getReply() ); fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc, NULL, NULL, subject ); if ( fields == NULL ) goto err_free_reply; xmailer = mailimf_field_new_custom( strdup( "User-Agent" ), strdup( USER_AGENT ) ); if ( xmailer == NULL ) goto err_free_fields; err = mailimf_fields_add( fields, xmailer ); if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer; return fields; // Success :) err_free_xmailer: mailimf_field_free( xmailer ); err_free_fields: mailimf_fields_free( fields ); err_free_reply: mailimf_address_list_free( reply ); mailimf_address_list_free( bcc ); mailimf_address_list_free( cc ); mailimf_address_list_free( to ); err_free_from: mailimf_mailbox_list_free( from ); err_free_fromBox: mailimf_mailbox_free( fromBox ); err_free_sender: mailimf_mailbox_free( sender ); err_free: free( subject ); qDebug( "createImfFields - error" ); return NULL; // Error :( } mailmime *SMTPwrapper::buildTxtPart(const QString&str ) { mailmime *txtPart; mailmime_fields *fields; mailmime_content *content; mailmime_parameter *param; char *txt = strdup( str.latin1() ); int err; param = mailmime_parameter_new( strdup( "charset" ), strdup( "iso-8859-1" ) ); if ( param == NULL ) goto err_free; content = mailmime_content_new_with_str( "text/plain" ); if ( content == NULL ) goto err_free_param; err = clist_append( content->ct_parameters, param ); if ( err != MAILIMF_NO_ERROR ) goto err_free_content; fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT ); if ( fields == NULL ) goto err_free_content; txtPart = mailmime_new_empty( content, fields ); if ( txtPart == NULL ) goto err_free_fields; err = mailmime_set_body_text( txtPart, txt, strlen( txt ) ); if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart; return txtPart; // Success :) err_free_txtPart: mailmime_free( txtPart ); err_free_fields: mailmime_fields_free( fields ); err_free_content: mailmime_content_free( content ); err_free_param: mailmime_parameter_free( param ); err_free: free( txt ); qDebug( "buildTxtPart - error" ); return NULL; // Error :( } mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype ) { mailmime * filePart; mailmime_fields * fields; mailmime_content * content; mailmime_parameter * param = NULL; int err; int pos = filename.findRev( '/' ); QString tmp = filename.right( filename.length() - ( pos + 1 ) ); char *name = strdup( tmp.latin1() ); // just filename char *file = strdup( filename.latin1() ); // full name with path char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain fields = mailmime_fields_new_filename( MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name, MAILMIME_MECHANISM_BASE64 ); if ( fields == NULL ) goto err_free; content = mailmime_content_new_with_str( mime ); if ( content == NULL ) goto err_free_fields; if ( mimetype.compare( "text/plain" ) == 0 ) { param = mailmime_parameter_new( strdup( "charset" ), strdup( "iso-8859-1" ) ); if ( param == NULL ) goto err_free_content; err = clist_append( content->ct_parameters, param ); if ( err != MAILIMF_NO_ERROR ) goto err_free_param; } filePart = mailmime_new_empty( content, fields ); if ( filePart == NULL ) goto err_free_param; err = mailmime_set_body_file( filePart, file ); if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart; return filePart; // Success :) err_free_filePart: mailmime_free( filePart ); err_free_param: if ( param != NULL ) mailmime_parameter_free( param ); err_free_content: mailmime_content_free( content ); err_free_fields: mailmime_fields_free( fields ); err_free: free( name ); free( mime ); free( file ); qDebug( "buildFilePart - error" ); return NULL; // Error :( } void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files ) { const Attachment *it; /* work around for the brainfucked qlist which can not act with const values */ for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) { qDebug( "Adding file" ); mailmime *filePart; int err; filePart = buildFilePart( it->getFileName(), it->getMimeType() ); if ( filePart == NULL ) goto err_free; err = mailmime_smart_add_part( message, filePart ); if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart; continue; // Success :) err_free_filePart: mailmime_free( filePart ); err_free: qDebug( "addFileParts: error adding file:" ); qDebug( it->getFileName() ); } } mailmime *SMTPwrapper::createMimeMail(const Mail &mail ) { mailmime *message, *txtPart; mailimf_fields *fields; int err; fields = createImfFields( mail ); if ( fields == NULL ) goto err_free; message = mailmime_new_message_data( NULL ); if ( message == NULL ) goto err_free_fields; mailmime_set_imf_fields( message, fields ); txtPart = buildTxtPart( mail.getMessage() ); if ( txtPart == NULL ) goto err_free_message; err = mailmime_smart_add_part( message, txtPart ); if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart; addFileParts( message, mail.getAttachments() ); return message; // Success :) err_free_txtPart: mailmime_free( txtPart ); err_free_message: mailmime_free( message ); err_free_fields: mailimf_fields_free( fields ); err_free: qDebug( "createMimeMail: error" ); return NULL; // Error :( } mailimf_field *SMTPwrapper::getField( mailimf_fields *fields, int type ) { mailimf_field *field; clistiter *it; it = clist_begin( fields->fld_list ); while ( it ) { field = (mailimf_field *) it->data; if ( field->fld_type == type ) { return field; } it = it->next; } return NULL; } void SMTPwrapper::addRcpts( clist *list, mailimf_address_list *addr_list ) { clistiter *it, *it2; for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) { mailimf_address *addr; addr = (mailimf_address *) it->data; if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) { esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL ); } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) { clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list; for ( it2 = clist_begin( l ); it2; it2 = it2->next ) { mailimf_mailbox *mbox; mbox = (mailimf_mailbox *) it2->data; esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL ); } } } } clist *SMTPwrapper::createRcptList( mailimf_fields *fields ) { clist *rcptList; mailimf_field *field; rcptList = esmtp_address_list_new(); field = getField( fields, MAILIMF_FIELD_TO ); if ( field && (field->fld_type == MAILIMF_FIELD_TO) && field->fld_data.fld_to->to_addr_list ) { addRcpts( rcptList, field->fld_data.fld_to->to_addr_list ); } field = getField( fields, MAILIMF_FIELD_CC ); if ( field && (field->fld_type == MAILIMF_FIELD_CC) && field->fld_data.fld_cc->cc_addr_list ) { addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list ); } 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( mailmime *mail ) { char *from = NULL; mailimf_field *ffrom; ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM ); 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; } SMTPaccount *SMTPwrapper::getAccount(const QString&from ) { SMTPaccount *smtp; QList<Account> list = settings->getAccounts(); Account *it; for ( it = list.first(); it; it = list.next() ) { if ( it->getType().compare( "SMTP" ) == 0 ) { smtp = static_cast<SMTPaccount *>(it); if ( smtp->getMail().compare( from ) == 0 ) { qDebug( "SMTPaccount found for" ); qDebug( from ); return smtp; } } } return NULL; } QString SMTPwrapper::getTmpFile() { int num = 0; QString unique; QDir dir( "/tmp" ); QStringList::Iterator it; QStringList list = dir.entryList( "opiemail-tmp-*" ); do { unique.setNum( num++ ); } while ( list.contains( "opiemail-tmp-" + unique ) > 0 ); return "/tmp/opiemail-tmp-" + unique; } void SMTPwrapper::writeToFile(const QString&file, mailmime *mail ) { FILE *f; int err, col = 0; f = fopen( file.latin1(), "w" ); if ( f == NULL ) { qDebug( "writeToFile: error opening file" ); return; } err = mailmime_write( f, &col, mail ); if ( err != MAILIMF_NO_ERROR ) { fclose( f ); qDebug( "writeToFile: error writing mailmime" ); return; } fclose( f ); } void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size ) { + + QFile msg_cache(file); + QString msg = ""; + msg_cache.open(IO_ReadOnly); + char*message = new char[4096]; + memset(message,0,4096); + while (msg_cache.readBlock(message,4095)>0) { + msg+=message; + memset(message,0,4096); + } + delete message; + *data = (char*)malloc(msg.length()+1*sizeof(char)); + memset(*data,0,msg.length()+1); + memcpy(*data,msg.ascii(),msg.length()); + *size=msg.length(); + +#if 0 char *buf; struct stat st; int fd, count = 0, total = 0; fd = open( file.latin1(), O_RDONLY, 0 ); if ( fd == -1 ) return; if ( fstat( fd, &st ) != 0 ) goto err_close; if ( !st.st_size ) goto err_close; buf = (char *) malloc( st.st_size ); if ( !buf ) goto err_close; while ( ( total < st.st_size ) && ( count >= 0 ) ) { count = read( fd, buf + total, st.st_size - total ); total += count; } if ( count < 0 ) goto err_free; *data = buf; *size = st.st_size; close( fd ); return; // Success :) err_free: free( buf ); err_close: close( fd ); +#endif } void SMTPwrapper::progress( size_t current, size_t maximum ) { qDebug( "Current: %i of %i", current, maximum ); } -void SMTPwrapper::smtpSend( mailmime *mail ) +void SMTPwrapper::storeMail(char*mail, size_t length, const QString&box) +{ + if (!mail) return; + QString localfolders = (QString) getenv( "HOME" ) + QString("/Applications/opiemail/localmail/"); + MBOXwrapper*wrap = new MBOXwrapper(localfolders); + wrap->storeMessage(mail,length,box); + delete wrap; +} + +void SMTPwrapper::smtpSend( mailmime *mail,bool later ) { mailsmtp *session; clist *rcpts; char *from, *data, *server, *user = NULL, *pass = NULL; size_t size; int err; bool ssl; uint16_t port; from = getFrom( mail ); SMTPaccount *smtp = getAccount( from ); if ( smtp == NULL ) { free(from); return; } - server = strdup( smtp->getServer().latin1() ); - ssl = smtp->getSSL(); - port = smtp->getPort().toUInt(); rcpts = createRcptList( mail->mm_data.mm_message.mm_fields ); QString file = getTmpFile(); writeToFile( file, mail ); + readFromFile( file, &data, &size ); QFile f( file ); f.remove(); + storeMail(data,size,(later?"Outgoing":"Sent")); + + if (later) { + smtp_address_list_free( rcpts ); + if (data) free( data ); + if (from) free(from); + return; + } + server = strdup( smtp->getServer().latin1() ); + ssl = smtp->getSSL(); + 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 ) goto free_mem_session; err = mailsmtp_init( session ); if ( err != MAILSMTP_NO_ERROR ) goto free_con_session; qDebug( "INIT OK" ); if ( smtp->getLogin() ) { 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 = strdup( login.getUser().latin1() ); pass = strdup( login.getPassword().latin1() ); } else { goto free_con_session; } } else { user = strdup( smtp->getUser().latin1() ); pass = strdup( smtp->getPassword().latin1() ); } qDebug( "session->auth: %i", session->auth); err = mailsmtp_auth( session, user, pass ); if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok"); qDebug( "Done auth!" ); } err = mailsmtp_send( session, from, rcpts, data, size ); if ( err != MAILSMTP_NO_ERROR ) goto free_con_session; qDebug( "Mail sent." ); free_con_session: mailsmtp_quit( session ); free_mem_session: mailsmtp_free( session ); free_mem: smtp_address_list_free( rcpts ); - free( data ); - free( server ); + if (data) free( data ); + if (from) free(from); + if (server) free( server ); if ( smtp->getLogin() ) { free( user ); free( pass ); } free( from ); } -void SMTPwrapper::sendMail(const Mail&mail ) +void SMTPwrapper::sendMail(const Mail&mail,bool later ) { mailmime *mimeMail; mimeMail = createMimeMail(mail ); if ( mimeMail == NULL ) { qDebug( "sendMail: error creating mime mail" ); } else { - smtpSend( mimeMail ); + smtpSend( mimeMail,later ); mailmime_free( mimeMail ); } } diff --git a/noncore/net/mail/smtpwrapper.h b/noncore/net/mail/smtpwrapper.h index 8fdb07d..41e9a8c 100644 --- a/noncore/net/mail/smtpwrapper.h +++ b/noncore/net/mail/smtpwrapper.h @@ -1,53 +1,55 @@ #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 Attachment; struct mailimf_fields; struct mailimf_field; struct mailimf_mailbox; struct mailmime; struct mailimf_address_list; class SMTPwrapper : public QObject { Q_OBJECT public: SMTPwrapper( Settings *s ); virtual ~SMTPwrapper(){} - void sendMail(const Mail& mail ); + void sendMail(const Mail& mail,bool later=false ); 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 ); - void smtpSend( mailmime *mail ); + void smtpSend( mailmime *mail,bool later ); mailimf_field *getField( mailimf_fields *fields, int type ); clist *createRcptList( mailimf_fields *fields ); char *getFrom( mailmime *mail ); SMTPaccount *getAccount(const QString&from ); void writeToFile(const QString&file, mailmime *mail ); void readFromFile(const QString&file, char **data, size_t *size ); + void storeMail(char*mail, size_t length, const QString&box); static QString mailsmtpError( int err ); static QString getTmpFile(); static void progress( size_t current, size_t maximum ); static void addRcpts( clist *list, mailimf_address_list *addr_list ); + void storeMail(mailmime*mail, const QString&box); Settings *settings; }; #endif |