-rw-r--r-- | noncore/net/mail/abstractmail.cpp | 21 | ||||
-rw-r--r-- | noncore/net/mail/abstractmail.h | 4 | ||||
-rw-r--r-- | noncore/net/mail/imapwrapper.cpp | 18 | ||||
-rw-r--r-- | noncore/net/mail/imapwrapper.h | 4 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/abstractmail.cpp | 21 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/abstractmail.h | 4 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.cpp | 18 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.h | 4 |
8 files changed, 78 insertions, 16 deletions
diff --git a/noncore/net/mail/abstractmail.cpp b/noncore/net/mail/abstractmail.cpp index 7380c31..0bb2525 100644 --- a/noncore/net/mail/abstractmail.cpp +++ b/noncore/net/mail/abstractmail.cpp @@ -1,13 +1,34 @@ #include "abstractmail.h" #include "imapwrapper.h" #include "pop3wrapper.h" +#include <qstring.h> +#include <stdlib.h> +#include <libetpan/mailmime_content.h> + AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) { return new IMAPwrapper(a); } AbstractMail* AbstractMail::getWrapper(POP3account *a) { return new POP3wrapper(a); } + +QString AbstractMail::decode_quoted_printable(const char*text) +{ + char*result_text; + size_t index = 0; + QString result = ""; + /* reset for recursive use! */ + size_t target_length = 0; + result_text = 0; + int err = mailmime_quoted_printable_body_parse(text,strlen(text), + &index,&result_text,&target_length,0); + if (result_text) { + result = result_text; + free(result_text); + } + return result; +} diff --git a/noncore/net/mail/abstractmail.h b/noncore/net/mail/abstractmail.h index 62e0715..4473ad2 100644 --- a/noncore/net/mail/abstractmail.h +++ b/noncore/net/mail/abstractmail.h @@ -10,22 +10,22 @@ class RecPart; class IMAPwrapper; class POP3wrapper; class Folder; class AbstractMail:public QObject { Q_OBJECT public: AbstractMail(){}; virtual ~AbstractMail(){} virtual QList<Folder>* listFolders()=0; virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0; virtual RecBody fetchBody(const RecMail&mail)=0; virtual QString fetchPart(const RecMail&mail,const RecPart&part)=0; virtual void deleteMail(const RecMail&mail)=0; virtual void answeredMail(const RecMail&mail)=0; - + static AbstractMail* getWrapper(IMAPaccount *a); static AbstractMail* getWrapper(POP3account *a); + static QString decode_quoted_printable(const char*text); }; - #endif diff --git a/noncore/net/mail/imapwrapper.cpp b/noncore/net/mail/imapwrapper.cpp index ad95384..a4e6228 100644 --- a/noncore/net/mail/imapwrapper.cpp +++ b/noncore/net/mail/imapwrapper.cpp @@ -379,39 +379,45 @@ RecBody IMAPwrapper::fetchBody(const RecMail&mail) /* this routine is just called when the mail has only ONE part. for filling the parts of a multi-part-message there are other routines 'cause we can not simply fetch the whole body. */ void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body) { if (!mailDescription) { return; } QString sub,body_text; RecPart singlePart; QValueList<int> path; fillSinglePart(singlePart,mailDescription); switch (mailDescription->bd_type) { case MAILIMAP_BODY_TYPE_1PART_MSG: path.append(1); body_text = fetchPart(mail,path,true); + if (singlePart.Encoding()=="quoted-printable") { + body_text = decode_quoted_printable(body_text.latin1()); + } target_body.setBodytext(body_text); target_body.setDescription(singlePart); break; case MAILIMAP_BODY_TYPE_1PART_TEXT: qDebug("Mediatype single: %s",mailDescription->bd_data.bd_type_text->bd_media_text); path.append(1); body_text = fetchPart(mail,path,true); + if (singlePart.Encoding()=="quoted-printable") { + body_text = decode_quoted_printable(body_text.latin1()); + } target_body.setBodytext(body_text); target_body.setDescription(singlePart); break; case MAILIMAP_BODY_TYPE_1PART_BASIC: qDebug("Single attachment"); target_body.setBodytext(""); target_body.addPart(singlePart); break; default: break; } return; } QStringList IMAPwrapper::address_list_to_stringlist(clist*list) @@ -442,33 +448,33 @@ QStringList IMAPwrapper::address_list_to_stringlist(clist*list) 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; } -QString IMAPwrapper::fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call) +QString IMAPwrapper::fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call,const QString&enc) { QString body(""); const char*mb; int err; mailimap_fetch_type *fetchType; mailimap_set *set; clistcell*current,*cur; login(); if (!m_imap) { return body; } if (!internal_call) { mb = mail.getMbox().latin1(); err = mailimap_select( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { @@ -494,33 +500,37 @@ QString IMAPwrapper::fetchPart(const RecMail&mail,const QValueList<int>&path,boo 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; msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; if (text) { - body = QString(text); + if (enc=="quoted-printable") { + body = decode_quoted_printable(text); + } else { + body = QString(text); + } free(text); } else { body = ""; } } } } } else { qDebug("error fetching text: %s",m_imap->imap_response); } mailimap_fetch_list_free(result); return body; } void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion,QValueList<int>recList) @@ -534,33 +544,33 @@ void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mai unsigned int count = 0; for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) { /* the point in the message */ ++count; current_body = (mailimap_body*)current->data; if (current_body->bd_type==MAILIMAP_BODY_MPART) { QValueList<int>clist = recList; clist.append(count); searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1,clist); } else if (current_body->bd_type==MAILIMAP_BODY_1PART){ RecPart currentPart; fillSinglePart(currentPart,current_body->bd_data.bd_body_1part); QValueList<int>clist = recList; clist.append(count); /* important: Check for is NULL 'cause a body can be empty! */ if (currentPart.Type()=="text" && target_body.Bodytext().isNull() ) { - QString body_text = fetchPart(mail,clist,true); + QString body_text = fetchPart(mail,clist,true,currentPart.Encoding()); target_body.setDescription(currentPart); target_body.setBodytext(body_text); } else { QString id(""); for (unsigned int j = 0; j < clist.count();++j) { id+=(j>0?" ":""); id+=QString("%1").arg(clist[j]); } qDebug("ID= %s",id.latin1()); currentPart.setIdentifier(id); currentPart.setPositionlist(clist); target_body.addPart(currentPart); } } } } @@ -692,33 +702,33 @@ void IMAPwrapper::fillBodyFields(RecPart&target_part,mailimap_body_fields*which) 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); } QString IMAPwrapper::fetchPart(const RecMail&mail,const RecPart&part) { - return fetchPart(mail,part.Positionlist(),false); + return fetchPart(mail,part.Positionlist(),false,part.Encoding()); } void IMAPwrapper::deleteMail(const RecMail&mail) { mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err; login(); if (!m_imap) { return; } const char *mb = mail.getMbox().latin1(); err = mailimap_select( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox for delete: %s",m_imap->imap_response); diff --git a/noncore/net/mail/imapwrapper.h b/noncore/net/mail/imapwrapper.h index 700d512..768a517 100644 --- a/noncore/net/mail/imapwrapper.h +++ b/noncore/net/mail/imapwrapper.h @@ -21,36 +21,36 @@ public: IMAPwrapper( IMAPaccount *a ); virtual ~IMAPwrapper(); virtual QList<Folder>* listFolders(); virtual void listMessages(const QString & mailbox,QList<RecMail>&target ); virtual RecBody fetchBody(const RecMail&mail); virtual QString fetchPart(const RecMail&mail,const RecPart&part); virtual void deleteMail(const RecMail&mail); virtual void answeredMail(const RecMail&mail); static void imap_progress( size_t current, size_t maximum ); protected: RecMail*parse_list_result(mailimap_msg_att*); void login(); void logout(); - virtual QString fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false); + virtual QString fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc=""); void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body); void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>()); void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which); /* just helpers */ static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); static QStringList address_list_to_stringlist(clist*list); -private: + IMAPaccount *account; mailimap *m_imap; }; #endif diff --git a/noncore/net/mail/libmailwrapper/abstractmail.cpp b/noncore/net/mail/libmailwrapper/abstractmail.cpp index 7380c31..0bb2525 100644 --- a/noncore/net/mail/libmailwrapper/abstractmail.cpp +++ b/noncore/net/mail/libmailwrapper/abstractmail.cpp @@ -1,13 +1,34 @@ #include "abstractmail.h" #include "imapwrapper.h" #include "pop3wrapper.h" +#include <qstring.h> +#include <stdlib.h> +#include <libetpan/mailmime_content.h> + AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) { return new IMAPwrapper(a); } AbstractMail* AbstractMail::getWrapper(POP3account *a) { return new POP3wrapper(a); } + +QString AbstractMail::decode_quoted_printable(const char*text) +{ + char*result_text; + size_t index = 0; + QString result = ""; + /* reset for recursive use! */ + size_t target_length = 0; + result_text = 0; + int err = mailmime_quoted_printable_body_parse(text,strlen(text), + &index,&result_text,&target_length,0); + if (result_text) { + result = result_text; + free(result_text); + } + return result; +} diff --git a/noncore/net/mail/libmailwrapper/abstractmail.h b/noncore/net/mail/libmailwrapper/abstractmail.h index 62e0715..4473ad2 100644 --- a/noncore/net/mail/libmailwrapper/abstractmail.h +++ b/noncore/net/mail/libmailwrapper/abstractmail.h @@ -10,22 +10,22 @@ class RecPart; class IMAPwrapper; class POP3wrapper; class Folder; class AbstractMail:public QObject { Q_OBJECT public: AbstractMail(){}; virtual ~AbstractMail(){} virtual QList<Folder>* listFolders()=0; virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0; virtual RecBody fetchBody(const RecMail&mail)=0; virtual QString fetchPart(const RecMail&mail,const RecPart&part)=0; virtual void deleteMail(const RecMail&mail)=0; virtual void answeredMail(const RecMail&mail)=0; - + static AbstractMail* getWrapper(IMAPaccount *a); static AbstractMail* getWrapper(POP3account *a); + static QString decode_quoted_printable(const char*text); }; - #endif diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp index ad95384..a4e6228 100644 --- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp +++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp @@ -379,39 +379,45 @@ RecBody IMAPwrapper::fetchBody(const RecMail&mail) /* this routine is just called when the mail has only ONE part. for filling the parts of a multi-part-message there are other routines 'cause we can not simply fetch the whole body. */ void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body) { if (!mailDescription) { return; } QString sub,body_text; RecPart singlePart; QValueList<int> path; fillSinglePart(singlePart,mailDescription); switch (mailDescription->bd_type) { case MAILIMAP_BODY_TYPE_1PART_MSG: path.append(1); body_text = fetchPart(mail,path,true); + if (singlePart.Encoding()=="quoted-printable") { + body_text = decode_quoted_printable(body_text.latin1()); + } target_body.setBodytext(body_text); target_body.setDescription(singlePart); break; case MAILIMAP_BODY_TYPE_1PART_TEXT: qDebug("Mediatype single: %s",mailDescription->bd_data.bd_type_text->bd_media_text); path.append(1); body_text = fetchPart(mail,path,true); + if (singlePart.Encoding()=="quoted-printable") { + body_text = decode_quoted_printable(body_text.latin1()); + } target_body.setBodytext(body_text); target_body.setDescription(singlePart); break; case MAILIMAP_BODY_TYPE_1PART_BASIC: qDebug("Single attachment"); target_body.setBodytext(""); target_body.addPart(singlePart); break; default: break; } return; } QStringList IMAPwrapper::address_list_to_stringlist(clist*list) @@ -442,33 +448,33 @@ QStringList IMAPwrapper::address_list_to_stringlist(clist*list) 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; } -QString IMAPwrapper::fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call) +QString IMAPwrapper::fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call,const QString&enc) { QString body(""); const char*mb; int err; mailimap_fetch_type *fetchType; mailimap_set *set; clistcell*current,*cur; login(); if (!m_imap) { return body; } if (!internal_call) { mb = mail.getMbox().latin1(); err = mailimap_select( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { @@ -494,33 +500,37 @@ QString IMAPwrapper::fetchPart(const RecMail&mail,const QValueList<int>&path,boo 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; msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; if (text) { - body = QString(text); + if (enc=="quoted-printable") { + body = decode_quoted_printable(text); + } else { + body = QString(text); + } free(text); } else { body = ""; } } } } } else { qDebug("error fetching text: %s",m_imap->imap_response); } mailimap_fetch_list_free(result); return body; } void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion,QValueList<int>recList) @@ -534,33 +544,33 @@ void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mai unsigned int count = 0; for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) { /* the point in the message */ ++count; current_body = (mailimap_body*)current->data; if (current_body->bd_type==MAILIMAP_BODY_MPART) { QValueList<int>clist = recList; clist.append(count); searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1,clist); } else if (current_body->bd_type==MAILIMAP_BODY_1PART){ RecPart currentPart; fillSinglePart(currentPart,current_body->bd_data.bd_body_1part); QValueList<int>clist = recList; clist.append(count); /* important: Check for is NULL 'cause a body can be empty! */ if (currentPart.Type()=="text" && target_body.Bodytext().isNull() ) { - QString body_text = fetchPart(mail,clist,true); + QString body_text = fetchPart(mail,clist,true,currentPart.Encoding()); target_body.setDescription(currentPart); target_body.setBodytext(body_text); } else { QString id(""); for (unsigned int j = 0; j < clist.count();++j) { id+=(j>0?" ":""); id+=QString("%1").arg(clist[j]); } qDebug("ID= %s",id.latin1()); currentPart.setIdentifier(id); currentPart.setPositionlist(clist); target_body.addPart(currentPart); } } } } @@ -692,33 +702,33 @@ void IMAPwrapper::fillBodyFields(RecPart&target_part,mailimap_body_fields*which) 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); } QString IMAPwrapper::fetchPart(const RecMail&mail,const RecPart&part) { - return fetchPart(mail,part.Positionlist(),false); + return fetchPart(mail,part.Positionlist(),false,part.Encoding()); } void IMAPwrapper::deleteMail(const RecMail&mail) { mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err; login(); if (!m_imap) { return; } const char *mb = mail.getMbox().latin1(); err = mailimap_select( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox for delete: %s",m_imap->imap_response); diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h index 700d512..768a517 100644 --- a/noncore/net/mail/libmailwrapper/imapwrapper.h +++ b/noncore/net/mail/libmailwrapper/imapwrapper.h @@ -21,36 +21,36 @@ public: IMAPwrapper( IMAPaccount *a ); virtual ~IMAPwrapper(); virtual QList<Folder>* listFolders(); virtual void listMessages(const QString & mailbox,QList<RecMail>&target ); virtual RecBody fetchBody(const RecMail&mail); virtual QString fetchPart(const RecMail&mail,const RecPart&part); virtual void deleteMail(const RecMail&mail); virtual void answeredMail(const RecMail&mail); static void imap_progress( size_t current, size_t maximum ); protected: RecMail*parse_list_result(mailimap_msg_att*); void login(); void logout(); - virtual QString fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false); + virtual QString fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc=""); void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body); void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>()); void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which); /* just helpers */ static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); static QStringList address_list_to_stringlist(clist*list); -private: + IMAPaccount *account; mailimap *m_imap; }; #endif |