summaryrefslogtreecommitdiffabout
path: root/kmicromail/libmailwrapper/imapwrapper.cpp
Side-by-side diff
Diffstat (limited to 'kmicromail/libmailwrapper/imapwrapper.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libmailwrapper/imapwrapper.cpp1182
1 files changed, 1182 insertions, 0 deletions
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);
+ }
+}