summaryrefslogtreecommitdiff
authoralwin <alwin>2004-01-03 02:17:50 (UTC)
committer alwin <alwin>2004-01-03 02:17:50 (UTC)
commit1214e08e45cda6f0de39a8f3bcff2e69244bb87f (patch) (side-by-side diff)
treed51a018b6014904c09272c684e211d8d05cf360e
parent79bca648a80c42d5dc7e7674b251715292db33b3 (diff)
downloadopie-1214e08e45cda6f0de39a8f3bcff2e69244bb87f.zip
opie-1214e08e45cda6f0de39a8f3bcff2e69244bb87f.tar.gz
opie-1214e08e45cda6f0de39a8f3bcff2e69244bb87f.tar.bz2
improved parsing of mailbodies 'cause it failed on multi-part fields which
contains multipart-fields, too.
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/net/mail/imapwrapper.cpp43
-rw-r--r--noncore/net/mail/imapwrapper.h3
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.cpp43
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.h3
4 files changed, 84 insertions, 8 deletions
diff --git a/noncore/net/mail/imapwrapper.cpp b/noncore/net/mail/imapwrapper.cpp
index f7e93aa..ae196bb 100644
--- a/noncore/net/mail/imapwrapper.cpp
+++ b/noncore/net/mail/imapwrapper.cpp
@@ -340,479 +340,516 @@ RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att)
addresslist = address_list_to_stringlist(head->env_bcc->bcc_list);
m->setBcc(addresslist);
}
if (head->env_reply_to!=NULL) {
addresslist = address_list_to_stringlist(head->env_reply_to->rt_list);
if (addresslist.count()) {
m->setReplyto(addresslist.first());
}
}
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));
qDebug("%i %i %i - %i %i %i",d->dt_year,d->dt_month,d->dt_day,d->dt_hour,d->dt_min,d->dt_sec);
qDebug(da.toString());
#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;
}
RecBody IMAPwrapper::fetchBody(const RecMail&mail)
{
RecBody body;
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 = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
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 {
qDebug("error fetching body: %s",m_imap->imap_response);
}
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 RecMail&mail,const QValueList<int>&path,bool internal_call)
{
encodedString*res=new encodedString;
const char*mb;
int err;
mailimap_fetch_type *fetchType;
mailimap_set *set;
clistcell*current,*cur;
login();
if (!m_imap) {
return res;
}
if (!internal_call) {
mb = mail.getMbox().latin1();
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
return res;
}
}
set = mailimap_set_new_single(mail.getNumber());
clist*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);
}
mailimap_section_part * section_part = mailimap_section_part_new(id_list);
mailimap_section_spec * section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL);
mailimap_section * section = mailimap_section_new(section_spec);
mailimap_fetch_att * 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 {
qDebug("error fetching text: %s",m_imap->imap_response);
}
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 RecMail&mail,mailimap_body*body,RecBody&target_body,
int current_recursion,QValueList<int>recList,int current_count)
{
if (!body || current_recursion>=10) {
return;
}
- ++current_count;
switch (body->bd_type) {
case MAILIMAP_BODY_1PART:
{
QValueList<int>countlist = recList;
countlist.append(current_count);
RecPart currentPart;
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]);
}
qDebug("ID = %s",id.latin1());
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 = current_count-1;
+ 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;
- traverseBody(mail,current_body,target_body,current_recursion+1,recList,ccount);
+ if (current_body->bd_type==MAILIMAP_BODY_MPART) {
+ RecPart targetPart;
+ 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]);
+ }
+ qDebug("ID(mpart) = %s",id.latin1());
+ }
+ 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(RecPart&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(RecPart&target_part,mailimap_body_type_text*which)
{
if (!which) {
return;
}
QString sub;
sub = which->bd_media_text;
+ qDebug("Type= text/%s",which->bd_media_text);
target_part.setSubtype(sub.lower());
target_part.setLines(which->bd_lines);
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which)
{
if (!which) {
return;
}
target_part.setSubtype("rfc822");
qDebug("Message part");
/* we set this type to text/plain */
target_part.setLines(which->bd_lines);
fillBodyFields(target_part,which->bd_fields);
}
+void IMAPwrapper::fillMultiPart(RecPart&target_part,mailimap_body_type_mpart*which)
+{
+ if (!which) return;
+ target_part.setSubtype(which->bd_media_subtype);
+ 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(RecPart&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 = "";
}
qDebug("Type = %s/%s",type.latin1(),sub.latin1());
target_part.setType(type.lower());
target_part.setSubtype(sub.lower());
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillBodyFields(RecPart&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 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);
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) {
qDebug("error deleting mail: %s",m_imap->imap_response);
return;
}
qDebug("deleting mail: %s",m_imap->imap_response);
/* should we realy do that at this moment? */
err = mailimap_expunge(m_imap);
if (err != MAILIMAP_NO_ERROR) {
qDebug("error deleting mail: %s",m_imap->imap_response);
}
qDebug("Delete successfull %s",m_imap->imap_response);
}
void IMAPwrapper::answeredMail(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 mark: %s",m_imap->imap_response);
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) {
qDebug("error marking mail: %s",m_imap->imap_response);
return;
}
}
QString IMAPwrapper::fetchTextPart(const RecMail&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 RecMail&mail,const RecPart&part)
{
return fetchTextPart(mail,part.Positionlist(),false,part.Encoding());
}
encodedString* IMAPwrapper::fetchDecodedPart(const RecMail&mail,const RecPart&part)
{
encodedString*res = fetchRawPart(mail,part.Positionlist(),false);
encodedString*r = decode_String(res,part.Encoding());
delete res;
return r;
}
encodedString* IMAPwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
{
return fetchRawPart(mail,part.Positionlist(),false);
}
int IMAPwrapper::deleteAllMail(const Folder*folder)
{
login();
diff --git a/noncore/net/mail/imapwrapper.h b/noncore/net/mail/imapwrapper.h
index e5846f8..7941046 100644
--- a/noncore/net/mail/imapwrapper.h
+++ b/noncore/net/mail/imapwrapper.h
@@ -1,66 +1,67 @@
#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 QList<Folder>* listFolders();
virtual void listMessages(const QString & mailbox,QList<RecMail>&target );
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
virtual int deleteAllMail(const Folder*folder);
virtual RecBody fetchBody(const RecMail&mail);
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
virtual int createMbox(const QString&,const Folder*parentfolder=0,const QString& delemiter="/",bool getsubfolder=false);
virtual int deleteMbox(const Folder*folder);
static void imap_progress( size_t current, size_t maximum );
protected:
RecMail*parse_list_result(mailimap_msg_att*);
void login();
void logout();
virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc="");
virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call);
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);
- void traverseBody(const RecMail&mail,mailimap_body*body,RecBody&target_body,int current_recursion,QValueList<int>recList,int current_count=0);
+ void fillMultiPart(RecPart&target_part,mailimap_body_type_mpart*which);
+ void traverseBody(const RecMail&mail,mailimap_body*body,RecBody&target_body,int current_recursion,QValueList<int>recList,int current_count=1);
/* just helpers */
static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which);
static QStringList address_list_to_stringlist(clist*list);
IMAPaccount *account;
mailimap *m_imap;
};
#endif
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
index f7e93aa..ae196bb 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
@@ -340,479 +340,516 @@ RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att)
addresslist = address_list_to_stringlist(head->env_bcc->bcc_list);
m->setBcc(addresslist);
}
if (head->env_reply_to!=NULL) {
addresslist = address_list_to_stringlist(head->env_reply_to->rt_list);
if (addresslist.count()) {
m->setReplyto(addresslist.first());
}
}
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));
qDebug("%i %i %i - %i %i %i",d->dt_year,d->dt_month,d->dt_day,d->dt_hour,d->dt_min,d->dt_sec);
qDebug(da.toString());
#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;
}
RecBody IMAPwrapper::fetchBody(const RecMail&mail)
{
RecBody body;
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 = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
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 {
qDebug("error fetching body: %s",m_imap->imap_response);
}
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 RecMail&mail,const QValueList<int>&path,bool internal_call)
{
encodedString*res=new encodedString;
const char*mb;
int err;
mailimap_fetch_type *fetchType;
mailimap_set *set;
clistcell*current,*cur;
login();
if (!m_imap) {
return res;
}
if (!internal_call) {
mb = mail.getMbox().latin1();
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
return res;
}
}
set = mailimap_set_new_single(mail.getNumber());
clist*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);
}
mailimap_section_part * section_part = mailimap_section_part_new(id_list);
mailimap_section_spec * section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL);
mailimap_section * section = mailimap_section_new(section_spec);
mailimap_fetch_att * 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 {
qDebug("error fetching text: %s",m_imap->imap_response);
}
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 RecMail&mail,mailimap_body*body,RecBody&target_body,
int current_recursion,QValueList<int>recList,int current_count)
{
if (!body || current_recursion>=10) {
return;
}
- ++current_count;
switch (body->bd_type) {
case MAILIMAP_BODY_1PART:
{
QValueList<int>countlist = recList;
countlist.append(current_count);
RecPart currentPart;
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]);
}
qDebug("ID = %s",id.latin1());
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 = current_count-1;
+ 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;
- traverseBody(mail,current_body,target_body,current_recursion+1,recList,ccount);
+ if (current_body->bd_type==MAILIMAP_BODY_MPART) {
+ RecPart targetPart;
+ 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]);
+ }
+ qDebug("ID(mpart) = %s",id.latin1());
+ }
+ 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(RecPart&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(RecPart&target_part,mailimap_body_type_text*which)
{
if (!which) {
return;
}
QString sub;
sub = which->bd_media_text;
+ qDebug("Type= text/%s",which->bd_media_text);
target_part.setSubtype(sub.lower());
target_part.setLines(which->bd_lines);
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which)
{
if (!which) {
return;
}
target_part.setSubtype("rfc822");
qDebug("Message part");
/* we set this type to text/plain */
target_part.setLines(which->bd_lines);
fillBodyFields(target_part,which->bd_fields);
}
+void IMAPwrapper::fillMultiPart(RecPart&target_part,mailimap_body_type_mpart*which)
+{
+ if (!which) return;
+ target_part.setSubtype(which->bd_media_subtype);
+ 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(RecPart&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 = "";
}
qDebug("Type = %s/%s",type.latin1(),sub.latin1());
target_part.setType(type.lower());
target_part.setSubtype(sub.lower());
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillBodyFields(RecPart&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 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);
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) {
qDebug("error deleting mail: %s",m_imap->imap_response);
return;
}
qDebug("deleting mail: %s",m_imap->imap_response);
/* should we realy do that at this moment? */
err = mailimap_expunge(m_imap);
if (err != MAILIMAP_NO_ERROR) {
qDebug("error deleting mail: %s",m_imap->imap_response);
}
qDebug("Delete successfull %s",m_imap->imap_response);
}
void IMAPwrapper::answeredMail(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 mark: %s",m_imap->imap_response);
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) {
qDebug("error marking mail: %s",m_imap->imap_response);
return;
}
}
QString IMAPwrapper::fetchTextPart(const RecMail&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 RecMail&mail,const RecPart&part)
{
return fetchTextPart(mail,part.Positionlist(),false,part.Encoding());
}
encodedString* IMAPwrapper::fetchDecodedPart(const RecMail&mail,const RecPart&part)
{
encodedString*res = fetchRawPart(mail,part.Positionlist(),false);
encodedString*r = decode_String(res,part.Encoding());
delete res;
return r;
}
encodedString* IMAPwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
{
return fetchRawPart(mail,part.Positionlist(),false);
}
int IMAPwrapper::deleteAllMail(const Folder*folder)
{
login();
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h
index e5846f8..7941046 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.h
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.h
@@ -1,66 +1,67 @@
#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 QList<Folder>* listFolders();
virtual void listMessages(const QString & mailbox,QList<RecMail>&target );
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
virtual int deleteAllMail(const Folder*folder);
virtual RecBody fetchBody(const RecMail&mail);
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
virtual int createMbox(const QString&,const Folder*parentfolder=0,const QString& delemiter="/",bool getsubfolder=false);
virtual int deleteMbox(const Folder*folder);
static void imap_progress( size_t current, size_t maximum );
protected:
RecMail*parse_list_result(mailimap_msg_att*);
void login();
void logout();
virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc="");
virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call);
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);
- void traverseBody(const RecMail&mail,mailimap_body*body,RecBody&target_body,int current_recursion,QValueList<int>recList,int current_count=0);
+ void fillMultiPart(RecPart&target_part,mailimap_body_type_mpart*which);
+ void traverseBody(const RecMail&mail,mailimap_body*body,RecBody&target_body,int current_recursion,QValueList<int>recList,int current_count=1);
/* just helpers */
static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which);
static QStringList address_list_to_stringlist(clist*list);
IMAPaccount *account;
mailimap *m_imap;
};
#endif