author | alwin <alwin> | 2003-12-19 02:35:50 (UTC) |
---|---|---|
committer | alwin <alwin> | 2003-12-19 02:35:50 (UTC) |
commit | ffc12a369b26b1c652213a48eb635ce24eab5458 (patch) (side-by-side diff) | |
tree | a9751d94a6f6a128edd6270977ac872a97bebe2f /noncore/net | |
parent | 5b88f5d05b2f3f5d106b58b07bc7018f757cfc03 (diff) | |
download | opie-ffc12a369b26b1c652213a48eb635ce24eab5458.zip opie-ffc12a369b26b1c652213a48eb635ce24eab5458.tar.gz opie-ffc12a369b26b1c652213a48eb635ce24eab5458.tar.bz2 |
fetching body-structure/content mostly finished
hard-limit: no mail larger than 5MB will fetched
TODO: messages has to be cached in memory. otherwise on every
part fetch we must fetch the whole message again.
Idea: setup a content cache for imap, too.
-rw-r--r-- | noncore/net/mail/libmailwrapper/pop3wrapper.cpp | 183 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/pop3wrapper.h | 8 | ||||
-rw-r--r-- | noncore/net/mail/pop3wrapper.cpp | 183 | ||||
-rw-r--r-- | noncore/net/mail/pop3wrapper.h | 8 |
4 files changed, 318 insertions, 64 deletions
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.cpp b/noncore/net/mail/libmailwrapper/pop3wrapper.cpp index b0b985c..2c2a42a 100644 --- a/noncore/net/mail/libmailwrapper/pop3wrapper.cpp +++ b/noncore/net/mail/libmailwrapper/pop3wrapper.cpp @@ -81,77 +81,54 @@ RecBody POP3wrapper::fetchBody( const RecMail &mail ) body = parseMail(message); free(message); return body; } RecBody POP3wrapper::parseMail( char *message ) { int err = MAILIMF_NO_ERROR; /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ size_t curTok = 0; mailimf_message *result = 0; mailmessage * msg=0; + mailmime_single_fields fields; + + /* is bound to msg and will be freed there */ struct mailmime * mime=0; - struct mailmime_single_fields fields; - + RecBody body; err = mailimf_message_parse( (char *) message, strlen( message ), &curTok, &result ); if ( err != MAILIMF_NO_ERROR ) { if (result) mailimf_message_free(result); return body; } -#if 0 char*body_msg = message; - if ( result && result->msg_body && result->msg_body->bd_text ) { - body_msg = (char*)result->msg_body->bd_text; - result->msg_body->bd_text = 0; - } - msg = mailmessage_new(); mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg)); generic_message_t * msg_data; msg_data = (generic_message_t *)msg->msg_data; msg_data->msg_fetched = 1; msg_data->msg_message = body_msg; msg_data->msg_length = strlen(body_msg); + + memset(&fields, 0, sizeof(struct mailmime_single_fields)); err = mailmessage_get_bodystructure(msg,&mime); + traverseBody(body,msg,mime); + + mailmessage_free(msg); - if (mime->mm_mime_fields != NULL) { - mailmime_single_fields_init(&fields, mime->mm_mime_fields, - mime->mm_content_type); - } -#endif - -#if 1 - if ( result && result->msg_body && result->msg_body->bd_text ) { - qDebug( "POP3: bodytext found" ); - // when curTok isn't set to 0 this line will fault! 'cause upper line faults! - body.setBodytext( QString( result->msg_body->bd_text ) ); -#if 0 - curTok = 0; - mailmime_content*mresult = 0; - size_t index = 0; - mailmime_content_parse(result->msg_body->bd_text, - strlen(result->msg_body->bd_text),&index,&mresult); - if (mresult) { - mailmime_content_free(mresult); - } -#endif - mailimf_message_free(result); - } -#endif return body; } void POP3wrapper::listMessages(const QString &, QList<RecMail> &target ) { int err = MAILPOP3_NO_ERROR; char * header = 0; /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ size_t length = 0; carray * messages = 0; login(); @@ -447,12 +424,154 @@ void POP3wrapper::answeredMail(const RecMail&) { } encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&) { return new encodedString(); } encodedString* POP3wrapper::fetchRawPart(const RecMail&,const RecPart&) { return new encodedString(); } + +void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec) +{ + if (current_rec >= 10) { + qDebug("too deep recursion!"); + } + if (!message || !mime) { + return; + } + int r; + char*data = 0; + size_t len; + clistiter * cur = 0; + mailmime_single_fields fields; + int res; + QString b; + memset(&fields, 0, sizeof(struct mailmime_single_fields)); + RecPart part; + + if (mime->mm_mime_fields != NULL) { + mailmime_single_fields_init(&fields, mime->mm_mime_fields, + mime->mm_content_type); + } + switch (mime->mm_type) { + case MAILMIME_SINGLE: + r = mailmessage_fetch_section(message,mime,&data,&len); + fillSingleBody(part,message,mime); + if (part.Type()=="text" && target.Bodytext().isNull()) { + encodedString*r = new encodedString(); + r->setContent(data,len); + encodedString*res = decode_String(r,part.Encoding()); + b = QString(res->Content()); + delete r; + delete res; + target.setBodytext(b); + target.setDescription(part); + } else { + /* TODO: Add the content to a list and store it for later use */ + if (data) free(data); + target.addPart(part); + } + break; + case MAILMIME_MULTIPLE: + for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { + traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1); + } + break; + case MAILMIME_MESSAGE: + if (mime->mm_data.mm_message.mm_msg_mime != NULL) { + traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1); + } + break; + } +} + +QString POP3wrapper::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 POP3wrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime) +{ + if (!mime) { + return; + } + mailmime_content*type = mime->mm_content_type; + mailmime_field*field = 0; + 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 (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; + } + } + } + // TODO search the parameter list for unique id and so on +} diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.h b/noncore/net/mail/libmailwrapper/pop3wrapper.h index a05021c..4171a76 100644 --- a/noncore/net/mail/libmailwrapper/pop3wrapper.h +++ b/noncore/net/mail/libmailwrapper/pop3wrapper.h @@ -1,22 +1,25 @@ #ifndef __POP3WRAPPER #define __POP3WRAPPER #include "mailwrapper.h" #include "abstractmail.h" class RecMail; class RecBody; class encodedString; struct mailpop3; +struct mailmessage; +struct mailmime; +struct mailmime_mechanism; class POP3wrapper : public AbstractMail { Q_OBJECT public: POP3wrapper( POP3account *a ); virtual ~POP3wrapper(); /* mailbox will be ignored */ virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); virtual QList<Folder>* listFolders(); virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); @@ -31,19 +34,24 @@ public: protected: void login(); void logout(); RecMail *parseHeader( const char *header ); RecBody parseMail( char *message ); 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 ); + + static void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0); + static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime); + static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc); + POP3account *account; mailpop3 *m_pop3; QString msgTempName; unsigned int last_msg_id; }; #endif diff --git a/noncore/net/mail/pop3wrapper.cpp b/noncore/net/mail/pop3wrapper.cpp index b0b985c..2c2a42a 100644 --- a/noncore/net/mail/pop3wrapper.cpp +++ b/noncore/net/mail/pop3wrapper.cpp @@ -81,77 +81,54 @@ RecBody POP3wrapper::fetchBody( const RecMail &mail ) body = parseMail(message); free(message); return body; } RecBody POP3wrapper::parseMail( char *message ) { int err = MAILIMF_NO_ERROR; /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ size_t curTok = 0; mailimf_message *result = 0; mailmessage * msg=0; + mailmime_single_fields fields; + + /* is bound to msg and will be freed there */ struct mailmime * mime=0; - struct mailmime_single_fields fields; - + RecBody body; err = mailimf_message_parse( (char *) message, strlen( message ), &curTok, &result ); if ( err != MAILIMF_NO_ERROR ) { if (result) mailimf_message_free(result); return body; } -#if 0 char*body_msg = message; - if ( result && result->msg_body && result->msg_body->bd_text ) { - body_msg = (char*)result->msg_body->bd_text; - result->msg_body->bd_text = 0; - } - msg = mailmessage_new(); mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg)); generic_message_t * msg_data; msg_data = (generic_message_t *)msg->msg_data; msg_data->msg_fetched = 1; msg_data->msg_message = body_msg; msg_data->msg_length = strlen(body_msg); + + memset(&fields, 0, sizeof(struct mailmime_single_fields)); err = mailmessage_get_bodystructure(msg,&mime); + traverseBody(body,msg,mime); + + mailmessage_free(msg); - if (mime->mm_mime_fields != NULL) { - mailmime_single_fields_init(&fields, mime->mm_mime_fields, - mime->mm_content_type); - } -#endif - -#if 1 - if ( result && result->msg_body && result->msg_body->bd_text ) { - qDebug( "POP3: bodytext found" ); - // when curTok isn't set to 0 this line will fault! 'cause upper line faults! - body.setBodytext( QString( result->msg_body->bd_text ) ); -#if 0 - curTok = 0; - mailmime_content*mresult = 0; - size_t index = 0; - mailmime_content_parse(result->msg_body->bd_text, - strlen(result->msg_body->bd_text),&index,&mresult); - if (mresult) { - mailmime_content_free(mresult); - } -#endif - mailimf_message_free(result); - } -#endif return body; } void POP3wrapper::listMessages(const QString &, QList<RecMail> &target ) { int err = MAILPOP3_NO_ERROR; char * header = 0; /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ size_t length = 0; carray * messages = 0; login(); @@ -447,12 +424,154 @@ void POP3wrapper::answeredMail(const RecMail&) { } encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&) { return new encodedString(); } encodedString* POP3wrapper::fetchRawPart(const RecMail&,const RecPart&) { return new encodedString(); } + +void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec) +{ + if (current_rec >= 10) { + qDebug("too deep recursion!"); + } + if (!message || !mime) { + return; + } + int r; + char*data = 0; + size_t len; + clistiter * cur = 0; + mailmime_single_fields fields; + int res; + QString b; + memset(&fields, 0, sizeof(struct mailmime_single_fields)); + RecPart part; + + if (mime->mm_mime_fields != NULL) { + mailmime_single_fields_init(&fields, mime->mm_mime_fields, + mime->mm_content_type); + } + switch (mime->mm_type) { + case MAILMIME_SINGLE: + r = mailmessage_fetch_section(message,mime,&data,&len); + fillSingleBody(part,message,mime); + if (part.Type()=="text" && target.Bodytext().isNull()) { + encodedString*r = new encodedString(); + r->setContent(data,len); + encodedString*res = decode_String(r,part.Encoding()); + b = QString(res->Content()); + delete r; + delete res; + target.setBodytext(b); + target.setDescription(part); + } else { + /* TODO: Add the content to a list and store it for later use */ + if (data) free(data); + target.addPart(part); + } + break; + case MAILMIME_MULTIPLE: + for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { + traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1); + } + break; + case MAILMIME_MESSAGE: + if (mime->mm_data.mm_message.mm_msg_mime != NULL) { + traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1); + } + break; + } +} + +QString POP3wrapper::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 POP3wrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime) +{ + if (!mime) { + return; + } + mailmime_content*type = mime->mm_content_type; + mailmime_field*field = 0; + 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 (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; + } + } + } + // TODO search the parameter list for unique id and so on +} diff --git a/noncore/net/mail/pop3wrapper.h b/noncore/net/mail/pop3wrapper.h index a05021c..4171a76 100644 --- a/noncore/net/mail/pop3wrapper.h +++ b/noncore/net/mail/pop3wrapper.h @@ -1,22 +1,25 @@ #ifndef __POP3WRAPPER #define __POP3WRAPPER #include "mailwrapper.h" #include "abstractmail.h" class RecMail; class RecBody; class encodedString; struct mailpop3; +struct mailmessage; +struct mailmime; +struct mailmime_mechanism; class POP3wrapper : public AbstractMail { Q_OBJECT public: POP3wrapper( POP3account *a ); virtual ~POP3wrapper(); /* mailbox will be ignored */ virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); virtual QList<Folder>* listFolders(); virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); @@ -31,19 +34,24 @@ public: protected: void login(); void logout(); RecMail *parseHeader( const char *header ); RecBody parseMail( char *message ); 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 ); + + static void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0); + static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime); + static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc); + POP3account *account; mailpop3 *m_pop3; QString msgTempName; unsigned int last_msg_id; }; #endif |