39 files changed, 6775 insertions, 0 deletions
diff --git a/kmicromail/libmailwrapper/.cvsignore b/kmicromail/libmailwrapper/.cvsignore new file mode 100644 index 0000000..581c299 --- a/dev/null +++ b/kmicromail/libmailwrapper/.cvsignore @@ -0,0 +1,6 @@ +logindialogui.cpp +logindialogui.h +sendmailprogressui.cpp +sendmailprogressui.h +.moc +Makefile diff --git a/kmicromail/libmailwrapper/abstractmail.cpp b/kmicromail/libmailwrapper/abstractmail.cpp new file mode 100644 index 0000000..128a7c0 --- a/dev/null +++ b/kmicromail/libmailwrapper/abstractmail.cpp @@ -0,0 +1,172 @@ +#include "abstractmail.h" +#include "imapwrapper.h" +#include "pop3wrapper.h" +#include "nntpwrapper.h" +#include "mhwrapper.h" +#include "mailtypes.h" + + + +#include <kdecore/kstandarddirs.h> +#include <qfile.h> +#include <qtextstream.h> +#include <stdlib.h> +#include <libetpan/mailmime_content.h> +#include <libetpan/mailmime.h> + +using namespace Opie::Core; +AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) +{ + return new IMAPwrapper(a); +} + +AbstractMail* AbstractMail::getWrapper(POP3account *a) +{ + return new POP3wrapper(a); +} + +AbstractMail* AbstractMail::getWrapper(NNTPaccount *a) +{ + return new NNTPwrapper(a); +} + +AbstractMail* AbstractMail::getWrapper(const QString&a,const QString&name) +{ + return new MHwrapper(a,name); +} + +AbstractMail* AbstractMail::getWrapper(Account*a) +{ + if (!a) return 0; + switch (a->getType()) { + case MAILLIB::A_IMAP: + return new IMAPwrapper((IMAPaccount*)a); + break; + case MAILLIB::A_POP3: + return new POP3wrapper((POP3account*)a); + break; + case MAILLIB::A_NNTP: + return new NNTPwrapper((NNTPaccount*)a); + break; + default: + return 0; + } +} + +encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) +{ + // odebug << "Decode string start" << oendl; + char*result_text; + size_t index = 0; + /* reset for recursive use! */ + size_t target_length = 0; + result_text = 0; + int mimetype = MAILMIME_MECHANISM_7BIT; + if (enc.lower()=="quoted-printable") { + mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; + } else if (enc.lower()=="base64") { + mimetype = MAILMIME_MECHANISM_BASE64; + } else if (enc.lower()=="8bit") { + mimetype = MAILMIME_MECHANISM_8BIT; + } else if (enc.lower()=="binary") { + mimetype = MAILMIME_MECHANISM_BINARY; + } + + int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype, + &result_text,&target_length); + + encodedString* result = new encodedString(); + if (err == MAILIMF_NO_ERROR) { + result->setContent(result_text,target_length); + } + //odebug << "Decode string finished" << oendl; + return result; +} + +QString AbstractMail::convert_String(const char*text) +{ + //size_t index = 0; + char*res = 0; + int err = MAILIMF_NO_ERROR; + + QString result(text); + + /* due a bug in libetpan it isn't usable this moment */ +/* int err = mailmime_encoded_phrase_parse("iso-8859-1", + text, strlen(text),&index, "iso-8859-1",&res);*/ + //odebug << "Input: " << text << "" << oendl; + if (err == MAILIMF_NO_ERROR && res && strlen(res)) { +// result = QString(res); +// odebug << "Res: " << res << ", length: " << strlen(res) << "" << oendl; + } + if (res) free(res); + return result; +} + +/* cp & paste from launcher */ +QString AbstractMail::gen_attachment_id() +{ + QFile file( "/proc/sys/kernel/random/uuid" ); + if (!file.open(IO_ReadOnly ) ) + return QString::null; + + QTextStream stream(&file); + + return "{" + stream.read().stripWhiteSpace() + "}"; +} + +int AbstractMail::createMbox(const QString&,const FolderP&,const QString& ,bool) +{ + return 0; +} + +QString AbstractMail::defaultLocalfolder() +{ + // QString f = getenv( "HOME" ); + QString f = locateLocal( "data", "kmicromail/localmail"); + // f += "/Applications/opiemail/localmail"; + return f; +} + +QString AbstractMail::draftFolder() +{ + return QString("Drafts"); +} + +/* temporary - will be removed when implemented in all classes */ +void AbstractMail::deleteMails(const QString &,const QValueList<Opie::Core::OSmartPointer<RecMail> > &) +{ +} + +void AbstractMail::mvcpAllMails(const FolderP&fromFolder, + const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) +{ + QValueList<RecMailP> t; + listMessages(fromFolder->getName(),t); + encodedString*st = 0; + while (t.count()>0) { + RecMailP r = (*t.begin()); + st = fetchRawBody(r); + if (st) { + targetWrapper->storeMessage(st->Content(),st->Length(),targetFolder); + delete st; + } + t.remove(t.begin()); + } + if (moveit) { + deleteAllMail(fromFolder); + } +} + +void AbstractMail::mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) +{ + encodedString*st = 0; + st = fetchRawBody(mail); + if (st) { + targetWrapper->storeMessage(st->Content(),st->Length(),targetFolder); + delete st; + } + if (moveit) { + deleteMail(mail); + } +} diff --git a/kmicromail/libmailwrapper/abstractmail.h b/kmicromail/libmailwrapper/abstractmail.h new file mode 100644 index 0000000..e5d64a6 --- a/dev/null +++ b/kmicromail/libmailwrapper/abstractmail.h @@ -0,0 +1,72 @@ +#ifndef __abstract_mail_ +#define __abstract_mail_ + +#include "maildefines.h" + +#include "settings.h" + +#include <qobject.h> +#include <opie2/osmartpointer.h> +#include "mailtypes.h" + +class IMAPwrapper; +class POP3wrapper; +class Folder; +class encodedString; +struct folderStat; + +class AbstractMail:public QObject +{ + Q_OBJECT +public: + AbstractMail(){}; + virtual ~AbstractMail(){} + virtual QValueList<Opie::Core::OSmartPointer<Folder> >* listFolders()=0; + virtual void listMessages(const QString & mailbox,QValueList<RecMailP>&target )=0; + virtual void statusFolder(folderStat&target_stat,const QString & mailbox="INBOX")=0; + virtual RecBodyP fetchBody(const RecMailP&mail)=0; + virtual QString fetchTextPart(const RecMailP&mail,const RecPartP&part)=0; + virtual encodedString* fetchDecodedPart(const RecMailP&mail,const RecPartP&part)=0; + virtual encodedString* fetchRawPart(const RecMailP&mail,const RecPartP&part)=0; + virtual encodedString* fetchRawBody(const RecMailP&mail)=0; + + virtual void deleteMail(const RecMailP&mail)=0; + virtual void answeredMail(const RecMailP&mail)=0; + virtual int deleteAllMail(const Opie::Core::OSmartPointer<Folder>&)=0; + virtual void deleteMails(const QString & FolderName,const QValueList<Opie::Core::OSmartPointer<RecMail> >&target); + virtual int deleteMbox(const Opie::Core::OSmartPointer<Folder>&)=0; + virtual void storeMessage(const char*msg,size_t length, const QString&folder)=0; + + virtual void mvcpAllMails(const Opie::Core::OSmartPointer<Folder>&fromFolder, + const QString&targetFolder,AbstractMail*targetWrapper,bool moveit); + virtual void mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit); + + virtual void cleanMimeCache(){}; + /* mail box methods */ + /* parameter is the box to create. + * if the implementing subclass has prefixes, + * them has to be appended automatic. + */ + virtual int createMbox(const QString&,const Opie::Core::OSmartPointer<Folder>&parentfolder=0, + const QString& delemiter="/",bool getsubfolder=false); + virtual void logout()=0; + + static AbstractMail* getWrapper(IMAPaccount *a); + static AbstractMail* getWrapper(POP3account *a); + static AbstractMail* getWrapper(NNTPaccount *a); + /* mbox only! */ + static AbstractMail* getWrapper(const QString&a,const QString&name="Local Folders"); + static AbstractMail* getWrapper(Account*a); + + static QString defaultLocalfolder(); + static QString draftFolder(); + + virtual MAILLIB::ATYPE getType()const=0; + virtual const QString&getName()const=0; + +protected: + static encodedString*decode_String(const encodedString*text,const QString&enc); + static QString convert_String(const char*text); + static QString gen_attachment_id(); +}; +#endif diff --git a/kmicromail/libmailwrapper/config.in b/kmicromail/libmailwrapper/config.in new file mode 100644 index 0000000..7da4a05 --- a/dev/null +++ b/kmicromail/libmailwrapper/config.in @@ -0,0 +1,4 @@ + config LIBMAILWRAPPER + boolean "libmailwrapper (libetpan wrapper library)" + default "y" + depends ( LIBQPE || LIBQPE-X11 ) && LIBETPAN_DEP diff --git a/kmicromail/libmailwrapper/generatemail.cpp b/kmicromail/libmailwrapper/generatemail.cpp new file mode 100644 index 0000000..49315ba --- a/dev/null +++ b/kmicromail/libmailwrapper/generatemail.cpp @@ -0,0 +1,460 @@ +#include "generatemail.h" +#include "mailwrapper.h" + +#include <libetpan/libetpan.h> + +//#include <qt.h> + +#include <stdlib.h> +#include <qfileinfo.h> + +using namespace Opie::Core; +const char* Generatemail::USER_AGENT="OpieMail v0.6"; + +Generatemail::Generatemail() +{ +} + +Generatemail::~Generatemail() +{ +} + +void Generatemail::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 ); + } + } + } +} + +char *Generatemail::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 *Generatemail::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); +} + +mailimf_field *Generatemail::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; +} + +mailimf_address_list *Generatemail::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; + break; + case ',': + if (!literal_open) { + s = addr.mid(startpos,i-startpos); + if (!s.isEmpty()) { + list.append(s); + } + // !!!! this is a MUST BE! + startpos = ++i; + } + break; + default: + break; + } + } + s = addr.mid(startpos,i-startpos); + if (!s.isEmpty()) { + list.append(s); + } + QStringList::Iterator it; + for ( it = list.begin(); it != list.end(); it++ ) { + int err = mailimf_address_list_add_parse( addresses, (char*)(*it).latin1() ); + if ( err != MAILIMF_NO_ERROR ) { + qDebug(" Error parsing"); // *it + } else { + } + } + return addresses; +} + +mailmime *Generatemail::buildFilePart(const QString&filename,const QString&mimetype,const QString&TextContent ) { + mailmime * filePart = 0; + mailmime_fields * fields = 0; + mailmime_content * content = 0; + mailmime_parameter * param = 0; + char*name = 0; + char*file = 0; + int err; + + int pos = filename.findRev( '/' ); + + if (filename.length()>0) { + QString tmp = filename.right( filename.length() - ( pos + 1 ) ); + name = strdup( tmp.latin1() ); // just filename + file = strdup( filename.latin1() ); // full name with path + } + + int disptype = MAILMIME_DISPOSITION_TYPE_ATTACHMENT; + int mechanism = MAILMIME_MECHANISM_BASE64; + + if ( mimetype.startsWith( "text/" ) ) { + param = mailmime_parameter_new( strdup( "charset" ), + strdup( "iso-8859-1" ) ); + mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE; + } + + fields = mailmime_fields_new_filename( + disptype, name, + mechanism ); + content = mailmime_content_new_with_str( (char*)mimetype.latin1() ); + if (content!=0 && fields != 0) { + if (param) { + clist_append(content->ct_parameters,param); + param = 0; + } + if (filename.length()>0) { + QFileInfo f(filename); + param = mailmime_parameter_new(strdup("name"),strdup(f.fileName().latin1())); + clist_append(content->ct_parameters,param); + param = 0; + } + filePart = mailmime_new_empty( content, fields ); + } + if (filePart) { + if (filename.length()>0) { + err = mailmime_set_body_file( filePart, file ); + } else { + err = mailmime_set_body_text(filePart,strdup(TextContent.data()),TextContent.length()); + } + if (err != MAILIMF_NO_ERROR) { + qDebug("Error setting body with file "); + mailmime_free( filePart ); + filePart = 0; + } + } + + if (!filePart) { + if ( param != NULL ) { + mailmime_parameter_free( param ); + } + if (content) { + mailmime_content_free( content ); + } + if (fields) { + mailmime_fields_free( fields ); + } else { + if (name) { + free( name ); + } + if (file) { + free( file ); + } + } + } + return filePart; // Success :) + +} + +void Generatemail::addFileParts( mailmime *message,const QList<Attachment>&files ) { + const Attachment *it; + unsigned int count = files.count(); + for ( unsigned int i = 0; i < count; ++i ) { + mailmime *filePart; + int err; + it = ((QList<Attachment>)files).at(i); + + filePart = buildFilePart( it->getFileName(), it->getMimeType(),"" ); + if ( filePart == NULL ) { + continue; + } + err = mailmime_smart_add_part( message, filePart ); + if ( err != MAILIMF_NO_ERROR ) { + mailmime_free( filePart ); + } + } +} + +mailmime *Generatemail::buildTxtPart(const QString&str ) { + mailmime *txtPart; + mailmime_fields *fields; + mailmime_content *content; + mailmime_parameter *param; + 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, (char*)str.data(), str.length() ); + 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: + ; + + return NULL; // Error :( +} + +mailimf_mailbox *Generatemail::newMailbox(const QString&name, const QString&mail ) { + return mailimf_mailbox_new( strdup( name.latin1() ), + strdup( mail.latin1() ) ); +} + +mailimf_fields *Generatemail::createImfFields(const Opie::Core::OSmartPointer<Mail>&mail ) +{ + mailimf_fields *fields = NULL; + mailimf_field *xmailer = NULL; + mailimf_mailbox *sender=0,*fromBox=0; + mailimf_mailbox_list *from=0; + mailimf_address_list *to=0, *cc=0, *bcc=0, *reply=0; + clist*in_reply_to = 0; + char *subject = strdup( mail->getSubject().latin1() ); + int err; + int res = 1; + + sender = newMailbox( mail->getName(), mail->getMail() ); + if ( sender == NULL ) { + res = 0; + } + + if (res) { + fromBox = newMailbox( mail->getName(), mail->getMail() ); + } + if ( fromBox == NULL ) { + res = 0; + } + + if (res) { + from = mailimf_mailbox_list_new_empty(); + } + if ( from == NULL ) { + res = 0; + } + + if (res && from) { + err = mailimf_mailbox_list_add( from, fromBox ); + if ( err != MAILIMF_NO_ERROR ) { + res = 0; + } + } + + if (res) to = parseAddresses( mail->getTo() ); + if (res) cc = parseAddresses( mail->getCC() ); + if (res) bcc = parseAddresses( mail->getBCC() ); + if (res) reply = parseAddresses( mail->getReply() ); + + if (res && mail->Inreply().count()>0) { + in_reply_to = clist_new(); + char*c_reply; + unsigned int nsize = 0; + for (QStringList::ConstIterator it=mail->Inreply().begin(); + it != mail->Inreply().end();++it) { + if ((*it).isEmpty()) + continue; + QString h((*it)); + while (h.length()>0 && h[0]=='<') { + h.remove(0,1); + } + while (h.length()>0 && h[h.length()-1]=='>') { + h.remove(h.length()-1,1); + } + if (h.isEmpty()) continue; + nsize = strlen(h.latin1()); + /* yes! must be malloc! */ + c_reply = (char*)malloc( (nsize+1)*sizeof(char)); + memset(c_reply,0,nsize+1); + memcpy(c_reply,h.latin1(),nsize); + clist_append(in_reply_to,c_reply); + } + } + + if (res) { + fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc, + in_reply_to, NULL, subject ); + if ( fields == NULL ) { + res = 0; + } + } + if (res) xmailer = mailimf_field_new_custom( strdup( "User-Agent" ), + strdup( USER_AGENT ) ); + if ( xmailer == NULL ) { + res = 0; + } else { + err = mailimf_fields_add( fields, xmailer ); + if ( err != MAILIMF_NO_ERROR ) { + res = 0; + } + } + if (!res ) { + if (xmailer) { + mailimf_field_free( xmailer ); + xmailer = NULL; + } + if (fields) { + mailimf_fields_free( fields ); + fields = NULL; + } else { + if (reply) + mailimf_address_list_free( reply ); + if (bcc) + mailimf_address_list_free( bcc ); + if (cc) + mailimf_address_list_free( cc ); + if (to) + mailimf_address_list_free( to ); + if (fromBox) { + mailimf_mailbox_free( fromBox ); + } else if (from) { + mailimf_mailbox_list_free( from ); + } + if (sender) { + mailimf_mailbox_free( sender ); + } + if (subject) { + free( subject ); + } + } + } + return fields; +} + +mailmime *Generatemail::createMimeMail(const Opie::Core::OSmartPointer<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: + ; + + return NULL; // Error :( +} + +clist *Generatemail::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; +} diff --git a/kmicromail/libmailwrapper/generatemail.h b/kmicromail/libmailwrapper/generatemail.h new file mode 100644 index 0000000..a767b61 --- a/dev/null +++ b/kmicromail/libmailwrapper/generatemail.h @@ -0,0 +1,46 @@ +#ifndef __GENERATE_MAIL_H +#define __GENERATE_MAIL_H + +#include <qpe/applnk.h> + +#include <qobject.h> +#include <libetpan/clist.h> + +#include <opie2/osmartpointer.h> + +class Mail; +class RecMail; +class Attachment; +struct mailimf_fields; +struct mailimf_field; +struct mailimf_mailbox; +struct mailmime; +struct mailimf_address_list; +class progressMailSend; +struct mailsmtp; + +class Generatemail : public QObject +{ + Q_OBJECT +public: + Generatemail(); + virtual ~Generatemail(); + +protected: + 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 ); + mailimf_address_list *parseAddresses(const QString&addr ); + void addFileParts( mailmime *message,const QList<Attachment>&files ); + mailmime *buildFilePart(const QString&filename,const QString&mimetype,const QString&content); + mailmime *buildTxtPart(const QString&str ); + mailimf_mailbox *newMailbox(const QString&name,const QString&mail ); + mailimf_fields *createImfFields(const Opie::Core::OSmartPointer<Mail> &mail ); + mailmime *createMimeMail(const Opie::Core::OSmartPointer<Mail>&mail ); + clist *createRcptList( mailimf_fields *fields ); + + static const char* USER_AGENT; +}; + +#endif diff --git a/kmicromail/libmailwrapper/genericwrapper.cpp b/kmicromail/libmailwrapper/genericwrapper.cpp new file mode 100644 index 0000000..f804e44 --- a/dev/null +++ b/kmicromail/libmailwrapper/genericwrapper.cpp @@ -0,0 +1,480 @@ +#include "genericwrapper.h" +#include <libetpan/libetpan.h> +#include "mailtypes.h" + + + +using namespace Opie::Core; +Genericwrapper::Genericwrapper() + : AbstractMail() +{ + bodyCache.clear(); + m_storage = 0; + m_folder = 0; +} + +Genericwrapper::~Genericwrapper() +{ + if (m_folder) { + mailfolder_free(m_folder); + } + if (m_storage) { + mailstorage_free(m_storage); + } + cleanMimeCache(); +} + +void Genericwrapper::fillSingleBody(RecPartP&target,mailmessage*,mailmime*mime) +{ + if (!mime) { + return; + } + mailmime_field*field = 0; + mailmime_single_fields fields; + memset(&fields, 0, sizeof(struct mailmime_single_fields)); + if (mime->mm_mime_fields != NULL) { + mailmime_single_fields_init(&fields, mime->mm_mime_fields, + mime->mm_content_type); + } + + mailmime_content*type = fields.fld_content; + clistcell*current; + if (!type) { + target->setType("text"); + target->setSubtype("plain"); + } else { + target->setSubtype(type->ct_subtype); + switch(type->ct_type->tp_data.tp_discrete_type->dt_type) { + case MAILMIME_DISCRETE_TYPE_TEXT: + target->setType("text"); + break; + case MAILMIME_DISCRETE_TYPE_IMAGE: + target->setType("image"); + break; + case MAILMIME_DISCRETE_TYPE_AUDIO: + target->setType("audio"); + break; + case MAILMIME_DISCRETE_TYPE_VIDEO: + target->setType("video"); + break; + case MAILMIME_DISCRETE_TYPE_APPLICATION: + target->setType("application"); + break; + case MAILMIME_DISCRETE_TYPE_EXTENSION: + default: + if (type->ct_type->tp_data.tp_discrete_type->dt_extension) { + target->setType(type->ct_type->tp_data.tp_discrete_type->dt_extension); + } + break; + } + if (type->ct_parameters) { + fillParameters(target,type->ct_parameters); + } + } + if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) { + for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) { + field = (mailmime_field*)current->data; + switch(field->fld_type) { + case MAILMIME_FIELD_TRANSFER_ENCODING: + target->setEncoding(getencoding(field->fld_data.fld_encoding)); + break; + case MAILMIME_FIELD_ID: + target->setIdentifier(field->fld_data.fld_id); + break; + case MAILMIME_FIELD_DESCRIPTION: + target->setDescription(field->fld_data.fld_description); + break; + default: + break; + } + } + } +} + +void Genericwrapper::fillParameters(RecPartP&target,clist*parameters) +{ + if (!parameters) {return;} + clistcell*current=0; + mailmime_parameter*param; + for (current=clist_begin(parameters);current!=0;current=clist_next(current)) { + param = (mailmime_parameter*)current->data; + if (param) { + target->addParameter(QString(param->pa_name).lower(),QString(param->pa_value)); + } + } +} + +QString Genericwrapper::getencoding(mailmime_mechanism*aEnc) +{ + QString enc="7bit"; + if (!aEnc) return enc; + switch(aEnc->enc_type) { + case MAILMIME_MECHANISM_7BIT: + enc = "7bit"; + break; + case MAILMIME_MECHANISM_8BIT: + enc = "8bit"; + break; + case MAILMIME_MECHANISM_BINARY: + enc = "binary"; + break; + case MAILMIME_MECHANISM_QUOTED_PRINTABLE: + enc = "quoted-printable"; + break; + case MAILMIME_MECHANISM_BASE64: + enc = "base64"; + break; + case MAILMIME_MECHANISM_TOKEN: + default: + if (aEnc->enc_token) { + enc = QString(aEnc->enc_token); + } + break; + } + return enc; +} + +void Genericwrapper::traverseBody(RecBodyP&target,mailmessage*message,mailmime*mime,QValueList<int>recList,unsigned int current_rec,int current_count) +{ + if (current_rec >= 10) { + ; // odebug << "too deep recursion!" << oendl; + } + if (!message || !mime) { + return; + } + int r; + char*data = 0; + size_t len; + clistiter * cur = 0; + QString b; + RecPartP part = new RecPart(); + + switch (mime->mm_type) { + case MAILMIME_SINGLE: + { + QValueList<int>countlist = recList; + countlist.append(current_count); + r = mailmessage_fetch_section(message,mime,&data,&len); + part->setSize(len); + part->setPositionlist(countlist); + b = gen_attachment_id(); + part->setIdentifier(b); + fillSingleBody(part,message,mime); + if (part->Type()=="text" && target->Bodytext().isNull()) { + encodedString*rs = new encodedString(); + rs->setContent(data,len); + encodedString*res = decode_String(rs,part->Encoding()); + if (countlist.count()>2) { + bodyCache[b]=rs; + target->addPart(part); + } else { + delete rs; + } + b = QString(res->Content()); + delete res; + target->setBodytext(b); + target->setDescription(part); + } else { + bodyCache[b]=new encodedString(data,len); + target->addPart(part); + } + } + break; + case MAILMIME_MULTIPLE: + { + unsigned int ccount = 1; + mailmime*cbody=0; + QValueList<int>countlist = recList; + for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { + cbody = (mailmime*)clist_content(cur); + if (cbody->mm_type==MAILMIME_MULTIPLE) { + RecPartP targetPart = new RecPart(); + targetPart->setType("multipart"); + countlist.append(current_count); + targetPart->setPositionlist(countlist); + target->addPart(targetPart); + } + traverseBody(target,message, cbody,countlist,current_rec+1,ccount); + if (cbody->mm_type==MAILMIME_MULTIPLE) { + countlist = recList; + } + ++ccount; + } + } + break; + case MAILMIME_MESSAGE: + { + QValueList<int>countlist = recList; + countlist.append(current_count); + /* the own header is always at recursion 0 - we don't need that */ + if (current_rec > 0) { + part->setPositionlist(countlist); + r = mailmessage_fetch_section(message,mime,&data,&len); + part->setSize(len); + part->setPositionlist(countlist); + b = gen_attachment_id(); + part->setIdentifier(b); + part->setType("message"); + part->setSubtype("rfc822"); + bodyCache[b]=new encodedString(data,len); + target->addPart(part); + } + if (mime->mm_data.mm_message.mm_msg_mime != NULL) { + traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,countlist,current_rec+1); + } + } + break; + } +} + +RecBodyP Genericwrapper::parseMail( mailmessage * msg ) +{ + int err = MAILIMF_NO_ERROR; + mailmime_single_fields fields; + /* is bound to msg and will be freed there */ + mailmime * mime=0; + RecBodyP body = new RecBody(); + memset(&fields, 0, sizeof(struct mailmime_single_fields)); + err = mailmessage_get_bodystructure(msg,&mime); + QValueList<int>recList; + traverseBody(body,msg,mime,recList); + return body; +} + +QString Genericwrapper::parseDateTime( mailimf_date_time *date ) +{ + char tmp[23]; + + // snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i", + // date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone ); + snprintf( tmp, 23, "%04i-%02i-%02i %02i:%02i:%02i %+05i", + date->dt_year,date->dt_month, date->dt_day, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone ); + + return QString( tmp ); +} + +QString Genericwrapper::parseAddressList( mailimf_address_list *list ) +{ + QString result( "" ); + + bool first = true; + if (list == 0) return result; + for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) { + mailimf_address *addr = (mailimf_address *) current->data; + + if ( !first ) { + result.append( "," ); + } else { + first = false; + } + + switch ( addr->ad_type ) { + case MAILIMF_ADDRESS_MAILBOX: + result.append( parseMailbox( addr->ad_data.ad_mailbox ) ); + break; + case MAILIMF_ADDRESS_GROUP: + result.append( parseGroup( addr->ad_data.ad_group ) ); + break; + default: + ; // odebug << "Generic: unkown mailimf address type" << oendl; + break; + } + } + + return result; +} + +QString Genericwrapper::parseGroup( mailimf_group *group ) +{ + QString result( "" ); + + result.append( group->grp_display_name ); + result.append( ": " ); + + if ( group->grp_mb_list != NULL ) { + result.append( parseMailboxList( group->grp_mb_list ) ); + } + + result.append( ";" ); + + return result; +} + +QString Genericwrapper::parseMailbox( mailimf_mailbox *box ) +{ + QString result( "" ); + + if ( box->mb_display_name == NULL ) { + result.append( box->mb_addr_spec ); + } else { + result.append( convert_String(box->mb_display_name).latin1() ); + result.append( " <" ); + result.append( box->mb_addr_spec ); + result.append( ">" ); + } + + return result; +} + +QString Genericwrapper::parseMailboxList( mailimf_mailbox_list *list ) +{ + QString result( "" ); + + bool first = true; + for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) { + mailimf_mailbox *box = (mailimf_mailbox *) current->data; + + if ( !first ) { + result.append( "," ); + } else { + first = false; + } + + result.append( parseMailbox( box ) ); + } + + return result; +} + +encodedString* Genericwrapper::fetchDecodedPart(const RecMailP&,const RecPartP&part) +{ + QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part->Identifier()); + if (it==bodyCache.end()) return new encodedString(); + encodedString*t = decode_String(it.data(),part->Encoding()); + return t; +} + +encodedString* Genericwrapper::fetchRawPart(const RecMailP&,const RecPartP&part) +{ + QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part->Identifier()); + if (it==bodyCache.end()) return new encodedString(); + encodedString*t = it.data(); + return t; +} + +QString Genericwrapper::fetchTextPart(const RecMailP&mail,const RecPartP&part) +{ + encodedString*t = fetchDecodedPart(mail,part); + QString text=t->Content(); + delete t; + return text; +} + +void Genericwrapper::cleanMimeCache() +{ + QMap<QString,encodedString*>::Iterator it = bodyCache.begin(); + for (;it!=bodyCache.end();++it) { + encodedString*t = it.data(); + //it.setValue(0); + if (t) delete t; + } + bodyCache.clear(); + ; // odebug << "Genericwrapper: cache cleaned" << oendl; +} + +QStringList Genericwrapper::parseInreplies(mailimf_in_reply_to * in_replies) +{ + QStringList res; + if (!in_replies || !in_replies->mid_list) return res; + clistiter * current = 0; + for ( current = clist_begin( in_replies->mid_list ); current != NULL; current = current->next ) { + QString h((char*)current->data); + while (h.length()>0 && h[0]=='<') { + h.remove(0,1); + } + while (h.length()>0 && h[h.length()-1]=='>') { + h.remove(h.length()-1,1); + } + if (h.length()>0) { + res.append(h); + } + } + return res; +} + +void Genericwrapper::parseList(QValueList<Opie::Core::OSmartPointer<RecMail> > &target,mailsession*session,const QString&mailbox,bool mbox_as_to) +{ + int r; + mailmessage_list * env_list = 0; + r = mailsession_get_messages_list(session,&env_list); + if (r != MAIL_NO_ERROR) { + ; // odebug << "Error message list" << oendl; + return; + } + r = mailsession_get_envelopes_list(session, env_list); + if (r != MAIL_NO_ERROR) { + ; // odebug << "Error filling message list" << oendl; + if (env_list) { + mailmessage_list_free(env_list); + } + return; + } + mailimf_references * refs = 0; + mailimf_in_reply_to * in_replies = 0; + uint32_t i = 0; + for(; 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) { + //; // odebug << "could not fetch envelope of message " << i << "" << oendl; + continue; + } + RecMailP mail = new RecMail(); + mail->setWrapper(this); + mail_flags * flag_result = 0; + r = mailmessage_get_flags(msg,&flag_result); + if (r == MAIL_ERROR_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(msg->msg_index); + 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 (!mbox_as_to) { + if (single_fields.fld_to) + mail->setTo( parseAddressList( single_fields.fld_to->to_addr_list ) ); + } else { + mail->setTo(mailbox); + } + 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 ) ); + // crashes when accessing pop3 account? + if (single_fields.fld_message_id->mid_value) { + mail->setMsgid(QString(single_fields.fld_message_id->mid_value)); + ; // odebug << "Msgid == " << mail->Msgid().latin1() << "" << oendl; + } + + if (single_fields.fld_reply_to) { + QStringList t = parseAddressList(single_fields.fld_reply_to->rt_addr_list); + if (t.count()>0) { + mail->setReplyto(t[0]); + } + } +#if 0 + 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)); + } +#endif + if (single_fields.fld_in_reply_to && single_fields.fld_in_reply_to->mid_list && + clist_count(single_fields.fld_in_reply_to->mid_list)) { + mail->setInreply(parseInreplies(single_fields.fld_in_reply_to)); + } + target.append(mail); + } + if (env_list) { + mailmessage_list_free(env_list); + } +} diff --git a/kmicromail/libmailwrapper/genericwrapper.h b/kmicromail/libmailwrapper/genericwrapper.h new file mode 100644 index 0000000..8be9212 --- a/dev/null +++ b/kmicromail/libmailwrapper/genericwrapper.h @@ -0,0 +1,67 @@ +#ifndef __GENERIC_WRAPPER_H +#define __GENERIC_WRAPPER_H + +#include "abstractmail.h" +#include <qmap.h> +#include <qstring.h> +#include <libetpan/clist.h> + +class RecMail; +class RecBody; +class encodedString; +struct mailpop3; +struct mailmessage; +struct mailmime; +struct mailmime_mechanism; +struct mailimf_mailbox_list; +struct mailimf_mailbox; +struct mailimf_date_time; +struct mailimf_group; +struct mailimf_address_list; +struct mailsession; +struct mailstorage; +struct mailfolder; +struct mailimf_in_reply_to; + +/* this class hold just the funs shared between + * mbox and pop3 (later mh, too) mail access. + * it is not desigend to make a instance of it! + */ +class Genericwrapper : public AbstractMail +{ + Q_OBJECT +public: + Genericwrapper(); + virtual ~Genericwrapper(); + + virtual encodedString* fetchDecodedPart(const RecMailP&mail,const RecPartP&part); + virtual encodedString* fetchRawPart(const RecMailP&mail,const RecPartP&part); + virtual QString fetchTextPart(const RecMailP&mail,const RecPartP&part); + virtual void cleanMimeCache(); + virtual int deleteMbox(const Opie::Core::OSmartPointer<Folder>&){return 1;} + virtual void logout(){}; + virtual void storeMessage(const char*msg,size_t length, const QString&folder){}; + +protected: + RecBodyP parseMail( mailmessage * msg ); + QString parseMailboxList( mailimf_mailbox_list *list ); + QString parseMailbox( mailimf_mailbox *box ); + QString parseGroup( mailimf_group *group ); + QString parseAddressList( mailimf_address_list *list ); + QString parseDateTime( mailimf_date_time *date ); + + void traverseBody(RecBodyP&target,mailmessage*message,mailmime*mime,QValueList<int>recList,unsigned int current_rek=0,int current_count=1); + static void fillSingleBody(RecPartP&target,mailmessage*message,mailmime*mime); + static void fillParameters(RecPartP&target,clist*parameters); + static QString getencoding(mailmime_mechanism*aEnc); + virtual void parseList(QValueList<Opie::Core::OSmartPointer<RecMail> > &target,mailsession*session,const QString&mailbox,bool mbox_as_to=false); + QStringList parseInreplies(mailimf_in_reply_to * in_replies); + + QString msgTempName; + unsigned int last_msg_id; + QMap<QString,encodedString*> bodyCache; + mailstorage * m_storage; + mailfolder*m_folder; +}; + +#endif diff --git a/kmicromail/libmailwrapper/imapwrapper.cpp b/kmicromail/libmailwrapper/imapwrapper.cpp new file mode 100644 index 0000000..e0fb6f9 --- a/dev/null +++ b/kmicromail/libmailwrapper/imapwrapper.cpp @@ -0,0 +1,1182 @@ +#include <stdlib.h> +#include <libetpan/libetpan.h> +#include <qpe/global.h> +#include <qapplication.h> +#include "imapwrapper.h" +#include "mailtypes.h" +#include "logindialog.h" + +using namespace Opie::Core; +IMAPwrapper::IMAPwrapper( IMAPaccount *a ) + : AbstractMail() +{ + account = a; + m_imap = 0; + m_Lastmbox = ""; +} + +IMAPwrapper::~IMAPwrapper() +{ + logout(); +} + +/* to avoid to often select statements in loops etc. + we trust that we are logged in and connection is established!*/ +int IMAPwrapper::selectMbox(const QString&mbox) +{ + if (mbox == m_Lastmbox) { + return MAILIMAP_NO_ERROR; + } + int err = mailimap_select( m_imap, (char*)mbox.latin1()); + if ( err != MAILIMAP_NO_ERROR ) { + m_Lastmbox = ""; + return err; + } + m_Lastmbox = mbox; + return err; +} + +void IMAPwrapper::imap_progress( size_t current, size_t maximum ) +{ + qApp->processEvents(); + qDebug("imap progress %d of %d ",current,maximum ); +} + +bool IMAPwrapper::start_tls(bool force_tls) +{ + int err; + bool try_tls; + mailimap_capability_data * cap_data = 0; + + err = mailimap_capability(m_imap,&cap_data); + if (err != MAILIMAP_NO_ERROR) { + Global::statusMessage("error getting capabilities!"); + return false; + } + clistiter * cur; + for(cur = clist_begin(cap_data->cap_list) ; cur != NULL;cur = clist_next(cur)) { + struct mailimap_capability * cap; + cap = (struct mailimap_capability *)clist_content(cur); + if (cap->cap_type == MAILIMAP_CAPABILITY_NAME) { + if (strcasecmp(cap->cap_data.cap_name, "STARTTLS") == 0) { + try_tls = true; + break; + } + } + } + if (cap_data) { + mailimap_capability_data_free(cap_data); + } + if (try_tls) { + err = mailimap_starttls(m_imap); + if (err != MAILIMAP_NO_ERROR && force_tls) { + Global::statusMessage(tr("Server has no TLS support!")); + try_tls = false; + } else { + mailstream_low * low; + mailstream_low * new_low; + low = mailstream_get_low(m_imap->imap_stream); + if (!low) { + try_tls = false; + } else { + int fd = mailstream_low_get_fd(low); + if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) { + mailstream_low_free(low); + mailstream_set_low(m_imap->imap_stream, new_low); + } else { + try_tls = false; + } + } + } + } + return try_tls; +} + +void IMAPwrapper::login() +{ + const char *server, *user, *pass; + uint16_t port; + int err = MAILIMAP_NO_ERROR; + + if (account->getOffline()) return; + /* we are connected this moment */ + /* TODO: setup a timer holding the line or if connection closed - delete the value */ + if (m_imap) { + err = mailimap_noop(m_imap); + if (err!=MAILIMAP_NO_ERROR) { + logout(); + } else { + mailstream_flush(m_imap->imap_stream); + return; + } + } + server = account->getServer().latin1(); + port = account->getPort().toUInt(); + if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { + LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); + login.show(); + if ( QDialog::Accepted == login.exec() ) { + // ok + user = login.getUser().latin1(); + pass = login.getPassword().latin1(); + } else { + // cancel + return; + } + } else { + user = account->getUser().latin1(); + pass = account->getPassword().latin1(); + } + + m_imap = mailimap_new( 20, &imap_progress ); + + /* connect */ + bool ssl = false; + bool try_tls = false; + bool force_tls = false; + + if ( account->ConnectionType() == 2 ) { + ssl = true; + } + if (account->ConnectionType()==1) { + force_tls = true; + } + + if ( ssl ) { + qDebug("using ssl "); + err = mailimap_ssl_connect( m_imap, (char*)server, port ); + } else { + err = mailimap_socket_connect( m_imap, (char*)server, port ); + } + + if ( err != MAILIMAP_NO_ERROR && + err != MAILIMAP_NO_ERROR_AUTHENTICATED && + err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) { + QString failure = ""; + if (err == MAILIMAP_ERROR_CONNECTION_REFUSED) { + failure="Connection refused"; + } else { + failure="Unknown failure"; + } + Global::statusMessage(tr("error connecting imap server: %1").arg(failure)); + mailimap_free( m_imap ); + m_imap = 0; + return; + } + + if (!ssl) { + try_tls = start_tls(force_tls); + } + + bool ok = true; + if (force_tls && !try_tls) { + Global::statusMessage(tr("Server has no TLS support!")); + ok = false; + } + + + /* login */ + + if (ok) { + err = mailimap_login_simple( m_imap, (char*)user, (char*)pass ); + if ( err != MAILIMAP_NO_ERROR ) { + Global::statusMessage(tr("error logging in imap server: %1").arg(m_imap->imap_response)); + ok = false; + } + } + if (!ok) { + err = mailimap_close( m_imap ); + mailimap_free( m_imap ); + m_imap = 0; + } +} + +void IMAPwrapper::logout() +{ + int err = MAILIMAP_NO_ERROR; + if (!m_imap) return; + err = mailimap_logout( m_imap ); + err = mailimap_close( m_imap ); + mailimap_free( m_imap ); + m_imap = 0; + m_Lastmbox = ""; +} + +void IMAPwrapper::listMessages(const QString&mailbox,QValueList<Opie::Core::OSmartPointer<RecMail> > &target ) +{ + int err = MAILIMAP_NO_ERROR; + clist *result = 0; + clistcell *current; + mailimap_fetch_type *fetchType = 0; + mailimap_set *set = 0; + + login(); + if (!m_imap) { + return; + } + /* select mailbox READONLY for operations */ + err = selectMbox(mailbox); + if ( err != MAILIMAP_NO_ERROR ) { + return; + } + + int last = m_imap->imap_selection_info->sel_exists; + + if (last == 0) { + Global::statusMessage(tr("Mailbox has no mails")); + return; + } else { + } + + /* the range has to start at 1!!! not with 0!!!! */ + set = mailimap_set_new_interval( 1, last ); + fetchType = mailimap_fetch_type_new_fetch_att_list_empty(); + mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope()); + mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags()); + mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate()); + mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size()); + + err = mailimap_fetch( m_imap, set, fetchType, &result ); + mailimap_set_free( set ); + mailimap_fetch_type_free( fetchType ); + + QString date,subject,from; + + if ( err == MAILIMAP_NO_ERROR ) { + mailimap_msg_att * msg_att; + int i = 0; + for (current = clist_begin(result); current != 0; current=clist_next(current)) { + ++i; + msg_att = (mailimap_msg_att*)current->data; + RecMail*m = parse_list_result(msg_att); + if (m) { + m->setNumber(i); + m->setMbox(mailbox); + m->setWrapper(this); + target.append(m); + } + } + Global::statusMessage(tr("Mailbox has %1 mails").arg(target.count())); + } else { + Global::statusMessage(tr("Error fetching headers: %1").arg(m_imap->imap_response)); + } + if (result) mailimap_fetch_list_free(result); +} + +QValueList<Opie::Core::OSmartPointer<Folder> >* IMAPwrapper::listFolders() +{ + const char *path, *mask; + int err = MAILIMAP_NO_ERROR; + clist *result = 0; + clistcell *current = 0; + clistcell*cur_flag = 0; + mailimap_mbx_list_flags*bflags = 0; + + QValueList<FolderP>* folders = new QValueList<FolderP>(); + login(); + if (!m_imap) { + return folders; + } + +/* + * First we have to check for INBOX 'cause it sometimes it's not inside the path. + * We must not forget to filter them out in next loop! + * it seems like ugly code. and yes - it is ugly code. but the best way. + */ + QString temp; + mask = "INBOX" ; + mailimap_mailbox_list *list; + err = mailimap_list( m_imap, (char*)"", (char*)mask, &result ); + QString del; + bool selectable = true; + bool no_inferiors = false; + if ( err == MAILIMAP_NO_ERROR ) { + current = result->first; + for ( int i = result->count; i > 0; i-- ) { + list = (mailimap_mailbox_list *) current->data; + // it is better use the deep copy mechanism of qt itself + // instead of using strdup! + temp = list->mb_name; + del = list->mb_delimiter; + current = current->next; + if ( (bflags = list->mb_flag) ) { + selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&& + bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT); + for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) { + if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) { + no_inferiors = true; + } + } + } + folders->append( new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix())); + } + } else { + qDebug("error fetching folders: "); + + } + mailimap_list_result_free( result ); + +/* + * second stage - get the other then inbox folders + */ + mask = "*" ; + path = account->getPrefix().latin1(); + if (!path) path = ""; + err = mailimap_list( m_imap, (char*)path, (char*)mask, &result ); + if ( err == MAILIMAP_NO_ERROR ) { + current = result->first; + for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) { + no_inferiors = false; + list = (mailimap_mailbox_list *) current->data; + // it is better use the deep copy mechanism of qt itself + // instead of using strdup! + temp = list->mb_name; + if (temp.lower()=="inbox") + continue; + if (temp.lower()==account->getPrefix().lower()) + continue; + if ( (bflags = list->mb_flag) ) { + selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&& + bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT); + for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) { + if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) { + no_inferiors = true; + } + } + } + del = list->mb_delimiter; + folders->append(new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix())); + } + } else { + qDebug("error fetching folders "); + + } + if (result) mailimap_list_result_free( result ); + return folders; +} + +RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att) +{ + RecMail * m = 0; + mailimap_msg_att_item *item=0; + clistcell *current,*c,*cf; + mailimap_msg_att_dynamic*flist; + mailimap_flag_fetch*cflag; + int size; + QBitArray mFlags(7); + QStringList addresslist; + + if (!m_att) { + return m; + } + m = new RecMail(); + for (c = clist_begin(m_att->att_list); c!=NULL;c=clist_next(c) ) { + current = c; + size = 0; + item = (mailimap_msg_att_item*)current->data; + if (item->att_type!=MAILIMAP_MSG_ATT_ITEM_STATIC) { + flist = (mailimap_msg_att_dynamic*)item->att_data.att_dyn; + if (!flist->att_list) { + continue; + } + cf = flist->att_list->first; + for (cf = clist_begin(flist->att_list); cf!=NULL; cf = clist_next(cf)) { + cflag = (mailimap_flag_fetch*)cf->data; + if (cflag->fl_type==MAILIMAP_FLAG_FETCH_OTHER && cflag->fl_flag!=0) { + switch (cflag->fl_flag->fl_type) { + case MAILIMAP_FLAG_ANSWERED: /* \Answered flag */ + mFlags.setBit(FLAG_ANSWERED); + break; + case MAILIMAP_FLAG_FLAGGED: /* \Flagged flag */ + mFlags.setBit(FLAG_FLAGGED); + break; + case MAILIMAP_FLAG_DELETED: /* \Deleted flag */ + mFlags.setBit(FLAG_DELETED); + break; + case MAILIMAP_FLAG_SEEN: /* \Seen flag */ + mFlags.setBit(FLAG_SEEN); + break; + case MAILIMAP_FLAG_DRAFT: /* \Draft flag */ + mFlags.setBit(FLAG_DRAFT); + break; + case MAILIMAP_FLAG_KEYWORD: /* keyword flag */ + break; + case MAILIMAP_FLAG_EXTENSION: /* \extension flag */ + break; + default: + break; + } + } else if (cflag->fl_type==MAILIMAP_FLAG_FETCH_RECENT) { + mFlags.setBit(FLAG_RECENT); + } + } + continue; + } + if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_ENVELOPE) { + mailimap_envelope * head = item->att_data.att_static->att_data.att_env; + m->setDate(head->env_date); + m->setSubject(convert_String((const char*)head->env_subject)); + //m->setSubject(head->env_subject); + if (head->env_from!=NULL) { + addresslist = address_list_to_stringlist(head->env_from->frm_list); + if (addresslist.count()) { + m->setFrom(addresslist.first()); + } + } + if (head->env_to!=NULL) { + addresslist = address_list_to_stringlist(head->env_to->to_list); + m->setTo(addresslist); + } + if (head->env_cc!=NULL) { + addresslist = address_list_to_stringlist(head->env_cc->cc_list); + m->setCC(addresslist); + } + if (head->env_bcc!=NULL) { + addresslist = address_list_to_stringlist(head->env_bcc->bcc_list); + m->setBcc(addresslist); + } + /* reply to address, eg. email. */ + if (head->env_reply_to!=NULL) { + addresslist = address_list_to_stringlist(head->env_reply_to->rt_list); + if (addresslist.count()) { + m->setReplyto(addresslist.first()); + } + } + if (head->env_in_reply_to!=NULL) { + QString h(head->env_in_reply_to); + while (h.length()>0 && h[0]=='<') { + h.remove(0,1); + } + while (h.length()>0 && h[h.length()-1]=='>') { + h.remove(h.length()-1,1); + } + if (h.length()>0) { + m->setInreply(QStringList(h)); + } + } + if (head->env_message_id) { + m->setMsgid(QString(head->env_message_id)); + } + } else if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_INTERNALDATE) { +#if 0 + mailimap_date_time*d = item->att_data.att_static->att_data.att_internal_date; + QDateTime da(QDate(d->dt_year,d->dt_month,d->dt_day),QTime(d->dt_hour,d->dt_min,d->dt_sec)); + //odebug << "" << d->dt_year << " " << d->dt_month << " " << d->dt_day << " - " << d->dt_hour << " " << d->dt_min << " " << d->dt_sec << "" << oendl; + //odebug << da.toString() << oendl; +#endif + } else if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_RFC822_SIZE) { + size = item->att_data.att_static->att_data.att_rfc822_size; + } + } + /* msg is already deleted */ + if (mFlags.testBit(FLAG_DELETED) && m) { + delete m; + m = 0; + } + if (m) { + m->setFlags(mFlags); + m->setMsgsize(size); + } + return m; +} + +RecBodyP IMAPwrapper::fetchBody(const RecMailP&mail) +{ + RecBodyP body = new RecBody(); + const char *mb; + int err = MAILIMAP_NO_ERROR; + clist *result = 0; + clistcell *current; + mailimap_fetch_att *fetchAtt = 0; + mailimap_fetch_type *fetchType = 0; + mailimap_set *set = 0; + mailimap_body*body_desc = 0; + + mb = mail->getMbox().latin1(); + + login(); + if (!m_imap) { + return body; + } + err = selectMbox(mail->getMbox()); + if ( err != MAILIMAP_NO_ERROR ) { + return body; + } + + /* the range has to start at 1!!! not with 0!!!! */ + set = mailimap_set_new_interval( mail->getNumber(),mail->getNumber() ); + fetchAtt = mailimap_fetch_att_new_bodystructure(); + fetchType = mailimap_fetch_type_new_fetch_att(fetchAtt); + err = mailimap_fetch( m_imap, set, fetchType, &result ); + mailimap_set_free( set ); + mailimap_fetch_type_free( fetchType ); + + if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) { + mailimap_msg_att * msg_att; + msg_att = (mailimap_msg_att*)current->data; + mailimap_msg_att_item*item = (mailimap_msg_att_item*)msg_att->att_list->first->data; + QValueList<int> path; + body_desc = item->att_data.att_static->att_data.att_body; + traverseBody(mail,body_desc,body,0,path); + } else { + //odebug << "error fetching body: " << m_imap->imap_response << "" << oendl; + } + if (result) mailimap_fetch_list_free(result); + return body; +} + +QStringList IMAPwrapper::address_list_to_stringlist(clist*list) +{ + QStringList l; + QString from; + bool named_from; + clistcell *current = NULL; + mailimap_address * current_address=NULL; + if (!list) { + return l; + } + unsigned int count = 0; + for (current=clist_begin(list);current!= NULL;current=clist_next(current)) { + from = ""; + named_from = false; + current_address=(mailimap_address*)current->data; + if (current_address->ad_personal_name){ + from+=convert_String((const char*)current_address->ad_personal_name); + from+=" "; + named_from = true; + } + if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) { + from+="<"; + } + if (current_address->ad_mailbox_name) { + from+=QString(current_address->ad_mailbox_name); + from+="@"; + } + if (current_address->ad_host_name) { + from+=QString(current_address->ad_host_name); + } + if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) { + from+=">"; + } + l.append(QString(from)); + if (++count > 99) { + break; + } + } + return l; +} + +encodedString*IMAPwrapper::fetchRawPart(const RecMailP&mail,const QValueList<int>&path,bool internal_call) +{ + encodedString*res=new encodedString; + int err; + mailimap_fetch_type *fetchType; + mailimap_set *set; + clistcell*current,*cur; + mailimap_section_part * section_part = 0; + mailimap_section_spec * section_spec = 0; + mailimap_section * section = 0; + mailimap_fetch_att * fetch_att = 0; + + login(); + if (!m_imap) { + return res; + } + if (!internal_call) { + err = selectMbox(mail->getMbox()); + if ( err != MAILIMAP_NO_ERROR ) { + return res; + } + } + set = mailimap_set_new_single(mail->getNumber()); + + clist*id_list = 0; + + /* if path == empty then its a request for the whole rfc822 mail and generates + a "fetch <id> (body[])" statement on imap server */ + if (path.count()>0 ) { + id_list = clist_new(); + for (unsigned j=0; j < path.count();++j) { + uint32_t * p_id = (uint32_t *)malloc(sizeof(*p_id)); + *p_id = path[j]; + clist_append(id_list,p_id); + } + section_part = mailimap_section_part_new(id_list); + section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL); + } + + section = mailimap_section_new(section_spec); + fetch_att = mailimap_fetch_att_new_body_section(section); + fetchType = mailimap_fetch_type_new_fetch_att(fetch_att); + + clist*result = 0; + + err = mailimap_fetch( m_imap, set, fetchType, &result ); + mailimap_set_free( set ); + mailimap_fetch_type_free( fetchType ); + + if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) { + mailimap_msg_att * msg_att; + msg_att = (mailimap_msg_att*)current->data; + mailimap_msg_att_item*msg_att_item; + for(cur = clist_begin(msg_att->att_list) ; cur != NULL ; cur = clist_next(cur)) { + msg_att_item = (mailimap_msg_att_item*)clist_content(cur); + if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) { + if (msg_att_item->att_data.att_static->att_type == MAILIMAP_MSG_ATT_BODY_SECTION) { + char*text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part; + /* detach - we take over the content */ + msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; + res->setContent(text,msg_att_item->att_data.att_static->att_data.att_body_section->sec_length); + } + } + } + } else { + ;//odebug << "error fetching text: " << m_imap->imap_response << "" << oendl; + } + if (result) mailimap_fetch_list_free(result); + return res; +} + +/* current_recursion is for recursive calls. + current_count means the position inside the internal loop! */ +void IMAPwrapper::traverseBody(const RecMailP&mail,mailimap_body*body,RecBodyP&target_body, + int current_recursion,QValueList<int>recList,int current_count) +{ + if (!body || current_recursion>=10) { + return; + } + switch (body->bd_type) { + case MAILIMAP_BODY_1PART: + { + QValueList<int>countlist = recList; + countlist.append(current_count); + RecPartP currentPart = new RecPart(); + mailimap_body_type_1part*part1 = body->bd_data.bd_body_1part; + QString id(""); + currentPart->setPositionlist(countlist); + for (unsigned int j = 0; j < countlist.count();++j) { + id+=(j>0?" ":""); + id+=QString("%1").arg(countlist[j]); + } + //odebug << "ID = " << id.latin1() << "" << oendl; + currentPart->setIdentifier(id); + fillSinglePart(currentPart,part1); + /* important: Check for is NULL 'cause a body can be empty! + And we put it only into the mail if it is the FIRST part */ + if (part1->bd_type==MAILIMAP_BODY_TYPE_1PART_TEXT && target_body->Bodytext().isNull() && countlist[0]==1) { + QString body_text = fetchTextPart(mail,countlist,true,currentPart->Encoding()); + target_body->setDescription(currentPart); + target_body->setBodytext(body_text); + if (countlist.count()>1) { + target_body->addPart(currentPart); + } + } else { + target_body->addPart(currentPart); + } + if (part1->bd_type==MAILIMAP_BODY_TYPE_1PART_MSG) { + traverseBody(mail,part1->bd_data.bd_type_msg->bd_body,target_body,current_recursion+1,countlist); + } + } + break; + case MAILIMAP_BODY_MPART: + { + QValueList<int>countlist = recList; + clistcell*current=0; + mailimap_body*current_body=0; + unsigned int ccount = 1; + mailimap_body_type_mpart*mailDescription = body->bd_data.bd_body_mpart; + for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) { + current_body = (mailimap_body*)current->data; + if (current_body->bd_type==MAILIMAP_BODY_MPART) { + RecPartP targetPart = new RecPart(); + targetPart->setType("multipart"); + fillMultiPart(targetPart,mailDescription); + countlist.append(current_count); + targetPart->setPositionlist(countlist); + target_body->addPart(targetPart); + QString id(""); + for (unsigned int j = 0; j < countlist.count();++j) { + id+=(j>0?" ":""); + id+=QString("%1").arg(countlist[j]); + } + // odebug << "ID(mpart) = " << id.latin1() << "" << oendl; + } + traverseBody(mail,current_body,target_body,current_recursion+1,countlist,ccount); + if (current_body->bd_type==MAILIMAP_BODY_MPART) { + countlist = recList; + } + ++ccount; + } + } + break; + default: + break; + } +} + +void IMAPwrapper::fillSinglePart(RecPartP&target_part,mailimap_body_type_1part*Description) +{ + if (!Description) { + return; + } + switch (Description->bd_type) { + case MAILIMAP_BODY_TYPE_1PART_TEXT: + target_part->setType("text"); + fillSingleTextPart(target_part,Description->bd_data.bd_type_text); + break; + case MAILIMAP_BODY_TYPE_1PART_BASIC: + fillSingleBasicPart(target_part,Description->bd_data.bd_type_basic); + break; + case MAILIMAP_BODY_TYPE_1PART_MSG: + target_part->setType("message"); + fillSingleMsgPart(target_part,Description->bd_data.bd_type_msg); + break; + default: + break; + } +} + +void IMAPwrapper::fillSingleTextPart(RecPartP&target_part,mailimap_body_type_text*which) +{ + if (!which) { + return; + } + QString sub; + sub = which->bd_media_text; + //odebug << "Type= text/" << which->bd_media_text << "" << oendl; + target_part->setSubtype(sub.lower()); + target_part->setLines(which->bd_lines); + fillBodyFields(target_part,which->bd_fields); +} + +void IMAPwrapper::fillSingleMsgPart(RecPartP&target_part,mailimap_body_type_msg*which) +{ + if (!which) { + return; + } + target_part->setSubtype("rfc822"); + //odebug << "Message part" << oendl; + /* we set this type to text/plain */ + target_part->setLines(which->bd_lines); + fillBodyFields(target_part,which->bd_fields); +} + +void IMAPwrapper::fillMultiPart(RecPartP&target_part,mailimap_body_type_mpart*which) +{ + if (!which) return; + QString sub = which->bd_media_subtype; + target_part->setSubtype(sub.lower()); + if (which->bd_ext_mpart && which->bd_ext_mpart->bd_parameter && which->bd_ext_mpart->bd_parameter->pa_list) { + clistcell*cur = 0; + mailimap_single_body_fld_param*param=0; + for (cur = clist_begin(which->bd_ext_mpart->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) { + param = (mailimap_single_body_fld_param*)cur->data; + if (param) { + target_part->addParameter(QString(param->pa_name).lower(),QString(param->pa_value)); + } + } + } +} + +void IMAPwrapper::fillSingleBasicPart(RecPartP&target_part,mailimap_body_type_basic*which) +{ + if (!which) { + return; + } + QString type,sub; + switch (which->bd_media_basic->med_type) { + case MAILIMAP_MEDIA_BASIC_APPLICATION: + type = "application"; + break; + case MAILIMAP_MEDIA_BASIC_AUDIO: + type = "audio"; + break; + case MAILIMAP_MEDIA_BASIC_IMAGE: + type = "image"; + break; + case MAILIMAP_MEDIA_BASIC_MESSAGE: + type = "message"; + break; + case MAILIMAP_MEDIA_BASIC_VIDEO: + type = "video"; + break; + case MAILIMAP_MEDIA_BASIC_OTHER: + default: + if (which->bd_media_basic->med_basic_type) { + type = which->bd_media_basic->med_basic_type; + } else { + type = ""; + } + break; + } + if (which->bd_media_basic->med_subtype) { + sub = which->bd_media_basic->med_subtype; + } else { + sub = ""; + } + // odebug << "Type = " << type.latin1() << "/" << sub.latin1() << "" << oendl; + target_part->setType(type.lower()); + target_part->setSubtype(sub.lower()); + fillBodyFields(target_part,which->bd_fields); +} + +void IMAPwrapper::fillBodyFields(RecPartP&target_part,mailimap_body_fields*which) +{ + if (!which) return; + if (which->bd_parameter && which->bd_parameter->pa_list && which->bd_parameter->pa_list->count>0) { + clistcell*cur; + mailimap_single_body_fld_param*param=0; + for (cur = clist_begin(which->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) { + param = (mailimap_single_body_fld_param*)cur->data; + if (param) { + target_part->addParameter(QString(param->pa_name).lower(),QString(param->pa_value)); + } + } + } + mailimap_body_fld_enc*enc = which->bd_encoding; + QString encoding(""); + switch (enc->enc_type) { + case MAILIMAP_BODY_FLD_ENC_7BIT: + encoding = "7bit"; + break; + case MAILIMAP_BODY_FLD_ENC_8BIT: + encoding = "8bit"; + break; + case MAILIMAP_BODY_FLD_ENC_BINARY: + encoding="binary"; + break; + case MAILIMAP_BODY_FLD_ENC_BASE64: + encoding="base64"; + break; + case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE: + encoding="quoted-printable"; + break; + case MAILIMAP_BODY_FLD_ENC_OTHER: + default: + if (enc->enc_value) { + char*t=enc->enc_value; + encoding=QString(enc->enc_value); + enc->enc_value=0L; + free(t); + } + } + if (which->bd_description) { + target_part->setDescription(QString(which->bd_description)); + } + target_part->setEncoding(encoding); + target_part->setSize(which->bd_size); +} + +void IMAPwrapper::deleteMail(const RecMailP&mail) +{ + mailimap_flag_list*flist; + mailimap_set *set; + mailimap_store_att_flags * store_flags; + int err; + login(); + if (!m_imap) { + return; + } + err = selectMbox(mail->getMbox()); + if ( err != MAILIMAP_NO_ERROR ) { + return; + } + flist = mailimap_flag_list_new_empty(); + mailimap_flag_list_add(flist,mailimap_flag_new_deleted()); + store_flags = mailimap_store_att_flags_new_set_flags(flist); + set = mailimap_set_new_single(mail->getNumber()); + err = mailimap_store(m_imap,set,store_flags); + mailimap_set_free( set ); + mailimap_store_att_flags_free(store_flags); + + if (err != MAILIMAP_NO_ERROR) { + // odebug << "error deleting mail: " << m_imap->imap_response << "" << oendl; + return; + } + // odebug << "deleting mail: " << m_imap->imap_response << "" << oendl; + /* should we realy do that at this moment? */ + err = mailimap_expunge(m_imap); + if (err != MAILIMAP_NO_ERROR) { + // odebug << "error deleting mail: " << m_imap->imap_response << "" << oendl; + } + // odebug << "Delete successfull " << m_imap->imap_response << "" << oendl; +} + +void IMAPwrapper::answeredMail(const RecMailP&mail) +{ + mailimap_flag_list*flist; + mailimap_set *set; + mailimap_store_att_flags * store_flags; + int err; + login(); + if (!m_imap) { + return; + } + err = selectMbox(mail->getMbox()); + if ( err != MAILIMAP_NO_ERROR ) { + return; + } + flist = mailimap_flag_list_new_empty(); + mailimap_flag_list_add(flist,mailimap_flag_new_answered()); + store_flags = mailimap_store_att_flags_new_add_flags(flist); + set = mailimap_set_new_single(mail->getNumber()); + err = mailimap_store(m_imap,set,store_flags); + mailimap_set_free( set ); + mailimap_store_att_flags_free(store_flags); + + if (err != MAILIMAP_NO_ERROR) { + // odebug << "error marking mail: " << m_imap->imap_response << "" << oendl; + return; + } +} + +QString IMAPwrapper::fetchTextPart(const RecMailP&mail,const QValueList<int>&path,bool internal_call,const QString&enc) +{ + QString body(""); + encodedString*res = fetchRawPart(mail,path,internal_call); + encodedString*r = decode_String(res,enc); + delete res; + if (r) { + if (r->Length()>0) { + body = r->Content(); + } + delete r; + } + return body; +} + +QString IMAPwrapper::fetchTextPart(const RecMailP&mail,const RecPartP&part) +{ + return fetchTextPart(mail,part->Positionlist(),false,part->Encoding()); +} + +encodedString* IMAPwrapper::fetchDecodedPart(const RecMailP&mail,const RecPartP&part) +{ + encodedString*res = fetchRawPart(mail,part->Positionlist(),false); + encodedString*r = decode_String(res,part->Encoding()); + delete res; + return r; +} + +encodedString* IMAPwrapper::fetchRawPart(const RecMailP&mail,const RecPartP&part) +{ + return fetchRawPart(mail,part->Positionlist(),false); +} + +int IMAPwrapper::deleteAllMail(const FolderP&folder) +{ + login(); + if (!m_imap) { + return 0; + } + mailimap_flag_list*flist; + mailimap_set *set; + mailimap_store_att_flags * store_flags; + int err = selectMbox(folder->getName()); + if ( err != MAILIMAP_NO_ERROR ) { + return 0; + } + + int last = m_imap->imap_selection_info->sel_exists; + if (last == 0) { + Global::statusMessage(tr("Mailbox has no mails!")); + return 0; + } + flist = mailimap_flag_list_new_empty(); + mailimap_flag_list_add(flist,mailimap_flag_new_deleted()); + store_flags = mailimap_store_att_flags_new_set_flags(flist); + set = mailimap_set_new_interval( 1, last ); + err = mailimap_store(m_imap,set,store_flags); + mailimap_set_free( set ); + mailimap_store_att_flags_free(store_flags); + if (err != MAILIMAP_NO_ERROR) { + Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response)); + return 0; + } + // odebug << "deleting mail: " << m_imap->imap_response << "" << oendl; + /* should we realy do that at this moment? */ + err = mailimap_expunge(m_imap); + if (err != MAILIMAP_NO_ERROR) { + Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response)); + return 0; + } + // odebug << "Delete successfull " << m_imap->imap_response << "" << oendl; + return 1; +} + +int IMAPwrapper::createMbox(const QString&folder,const FolderP&parentfolder,const QString& delemiter,bool getsubfolder) +{ + if (folder.length()==0) return 0; + login(); + if (!m_imap) {return 0;} + QString pre = account->getPrefix(); + if (delemiter.length()>0 && pre.findRev(delemiter)!=pre.length()-1) { + pre+=delemiter; + } + if (parentfolder) { + pre += parentfolder->getDisplayName()+delemiter; + } + pre+=folder; + if (getsubfolder) { + if (delemiter.length()>0) { + pre+=delemiter; + } else { + Global::statusMessage(tr("Cannot create folder %1 for holding subfolders").arg(pre)); + return 0; + } + } + // odebug << "Creating " << pre.latin1() << "" << oendl; + int res = mailimap_create(m_imap,pre.latin1()); + if (res != MAILIMAP_NO_ERROR) { + Global::statusMessage(tr("%1").arg(m_imap->imap_response)); + return 0; + } + return 1; +} + +int IMAPwrapper::deleteMbox(const FolderP&folder) +{ + if (!folder) return 0; + login(); + if (!m_imap) {return 0;} + int res = mailimap_delete(m_imap,folder->getName()); + if (res != MAILIMAP_NO_ERROR) { + Global::statusMessage(tr("%1").arg(m_imap->imap_response)); + return 0; + } + return 1; +} + +void IMAPwrapper::statusFolder(folderStat&target_stat,const QString & mailbox) +{ + mailimap_status_att_list * att_list =0; + mailimap_mailbox_data_status * status=0; + clistiter * cur = 0; + int r = 0; + target_stat.message_count = 0; + target_stat.message_unseen = 0; + target_stat.message_recent = 0; + login(); + if (!m_imap) { + return; + } + att_list = mailimap_status_att_list_new_empty(); + if (!att_list) return; + r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_MESSAGES); + r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_RECENT); + r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_UNSEEN); + r = mailimap_status(m_imap, mailbox.latin1(), att_list, &status); + if (r==MAILIMAP_NO_ERROR&&status->st_info_list!=0) { + for (cur = clist_begin(status->st_info_list); + cur != NULL ; cur = clist_next(cur)) { + mailimap_status_info * status_info; + status_info = (mailimap_status_info *)clist_content(cur); + switch (status_info->st_att) { + case MAILIMAP_STATUS_ATT_MESSAGES: + target_stat.message_count = status_info->st_value; + break; + case MAILIMAP_STATUS_ATT_RECENT: + target_stat.message_recent = status_info->st_value; + break; + case MAILIMAP_STATUS_ATT_UNSEEN: + target_stat.message_unseen = status_info->st_value; + break; + } + } + } else { + // odebug << "Error retrieving status" << oendl; + } + if (status) mailimap_mailbox_data_status_free(status); + if (att_list) mailimap_status_att_list_free(att_list); +} + +void IMAPwrapper::storeMessage(const char*msg,size_t length, const QString&folder) +{ + login(); + if (!m_imap) return; + if (!msg) return; + int r = mailimap_append(m_imap,(char*)folder.latin1(),0,0,msg,length); + if (r != MAILIMAP_NO_ERROR) { + Global::statusMessage("Error storing mail!"); + } +} + +MAILLIB::ATYPE IMAPwrapper::getType()const +{ + return account->getType(); +} + +const QString&IMAPwrapper::getName()const +{ + // odebug << "Get name: " << account->getAccountName().latin1() << "" << oendl; + return account->getAccountName(); +} + +encodedString* IMAPwrapper::fetchRawBody(const RecMailP&mail) +{ + // dummy + QValueList<int> path; + return fetchRawPart(mail,path,false); +} + +void IMAPwrapper::mvcpAllMails(const FolderP&fromFolder, + const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) +{ + if (targetWrapper != this) { + AbstractMail::mvcpAllMails(fromFolder,targetFolder,targetWrapper,moveit); + // odebug << "Using generic" << oendl; + return; + } + mailimap_set *set = 0; + login(); + if (!m_imap) { + return; + } + int err = selectMbox(fromFolder->getName()); + if ( err != MAILIMAP_NO_ERROR ) { + return; + } + int last = m_imap->imap_selection_info->sel_exists; + set = mailimap_set_new_interval( 1, last ); + err = mailimap_copy(m_imap,set,targetFolder.latin1()); + mailimap_set_free( set ); + if ( err != MAILIMAP_NO_ERROR ) { + QString error_msg = tr("error copy mails: %1").arg(m_imap->imap_response); + Global::statusMessage(error_msg); + // odebug << error_msg << oendl; + return; + } + if (moveit) { + deleteAllMail(fromFolder); + } +} + +void IMAPwrapper::mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) +{ + if (targetWrapper != this) { + // odebug << "Using generic" << oendl; + AbstractMail::mvcpMail(mail,targetFolder,targetWrapper,moveit); + return; + } + mailimap_set *set = 0; + login(); + if (!m_imap) { + return; + } + int err = selectMbox(mail->getMbox()); + if ( err != MAILIMAP_NO_ERROR ) { + return; + } + set = mailimap_set_new_single(mail->getNumber()); + err = mailimap_copy(m_imap,set,targetFolder.latin1()); + mailimap_set_free( set ); + if ( err != MAILIMAP_NO_ERROR ) { + QString error_msg = tr("error copy mail: %1").arg(m_imap->imap_response); + Global::statusMessage(error_msg); + // odebug << error_msg << oendl; + return; + } + if (moveit) { + deleteMail(mail); + } +} diff --git a/kmicromail/libmailwrapper/imapwrapper.h b/kmicromail/libmailwrapper/imapwrapper.h new file mode 100644 index 0000000..e56605a --- a/dev/null +++ b/kmicromail/libmailwrapper/imapwrapper.h @@ -0,0 +1,80 @@ +#ifndef __IMAPWRAPPER +#define __IMAPWRAPPER + +#include <qlist.h> +#include "mailwrapper.h" +#include "abstractmail.h" +#include <libetpan/clist.h> + +struct mailimap; +struct mailimap_body; +struct mailimap_body_type_1part; +struct mailimap_body_type_text; +struct mailimap_body_type_basic; +struct mailimap_body_type_msg; +struct mailimap_body_type_mpart; +struct mailimap_body_fields; +struct mailimap_msg_att; +class encodedString; + +class IMAPwrapper : public AbstractMail +{ + Q_OBJECT +public: + IMAPwrapper( IMAPaccount *a ); + virtual ~IMAPwrapper(); + virtual QValueList<Opie::Core::OSmartPointer<Folder> >* listFolders(); + virtual void listMessages(const QString & mailbox,QValueList<Opie::Core::OSmartPointer<RecMail> >&target ); + virtual void statusFolder(folderStat&target_stat,const QString & mailbox="INBOX"); + + virtual void deleteMail(const RecMailP&mail); + virtual void answeredMail(const RecMailP&mail); + virtual int deleteAllMail(const Opie::Core::OSmartPointer<Folder>&folder); + virtual void storeMessage(const char*msg,size_t length, const QString&folder); + virtual void mvcpAllMails(const Opie::Core::OSmartPointer<Folder>&fromFolder, + const QString&targetFolder,AbstractMail*targetWrapper,bool moveit); + virtual void mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit); + + virtual RecBodyP fetchBody(const RecMailP&mail); + virtual QString fetchTextPart(const RecMailP&mail,const RecPartP&part); + virtual encodedString* fetchDecodedPart(const RecMailP&mail,const RecPartP&part); + virtual encodedString* fetchRawPart(const RecMailP&mail,const RecPartP&part); + virtual encodedString* fetchRawBody(const RecMailP&mail); + + virtual int createMbox(const QString&,const Opie::Core::OSmartPointer<Folder>&parentfolder=0, + const QString& delemiter="/",bool getsubfolder=false); + virtual int deleteMbox(const Opie::Core::OSmartPointer<Folder>&folder); + + static void imap_progress( size_t current, size_t maximum ); + + virtual void logout(); + virtual MAILLIB::ATYPE getType()const; + virtual const QString&getName()const; + +protected: + RecMail*parse_list_result(mailimap_msg_att*); + void login(); + bool start_tls(bool force=true); + + virtual QString fetchTextPart(const RecMailP&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc=""); + virtual encodedString*fetchRawPart(const RecMailP&mail,const QValueList<int>&path,bool internal_call); + int selectMbox(const QString&mbox); + + void fillSinglePart(RecPartP&target_part,mailimap_body_type_1part*Description); + void fillSingleTextPart(RecPartP&target_part,mailimap_body_type_text*which); + void fillSingleBasicPart(RecPartP&target_part,mailimap_body_type_basic*which); + void fillSingleMsgPart(RecPartP&target_part,mailimap_body_type_msg*which); + void fillMultiPart(RecPartP&target_part,mailimap_body_type_mpart*which); + void traverseBody(const RecMailP&mail,mailimap_body*body,RecBodyP&target_body,int current_recursion,QValueList<int>recList,int current_count=1); + + /* just helpers */ + static void fillBodyFields(RecPartP&target_part,mailimap_body_fields*which); + static QStringList address_list_to_stringlist(clist*list); + + + IMAPaccount *account; + mailimap *m_imap; + QString m_Lastmbox; +}; + +#endif diff --git a/kmicromail/libmailwrapper/libmailwrapper.control b/kmicromail/libmailwrapper/libmailwrapper.control new file mode 100644 index 0000000..ec55bb3 --- a/dev/null +++ b/kmicromail/libmailwrapper/libmailwrapper.control @@ -0,0 +1,10 @@ +Package: libmailwrapper +Files: lib/libmailwrapper.so* +Priority: optional +Section: libs +Maintainer: Rajko Albrecht <alwin@handhelds.org>, Juergen Graf <jgf@handhelds.org>, Maximilian Reiß <harlekin@handhelds.org> +Architecture: arm +Version: 0.6-$SUB_VERSION +Depends: task-opie-minimal, libopiecore2, libopieui2, libetpan (>= 0.33pre) +Description: wrapper lib needed by Opie's mailer +License: LGPL diff --git a/kmicromail/libmailwrapper/libmailwrapperE.pro b/kmicromail/libmailwrapper/libmailwrapperE.pro new file mode 100644 index 0000000..a53b022 --- a/dev/null +++ b/kmicromail/libmailwrapper/libmailwrapperE.pro @@ -0,0 +1,49 @@ +TEMPLATE = lib +CONFIG += qt warn_on + +HEADERS = mailwrapper.h \ + imapwrapper.h \ + mailtypes.h \ + pop3wrapper.h \ + abstractmail.h \ + smtpwrapper.h \ + genericwrapper.h \ + mboxwrapper.h \ + settings.h \ + logindialog.h \ + sendmailprogress.h \ + statusmail.h \ + mhwrapper.h \ + nntpwrapper.h \ + generatemail.h \ + storemail.h + +SOURCES = imapwrapper.cpp \ + mailwrapper.cpp \ + mailtypes.cpp \ + pop3wrapper.cpp \ + abstractmail.cpp \ + smtpwrapper.cpp \ + genericwrapper.cpp \ + mboxwrapper.cpp \ + settings.cpp \ + logindialog.cpp \ + sendmailprogress.cpp \ + statusmail.cpp \ + mhwrapper.cpp \ + nntpwrapper.cpp \ + generatemail.cpp \ + storemail.cpp + +INTERFACES = logindialogui.ui \ + sendmailprogressui.ui + +INCLUDEPATH += ../../microkde ../../microkde/kdecore ../libetpan/include $(QPEDIR)/include +LIBS += -lssl -lcrypto + +#-lqpe -letpan + +DESTDIR = $(QPEDIR)/lib +OBJECTS_DIR = obj/$(PLATFORM) +MOC_DIR = moc/$(PLATFORM) +TARGET = kmicromailwrapper diff --git a/kmicromail/libmailwrapper/logindialog.cpp b/kmicromail/libmailwrapper/logindialog.cpp new file mode 100644 index 0000000..31b75d0 --- a/dev/null +++ b/kmicromail/libmailwrapper/logindialog.cpp @@ -0,0 +1,33 @@ +#include <qlineedit.h> + +#include "logindialog.h" + + + +//using namespace Opie::Core; + +LoginDialog::LoginDialog(const QString&user,const QString&pass, QWidget *parent, const char *name, bool modal, WFlags flags ) + : LoginDialogUI( parent, name, modal, flags ) +{ + userLine->setText( (user.isEmpty()?QString(""):user) ); + passLine->setText( (pass.isEmpty()?QString(""):pass) ); + _user = user; + _pass = pass; + + if ( user.isEmpty() ) { + userLine->setFocus(); + } else { + passLine->setFocus(); + } +} + +void LoginDialog::accept() +{ + //_user.replace( 0, _user.length(), userLine->text() ); + //_pass.replace( 0, _pass.length(), passLine->text() ); + _user = userLine->text(); + _pass = passLine->text(); + + //odebug << "User im accept: |" << _user.latin1() << "|" << oendl; + QDialog::accept(); +} diff --git a/kmicromail/libmailwrapper/logindialog.h b/kmicromail/libmailwrapper/logindialog.h new file mode 100644 index 0000000..f406f2c --- a/dev/null +++ b/kmicromail/libmailwrapper/logindialog.h @@ -0,0 +1,23 @@ +#ifndef LOGINDIALOG_H +#define LOGINDIALOG_H + +#include "logindialogui.h" + +class LoginDialog : public LoginDialogUI +{ + Q_OBJECT + +public: + LoginDialog(const QString&user,const QString&pass, QWidget *parent = 0, const char *name = 0, bool modal = false, WFlags flags = 0 ); + QString getUser() { return _user; } + QString getPassword() { return _pass; } + +protected slots: + void accept(); + +private: + QString _user, _pass; + +}; + +#endif diff --git a/kmicromail/libmailwrapper/logindialogui.ui b/kmicromail/libmailwrapper/logindialogui.ui new file mode 100644 index 0000000..565f777 --- a/dev/null +++ b/kmicromail/libmailwrapper/logindialogui.ui @@ -0,0 +1,83 @@ +<!DOCTYPE UI><UI> +<class>LoginDialogUI</class> +<widget> + <class>QDialog</class> + <property stdset="1"> + <name>name</name> + <cstring>LoginDialogUI</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>196</width> + <height>110</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Login</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <grid> + <property stdset="1"> + <name>margin</name> + <number>4</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>3</number> + </property> + <widget row="0" column="0" > + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>userLabel</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>User</string> + </property> + </widget> + <widget row="1" column="0" > + <class>QLineEdit</class> + <property stdset="1"> + <name>name</name> + <cstring>userLine</cstring> + </property> + </widget> + <widget row="3" column="0" > + <class>QLineEdit</class> + <property stdset="1"> + <name>name</name> + <cstring>passLine</cstring> + </property> + <property stdset="1"> + <name>echoMode</name> + <enum>Password</enum> + </property> + </widget> + <widget row="2" column="0" > + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>passLabel</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Password</string> + </property> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>userLine</tabstop> + <tabstop>passLine</tabstop> +</tabstops> +</UI> diff --git a/kmicromail/libmailwrapper/maildefines.h b/kmicromail/libmailwrapper/maildefines.h new file mode 100644 index 0000000..431f9ea --- a/dev/null +++ b/kmicromail/libmailwrapper/maildefines.h @@ -0,0 +1,16 @@ +#ifndef __MAILDEFINES_H +#define __MAILDEFINES_H + +namespace MAILLIB { + enum ATYPE { + A_UNDEFINED, + A_IMAP, + A_POP3, + A_SMTP, + A_MH, + A_MBOX, + A_NNTP, + }; +} + +#endif diff --git a/kmicromail/libmailwrapper/mailtypes.cpp b/kmicromail/libmailwrapper/mailtypes.cpp new file mode 100644 index 0000000..d43bdc6 --- a/dev/null +++ b/kmicromail/libmailwrapper/mailtypes.cpp @@ -0,0 +1,399 @@ +#include "mailtypes.h" + +//#include <opie2/odebug.h> + +#include <stdlib.h> + +using namespace Opie::Core; +RecMail::RecMail() + :Opie::Core::ORefCount(),subject(""),date(""),from(""),mbox(""),msg_id(""),msg_number(0),msg_size(0),msg_flags(7) +{ + init(); +} + +RecMail::RecMail(const RecMail&old) + :Opie::Core::ORefCount(),subject(""),date(""),from(""),mbox(""),msg_id(""),msg_number(0),msg_flags(7) +{ + init(); + copy_old(old); + // odebug << "Copy constructor RecMail" << oendl; +} + +RecMail::~RecMail() +{ + wrapper = 0; +} + +void RecMail::copy_old(const RecMail&old) +{ + subject = old.subject; + date = old.date; + mbox = old.mbox; + msg_id = old.msg_id; + msg_size = old.msg_size; + msg_number = old.msg_number; + from = old.from; + msg_flags = old.msg_flags; + to = old.to; + cc = old.cc; + bcc = old.bcc; + wrapper = old.wrapper; + in_reply_to = old.in_reply_to; + references = old.references; + replyto = old.replyto; +} + +void RecMail::init() +{ + to.clear(); + cc.clear(); + bcc.clear(); + in_reply_to.clear(); + references.clear(); + wrapper = 0; +} + +void RecMail::setWrapper(AbstractMail*awrapper) +{ + wrapper = awrapper; +} + +AbstractMail* RecMail::Wrapper() +{ + return wrapper; +} + +void RecMail::setTo(const QStringList&list) +{ + to = list; +} + +const QStringList&RecMail::To()const +{ + return to; +} + +void RecMail::setCC(const QStringList&list) +{ + cc = list; +} + +const QStringList&RecMail::CC()const +{ + return cc; +} + +void RecMail::setBcc(const QStringList&list) +{ + bcc = list; +} + +const QStringList& RecMail::Bcc()const +{ + return bcc; +} + +void RecMail::setInreply(const QStringList&list) +{ + in_reply_to = list; +} + +const QStringList& RecMail::Inreply()const +{ + return in_reply_to; +} + +void RecMail::setReferences(const QStringList&list) +{ + references = list; +} + +const QStringList& RecMail::References()const +{ + return references; +} + +RecPart::RecPart() + : Opie::Core::ORefCount(), + m_type(""),m_subtype(""),m_identifier(""),m_encoding(""),m_description(""),m_lines(0),m_size(0) +{ + m_Parameters.clear(); + m_poslist.clear(); +} + +RecPart::RecPart(const RecPart&old) + : Opie::Core::ORefCount(), + m_type(""),m_subtype(""),m_identifier(""),m_encoding(""),m_description(""),m_lines(0),m_size(0) +{ + m_type = old.m_type; + m_subtype = old.m_subtype; + m_identifier = old.m_identifier; + m_encoding = old.m_encoding; + m_description = old.m_description; + m_lines = old.m_lines; + m_size = old.m_size; + m_Parameters = old.m_Parameters; + m_poslist = old.m_poslist; + // odebug << "RecPart copy constructor" << oendl; +} + +RecPart::~RecPart() +{ +} + +void RecPart::setSize(unsigned int size) +{ + m_size = size; +} + +const unsigned int RecPart::Size()const +{ + return m_size; +} + +void RecPart::setLines(unsigned int lines) +{ + m_lines = lines; +} + +const unsigned int RecPart::Lines()const +{ + return m_lines; +} + +const QString& RecPart::Type()const +{ + return m_type; +} + +void RecPart::setType(const QString&type) +{ + m_type = type; +} + +const QString& RecPart::Subtype()const +{ + return m_subtype; +} + +void RecPart::setSubtype(const QString&subtype) +{ + m_subtype = subtype; +} + +const QString& RecPart::Identifier()const +{ + return m_identifier; +} + +void RecPart::setIdentifier(const QString&identifier) +{ + m_identifier = identifier; +} + +const QString& RecPart::Encoding()const +{ + return m_encoding; +} + +void RecPart::setEncoding(const QString&encoding) +{ + m_encoding = encoding; +} + +const QString& RecPart::Description()const +{ + return m_description; +} + +void RecPart::setDescription(const QString&desc) +{ + m_description = desc; +} + +void RecPart::setParameters(const part_plist_t&list) +{ + m_Parameters = list; +} + +const part_plist_t& RecPart::Parameters()const +{ + return m_Parameters; +} + +void RecPart::addParameter(const QString&key,const QString&value) +{ + m_Parameters[key]=value; +} + +const QString RecPart::searchParamter(const QString&key)const +{ + QString value(""); + part_plist_t::ConstIterator it = m_Parameters.find(key); + if (it != m_Parameters.end()) { + value = it.data(); + } + return value; +} + +void RecPart::setPositionlist(const QValueList<int>&poslist) +{ + m_poslist = poslist; +} + +const QValueList<int>& RecPart::Positionlist()const +{ + return m_poslist; +} + +RecBody::RecBody() + : Opie::Core::ORefCount(),m_BodyText(),m_description(new RecPart()) +{ + m_PartsList.clear(); +} + +RecBody::RecBody(const RecBody&old) + :Opie::Core::ORefCount(),m_BodyText(),m_PartsList(),m_description(new RecPart()) +{ + m_BodyText = old.m_BodyText; + m_PartsList = old.m_PartsList; + m_description = old.m_description; + // odebug << "Recbody copy constructor" << oendl; +} + +RecBody::~RecBody() +{ +} + +void RecBody::setBodytext(const QString&bodyText) +{ + m_BodyText = bodyText; +} + +const QString& RecBody::Bodytext()const +{ + return m_BodyText; +} + +void RecBody::setParts(const QValueList<RecPartP>&parts) +{ + m_PartsList.clear(); + m_PartsList = parts; +} + +const QValueList<RecPartP>& RecBody::Parts()const +{ + return m_PartsList; +} + +void RecBody::addPart(const RecPartP& part) +{ + m_PartsList.append(part); +} + +void RecBody::setDescription(const RecPartP&des) +{ + m_description = des; +} + +const RecPartP& RecBody::Description()const +{ + return m_description; +} + +/* handling encoded content */ +encodedString::encodedString() +{ + init(); +} + +encodedString::encodedString(const char*nContent,unsigned int nSize) +{ + init(); + setContent(nContent,nSize); +} + +encodedString::encodedString(char*nContent,unsigned int nSize) +{ + init(); + setContent(nContent,nSize); +} + +encodedString::encodedString(const encodedString&old) +{ + init(); + copy_old(old); + // odebug << "encodedeString: copy constructor!" << oendl; +} + +encodedString& encodedString::operator=(const encodedString&old) +{ + init(); + copy_old(old); + // odebug << "encodedString: assign operator!" << oendl; + return *this; +} + +encodedString::~encodedString() +{ + clean(); +} + +void encodedString::init() +{ + content = 0; + size = 0; +} + +void encodedString::clean() +{ + if (content) { + free(content); + } + content = 0; + size = 0; +} + +void encodedString::copy_old(const encodedString&old) +{ + clean(); + if (old.size>0 && old.content) { + content = (char*)malloc(old.size*sizeof(char)); + memcpy(content,old.content,size); + size = old.size; + } +} + +const char*encodedString::Content()const +{ + return content; +} + +const int encodedString::Length()const +{ + return size; +} + +void encodedString::setContent(const char*nContent,int nSize) +{ + if (nSize>0 && nContent) { + content = (char*)malloc(nSize*sizeof(char)); + memcpy(content,nContent,nSize); + size = nSize; + } +} + +void encodedString::setContent(char*nContent,int nSize) +{ + content = nContent; + size = nSize; +} + +folderStat&folderStat::operator=(const folderStat&old) +{ + message_count = old.message_count; + message_unseen = old.message_unseen; + message_recent = old.message_recent; + return *this; +} + diff --git a/kmicromail/libmailwrapper/mailtypes.h b/kmicromail/libmailwrapper/mailtypes.h new file mode 100644 index 0000000..c317880 --- a/dev/null +++ b/kmicromail/libmailwrapper/mailtypes.h @@ -0,0 +1,206 @@ +#ifndef __MAIL_TYPES_H +#define __MAIL_TYPES_H + +#define FLAG_ANSWERED 0 +#define FLAG_FLAGGED 1 +#define FLAG_DELETED 2 +#define FLAG_SEEN 3 +#define FLAG_DRAFT 4 +#define FLAG_RECENT 5 + +#include <opie2/osmartpointer.h> + +#include <qbitarray.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> +#include <qvaluelist.h> + +class AbstractMail; +/* a class to describe mails in a mailbox */ +/* Attention! + From programmers point of view it would make sense to + store the mail body into this class, too. + But: not from the point of view of the device. + Mailbodies can be real large. So we request them when + needed from the mail-wrapper class direct from the server itself + (imap) or from a file-based cache (pop3?) + So there is no interface "const QString&body()" but you should + make a request to the mailwrapper with this class as parameter to + get the body. Same words for the attachments. +*/ +class RecMail:public Opie::Core::ORefCount +{ +public: + RecMail(); + RecMail(const RecMail&old); + virtual ~RecMail(); + + const unsigned int getNumber()const{return msg_number;} + void setNumber(unsigned int number){msg_number=number;} + const QString&getDate()const{ return date; } + void setDate( const QString&a ) { date = a; } + const QString&getFrom()const{ return from; } + void setFrom( const QString&a ) { from = a; } + const QString&getSubject()const { return subject; } + void setSubject( const QString&s ) { subject = s; } + const QString&getMbox()const{return mbox;} + void setMbox(const QString&box){mbox = box;} + void setMsgid(const QString&id){msg_id=id;} + const QString&Msgid()const{return msg_id;} + void setReplyto(const QString&reply){replyto=reply;} + const QString&Replyto()const{return replyto;} + void setMsgsize(unsigned int size){msg_size = size;} + const unsigned int Msgsize()const{return msg_size;} + + + void setTo(const QStringList&list); + const QStringList&To()const; + void setCC(const QStringList&list); + const QStringList&CC()const; + void setBcc(const QStringList&list); + const QStringList&Bcc()const; + void setInreply(const QStringList&list); + const QStringList&Inreply()const; + void setReferences(const QStringList&list); + const QStringList&References()const; + + const QBitArray&getFlags()const{return msg_flags;} + void setFlags(const QBitArray&flags){msg_flags = flags;} + + void setWrapper(AbstractMail*wrapper); + AbstractMail* Wrapper(); + +protected: + QString subject,date,from,mbox,msg_id,replyto; + unsigned int msg_number,msg_size; + QBitArray msg_flags; + QStringList to,cc,bcc,in_reply_to,references; + AbstractMail*wrapper; + void init(); + void copy_old(const RecMail&old); +}; + +typedef Opie::Core::OSmartPointer<RecMail> RecMailP; +typedef QMap<QString,QString> part_plist_t; + +class RecPart:public Opie::Core::ORefCount +{ +protected: + QString m_type,m_subtype,m_identifier,m_encoding,m_description; + unsigned int m_lines,m_size; + part_plist_t m_Parameters; + /* describes the position in the mail */ + QValueList<int> m_poslist; + +public: + RecPart(); + RecPart(const RecPart&); + virtual ~RecPart(); + + const QString&Type()const; + void setType(const QString&type); + const QString&Subtype()const; + void setSubtype(const QString&subtype); + const QString&Identifier()const; + void setIdentifier(const QString&identifier); + const QString&Encoding()const; + void setEncoding(const QString&encoding); + const QString&Description()const; + void setDescription(const QString&desc); + void setLines(unsigned int lines); + const unsigned int Lines()const; + void setSize(unsigned int size); + const unsigned int Size()const; + + + void setParameters(const part_plist_t&list); + const part_plist_t&Parameters()const; + void addParameter(const QString&key,const QString&value); + const QString searchParamter(const QString&key)const; + void setPositionlist(const QValueList<int>&poslist); + const QValueList<int>& Positionlist()const; +}; + +typedef Opie::Core::OSmartPointer<RecPart> RecPartP; + +class RecBody:public Opie::Core::ORefCount +{ +protected: + QString m_BodyText; + QValueList<RecPartP> m_PartsList; + RecPartP m_description; + +public: + RecBody(); + RecBody(const RecBody&old); + virtual ~RecBody(); + void setBodytext(const QString&); + const QString& Bodytext()const; + + void setDescription(const RecPartP&des); + const RecPartP& Description()const; + + void setParts(const QValueList<RecPartP>&parts); + const QValueList<RecPartP>& Parts()const; + void addPart(const RecPartP&part); +}; + +typedef Opie::Core::OSmartPointer<RecBody> RecBodyP; + +class encodedString +{ +public: + encodedString(); + /* + creates an new content string. + it makes a deep copy of it! + */ + encodedString(const char*nContent,unsigned int length); + /* + Take over the nContent. Means: it will just copy the pointer, not the content. + so make sure: No one else frees the string, the string has allocated with + malloc for compatibility with c-based libs + */ + encodedString(char*nContent,unsigned int nSize); + /* copy construkor - makes ALWAYS a deep copy!!!! */ + encodedString(const encodedString&old); + /* assign operator - makes ALWAYS a deep copy!!!! */ + encodedString& operator=(const encodedString&old); + /* destructor - cleans the content */ + virtual ~encodedString(); + + /* returns a pointer to the content - do not delete yoursel! */ + const char*Content()const; + /* returns the lengths of the content 'cause it must not be a null-terminated string! */ + const int Length()const; + + /* + makes a deep copy of nContent! + */ + void setContent(const char*nContent,int nSize); + /* + Take over the nContent. Means: it will just copy the pointer, not the content. + so make sure: No one else frees the string, the string has allocated with + malloc for compatibility with c-based libs + */ + void setContent(char*nContent,int nSize); + +protected: + char * content; + unsigned int size; + + void init(); + void copy_old(const encodedString&old); + void clean(); +}; + +struct folderStat +{ + unsigned int message_count; + unsigned int message_unseen; + unsigned int message_recent; + folderStat&operator=(const folderStat&old); +}; + +#endif diff --git a/kmicromail/libmailwrapper/mailwrapper.cpp b/kmicromail/libmailwrapper/mailwrapper.cpp new file mode 100644 index 0000000..9400649 --- a/dev/null +++ b/kmicromail/libmailwrapper/mailwrapper.cpp @@ -0,0 +1,180 @@ +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <qdir.h> + +#include "mailwrapper.h" +//#include "logindialog.h" +//#include "defines.h" + +#define UNDEFINED 64 +#define MAXLINE 76 +#define UTF16MASK 0x03FFUL +#define UTF16SHIFT 10 +#define UTF16BASE 0x10000UL +#define UTF16HIGHSTART 0xD800UL +#define UTF16HIGHEND 0xDBFFUL +#define UTF16LOSTART 0xDC00UL +#define UTF16LOEND 0xDFFFUL + + +using namespace Opie::Core; +Attachment::Attachment( QString lnk ) +{ + doc = lnk; + size = QFileInfo( doc ).size(); + mPix = SmallIcon( "files" ); +} + +Folder::Folder(const QString&tmp_name, const QString&sep ) +{ + name = tmp_name; + nameDisplay = name; + separator = sep; + prefix = ""; +} + +Folder::~Folder() +{ +} + +const QString& Folder::Separator()const +{ + return separator; +} + +IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,bool no_inf, const QString&aprefix ) + : Folder( name,sep ),m_MaySelect(select),m_NoInferior(no_inf) +{ + // Decode IMAP foldername + nameDisplay = IMAPFolder::decodeFolderName( name ); + /* + odebug << "folder " + name + " - displayed as " + nameDisplay << oendl; + */ + prefix = aprefix; + + if (prefix.length()>0) { + if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) { + nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length()); + } + } +} + +IMAPFolder::~IMAPFolder() +{ +} + +static unsigned char base64chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; + +/** + * Decodes base64 encoded parts of the imapfolder name + * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc + */ +QString IMAPFolder::decodeFolderName( const QString &name ) +{ + unsigned char c, i, bitcount; + unsigned long ucs4, utf16, bitbuf; + unsigned char base64[256], utf8[6]; + unsigned long srcPtr = 0; + QCString dst = ""; + QCString src = name.ascii(); + + /* initialize modified base64 decoding table */ + memset(base64, UNDEFINED, sizeof(base64)); + for (i = 0; i < sizeof(base64chars); ++i) { + base64[(int)base64chars[i]] = i; + } + + /* loop until end of string */ + while (srcPtr < src.length ()) { + c = src[srcPtr++]; + /* deal with literal characters and &- */ + if (c != '&' || src[srcPtr] == '-') { + /* encode literally */ + dst += c; + /* skip over the '-' if this is an &- sequence */ + if (c == '&') + srcPtr++; + } else { + /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */ + bitbuf = 0; + bitcount = 0; + ucs4 = 0; + while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) { + ++srcPtr; + bitbuf = (bitbuf << 6) | c; + bitcount += 6; + /* enough bits for a UTF-16 character? */ + if (bitcount >= 16) { + bitcount -= 16; + utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff; + /* convert UTF16 to UCS4 */ + if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) { + ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT; + continue; + } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) { + ucs4 += utf16 - UTF16LOSTART + UTF16BASE; + } else { + ucs4 = utf16; + } + /* convert UTF-16 range of UCS4 to UTF-8 */ + if (ucs4 <= 0x7fUL) { + utf8[0] = ucs4; + i = 1; + } else if (ucs4 <= 0x7ffUL) { + utf8[0] = 0xc0 | (ucs4 >> 6); + utf8[1] = 0x80 | (ucs4 & 0x3f); + i = 2; + } else if (ucs4 <= 0xffffUL) { + utf8[0] = 0xe0 | (ucs4 >> 12); + utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f); + utf8[2] = 0x80 | (ucs4 & 0x3f); + i = 3; + } else { + utf8[0] = 0xf0 | (ucs4 >> 18); + utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f); + utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f); + utf8[3] = 0x80 | (ucs4 & 0x3f); + i = 4; + } + /* copy it */ + for (c = 0; c < i; ++c) { + dst += utf8[c]; + } + } + } + /* skip over trailing '-' in modified UTF-7 encoding */ + if (src[srcPtr] == '-') + ++srcPtr; + } + } + + return QString::fromUtf8( dst.data() ); +} + +Mail::Mail() + :Opie::Core::ORefCount(),name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("") +{ +} + +MHFolder::MHFolder(const QString&disp_name,const QString&mbox) + : Folder( disp_name,"/" ) +{ + separator = "/"; + name = mbox; + if (!disp_name.startsWith("/") && disp_name.length()>0) + name+="/"; + name+=disp_name; + if (disp_name.length()==0) { + nameDisplay = separator; + } + prefix = mbox; +} + +MHFolder::~MHFolder() +{ +} diff --git a/kmicromail/libmailwrapper/mailwrapper.h b/kmicromail/libmailwrapper/mailwrapper.h new file mode 100644 index 0000000..adfac6a --- a/dev/null +++ b/kmicromail/libmailwrapper/mailwrapper.h @@ -0,0 +1,128 @@ +#ifndef MAILWRAPPER_H +#define MAILWRAPPER_H + +#include <qpe/applnk.h> + +#include <qbitarray.h> +#include <qdatetime.h> +#include <qfileinfo.h> +#include <kiconloader.h> + +#include "settings.h" + +#include <opie2/osmartpointer.h> +/* +class Attachment +{ +public: + Attachment( DocLnk lnk ); + virtual ~Attachment(){} + const QString getFileName()const{ return doc.file(); } + const QString getName()const{ return doc.name(); } + const QString getMimeType()const{ return doc.type(); } + const QPixmap getPixmap()const{ return doc.pixmap(); } + const int getSize()const { return size; } + DocLnk getDocLnk() { return doc; } + +protected: + DocLnk doc; + int size; + +}; +*/ + +class Attachment +{ +public: + Attachment( QString lnk ); + virtual ~Attachment(){} + const QString getFileName()const{ return QFileInfo( doc ).fileName (); } + const QString getName()const{ return QFileInfo( doc ).baseName (); } + const QString getMimeType()const{ return QFileInfo( doc ).extension(false); } + const QPixmap getPixmap()const{ return mPix; } + const int getSize()const { return size; } + QString getDocLnk() { return doc; } + +protected: + QPixmap mPix; + QString doc; + int size; + +}; + +class Mail:public Opie::Core::ORefCount +{ +public: + Mail(); + /* Possible that this destructor must not be declared virtual + * 'cause it seems that it will never have some child classes. + * in this case this object will not get a virtual table -> memory and + * speed will be a little bit better? + */ + virtual ~Mail(){} + void addAttachment( Attachment *att ) { attList.append( att ); } + const QList<Attachment>& getAttachments()const { return attList; } + void removeAttachment( Attachment *att ) { attList.remove( att ); } + const QString&getName()const { return name; } + void setName( QString s ) { name = s; } + const QString&getMail()const{ return mail; } + void setMail( const QString&s ) { mail = s; } + const QString&getTo()const{ return to; } + void setTo( const QString&s ) { to = s; } + const QString&getCC()const{ return cc; } + void setCC( const QString&s ) { cc = s; } + const QString&getBCC()const { return bcc; } + void setBCC( const QString&s ) { bcc = s; } + const QString&getMessage()const { return message; } + void setMessage( const QString&s ) { message = s; } + const QString&getSubject()const { return subject; } + void setSubject( const QString&s ) { subject = s; } + const QString&getReply()const{ return reply; } + void setReply( const QString&a ) { reply = a; } + void setInreply(const QStringList&list){m_in_reply_to = list;} + const QStringList&Inreply()const{return m_in_reply_to;} + +private: + QList<Attachment> attList; + QString name, mail, to, cc, bcc, reply, subject, message; + QStringList m_in_reply_to; +}; + +class Folder:public Opie::Core::ORefCount +{ +public: + Folder( const QString&init_name,const QString&sep ); + virtual ~Folder(); + const QString&getDisplayName()const { return nameDisplay; } + const QString&getName()const { return name; } + const QString&getPrefix()const{return prefix; } + virtual bool may_select()const{return true;} + virtual bool no_inferior()const{return true;} + const QString&Separator()const; + +protected: + QString nameDisplay, name, separator,prefix; +}; + +typedef Opie::Core::OSmartPointer<Folder> FolderP; + +class MHFolder : public Folder +{ +public: + MHFolder(const QString&disp_name,const QString&mbox); + virtual ~MHFolder(); +}; + +class IMAPFolder : public Folder +{ + public: + IMAPFolder(const QString&name, const QString&sep, bool select=true,bool noinf=false,const QString&prefix="" ); + virtual ~IMAPFolder(); + virtual bool may_select()const{return m_MaySelect;} + virtual bool no_inferior()const{return m_NoInferior;} + private: + static QString decodeFolderName( const QString &name ); + bool m_MaySelect,m_NoInferior; +}; + +#endif diff --git a/kmicromail/libmailwrapper/mboxwrapper.cpp b/kmicromail/libmailwrapper/mboxwrapper.cpp new file mode 100644 index 0000000..39dd156 --- a/dev/null +++ b/kmicromail/libmailwrapper/mboxwrapper.cpp @@ -0,0 +1,338 @@ +#include "mboxwrapper.h" +#include "mailtypes.h" +#include "mailwrapper.h" +#include <libetpan/libetpan.h> +#include <qdir.h> +#include <stdlib.h> + + +#include <qpe/global.h> + +using namespace Opie::Core; +MBOXwrapper::MBOXwrapper(const QString & mbox_dir,const QString&mbox_name) + : Genericwrapper(),MBOXPath(mbox_dir),MBOXName(mbox_name) +{ + QDir dir(MBOXPath); + if (!dir.exists()) { + dir.mkdir(MBOXPath); + } +} + +MBOXwrapper::~MBOXwrapper() +{ +} + +void MBOXwrapper::listMessages(const QString & mailbox, QValueList<RecMailP> &target ) +{ + mailstorage*storage = mailstorage_new(NULL); + QString p = MBOXPath+"/"; + p+=mailbox; + + int r = mbox_mailstorage_init(storage,(char*)p.latin1(),0,0,0); + mailfolder*folder; + folder = mailfolder_new( storage,(char*)p.latin1(),NULL); + r = mailfolder_connect(folder); + if (r != MAIL_NO_ERROR) { + //odebug << "Error initializing mbox" << oendl; + mailfolder_free(folder); + mailstorage_free(storage); + return; + } + + parseList(target,folder->fld_session,mailbox); + + mailfolder_disconnect(folder); + mailfolder_free(folder); + mailstorage_free(storage); + Global::statusMessage(tr("Mailbox has %1 mail(s)").arg(target.count())); +} + +QValueList<Opie::Core::OSmartPointer<Folder> >* MBOXwrapper::listFolders() +{ + QValueList<Opie::Core::OSmartPointer<Folder> >* folders = new QValueList<Opie::Core::OSmartPointer<Folder> >(); + 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) { + FolderP inb=new Folder(*it,"/"); + folders->append(inb); + } + return folders; +} + +void MBOXwrapper::deleteMail(const RecMailP & mail) +{ + mailstorage*storage = mailstorage_new(NULL); + QString p = MBOXPath+"/"; + p+=mail->getMbox(); + int r = mbox_mailstorage_init(storage,(char*)p.latin1(),0,0,0); + mailfolder*folder; + folder = mailfolder_new( storage,(char*)p.latin1(),NULL); + r = mailfolder_connect(folder); + if (r != MAIL_NO_ERROR) { + ; // << "Error initializing mbox" << oendl; + mailfolder_free(folder); + mailstorage_free(storage); + return; + } + r = mailsession_remove_message(folder->fld_session,mail->getNumber()); + if (r != MAIL_NO_ERROR) { + ; // << "error deleting mail" << oendl; + } + mailfolder_free(folder); + mailstorage_free(storage); +} + +void MBOXwrapper::answeredMail(const RecMailP&) +{ +} + +RecBodyP MBOXwrapper::fetchBody( const RecMailP &mail ) +{ + RecBodyP body = new RecBody(); + 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,(char*)p.latin1(),0,0,0); + mailfolder*folder; + folder = mailfolder_new( storage,(char*)p.latin1(),NULL); + r = mailfolder_connect(folder); + if (r != MAIL_NO_ERROR) { + ; // << "Error initializing mbox" << oendl; + mailfolder_free(folder); + mailstorage_free(storage); + return body; + } + r = mailsession_get_message(folder->fld_session, mail->getNumber(), &msg); + if (r != MAIL_NO_ERROR) { + ; // << "Error fetching mail " << mail->getNumber() << "" << oendl; + mailfolder_free(folder); + mailstorage_free(storage); + return body; + } + r = mailmessage_fetch(msg,&data,&size); + if (r != MAIL_NO_ERROR) { + ; // << "Error fetching mail " << mail->getNumber() << "" << oendl; + 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 ) +{ + ; // << "MBOX " << current << " von " << maximum << "" << oendl; +} + +int MBOXwrapper::createMbox(const QString&folder,const FolderP&,const QString&,bool ) +{ + QString p = MBOXPath+"/"; + p+=folder; + QFileInfo fi(p); + if (fi.exists()) { + Global::statusMessage(tr("Mailbox exists.")); + return 0; + } + mailmbox_folder*f = 0; + if (mailmbox_init(p.latin1(),0,1,0,&f) != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error init folder")); + return 0; + } + if (f) mailmbox_done(f); + return 1; +} + +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) { + Global::statusMessage(tr("Error init folder")); + return; + } + r = mailmbox_append_message(f,msg,length); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error writing to message folder")); + } + mailmbox_done(f); +} + +encodedString* MBOXwrapper::fetchRawBody(const RecMailP&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,(char*)p.latin1(),0,0,0); + mailfolder*folder; + folder = mailfolder_new( storage,(char*)p.latin1(),NULL); + r = mailfolder_connect(folder); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error initializing mbox")); + mailfolder_free(folder); + mailstorage_free(storage); + return 0; + } + r = mailsession_get_message(folder->fld_session, mail->getNumber(), &msg); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error fetching mail %i").arg(mail->getNumber())); + mailfolder_free(folder); + mailstorage_free(storage); + return 0; + } + r = mailmessage_fetch(msg,&data,&size); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error fetching mail %i").arg(mail->getNumber())); + mailfolder_free(folder); + mailstorage_free(storage); + mailmessage_free(msg); + return 0; + } + encodedString*result = new encodedString(data,size); + + mailfolder_free(folder); + mailstorage_free(storage); + mailmessage_free(msg); + return result; +} + +void MBOXwrapper::deleteMails(const QString & mailbox,const QValueList<RecMailP> &target) +{ + QString p = MBOXPath+"/"; + p+=mailbox; + mailmbox_folder*f = 0; + int r = mailmbox_init(p.latin1(),0,1,0,&f); + if (r != MAIL_NO_ERROR) { + ; // << "Error init folder" << oendl; + return; + } + deleteMails(f,target); + mailmbox_done(f); +} + +void MBOXwrapper::deleteMails(mailmbox_folder*f,const QValueList<RecMailP> &target) +{ + if (!f) return; + int r; + QValueList<RecMailP>::ConstIterator it; + for (it=target.begin(); it != target.end();++it) { + r = mailmbox_delete_msg(f,(*it)->getNumber()); + if (r!=MAILMBOX_NO_ERROR) { + ; // << "error delete mail" << oendl; + } + } + r = mailmbox_expunge(f); + if (r != MAILMBOX_NO_ERROR) { + ; // << "error expunge mailbox" << oendl; + } +} + +int MBOXwrapper::deleteAllMail(const FolderP&tfolder) +{ + if (!tfolder) return 0; + QString p = MBOXPath+"/"+tfolder->getDisplayName(); + int res = 1; + + mailfolder*folder = 0; + mailmessage_list*l=0; + mailstorage*storage = mailstorage_new(NULL); + int r = mbox_mailstorage_init(storage,(char*)p.latin1(),0,0,0); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error initializing mbox")); + res = 0; + } + if (res) { + folder = mailfolder_new( storage,(char*)p.latin1(),NULL); + r = mailfolder_connect(folder); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error initializing mbox")); + res = 0; + } + } + if (res) { + r = mailsession_get_messages_list(folder->fld_session,&l); + if (r != MAIL_NO_ERROR) { + ; // << "Error message list" << oendl; + res=0; + } + } + for(unsigned int i = 0 ; l!= 0 && res==1 && i < carray_count(l->msg_tab) ; ++i) { + r = mailsession_remove_message(folder->fld_session,i+1); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error deleting mail %1").arg(i+1)); + res = 0; + break; + } + } + if (l) mailmessage_list_free(l); + if (folder) mailfolder_free(folder); + if (storage) mailstorage_free(storage); + return res; +} + +int MBOXwrapper::deleteMbox(const FolderP&tfolder) +{ + if (!tfolder) return 0; + QString p = MBOXPath+"/"+tfolder->getDisplayName(); + QFile fi(p); + if (!fi.exists()) { + Global::statusMessage(tr("Mailbox doesn't exist.")); + return 0; + } + if (!fi.remove()) { + Global::statusMessage(tr("Error deleting Mailbox.")); + return 0; + } + return 1; +} + +void MBOXwrapper::statusFolder(folderStat&target_stat,const QString & mailbox) +{ + mailfolder*folder = 0; + mailstorage*storage = mailstorage_new(NULL); + target_stat.message_count = 0; + target_stat.message_unseen = 0; + target_stat.message_recent = 0; + QString p = MBOXPath+"/"+mailbox; + QFile fi(p); + if (!fi.exists()) { + Global::statusMessage(tr("Mailbox doesn't exist.")); + return; + } + int r = mbox_mailstorage_init(storage,(char*)p.latin1(),0,0,0); + folder = mailfolder_new( storage,(char*)p.latin1(),NULL); + r = mailfolder_connect(folder); + r = mailsession_status_folder(folder->fld_session,(char*)mailbox.latin1(),&target_stat.message_count, + &target_stat.message_recent,&target_stat.message_unseen); + if (folder) mailfolder_free(folder); + if (storage) mailstorage_free(storage); +} + +MAILLIB::ATYPE MBOXwrapper::getType()const +{ + return MAILLIB::A_MBOX; +} + +const QString&MBOXwrapper::getName()const +{ + return MBOXName; +} diff --git a/kmicromail/libmailwrapper/mboxwrapper.h b/kmicromail/libmailwrapper/mboxwrapper.h new file mode 100644 index 0000000..9731b85 --- a/dev/null +++ b/kmicromail/libmailwrapper/mboxwrapper.h @@ -0,0 +1,46 @@ +#ifndef __MBOX_WRAPPER_H +#define __MBOX_WRAPPER_H + +#include "genericwrapper.h" +#include <qstring.h> + +class encodedString; +struct mailmbox_folder; + +class MBOXwrapper : public Genericwrapper +{ + Q_OBJECT + +public: + MBOXwrapper(const QString & dir,const QString&name); + virtual ~MBOXwrapper(); + + virtual void listMessages(const QString & mailbox, QValueList<RecMailP>&target ); + virtual QValueList<Opie::Core::OSmartPointer<Folder> >* listFolders(); + virtual void statusFolder(folderStat&target_stat,const QString & mailbox="INBOX"); + + virtual void deleteMail(const RecMailP&mail); + virtual void answeredMail(const RecMailP&mail); + + virtual int createMbox(const QString&folder,const Opie::Core::OSmartPointer<Folder>&f=0, + const QString&d="",bool s=false); + virtual int deleteMbox(const Opie::Core::OSmartPointer<Folder>&); + + virtual void storeMessage(const char*msg,size_t length, const QString&folder); + + virtual RecBodyP fetchBody( const RecMailP &mail ); + static void mbox_progress( size_t current, size_t maximum ); + + virtual encodedString* fetchRawBody(const RecMailP&mail); + virtual void deleteMails(const QString & FolderName,const QValueList<RecMailP> &target); + virtual int deleteAllMail(const Opie::Core::OSmartPointer<Folder>&); + virtual MAILLIB::ATYPE getType()const; + virtual const QString&getName()const; + +protected: + static void deleteMails(mailmbox_folder*f,const QValueList<RecMailP> &target); + QString MBOXPath; + QString MBOXName; +}; + +#endif diff --git a/kmicromail/libmailwrapper/mhwrapper.cpp b/kmicromail/libmailwrapper/mhwrapper.cpp new file mode 100644 index 0000000..7ef9b32 --- a/dev/null +++ b/kmicromail/libmailwrapper/mhwrapper.cpp @@ -0,0 +1,446 @@ +#include "mhwrapper.h" +#include "mailtypes.h" +#include "mailwrapper.h" +#include <libetpan/libetpan.h> +#include <qdir.h> +#include <qmessagebox.h> +#include <stdlib.h> +#include <qpe/global.h> +#include <oprocess.h> +//#include <opie2/odebug.h> + +using namespace Opie::Core; +MHwrapper::MHwrapper(const QString & mbox_dir,const QString&mbox_name) + : Genericwrapper(),MHPath(mbox_dir),MHName(mbox_name) +{ + if (MHPath.length()>0) { + if (MHPath[MHPath.length()-1]=='/') { + MHPath=MHPath.left(MHPath.length()-1); + } + //odebug << MHPath << oendl; + QDir dir(MHPath); + if (!dir.exists()) { + dir.mkdir(MHPath); + } + init_storage(); + } +} + +void MHwrapper::init_storage() +{ + int r; + QString pre = MHPath; + if (!m_storage) { + m_storage = mailstorage_new(NULL); + r = mh_mailstorage_init(m_storage,(char*)pre.latin1(),0,0,0); + if (r != MAIL_NO_ERROR) { + qDebug(" error init storage "); + mailstorage_free(m_storage); + m_storage = 0; + return; + } + } + r = mailstorage_connect(m_storage); + if (r!=MAIL_NO_ERROR) { + qDebug("error connecting storage "); + mailstorage_free(m_storage); + m_storage = 0; + } +} + +void MHwrapper::clean_storage() +{ + if (m_storage) { + mailstorage_disconnect(m_storage); + mailstorage_free(m_storage); + m_storage = 0; + } +} + +MHwrapper::~MHwrapper() +{ + clean_storage(); +} + +void MHwrapper::listMessages(const QString & mailbox, QValueList<Opie::Core::OSmartPointer<RecMail> > &target ) +{ + init_storage(); + if (!m_storage) { + return; + } + QString f = buildPath(mailbox); + int r = mailsession_select_folder(m_storage->sto_session,(char*)f.latin1()); + if (r!=MAIL_NO_ERROR) { + qDebug("listMessages: error selecting folder! "); + return; + } + parseList(target,m_storage->sto_session,f); + Global::statusMessage(tr("Mailbox has %1 mail(s)").arg(target.count())); +} + +QValueList<Opie::Core::OSmartPointer<Folder> >* MHwrapper::listFolders() +{ + QValueList<Opie::Core::OSmartPointer<Folder> >* folders = new QValueList<Opie::Core::OSmartPointer<Folder> >(); + /* this is needed! */ + if (m_storage) mailstorage_disconnect(m_storage); + init_storage(); + if (!m_storage) { + return folders; + } + mail_list*flist = 0; + clistcell*current=0; + int r = mailsession_list_folders(m_storage->sto_session,NULL,&flist); + if (r != MAIL_NO_ERROR || !flist) { + qDebug("error getting folder list "); + return folders; + } + for (current=clist_begin(flist->mb_list);current!=0;current=clist_next(current)) { + QString t = (char*)current->data; + t.replace(0,MHPath.length(),""); + folders->append(new MHFolder(t,MHPath)); + } + mail_list_free(flist); + return folders; +} + +void MHwrapper::deleteMail(const RecMailP&mail) +{ + init_storage(); + if (!m_storage) { + return; + } + int r = mailsession_select_folder(m_storage->sto_session,(char*)mail->getMbox().latin1()); + if (r!=MAIL_NO_ERROR) { + qDebug("error selecting folder! "); + return; + } + r = mailsession_remove_message(m_storage->sto_session,mail->getNumber()); + if (r != MAIL_NO_ERROR) { + qDebug("error deleting mail "); + } +} + +void MHwrapper::answeredMail(const RecMailP&) +{ +} + +RecBodyP MHwrapper::fetchBody( const RecMailP &mail ) +{ + RecBodyP body = new RecBody(); + init_storage(); + if (!m_storage) { + return body; + } + mailmessage * msg; + char*data=0; + + /* mail should hold the complete path! */ + int r = mailsession_select_folder(m_storage->sto_session,(char*)mail->getMbox().latin1()); + if (r != MAIL_NO_ERROR) { + return body; + } + r = mailsession_get_message(m_storage->sto_session, mail->getNumber(), &msg); + if (r != MAIL_NO_ERROR) { + qDebug("Error fetching mail "); + + return body; + } + body = parseMail(msg); + mailmessage_fetch_result_free(msg,data); + return body; +} + +void MHwrapper::mbox_progress( size_t current, size_t maximum ) +{ + qDebug("MBox Progress %d of %d",current,maximum ); + //odebug << "MH " << current << " von " << maximum << "" << oendl; +} + +QString MHwrapper::buildPath(const QString&p) +{ + QString f=""; + if (p.length()==0||p=="/") + return MHPath; + if (!p.startsWith(MHPath)) { + f+=MHPath; + } + if (!p.startsWith("/")) { + f+="/"; + } + f+=p; + return f; +} + +int MHwrapper::createMbox(const QString&folder,const FolderP&pfolder,const QString&,bool ) +{ + init_storage(); + if (!m_storage) { + return 0; + } + QString f; + if (!pfolder) { + // toplevel folder + f = buildPath(folder); + } else { + f = pfolder->getName(); + f+="/"; + f+=folder; + } + + int r = mailsession_create_folder(m_storage->sto_session,(char*)f.latin1()); + if (r != MAIL_NO_ERROR) { + qDebug("error creating folder "); + return 0; + } + qDebug("Folder created "); + return 1; +} + +void MHwrapper::storeMessage(const char*msg,size_t length, const QString&Folder) +{ + init_storage(); + if (!m_storage) { + return; + } + QString f = buildPath(Folder); + int r = mailsession_select_folder(m_storage->sto_session,(char*)f.latin1()); + if (r!=MAIL_NO_ERROR) { + qDebug("error selecting folder! "); + return; + } + r = mailsession_append_message(m_storage->sto_session,(char*)msg,length); + if (r!=MAIL_NO_ERROR) { + qDebug("error storing mail "); + } + return; +} + +encodedString* MHwrapper::fetchRawBody(const RecMailP&mail) +{ + encodedString*result = 0; + init_storage(); + if (!m_storage) { + return result; + } + mailmessage * msg = 0; + char*data=0; + size_t size; + int r = mailsession_select_folder(m_storage->sto_session,(char*)mail->getMbox().latin1()); + if (r!=MAIL_NO_ERROR) { + qDebug("error selecting folder! "); + return result; + } + r = mailsession_get_message(m_storage->sto_session, mail->getNumber(), &msg); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error fetching mail %i").arg(mail->getNumber())); + return 0; + } + r = mailmessage_fetch(msg,&data,&size); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error fetching mail %i").arg(mail->getNumber())); + if (msg) mailmessage_free(msg); + return 0; + } + result = new encodedString(data,size); + if (msg) mailmessage_free(msg); + return result; +} + +void MHwrapper::deleteMails(const QString & mailbox,const QValueList<RecMailP> &target) +{ + QString f = buildPath(mailbox); + int r = mailsession_select_folder(m_storage->sto_session,(char*)f.latin1()); + if (r!=MAIL_NO_ERROR) { + qDebug("deleteMails: error selecting folder! "); + return; + } + QValueList<RecMailP>::ConstIterator it; + for (it=target.begin(); it!=target.end();++it) { + r = mailsession_remove_message(m_storage->sto_session,(*it)->getNumber()); + if (r != MAIL_NO_ERROR) { + qDebug("error deleting mail "); + break; + } + } +} + +int MHwrapper::deleteAllMail(const FolderP&tfolder) +{ + init_storage(); + if (!m_storage) { + return 0; + } + int res = 1; + if (!tfolder) return 0; + int r = mailsession_select_folder(m_storage->sto_session,(char*)tfolder->getName().latin1()); + if (r!=MAIL_NO_ERROR) { + qDebug("error selecting folder! "); + return 0; + } + mailmessage_list*l=0; + r = mailsession_get_messages_list(m_storage->sto_session,&l); + if (r != MAIL_NO_ERROR) { + qDebug("Error message list "); + res = 0; + } + unsigned j = 0; + for(unsigned int i = 0 ; l!= 0 && res==1 && i < carray_count(l->msg_tab) ; ++i) { + mailmessage * msg; + msg = (mailmessage*)carray_get(l->msg_tab, i); + j = msg->msg_index; + r = mailsession_remove_message(m_storage->sto_session,j); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error deleting mail %1").arg(i+1)); + res = 0; + break; + } + } + if (l) mailmessage_list_free(l); + return res; +} + +int MHwrapper::deleteMbox(const FolderP&tfolder) +{ + init_storage(); + if (!m_storage) { + return 0; + } + if (!tfolder) return 0; + if (tfolder->getName()=="/" || tfolder->getName().isEmpty()) return 0; + + int r = mailsession_delete_folder(m_storage->sto_session,(char*)tfolder->getName().latin1()); + + if (r != MAIL_NO_ERROR) { + qDebug("error deleting mail box "); + return 0; + } + QString cmd = "rm -rf "+tfolder->getName(); + QStringList command; + command << "/bin/sh"; + command << "-c"; + command << cmd.latin1(); + OProcess *process = new OProcess(); + + connect(process, SIGNAL(processExited(Opie::Core::OProcess*)), + this, SLOT( processEnded(Opie::Core::OProcess*))); + connect(process, SIGNAL( receivedStderr(Opie::Core::OProcess*,char*,int)), + this, SLOT( oprocessStderr(Opie::Core::OProcess*,char*,int))); + + *process << command; + removeMboxfailed = false; + if(!process->start(OProcess::Block, OProcess::All) ) { + qDebug("could not start process "); + return 0; + } + qDebug("mail box deleted "); + return 1; +} + +void MHwrapper::processEnded(OProcess *p) +{ + if (p) delete p; +} + +void MHwrapper::oprocessStderr(OProcess*, char *buffer, int ) +{ + QString lineStr = buffer; + QMessageBox::warning( 0, tr("Error"), lineStr ,tr("Ok") ); + removeMboxfailed = true; +} + +void MHwrapper::statusFolder(folderStat&target_stat,const QString & mailbox) +{ + init_storage(); + if (!m_storage) { + return; + } + target_stat.message_count = 0; + target_stat.message_unseen = 0; + target_stat.message_recent = 0; + QString f = buildPath(mailbox); + int r = mailsession_status_folder(m_storage->sto_session,(char*)f.latin1(),&target_stat.message_count, + &target_stat.message_recent,&target_stat.message_unseen); + if (r != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error retrieving status")); + } +} + +MAILLIB::ATYPE MHwrapper::getType()const +{ + return MAILLIB::A_MH; +} + +const QString&MHwrapper::getName()const +{ + return MHName; +} +void MHwrapper::mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) +{ + init_storage(); + if (!m_storage) { + return; + } + if (targetWrapper != this) { + qDebug("Using generic "); + Genericwrapper::mvcpMail(mail,targetFolder,targetWrapper,moveit); + return; + } + qDebug("Using internal routines for move/copy "); + QString tf = buildPath(targetFolder); + int r = mailsession_select_folder(m_storage->sto_session,(char*)mail->getMbox().latin1()); + if (r != MAIL_NO_ERROR) { + qDebug("Error selecting source mailbox "); + return; + } + if (moveit) { + r = mailsession_move_message(m_storage->sto_session,mail->getNumber(),(char*)tf.latin1()); + } else { + r = mailsession_copy_message(m_storage->sto_session,mail->getNumber(),(char*)tf.latin1()); + } + if (r != MAIL_NO_ERROR) { + qDebug("Error copy/moving mail internal "); + } +} + +void MHwrapper::mvcpAllMails(const FolderP&fromFolder, + const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) +{ + init_storage(); + if (!m_storage) { + return; + } + if (targetWrapper != this) { + qDebug("Using generic "); + Genericwrapper::mvcpAllMails(fromFolder,targetFolder,targetWrapper,moveit); + return; + } + if (!fromFolder) return; + int r = mailsession_select_folder(m_storage->sto_session,(char*)fromFolder->getName().latin1()); + if (r!=MAIL_NO_ERROR) { + qDebug("error selecting source folder! "); + return; + } + QString tf = buildPath(targetFolder); + mailmessage_list*l=0; + r = mailsession_get_messages_list(m_storage->sto_session,&l); + if (r != MAIL_NO_ERROR) { + qDebug("Error message list "); + } + unsigned j = 0; + for(unsigned int i = 0 ; l!= 0 && i < carray_count(l->msg_tab) ; ++i) { + mailmessage * msg; + msg = (mailmessage*)carray_get(l->msg_tab, i); + j = msg->msg_index; + if (moveit) { + r = mailsession_move_message(m_storage->sto_session,j,(char*)tf.latin1()); + } else { + r = mailsession_copy_message(m_storage->sto_session,j,(char*)tf.latin1()); + } + if (r != MAIL_NO_ERROR) { + qDebug("Error copy/moving mail interna "); + + break; + } + } + if (l) mailmessage_list_free(l); +} diff --git a/kmicromail/libmailwrapper/mhwrapper.h b/kmicromail/libmailwrapper/mhwrapper.h new file mode 100644 index 0000000..4310c84 --- a/dev/null +++ b/kmicromail/libmailwrapper/mhwrapper.h @@ -0,0 +1,60 @@ +#ifndef __MH_WRAPPER_H +#define __MH_WRAPPER_H + +#include "maildefines.h" + +#include "genericwrapper.h" +#include <qstring.h> + +class encodedString; +struct mailmbox_folder; +namespace Opie {namespace Core {class OProcess;}} + +class MHwrapper : public Genericwrapper +{ + Q_OBJECT +public: + MHwrapper(const QString & dir,const QString&name); + virtual ~MHwrapper(); + + virtual void listMessages(const QString & mailbox, QValueList<Opie::Core::OSmartPointer<RecMail> > &target ); + virtual QValueList<Opie::Core::OSmartPointer<Folder> >* listFolders(); + virtual void statusFolder(folderStat&target_stat,const QString & mailbox="INBOX"); + + virtual void deleteMail(const RecMailP&mail); + virtual void answeredMail(const RecMailP&mail); + virtual void mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit); + virtual void mvcpAllMails(const Opie::Core::OSmartPointer<Folder>&fromFolder, + const QString&targetFolder,AbstractMail*targetWrapper,bool moveit); + + virtual int createMbox(const QString&folder,const Opie::Core::OSmartPointer<Folder>&f=0, + const QString&d="",bool s=false); + virtual int deleteMbox(const Opie::Core::OSmartPointer<Folder>&); + + virtual void storeMessage(const char*msg,size_t length, const QString&folder); + + virtual RecBodyP fetchBody( const RecMailP &mail ); + static void mbox_progress( size_t current, size_t maximum ); + + virtual encodedString* fetchRawBody(const RecMailP&mail); + virtual void deleteMails(const QString & FolderName,const QValueList<Opie::Core::OSmartPointer<RecMail> > &target); + virtual int deleteAllMail(const Opie::Core::OSmartPointer<Folder>&); + virtual MAILLIB::ATYPE getType()const; + virtual const QString&getName()const; + +public slots: + /* for deleting maildirs we are using a system call */ + virtual void oprocessStderr(Opie::Core::OProcess*, char *buffer, int ); + virtual void processEnded(Opie::Core::OProcess *); +protected: + QString buildPath(const QString&p); + QString MHPath; + QString MHName; + + void init_storage(); + void clean_storage(); + + bool removeMboxfailed; +}; + +#endif diff --git a/kmicromail/libmailwrapper/nntpwrapper.cpp b/kmicromail/libmailwrapper/nntpwrapper.cpp new file mode 100644 index 0000000..daa128e --- a/dev/null +++ b/kmicromail/libmailwrapper/nntpwrapper.cpp @@ -0,0 +1,289 @@ +#include "nntpwrapper.h" +#include "logindialog.h" +#include "mailtypes.h" + +#include <qfile.h> + +#include <stdlib.h> + +#include <libetpan/libetpan.h> + + + +#define HARD_MSG_SIZE_LIMIT 5242880 + +using namespace Opie::Core; +NNTPwrapper::NNTPwrapper( NNTPaccount *a ) +: Genericwrapper() { + account = a; + m_nntp = NULL; + msgTempName = a->getFileName()+"_msg_cache"; + last_msg_id = 0; +} + +NNTPwrapper::~NNTPwrapper() { + logout(); + QFile msg_cache(msgTempName); + if (msg_cache.exists()) { + msg_cache.remove(); + } +} + +void NNTPwrapper::nntp_progress( size_t current, size_t maximum ) { + ; // << "NNTP: " << current << " of " << maximum << "" << oendl; +} + + +RecBodyP NNTPwrapper::fetchBody( const RecMailP &mail ) { + int err = NEWSNNTP_NO_ERROR; + char *message = 0; + size_t length = 0; + + RecBodyP body = new RecBody(); + login(); + if ( !m_nntp ) { + return body; + } + + mailmessage * mailmsg; + if (mail->Msgsize()>HARD_MSG_SIZE_LIMIT) { + ; // << "Message to large: " << mail->Msgsize() << "" << oendl; + return body; + } + + QFile msg_cache(msgTempName); + + cleanMimeCache(); + + if (mail->getNumber()!=last_msg_id) { + if (msg_cache.exists()) { + msg_cache.remove(); + } + msg_cache.open(IO_ReadWrite|IO_Truncate); + last_msg_id = mail->getNumber(); + err = mailsession_get_message(m_nntp->sto_session, mail->getNumber(), &mailmsg); + err = mailmessage_fetch(mailmsg,&message,&length); + msg_cache.writeBlock(message,length); + } else { + QString msg=""; + msg_cache.open(IO_ReadOnly); + message = new char[4096]; + memset(message,0,4096); + while (msg_cache.readBlock(message,4095)>0) { + msg+=message; + memset(message,0,4096); + } + delete message; + message = (char*)malloc(msg.length()+1*sizeof(char)); + memset(message,0,msg.length()+1); + memcpy(message,msg.latin1(),msg.length()); + /* transform to libetpan stuff */ + mailmsg = mailmessage_new(); + mailmessage_init(mailmsg, NULL, data_message_driver, 0, strlen(message)); + generic_message_t * msg_data; + msg_data = (generic_message_t *)mailmsg->msg_data; + msg_data->msg_fetched = 1; + msg_data->msg_message = message; + msg_data->msg_length = strlen(message); + } + body = parseMail(mailmsg); + + /* clean up */ + if (mailmsg) + mailmessage_free(mailmsg); + if (message) + free(message); + + return body; +} + + +void NNTPwrapper::listMessages(const QString & which, QValueList<Opie::Core::OSmartPointer<RecMail> > &target ) +{ + login(); + if (!m_nntp) + return; + uint32_t res_messages,res_recent,res_unseen; + mailsession_status_folder(m_nntp->sto_session,(char*)which.latin1(),&res_messages,&res_recent,&res_unseen); + parseList(target,m_nntp->sto_session,which,true); +} + +void NNTPwrapper::login() +{ + if (account->getOffline()) + return; + /* we'll hold the line */ + if ( m_nntp != NULL ) + return; + + const char *server, *user, *pass; + QString User,Pass; + uint16_t port; + int err = NEWSNNTP_NO_ERROR; + + server = account->getServer().latin1(); + port = account->getPort().toUInt(); + + user = pass = 0; + + if ( ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) && account->getLogin() ) { + LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); + login.show(); + if ( QDialog::Accepted == login.exec() ) { + // ok + User = login.getUser().latin1(); + Pass = login.getPassword().latin1(); + } else { + // cancel + ; // << "NNTP: Login canceled" << oendl; + return; + } + } else { + User = account->getUser().latin1(); + Pass = account->getPassword().latin1(); + } + + if (User.isEmpty()) { + user=0; + pass = 0; + } else { + user=User.latin1(); + pass=Pass.latin1(); + } + // bool ssl = account->getSSL(); + + m_nntp=mailstorage_new(NULL); + + int conntypeset = account->ConnectionType(); + int conntype = 0; + if ( conntypeset == 3 ) { + conntype = CONNECTION_TYPE_COMMAND; + } else if ( conntypeset == 2 ) { + conntype = CONNECTION_TYPE_TLS; + } else if ( conntypeset == 1 ) { + conntype = CONNECTION_TYPE_STARTTLS; + } else if ( conntypeset == 0 ) { + conntype = CONNECTION_TYPE_TRY_STARTTLS; + } + + nntp_mailstorage_init(m_nntp,(char*)server, port, NULL, CONNECTION_TYPE_PLAIN, NNTP_AUTH_TYPE_PLAIN, + (char*)user,(char*)pass,0,0,0); + + err = mailstorage_connect( m_nntp ); + + if (err != NEWSNNTP_NO_ERROR) { + ; // << QString( "FEHLERNUMMER %1" ).arg( err ) << oendl; + // Global::statusMessage(tr("Error initializing folder")); + mailstorage_free(m_nntp); + m_nntp = 0; + + } else { + mailsession * session = m_nntp->sto_session; + newsnntp * news = ( ( nntp_session_state_data * )session->sess_data )->nntp_session; + news->nntp_progr_fun = &nntp_progress; + } + +} + +void NNTPwrapper::logout() +{ + int err = NEWSNNTP_NO_ERROR; + if ( m_nntp == NULL ) + return; + mailstorage_free(m_nntp); + m_nntp = 0; +} + +QValueList<Opie::Core::OSmartPointer<Folder> >* NNTPwrapper::listFolders() { + + QValueList<Opie::Core::OSmartPointer<Folder> >* folders = new QValueList<Opie::Core::OSmartPointer<Folder> >(); + QStringList groups; + if (account) { + groups = account->getGroups(); + } + for ( QStringList::Iterator it = groups.begin(); it != groups.end(); ++it ) { + folders->append(new Folder((*it),".")); + } + return folders; +} + +/* we made this method in raw nntp access of etpan and not via generic interface + * 'cause in that case there will be doubled copy operations. eg. the etpan would + * copy that stuff into its own structures and we must copy it into useable c++ + * structures for our frontend. this would not make sense, so it is better to reimplement + * the stuff from generic interface of etpan but copy it direct to qt classes. + */ +QStringList NNTPwrapper::listAllNewsgroups(const QString&mask) { + login(); + QStringList res; + clist *result = 0; + clistcell *current = 0; + newsnntp_group_description *group; + + if ( m_nntp ) { + mailsession * session = m_nntp->sto_session; + newsnntp * news = ( ( nntp_session_state_data * )session->sess_data )->nntp_session; + int err = NEWSNNTP_NO_ERROR; + if (mask.isEmpty()) { + err = newsnntp_list(news, &result); + } else { + /* taken from generic wrapper of etpan */ + QString nmask = mask+".*"; + err = newsnntp_list_active(news, nmask.latin1(), &result); + } + if ( err == NEWSNNTP_NO_ERROR && result) { + for ( current=clist_begin(result);current!=NULL;current=clist_next(current) ) { + group = ( newsnntp_group_description* ) current->data; + if (!group||!group->grp_name||strlen(group->grp_name)==0) continue; + res.append(group->grp_name); + } + } + } + if (result) { + newsnntp_list_free(result); + } + return res; +} + +void NNTPwrapper::answeredMail(const RecMailP&) {} + +void NNTPwrapper::statusFolder(folderStat&target_stat,const QString&) { + login(); + target_stat.message_count = 0; + target_stat.message_unseen = 0; + target_stat.message_recent = 0; + if (!m_nntp) + return; + int r = mailsession_status_folder(m_nntp->sto_session,0,&target_stat.message_count, + &target_stat.message_recent,&target_stat.message_unseen); +} + + +encodedString* NNTPwrapper::fetchRawBody(const RecMailP&mail) { + char*target=0; + size_t length=0; + encodedString*res = 0; + mailmessage * mailmsg = 0; + int err = mailsession_get_message(m_nntp->sto_session, mail->getNumber(), &mailmsg); + err = mailmessage_fetch(mailmsg,&target,&length); + if (mailmsg) + mailmessage_free(mailmsg); + if (target) { + res = new encodedString(target,length); + } + return res; +} + +MAILLIB::ATYPE NNTPwrapper::getType()const { + return account->getType(); +} + +const QString&NNTPwrapper::getName()const{ + return account->getAccountName(); +} + +void NNTPwrapper::deleteMail(const RecMailP&) { +} + +int NNTPwrapper::deleteAllMail(const FolderP&) { +} diff --git a/kmicromail/libmailwrapper/nntpwrapper.h b/kmicromail/libmailwrapper/nntpwrapper.h new file mode 100644 index 0000000..2fb82f2 --- a/dev/null +++ b/kmicromail/libmailwrapper/nntpwrapper.h @@ -0,0 +1,48 @@ +#ifndef __NNTPWRAPPER +#define __NNTPWRAPPER + +#include "mailwrapper.h" +#include "genericwrapper.h" +#include <qstring.h> +#include <libetpan/clist.h> + +class encodedString; +struct mailstorage; +struct mailfolder; + +class NNTPwrapper : public Genericwrapper +{ + + Q_OBJECT + +public: + NNTPwrapper( NNTPaccount *a ); + virtual ~NNTPwrapper(); + + /* mailbox will be ignored */ + virtual void listMessages(const QString & mailbox, QValueList<Opie::Core::OSmartPointer<RecMail> > &target ); + /* should only get the subscribed one */ + virtual QValueList<Opie::Core::OSmartPointer<Folder> >* listFolders(); + /* mailbox will be ignored */ + virtual void statusFolder(folderStat&target_stat,const QString & mailbox="INBOX"); + QStringList listAllNewsgroups(const QString&mask = QString::null); + virtual void deleteMail(const RecMailP&mail); + virtual void answeredMail(const RecMailP&mail); + virtual int deleteAllMail(const Opie::Core::OSmartPointer<Folder>&); + + virtual RecBodyP fetchBody( const RecMailP &mail ); + virtual encodedString* fetchRawBody(const RecMailP&mail); + virtual void logout(); + virtual MAILLIB::ATYPE getType()const; + virtual const QString&getName()const; + static void nntp_progress( size_t current, size_t maximum ); + +protected: + void login(); + NNTPaccount *account; + mailstorage* m_nntp; + + +}; + +#endif diff --git a/kmicromail/libmailwrapper/pop3wrapper.cpp b/kmicromail/libmailwrapper/pop3wrapper.cpp new file mode 100644 index 0000000..e5d083a --- a/dev/null +++ b/kmicromail/libmailwrapper/pop3wrapper.cpp @@ -0,0 +1,265 @@ +#include <stdlib.h> +#include "pop3wrapper.h" +#include "mailtypes.h" +#include "logindialog.h" +#include <libetpan/libetpan.h> + + +#include <qpe/global.h> +#include <qfile.h> + +/* we don't fetch messages larger than 5 MB */ +#define HARD_MSG_SIZE_LIMIT 5242880 + +using namespace Opie::Core; +POP3wrapper::POP3wrapper( POP3account *a ) +: Genericwrapper() { + account = a; + m_pop3 = NULL; + msgTempName = a->getFileName()+"_msg_cache"; + last_msg_id = 0; +} + +POP3wrapper::~POP3wrapper() { + logout(); + QFile msg_cache(msgTempName); + if (msg_cache.exists()) { + msg_cache.remove(); + } +} + +void POP3wrapper::pop3_progress( size_t current, size_t maximum ) { + ; // odebug << "POP3: " << current << " of " << maximum << "" << oendl; +} + +RecBodyP POP3wrapper::fetchBody( const RecMailP &mail ) { + int err = MAILPOP3_NO_ERROR; + char *message = 0; + size_t length = 0; + + RecBodyP body = new RecBody(); + + login(); + if ( !m_pop3 ) { + return body; + } + + mailmessage * mailmsg; + if (mail->Msgsize()>HARD_MSG_SIZE_LIMIT) { + ; // odebug << "Message to large: " << mail->Msgsize() << "" << oendl; + return body; + } + + QFile msg_cache(msgTempName); + + cleanMimeCache(); + + if (mail->getNumber()!=last_msg_id) { + if (msg_cache.exists()) { + msg_cache.remove(); + } + msg_cache.open(IO_ReadWrite|IO_Truncate); + last_msg_id = mail->getNumber(); + err = mailsession_get_message(m_pop3->sto_session, mail->getNumber(), &mailmsg); + err = mailmessage_fetch(mailmsg,&message,&length); + msg_cache.writeBlock(message,length); + } else { + QString msg=""; + msg_cache.open(IO_ReadOnly); + message = new char[4096]; + memset(message,0,4096); + while (msg_cache.readBlock(message,4095)>0) { + msg+=message; + memset(message,0,4096); + } + delete message; + message = (char*)malloc(msg.length()+1*sizeof(char)); + memset(message,0,msg.length()+1); + memcpy(message,msg.latin1(),msg.length()); + /* transform to libetpan stuff */ + mailmsg = mailmessage_new(); + mailmessage_init(mailmsg, NULL, data_message_driver, 0, strlen(message)); + generic_message_t * msg_data; + msg_data = (generic_message_t *)mailmsg->msg_data; + msg_data->msg_fetched = 1; + msg_data->msg_message = message; + msg_data->msg_length = strlen(message); + } + body = parseMail(mailmsg); + + /* clean up */ + if (mailmsg) + mailmessage_free(mailmsg); + if (message) + free(message); + + return body; +} + +void POP3wrapper::listMessages(const QString &, QValueList<Opie::Core::OSmartPointer<RecMail> > &target ) +{ + login(); + if (!m_pop3) + return; + uint32_t res_messages,res_recent,res_unseen; + mailsession_status_folder(m_pop3->sto_session,"INBOX",&res_messages,&res_recent,&res_unseen); + parseList(target,m_pop3->sto_session,"INBOX"); + Global::statusMessage( tr("Mailbox contains %1 mail(s)").arg(res_messages)); +} + +void POP3wrapper::login() +{ + if (account->getOffline()) + return; + /* we'll hold the line */ + if ( m_pop3 != NULL ) + return; + + const char *server, *user, *pass; + uint16_t port; + int err = MAILPOP3_NO_ERROR; + + server = account->getServer().latin1(); + port = account->getPort().toUInt(); + + if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { + LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); + login.show(); + if ( QDialog::Accepted == login.exec() ) { + // ok + user = login.getUser().latin1(); + pass = login.getPassword().latin1(); + } else { + // cancel + ; // odebug << "POP3: Login canceled" << oendl; + return; + } + } else { + user = account->getUser().latin1(); + pass = account->getPassword().latin1(); + } + + // bool ssl = account->getSSL(); + + m_pop3=mailstorage_new(NULL); + + int conntypeset = account->ConnectionType(); + int conntype = 0; + if ( conntypeset == 3 ) { + conntype = CONNECTION_TYPE_COMMAND; + } else if ( conntypeset == 2 ) { + conntype = CONNECTION_TYPE_TLS; + } else if ( conntypeset == 1 ) { + conntype = CONNECTION_TYPE_STARTTLS; + } else if ( conntypeset == 0 ) { + conntype = CONNECTION_TYPE_TRY_STARTTLS; + } + + //(ssl?CONNECTION_TYPE_TLS:CONNECTION_TYPE_PLAIN); + + pop3_mailstorage_init(m_pop3,(char*)server, port, NULL, conntype, POP3_AUTH_TYPE_PLAIN, + (char*)user,(char*)pass,0,0,0); + + + err = mailstorage_connect(m_pop3); + if (err != MAIL_NO_ERROR) { + ; // odebug << QString( "FEHLERNUMMER %1" ).arg( err ) << oendl; + Global::statusMessage(tr("Error initializing folder")); + mailstorage_free(m_pop3); + m_pop3 = 0; + } else { + mailsession * session = m_pop3->sto_session; + mailpop3 * mail = ( ( pop3_session_state_data * )session->sess_data )->pop3_session; + if (mail) { + mail->pop3_progr_fun = &pop3_progress; + } + } +} + +void POP3wrapper::logout() +{ + if ( m_pop3 == NULL ) + return; + mailstorage_free(m_pop3); + m_pop3 = 0; +} + + +QValueList<Opie::Core::OSmartPointer<Folder> >* POP3wrapper::listFolders() { + QValueList<Opie::Core::OSmartPointer<Folder> >* folders = new QValueList<FolderP>(); + FolderP inb=new Folder("INBOX","/"); + folders->append(inb); + return folders; +} + +void POP3wrapper::deleteMail(const RecMailP&mail) { + login(); + if (!m_pop3) + return; + int err = mailsession_remove_message(m_pop3->sto_session,mail->getNumber()); + if (err != MAIL_NO_ERROR) { + Global::statusMessage(tr("error deleting mail")); + } +} + +void POP3wrapper::answeredMail(const RecMailP&) {} + +int POP3wrapper::deleteAllMail(const FolderP&) { + login(); + if (!m_pop3) + return 0; + int res = 1; + + uint32_t result = 0; + int err = mailsession_messages_number(m_pop3->sto_session,NULL,&result); + if (err != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error getting folder info")); + return 0; + } + for (unsigned int i = 0; i < result; ++i) { + err = mailsession_remove_message(m_pop3->sto_session,i+1); + if (err != MAIL_NO_ERROR) { + Global::statusMessage(tr("Error deleting mail %1").arg(i+1)); + res=0; + } + break; + } + return res; +} + +void POP3wrapper::statusFolder(folderStat&target_stat,const QString&) { + login(); + target_stat.message_count = 0; + target_stat.message_unseen = 0; + target_stat.message_recent = 0; + if (!m_pop3) + return; + int r = mailsession_status_folder(m_pop3->sto_session,0,&target_stat.message_count, + &target_stat.message_recent,&target_stat.message_unseen); + if (r != MAIL_NO_ERROR) { + ; // odebug << "error getting folter status." << oendl; + } +} + +encodedString* POP3wrapper::fetchRawBody(const RecMailP&mail) { + char*target=0; + size_t length=0; + encodedString*res = 0; + mailmessage * mailmsg = 0; + int err = mailsession_get_message(m_pop3->sto_session, mail->getNumber(), &mailmsg); + err = mailmessage_fetch(mailmsg,&target,&length); + if (mailmsg) + mailmessage_free(mailmsg); + if (target) { + res = new encodedString(target,length); + } + return res; +} + +MAILLIB::ATYPE POP3wrapper::getType()const { + return account->getType(); +} + +const QString&POP3wrapper::getName()const{ + return account->getAccountName(); +} diff --git a/kmicromail/libmailwrapper/pop3wrapper.h b/kmicromail/libmailwrapper/pop3wrapper.h new file mode 100644 index 0000000..5101fa5 --- a/dev/null +++ b/kmicromail/libmailwrapper/pop3wrapper.h @@ -0,0 +1,42 @@ +#ifndef __POP3WRAPPER +#define __POP3WRAPPER + +#include "mailwrapper.h" +#include "genericwrapper.h" +#include <qstring.h> + +class encodedString; +struct mailstorage; +struct mailfolder; + +class POP3wrapper : public Genericwrapper +{ + Q_OBJECT + +public: + POP3wrapper( POP3account *a ); + virtual ~POP3wrapper(); + /* mailbox will be ignored */ + virtual void listMessages(const QString & mailbox, QValueList<Opie::Core::OSmartPointer<RecMail> > &target ); + virtual QValueList<Opie::Core::OSmartPointer<Folder> >* listFolders(); + /* mailbox will be ignored */ + virtual void statusFolder(folderStat&target_stat,const QString & mailbox="INBOX"); + + virtual void deleteMail(const RecMailP&mail); + virtual void answeredMail(const RecMailP&mail); + virtual int deleteAllMail(const Opie::Core::OSmartPointer<Folder>&); + + virtual RecBodyP fetchBody( const RecMailP &mail ); + virtual encodedString* fetchRawBody(const RecMailP&mail); + virtual void logout(); + virtual MAILLIB::ATYPE getType()const; + virtual const QString&getName()const; + static void pop3_progress( size_t current, size_t maximum ); + +protected: + void login(); + POP3account *account; + mailstorage*m_pop3; +}; + +#endif diff --git a/kmicromail/libmailwrapper/sendmailprogress.cpp b/kmicromail/libmailwrapper/sendmailprogress.cpp new file mode 100644 index 0000000..dc0c75a --- a/dev/null +++ b/kmicromail/libmailwrapper/sendmailprogress.cpp @@ -0,0 +1,47 @@ +#include "sendmailprogress.h" +#include <qprogressbar.h> +#include <qlabel.h> + +progressMailSend::progressMailSend(QWidget*parent, const char * name) + :progressMailSendUI(parent,name,true),m_current_mail(0),m_current_single(0),m_max_mail(0),m_max_single(0) +{ +} + +progressMailSend::~progressMailSend() +{ +} + +void progressMailSend::setMaxMails(unsigned int aMaxMails) +{ + m_max_mail = aMaxMails; + allMailProgressBar->setTotalSteps(aMaxMails); + setMails(); +} + +void progressMailSend::setCurrentMails(unsigned int aCurrent) +{ + m_current_mail = aCurrent; + allMailProgressBar->setProgress(aCurrent); + setMails(); +} + +void progressMailSend::setSingleMail(unsigned int aCurrent,unsigned int aMax) +{ + m_current_single = aCurrent; + m_max_single = aMax; + setSingle(); +} + +void progressMailSend::setSingle() +{ + QString text = QString(tr("%1 of %2 bytes send")).arg(m_current_single).arg(m_max_single); + singleMailLabel->setText(text); + singleMailProgressBar->setTotalSteps(m_max_single); + singleMailProgressBar->setProgress(m_current_single); +} + +void progressMailSend::setMails() +{ + QString text = QString(tr("Sending mail %1 of %2")).arg(m_current_mail+1).arg(m_max_mail); + allMailLabel->setText(text); +} diff --git a/kmicromail/libmailwrapper/sendmailprogress.h b/kmicromail/libmailwrapper/sendmailprogress.h new file mode 100644 index 0000000..5b7d33b --- a/dev/null +++ b/kmicromail/libmailwrapper/sendmailprogress.h @@ -0,0 +1,19 @@ +#include "sendmailprogressui.h" + +class progressMailSend:public progressMailSendUI +{ + Q_OBJECT +public: + progressMailSend(QWidget*parent = 0, const char * name = 0); + ~progressMailSend(); + + void setMaxMails(unsigned int aMaxMails); + void setCurrentMails(unsigned int aCurrent); + + void setSingleMail(unsigned int aCurrent,unsigned int aMax); + +protected: + unsigned m_current_mail,m_current_single,m_max_mail,m_max_single; + void setSingle(); + void setMails(); +}; diff --git a/kmicromail/libmailwrapper/sendmailprogressui.ui b/kmicromail/libmailwrapper/sendmailprogressui.ui new file mode 100644 index 0000000..287ab5e --- a/dev/null +++ b/kmicromail/libmailwrapper/sendmailprogressui.ui @@ -0,0 +1,110 @@ +<!DOCTYPE UI><UI> +<class>progressMailSendUI</class> +<widget> + <class>QDialog</class> + <property stdset="1"> + <name>name</name> + <cstring>progressMailSendUI</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>221</width> + <height>127</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Sending mail</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>4</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>2</number> + </property> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>singleMailLabel</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Progress of mail</string> + </property> + <property stdset="1"> + <name>alignment</name> + <set>AlignCenter</set> + </property> + <property> + <name>hAlign</name> + </property> + </widget> + <widget> + <class>QProgressBar</class> + <property stdset="1"> + <name>name</name> + <cstring>singleMailProgressBar</cstring> + </property> + </widget> + <widget> + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>allMailLabel</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Sending mail</string> + </property> + <property stdset="1"> + <name>alignment</name> + <set>AlignCenter</set> + </property> + <property> + <name>hAlign</name> + </property> + </widget> + <widget> + <class>QProgressBar</class> + <property stdset="1"> + <name>name</name> + <cstring>allMailProgressBar</cstring> + </property> + </widget> + <spacer> + <property> + <name>name</name> + <cstring>Spacer6</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Vertical</enum> + </property> + <property stdset="1"> + <name>sizeType</name> + <enum>Expanding</enum> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> +</widget> +</UI> diff --git a/kmicromail/libmailwrapper/settings.cpp b/kmicromail/libmailwrapper/settings.cpp new file mode 100644 index 0000000..bdb2a25 --- a/dev/null +++ b/kmicromail/libmailwrapper/settings.cpp @@ -0,0 +1,440 @@ +#include <stdlib.h> +#include <qdir.h> + +//#include <opie2/odebug.h> +#include <qpe/config.h> + +#include <kstandarddirs.h> +#include "settings.h" +//#include "defines.h" + +#define IMAP_PORT "143" +#define IMAP_SSL_PORT "993" +#define SMTP_PORT "25" +#define SMTP_SSL_PORT "465" +#define POP3_PORT "110" +#define POP3_SSL_PORT "995" +#define NNTP_PORT "119" +#define NNTP_SSL_PORT "563" + + +Settings::Settings() + : QObject() +{ + updateAccounts(); +} + +void Settings::checkDirectory() +{ + qDebug("Settings::checkDirectory() "); + return; + locateLocal("data", "kmicromail" ); + /* + if ( !QDir( (QString) getenv( "HOME" ) + "/Applications/opiemail/" ).exists() ) { + system( "mkdir -p $HOME/Applications/opiemail" ); + qDebug("$HOME/Applications/opiemail created "); + } + */ +} + +QList<Account> Settings::getAccounts() +{ + return accounts; +} + +void Settings::addAccount( Account *account ) +{ + accounts.append( account ); +} + +void Settings::delAccount( Account *account ) +{ + accounts.remove( account ); + account->remove(); +} + +void Settings::updateAccounts() +{ + accounts.clear(); + QDir dir( locateLocal("data", "kmicromail" ) ); + QStringList::Iterator it; + + QStringList imap = dir.entryList( "imap-*" ); + for ( it = imap.begin(); it != imap.end(); it++ ) { + IMAPaccount *account = new IMAPaccount( (*it).replace(0, 5, "") ); + accounts.append( account ); + } + + QStringList pop3 = dir.entryList( "pop3-*" ); + for ( it = pop3.begin(); it != pop3.end(); it++ ) { + POP3account *account = new POP3account( (*it).replace(0, 5, "") ); + accounts.append( account ); + } + + QStringList smtp = dir.entryList( "smtp-*" ); + for ( it = smtp.begin(); it != smtp.end(); it++ ) { + SMTPaccount *account = new SMTPaccount( (*it).replace(0, 5, "") ); + accounts.append( account ); + } + + QStringList nntp = dir.entryList( "nntp-*" ); + for ( it = nntp.begin(); it != nntp.end(); it++ ) { + NNTPaccount *account = new NNTPaccount( (*it).replace(0, 5, "") ); + accounts.append( account ); + } + + readAccounts(); +} + +void Settings::saveAccounts() +{ + checkDirectory(); + Account *it; + + for ( it = accounts.first(); it; it = accounts.next() ) { + it->save(); + } +} + +void Settings::readAccounts() +{ + checkDirectory(); + Account *it; + + for ( it = accounts.first(); it; it = accounts.next() ) { + it->read(); + } +} + +Account::Account() +{ + accountName = "changeMe"; + type = MAILLIB::A_UNDEFINED; + ssl = false; + connectionType = 1; + offline = false; +} + +void Account::remove() +{ + QFile file( getFileName() ); + file.remove(); +} + +IMAPaccount::IMAPaccount() + : Account() +{ + file = IMAPaccount::getUniqueFileName(); + accountName = "New IMAP Account"; + ssl = false; + connectionType = 1; + type = MAILLIB::A_IMAP; + port = IMAP_PORT; +} + +IMAPaccount::IMAPaccount( QString filename ) + : Account() +{ + file = filename; + accountName = "New IMAP Account"; + ssl = false; + connectionType = 1; + type = MAILLIB::A_IMAP; + port = IMAP_PORT; +} + +QString IMAPaccount::getUniqueFileName() +{ + int num = 0; + QString unique; + + QDir dir( locateLocal("data", "kmicromail" ) ); + + QStringList imap = dir.entryList( "imap-*" ); + do { + unique.setNum( num++ ); + } while ( imap.contains( "imap-" + unique ) > 0 ); + + return unique; +} + +void IMAPaccount::read() +{ + Config *conf = new Config( getFileName(), Config::File ); + conf->setGroup( "IMAP Account" ); + accountName = conf->readEntry( "Account","" ); + if (accountName.isNull()) accountName = ""; + server = conf->readEntry( "Server","" ); + if (server.isNull()) server=""; + port = conf->readEntry( "Port","" ); + if (port.isNull()) port="143"; + connectionType = conf->readNumEntry( "ConnectionType" ); + ssl = conf->readBoolEntry( "SSL",false ); + user = conf->readEntry( "User","" ); + if (user.isNull()) user = ""; + password = conf->readEntryCrypt( "Password","" ); + if (password.isNull()) password = ""; + prefix = conf->readEntry("MailPrefix",""); + if (prefix.isNull()) prefix = ""; + offline = conf->readBoolEntry("Offline",false); + delete conf; +} + +void IMAPaccount::save() +{ + qDebug("saving %s ",getFileName().latin1() ); + Settings::checkDirectory(); + + Config *conf = new Config( getFileName(), Config::File ); + conf->setGroup( "IMAP Account" ); + conf->writeEntry( "Account", accountName ); + conf->writeEntry( "Server", server ); + conf->writeEntry( "Port", port ); + conf->writeEntry( "SSL", ssl ); + conf->writeEntry( "ConnectionType", connectionType ); + conf->writeEntry( "User", user ); + conf->writeEntryCrypt( "Password", password ); + conf->writeEntry( "MailPrefix",prefix); + conf->writeEntry( "Offline",offline); + conf->write(); + delete conf; +} + + +QString IMAPaccount::getFileName() +{ + return locateLocal("data", "kmicromail" ) +"/imap-" + file; +} + +POP3account::POP3account() + : Account() +{ + file = POP3account::getUniqueFileName(); + accountName = "New POP3 Account"; + ssl = false; + connectionType = 1; + type = MAILLIB::A_POP3; + port = POP3_PORT; +} + +POP3account::POP3account( QString filename ) + : Account() +{ + file = filename; + accountName = "New POP3 Account"; + ssl = false; + connectionType = 1; + type = MAILLIB::A_POP3; + port = POP3_PORT; +} + +QString POP3account::getUniqueFileName() +{ + int num = 0; + QString unique; + + QDir dir( locateLocal("data", "kmicromail" ) ); + + QStringList imap = dir.entryList( "pop3-*" ); + do { + unique.setNum( num++ ); + } while ( imap.contains( "pop3-" + unique ) > 0 ); + + return unique; +} + +void POP3account::read() +{ + Config *conf = new Config( getFileName(), Config::File ); + conf->setGroup( "POP3 Account" ); + accountName = conf->readEntry( "Account" ); + server = conf->readEntry( "Server" ); + port = conf->readEntry( "Port" ); + ssl = conf->readBoolEntry( "SSL" ); + connectionType = conf->readNumEntry( "ConnectionType" ); + user = conf->readEntry( "User" ); + password = conf->readEntryCrypt( "Password" ); + offline = conf->readBoolEntry("Offline",false); + delete conf; +} + +void POP3account::save() +{ + Settings::checkDirectory(); + + Config *conf = new Config( getFileName(), Config::File ); + conf->setGroup( "POP3 Account" ); + conf->writeEntry( "Account", accountName ); + conf->writeEntry( "Server", server ); + conf->writeEntry( "Port", port ); + conf->writeEntry( "SSL", ssl ); + conf->writeEntry( "ConnectionType", connectionType ); + conf->writeEntry( "User", user ); + conf->writeEntryCrypt( "Password", password ); + conf->writeEntry( "Offline",offline); + conf->write(); + delete conf; +} + + +QString POP3account::getFileName() +{ + return locateLocal("data", "kmicromail" ) +"/pop3-" + file; +} + +SMTPaccount::SMTPaccount() + : Account() +{ + file = SMTPaccount::getUniqueFileName(); + accountName = "New SMTP Account"; + ssl = false; + connectionType = 1; + login = false; + useCC = false; + useBCC = false; + useReply = false; + type = MAILLIB::A_SMTP; + port = SMTP_PORT; +} + +SMTPaccount::SMTPaccount( QString filename ) + : Account() +{ + file = filename; + accountName = "New SMTP Account"; + ssl = false; + connectionType = 1; + login = false; + type = MAILLIB::A_SMTP; + port = SMTP_PORT; +} + +QString SMTPaccount::getUniqueFileName() +{ + int num = 0; + QString unique; + + QDir dir( locateLocal("data", "kmicromail" ) ); + + QStringList imap = dir.entryList( "smtp-*" ); + do { + unique.setNum( num++ ); + } while ( imap.contains( "smtp-" + unique ) > 0 ); + + return unique; +} + +void SMTPaccount::read() +{ + Config *conf = new Config( getFileName(), Config::File ); + conf->setGroup( "SMTP Account" ); + accountName = conf->readEntry( "Account" ); + server = conf->readEntry( "Server" ); + port = conf->readEntry( "Port" ); + ssl = conf->readBoolEntry( "SSL" ); + connectionType = conf->readNumEntry( "ConnectionType" ); + login = conf->readBoolEntry( "Login" ); + user = conf->readEntry( "User" ); + password = conf->readEntryCrypt( "Password" ); + delete conf; +} + +void SMTPaccount::save() +{ + Settings::checkDirectory(); + + Config *conf = new Config( getFileName(), Config::File ); + conf->setGroup( "SMTP Account" ); + conf->writeEntry( "Account", accountName ); + conf->writeEntry( "Server", server ); + conf->writeEntry( "Port", port ); + conf->writeEntry( "SSL", ssl ); + conf->writeEntry( "ConnectionType", connectionType ); + conf->writeEntry( "Login", login ); + conf->writeEntry( "User", user ); + conf->writeEntryCrypt( "Password", password ); + conf->write(); + delete conf; +} + + +QString SMTPaccount::getFileName() +{ + return locateLocal("data", "kmicromail" ) +"/smtp-" + file; +} + +NNTPaccount::NNTPaccount() + : Account() +{ + file = NNTPaccount::getUniqueFileName(); + accountName = "New NNTP Account"; + ssl = false; + login = false; + type = MAILLIB::A_NNTP; + port = NNTP_PORT; +} + +NNTPaccount::NNTPaccount( QString filename ) + : Account() +{ + file = filename; + accountName = "New NNTP Account"; + ssl = false; + login = false; + type = MAILLIB::A_NNTP; + port = NNTP_PORT; +} + +QString NNTPaccount::getUniqueFileName() +{ + int num = 0; + QString unique; + + QDir dir( locateLocal("data", "kmicromail" ) ); + + QStringList imap = dir.entryList( "nntp-*" ); + do { + unique.setNum( num++ ); + } while ( imap.contains( "nntp-" + unique ) > 0 ); + + return unique; +} + +void NNTPaccount::read() +{ + Config *conf = new Config( getFileName(), Config::File ); + conf->setGroup( "NNTP Account" ); + accountName = conf->readEntry( "Account" ); + server = conf->readEntry( "Server" ); + port = conf->readEntry( "Port" ); + ssl = conf->readBoolEntry( "SSL" ); + login = conf->readBoolEntry( "Login" ); + user = conf->readEntry( "User" ); + password = conf->readEntryCrypt( "Password" ); + subscribedGroups = conf->readListEntry( "Subscribed", ',' ); + delete conf; +} + +void NNTPaccount::save() +{ + Settings::checkDirectory(); + + Config *conf = new Config( getFileName(), Config::File ); + conf->setGroup( "NNTP Account" ); + conf->writeEntry( "Account", accountName ); + conf->writeEntry( "Server", server ); + conf->writeEntry( "Port", port ); + conf->writeEntry( "SSL", ssl ); + conf->writeEntry( "Login", login ); + conf->writeEntry( "User", user ); + conf->writeEntryCrypt( "Password", password ); + conf->writeEntry( "Subscribed" , subscribedGroups, ',' ); + conf->write(); + delete conf; +} + + +QString NNTPaccount::getFileName() +{ + return locateLocal("data", "kmicromail" ) +"/nntp-" + file; +} diff --git a/kmicromail/libmailwrapper/settings.h b/kmicromail/libmailwrapper/settings.h new file mode 100644 index 0000000..ba3ec89 --- a/dev/null +++ b/kmicromail/libmailwrapper/settings.h @@ -0,0 +1,164 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include "maildefines.h" + +/* OPIE */ + +/* QT */ +#include <qobject.h> +#include <qlist.h> + +class Account +{ + +public: + Account(); + virtual ~Account() {} + + void remove(); + void setAccountName( QString name ) { accountName = name; } + const QString&getAccountName()const{ return accountName; } + MAILLIB::ATYPE getType()const{ return type; } + + void setServer(const QString&str){ server = str; } + const QString&getServer()const{ return server; } + + void setPort(const QString&str) { port = str; } + const QString&getPort()const{ return port; } + + void setUser(const QString&str){ user = str; } + const QString&getUser()const{ return user; } + + void setPassword(const QString&str) { password = str; } + const QString&getPassword()const { return password; } + + void setSSL( bool b ) { ssl = b; } + bool getSSL() { return ssl; } + + void setConnectionType( int x ) { connectionType = x; } + int ConnectionType() { return connectionType; } + + + void setOffline(bool b) {offline = b;} + bool getOffline()const{return offline;} + + virtual QString getFileName() { return accountName; } + virtual void read() { ; } + virtual void save() { ; } + +protected: + QString accountName, server, port, user, password; + bool ssl; + int connectionType; + bool offline; + MAILLIB::ATYPE type; +}; + +class IMAPaccount : public Account +{ + +public: + IMAPaccount(); + IMAPaccount( QString filename ); + + static QString getUniqueFileName(); + + virtual void read(); + virtual void save(); + virtual QString getFileName(); + + void setPrefix(const QString&str) {prefix=str;} + const QString&getPrefix()const{return prefix;} + +private: + QString file,prefix; + +}; + +class POP3account : public Account +{ + +public: + POP3account(); + POP3account( QString filename ); + + static QString getUniqueFileName(); + + virtual void read(); + virtual void save(); + virtual QString getFileName(); + +private: + QString file; + +}; + +class SMTPaccount : public Account +{ + +public: + SMTPaccount(); + SMTPaccount( QString filename ); + + static QString getUniqueFileName(); + + virtual void read(); + virtual void save(); + virtual QString getFileName(); + + void setLogin( bool b ) { login = b; } + bool getLogin() { return login; } + +private: + QString file, name, mail, org, cc, bcc, reply, signature; + bool useCC, useBCC, useReply, login; + +}; + +class NNTPaccount : public Account +{ + +public: + NNTPaccount(); + NNTPaccount( QString filename ); + + static QString getUniqueFileName(); + + virtual void read(); + virtual void save(); + virtual QString getFileName(); + + void setLogin( bool b ) { login = b; } + bool getLogin() { return login; } + + void setGroups( QStringList list ) { subscribedGroups = list; } + QStringList getGroups() { return subscribedGroups; } + +private: + QString file; + bool login; + QStringList subscribedGroups; + +}; + +class Settings : public QObject +{ + Q_OBJECT + +public: + Settings(); + QList<Account> getAccounts(); + void addAccount(Account *account); + void delAccount(Account *account); + void saveAccounts(); + void readAccounts(); + static void checkDirectory(); + +private: + void updateAccounts(); + QList<Account> accounts; + +}; + +#endif diff --git a/kmicromail/libmailwrapper/smtpwrapper.cpp b/kmicromail/libmailwrapper/smtpwrapper.cpp new file mode 100644 index 0000000..04a21ea --- a/dev/null +++ b/kmicromail/libmailwrapper/smtpwrapper.cpp @@ -0,0 +1,458 @@ +#include "smtpwrapper.h" +#include "mailwrapper.h" +#include "abstractmail.h" +#include "logindialog.h" +#include "mailtypes.h" +#include "sendmailprogress.h" + +//#include <opie2/odebug.h> +//#include <qt.h> +#include <qapplication.h> +#include <qmessagebox.h> +#include <stdlib.h> +#include <qpe/config.h> +#include <qpe/qcopenvelope_qws.h> + +#include <libetpan/libetpan.h> + + +using namespace Opie::Core; +progressMailSend*SMTPwrapper::sendProgress = 0; + +SMTPwrapper::SMTPwrapper(SMTPaccount * aSmtp ) + : Generatemail() +{ + m_SmtpAccount = aSmtp; + 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) ) ); + m_smtp = 0; +} + +SMTPwrapper::~SMTPwrapper() +{ + disc_server(); +} + +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_STARTTLS_NOT_SUPPORTED: + return tr( "Starttls not supported" ); + // 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" ); + } +} + + +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) { + clist *rcpts = 0; + char *from, *data; + size_t size; + + 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); + ; // odebug << "Error fetching mime..." << oendl; + 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); + 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::start_smtp_tls() +{ + if (!m_smtp) { + return MAILSMTP_ERROR_IN_PROCESSING; + } + int err = mailesmtp_starttls(m_smtp); + if (err != MAILSMTP_NO_ERROR) return err; + mailstream_low * low; + mailstream_low * new_low; + low = mailstream_get_low(m_smtp->stream); + if (!low) { + return MAILSMTP_ERROR_IN_PROCESSING; + } + int fd = mailstream_low_get_fd(low); + if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) { + mailstream_low_free(low); + mailstream_set_low(m_smtp->stream, new_low); + } else { + return MAILSMTP_ERROR_IN_PROCESSING; + } + return err; +} + +void SMTPwrapper::connect_server() +{ + const char *server, *user, *pass; + bool ssl; + uint16_t port; + ssl = false; + bool try_tls = true; + bool force_tls=false; + server = user = pass = 0; + QString failuretext = ""; + + if (m_smtp || !m_SmtpAccount) { + return; + } + server = m_SmtpAccount->getServer().latin1(); + if ( m_SmtpAccount->ConnectionType() == 2 ) { + ssl = true; + try_tls = false; + } else if (m_SmtpAccount->ConnectionType() == 1) { + force_tls = true; + } + int result = 1; + port = m_SmtpAccount->getPort().toUInt(); + + m_smtp = mailsmtp_new( 20, &progress ); + if ( m_smtp == NULL ) { + /* no failure message cause this happens when problems with memory - than we + we can not display any messagebox */ + return; + } + + int err = MAILSMTP_NO_ERROR; + ; // odebug << "Servername " << server << " at port " << port << "" << oendl; + if ( ssl ) { + ; // odebug << "SSL session" << oendl; + err = mailsmtp_ssl_connect( m_smtp, server, port ); + } else { + ; // odebug << "No SSL session" << oendl; + err = mailsmtp_socket_connect( m_smtp, server, port ); + } + if ( err != MAILSMTP_NO_ERROR ) { + ; // odebug << "Error init connection" << oendl; + failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err)); + result = 0; + } + + /* switch to tls after init 'cause there it will send the ehlo */ + if (result) { + err = mailsmtp_init( m_smtp ); + if (err != MAILSMTP_NO_ERROR) { + result = 0; + failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err)); + } + } + + if (try_tls) { + err = start_smtp_tls(); + if (err != MAILSMTP_NO_ERROR) { + try_tls = false; + } else { + err = mailesmtp_ehlo(m_smtp); + } + } + + if (!try_tls && force_tls) { + result = 0; + failuretext = tr("Error init SMTP tls: %1").arg(mailsmtpError(err)); + } + + if (result==1 && m_SmtpAccount->getLogin() ) { + ; // odebug << "smtp with auth" << oendl; + if ( m_SmtpAccount->getUser().isEmpty() || m_SmtpAccount->getPassword().isEmpty() ) { + // get'em + LoginDialog login( m_SmtpAccount->getUser(), + m_SmtpAccount->getPassword(), NULL, 0, true ); + login.show(); + if ( QDialog::Accepted == login.exec() ) { + // ok + user = login.getUser().latin1(); + pass = login.getPassword().latin1(); + } else { + result = 0; + failuretext=tr("Login aborted - storing mail to localfolder"); + } + } else { + user = m_SmtpAccount->getUser().latin1(); + pass = m_SmtpAccount->getPassword().latin1(); + } + ; // odebug << "session->auth: " << m_smtp->auth << "" << oendl; + if (result) { + err = mailsmtp_auth( m_smtp, (char*)user, (char*)pass ); + if ( err == MAILSMTP_NO_ERROR ) { + ; // odebug << "auth ok" << oendl; + } else { + failuretext = tr("Authentification failed"); + result = 0; + } + } + } +} + +void SMTPwrapper::disc_server() +{ + if (m_smtp) { + mailsmtp_quit( m_smtp ); + mailsmtp_free( m_smtp ); + m_smtp = 0; + } +} + +int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size ) +{ + int err,result; + QString failuretext = ""; + + connect_server(); + + result = 1; + if (m_smtp) { + err = mailsmtp_send( m_smtp, from, rcpts, data, size ); + if ( err != MAILSMTP_NO_ERROR ) { + failuretext=tr("Error sending mail: %1").arg(mailsmtpError(err)); + result = 0; + } + } else { + result = 0; + } + + if (!result) { + storeFailedMail(data,size,failuretext); + } else { + ; // odebug << "Mail sent." << oendl; + storeMail(data,size,"Sent"); + } + return result; +} + +void SMTPwrapper::sendMail(const Opie::Core::OSmartPointer<Mail>&mail,bool later ) +{ + mailmime * mimeMail; + + mimeMail = createMimeMail(mail ); + if ( mimeMail == NULL ) { + ; // odebug << "sendMail: error creating mime mail" << oendl; + } else { + sendProgress = new progressMailSend(); + sendProgress->show(); + sendProgress->setMaxMails(1); + smtpSend( mimeMail,later); + ; // odebug << "Clean up done" << oendl; + sendProgress->hide(); + delete sendProgress; + sendProgress = 0; + mailmime_free( mimeMail ); + } +} + +int SMTPwrapper::sendQueuedMail(AbstractMail*wrap,const RecMailP&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()); + } + 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() { + bool returnValue = true; + + ; // odebug << "Sending the queue" << oendl; + if (!m_SmtpAccount) { + ; // odebug << "No smtp account given" << oendl; + return false; + } + + bool reset_user_value = false; + QString localfolders = AbstractMail::defaultLocalfolder(); + AbstractMail*wrap = AbstractMail::getWrapper(localfolders); + if (!wrap) { + ; // odebug << "memory error" << oendl; + return false; + } + QString oldPw, oldUser; + QValueList<RecMailP> mailsToSend; + QValueList<RecMailP> mailsToRemove; + QString mbox("Outgoing"); + wrap->listMessages(mbox,mailsToSend); + if (mailsToSend.count()==0) { + delete wrap; + ; // odebug << "No mails to send" << oendl; + return false; + } + + oldPw = m_SmtpAccount->getPassword(); + oldUser = m_SmtpAccount->getUser(); + if (m_SmtpAccount->getLogin() && (m_SmtpAccount->getUser().isEmpty() || m_SmtpAccount->getPassword().isEmpty()) ) { + // get'em + QString user,pass; + LoginDialog login( m_SmtpAccount->getUser(), m_SmtpAccount->getPassword(), NULL, 0, true ); + login.show(); + if ( QDialog::Accepted == login.exec() ) { + // ok + user = login.getUser().latin1(); + pass = login.getPassword().latin1(); + reset_user_value = true; + m_SmtpAccount->setUser(user); + m_SmtpAccount->setPassword(pass); + } else { + return true; + } + } + + + sendProgress = new progressMailSend(); + sendProgress->show(); + sendProgress->setMaxMails(mailsToSend.count()); + + while (mailsToSend.count()>0) { + if (sendQueuedMail(wrap, (*mailsToSend.begin()))==0) { + QMessageBox::critical(0,tr("Error sending mail"), + tr("Error sending queued mail - breaking")); + returnValue = false; + break; + } + mailsToRemove.append((*mailsToSend.begin())); + mailsToSend.remove(mailsToSend.begin()); + sendProgress->setCurrentMails(mailsToRemove.count()); + } + if (reset_user_value) { + m_SmtpAccount->setUser(oldUser); + m_SmtpAccount->setPassword(oldPw); + } + Config cfg( "mail" ); + cfg.setGroup( "Status" ); + m_queuedMail = 0; + cfg.writeEntry( "outgoing", m_queuedMail ); + emit queuedMails( m_queuedMail ); + sendProgress->hide(); + delete sendProgress; + sendProgress = 0; + wrap->deleteMails(mbox,mailsToRemove); + delete wrap; + return returnValue; +} diff --git a/kmicromail/libmailwrapper/smtpwrapper.h b/kmicromail/libmailwrapper/smtpwrapper.h new file mode 100644 index 0000000..6c5bbe8 --- a/dev/null +++ b/kmicromail/libmailwrapper/smtpwrapper.h @@ -0,0 +1,63 @@ +// -*- Mode: C++; -*- +#ifndef SMTPwrapper_H +#define SMTPwrapper_H + +#include <qpe/applnk.h> + +#include <qbitarray.h> +#include <qdatetime.h> +#include <libetpan/clist.h> + +#include "settings.h" +#include "generatemail.h" + +#include <opie2/osmartpointer.h> + +class SMTPaccount; +class AbstractMail; + +class SMTPwrapper : public Generatemail +{ + Q_OBJECT + +public: + SMTPwrapper(SMTPaccount * aSmtp); + virtual ~SMTPwrapper(); + void sendMail(const Opie::Core::OSmartPointer<Mail>& mail,bool later=false ); + bool flushOutbox(); + + static progressMailSend*sendProgress; + +signals: + void queuedMails( int ); + +protected: + mailsmtp *m_smtp; + SMTPaccount * m_SmtpAccount; + + void connect_server(); + void disc_server(); + int start_smtp_tls(); + + + void smtpSend( mailmime *mail,bool later); + + 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 ); + + int smtpSend(char*from,clist*rcpts,const char*data,size_t size); + + void storeMail(mailmime*mail, const QString&box); + + int sendQueuedMail(AbstractMail*wrap,const Opie::Core::OSmartPointer<RecMail>&which); + void storeFailedMail(const char*data,unsigned int size, const char*failuremessage); + + int m_queuedMail; + +protected slots: + void emitQCop( int queued ); + +}; + +#endif diff --git a/kmicromail/libmailwrapper/statusmail.cpp b/kmicromail/libmailwrapper/statusmail.cpp new file mode 100644 index 0000000..90c9233 --- a/dev/null +++ b/kmicromail/libmailwrapper/statusmail.cpp @@ -0,0 +1,94 @@ +#include "statusmail.h" + + + +using namespace Opie::Core; + +StatusMail::StatusMail(QList<Account>&list) +{ + currentImapStat.message_count=0; + currentImapStat.message_unseen=0; + currentImapStat.message_recent=0; + lastPop3Stat = currentImapStat; + currentPop3Stat = currentImapStat; + connectionList.setAutoDelete(true); + connectionList.clear(); + initAccounts(list); +} + +StatusMail::~StatusMail() +{ +} + +void StatusMail::initAccounts(QList<Account>&accounts) +{ + + Account *it; + folderStat currentStat; + AbstractMail * current = 0; + currentPop3Stat.message_count=0; + currentPop3Stat.message_recent=0; + currentPop3Stat.message_unseen=0; + for ( it = accounts.first(); it; it = accounts.next() ) { + if ( it->getType()==MAILLIB::A_IMAP && !it->getOffline() ) { + IMAPaccount*ima = static_cast<IMAPaccount *>(it); + current = AbstractMail::getWrapper(ima); + connectionList.append(current); + current->statusFolder(currentStat); + currentImapStat.message_count+=currentStat.message_unseen; + currentImapStat.message_count+=currentStat.message_recent; + currentImapStat.message_count+=currentStat.message_count; + } else if ( it->getType() == MAILLIB::A_POP3 && !it->getOffline() ) { + POP3account *pop3 = static_cast<POP3account *>(it); + current = AbstractMail::getWrapper(pop3); + connectionList.append(current); + current->statusFolder(currentStat); + currentPop3Stat.message_count+=currentStat.message_count; + } + current->logout(); + } + ; // << "Pop3 init count: " << currentPop3Stat.message_count << "" << oendl; + currentPop3Stat.message_recent = currentPop3Stat.message_unseen = 0; + lastPop3Stat.message_unseen = currentPop3Stat.message_unseen; + lastPop3Stat.message_recent = currentPop3Stat.message_recent; + lastPop3Stat.message_count = currentPop3Stat.message_count; +} + +void StatusMail::reset_status() +{ + lastPop3Stat = currentPop3Stat; +} + +void StatusMail::check_current_stat(folderStat&targetStat) +{ + AbstractMail*it = 0; + folderStat currentStat; + currentPop3Stat.message_recent = 0; + currentPop3Stat.message_count = 0; + currentPop3Stat.message_unseen = 0; + currentImapStat = currentPop3Stat; + for ( it = connectionList.first(); it; it = connectionList.next() ) { + it->statusFolder(currentStat); + it->logout(); + if (it->getType() == MAILLIB::A_IMAP) { + currentImapStat.message_unseen+=currentStat.message_unseen; + currentImapStat.message_recent+=currentStat.message_recent; + currentImapStat.message_count+=currentStat.message_count; + } else if (it->getType() == MAILLIB::A_POP3) { + currentPop3Stat.message_count+=currentStat.message_count; + ; // << "Pop3 count: " << currentPop3Stat.message_count << "" << oendl; + } + } + ; // << "Pop3 last: " << lastPop3Stat.message_count << "" << oendl; + if (currentPop3Stat.message_count > lastPop3Stat.message_count) { + currentPop3Stat.message_recent = currentPop3Stat.message_count - lastPop3Stat.message_count; + currentPop3Stat.message_unseen = currentPop3Stat.message_recent; + } else { + lastPop3Stat.message_count = currentPop3Stat.message_count; + currentPop3Stat.message_recent = currentPop3Stat.message_unseen = 0; + } + targetStat = currentImapStat; + targetStat.message_unseen+=currentPop3Stat.message_unseen; + targetStat.message_recent+=currentPop3Stat.message_recent; + targetStat.message_count+=currentPop3Stat.message_count; +} diff --git a/kmicromail/libmailwrapper/statusmail.h b/kmicromail/libmailwrapper/statusmail.h new file mode 100644 index 0000000..2637232 --- a/dev/null +++ b/kmicromail/libmailwrapper/statusmail.h @@ -0,0 +1,31 @@ +#ifndef __MAIL_STATUS_H +#define __MAIL_STATUS_H + +#include "settings.h" +#include "abstractmail.h" +#include "mailtypes.h" + +class StatusMail +{ +public: + StatusMail(QList<Account>&list); + virtual ~StatusMail(); + + /* this should be called if opiemail is starte or a mailbox touched - may be trough + a qcop signal or if tab on the taskbar applet*/ + virtual void reset_status(); + virtual void check_current_stat(folderStat&targetStat); + +protected: + void initAccounts(QList<Account>&accounts); + /* this must be cause we have to calculate the recent for pop3*/ + folderStat currentImapStat; + /* currentPop3Stat is the sum of messages in POP3 accounts in CURRENT loop + the recent are calculated to the difference of the LAST loop */ + folderStat currentPop3Stat; + /* lastPop3Stat is the sum of messages in LAST loop */ + folderStat lastPop3Stat; + QList<AbstractMail> connectionList; +}; + +#endif diff --git a/kmicromail/libmailwrapper/storemail.cpp b/kmicromail/libmailwrapper/storemail.cpp new file mode 100644 index 0000000..ed1d44a --- a/dev/null +++ b/kmicromail/libmailwrapper/storemail.cpp @@ -0,0 +1,90 @@ +#include "storemail.h" +#include "mailwrapper.h" +#include "settings.h" +#include "abstractmail.h" + +#include <libetpan/libetpan.h> +#include <qstring.h> + +#include <stdlib.h> + +using namespace Opie::Core; +Storemail::Storemail(Account*aAccount,const QString&aFolder) + : Generatemail() +{ + wrapper = 0; + m_Account = aAccount; + m_tfolder = aFolder; + wrapper = AbstractMail::getWrapper(m_Account); + if (wrapper) { + wrapper->createMbox(m_tfolder); + } +} + +Storemail::Storemail(const QString&dir,const QString&aFolder) + : Generatemail() +{ + wrapper = 0; + m_Account = 0; + m_tfolder = aFolder; + wrapper = AbstractMail::getWrapper(dir); + if (wrapper) { + wrapper->createMbox(m_tfolder); + } +} + +Storemail::Storemail(const QString&aFolder) + : Generatemail() +{ + wrapper = 0; + m_Account = 0; + m_tfolder = aFolder; + wrapper = AbstractMail::getWrapper(AbstractMail::defaultLocalfolder()); + if (wrapper) { + wrapper->createMbox(m_tfolder); + } +} + +Storemail::~Storemail() +{ +} + +int Storemail::storeMail(const Opie::Core::OSmartPointer<Mail>&mail) +{ + if (!wrapper) return 0; + int ret = 1; + + mailmime * mimeMail = 0; + mimeMail = createMimeMail(mail ); + if ( mimeMail == NULL ) { + qDebug("storeMail: error creating mime mail "); + return 0; + } + char *data; + size_t size; + data = 0; + + mailmessage * msg = 0; + msg = mime_message_init(mimeMail); + mime_message_set_tmpdir(msg,getenv( "HOME" )); + int r = mailmessage_fetch(msg,&data,&size); + mime_message_detach_mime(msg); + mailmessage_free(msg); + msg = 0; + if (r != MAIL_NO_ERROR || !data) { + qDebug("Error fetching mime... "); + ret = 0; + } + + if (ret) { + wrapper->storeMessage(data,size,m_tfolder); + } + + if (data) { + free(data); + } + if (mimeMail) { + mailmime_free( mimeMail ); + } + return ret; +} diff --git a/kmicromail/libmailwrapper/storemail.h b/kmicromail/libmailwrapper/storemail.h new file mode 100644 index 0000000..4433de0 --- a/dev/null +++ b/kmicromail/libmailwrapper/storemail.h @@ -0,0 +1,29 @@ +#ifndef __STORE_MAIL_H +#define __STORE_MAIL_H + +#include <qpe/applnk.h> + +#include "generatemail.h" + +class Account; +class Mail; +class AbstractMail; + +class Storemail : public Generatemail +{ + Q_OBJECT +public: + Storemail(Account*aAccount,const QString&aFolder); + Storemail(const QString&dir,const QString&aFolder); + Storemail(const QString&aFolder); + virtual ~Storemail(); + + int storeMail(const Opie::Core::OSmartPointer<Mail>&mail); + +protected: + Account* m_Account; + QString m_tfolder; + AbstractMail*wrapper; +}; + +#endif |