summaryrefslogtreecommitdiff
authoralwin <alwin>2003-12-21 21:33:49 (UTC)
committer alwin <alwin>2003-12-21 21:33:49 (UTC)
commit6e7358f954618d8fdbbe852df7df862c3c132bbd (patch) (side-by-side diff)
tree0e2a94a0a42393b811d85172677c117517db5fd4
parentfafcc882ba0d797d5aa8ed7f2f8d5518ba6d2960 (diff)
downloadopie-6e7358f954618d8fdbbe852df7df862c3c132bbd.zip
opie-6e7358f954618d8fdbbe852df7df862c3c132bbd.tar.gz
opie-6e7358f954618d8fdbbe852df7df862c3c132bbd.tar.bz2
- mbox-wrapper mostly finished
- special-folders "Local Folders" will be displayed ToDo: "STORE" - method for all wrapper, but mostly for mbox for send queue.
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/net/mail/abstractmail.cpp6
-rw-r--r--noncore/net/mail/abstractmail.h3
-rw-r--r--noncore/net/mail/accountview.cpp86
-rw-r--r--noncore/net/mail/accountview.h30
-rw-r--r--noncore/net/mail/genericwrapper.cpp393
-rw-r--r--noncore/net/mail/genericwrapper.h59
-rw-r--r--noncore/net/mail/libmailwrapper/abstractmail.cpp6
-rw-r--r--noncore/net/mail/libmailwrapper/abstractmail.h3
-rw-r--r--noncore/net/mail/libmailwrapper/genericwrapper.cpp393
-rw-r--r--noncore/net/mail/libmailwrapper/genericwrapper.h59
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.cpp412
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.h43
-rw-r--r--noncore/net/mail/mail.pro8
-rw-r--r--noncore/net/mail/pop3wrapper.cpp412
-rw-r--r--noncore/net/mail/pop3wrapper.h43
-rw-r--r--noncore/net/mail/viewmail.cpp1
16 files changed, 1074 insertions, 883 deletions
diff --git a/noncore/net/mail/abstractmail.cpp b/noncore/net/mail/abstractmail.cpp
index 3cb8f7d..416795b 100644
--- a/noncore/net/mail/abstractmail.cpp
+++ b/noncore/net/mail/abstractmail.cpp
@@ -1,84 +1,90 @@
#include "abstractmail.h"
#include "imapwrapper.h"
#include "pop3wrapper.h"
+#include "mboxwrapper.h"
#include "mailtypes.h"
#include <qstring.h>
#include <qfile.h>
#include <qtextstream.h>
#include <stdlib.h>
#include <libetpan/mailmime_content.h>
#include <libetpan/mailmime.h>
AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
{
return new IMAPwrapper(a);
}
AbstractMail* AbstractMail::getWrapper(POP3account *a)
{
return new POP3wrapper(a);
}
+AbstractMail* AbstractMail::getWrapper(const QString&a)
+{
+ return new MBOXwrapper(a);
+}
+
encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
{
qDebug("Decode string start");
char*result_text;
size_t index = 0;
/* reset for recursive use! */
size_t target_length = 0;
result_text = 0;
int mimetype = MAILMIME_MECHANISM_7BIT;
if (enc.lower()=="quoted-printable") {
mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
} else if (enc.lower()=="base64") {
mimetype = MAILMIME_MECHANISM_BASE64;
} else if (enc.lower()=="8bit") {
mimetype = MAILMIME_MECHANISM_8BIT;
} else if (enc.lower()=="binary") {
mimetype = MAILMIME_MECHANISM_BINARY;
}
int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype,
&result_text,&target_length);
encodedString* result = new encodedString();
if (err == MAILIMF_NO_ERROR) {
result->setContent(result_text,target_length);
}
qDebug("Decode string finished");
return result;
}
QString AbstractMail::convert_String(const char*text)
{
size_t index = 0;
char*res = 0;
/* attention - doesn't work with arm systems! */
int err = mailmime_encoded_phrase_parse("iso-8859-1",
text, strlen(text),&index, "iso-8859-1",&res);
if (err != MAILIMF_NO_ERROR) {
if (res) free(res);
return QString(text);
}
if (res) {
QString result(res);
free(res);
return result;
}
return QString(text);
}
/* cp & paste from launcher */
QString AbstractMail::gen_attachment_id()
{
QFile file( "/proc/sys/kernel/random/uuid" );
if (!file.open(IO_ReadOnly ) )
return QString::null;
QTextStream stream(&file);
return "{" + stream.read().stripWhiteSpace() + "}";
}
diff --git a/noncore/net/mail/abstractmail.h b/noncore/net/mail/abstractmail.h
index 8dd2e12..509b68e 100644
--- a/noncore/net/mail/abstractmail.h
+++ b/noncore/net/mail/abstractmail.h
@@ -1,39 +1,42 @@
#ifndef __abstract_mail_
#define __abstract_mail_
#include <qobject.h>
#include "settings.h"
class RecMail;
class RecBody;
class RecPart;
class IMAPwrapper;
class POP3wrapper;
class Folder;
class encodedString;
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 fetchTextPart(const RecMail&mail,const RecPart&part)=0;
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0;
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0;
virtual void deleteMail(const RecMail&mail)=0;
virtual void answeredMail(const RecMail&mail)=0;
+ virtual void cleanMimeCache(){};
static AbstractMail* getWrapper(IMAPaccount *a);
static AbstractMail* getWrapper(POP3account *a);
+ /* mbox only! */
+ static AbstractMail* getWrapper(const QString&a);
protected:
static encodedString*decode_String(const encodedString*text,const QString&enc);
static QString convert_String(const char*text);
static QString gen_attachment_id();
};
#endif
diff --git a/noncore/net/mail/accountview.cpp b/noncore/net/mail/accountview.cpp
index 71a0d74..6bc8b8b 100644
--- a/noncore/net/mail/accountview.cpp
+++ b/noncore/net/mail/accountview.cpp
@@ -1,295 +1,379 @@
+#include <stdlib.h>
#include "accountview.h"
#include "mailtypes.h"
#include "defines.h"
-
/**
* POP3 Account stuff
*/
POP3viewItem::POP3viewItem( POP3account *a, QListView *parent )
: AccountViewItem( parent )
{
account = a;
wrapper = AbstractMail::getWrapper( account );
setPixmap( 0, PIXMAP_POP3FOLDER );
setText( 0, account->getAccountName() );
setOpen( true );
}
POP3viewItem::~POP3viewItem()
{
delete wrapper;
}
AbstractMail *POP3viewItem::getWrapper()
{
return wrapper;
}
void POP3viewItem::refresh( QList<RecMail> & )
{
QList<Folder> *folders = wrapper->listFolders();
QListViewItem *child = firstChild();
while ( child ) {
QListViewItem *tmp = child;
child = child->nextSibling();
delete tmp;
}
Folder *it;
QListViewItem*item = 0;
for ( it = folders->first(); it; it = folders->next() ) {
item = new POP3folderItem( it, this , item );
item->setSelectable(it->may_select());
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
folders->setAutoDelete(false);
delete folders;
}
RecBody POP3viewItem::fetchBody( const RecMail &mail )
{
qDebug( "POP3 fetchBody" );
return wrapper->fetchBody( mail );
}
POP3folderItem::~POP3folderItem()
{
delete folder;
}
POP3folderItem::POP3folderItem( Folder *folderInit, POP3viewItem *parent , QListViewItem*after )
: AccountViewItem( parent,after )
{
folder = folderInit;
pop3 = parent;
if (folder->getDisplayName().lower()!="inbox") {
setPixmap( 0, PIXMAP_POP3FOLDER );
} else {
setPixmap( 0, PIXMAP_INBOXFOLDER);
}
setText( 0, folder->getDisplayName() );
}
void POP3folderItem::refresh(QList<RecMail>&target)
{
if (folder->may_select())
pop3->getWrapper()->listMessages( folder->getName(),target );
}
RecBody POP3folderItem::fetchBody(const RecMail&aMail)
{
return pop3->getWrapper()->fetchBody(aMail);
}
/**
* IMAP Account stuff
*/
IMAPviewItem::IMAPviewItem( IMAPaccount *a, QListView *parent )
: AccountViewItem( parent )
{
account = a;
wrapper = AbstractMail::getWrapper( account );
setPixmap( 0, PIXMAP_IMAPFOLDER );
setText( 0, account->getAccountName() );
setOpen( true );
}
IMAPviewItem::~IMAPviewItem()
{
delete wrapper;
}
AbstractMail *IMAPviewItem::getWrapper()
{
return wrapper;
}
IMAPfolderItem*IMAPviewItem::findSubItem(const QString&path,IMAPfolderItem*start)
{
IMAPfolderItem*pitem,*sitem;
if (!start) pitem = (IMAPfolderItem*)firstChild();
else pitem = (IMAPfolderItem*)start->firstChild();
while (pitem) {
if (pitem->matchName(path)) {
break;
}
if (pitem->childCount()>0) {
sitem = findSubItem(path,pitem);
if (sitem) {
pitem = sitem;
break;
}
}
pitem=(IMAPfolderItem*)pitem->nextSibling();
}
return pitem;
}
void IMAPviewItem::refresh(QList<RecMail>&)
{
if (childCount()>0) return;
QList<Folder> *folders = wrapper->listFolders();
QListViewItem *child = firstChild();
while ( child ) {
QListViewItem *tmp = child;
child = child->nextSibling();
delete tmp;
}
Folder *it;
QListViewItem*item = 0;
QListViewItem*titem = 0;
QString fname,del,search;
int pos;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
folders->setAutoDelete(false);
for ( it = folders->first(); it; it = folders->next() ) {
if (it->getDisplayName().lower()=="inbox") {
item = new IMAPfolderItem( it, this , item );
folders->remove(it);
qDebug("inbox found");
break;
}
}
for ( it = folders->first(); it; it = folders->next() ) {
fname = it->getDisplayName();
pos = fname.findRev(it->Separator());
if (pos != -1) {
fname = fname.left(pos);
}
IMAPfolderItem*pitem = findSubItem(fname);
if (pitem) {
titem = item;
item = new IMAPfolderItem(it,pitem,pitem->firstChild(),this);
item->setSelectable(it->may_select());
/* setup the short name */
item->setText(0,it->getDisplayName().right(it->getDisplayName().length()-pos-1));
item = titem;
} else {
item = new IMAPfolderItem( it, this , item );
item->setSelectable(it->may_select());
}
}
delete folders;
}
RecBody IMAPviewItem::fetchBody(const RecMail&)
{
return RecBody();
}
IMAPfolderItem::~IMAPfolderItem()
{
delete folder;
}
IMAPfolderItem::IMAPfolderItem( Folder *folderInit, IMAPviewItem *parent , QListViewItem*after )
: AccountViewItem( parent , after )
{
folder = folderInit;
imap = parent;
if (folder->getDisplayName().lower()!="inbox") {
setPixmap( 0, PIXMAP_IMAPFOLDER );
} else {
setPixmap( 0, PIXMAP_INBOXFOLDER);
}
setText( 0, folder->getDisplayName() );
}
IMAPfolderItem::IMAPfolderItem( Folder *folderInit, IMAPfolderItem *parent , QListViewItem*after, IMAPviewItem *master )
: AccountViewItem( parent,after )
{
folder = folderInit;
imap = master;
if (folder->getDisplayName().lower()!="inbox") {
setPixmap( 0, PIXMAP_IMAPFOLDER );
} else {
setPixmap( 0, PIXMAP_INBOXFOLDER);
}
setText( 0, folder->getDisplayName() );
}
bool IMAPfolderItem::matchName(const QString&name)const
{
return folder->getDisplayName()==name;
}
void IMAPfolderItem::refresh(QList<RecMail>&target)
{
if (folder->may_select())
imap->getWrapper()->listMessages( folder->getName(),target );
}
RecBody IMAPfolderItem::fetchBody(const RecMail&aMail)
{
return imap->getWrapper()->fetchBody(aMail);
}
+
/**
* Generic stuff
*/
AccountView::AccountView( QWidget *parent, const char *name, WFlags flags )
: QListView( parent, name, flags )
{
connect( this, SIGNAL( selectionChanged( QListViewItem * ) ),
SLOT( refresh( QListViewItem * ) ) );
setSorting(0);
}
void AccountView::populate( QList<Account> list )
{
clear();
+ QString localfolders = (QString) getenv( "HOME" ) + QString("/Applications/opiemail/localmail/");
+ (void) new MBOXviewItem(localfolders,this);
+
Account *it;
for ( it = list.first(); it; it = list.next() ) {
if ( it->getType().compare( "IMAP" ) == 0 ) {
IMAPaccount *imap = static_cast<IMAPaccount *>(it);
qDebug( "added IMAP " + imap->getAccountName() );
(void) new IMAPviewItem( imap, this );
} else if ( it->getType().compare( "POP3" ) == 0 ) {
POP3account *pop3 = static_cast<POP3account *>(it);
qDebug( "added POP3 " + pop3->getAccountName() );
(void) new POP3viewItem( pop3, this );
}
}
}
void AccountView::refresh(QListViewItem *item) {
qDebug("AccountView refresh...");
if ( item ) {
m_currentItem = item;
QList<RecMail> headerlist;
headerlist.setAutoDelete(true);
AccountViewItem *view = static_cast<AccountViewItem *>(item);
view->refresh(headerlist);
emit refreshMailview(&headerlist);
}
}
void AccountView::refreshCurrent()
{
if ( !m_currentItem ) return;
QList<RecMail> headerlist;
headerlist.setAutoDelete(true);
AccountViewItem *view = static_cast<AccountViewItem *>(m_currentItem);
view->refresh(headerlist);
emit refreshMailview(&headerlist);
}
void AccountView::refreshAll()
{
}
RecBody AccountView::fetchBody(const RecMail&aMail)
{
QListViewItem*item = selectedItem ();
if (!item) return RecBody();
AccountViewItem *view = static_cast<AccountViewItem *>(item);
return view->fetchBody(aMail);
}
+
+/**
+ * MBOX Account stuff
+ */
+
+MBOXviewItem::MBOXviewItem( const QString&aPath, QListView *parent )
+ : AccountViewItem( parent )
+{
+ m_Path = aPath;
+ wrapper = AbstractMail::getWrapper( m_Path );
+ setPixmap( 0, PIXMAP_POP3FOLDER );
+ setText( 0, " Local Folders" );
+ setOpen( true );
+}
+
+MBOXviewItem::~MBOXviewItem()
+{
+ delete wrapper;
+}
+
+AbstractMail *MBOXviewItem::getWrapper()
+{
+ return wrapper;
+}
+
+void MBOXviewItem::refresh( QList<RecMail> & )
+{
+ QList<Folder> *folders = wrapper->listFolders();
+ QListViewItem *child = firstChild();
+ while ( child ) {
+ QListViewItem *tmp = child;
+ child = child->nextSibling();
+ delete tmp;
+ }
+ Folder *it;
+ QListViewItem*item = 0;
+ for ( it = folders->first(); it; it = folders->next() ) {
+ item = new MBOXfolderItem( it, this , item );
+ item->setSelectable(it->may_select());
+ }
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ folders->setAutoDelete(false);
+ delete folders;
+}
+
+RecBody MBOXviewItem::fetchBody( const RecMail &mail )
+{
+ qDebug( "POP3 fetchBody" );
+ return wrapper->fetchBody( mail );
+}
+
+MBOXfolderItem::~MBOXfolderItem()
+{
+ delete folder;
+}
+
+MBOXfolderItem::MBOXfolderItem( Folder *folderInit, MBOXviewItem *parent , QListViewItem*after )
+ : AccountViewItem( parent,after )
+{
+ folder = folderInit;
+ mbox = parent;
+ if (folder->getDisplayName().lower()!="inbox") {
+ setPixmap( 0, PIXMAP_POP3FOLDER );
+ } else {
+ setPixmap( 0, PIXMAP_INBOXFOLDER);
+ }
+ setText( 0, folder->getDisplayName() );
+}
+
+void MBOXfolderItem::refresh(QList<RecMail>&target)
+{
+ if (folder->may_select())
+ mbox->getWrapper()->listMessages( folder->getName(),target );
+}
+
+RecBody MBOXfolderItem::fetchBody(const RecMail&aMail)
+{
+ return mbox->getWrapper()->fetchBody(aMail);
+}
+
diff --git a/noncore/net/mail/accountview.h b/noncore/net/mail/accountview.h
index 64abed9..35499ac 100644
--- a/noncore/net/mail/accountview.h
+++ b/noncore/net/mail/accountview.h
@@ -1,110 +1,140 @@
#ifndef ACCOUNTVIEW_H
#define ACCOUNTVIEW_H
#include <qlistview.h>
#include <qlist.h>
#include "settings.h"
#include "mailwrapper.h"
#include "abstractmail.h"
class POP3wrapper;
class RecMail;
class RecBody;
class AccountViewItem : public QListViewItem
{
public:
AccountViewItem( QListView *parent ) : QListViewItem( parent ) {}
AccountViewItem( QListViewItem *parent) : QListViewItem( parent) {}
AccountViewItem( QListViewItem *parent , QListViewItem*after ) : QListViewItem( parent,after ) {}
virtual void refresh(QList<RecMail>&)=0;
virtual RecBody fetchBody(const RecMail&)=0;
};
class POP3viewItem : public AccountViewItem
{
public:
POP3viewItem( POP3account *a, QListView *parent );
~POP3viewItem();
virtual void refresh( QList<RecMail> &target );
virtual RecBody fetchBody( const RecMail &mail );
AbstractMail *getWrapper();
private:
POP3account *account;
AbstractMail *wrapper;
};
class POP3folderItem : public AccountViewItem
{
public:
POP3folderItem( Folder *folder, POP3viewItem *parent , QListViewItem*after );
~POP3folderItem();
virtual void refresh(QList<RecMail>&);
virtual RecBody fetchBody(const RecMail&);
private:
Folder *folder;
POP3viewItem *pop3;
};
class IMAPfolderItem;
class IMAPviewItem : public AccountViewItem
{
public:
IMAPviewItem( IMAPaccount *a, QListView *parent );
~IMAPviewItem();
virtual void refresh(QList<RecMail>&);
virtual RecBody fetchBody(const RecMail&);
AbstractMail *getWrapper();
protected:
IMAPfolderItem*findSubItem(const QString&path,IMAPfolderItem*start=0);
private:
IMAPaccount *account;
AbstractMail *wrapper;
};
class IMAPfolderItem : public AccountViewItem
{
public:
IMAPfolderItem( Folder *folder, IMAPviewItem *parent , QListViewItem*after );
IMAPfolderItem( Folder *folder, IMAPfolderItem *parent , QListViewItem*after, IMAPviewItem *master );
~IMAPfolderItem();
virtual void refresh(QList<RecMail>&);
virtual RecBody fetchBody(const RecMail&);
bool matchName(const QString&name)const;
private:
Folder *folder;
IMAPviewItem *imap;
};
+class MBOXviewItem : public AccountViewItem
+{
+
+public:
+// MBOXviewItem( MBOXaccount *a, QListView *parent );
+ MBOXviewItem( const QString&aMboxPath, QListView *parent );
+ ~MBOXviewItem();
+ virtual void refresh( QList<RecMail> &target );
+ virtual RecBody fetchBody( const RecMail &mail );
+ AbstractMail *getWrapper();
+private:
+// MBOXaccount *account;
+ QString m_Path;
+ AbstractMail *wrapper;
+
+};
+
+class MBOXfolderItem : public AccountViewItem
+{
+
+public:
+ MBOXfolderItem( Folder *folder, MBOXviewItem *parent , QListViewItem*after );
+ ~MBOXfolderItem();
+ virtual void refresh(QList<RecMail>&);
+ virtual RecBody fetchBody(const RecMail&);
+private:
+ Folder *folder;
+ MBOXviewItem *mbox;
+};
+
class AccountView : public QListView
{
Q_OBJECT
public:
AccountView( QWidget *parent = 0, const char *name = 0, WFlags flags = 0 );
void populate( QList<Account> list );
RecBody fetchBody(const RecMail&aMail);
public slots:
void refreshAll();
void refresh(QListViewItem *item);
void refreshCurrent();
signals:
void refreshMailview(QList<RecMail>*);
private:
QListViewItem* m_currentItem;
};
#endif
diff --git a/noncore/net/mail/genericwrapper.cpp b/noncore/net/mail/genericwrapper.cpp
new file mode 100644
index 0000000..447cad0
--- a/dev/null
+++ b/noncore/net/mail/genericwrapper.cpp
@@ -0,0 +1,393 @@
+#include "genericwrapper.h"
+#include <libetpan/mailmime.h>
+#include <libetpan/data_message_driver.h>
+#include "mailtypes.h"
+
+Genericwrapper::Genericwrapper()
+ : AbstractMail()
+{
+ bodyCache.clear();
+}
+
+Genericwrapper::~Genericwrapper()
+{
+ cleanMimeCache();
+}
+
+void Genericwrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
+{
+ if (!mime) {
+ return;
+ }
+ mailmime_field*field = 0;
+ mailmime_single_fields fields;
+ memset(&fields, 0, sizeof(struct mailmime_single_fields));
+ if (mime->mm_mime_fields != NULL) {
+ mailmime_single_fields_init(&fields, mime->mm_mime_fields,
+ mime->mm_content_type);
+ }
+
+ mailmime_content*type = fields.fld_content;
+ clistcell*current;
+ if (!type) {
+ target.setType("text");
+ target.setSubtype("plain");
+ } else {
+ target.setSubtype(type->ct_subtype);
+ switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
+ case MAILMIME_DISCRETE_TYPE_TEXT:
+ target.setType("text");
+ break;
+ case MAILMIME_DISCRETE_TYPE_IMAGE:
+ target.setType("image");
+ break;
+ case MAILMIME_DISCRETE_TYPE_AUDIO:
+ target.setType("audio");
+ break;
+ case MAILMIME_DISCRETE_TYPE_VIDEO:
+ target.setType("video");
+ break;
+ case MAILMIME_DISCRETE_TYPE_APPLICATION:
+ target.setType("application");
+ break;
+ case MAILMIME_DISCRETE_TYPE_EXTENSION:
+ default:
+ if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
+ target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
+ }
+ break;
+ }
+ if (type->ct_parameters) {
+ fillParameters(target,type->ct_parameters);
+ }
+ }
+ if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
+ for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
+ field = (mailmime_field*)current->data;
+ switch(field->fld_type) {
+ case MAILMIME_FIELD_TRANSFER_ENCODING:
+ target.setEncoding(getencoding(field->fld_data.fld_encoding));
+ break;
+ case MAILMIME_FIELD_ID:
+ target.setIdentifier(field->fld_data.fld_id);
+ break;
+ case MAILMIME_FIELD_DESCRIPTION:
+ target.setDescription(field->fld_data.fld_description);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+void Genericwrapper::fillParameters(RecPart&target,clist*parameters)
+{
+ if (!parameters) {return;}
+ clistcell*current=0;
+ mailmime_parameter*param;
+ for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
+ param = (mailmime_parameter*)current->data;
+ if (param) {
+ target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
+ }
+ }
+}
+
+QString Genericwrapper::getencoding(mailmime_mechanism*aEnc)
+{
+ QString enc="7bit";
+ if (!aEnc) return enc;
+ switch(aEnc->enc_type) {
+ case MAILMIME_MECHANISM_7BIT:
+ enc = "7bit";
+ break;
+ case MAILMIME_MECHANISM_8BIT:
+ enc = "8bit";
+ break;
+ case MAILMIME_MECHANISM_BINARY:
+ enc = "binary";
+ break;
+ case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
+ enc = "quoted-printable";
+ break;
+ case MAILMIME_MECHANISM_BASE64:
+ enc = "base64";
+ break;
+ case MAILMIME_MECHANISM_TOKEN:
+ default:
+ if (aEnc->enc_token) {
+ enc = QString(aEnc->enc_token);
+ }
+ break;
+ }
+ return enc;
+}
+
+void Genericwrapper::traverseBody(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;
+ QString b;
+ RecPart part;
+
+ switch (mime->mm_type) {
+ case MAILMIME_SINGLE:
+ r = mailmessage_fetch_section(message,mime,&data,&len);
+ part.setSize(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 {
+ b = gen_attachment_id();
+ part.setIdentifier(b);
+ bodyCache[b]=new encodedString(data,len);
+ 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;
+ }
+}
+
+RecBody Genericwrapper::parseMail( mailmessage * msg )
+{
+ int err = MAILIMF_NO_ERROR;
+ mailmime_single_fields fields;
+ /* is bound to msg and will be freed there */
+ mailmime * mime=0;
+ RecBody body;
+ memset(&fields, 0, sizeof(struct mailmime_single_fields));
+ err = mailmessage_get_bodystructure(msg,&mime);
+ traverseBody(body,msg,mime);
+ return body;
+}
+
+RecMail *Genericwrapper::parseHeader( const char *header )
+{
+ int err = MAILIMF_NO_ERROR;
+ size_t curTok = 0;
+ RecMail *mail = new RecMail();
+ mailimf_fields *fields;
+ mailimf_references * refs;
+ mailimf_keywords*keys;
+ QString status;
+ QString value;
+ QBitArray mFlags(7);
+
+ err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
+ for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
+ mailimf_field *field = (mailimf_field *) current->data;
+ switch ( field->fld_type ) {
+ case MAILIMF_FIELD_FROM:
+ mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
+ break;
+ case MAILIMF_FIELD_TO:
+ mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
+ break;
+ case MAILIMF_FIELD_CC:
+ mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
+ break;
+ case MAILIMF_FIELD_BCC:
+ mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
+ break;
+ case MAILIMF_FIELD_SUBJECT:
+ mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
+ break;
+ case MAILIMF_FIELD_ORIG_DATE:
+ mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
+ break;
+ case MAILIMF_FIELD_MESSAGE_ID:
+ mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
+ break;
+ case MAILIMF_FIELD_REFERENCES:
+ refs = field->fld_data.fld_references;
+ if (refs && refs->mid_list && clist_count(refs->mid_list)) {
+ char * text = (char*)refs->mid_list->first->data;
+ mail->setReplyto(QString(text));
+ }
+ break;
+ case MAILIMF_FIELD_KEYWORDS:
+ keys = field->fld_data.fld_keywords;
+ for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
+ qDebug("Keyword: %s",(char*)cur->data);
+ }
+ break;
+ case MAILIMF_FIELD_OPTIONAL_FIELD:
+ status = field->fld_data.fld_optional_field->fld_name;
+ value = field->fld_data.fld_optional_field->fld_value;
+ if (status.lower()=="status") {
+ if (value.lower()=="ro") {
+ mFlags.setBit(FLAG_SEEN);
+ }
+ } else if (status.lower()=="x-status") {
+ qDebug("X-Status: %s",value.latin1());
+ if (value.lower()=="a") {
+ mFlags.setBit(FLAG_ANSWERED);
+ }
+ } else {
+// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
+// field->fld_data.fld_optional_field->fld_value);
+ }
+ break;
+ default:
+ qDebug("Non parsed field");
+ break;
+ }
+ }
+ if (fields) mailimf_fields_free(fields);
+ mail->setFlags(mFlags);
+ return mail;
+}
+
+QString Genericwrapper::parseDateTime( mailimf_date_time *date )
+{
+ char tmp[23];
+
+ snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
+ date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
+
+ return QString( tmp );
+}
+
+QString Genericwrapper::parseAddressList( mailimf_address_list *list )
+{
+ QString result( "" );
+
+ bool first = true;
+ if (list == 0) return result;
+ for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
+ mailimf_address *addr = (mailimf_address *) current->data;
+
+ if ( !first ) {
+ result.append( "," );
+ } else {
+ first = false;
+ }
+
+ switch ( addr->ad_type ) {
+ case MAILIMF_ADDRESS_MAILBOX:
+ result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
+ break;
+ case MAILIMF_ADDRESS_GROUP:
+ result.append( parseGroup( addr->ad_data.ad_group ) );
+ break;
+ default:
+ qDebug( "Generic: unkown mailimf address type" );
+ break;
+ }
+ }
+
+ return result;
+}
+
+QString Genericwrapper::parseGroup( mailimf_group *group )
+{
+ QString result( "" );
+
+ result.append( group->grp_display_name );
+ result.append( ": " );
+
+ if ( group->grp_mb_list != NULL ) {
+ result.append( parseMailboxList( group->grp_mb_list ) );
+ }
+
+ result.append( ";" );
+
+ return result;
+}
+
+QString Genericwrapper::parseMailbox( mailimf_mailbox *box )
+{
+ QString result( "" );
+
+ if ( box->mb_display_name == NULL ) {
+ result.append( box->mb_addr_spec );
+ } else {
+ result.append( convert_String(box->mb_display_name).latin1() );
+ result.append( " <" );
+ result.append( box->mb_addr_spec );
+ result.append( ">" );
+ }
+
+ return result;
+}
+
+QString Genericwrapper::parseMailboxList( mailimf_mailbox_list *list )
+{
+ QString result( "" );
+
+ bool first = true;
+ for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
+ mailimf_mailbox *box = (mailimf_mailbox *) current->data;
+
+ if ( !first ) {
+ result.append( "," );
+ } else {
+ first = false;
+ }
+
+ result.append( parseMailbox( box ) );
+ }
+
+ return result;
+}
+
+encodedString* Genericwrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
+{
+ QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
+ if (it==bodyCache.end()) return new encodedString();
+ encodedString*t = decode_String(it.data(),part.Encoding());
+ return t;
+}
+
+encodedString* Genericwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
+{
+ QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
+ if (it==bodyCache.end()) return new encodedString();
+ encodedString*t = it.data();
+ return t;
+}
+
+QString Genericwrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
+{
+ encodedString*t = fetchDecodedPart(mail,part);
+ QString text=t->Content();
+ delete t;
+ return text;
+}
+
+void Genericwrapper::cleanMimeCache()
+{
+ QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
+ for (;it!=bodyCache.end();++it) {
+ encodedString*t = it.data();
+ //it.setValue(0);
+ if (t) delete t;
+ }
+ bodyCache.clear();
+ qDebug("Genericwrapper: cache cleaned");
+}
diff --git a/noncore/net/mail/genericwrapper.h b/noncore/net/mail/genericwrapper.h
new file mode 100644
index 0000000..12f6928
--- a/dev/null
+++ b/noncore/net/mail/genericwrapper.h
@@ -0,0 +1,59 @@
+#ifndef __GENERIC_WRAPPER_H
+#define __GENERIC_WRAPPER_H
+
+#include "abstractmail.h"
+#include <qmap.h>
+#include <qstring.h>
+#include <libetpan/clist.h>
+
+class RecMail;
+class RecBody;
+class encodedString;
+struct mailpop3;
+struct mailmessage;
+struct mailmime;
+struct mailmime_mechanism;
+struct mailimf_mailbox_list;
+struct mailimf_mailbox;
+struct mailimf_date_time;
+struct mailimf_group;
+struct mailimf_address_list;
+
+/* this class hold just the funs shared between
+ * mbox and pop3 (later mh, too) mail access.
+ * it is not desigend to make a instance of it!
+ */
+class Genericwrapper : public AbstractMail
+{
+ Q_OBJECT
+public:
+ Genericwrapper();
+ virtual ~Genericwrapper();
+
+ virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
+ virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
+ virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
+ virtual void cleanMimeCache();
+
+protected:
+ RecMail *parseHeader( const char *header );
+ RecBody parseMail( mailmessage * msg );
+ QString parseMailboxList( mailimf_mailbox_list *list );
+ QString parseMailbox( mailimf_mailbox *box );
+ QString parseGroup( mailimf_group *group );
+ QString parseAddressList( mailimf_address_list *list );
+ QString parseDateTime( mailimf_date_time *date );
+
+ void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
+ static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
+ static void fillParameters(RecPart&target,clist*parameters);
+ static QString getencoding(mailmime_mechanism*aEnc);
+
+ POP3account *account;
+ mailpop3 *m_pop3;
+ QString msgTempName;
+ unsigned int last_msg_id;
+ QMap<QString,encodedString*> bodyCache;
+};
+
+#endif
diff --git a/noncore/net/mail/libmailwrapper/abstractmail.cpp b/noncore/net/mail/libmailwrapper/abstractmail.cpp
index 3cb8f7d..416795b 100644
--- a/noncore/net/mail/libmailwrapper/abstractmail.cpp
+++ b/noncore/net/mail/libmailwrapper/abstractmail.cpp
@@ -1,84 +1,90 @@
#include "abstractmail.h"
#include "imapwrapper.h"
#include "pop3wrapper.h"
+#include "mboxwrapper.h"
#include "mailtypes.h"
#include <qstring.h>
#include <qfile.h>
#include <qtextstream.h>
#include <stdlib.h>
#include <libetpan/mailmime_content.h>
#include <libetpan/mailmime.h>
AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
{
return new IMAPwrapper(a);
}
AbstractMail* AbstractMail::getWrapper(POP3account *a)
{
return new POP3wrapper(a);
}
+AbstractMail* AbstractMail::getWrapper(const QString&a)
+{
+ return new MBOXwrapper(a);
+}
+
encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
{
qDebug("Decode string start");
char*result_text;
size_t index = 0;
/* reset for recursive use! */
size_t target_length = 0;
result_text = 0;
int mimetype = MAILMIME_MECHANISM_7BIT;
if (enc.lower()=="quoted-printable") {
mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
} else if (enc.lower()=="base64") {
mimetype = MAILMIME_MECHANISM_BASE64;
} else if (enc.lower()=="8bit") {
mimetype = MAILMIME_MECHANISM_8BIT;
} else if (enc.lower()=="binary") {
mimetype = MAILMIME_MECHANISM_BINARY;
}
int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype,
&result_text,&target_length);
encodedString* result = new encodedString();
if (err == MAILIMF_NO_ERROR) {
result->setContent(result_text,target_length);
}
qDebug("Decode string finished");
return result;
}
QString AbstractMail::convert_String(const char*text)
{
size_t index = 0;
char*res = 0;
/* attention - doesn't work with arm systems! */
int err = mailmime_encoded_phrase_parse("iso-8859-1",
text, strlen(text),&index, "iso-8859-1",&res);
if (err != MAILIMF_NO_ERROR) {
if (res) free(res);
return QString(text);
}
if (res) {
QString result(res);
free(res);
return result;
}
return QString(text);
}
/* cp & paste from launcher */
QString AbstractMail::gen_attachment_id()
{
QFile file( "/proc/sys/kernel/random/uuid" );
if (!file.open(IO_ReadOnly ) )
return QString::null;
QTextStream stream(&file);
return "{" + stream.read().stripWhiteSpace() + "}";
}
diff --git a/noncore/net/mail/libmailwrapper/abstractmail.h b/noncore/net/mail/libmailwrapper/abstractmail.h
index 8dd2e12..509b68e 100644
--- a/noncore/net/mail/libmailwrapper/abstractmail.h
+++ b/noncore/net/mail/libmailwrapper/abstractmail.h
@@ -1,39 +1,42 @@
#ifndef __abstract_mail_
#define __abstract_mail_
#include <qobject.h>
#include "settings.h"
class RecMail;
class RecBody;
class RecPart;
class IMAPwrapper;
class POP3wrapper;
class Folder;
class encodedString;
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 fetchTextPart(const RecMail&mail,const RecPart&part)=0;
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0;
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0;
virtual void deleteMail(const RecMail&mail)=0;
virtual void answeredMail(const RecMail&mail)=0;
+ virtual void cleanMimeCache(){};
static AbstractMail* getWrapper(IMAPaccount *a);
static AbstractMail* getWrapper(POP3account *a);
+ /* mbox only! */
+ static AbstractMail* getWrapper(const QString&a);
protected:
static encodedString*decode_String(const encodedString*text,const QString&enc);
static QString convert_String(const char*text);
static QString gen_attachment_id();
};
#endif
diff --git a/noncore/net/mail/libmailwrapper/genericwrapper.cpp b/noncore/net/mail/libmailwrapper/genericwrapper.cpp
new file mode 100644
index 0000000..447cad0
--- a/dev/null
+++ b/noncore/net/mail/libmailwrapper/genericwrapper.cpp
@@ -0,0 +1,393 @@
+#include "genericwrapper.h"
+#include <libetpan/mailmime.h>
+#include <libetpan/data_message_driver.h>
+#include "mailtypes.h"
+
+Genericwrapper::Genericwrapper()
+ : AbstractMail()
+{
+ bodyCache.clear();
+}
+
+Genericwrapper::~Genericwrapper()
+{
+ cleanMimeCache();
+}
+
+void Genericwrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
+{
+ if (!mime) {
+ return;
+ }
+ mailmime_field*field = 0;
+ mailmime_single_fields fields;
+ memset(&fields, 0, sizeof(struct mailmime_single_fields));
+ if (mime->mm_mime_fields != NULL) {
+ mailmime_single_fields_init(&fields, mime->mm_mime_fields,
+ mime->mm_content_type);
+ }
+
+ mailmime_content*type = fields.fld_content;
+ clistcell*current;
+ if (!type) {
+ target.setType("text");
+ target.setSubtype("plain");
+ } else {
+ target.setSubtype(type->ct_subtype);
+ switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
+ case MAILMIME_DISCRETE_TYPE_TEXT:
+ target.setType("text");
+ break;
+ case MAILMIME_DISCRETE_TYPE_IMAGE:
+ target.setType("image");
+ break;
+ case MAILMIME_DISCRETE_TYPE_AUDIO:
+ target.setType("audio");
+ break;
+ case MAILMIME_DISCRETE_TYPE_VIDEO:
+ target.setType("video");
+ break;
+ case MAILMIME_DISCRETE_TYPE_APPLICATION:
+ target.setType("application");
+ break;
+ case MAILMIME_DISCRETE_TYPE_EXTENSION:
+ default:
+ if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
+ target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
+ }
+ break;
+ }
+ if (type->ct_parameters) {
+ fillParameters(target,type->ct_parameters);
+ }
+ }
+ if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
+ for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
+ field = (mailmime_field*)current->data;
+ switch(field->fld_type) {
+ case MAILMIME_FIELD_TRANSFER_ENCODING:
+ target.setEncoding(getencoding(field->fld_data.fld_encoding));
+ break;
+ case MAILMIME_FIELD_ID:
+ target.setIdentifier(field->fld_data.fld_id);
+ break;
+ case MAILMIME_FIELD_DESCRIPTION:
+ target.setDescription(field->fld_data.fld_description);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+void Genericwrapper::fillParameters(RecPart&target,clist*parameters)
+{
+ if (!parameters) {return;}
+ clistcell*current=0;
+ mailmime_parameter*param;
+ for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
+ param = (mailmime_parameter*)current->data;
+ if (param) {
+ target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
+ }
+ }
+}
+
+QString Genericwrapper::getencoding(mailmime_mechanism*aEnc)
+{
+ QString enc="7bit";
+ if (!aEnc) return enc;
+ switch(aEnc->enc_type) {
+ case MAILMIME_MECHANISM_7BIT:
+ enc = "7bit";
+ break;
+ case MAILMIME_MECHANISM_8BIT:
+ enc = "8bit";
+ break;
+ case MAILMIME_MECHANISM_BINARY:
+ enc = "binary";
+ break;
+ case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
+ enc = "quoted-printable";
+ break;
+ case MAILMIME_MECHANISM_BASE64:
+ enc = "base64";
+ break;
+ case MAILMIME_MECHANISM_TOKEN:
+ default:
+ if (aEnc->enc_token) {
+ enc = QString(aEnc->enc_token);
+ }
+ break;
+ }
+ return enc;
+}
+
+void Genericwrapper::traverseBody(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;
+ QString b;
+ RecPart part;
+
+ switch (mime->mm_type) {
+ case MAILMIME_SINGLE:
+ r = mailmessage_fetch_section(message,mime,&data,&len);
+ part.setSize(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 {
+ b = gen_attachment_id();
+ part.setIdentifier(b);
+ bodyCache[b]=new encodedString(data,len);
+ 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;
+ }
+}
+
+RecBody Genericwrapper::parseMail( mailmessage * msg )
+{
+ int err = MAILIMF_NO_ERROR;
+ mailmime_single_fields fields;
+ /* is bound to msg and will be freed there */
+ mailmime * mime=0;
+ RecBody body;
+ memset(&fields, 0, sizeof(struct mailmime_single_fields));
+ err = mailmessage_get_bodystructure(msg,&mime);
+ traverseBody(body,msg,mime);
+ return body;
+}
+
+RecMail *Genericwrapper::parseHeader( const char *header )
+{
+ int err = MAILIMF_NO_ERROR;
+ size_t curTok = 0;
+ RecMail *mail = new RecMail();
+ mailimf_fields *fields;
+ mailimf_references * refs;
+ mailimf_keywords*keys;
+ QString status;
+ QString value;
+ QBitArray mFlags(7);
+
+ err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
+ for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
+ mailimf_field *field = (mailimf_field *) current->data;
+ switch ( field->fld_type ) {
+ case MAILIMF_FIELD_FROM:
+ mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
+ break;
+ case MAILIMF_FIELD_TO:
+ mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
+ break;
+ case MAILIMF_FIELD_CC:
+ mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
+ break;
+ case MAILIMF_FIELD_BCC:
+ mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
+ break;
+ case MAILIMF_FIELD_SUBJECT:
+ mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
+ break;
+ case MAILIMF_FIELD_ORIG_DATE:
+ mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
+ break;
+ case MAILIMF_FIELD_MESSAGE_ID:
+ mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
+ break;
+ case MAILIMF_FIELD_REFERENCES:
+ refs = field->fld_data.fld_references;
+ if (refs && refs->mid_list && clist_count(refs->mid_list)) {
+ char * text = (char*)refs->mid_list->first->data;
+ mail->setReplyto(QString(text));
+ }
+ break;
+ case MAILIMF_FIELD_KEYWORDS:
+ keys = field->fld_data.fld_keywords;
+ for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
+ qDebug("Keyword: %s",(char*)cur->data);
+ }
+ break;
+ case MAILIMF_FIELD_OPTIONAL_FIELD:
+ status = field->fld_data.fld_optional_field->fld_name;
+ value = field->fld_data.fld_optional_field->fld_value;
+ if (status.lower()=="status") {
+ if (value.lower()=="ro") {
+ mFlags.setBit(FLAG_SEEN);
+ }
+ } else if (status.lower()=="x-status") {
+ qDebug("X-Status: %s",value.latin1());
+ if (value.lower()=="a") {
+ mFlags.setBit(FLAG_ANSWERED);
+ }
+ } else {
+// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
+// field->fld_data.fld_optional_field->fld_value);
+ }
+ break;
+ default:
+ qDebug("Non parsed field");
+ break;
+ }
+ }
+ if (fields) mailimf_fields_free(fields);
+ mail->setFlags(mFlags);
+ return mail;
+}
+
+QString Genericwrapper::parseDateTime( mailimf_date_time *date )
+{
+ char tmp[23];
+
+ snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
+ date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
+
+ return QString( tmp );
+}
+
+QString Genericwrapper::parseAddressList( mailimf_address_list *list )
+{
+ QString result( "" );
+
+ bool first = true;
+ if (list == 0) return result;
+ for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
+ mailimf_address *addr = (mailimf_address *) current->data;
+
+ if ( !first ) {
+ result.append( "," );
+ } else {
+ first = false;
+ }
+
+ switch ( addr->ad_type ) {
+ case MAILIMF_ADDRESS_MAILBOX:
+ result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
+ break;
+ case MAILIMF_ADDRESS_GROUP:
+ result.append( parseGroup( addr->ad_data.ad_group ) );
+ break;
+ default:
+ qDebug( "Generic: unkown mailimf address type" );
+ break;
+ }
+ }
+
+ return result;
+}
+
+QString Genericwrapper::parseGroup( mailimf_group *group )
+{
+ QString result( "" );
+
+ result.append( group->grp_display_name );
+ result.append( ": " );
+
+ if ( group->grp_mb_list != NULL ) {
+ result.append( parseMailboxList( group->grp_mb_list ) );
+ }
+
+ result.append( ";" );
+
+ return result;
+}
+
+QString Genericwrapper::parseMailbox( mailimf_mailbox *box )
+{
+ QString result( "" );
+
+ if ( box->mb_display_name == NULL ) {
+ result.append( box->mb_addr_spec );
+ } else {
+ result.append( convert_String(box->mb_display_name).latin1() );
+ result.append( " <" );
+ result.append( box->mb_addr_spec );
+ result.append( ">" );
+ }
+
+ return result;
+}
+
+QString Genericwrapper::parseMailboxList( mailimf_mailbox_list *list )
+{
+ QString result( "" );
+
+ bool first = true;
+ for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
+ mailimf_mailbox *box = (mailimf_mailbox *) current->data;
+
+ if ( !first ) {
+ result.append( "," );
+ } else {
+ first = false;
+ }
+
+ result.append( parseMailbox( box ) );
+ }
+
+ return result;
+}
+
+encodedString* Genericwrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
+{
+ QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
+ if (it==bodyCache.end()) return new encodedString();
+ encodedString*t = decode_String(it.data(),part.Encoding());
+ return t;
+}
+
+encodedString* Genericwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
+{
+ QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
+ if (it==bodyCache.end()) return new encodedString();
+ encodedString*t = it.data();
+ return t;
+}
+
+QString Genericwrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
+{
+ encodedString*t = fetchDecodedPart(mail,part);
+ QString text=t->Content();
+ delete t;
+ return text;
+}
+
+void Genericwrapper::cleanMimeCache()
+{
+ QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
+ for (;it!=bodyCache.end();++it) {
+ encodedString*t = it.data();
+ //it.setValue(0);
+ if (t) delete t;
+ }
+ bodyCache.clear();
+ qDebug("Genericwrapper: cache cleaned");
+}
diff --git a/noncore/net/mail/libmailwrapper/genericwrapper.h b/noncore/net/mail/libmailwrapper/genericwrapper.h
new file mode 100644
index 0000000..12f6928
--- a/dev/null
+++ b/noncore/net/mail/libmailwrapper/genericwrapper.h
@@ -0,0 +1,59 @@
+#ifndef __GENERIC_WRAPPER_H
+#define __GENERIC_WRAPPER_H
+
+#include "abstractmail.h"
+#include <qmap.h>
+#include <qstring.h>
+#include <libetpan/clist.h>
+
+class RecMail;
+class RecBody;
+class encodedString;
+struct mailpop3;
+struct mailmessage;
+struct mailmime;
+struct mailmime_mechanism;
+struct mailimf_mailbox_list;
+struct mailimf_mailbox;
+struct mailimf_date_time;
+struct mailimf_group;
+struct mailimf_address_list;
+
+/* this class hold just the funs shared between
+ * mbox and pop3 (later mh, too) mail access.
+ * it is not desigend to make a instance of it!
+ */
+class Genericwrapper : public AbstractMail
+{
+ Q_OBJECT
+public:
+ Genericwrapper();
+ virtual ~Genericwrapper();
+
+ virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
+ virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
+ virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
+ virtual void cleanMimeCache();
+
+protected:
+ RecMail *parseHeader( const char *header );
+ RecBody parseMail( mailmessage * msg );
+ QString parseMailboxList( mailimf_mailbox_list *list );
+ QString parseMailbox( mailimf_mailbox *box );
+ QString parseGroup( mailimf_group *group );
+ QString parseAddressList( mailimf_address_list *list );
+ QString parseDateTime( mailimf_date_time *date );
+
+ void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
+ static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
+ static void fillParameters(RecPart&target,clist*parameters);
+ static QString getencoding(mailmime_mechanism*aEnc);
+
+ POP3account *account;
+ mailpop3 *m_pop3;
+ QString msgTempName;
+ unsigned int last_msg_id;
+ QMap<QString,encodedString*> bodyCache;
+};
+
+#endif
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.cpp b/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
index d3447f4..efd83ba 100644
--- a/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
@@ -1,618 +1,230 @@
#include <stdlib.h>
#include "pop3wrapper.h"
#include "mailtypes.h"
#include "logindialog.h"
#include <libetpan/mailpop3.h>
#include <libetpan/mailmime.h>
#include <libetpan/data_message_driver.h>
#include <qfile.h>
/* we don't fetch messages larger than 5 MB */
#define HARD_MSG_SIZE_LIMIT 5242880
POP3wrapper::POP3wrapper( POP3account *a )
+ : Genericwrapper()
{
account = a;
m_pop3 = NULL;
msgTempName = a->getFileName()+"_msg_cache";
last_msg_id = 0;
- bodyCache.clear();
}
POP3wrapper::~POP3wrapper()
{
logout();
QFile msg_cache(msgTempName);
if (msg_cache.exists()) {
msg_cache.remove();
}
- cleanUpCache();
-}
-
-void POP3wrapper::cleanUpCache()
-{
- QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
- for (;it!=bodyCache.end();++it) {
- encodedString*t = it.data();
- //it.setValue(0);
- if (t) delete t;
- }
- bodyCache.clear();
}
void POP3wrapper::pop3_progress( size_t current, size_t maximum )
{
//qDebug( "POP3: %i of %i", current, maximum );
}
RecBody POP3wrapper::fetchBody( const RecMail &mail )
{
int err = MAILPOP3_NO_ERROR;
char *message;
size_t length = 0;
login();
if ( !m_pop3 ) {
return RecBody();
}
RecBody body;
+ mailmessage * msg = 0;
QFile msg_cache(msgTempName);
if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) {
qDebug("Message to large: %i",mail.Msgsize());
return body;
}
- cleanUpCache();
+ cleanMimeCache();
if (mail.getNumber()!=last_msg_id) {
if (msg_cache.exists()) {
msg_cache.remove();
}
msg_cache.open(IO_ReadWrite|IO_Truncate);
last_msg_id = mail.getNumber();
err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length );
if ( err != MAILPOP3_NO_ERROR ) {
qDebug( "POP3: error retrieving body with index %i", mail.getNumber() );
last_msg_id = 0;
return RecBody();
}
msg_cache.writeBlock(message,length);
} else {
QString msg="";
msg_cache.open(IO_ReadOnly);
message = new char[4096];
memset(message,0,4096);
while (msg_cache.readBlock(message,4095)>0) {
msg+=message;
memset(message,0,4096);
}
delete message;
message = (char*)malloc(msg.length()+1*sizeof(char));
memset(message,0,msg.length()+1);
memcpy(message,msg.latin1(),msg.length());
}
- 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;
-
- 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;
- }
- char*body_msg = message;
+ /* transform to libetpan stuff */
msg = mailmessage_new();
- mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg));
+ mailmessage_init(msg, NULL, data_message_driver, 0, strlen(message));
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);
+ msg_data->msg_message = message;
+ msg_data->msg_length = strlen(message);
+ /* parse the mail */
+ body = parseMail(msg);
- memset(&fields, 0, sizeof(struct mailmime_single_fields));
- err = mailmessage_get_bodystructure(msg,&mime);
- traverseBody(body,msg,mime);
-
+ /* clean up */
mailmessage_free(msg);
+ free(message);
+ /* finish */
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();
if (!m_pop3) return;
mailpop3_list( m_pop3, &messages );
for (unsigned int i = 0; i < carray_count(messages);++i) {
mailpop3_msg_info *info;
err = mailpop3_get_msg_info(m_pop3,i+1,&info);
if (info->msg_deleted)
continue;
err = mailpop3_header( m_pop3, info->msg_index, &header, &length );
if ( err != MAILPOP3_NO_ERROR ) {
qDebug( "POP3: error retrieving header msgid: %i", info->msg_index );
free(header);
return;
}
RecMail *mail = parseHeader( header );
mail->setNumber( info->msg_index );
mail->setWrapper(this);
mail->setMsgsize(info->msg_size);
target.append( mail );
free(header);
}
}
-RecMail *POP3wrapper::parseHeader( const char *header )
-{
- int err = MAILIMF_NO_ERROR;
- size_t curTok = 0;
- RecMail *mail = new RecMail();
- mailimf_fields *fields;
- mailimf_references * refs;
- mailimf_keywords*keys;
- QString status;
- QString value;
- QBitArray mFlags(7);
-
- err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
- for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
- mailimf_field *field = (mailimf_field *) current->data;
- switch ( field->fld_type ) {
- case MAILIMF_FIELD_FROM:
- mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
- break;
- case MAILIMF_FIELD_TO:
- mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
- break;
- case MAILIMF_FIELD_CC:
- mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
- break;
- case MAILIMF_FIELD_BCC:
- mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
- break;
- case MAILIMF_FIELD_SUBJECT:
- mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
- break;
- case MAILIMF_FIELD_ORIG_DATE:
- mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
- break;
- case MAILIMF_FIELD_MESSAGE_ID:
- mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
- break;
- case MAILIMF_FIELD_REFERENCES:
- refs = field->fld_data.fld_references;
- if (refs && refs->mid_list && clist_count(refs->mid_list)) {
- char * text = (char*)refs->mid_list->first->data;
- mail->setReplyto(QString(text));
- }
- break;
- case MAILIMF_FIELD_KEYWORDS:
- keys = field->fld_data.fld_keywords;
- for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
- qDebug("Keyword: %s",(char*)cur->data);
- }
- break;
- case MAILIMF_FIELD_OPTIONAL_FIELD:
- status = field->fld_data.fld_optional_field->fld_name;
- value = field->fld_data.fld_optional_field->fld_value;
- if (status.lower()=="status") {
- if (value.lower()=="ro") {
- mFlags.setBit(FLAG_SEEN);
- }
- } else if (status.lower()=="x-status") {
- qDebug("X-Status: %s",value.latin1());
- if (value.lower()=="a") {
- mFlags.setBit(FLAG_ANSWERED);
- }
- } else {
-// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
-// field->fld_data.fld_optional_field->fld_value);
- }
- break;
- default:
- qDebug("Non parsed field");
- break;
- }
- }
- if (fields) mailimf_fields_free(fields);
- mail->setFlags(mFlags);
- return mail;
-}
-
-QString POP3wrapper::parseDateTime( mailimf_date_time *date )
-{
- char tmp[23];
-
- snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
- date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
-
- return QString( tmp );
-}
-
-QString POP3wrapper::parseAddressList( mailimf_address_list *list )
-{
- QString result( "" );
-
- bool first = true;
- for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
- mailimf_address *addr = (mailimf_address *) current->data;
-
- if ( !first ) {
- result.append( "," );
- } else {
- first = false;
- }
-
- switch ( addr->ad_type ) {
- case MAILIMF_ADDRESS_MAILBOX:
- result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
- break;
- case MAILIMF_ADDRESS_GROUP:
- result.append( parseGroup( addr->ad_data.ad_group ) );
- break;
- default:
- qDebug( "POP3: unkown mailimf address type" );
- break;
- }
- }
-
- return result;
-}
-
-QString POP3wrapper::parseGroup( mailimf_group *group )
-{
- QString result( "" );
-
- result.append( group->grp_display_name );
- result.append( ": " );
-
- if ( group->grp_mb_list != NULL ) {
- result.append( parseMailboxList( group->grp_mb_list ) );
- }
-
- result.append( ";" );
-
- return result;
-}
-
-QString POP3wrapper::parseMailbox( mailimf_mailbox *box )
-{
- QString result( "" );
-
- if ( box->mb_display_name == NULL ) {
- result.append( box->mb_addr_spec );
- } else {
- result.append( convert_String(box->mb_display_name).latin1() );
- result.append( " <" );
- result.append( box->mb_addr_spec );
- result.append( ">" );
- }
-
- return result;
-}
-
-QString POP3wrapper::parseMailboxList( mailimf_mailbox_list *list )
-{
- QString result( "" );
-
- bool first = true;
- for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
- mailimf_mailbox *box = (mailimf_mailbox *) current->data;
-
- if ( !first ) {
- result.append( "," );
- } else {
- first = false;
- }
-
- result.append( parseMailbox( box ) );
- }
-
- return result;
-}
-
void POP3wrapper::login()
{
/* we'll hold the line */
if ( m_pop3 != NULL ) return;
const char *server, *user, *pass;
uint16_t port;
int err = MAILPOP3_NO_ERROR;
server = account->getServer().latin1();
port = account->getPort().toUInt();
if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = strdup( login.getUser().latin1() );
pass = strdup( login.getPassword().latin1() );
} else {
// cancel
qDebug( "POP3: Login canceled" );
return;
}
} else {
user = account->getUser().latin1();
pass = account->getPassword().latin1();
}
m_pop3 = mailpop3_new( 200, &pop3_progress );
// connect
if (account->getSSL()) {
err = mailpop3_ssl_connect( m_pop3, (char*)server, port );
} else {
err = mailpop3_socket_connect( m_pop3, (char*)server, port );
}
if ( err != MAILPOP3_NO_ERROR ) {
qDebug( "pop3: error connecting to %s\n reason: %s", server,
m_pop3->pop3_response );
mailpop3_free( m_pop3 );
m_pop3 = NULL;
return;
}
qDebug( "POP3: connected!" );
// login
// TODO: decide if apop or plain login should be used
err = mailpop3_login( m_pop3, (char *) user, (char *) pass );
if ( err != MAILPOP3_NO_ERROR ) {
qDebug( "pop3: error logging in: %s", m_pop3->pop3_response );
logout();
return;
}
qDebug( "POP3: logged in!" );
}
void POP3wrapper::logout()
{
int err = MAILPOP3_NO_ERROR;
if ( m_pop3 == NULL ) return;
err = mailpop3_quit( m_pop3 );
mailpop3_free( m_pop3 );
m_pop3 = NULL;
}
QList<Folder>* POP3wrapper::listFolders()
{
/* TODO: integrate MH directories
but not before version 0.1 ;)
*/
QList<Folder> * folders = new QList<Folder>();
folders->setAutoDelete( false );
Folder*inb=new Folder("INBOX","/");
folders->append(inb);
return folders;
}
-QString POP3wrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
-{
- encodedString*t = fetchDecodedPart(mail,part);
- QString text=t->Content();
- delete t;
- return text;
-}
-
void POP3wrapper::deleteMail(const RecMail&mail)
{
login();
if (!m_pop3) return;
int err = mailpop3_dele(m_pop3,mail.getNumber());
if (err != MAILPOP3_NO_ERROR) {
qDebug("error deleting mail");
}
}
void POP3wrapper::answeredMail(const RecMail&)
{
}
-
-encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
-{
- QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
- if (it==bodyCache.end()) return new encodedString();
- encodedString*t = decode_String(it.data(),part.Encoding());
- return t;
-}
-
-encodedString* POP3wrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
-{
- QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
- if (it==bodyCache.end()) return new encodedString();
- encodedString*t = it.data();
- return t;
-}
-
-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;
- int res;
- QString b;
- RecPart part;
-
- switch (mime->mm_type) {
- case MAILMIME_SINGLE:
- r = mailmessage_fetch_section(message,mime,&data,&len);
- part.setSize(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 {
- b = gen_attachment_id();
- part.setIdentifier(b);
- bodyCache[b]=new encodedString(data,len);
- 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_field*field = 0;
- mailmime_single_fields fields;
- memset(&fields, 0, sizeof(struct mailmime_single_fields));
- if (mime->mm_mime_fields != NULL) {
- mailmime_single_fields_init(&fields, mime->mm_mime_fields,
- mime->mm_content_type);
- }
-
- mailmime_content*type = fields.fld_content;
- clistcell*current;
- if (!type) {
- target.setType("text");
- target.setSubtype("plain");
- } else {
- target.setSubtype(type->ct_subtype);
- switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
- case MAILMIME_DISCRETE_TYPE_TEXT:
- target.setType("text");
- break;
- case MAILMIME_DISCRETE_TYPE_IMAGE:
- target.setType("image");
- break;
- case MAILMIME_DISCRETE_TYPE_AUDIO:
- target.setType("audio");
- break;
- case MAILMIME_DISCRETE_TYPE_VIDEO:
- target.setType("video");
- break;
- case MAILMIME_DISCRETE_TYPE_APPLICATION:
- target.setType("application");
- break;
- case MAILMIME_DISCRETE_TYPE_EXTENSION:
- default:
- if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
- target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
- }
- break;
- }
- if (type->ct_parameters) {
- fillParameters(target,type->ct_parameters);
- }
- }
- if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
- for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
- field = (mailmime_field*)current->data;
- switch(field->fld_type) {
- case MAILMIME_FIELD_TRANSFER_ENCODING:
- target.setEncoding(getencoding(field->fld_data.fld_encoding));
- break;
- case MAILMIME_FIELD_ID:
- target.setIdentifier(field->fld_data.fld_id);
- break;
- case MAILMIME_FIELD_DESCRIPTION:
- target.setDescription(field->fld_data.fld_description);
- break;
- default:
- break;
- }
- }
- }
-}
-
-void POP3wrapper::fillParameters(RecPart&target,clist*parameters)
-{
- if (!parameters) {return;}
- clistcell*current=0;
- mailmime_parameter*param;
- for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
- param = (mailmime_parameter*)current->data;
- if (param) {
- target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
- }
- }
-}
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.h b/noncore/net/mail/libmailwrapper/pop3wrapper.h
index 75d70f8..b738cca 100644
--- a/noncore/net/mail/libmailwrapper/pop3wrapper.h
+++ b/noncore/net/mail/libmailwrapper/pop3wrapper.h
@@ -1,69 +1,32 @@
#ifndef __POP3WRAPPER
#define __POP3WRAPPER
-#include <libetpan/clist.h>
#include "mailwrapper.h"
-#include "abstractmail.h"
-#include <qmap.h>
+#include "genericwrapper.h"
#include <qstring.h>
-class RecMail;
-class RecBody;
-class encodedString;
-struct mailpop3;
-struct mailmessage;
-struct mailmime;
-struct mailmime_mechanism;
-struct mailimf_mailbox_list;
-struct mailimf_mailbox;
-struct mailimf_date_time;
-struct mailimf_group;
-struct mailimf_address_list;
-class POP3wrapper : public AbstractMail
+class POP3wrapper : public Genericwrapper
{
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);
- virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
- virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
- RecBody fetchBody( const RecMail &mail );
+ virtual RecBody fetchBody( const RecMail &mail );
static void pop3_progress( size_t current, size_t maximum );
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 );
-
- void cleanUpCache();
-
- void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
- static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
- static void fillParameters(RecPart&target,clist*parameters);
- static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
-
- POP3account *account;
- mailpop3 *m_pop3;
- QString msgTempName;
- unsigned int last_msg_id;
- QMap<QString,encodedString*> bodyCache;
};
#endif
diff --git a/noncore/net/mail/mail.pro b/noncore/net/mail/mail.pro
index 2542344..dd3c337 100644
--- a/noncore/net/mail/mail.pro
+++ b/noncore/net/mail/mail.pro
@@ -1,66 +1,70 @@
CONFIG += qt warn_on debug quick-app
HEADERS = defines.h \
logindialog.h \
settings.h \
editaccounts.h \
mailwrapper.h \
composemail.h \
accountview.h \
mainwindow.h \
viewmail.h \
viewmailbase.h \
opiemail.h \
imapwrapper.h \
mailtypes.h \
mailistviewitem.h \
pop3wrapper.h \
abstractmail.h \
settingsdialog.h \
statuswidget.h \
- smtpwrapper.h
+ smtpwrapper.h \
+ genericwrapper.h \
+ mboxwrapper.h
SOURCES = main.cpp \
opiemail.cpp \
mainwindow.cpp \
accountview.cpp \
composemail.cpp \
mailwrapper.cpp \
imapwrapper.cpp \
addresspicker.cpp \
editaccounts.cpp \
logindialog.cpp \
viewmail.cpp \
viewmailbase.cpp \
settings.cpp \
mailtypes.cpp \
pop3wrapper.cpp \
abstractmail.cpp \
settingsdialog.cpp \
statuswidget.cpp \
- smtpwrapper.cpp
+ smtpwrapper.cpp \
+ genericwrapper.cpp \
+ mboxwrapper.cpp
INTERFACES = editaccountsui.ui \
selectmailtypeui.ui \
imapconfigui.ui \
pop3configui.ui \
nntpconfigui.ui \
smtpconfigui.ui \
addresspickerui.ui \
logindialogui.ui \
composemailui.ui \
settingsdialogui.ui \
statuswidgetui.ui
INCLUDEPATH += $(OPIEDIR)/include
CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX )
contains( CONFTEST, y ){
LIBS += -lqpe -letpan -lssl -lcrypto -lopie -liconv
}else{
LIBS += -lqpe -letpan -lssl -lcrypto -lopie
}
TARGET = opiemail
include ( $(OPIEDIR)/include.pro )
diff --git a/noncore/net/mail/pop3wrapper.cpp b/noncore/net/mail/pop3wrapper.cpp
index d3447f4..efd83ba 100644
--- a/noncore/net/mail/pop3wrapper.cpp
+++ b/noncore/net/mail/pop3wrapper.cpp
@@ -1,618 +1,230 @@
#include <stdlib.h>
#include "pop3wrapper.h"
#include "mailtypes.h"
#include "logindialog.h"
#include <libetpan/mailpop3.h>
#include <libetpan/mailmime.h>
#include <libetpan/data_message_driver.h>
#include <qfile.h>
/* we don't fetch messages larger than 5 MB */
#define HARD_MSG_SIZE_LIMIT 5242880
POP3wrapper::POP3wrapper( POP3account *a )
+ : Genericwrapper()
{
account = a;
m_pop3 = NULL;
msgTempName = a->getFileName()+"_msg_cache";
last_msg_id = 0;
- bodyCache.clear();
}
POP3wrapper::~POP3wrapper()
{
logout();
QFile msg_cache(msgTempName);
if (msg_cache.exists()) {
msg_cache.remove();
}
- cleanUpCache();
-}
-
-void POP3wrapper::cleanUpCache()
-{
- QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
- for (;it!=bodyCache.end();++it) {
- encodedString*t = it.data();
- //it.setValue(0);
- if (t) delete t;
- }
- bodyCache.clear();
}
void POP3wrapper::pop3_progress( size_t current, size_t maximum )
{
//qDebug( "POP3: %i of %i", current, maximum );
}
RecBody POP3wrapper::fetchBody( const RecMail &mail )
{
int err = MAILPOP3_NO_ERROR;
char *message;
size_t length = 0;
login();
if ( !m_pop3 ) {
return RecBody();
}
RecBody body;
+ mailmessage * msg = 0;
QFile msg_cache(msgTempName);
if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) {
qDebug("Message to large: %i",mail.Msgsize());
return body;
}
- cleanUpCache();
+ cleanMimeCache();
if (mail.getNumber()!=last_msg_id) {
if (msg_cache.exists()) {
msg_cache.remove();
}
msg_cache.open(IO_ReadWrite|IO_Truncate);
last_msg_id = mail.getNumber();
err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length );
if ( err != MAILPOP3_NO_ERROR ) {
qDebug( "POP3: error retrieving body with index %i", mail.getNumber() );
last_msg_id = 0;
return RecBody();
}
msg_cache.writeBlock(message,length);
} else {
QString msg="";
msg_cache.open(IO_ReadOnly);
message = new char[4096];
memset(message,0,4096);
while (msg_cache.readBlock(message,4095)>0) {
msg+=message;
memset(message,0,4096);
}
delete message;
message = (char*)malloc(msg.length()+1*sizeof(char));
memset(message,0,msg.length()+1);
memcpy(message,msg.latin1(),msg.length());
}
- 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;
-
- 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;
- }
- char*body_msg = message;
+ /* transform to libetpan stuff */
msg = mailmessage_new();
- mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg));
+ mailmessage_init(msg, NULL, data_message_driver, 0, strlen(message));
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);
+ msg_data->msg_message = message;
+ msg_data->msg_length = strlen(message);
+ /* parse the mail */
+ body = parseMail(msg);
- memset(&fields, 0, sizeof(struct mailmime_single_fields));
- err = mailmessage_get_bodystructure(msg,&mime);
- traverseBody(body,msg,mime);
-
+ /* clean up */
mailmessage_free(msg);
+ free(message);
+ /* finish */
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();
if (!m_pop3) return;
mailpop3_list( m_pop3, &messages );
for (unsigned int i = 0; i < carray_count(messages);++i) {
mailpop3_msg_info *info;
err = mailpop3_get_msg_info(m_pop3,i+1,&info);
if (info->msg_deleted)
continue;
err = mailpop3_header( m_pop3, info->msg_index, &header, &length );
if ( err != MAILPOP3_NO_ERROR ) {
qDebug( "POP3: error retrieving header msgid: %i", info->msg_index );
free(header);
return;
}
RecMail *mail = parseHeader( header );
mail->setNumber( info->msg_index );
mail->setWrapper(this);
mail->setMsgsize(info->msg_size);
target.append( mail );
free(header);
}
}
-RecMail *POP3wrapper::parseHeader( const char *header )
-{
- int err = MAILIMF_NO_ERROR;
- size_t curTok = 0;
- RecMail *mail = new RecMail();
- mailimf_fields *fields;
- mailimf_references * refs;
- mailimf_keywords*keys;
- QString status;
- QString value;
- QBitArray mFlags(7);
-
- err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
- for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
- mailimf_field *field = (mailimf_field *) current->data;
- switch ( field->fld_type ) {
- case MAILIMF_FIELD_FROM:
- mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
- break;
- case MAILIMF_FIELD_TO:
- mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
- break;
- case MAILIMF_FIELD_CC:
- mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
- break;
- case MAILIMF_FIELD_BCC:
- mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
- break;
- case MAILIMF_FIELD_SUBJECT:
- mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
- break;
- case MAILIMF_FIELD_ORIG_DATE:
- mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
- break;
- case MAILIMF_FIELD_MESSAGE_ID:
- mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
- break;
- case MAILIMF_FIELD_REFERENCES:
- refs = field->fld_data.fld_references;
- if (refs && refs->mid_list && clist_count(refs->mid_list)) {
- char * text = (char*)refs->mid_list->first->data;
- mail->setReplyto(QString(text));
- }
- break;
- case MAILIMF_FIELD_KEYWORDS:
- keys = field->fld_data.fld_keywords;
- for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
- qDebug("Keyword: %s",(char*)cur->data);
- }
- break;
- case MAILIMF_FIELD_OPTIONAL_FIELD:
- status = field->fld_data.fld_optional_field->fld_name;
- value = field->fld_data.fld_optional_field->fld_value;
- if (status.lower()=="status") {
- if (value.lower()=="ro") {
- mFlags.setBit(FLAG_SEEN);
- }
- } else if (status.lower()=="x-status") {
- qDebug("X-Status: %s",value.latin1());
- if (value.lower()=="a") {
- mFlags.setBit(FLAG_ANSWERED);
- }
- } else {
-// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
-// field->fld_data.fld_optional_field->fld_value);
- }
- break;
- default:
- qDebug("Non parsed field");
- break;
- }
- }
- if (fields) mailimf_fields_free(fields);
- mail->setFlags(mFlags);
- return mail;
-}
-
-QString POP3wrapper::parseDateTime( mailimf_date_time *date )
-{
- char tmp[23];
-
- snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
- date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
-
- return QString( tmp );
-}
-
-QString POP3wrapper::parseAddressList( mailimf_address_list *list )
-{
- QString result( "" );
-
- bool first = true;
- for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
- mailimf_address *addr = (mailimf_address *) current->data;
-
- if ( !first ) {
- result.append( "," );
- } else {
- first = false;
- }
-
- switch ( addr->ad_type ) {
- case MAILIMF_ADDRESS_MAILBOX:
- result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
- break;
- case MAILIMF_ADDRESS_GROUP:
- result.append( parseGroup( addr->ad_data.ad_group ) );
- break;
- default:
- qDebug( "POP3: unkown mailimf address type" );
- break;
- }
- }
-
- return result;
-}
-
-QString POP3wrapper::parseGroup( mailimf_group *group )
-{
- QString result( "" );
-
- result.append( group->grp_display_name );
- result.append( ": " );
-
- if ( group->grp_mb_list != NULL ) {
- result.append( parseMailboxList( group->grp_mb_list ) );
- }
-
- result.append( ";" );
-
- return result;
-}
-
-QString POP3wrapper::parseMailbox( mailimf_mailbox *box )
-{
- QString result( "" );
-
- if ( box->mb_display_name == NULL ) {
- result.append( box->mb_addr_spec );
- } else {
- result.append( convert_String(box->mb_display_name).latin1() );
- result.append( " <" );
- result.append( box->mb_addr_spec );
- result.append( ">" );
- }
-
- return result;
-}
-
-QString POP3wrapper::parseMailboxList( mailimf_mailbox_list *list )
-{
- QString result( "" );
-
- bool first = true;
- for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
- mailimf_mailbox *box = (mailimf_mailbox *) current->data;
-
- if ( !first ) {
- result.append( "," );
- } else {
- first = false;
- }
-
- result.append( parseMailbox( box ) );
- }
-
- return result;
-}
-
void POP3wrapper::login()
{
/* we'll hold the line */
if ( m_pop3 != NULL ) return;
const char *server, *user, *pass;
uint16_t port;
int err = MAILPOP3_NO_ERROR;
server = account->getServer().latin1();
port = account->getPort().toUInt();
if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = strdup( login.getUser().latin1() );
pass = strdup( login.getPassword().latin1() );
} else {
// cancel
qDebug( "POP3: Login canceled" );
return;
}
} else {
user = account->getUser().latin1();
pass = account->getPassword().latin1();
}
m_pop3 = mailpop3_new( 200, &pop3_progress );
// connect
if (account->getSSL()) {
err = mailpop3_ssl_connect( m_pop3, (char*)server, port );
} else {
err = mailpop3_socket_connect( m_pop3, (char*)server, port );
}
if ( err != MAILPOP3_NO_ERROR ) {
qDebug( "pop3: error connecting to %s\n reason: %s", server,
m_pop3->pop3_response );
mailpop3_free( m_pop3 );
m_pop3 = NULL;
return;
}
qDebug( "POP3: connected!" );
// login
// TODO: decide if apop or plain login should be used
err = mailpop3_login( m_pop3, (char *) user, (char *) pass );
if ( err != MAILPOP3_NO_ERROR ) {
qDebug( "pop3: error logging in: %s", m_pop3->pop3_response );
logout();
return;
}
qDebug( "POP3: logged in!" );
}
void POP3wrapper::logout()
{
int err = MAILPOP3_NO_ERROR;
if ( m_pop3 == NULL ) return;
err = mailpop3_quit( m_pop3 );
mailpop3_free( m_pop3 );
m_pop3 = NULL;
}
QList<Folder>* POP3wrapper::listFolders()
{
/* TODO: integrate MH directories
but not before version 0.1 ;)
*/
QList<Folder> * folders = new QList<Folder>();
folders->setAutoDelete( false );
Folder*inb=new Folder("INBOX","/");
folders->append(inb);
return folders;
}
-QString POP3wrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
-{
- encodedString*t = fetchDecodedPart(mail,part);
- QString text=t->Content();
- delete t;
- return text;
-}
-
void POP3wrapper::deleteMail(const RecMail&mail)
{
login();
if (!m_pop3) return;
int err = mailpop3_dele(m_pop3,mail.getNumber());
if (err != MAILPOP3_NO_ERROR) {
qDebug("error deleting mail");
}
}
void POP3wrapper::answeredMail(const RecMail&)
{
}
-
-encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
-{
- QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
- if (it==bodyCache.end()) return new encodedString();
- encodedString*t = decode_String(it.data(),part.Encoding());
- return t;
-}
-
-encodedString* POP3wrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
-{
- QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
- if (it==bodyCache.end()) return new encodedString();
- encodedString*t = it.data();
- return t;
-}
-
-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;
- int res;
- QString b;
- RecPart part;
-
- switch (mime->mm_type) {
- case MAILMIME_SINGLE:
- r = mailmessage_fetch_section(message,mime,&data,&len);
- part.setSize(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 {
- b = gen_attachment_id();
- part.setIdentifier(b);
- bodyCache[b]=new encodedString(data,len);
- 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_field*field = 0;
- mailmime_single_fields fields;
- memset(&fields, 0, sizeof(struct mailmime_single_fields));
- if (mime->mm_mime_fields != NULL) {
- mailmime_single_fields_init(&fields, mime->mm_mime_fields,
- mime->mm_content_type);
- }
-
- mailmime_content*type = fields.fld_content;
- clistcell*current;
- if (!type) {
- target.setType("text");
- target.setSubtype("plain");
- } else {
- target.setSubtype(type->ct_subtype);
- switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
- case MAILMIME_DISCRETE_TYPE_TEXT:
- target.setType("text");
- break;
- case MAILMIME_DISCRETE_TYPE_IMAGE:
- target.setType("image");
- break;
- case MAILMIME_DISCRETE_TYPE_AUDIO:
- target.setType("audio");
- break;
- case MAILMIME_DISCRETE_TYPE_VIDEO:
- target.setType("video");
- break;
- case MAILMIME_DISCRETE_TYPE_APPLICATION:
- target.setType("application");
- break;
- case MAILMIME_DISCRETE_TYPE_EXTENSION:
- default:
- if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
- target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
- }
- break;
- }
- if (type->ct_parameters) {
- fillParameters(target,type->ct_parameters);
- }
- }
- if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
- for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
- field = (mailmime_field*)current->data;
- switch(field->fld_type) {
- case MAILMIME_FIELD_TRANSFER_ENCODING:
- target.setEncoding(getencoding(field->fld_data.fld_encoding));
- break;
- case MAILMIME_FIELD_ID:
- target.setIdentifier(field->fld_data.fld_id);
- break;
- case MAILMIME_FIELD_DESCRIPTION:
- target.setDescription(field->fld_data.fld_description);
- break;
- default:
- break;
- }
- }
- }
-}
-
-void POP3wrapper::fillParameters(RecPart&target,clist*parameters)
-{
- if (!parameters) {return;}
- clistcell*current=0;
- mailmime_parameter*param;
- for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
- param = (mailmime_parameter*)current->data;
- if (param) {
- target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
- }
- }
-}
diff --git a/noncore/net/mail/pop3wrapper.h b/noncore/net/mail/pop3wrapper.h
index 75d70f8..b738cca 100644
--- a/noncore/net/mail/pop3wrapper.h
+++ b/noncore/net/mail/pop3wrapper.h
@@ -1,69 +1,32 @@
#ifndef __POP3WRAPPER
#define __POP3WRAPPER
-#include <libetpan/clist.h>
#include "mailwrapper.h"
-#include "abstractmail.h"
-#include <qmap.h>
+#include "genericwrapper.h"
#include <qstring.h>
-class RecMail;
-class RecBody;
-class encodedString;
-struct mailpop3;
-struct mailmessage;
-struct mailmime;
-struct mailmime_mechanism;
-struct mailimf_mailbox_list;
-struct mailimf_mailbox;
-struct mailimf_date_time;
-struct mailimf_group;
-struct mailimf_address_list;
-class POP3wrapper : public AbstractMail
+class POP3wrapper : public Genericwrapper
{
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);
- virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
- virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
- RecBody fetchBody( const RecMail &mail );
+ virtual RecBody fetchBody( const RecMail &mail );
static void pop3_progress( size_t current, size_t maximum );
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 );
-
- void cleanUpCache();
-
- void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
- static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
- static void fillParameters(RecPart&target,clist*parameters);
- static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
-
- POP3account *account;
- mailpop3 *m_pop3;
- QString msgTempName;
- unsigned int last_msg_id;
- QMap<QString,encodedString*> bodyCache;
};
#endif
diff --git a/noncore/net/mail/viewmail.cpp b/noncore/net/mail/viewmail.cpp
index e11fe1f..0ad7359 100644
--- a/noncore/net/mail/viewmail.cpp
+++ b/noncore/net/mail/viewmail.cpp
@@ -1,370 +1,371 @@
#include <qtextbrowser.h>
#include <qmessagebox.h>
#include <qtextstream.h>
#include <qaction.h>
#include <qpopupmenu.h>
#include <qfile.h>
#include <qapplication.h>
#include <qpe/config.h>
#include <opie/ofiledialog.h>
#include "settings.h"
#include "composemail.h"
#include "viewmail.h"
#include "abstractmail.h"
#include "accountview.h"
#include "mailtypes.h"
AttachItem::AttachItem(QListView * parent,QListViewItem *after, const QString&mime,const QString&desc,const QString&file,
const QString&fsize,int num)
: QListViewItem(parent,after),_partNum(num)
{
setText(0, mime);
setText(1, desc);
setText(2, file);
setText(3, fsize);
}
void ViewMail::setBody( RecBody body ) {
m_body = body;
m_mail[2] = body.Bodytext();
attachbutton->setEnabled(body.Parts().count()>0);
attachments->setEnabled(body.Parts().count()>0);
if (body.Parts().count()==0) {
return;
}
AttachItem * curItem=0;
QString type=body.Description().Type()+"/"+body.Description().Subtype();
QString desc,fsize;
double s = body.Description().Size();
int w;
w=0;
while (s>1024) {
s/=1024;
++w;
if (w>=2) break;
}
QString q="";
switch(w) {
case 1:
q="k";
break;
case 2:
q="M";
break;
default:
break;
}
{
/* I did not found a method to make a CONTENT reset on a QTextStream
so I use this construct that the stream will re-constructed in each
loop. To let it work, the textstream is packed into a own area of
code is it will be destructed after finishing its small job.
*/
QTextOStream o(&fsize);
if (w>0) o.precision(2); else o.precision(0);
o.setf(QTextStream::fixed);
o << s << " " << q << "Byte";
}
curItem=new AttachItem(attachments,curItem,type,"Mailbody","",fsize,-1);
QString filename = "";
for (unsigned int i = 0; i < body.Parts().count();++i) {
type = body.Parts()[i].Type()+"/"+body.Parts()[i].Subtype();
part_plist_t::ConstIterator it = body.Parts()[i].Parameters().begin();
for (;it!=body.Parts()[i].Parameters().end();++it) {
qDebug(it.key());
if (it.key().lower()=="name") {
filename=it.data();
}
}
s = body.Parts()[i].Size();
w = 0;
while (s>1024) {
s/=1024;
++w;
if (w>=2) break;
}
switch(w) {
case 1:
q="k";
break;
case 2:
q="M";
break;
default:
q="";
break;
}
QTextOStream o(&fsize);
if (w>0) o.precision(2); else o.precision(0);
o.setf(QTextStream::fixed);
o << s << " " << q << "Byte";
desc = body.Parts()[i].Description();
curItem=new AttachItem(attachments,curItem,type,desc,filename,fsize,i);
}
}
void ViewMail::slotShowHtml( bool state ) {
m_showHtml = state;
setText();
}
void ViewMail::slotItemClicked( QListViewItem * item , const QPoint & point, int ) {
if (!item )
return;
if ( ( ( AttachItem* )item )->Partnumber() == -1 ) {
setText();
return;
}
QPopupMenu *menu = new QPopupMenu();
int ret=0;
if ( item->text( 0 ).left( 5 ) == "text/" ) {
menu->insertItem( tr( "Show Text" ), 1 );
}
menu->insertItem( tr( "Save Attachment" ), 0 );
menu->insertSeparator(1);
ret = menu->exec( point, 0 );
switch(ret) {
case 0:
{ MimeTypes types;
types.insert( "all", "*" );
QString str = OFileDialog::getSaveFileName( 1,
"/", item->text( 2 ) , types, 0 );
if( !str.isEmpty() ) {
encodedString*content = m_recMail.Wrapper()->fetchDecodedPart( m_recMail, m_body.Parts()[ ( ( AttachItem* )item )->Partnumber() ] );
if (content) {
QFile output(str);
output.open(IO_WriteOnly);
output.writeBlock(content->Content(),content->Length());
output.close();
delete content;
}
}
}
break ;
case 1:
if ( ( ( AttachItem* )item )->Partnumber() == -1 ) {
setText();
} else {
if ( m_recMail.Wrapper() != 0l ) { // make sure that there is a wrapper , even after delete or simular actions
browser->setText( m_recMail.Wrapper()->fetchTextPart( m_recMail, m_body.Parts()[ ( ( AttachItem* )item )->Partnumber() ] ) );
}
}
break;
}
delete menu;
}
void ViewMail::setMail( RecMail mail ) {
m_recMail = mail;
m_mail[0] = mail.getFrom();
m_mail[1] = mail.getSubject();
m_mail[3] = mail.getDate();
m_mail[4] = mail.Msgid();
m_mail2[0] = mail.To();
m_mail2[1] = mail.CC();
m_mail2[2] = mail.Bcc();
setText();
}
ViewMail::ViewMail( QWidget *parent, const char *name, WFlags fl)
: ViewMailBase(parent, name, fl), _inLoop(false)
{
m_gotBody = false;
deleted = false;
connect( reply, SIGNAL(activated()), SLOT(slotReply()));
connect( forward, SIGNAL(activated()), SLOT(slotForward()));
connect( deleteMail, SIGNAL( activated() ), SLOT( slotDeleteMail( ) ) );
connect( showHtml, SIGNAL( toggled( bool ) ), SLOT( slotShowHtml( bool ) ) );
attachments->setEnabled(m_gotBody);
connect( attachments, SIGNAL( clicked ( QListViewItem *, const QPoint & , int ) ), SLOT( slotItemClicked( QListViewItem *, const QPoint & , int ) ) );
readConfig();
}
void ViewMail::readConfig() {
Config cfg( "mail" );
cfg.setGroup( "Settings" );
m_showHtml = cfg.readBoolEntry( "showHtml", false );
showHtml->setOn( m_showHtml );
}
void ViewMail::setText()
{
QString toString;
QString ccString;
QString bccString;
for ( QStringList::Iterator it = ( m_mail2[0] ).begin(); it != ( m_mail2[0] ).end(); ++it ) {
toString += (*it);
}
for ( QStringList::Iterator it = ( m_mail2[1] ).begin(); it != ( m_mail2[1] ).end(); ++it ) {
ccString += (*it);
}
for ( QStringList::Iterator it = ( m_mail2[2] ).begin(); it != ( m_mail2[2] ).end(); ++it ) {
bccString += (*it);
}
setCaption( caption().arg( m_mail[0] ) );
m_mailHtml = "<html><body>"
"<table width=\"100%\" border=\"0\"><tr bgcolor=\"#FFDD76\"><td>"
"<div align=left><b>" + deHtml( m_mail[1] ) + "</b></div>"
"</td></tr><tr bgcolor=\"#EEEEE6\"><td>"
"<b>" + tr( "From" ) + ": </b><font color=#6C86C0>" + deHtml( m_mail[0] ) + "</font><br>"
"<b>" + tr( "To" ) + ": </b><font color=#6C86C0>" + deHtml( toString ) + "</font><br><b>" +
tr( "Cc" ) + ": </b>" + deHtml( ccString ) + "<br>"
"<b>" + tr( "Date" ) + ": </b> " + m_mail[3] +
"</td></tr></table><font face=fixed>";
if ( !m_showHtml ) {
browser->setText( QString( m_mailHtml) + deHtml( m_mail[2] ) + "</font></html>" );
} else {
browser->setText( QString( m_mailHtml) + m_mail[2] + "</font></html>" );
}
// remove later in favor of a real handling
m_gotBody = true;
}
ViewMail::~ViewMail()
{
+ m_recMail.Wrapper()->cleanMimeCache();
hide();
}
void ViewMail::hide()
{
QWidget::hide();
if (_inLoop) {
_inLoop = false;
qApp->exit_loop();
}
}
void ViewMail::exec()
{
show();
if (!_inLoop) {
_inLoop = true;
qApp->enter_loop();
}
}
QString ViewMail::deHtml(const QString &string)
{
QString string_ = string;
string_.replace(QRegExp("&"), "&amp;");
string_.replace(QRegExp("<"), "&lt;");
string_.replace(QRegExp(">"), "&gt;");
string_.replace(QRegExp("\\n"), "<br>");
return string_;
}
void ViewMail::slotReply()
{
if (!m_gotBody) {
QMessageBox::information(this, tr("Error"), tr("<p>The mail body is not yet downloaded, so you cannot reply yet."), tr("Ok"));
return;
}
QString rtext;
rtext += QString("* %1 wrote on %2:\n") // no i18n on purpose
.arg( m_mail[0] )
.arg( m_mail[3] );
QString text = m_mail[2];
QStringList lines = QStringList::split(QRegExp("\\n"), text);
QStringList::Iterator it;
for (it = lines.begin(); it != lines.end(); it++) {
rtext += "> " + *it + "\n";
}
rtext += "\n";
QString prefix;
if ( m_mail[1].find(QRegExp("^Re: *$")) != -1) prefix = "";
else prefix = "Re: "; // no i18n on purpose
Settings *settings = new Settings();
ComposeMail composer( settings ,this, 0, true);
composer.setTo( m_mail[0] );
composer.setSubject( "Re: " + m_mail[1] );
composer.setMessage( rtext );
composer.showMaximized();
if ( QDialog::Accepted==composer.exec()) {
m_recMail.Wrapper()->answeredMail(m_recMail);
}
}
void ViewMail::slotForward()
{
if (!m_gotBody) {
QMessageBox::information(this, tr("Error"), tr("<p>The mail body is not yet downloaded, so you cannot forward yet."), tr("Ok"));
return;
}
QString ftext;
ftext += QString("\n----- Forwarded message from %1 -----\n\n")
.arg( m_mail[0] );
if (!m_mail[3].isNull())
ftext += QString("Date: %1\n")
.arg( m_mail[3] );
if (!m_mail[0].isNull())
ftext += QString("From: %1\n")
.arg( m_mail[0] );
if (!m_mail[1].isNull())
ftext += QString("Subject: %1\n")
.arg( m_mail[1] );
ftext += QString("\n%1\n")
.arg( m_mail[2]);
ftext += QString("----- End forwarded message -----\n");
Settings *settings = new Settings();
ComposeMail composer( settings ,this, 0, true);
composer.setSubject( "Fwd: " + m_mail[1] );
composer.setMessage( ftext );
composer.showMaximized();
if ( QDialog::Accepted==composer.exec()) {
}
}
void ViewMail::slotDeleteMail( )
{
if ( QMessageBox::warning(this, tr("Delete Mail"), QString( tr("<p>Do you really want to delete this mail? <br><br>" ) + m_mail[0] + " - " + m_mail[1] ) , QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) {
m_recMail.Wrapper()->deleteMail( m_recMail );
hide();
deleted = true;
}
}