summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore 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.cpp418
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.h43
-rw-r--r--noncore/net/mail/mail.pro48
-rw-r--r--noncore/net/mail/pop3wrapper.cpp418
-rw-r--r--noncore/net/mail/pop3wrapper.h43
-rw-r--r--noncore/net/mail/viewmail.cpp1
16 files changed, 1100 insertions, 909 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 @@
1#include "abstractmail.h" 1#include "abstractmail.h"
2#include "imapwrapper.h" 2#include "imapwrapper.h"
3#include "pop3wrapper.h" 3#include "pop3wrapper.h"
4#include "mboxwrapper.h"
4#include "mailtypes.h" 5#include "mailtypes.h"
5 6
6#include <qstring.h> 7#include <qstring.h>
7#include <qfile.h> 8#include <qfile.h>
8#include <qtextstream.h> 9#include <qtextstream.h>
9#include <stdlib.h> 10#include <stdlib.h>
10#include <libetpan/mailmime_content.h> 11#include <libetpan/mailmime_content.h>
11#include <libetpan/mailmime.h> 12#include <libetpan/mailmime.h>
12 13
13AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) 14AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
14{ 15{
15 return new IMAPwrapper(a); 16 return new IMAPwrapper(a);
16} 17}
17 18
18AbstractMail* AbstractMail::getWrapper(POP3account *a) 19AbstractMail* AbstractMail::getWrapper(POP3account *a)
19{ 20{
20 return new POP3wrapper(a); 21 return new POP3wrapper(a);
21} 22}
22 23
24AbstractMail* AbstractMail::getWrapper(const QString&a)
25{
26 return new MBOXwrapper(a);
27}
28
23encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) 29encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
24{ 30{
25 qDebug("Decode string start"); 31 qDebug("Decode string start");
26 char*result_text; 32 char*result_text;
27 size_t index = 0; 33 size_t index = 0;
28 /* reset for recursive use! */ 34 /* reset for recursive use! */
29 size_t target_length = 0; 35 size_t target_length = 0;
30 result_text = 0; 36 result_text = 0;
31 int mimetype = MAILMIME_MECHANISM_7BIT; 37 int mimetype = MAILMIME_MECHANISM_7BIT;
32 if (enc.lower()=="quoted-printable") { 38 if (enc.lower()=="quoted-printable") {
33 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; 39 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
34 } else if (enc.lower()=="base64") { 40 } else if (enc.lower()=="base64") {
35 mimetype = MAILMIME_MECHANISM_BASE64; 41 mimetype = MAILMIME_MECHANISM_BASE64;
36 } else if (enc.lower()=="8bit") { 42 } else if (enc.lower()=="8bit") {
37 mimetype = MAILMIME_MECHANISM_8BIT; 43 mimetype = MAILMIME_MECHANISM_8BIT;
38 } else if (enc.lower()=="binary") { 44 } else if (enc.lower()=="binary") {
39 mimetype = MAILMIME_MECHANISM_BINARY; 45 mimetype = MAILMIME_MECHANISM_BINARY;
40 } 46 }
41 47
42 int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype, 48 int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype,
43 &result_text,&target_length); 49 &result_text,&target_length);
44 50
45 encodedString* result = new encodedString(); 51 encodedString* result = new encodedString();
46 if (err == MAILIMF_NO_ERROR) { 52 if (err == MAILIMF_NO_ERROR) {
47 result->setContent(result_text,target_length); 53 result->setContent(result_text,target_length);
48 } 54 }
49 qDebug("Decode string finished"); 55 qDebug("Decode string finished");
50 return result; 56 return result;
51} 57}
52 58
53QString AbstractMail::convert_String(const char*text) 59QString AbstractMail::convert_String(const char*text)
54{ 60{
55 size_t index = 0; 61 size_t index = 0;
56 char*res = 0; 62 char*res = 0;
57 63
58 /* attention - doesn't work with arm systems! */ 64 /* attention - doesn't work with arm systems! */
59 int err = mailmime_encoded_phrase_parse("iso-8859-1", 65 int err = mailmime_encoded_phrase_parse("iso-8859-1",
60 text, strlen(text),&index, "iso-8859-1",&res); 66 text, strlen(text),&index, "iso-8859-1",&res);
61 if (err != MAILIMF_NO_ERROR) { 67 if (err != MAILIMF_NO_ERROR) {
62 if (res) free(res); 68 if (res) free(res);
63 return QString(text); 69 return QString(text);
64 } 70 }
65 if (res) { 71 if (res) {
66 QString result(res); 72 QString result(res);
67 free(res); 73 free(res);
68 return result; 74 return result;
69 } 75 }
70 return QString(text); 76 return QString(text);
71} 77}
72 78
73/* cp & paste from launcher */ 79/* cp & paste from launcher */
74QString AbstractMail::gen_attachment_id() 80QString AbstractMail::gen_attachment_id()
75{ 81{
76 QFile file( "/proc/sys/kernel/random/uuid" ); 82 QFile file( "/proc/sys/kernel/random/uuid" );
77 if (!file.open(IO_ReadOnly ) ) 83 if (!file.open(IO_ReadOnly ) )
78 return QString::null; 84 return QString::null;
79 85
80 QTextStream stream(&file); 86 QTextStream stream(&file);
81 87
82 return "{" + stream.read().stripWhiteSpace() + "}"; 88 return "{" + stream.read().stripWhiteSpace() + "}";
83} 89}
84 90
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 @@
1#ifndef __abstract_mail_ 1#ifndef __abstract_mail_
2#define __abstract_mail_ 2#define __abstract_mail_
3 3
4#include <qobject.h> 4#include <qobject.h>
5#include "settings.h" 5#include "settings.h"
6 6
7class RecMail; 7class RecMail;
8class RecBody; 8class RecBody;
9class RecPart; 9class RecPart;
10class IMAPwrapper; 10class IMAPwrapper;
11class POP3wrapper; 11class POP3wrapper;
12class Folder; 12class Folder;
13class encodedString; 13class encodedString;
14 14
15class AbstractMail:public QObject 15class AbstractMail:public QObject
16{ 16{
17 Q_OBJECT 17 Q_OBJECT
18public: 18public:
19 AbstractMail(){}; 19 AbstractMail(){};
20 virtual ~AbstractMail(){} 20 virtual ~AbstractMail(){}
21 virtual QList<Folder>* listFolders()=0; 21 virtual QList<Folder>* listFolders()=0;
22 virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0; 22 virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0;
23 virtual RecBody fetchBody(const RecMail&mail)=0; 23 virtual RecBody fetchBody(const RecMail&mail)=0;
24 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part)=0; 24 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part)=0;
25 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0; 25 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0;
26 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0; 26 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0;
27 27
28 virtual void deleteMail(const RecMail&mail)=0; 28 virtual void deleteMail(const RecMail&mail)=0;
29 virtual void answeredMail(const RecMail&mail)=0; 29 virtual void answeredMail(const RecMail&mail)=0;
30 virtual void cleanMimeCache(){};
30 31
31 static AbstractMail* getWrapper(IMAPaccount *a); 32 static AbstractMail* getWrapper(IMAPaccount *a);
32 static AbstractMail* getWrapper(POP3account *a); 33 static AbstractMail* getWrapper(POP3account *a);
34 /* mbox only! */
35 static AbstractMail* getWrapper(const QString&a);
33 36
34protected: 37protected:
35 static encodedString*decode_String(const encodedString*text,const QString&enc); 38 static encodedString*decode_String(const encodedString*text,const QString&enc);
36 static QString convert_String(const char*text); 39 static QString convert_String(const char*text);
37 static QString gen_attachment_id(); 40 static QString gen_attachment_id();
38}; 41};
39#endif 42#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 @@
1#include <stdlib.h>
1#include "accountview.h" 2#include "accountview.h"
2#include "mailtypes.h" 3#include "mailtypes.h"
3#include "defines.h" 4#include "defines.h"
4 5
5
6/** 6/**
7 * POP3 Account stuff 7 * POP3 Account stuff
8 */ 8 */
9 9
10POP3viewItem::POP3viewItem( POP3account *a, QListView *parent ) 10POP3viewItem::POP3viewItem( POP3account *a, QListView *parent )
11 : AccountViewItem( parent ) 11 : AccountViewItem( parent )
12{ 12{
13 account = a; 13 account = a;
14 wrapper = AbstractMail::getWrapper( account ); 14 wrapper = AbstractMail::getWrapper( account );
15 setPixmap( 0, PIXMAP_POP3FOLDER ); 15 setPixmap( 0, PIXMAP_POP3FOLDER );
16 setText( 0, account->getAccountName() ); 16 setText( 0, account->getAccountName() );
17 setOpen( true ); 17 setOpen( true );
18} 18}
19 19
20POP3viewItem::~POP3viewItem() 20POP3viewItem::~POP3viewItem()
21{ 21{
22 delete wrapper; 22 delete wrapper;
23} 23}
24 24
25AbstractMail *POP3viewItem::getWrapper() 25AbstractMail *POP3viewItem::getWrapper()
26{ 26{
27 return wrapper; 27 return wrapper;
28} 28}
29 29
30void POP3viewItem::refresh( QList<RecMail> & ) 30void POP3viewItem::refresh( QList<RecMail> & )
31{ 31{
32 QList<Folder> *folders = wrapper->listFolders(); 32 QList<Folder> *folders = wrapper->listFolders();
33 QListViewItem *child = firstChild(); 33 QListViewItem *child = firstChild();
34 while ( child ) { 34 while ( child ) {
35 QListViewItem *tmp = child; 35 QListViewItem *tmp = child;
36 child = child->nextSibling(); 36 child = child->nextSibling();
37 delete tmp; 37 delete tmp;
38 } 38 }
39 Folder *it; 39 Folder *it;
40 QListViewItem*item = 0; 40 QListViewItem*item = 0;
41 for ( it = folders->first(); it; it = folders->next() ) { 41 for ( it = folders->first(); it; it = folders->next() ) {
42 item = new POP3folderItem( it, this , item ); 42 item = new POP3folderItem( it, this , item );
43 item->setSelectable(it->may_select()); 43 item->setSelectable(it->may_select());
44 } 44 }
45 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 45 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
46 folders->setAutoDelete(false); 46 folders->setAutoDelete(false);
47 delete folders; 47 delete folders;
48} 48}
49 49
50RecBody POP3viewItem::fetchBody( const RecMail &mail ) 50RecBody POP3viewItem::fetchBody( const RecMail &mail )
51{ 51{
52 qDebug( "POP3 fetchBody" ); 52 qDebug( "POP3 fetchBody" );
53 return wrapper->fetchBody( mail ); 53 return wrapper->fetchBody( mail );
54} 54}
55 55
56POP3folderItem::~POP3folderItem() 56POP3folderItem::~POP3folderItem()
57{ 57{
58 delete folder; 58 delete folder;
59} 59}
60 60
61POP3folderItem::POP3folderItem( Folder *folderInit, POP3viewItem *parent , QListViewItem*after ) 61POP3folderItem::POP3folderItem( Folder *folderInit, POP3viewItem *parent , QListViewItem*after )
62 : AccountViewItem( parent,after ) 62 : AccountViewItem( parent,after )
63{ 63{
64 folder = folderInit; 64 folder = folderInit;
65 pop3 = parent; 65 pop3 = parent;
66 if (folder->getDisplayName().lower()!="inbox") { 66 if (folder->getDisplayName().lower()!="inbox") {
67 setPixmap( 0, PIXMAP_POP3FOLDER ); 67 setPixmap( 0, PIXMAP_POP3FOLDER );
68 } else { 68 } else {
69 setPixmap( 0, PIXMAP_INBOXFOLDER); 69 setPixmap( 0, PIXMAP_INBOXFOLDER);
70 } 70 }
71 setText( 0, folder->getDisplayName() ); 71 setText( 0, folder->getDisplayName() );
72} 72}
73 73
74void POP3folderItem::refresh(QList<RecMail>&target) 74void POP3folderItem::refresh(QList<RecMail>&target)
75{ 75{
76 if (folder->may_select()) 76 if (folder->may_select())
77 pop3->getWrapper()->listMessages( folder->getName(),target ); 77 pop3->getWrapper()->listMessages( folder->getName(),target );
78} 78}
79 79
80RecBody POP3folderItem::fetchBody(const RecMail&aMail) 80RecBody POP3folderItem::fetchBody(const RecMail&aMail)
81{ 81{
82 return pop3->getWrapper()->fetchBody(aMail); 82 return pop3->getWrapper()->fetchBody(aMail);
83} 83}
84 84
85/** 85/**
86 * IMAP Account stuff 86 * IMAP Account stuff
87 */ 87 */
88IMAPviewItem::IMAPviewItem( IMAPaccount *a, QListView *parent ) 88IMAPviewItem::IMAPviewItem( IMAPaccount *a, QListView *parent )
89 : AccountViewItem( parent ) 89 : AccountViewItem( parent )
90{ 90{
91 account = a; 91 account = a;
92 wrapper = AbstractMail::getWrapper( account ); 92 wrapper = AbstractMail::getWrapper( account );
93 setPixmap( 0, PIXMAP_IMAPFOLDER ); 93 setPixmap( 0, PIXMAP_IMAPFOLDER );
94 setText( 0, account->getAccountName() ); 94 setText( 0, account->getAccountName() );
95 setOpen( true ); 95 setOpen( true );
96} 96}
97 97
98IMAPviewItem::~IMAPviewItem() 98IMAPviewItem::~IMAPviewItem()
99{ 99{
100 delete wrapper; 100 delete wrapper;
101} 101}
102 102
103AbstractMail *IMAPviewItem::getWrapper() 103AbstractMail *IMAPviewItem::getWrapper()
104{ 104{
105 return wrapper; 105 return wrapper;
106} 106}
107 107
108IMAPfolderItem*IMAPviewItem::findSubItem(const QString&path,IMAPfolderItem*start) 108IMAPfolderItem*IMAPviewItem::findSubItem(const QString&path,IMAPfolderItem*start)
109{ 109{
110 IMAPfolderItem*pitem,*sitem; 110 IMAPfolderItem*pitem,*sitem;
111 if (!start) pitem = (IMAPfolderItem*)firstChild(); 111 if (!start) pitem = (IMAPfolderItem*)firstChild();
112 else pitem = (IMAPfolderItem*)start->firstChild(); 112 else pitem = (IMAPfolderItem*)start->firstChild();
113 while (pitem) { 113 while (pitem) {
114 if (pitem->matchName(path)) { 114 if (pitem->matchName(path)) {
115 break; 115 break;
116 } 116 }
117 if (pitem->childCount()>0) { 117 if (pitem->childCount()>0) {
118 sitem = findSubItem(path,pitem); 118 sitem = findSubItem(path,pitem);
119 if (sitem) { 119 if (sitem) {
120 pitem = sitem; 120 pitem = sitem;
121 break; 121 break;
122 } 122 }
123 } 123 }
124 pitem=(IMAPfolderItem*)pitem->nextSibling(); 124 pitem=(IMAPfolderItem*)pitem->nextSibling();
125 } 125 }
126 return pitem; 126 return pitem;
127} 127}
128 128
129void IMAPviewItem::refresh(QList<RecMail>&) 129void IMAPviewItem::refresh(QList<RecMail>&)
130{ 130{
131 if (childCount()>0) return; 131 if (childCount()>0) return;
132 QList<Folder> *folders = wrapper->listFolders(); 132 QList<Folder> *folders = wrapper->listFolders();
133 133
134 QListViewItem *child = firstChild(); 134 QListViewItem *child = firstChild();
135 while ( child ) { 135 while ( child ) {
136 QListViewItem *tmp = child; 136 QListViewItem *tmp = child;
137 child = child->nextSibling(); 137 child = child->nextSibling();
138 delete tmp; 138 delete tmp;
139 } 139 }
140 140
141 Folder *it; 141 Folder *it;
142 QListViewItem*item = 0; 142 QListViewItem*item = 0;
143 QListViewItem*titem = 0; 143 QListViewItem*titem = 0;
144 QString fname,del,search; 144 QString fname,del,search;
145 int pos; 145 int pos;
146 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 146 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
147 folders->setAutoDelete(false); 147 folders->setAutoDelete(false);
148 148
149 for ( it = folders->first(); it; it = folders->next() ) { 149 for ( it = folders->first(); it; it = folders->next() ) {
150 if (it->getDisplayName().lower()=="inbox") { 150 if (it->getDisplayName().lower()=="inbox") {
151 item = new IMAPfolderItem( it, this , item ); 151 item = new IMAPfolderItem( it, this , item );
152 folders->remove(it); 152 folders->remove(it);
153 qDebug("inbox found"); 153 qDebug("inbox found");
154 break; 154 break;
155 } 155 }
156 } 156 }
157 for ( it = folders->first(); it; it = folders->next() ) { 157 for ( it = folders->first(); it; it = folders->next() ) {
158 fname = it->getDisplayName(); 158 fname = it->getDisplayName();
159 pos = fname.findRev(it->Separator()); 159 pos = fname.findRev(it->Separator());
160 if (pos != -1) { 160 if (pos != -1) {
161 fname = fname.left(pos); 161 fname = fname.left(pos);
162 } 162 }
163 IMAPfolderItem*pitem = findSubItem(fname); 163 IMAPfolderItem*pitem = findSubItem(fname);
164 if (pitem) { 164 if (pitem) {
165 titem = item; 165 titem = item;
166 item = new IMAPfolderItem(it,pitem,pitem->firstChild(),this); 166 item = new IMAPfolderItem(it,pitem,pitem->firstChild(),this);
167 item->setSelectable(it->may_select()); 167 item->setSelectable(it->may_select());
168 /* setup the short name */ 168 /* setup the short name */
169 item->setText(0,it->getDisplayName().right(it->getDisplayName().length()-pos-1)); 169 item->setText(0,it->getDisplayName().right(it->getDisplayName().length()-pos-1));
170 item = titem; 170 item = titem;
171 } else { 171 } else {
172 item = new IMAPfolderItem( it, this , item ); 172 item = new IMAPfolderItem( it, this , item );
173 item->setSelectable(it->may_select()); 173 item->setSelectable(it->may_select());
174 } 174 }
175 } 175 }
176 delete folders; 176 delete folders;
177} 177}
178 178
179RecBody IMAPviewItem::fetchBody(const RecMail&) 179RecBody IMAPviewItem::fetchBody(const RecMail&)
180{ 180{
181 return RecBody(); 181 return RecBody();
182} 182}
183 183
184IMAPfolderItem::~IMAPfolderItem() 184IMAPfolderItem::~IMAPfolderItem()
185{ 185{
186 delete folder; 186 delete folder;
187} 187}
188 188
189IMAPfolderItem::IMAPfolderItem( Folder *folderInit, IMAPviewItem *parent , QListViewItem*after ) 189IMAPfolderItem::IMAPfolderItem( Folder *folderInit, IMAPviewItem *parent , QListViewItem*after )
190 : AccountViewItem( parent , after ) 190 : AccountViewItem( parent , after )
191{ 191{
192 folder = folderInit; 192 folder = folderInit;
193 imap = parent; 193 imap = parent;
194 if (folder->getDisplayName().lower()!="inbox") { 194 if (folder->getDisplayName().lower()!="inbox") {
195 setPixmap( 0, PIXMAP_IMAPFOLDER ); 195 setPixmap( 0, PIXMAP_IMAPFOLDER );
196 } else { 196 } else {
197 setPixmap( 0, PIXMAP_INBOXFOLDER); 197 setPixmap( 0, PIXMAP_INBOXFOLDER);
198 } 198 }
199 setText( 0, folder->getDisplayName() ); 199 setText( 0, folder->getDisplayName() );
200} 200}
201 201
202IMAPfolderItem::IMAPfolderItem( Folder *folderInit, IMAPfolderItem *parent , QListViewItem*after, IMAPviewItem *master ) 202IMAPfolderItem::IMAPfolderItem( Folder *folderInit, IMAPfolderItem *parent , QListViewItem*after, IMAPviewItem *master )
203 : AccountViewItem( parent,after ) 203 : AccountViewItem( parent,after )
204{ 204{
205 folder = folderInit; 205 folder = folderInit;
206 imap = master; 206 imap = master;
207 if (folder->getDisplayName().lower()!="inbox") { 207 if (folder->getDisplayName().lower()!="inbox") {
208 setPixmap( 0, PIXMAP_IMAPFOLDER ); 208 setPixmap( 0, PIXMAP_IMAPFOLDER );
209 } else { 209 } else {
210 setPixmap( 0, PIXMAP_INBOXFOLDER); 210 setPixmap( 0, PIXMAP_INBOXFOLDER);
211 } 211 }
212 setText( 0, folder->getDisplayName() ); 212 setText( 0, folder->getDisplayName() );
213} 213}
214 214
215bool IMAPfolderItem::matchName(const QString&name)const 215bool IMAPfolderItem::matchName(const QString&name)const
216{ 216{
217 return folder->getDisplayName()==name; 217 return folder->getDisplayName()==name;
218} 218}
219 219
220void IMAPfolderItem::refresh(QList<RecMail>&target) 220void IMAPfolderItem::refresh(QList<RecMail>&target)
221{ 221{
222 if (folder->may_select()) 222 if (folder->may_select())
223 imap->getWrapper()->listMessages( folder->getName(),target ); 223 imap->getWrapper()->listMessages( folder->getName(),target );
224} 224}
225 225
226RecBody IMAPfolderItem::fetchBody(const RecMail&aMail) 226RecBody IMAPfolderItem::fetchBody(const RecMail&aMail)
227{ 227{
228 return imap->getWrapper()->fetchBody(aMail); 228 return imap->getWrapper()->fetchBody(aMail);
229} 229}
230 230
231
231/** 232/**
232 * Generic stuff 233 * Generic stuff
233 */ 234 */
234 235
235AccountView::AccountView( QWidget *parent, const char *name, WFlags flags ) 236AccountView::AccountView( QWidget *parent, const char *name, WFlags flags )
236 : QListView( parent, name, flags ) 237 : QListView( parent, name, flags )
237{ 238{
238 connect( this, SIGNAL( selectionChanged( QListViewItem * ) ), 239 connect( this, SIGNAL( selectionChanged( QListViewItem * ) ),
239 SLOT( refresh( QListViewItem * ) ) ); 240 SLOT( refresh( QListViewItem * ) ) );
240 setSorting(0); 241 setSorting(0);
241} 242}
242 243
243void AccountView::populate( QList<Account> list ) 244void AccountView::populate( QList<Account> list )
244{ 245{
245 clear(); 246 clear();
246 247
248 QString localfolders = (QString) getenv( "HOME" ) + QString("/Applications/opiemail/localmail/");
249 (void) new MBOXviewItem(localfolders,this);
250
247 Account *it; 251 Account *it;
248 for ( it = list.first(); it; it = list.next() ) { 252 for ( it = list.first(); it; it = list.next() ) {
249 if ( it->getType().compare( "IMAP" ) == 0 ) { 253 if ( it->getType().compare( "IMAP" ) == 0 ) {
250 IMAPaccount *imap = static_cast<IMAPaccount *>(it); 254 IMAPaccount *imap = static_cast<IMAPaccount *>(it);
251 qDebug( "added IMAP " + imap->getAccountName() ); 255 qDebug( "added IMAP " + imap->getAccountName() );
252 (void) new IMAPviewItem( imap, this ); 256 (void) new IMAPviewItem( imap, this );
253 } else if ( it->getType().compare( "POP3" ) == 0 ) { 257 } else if ( it->getType().compare( "POP3" ) == 0 ) {
254 POP3account *pop3 = static_cast<POP3account *>(it); 258 POP3account *pop3 = static_cast<POP3account *>(it);
255 qDebug( "added POP3 " + pop3->getAccountName() ); 259 qDebug( "added POP3 " + pop3->getAccountName() );
256 (void) new POP3viewItem( pop3, this ); 260 (void) new POP3viewItem( pop3, this );
257 } 261 }
258 } 262 }
259} 263}
260 264
261void AccountView::refresh(QListViewItem *item) { 265void AccountView::refresh(QListViewItem *item) {
262 266
263 qDebug("AccountView refresh..."); 267 qDebug("AccountView refresh...");
264 if ( item ) { 268 if ( item ) {
265 m_currentItem = item; 269 m_currentItem = item;
266 QList<RecMail> headerlist; 270 QList<RecMail> headerlist;
267 headerlist.setAutoDelete(true); 271 headerlist.setAutoDelete(true);
268 AccountViewItem *view = static_cast<AccountViewItem *>(item); 272 AccountViewItem *view = static_cast<AccountViewItem *>(item);
269 view->refresh(headerlist); 273 view->refresh(headerlist);
270 emit refreshMailview(&headerlist); 274 emit refreshMailview(&headerlist);
271 } 275 }
272} 276}
273 277
274void AccountView::refreshCurrent() 278void AccountView::refreshCurrent()
275{ 279{
276 if ( !m_currentItem ) return; 280 if ( !m_currentItem ) return;
277 QList<RecMail> headerlist; 281 QList<RecMail> headerlist;
278 headerlist.setAutoDelete(true); 282 headerlist.setAutoDelete(true);
279 AccountViewItem *view = static_cast<AccountViewItem *>(m_currentItem); 283 AccountViewItem *view = static_cast<AccountViewItem *>(m_currentItem);
280 view->refresh(headerlist); 284 view->refresh(headerlist);
281 emit refreshMailview(&headerlist); 285 emit refreshMailview(&headerlist);
282} 286}
283 287
284void AccountView::refreshAll() 288void AccountView::refreshAll()
285{ 289{
286 290
287} 291}
288 292
289RecBody AccountView::fetchBody(const RecMail&aMail) 293RecBody AccountView::fetchBody(const RecMail&aMail)
290{ 294{
291 QListViewItem*item = selectedItem (); 295 QListViewItem*item = selectedItem ();
292 if (!item) return RecBody(); 296 if (!item) return RecBody();
293 AccountViewItem *view = static_cast<AccountViewItem *>(item); 297 AccountViewItem *view = static_cast<AccountViewItem *>(item);
294 return view->fetchBody(aMail); 298 return view->fetchBody(aMail);
295} 299}
300
301/**
302 * MBOX Account stuff
303 */
304
305MBOXviewItem::MBOXviewItem( const QString&aPath, QListView *parent )
306 : AccountViewItem( parent )
307{
308 m_Path = aPath;
309 wrapper = AbstractMail::getWrapper( m_Path );
310 setPixmap( 0, PIXMAP_POP3FOLDER );
311 setText( 0, " Local Folders" );
312 setOpen( true );
313}
314
315MBOXviewItem::~MBOXviewItem()
316{
317 delete wrapper;
318}
319
320AbstractMail *MBOXviewItem::getWrapper()
321{
322 return wrapper;
323}
324
325void MBOXviewItem::refresh( QList<RecMail> & )
326{
327 QList<Folder> *folders = wrapper->listFolders();
328 QListViewItem *child = firstChild();
329 while ( child ) {
330 QListViewItem *tmp = child;
331 child = child->nextSibling();
332 delete tmp;
333 }
334 Folder *it;
335 QListViewItem*item = 0;
336 for ( it = folders->first(); it; it = folders->next() ) {
337 item = new MBOXfolderItem( it, this , item );
338 item->setSelectable(it->may_select());
339 }
340 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
341 folders->setAutoDelete(false);
342 delete folders;
343}
344
345RecBody MBOXviewItem::fetchBody( const RecMail &mail )
346{
347 qDebug( "POP3 fetchBody" );
348 return wrapper->fetchBody( mail );
349}
350
351MBOXfolderItem::~MBOXfolderItem()
352{
353 delete folder;
354}
355
356MBOXfolderItem::MBOXfolderItem( Folder *folderInit, MBOXviewItem *parent , QListViewItem*after )
357 : AccountViewItem( parent,after )
358{
359 folder = folderInit;
360 mbox = parent;
361 if (folder->getDisplayName().lower()!="inbox") {
362 setPixmap( 0, PIXMAP_POP3FOLDER );
363 } else {
364 setPixmap( 0, PIXMAP_INBOXFOLDER);
365 }
366 setText( 0, folder->getDisplayName() );
367}
368
369void MBOXfolderItem::refresh(QList<RecMail>&target)
370{
371 if (folder->may_select())
372 mbox->getWrapper()->listMessages( folder->getName(),target );
373}
374
375RecBody MBOXfolderItem::fetchBody(const RecMail&aMail)
376{
377 return mbox->getWrapper()->fetchBody(aMail);
378}
379
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 @@
1#ifndef ACCOUNTVIEW_H 1#ifndef ACCOUNTVIEW_H
2#define ACCOUNTVIEW_H 2#define ACCOUNTVIEW_H
3 3
4#include <qlistview.h> 4#include <qlistview.h>
5#include <qlist.h> 5#include <qlist.h>
6 6
7#include "settings.h" 7#include "settings.h"
8#include "mailwrapper.h" 8#include "mailwrapper.h"
9#include "abstractmail.h" 9#include "abstractmail.h"
10 10
11class POP3wrapper; 11class POP3wrapper;
12class RecMail; 12class RecMail;
13class RecBody; 13class RecBody;
14 14
15class AccountViewItem : public QListViewItem 15class AccountViewItem : public QListViewItem
16{ 16{
17 17
18public: 18public:
19 AccountViewItem( QListView *parent ) : QListViewItem( parent ) {} 19 AccountViewItem( QListView *parent ) : QListViewItem( parent ) {}
20 AccountViewItem( QListViewItem *parent) : QListViewItem( parent) {} 20 AccountViewItem( QListViewItem *parent) : QListViewItem( parent) {}
21 AccountViewItem( QListViewItem *parent , QListViewItem*after ) : QListViewItem( parent,after ) {} 21 AccountViewItem( QListViewItem *parent , QListViewItem*after ) : QListViewItem( parent,after ) {}
22 virtual void refresh(QList<RecMail>&)=0; 22 virtual void refresh(QList<RecMail>&)=0;
23 virtual RecBody fetchBody(const RecMail&)=0; 23 virtual RecBody fetchBody(const RecMail&)=0;
24}; 24};
25 25
26class POP3viewItem : public AccountViewItem 26class POP3viewItem : public AccountViewItem
27{ 27{
28 28
29public: 29public:
30 POP3viewItem( POP3account *a, QListView *parent ); 30 POP3viewItem( POP3account *a, QListView *parent );
31 ~POP3viewItem(); 31 ~POP3viewItem();
32 virtual void refresh( QList<RecMail> &target ); 32 virtual void refresh( QList<RecMail> &target );
33 virtual RecBody fetchBody( const RecMail &mail ); 33 virtual RecBody fetchBody( const RecMail &mail );
34 AbstractMail *getWrapper(); 34 AbstractMail *getWrapper();
35private: 35private:
36 POP3account *account; 36 POP3account *account;
37 AbstractMail *wrapper; 37 AbstractMail *wrapper;
38 38
39}; 39};
40 40
41class POP3folderItem : public AccountViewItem 41class POP3folderItem : public AccountViewItem
42{ 42{
43 43
44public: 44public:
45 POP3folderItem( Folder *folder, POP3viewItem *parent , QListViewItem*after ); 45 POP3folderItem( Folder *folder, POP3viewItem *parent , QListViewItem*after );
46 ~POP3folderItem(); 46 ~POP3folderItem();
47 virtual void refresh(QList<RecMail>&); 47 virtual void refresh(QList<RecMail>&);
48 virtual RecBody fetchBody(const RecMail&); 48 virtual RecBody fetchBody(const RecMail&);
49private: 49private:
50 Folder *folder; 50 Folder *folder;
51 POP3viewItem *pop3; 51 POP3viewItem *pop3;
52}; 52};
53 53
54class IMAPfolderItem; 54class IMAPfolderItem;
55 55
56class IMAPviewItem : public AccountViewItem 56class IMAPviewItem : public AccountViewItem
57{ 57{
58 58
59public: 59public:
60 IMAPviewItem( IMAPaccount *a, QListView *parent ); 60 IMAPviewItem( IMAPaccount *a, QListView *parent );
61 ~IMAPviewItem(); 61 ~IMAPviewItem();
62 virtual void refresh(QList<RecMail>&); 62 virtual void refresh(QList<RecMail>&);
63 virtual RecBody fetchBody(const RecMail&); 63 virtual RecBody fetchBody(const RecMail&);
64 AbstractMail *getWrapper(); 64 AbstractMail *getWrapper();
65 65
66protected: 66protected:
67 IMAPfolderItem*findSubItem(const QString&path,IMAPfolderItem*start=0); 67 IMAPfolderItem*findSubItem(const QString&path,IMAPfolderItem*start=0);
68 68
69private: 69private:
70 IMAPaccount *account; 70 IMAPaccount *account;
71 AbstractMail *wrapper; 71 AbstractMail *wrapper;
72}; 72};
73 73
74class IMAPfolderItem : public AccountViewItem 74class IMAPfolderItem : public AccountViewItem
75{ 75{
76 76
77public: 77public:
78 IMAPfolderItem( Folder *folder, IMAPviewItem *parent , QListViewItem*after ); 78 IMAPfolderItem( Folder *folder, IMAPviewItem *parent , QListViewItem*after );
79 IMAPfolderItem( Folder *folder, IMAPfolderItem *parent , QListViewItem*after, IMAPviewItem *master ); 79 IMAPfolderItem( Folder *folder, IMAPfolderItem *parent , QListViewItem*after, IMAPviewItem *master );
80 ~IMAPfolderItem(); 80 ~IMAPfolderItem();
81 virtual void refresh(QList<RecMail>&); 81 virtual void refresh(QList<RecMail>&);
82 virtual RecBody fetchBody(const RecMail&); 82 virtual RecBody fetchBody(const RecMail&);
83 bool matchName(const QString&name)const; 83 bool matchName(const QString&name)const;
84private: 84private:
85 Folder *folder; 85 Folder *folder;
86 IMAPviewItem *imap; 86 IMAPviewItem *imap;
87}; 87};
88 88
89class MBOXviewItem : public AccountViewItem
90{
91
92public:
93// MBOXviewItem( MBOXaccount *a, QListView *parent );
94 MBOXviewItem( const QString&aMboxPath, QListView *parent );
95 ~MBOXviewItem();
96 virtual void refresh( QList<RecMail> &target );
97 virtual RecBody fetchBody( const RecMail &mail );
98 AbstractMail *getWrapper();
99private:
100// MBOXaccount *account;
101 QString m_Path;
102 AbstractMail *wrapper;
103
104};
105
106class MBOXfolderItem : public AccountViewItem
107{
108
109public:
110 MBOXfolderItem( Folder *folder, MBOXviewItem *parent , QListViewItem*after );
111 ~MBOXfolderItem();
112 virtual void refresh(QList<RecMail>&);
113 virtual RecBody fetchBody(const RecMail&);
114private:
115 Folder *folder;
116 MBOXviewItem *mbox;
117};
118
89class AccountView : public QListView 119class AccountView : public QListView
90{ 120{
91 Q_OBJECT 121 Q_OBJECT
92 122
93public: 123public:
94 AccountView( QWidget *parent = 0, const char *name = 0, WFlags flags = 0 ); 124 AccountView( QWidget *parent = 0, const char *name = 0, WFlags flags = 0 );
95 void populate( QList<Account> list ); 125 void populate( QList<Account> list );
96 RecBody fetchBody(const RecMail&aMail); 126 RecBody fetchBody(const RecMail&aMail);
97 127
98public slots: 128public slots:
99 void refreshAll(); 129 void refreshAll();
100 void refresh(QListViewItem *item); 130 void refresh(QListViewItem *item);
101 void refreshCurrent(); 131 void refreshCurrent();
102 132
103signals: 133signals:
104 void refreshMailview(QList<RecMail>*); 134 void refreshMailview(QList<RecMail>*);
105 135
106private: 136private:
107 QListViewItem* m_currentItem; 137 QListViewItem* m_currentItem;
108}; 138};
109 139
110#endif 140#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 @@
1#include "genericwrapper.h"
2#include <libetpan/mailmime.h>
3#include <libetpan/data_message_driver.h>
4#include "mailtypes.h"
5
6Genericwrapper::Genericwrapper()
7 : AbstractMail()
8{
9 bodyCache.clear();
10}
11
12Genericwrapper::~Genericwrapper()
13{
14 cleanMimeCache();
15}
16
17void Genericwrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
18{
19 if (!mime) {
20 return;
21 }
22 mailmime_field*field = 0;
23 mailmime_single_fields fields;
24 memset(&fields, 0, sizeof(struct mailmime_single_fields));
25 if (mime->mm_mime_fields != NULL) {
26 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
27 mime->mm_content_type);
28 }
29
30 mailmime_content*type = fields.fld_content;
31 clistcell*current;
32 if (!type) {
33 target.setType("text");
34 target.setSubtype("plain");
35 } else {
36 target.setSubtype(type->ct_subtype);
37 switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
38 case MAILMIME_DISCRETE_TYPE_TEXT:
39 target.setType("text");
40 break;
41 case MAILMIME_DISCRETE_TYPE_IMAGE:
42 target.setType("image");
43 break;
44 case MAILMIME_DISCRETE_TYPE_AUDIO:
45 target.setType("audio");
46 break;
47 case MAILMIME_DISCRETE_TYPE_VIDEO:
48 target.setType("video");
49 break;
50 case MAILMIME_DISCRETE_TYPE_APPLICATION:
51 target.setType("application");
52 break;
53 case MAILMIME_DISCRETE_TYPE_EXTENSION:
54 default:
55 if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
56 target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
57 }
58 break;
59 }
60 if (type->ct_parameters) {
61 fillParameters(target,type->ct_parameters);
62 }
63 }
64 if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
65 for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
66 field = (mailmime_field*)current->data;
67 switch(field->fld_type) {
68 case MAILMIME_FIELD_TRANSFER_ENCODING:
69 target.setEncoding(getencoding(field->fld_data.fld_encoding));
70 break;
71 case MAILMIME_FIELD_ID:
72 target.setIdentifier(field->fld_data.fld_id);
73 break;
74 case MAILMIME_FIELD_DESCRIPTION:
75 target.setDescription(field->fld_data.fld_description);
76 break;
77 default:
78 break;
79 }
80 }
81 }
82}
83
84void Genericwrapper::fillParameters(RecPart&target,clist*parameters)
85{
86 if (!parameters) {return;}
87 clistcell*current=0;
88 mailmime_parameter*param;
89 for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
90 param = (mailmime_parameter*)current->data;
91 if (param) {
92 target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
93 }
94 }
95}
96
97QString Genericwrapper::getencoding(mailmime_mechanism*aEnc)
98{
99 QString enc="7bit";
100 if (!aEnc) return enc;
101 switch(aEnc->enc_type) {
102 case MAILMIME_MECHANISM_7BIT:
103 enc = "7bit";
104 break;
105 case MAILMIME_MECHANISM_8BIT:
106 enc = "8bit";
107 break;
108 case MAILMIME_MECHANISM_BINARY:
109 enc = "binary";
110 break;
111 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
112 enc = "quoted-printable";
113 break;
114 case MAILMIME_MECHANISM_BASE64:
115 enc = "base64";
116 break;
117 case MAILMIME_MECHANISM_TOKEN:
118 default:
119 if (aEnc->enc_token) {
120 enc = QString(aEnc->enc_token);
121 }
122 break;
123 }
124 return enc;
125}
126
127void Genericwrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec)
128{
129 if (current_rec >= 10) {
130 qDebug("too deep recursion!");
131 }
132 if (!message || !mime) {
133 return;
134 }
135 int r;
136 char*data = 0;
137 size_t len;
138 clistiter * cur = 0;
139 QString b;
140 RecPart part;
141
142 switch (mime->mm_type) {
143 case MAILMIME_SINGLE:
144 r = mailmessage_fetch_section(message,mime,&data,&len);
145 part.setSize(len);
146 fillSingleBody(part,message,mime);
147 if (part.Type()=="text" && target.Bodytext().isNull()) {
148 encodedString*r = new encodedString();
149 r->setContent(data,len);
150 encodedString*res = decode_String(r,part.Encoding());
151 b = QString(res->Content());
152 delete r;
153 delete res;
154 target.setBodytext(b);
155 target.setDescription(part);
156 } else {
157 b = gen_attachment_id();
158 part.setIdentifier(b);
159 bodyCache[b]=new encodedString(data,len);
160 target.addPart(part);
161 }
162 break;
163 case MAILMIME_MULTIPLE:
164 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
165 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1);
166 }
167 break;
168 case MAILMIME_MESSAGE:
169 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
170 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1);
171 }
172 break;
173 }
174}
175
176RecBody Genericwrapper::parseMail( mailmessage * msg )
177{
178 int err = MAILIMF_NO_ERROR;
179 mailmime_single_fields fields;
180 /* is bound to msg and will be freed there */
181 mailmime * mime=0;
182 RecBody body;
183 memset(&fields, 0, sizeof(struct mailmime_single_fields));
184 err = mailmessage_get_bodystructure(msg,&mime);
185 traverseBody(body,msg,mime);
186 return body;
187}
188
189RecMail *Genericwrapper::parseHeader( const char *header )
190{
191 int err = MAILIMF_NO_ERROR;
192 size_t curTok = 0;
193 RecMail *mail = new RecMail();
194 mailimf_fields *fields;
195 mailimf_references * refs;
196 mailimf_keywords*keys;
197 QString status;
198 QString value;
199 QBitArray mFlags(7);
200
201 err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
202 for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
203 mailimf_field *field = (mailimf_field *) current->data;
204 switch ( field->fld_type ) {
205 case MAILIMF_FIELD_FROM:
206 mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
207 break;
208 case MAILIMF_FIELD_TO:
209 mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
210 break;
211 case MAILIMF_FIELD_CC:
212 mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
213 break;
214 case MAILIMF_FIELD_BCC:
215 mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
216 break;
217 case MAILIMF_FIELD_SUBJECT:
218 mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
219 break;
220 case MAILIMF_FIELD_ORIG_DATE:
221 mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
222 break;
223 case MAILIMF_FIELD_MESSAGE_ID:
224 mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
225 break;
226 case MAILIMF_FIELD_REFERENCES:
227 refs = field->fld_data.fld_references;
228 if (refs && refs->mid_list && clist_count(refs->mid_list)) {
229 char * text = (char*)refs->mid_list->first->data;
230 mail->setReplyto(QString(text));
231 }
232 break;
233 case MAILIMF_FIELD_KEYWORDS:
234 keys = field->fld_data.fld_keywords;
235 for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
236 qDebug("Keyword: %s",(char*)cur->data);
237 }
238 break;
239 case MAILIMF_FIELD_OPTIONAL_FIELD:
240 status = field->fld_data.fld_optional_field->fld_name;
241 value = field->fld_data.fld_optional_field->fld_value;
242 if (status.lower()=="status") {
243 if (value.lower()=="ro") {
244 mFlags.setBit(FLAG_SEEN);
245 }
246 } else if (status.lower()=="x-status") {
247 qDebug("X-Status: %s",value.latin1());
248 if (value.lower()=="a") {
249 mFlags.setBit(FLAG_ANSWERED);
250 }
251 } else {
252// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
253// field->fld_data.fld_optional_field->fld_value);
254 }
255 break;
256 default:
257 qDebug("Non parsed field");
258 break;
259 }
260 }
261 if (fields) mailimf_fields_free(fields);
262 mail->setFlags(mFlags);
263 return mail;
264}
265
266QString Genericwrapper::parseDateTime( mailimf_date_time *date )
267{
268 char tmp[23];
269
270 snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
271 date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
272
273 return QString( tmp );
274}
275
276QString Genericwrapper::parseAddressList( mailimf_address_list *list )
277{
278 QString result( "" );
279
280 bool first = true;
281 if (list == 0) return result;
282 for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
283 mailimf_address *addr = (mailimf_address *) current->data;
284
285 if ( !first ) {
286 result.append( "," );
287 } else {
288 first = false;
289 }
290
291 switch ( addr->ad_type ) {
292 case MAILIMF_ADDRESS_MAILBOX:
293 result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
294 break;
295 case MAILIMF_ADDRESS_GROUP:
296 result.append( parseGroup( addr->ad_data.ad_group ) );
297 break;
298 default:
299 qDebug( "Generic: unkown mailimf address type" );
300 break;
301 }
302 }
303
304 return result;
305}
306
307QString Genericwrapper::parseGroup( mailimf_group *group )
308{
309 QString result( "" );
310
311 result.append( group->grp_display_name );
312 result.append( ": " );
313
314 if ( group->grp_mb_list != NULL ) {
315 result.append( parseMailboxList( group->grp_mb_list ) );
316 }
317
318 result.append( ";" );
319
320 return result;
321}
322
323QString Genericwrapper::parseMailbox( mailimf_mailbox *box )
324{
325 QString result( "" );
326
327 if ( box->mb_display_name == NULL ) {
328 result.append( box->mb_addr_spec );
329 } else {
330 result.append( convert_String(box->mb_display_name).latin1() );
331 result.append( " <" );
332 result.append( box->mb_addr_spec );
333 result.append( ">" );
334 }
335
336 return result;
337}
338
339QString Genericwrapper::parseMailboxList( mailimf_mailbox_list *list )
340{
341 QString result( "" );
342
343 bool first = true;
344 for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
345 mailimf_mailbox *box = (mailimf_mailbox *) current->data;
346
347 if ( !first ) {
348 result.append( "," );
349 } else {
350 first = false;
351 }
352
353 result.append( parseMailbox( box ) );
354 }
355
356 return result;
357}
358
359encodedString* Genericwrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
360{
361 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
362 if (it==bodyCache.end()) return new encodedString();
363 encodedString*t = decode_String(it.data(),part.Encoding());
364 return t;
365}
366
367encodedString* Genericwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
368{
369 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
370 if (it==bodyCache.end()) return new encodedString();
371 encodedString*t = it.data();
372 return t;
373}
374
375QString Genericwrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
376{
377 encodedString*t = fetchDecodedPart(mail,part);
378 QString text=t->Content();
379 delete t;
380 return text;
381}
382
383void Genericwrapper::cleanMimeCache()
384{
385 QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
386 for (;it!=bodyCache.end();++it) {
387 encodedString*t = it.data();
388 //it.setValue(0);
389 if (t) delete t;
390 }
391 bodyCache.clear();
392 qDebug("Genericwrapper: cache cleaned");
393}
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 @@
1#ifndef __GENERIC_WRAPPER_H
2#define __GENERIC_WRAPPER_H
3
4#include "abstractmail.h"
5#include <qmap.h>
6#include <qstring.h>
7#include <libetpan/clist.h>
8
9class RecMail;
10class RecBody;
11class encodedString;
12struct mailpop3;
13struct mailmessage;
14struct mailmime;
15struct mailmime_mechanism;
16struct mailimf_mailbox_list;
17struct mailimf_mailbox;
18struct mailimf_date_time;
19struct mailimf_group;
20struct mailimf_address_list;
21
22/* this class hold just the funs shared between
23 * mbox and pop3 (later mh, too) mail access.
24 * it is not desigend to make a instance of it!
25 */
26class Genericwrapper : public AbstractMail
27{
28 Q_OBJECT
29public:
30 Genericwrapper();
31 virtual ~Genericwrapper();
32
33 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
34 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
35 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
36 virtual void cleanMimeCache();
37
38protected:
39 RecMail *parseHeader( const char *header );
40 RecBody parseMail( mailmessage * msg );
41 QString parseMailboxList( mailimf_mailbox_list *list );
42 QString parseMailbox( mailimf_mailbox *box );
43 QString parseGroup( mailimf_group *group );
44 QString parseAddressList( mailimf_address_list *list );
45 QString parseDateTime( mailimf_date_time *date );
46
47 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
48 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
49 static void fillParameters(RecPart&target,clist*parameters);
50 static QString getencoding(mailmime_mechanism*aEnc);
51
52 POP3account *account;
53 mailpop3 *m_pop3;
54 QString msgTempName;
55 unsigned int last_msg_id;
56 QMap<QString,encodedString*> bodyCache;
57};
58
59#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 @@
1#include "abstractmail.h" 1#include "abstractmail.h"
2#include "imapwrapper.h" 2#include "imapwrapper.h"
3#include "pop3wrapper.h" 3#include "pop3wrapper.h"
4#include "mboxwrapper.h"
4#include "mailtypes.h" 5#include "mailtypes.h"
5 6
6#include <qstring.h> 7#include <qstring.h>
7#include <qfile.h> 8#include <qfile.h>
8#include <qtextstream.h> 9#include <qtextstream.h>
9#include <stdlib.h> 10#include <stdlib.h>
10#include <libetpan/mailmime_content.h> 11#include <libetpan/mailmime_content.h>
11#include <libetpan/mailmime.h> 12#include <libetpan/mailmime.h>
12 13
13AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) 14AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
14{ 15{
15 return new IMAPwrapper(a); 16 return new IMAPwrapper(a);
16} 17}
17 18
18AbstractMail* AbstractMail::getWrapper(POP3account *a) 19AbstractMail* AbstractMail::getWrapper(POP3account *a)
19{ 20{
20 return new POP3wrapper(a); 21 return new POP3wrapper(a);
21} 22}
22 23
24AbstractMail* AbstractMail::getWrapper(const QString&a)
25{
26 return new MBOXwrapper(a);
27}
28
23encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) 29encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
24{ 30{
25 qDebug("Decode string start"); 31 qDebug("Decode string start");
26 char*result_text; 32 char*result_text;
27 size_t index = 0; 33 size_t index = 0;
28 /* reset for recursive use! */ 34 /* reset for recursive use! */
29 size_t target_length = 0; 35 size_t target_length = 0;
30 result_text = 0; 36 result_text = 0;
31 int mimetype = MAILMIME_MECHANISM_7BIT; 37 int mimetype = MAILMIME_MECHANISM_7BIT;
32 if (enc.lower()=="quoted-printable") { 38 if (enc.lower()=="quoted-printable") {
33 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; 39 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
34 } else if (enc.lower()=="base64") { 40 } else if (enc.lower()=="base64") {
35 mimetype = MAILMIME_MECHANISM_BASE64; 41 mimetype = MAILMIME_MECHANISM_BASE64;
36 } else if (enc.lower()=="8bit") { 42 } else if (enc.lower()=="8bit") {
37 mimetype = MAILMIME_MECHANISM_8BIT; 43 mimetype = MAILMIME_MECHANISM_8BIT;
38 } else if (enc.lower()=="binary") { 44 } else if (enc.lower()=="binary") {
39 mimetype = MAILMIME_MECHANISM_BINARY; 45 mimetype = MAILMIME_MECHANISM_BINARY;
40 } 46 }
41 47
42 int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype, 48 int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype,
43 &result_text,&target_length); 49 &result_text,&target_length);
44 50
45 encodedString* result = new encodedString(); 51 encodedString* result = new encodedString();
46 if (err == MAILIMF_NO_ERROR) { 52 if (err == MAILIMF_NO_ERROR) {
47 result->setContent(result_text,target_length); 53 result->setContent(result_text,target_length);
48 } 54 }
49 qDebug("Decode string finished"); 55 qDebug("Decode string finished");
50 return result; 56 return result;
51} 57}
52 58
53QString AbstractMail::convert_String(const char*text) 59QString AbstractMail::convert_String(const char*text)
54{ 60{
55 size_t index = 0; 61 size_t index = 0;
56 char*res = 0; 62 char*res = 0;
57 63
58 /* attention - doesn't work with arm systems! */ 64 /* attention - doesn't work with arm systems! */
59 int err = mailmime_encoded_phrase_parse("iso-8859-1", 65 int err = mailmime_encoded_phrase_parse("iso-8859-1",
60 text, strlen(text),&index, "iso-8859-1",&res); 66 text, strlen(text),&index, "iso-8859-1",&res);
61 if (err != MAILIMF_NO_ERROR) { 67 if (err != MAILIMF_NO_ERROR) {
62 if (res) free(res); 68 if (res) free(res);
63 return QString(text); 69 return QString(text);
64 } 70 }
65 if (res) { 71 if (res) {
66 QString result(res); 72 QString result(res);
67 free(res); 73 free(res);
68 return result; 74 return result;
69 } 75 }
70 return QString(text); 76 return QString(text);
71} 77}
72 78
73/* cp & paste from launcher */ 79/* cp & paste from launcher */
74QString AbstractMail::gen_attachment_id() 80QString AbstractMail::gen_attachment_id()
75{ 81{
76 QFile file( "/proc/sys/kernel/random/uuid" ); 82 QFile file( "/proc/sys/kernel/random/uuid" );
77 if (!file.open(IO_ReadOnly ) ) 83 if (!file.open(IO_ReadOnly ) )
78 return QString::null; 84 return QString::null;
79 85
80 QTextStream stream(&file); 86 QTextStream stream(&file);
81 87
82 return "{" + stream.read().stripWhiteSpace() + "}"; 88 return "{" + stream.read().stripWhiteSpace() + "}";
83} 89}
84 90
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 @@
1#ifndef __abstract_mail_ 1#ifndef __abstract_mail_
2#define __abstract_mail_ 2#define __abstract_mail_
3 3
4#include <qobject.h> 4#include <qobject.h>
5#include "settings.h" 5#include "settings.h"
6 6
7class RecMail; 7class RecMail;
8class RecBody; 8class RecBody;
9class RecPart; 9class RecPart;
10class IMAPwrapper; 10class IMAPwrapper;
11class POP3wrapper; 11class POP3wrapper;
12class Folder; 12class Folder;
13class encodedString; 13class encodedString;
14 14
15class AbstractMail:public QObject 15class AbstractMail:public QObject
16{ 16{
17 Q_OBJECT 17 Q_OBJECT
18public: 18public:
19 AbstractMail(){}; 19 AbstractMail(){};
20 virtual ~AbstractMail(){} 20 virtual ~AbstractMail(){}
21 virtual QList<Folder>* listFolders()=0; 21 virtual QList<Folder>* listFolders()=0;
22 virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0; 22 virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0;
23 virtual RecBody fetchBody(const RecMail&mail)=0; 23 virtual RecBody fetchBody(const RecMail&mail)=0;
24 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part)=0; 24 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part)=0;
25 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0; 25 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0;
26 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0; 26 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0;
27 27
28 virtual void deleteMail(const RecMail&mail)=0; 28 virtual void deleteMail(const RecMail&mail)=0;
29 virtual void answeredMail(const RecMail&mail)=0; 29 virtual void answeredMail(const RecMail&mail)=0;
30 virtual void cleanMimeCache(){};
30 31
31 static AbstractMail* getWrapper(IMAPaccount *a); 32 static AbstractMail* getWrapper(IMAPaccount *a);
32 static AbstractMail* getWrapper(POP3account *a); 33 static AbstractMail* getWrapper(POP3account *a);
34 /* mbox only! */
35 static AbstractMail* getWrapper(const QString&a);
33 36
34protected: 37protected:
35 static encodedString*decode_String(const encodedString*text,const QString&enc); 38 static encodedString*decode_String(const encodedString*text,const QString&enc);
36 static QString convert_String(const char*text); 39 static QString convert_String(const char*text);
37 static QString gen_attachment_id(); 40 static QString gen_attachment_id();
38}; 41};
39#endif 42#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 @@
1#include "genericwrapper.h"
2#include <libetpan/mailmime.h>
3#include <libetpan/data_message_driver.h>
4#include "mailtypes.h"
5
6Genericwrapper::Genericwrapper()
7 : AbstractMail()
8{
9 bodyCache.clear();
10}
11
12Genericwrapper::~Genericwrapper()
13{
14 cleanMimeCache();
15}
16
17void Genericwrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
18{
19 if (!mime) {
20 return;
21 }
22 mailmime_field*field = 0;
23 mailmime_single_fields fields;
24 memset(&fields, 0, sizeof(struct mailmime_single_fields));
25 if (mime->mm_mime_fields != NULL) {
26 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
27 mime->mm_content_type);
28 }
29
30 mailmime_content*type = fields.fld_content;
31 clistcell*current;
32 if (!type) {
33 target.setType("text");
34 target.setSubtype("plain");
35 } else {
36 target.setSubtype(type->ct_subtype);
37 switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
38 case MAILMIME_DISCRETE_TYPE_TEXT:
39 target.setType("text");
40 break;
41 case MAILMIME_DISCRETE_TYPE_IMAGE:
42 target.setType("image");
43 break;
44 case MAILMIME_DISCRETE_TYPE_AUDIO:
45 target.setType("audio");
46 break;
47 case MAILMIME_DISCRETE_TYPE_VIDEO:
48 target.setType("video");
49 break;
50 case MAILMIME_DISCRETE_TYPE_APPLICATION:
51 target.setType("application");
52 break;
53 case MAILMIME_DISCRETE_TYPE_EXTENSION:
54 default:
55 if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
56 target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
57 }
58 break;
59 }
60 if (type->ct_parameters) {
61 fillParameters(target,type->ct_parameters);
62 }
63 }
64 if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
65 for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
66 field = (mailmime_field*)current->data;
67 switch(field->fld_type) {
68 case MAILMIME_FIELD_TRANSFER_ENCODING:
69 target.setEncoding(getencoding(field->fld_data.fld_encoding));
70 break;
71 case MAILMIME_FIELD_ID:
72 target.setIdentifier(field->fld_data.fld_id);
73 break;
74 case MAILMIME_FIELD_DESCRIPTION:
75 target.setDescription(field->fld_data.fld_description);
76 break;
77 default:
78 break;
79 }
80 }
81 }
82}
83
84void Genericwrapper::fillParameters(RecPart&target,clist*parameters)
85{
86 if (!parameters) {return;}
87 clistcell*current=0;
88 mailmime_parameter*param;
89 for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
90 param = (mailmime_parameter*)current->data;
91 if (param) {
92 target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
93 }
94 }
95}
96
97QString Genericwrapper::getencoding(mailmime_mechanism*aEnc)
98{
99 QString enc="7bit";
100 if (!aEnc) return enc;
101 switch(aEnc->enc_type) {
102 case MAILMIME_MECHANISM_7BIT:
103 enc = "7bit";
104 break;
105 case MAILMIME_MECHANISM_8BIT:
106 enc = "8bit";
107 break;
108 case MAILMIME_MECHANISM_BINARY:
109 enc = "binary";
110 break;
111 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
112 enc = "quoted-printable";
113 break;
114 case MAILMIME_MECHANISM_BASE64:
115 enc = "base64";
116 break;
117 case MAILMIME_MECHANISM_TOKEN:
118 default:
119 if (aEnc->enc_token) {
120 enc = QString(aEnc->enc_token);
121 }
122 break;
123 }
124 return enc;
125}
126
127void Genericwrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec)
128{
129 if (current_rec >= 10) {
130 qDebug("too deep recursion!");
131 }
132 if (!message || !mime) {
133 return;
134 }
135 int r;
136 char*data = 0;
137 size_t len;
138 clistiter * cur = 0;
139 QString b;
140 RecPart part;
141
142 switch (mime->mm_type) {
143 case MAILMIME_SINGLE:
144 r = mailmessage_fetch_section(message,mime,&data,&len);
145 part.setSize(len);
146 fillSingleBody(part,message,mime);
147 if (part.Type()=="text" && target.Bodytext().isNull()) {
148 encodedString*r = new encodedString();
149 r->setContent(data,len);
150 encodedString*res = decode_String(r,part.Encoding());
151 b = QString(res->Content());
152 delete r;
153 delete res;
154 target.setBodytext(b);
155 target.setDescription(part);
156 } else {
157 b = gen_attachment_id();
158 part.setIdentifier(b);
159 bodyCache[b]=new encodedString(data,len);
160 target.addPart(part);
161 }
162 break;
163 case MAILMIME_MULTIPLE:
164 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
165 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1);
166 }
167 break;
168 case MAILMIME_MESSAGE:
169 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
170 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1);
171 }
172 break;
173 }
174}
175
176RecBody Genericwrapper::parseMail( mailmessage * msg )
177{
178 int err = MAILIMF_NO_ERROR;
179 mailmime_single_fields fields;
180 /* is bound to msg and will be freed there */
181 mailmime * mime=0;
182 RecBody body;
183 memset(&fields, 0, sizeof(struct mailmime_single_fields));
184 err = mailmessage_get_bodystructure(msg,&mime);
185 traverseBody(body,msg,mime);
186 return body;
187}
188
189RecMail *Genericwrapper::parseHeader( const char *header )
190{
191 int err = MAILIMF_NO_ERROR;
192 size_t curTok = 0;
193 RecMail *mail = new RecMail();
194 mailimf_fields *fields;
195 mailimf_references * refs;
196 mailimf_keywords*keys;
197 QString status;
198 QString value;
199 QBitArray mFlags(7);
200
201 err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
202 for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
203 mailimf_field *field = (mailimf_field *) current->data;
204 switch ( field->fld_type ) {
205 case MAILIMF_FIELD_FROM:
206 mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
207 break;
208 case MAILIMF_FIELD_TO:
209 mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
210 break;
211 case MAILIMF_FIELD_CC:
212 mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
213 break;
214 case MAILIMF_FIELD_BCC:
215 mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
216 break;
217 case MAILIMF_FIELD_SUBJECT:
218 mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
219 break;
220 case MAILIMF_FIELD_ORIG_DATE:
221 mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
222 break;
223 case MAILIMF_FIELD_MESSAGE_ID:
224 mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
225 break;
226 case MAILIMF_FIELD_REFERENCES:
227 refs = field->fld_data.fld_references;
228 if (refs && refs->mid_list && clist_count(refs->mid_list)) {
229 char * text = (char*)refs->mid_list->first->data;
230 mail->setReplyto(QString(text));
231 }
232 break;
233 case MAILIMF_FIELD_KEYWORDS:
234 keys = field->fld_data.fld_keywords;
235 for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
236 qDebug("Keyword: %s",(char*)cur->data);
237 }
238 break;
239 case MAILIMF_FIELD_OPTIONAL_FIELD:
240 status = field->fld_data.fld_optional_field->fld_name;
241 value = field->fld_data.fld_optional_field->fld_value;
242 if (status.lower()=="status") {
243 if (value.lower()=="ro") {
244 mFlags.setBit(FLAG_SEEN);
245 }
246 } else if (status.lower()=="x-status") {
247 qDebug("X-Status: %s",value.latin1());
248 if (value.lower()=="a") {
249 mFlags.setBit(FLAG_ANSWERED);
250 }
251 } else {
252// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
253// field->fld_data.fld_optional_field->fld_value);
254 }
255 break;
256 default:
257 qDebug("Non parsed field");
258 break;
259 }
260 }
261 if (fields) mailimf_fields_free(fields);
262 mail->setFlags(mFlags);
263 return mail;
264}
265
266QString Genericwrapper::parseDateTime( mailimf_date_time *date )
267{
268 char tmp[23];
269
270 snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
271 date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
272
273 return QString( tmp );
274}
275
276QString Genericwrapper::parseAddressList( mailimf_address_list *list )
277{
278 QString result( "" );
279
280 bool first = true;
281 if (list == 0) return result;
282 for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
283 mailimf_address *addr = (mailimf_address *) current->data;
284
285 if ( !first ) {
286 result.append( "," );
287 } else {
288 first = false;
289 }
290
291 switch ( addr->ad_type ) {
292 case MAILIMF_ADDRESS_MAILBOX:
293 result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
294 break;
295 case MAILIMF_ADDRESS_GROUP:
296 result.append( parseGroup( addr->ad_data.ad_group ) );
297 break;
298 default:
299 qDebug( "Generic: unkown mailimf address type" );
300 break;
301 }
302 }
303
304 return result;
305}
306
307QString Genericwrapper::parseGroup( mailimf_group *group )
308{
309 QString result( "" );
310
311 result.append( group->grp_display_name );
312 result.append( ": " );
313
314 if ( group->grp_mb_list != NULL ) {
315 result.append( parseMailboxList( group->grp_mb_list ) );
316 }
317
318 result.append( ";" );
319
320 return result;
321}
322
323QString Genericwrapper::parseMailbox( mailimf_mailbox *box )
324{
325 QString result( "" );
326
327 if ( box->mb_display_name == NULL ) {
328 result.append( box->mb_addr_spec );
329 } else {
330 result.append( convert_String(box->mb_display_name).latin1() );
331 result.append( " <" );
332 result.append( box->mb_addr_spec );
333 result.append( ">" );
334 }
335
336 return result;
337}
338
339QString Genericwrapper::parseMailboxList( mailimf_mailbox_list *list )
340{
341 QString result( "" );
342
343 bool first = true;
344 for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
345 mailimf_mailbox *box = (mailimf_mailbox *) current->data;
346
347 if ( !first ) {
348 result.append( "," );
349 } else {
350 first = false;
351 }
352
353 result.append( parseMailbox( box ) );
354 }
355
356 return result;
357}
358
359encodedString* Genericwrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
360{
361 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
362 if (it==bodyCache.end()) return new encodedString();
363 encodedString*t = decode_String(it.data(),part.Encoding());
364 return t;
365}
366
367encodedString* Genericwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
368{
369 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
370 if (it==bodyCache.end()) return new encodedString();
371 encodedString*t = it.data();
372 return t;
373}
374
375QString Genericwrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
376{
377 encodedString*t = fetchDecodedPart(mail,part);
378 QString text=t->Content();
379 delete t;
380 return text;
381}
382
383void Genericwrapper::cleanMimeCache()
384{
385 QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
386 for (;it!=bodyCache.end();++it) {
387 encodedString*t = it.data();
388 //it.setValue(0);
389 if (t) delete t;
390 }
391 bodyCache.clear();
392 qDebug("Genericwrapper: cache cleaned");
393}
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 @@
1#ifndef __GENERIC_WRAPPER_H
2#define __GENERIC_WRAPPER_H
3
4#include "abstractmail.h"
5#include <qmap.h>
6#include <qstring.h>
7#include <libetpan/clist.h>
8
9class RecMail;
10class RecBody;
11class encodedString;
12struct mailpop3;
13struct mailmessage;
14struct mailmime;
15struct mailmime_mechanism;
16struct mailimf_mailbox_list;
17struct mailimf_mailbox;
18struct mailimf_date_time;
19struct mailimf_group;
20struct mailimf_address_list;
21
22/* this class hold just the funs shared between
23 * mbox and pop3 (later mh, too) mail access.
24 * it is not desigend to make a instance of it!
25 */
26class Genericwrapper : public AbstractMail
27{
28 Q_OBJECT
29public:
30 Genericwrapper();
31 virtual ~Genericwrapper();
32
33 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
34 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
35 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
36 virtual void cleanMimeCache();
37
38protected:
39 RecMail *parseHeader( const char *header );
40 RecBody parseMail( mailmessage * msg );
41 QString parseMailboxList( mailimf_mailbox_list *list );
42 QString parseMailbox( mailimf_mailbox *box );
43 QString parseGroup( mailimf_group *group );
44 QString parseAddressList( mailimf_address_list *list );
45 QString parseDateTime( mailimf_date_time *date );
46
47 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
48 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
49 static void fillParameters(RecPart&target,clist*parameters);
50 static QString getencoding(mailmime_mechanism*aEnc);
51
52 POP3account *account;
53 mailpop3 *m_pop3;
54 QString msgTempName;
55 unsigned int last_msg_id;
56 QMap<QString,encodedString*> bodyCache;
57};
58
59#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 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include "pop3wrapper.h" 2#include "pop3wrapper.h"
3#include "mailtypes.h" 3#include "mailtypes.h"
4#include "logindialog.h" 4#include "logindialog.h"
5#include <libetpan/mailpop3.h> 5#include <libetpan/mailpop3.h>
6#include <libetpan/mailmime.h> 6#include <libetpan/mailmime.h>
7#include <libetpan/data_message_driver.h> 7#include <libetpan/data_message_driver.h>
8#include <qfile.h> 8#include <qfile.h>
9 9
10/* we don't fetch messages larger than 5 MB */ 10/* we don't fetch messages larger than 5 MB */
11#define HARD_MSG_SIZE_LIMIT 5242880 11#define HARD_MSG_SIZE_LIMIT 5242880
12 12
13POP3wrapper::POP3wrapper( POP3account *a ) 13POP3wrapper::POP3wrapper( POP3account *a )
14 : Genericwrapper()
14{ 15{
15 account = a; 16 account = a;
16 m_pop3 = NULL; 17 m_pop3 = NULL;
17 msgTempName = a->getFileName()+"_msg_cache"; 18 msgTempName = a->getFileName()+"_msg_cache";
18 last_msg_id = 0; 19 last_msg_id = 0;
19 bodyCache.clear();
20} 20}
21 21
22POP3wrapper::~POP3wrapper() 22POP3wrapper::~POP3wrapper()
23{ 23{
24 logout(); 24 logout();
25 QFile msg_cache(msgTempName); 25 QFile msg_cache(msgTempName);
26 if (msg_cache.exists()) { 26 if (msg_cache.exists()) {
27 msg_cache.remove(); 27 msg_cache.remove();
28 } 28 }
29 cleanUpCache();
30}
31
32void POP3wrapper::cleanUpCache()
33{
34 QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
35 for (;it!=bodyCache.end();++it) {
36 encodedString*t = it.data();
37 //it.setValue(0);
38 if (t) delete t;
39 }
40 bodyCache.clear();
41} 29}
42 30
43void POP3wrapper::pop3_progress( size_t current, size_t maximum ) 31void POP3wrapper::pop3_progress( size_t current, size_t maximum )
44{ 32{
45 //qDebug( "POP3: %i of %i", current, maximum ); 33 //qDebug( "POP3: %i of %i", current, maximum );
46} 34}
47 35
48RecBody POP3wrapper::fetchBody( const RecMail &mail ) 36RecBody POP3wrapper::fetchBody( const RecMail &mail )
49{ 37{
50 int err = MAILPOP3_NO_ERROR; 38 int err = MAILPOP3_NO_ERROR;
51 char *message; 39 char *message;
52 size_t length = 0; 40 size_t length = 0;
53 41
54 login(); 42 login();
55 if ( !m_pop3 ) { 43 if ( !m_pop3 ) {
56 return RecBody(); 44 return RecBody();
57 } 45 }
58 46
59 RecBody body; 47 RecBody body;
60 48 mailmessage * msg = 0;
49
61 QFile msg_cache(msgTempName); 50 QFile msg_cache(msgTempName);
62 51
63 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) { 52 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) {
64 qDebug("Message to large: %i",mail.Msgsize()); 53 qDebug("Message to large: %i",mail.Msgsize());
65 return body; 54 return body;
66 } 55 }
67 cleanUpCache(); 56 cleanMimeCache();
68 if (mail.getNumber()!=last_msg_id) { 57 if (mail.getNumber()!=last_msg_id) {
69 if (msg_cache.exists()) { 58 if (msg_cache.exists()) {
70 msg_cache.remove(); 59 msg_cache.remove();
71 } 60 }
72 msg_cache.open(IO_ReadWrite|IO_Truncate); 61 msg_cache.open(IO_ReadWrite|IO_Truncate);
73 last_msg_id = mail.getNumber(); 62 last_msg_id = mail.getNumber();
74 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length ); 63 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length );
75 if ( err != MAILPOP3_NO_ERROR ) { 64 if ( err != MAILPOP3_NO_ERROR ) {
76 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() ); 65 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() );
77 last_msg_id = 0; 66 last_msg_id = 0;
78 return RecBody(); 67 return RecBody();
79 } 68 }
80 msg_cache.writeBlock(message,length); 69 msg_cache.writeBlock(message,length);
81 } else { 70 } else {
82 QString msg=""; 71 QString msg="";
83 msg_cache.open(IO_ReadOnly); 72 msg_cache.open(IO_ReadOnly);
84 message = new char[4096]; 73 message = new char[4096];
85 memset(message,0,4096); 74 memset(message,0,4096);
86 while (msg_cache.readBlock(message,4095)>0) { 75 while (msg_cache.readBlock(message,4095)>0) {
87 msg+=message; 76 msg+=message;
88 memset(message,0,4096); 77 memset(message,0,4096);
89 } 78 }
90 delete message; 79 delete message;
91 message = (char*)malloc(msg.length()+1*sizeof(char)); 80 message = (char*)malloc(msg.length()+1*sizeof(char));
92 memset(message,0,msg.length()+1); 81 memset(message,0,msg.length()+1);
93 memcpy(message,msg.latin1(),msg.length()); 82 memcpy(message,msg.latin1(),msg.length());
94 } 83 }
95 body = parseMail(message);
96 free(message);
97 return body;
98}
99
100RecBody POP3wrapper::parseMail( char *message )
101{
102 int err = MAILIMF_NO_ERROR;
103 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */
104 size_t curTok = 0;
105 mailimf_message *result = 0;
106 mailmessage * msg=0;
107 mailmime_single_fields fields;
108 84
109 /* is bound to msg and will be freed there */ 85 /* transform to libetpan stuff */
110 struct mailmime * mime=0;
111
112 RecBody body;
113
114
115 err = mailimf_message_parse( (char *) message, strlen( message ), &curTok, &result );
116 if ( err != MAILIMF_NO_ERROR ) {
117 if (result) mailimf_message_free(result);
118 return body;
119 }
120
121 char*body_msg = message;
122 msg = mailmessage_new(); 86 msg = mailmessage_new();
123 mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg)); 87 mailmessage_init(msg, NULL, data_message_driver, 0, strlen(message));
124 generic_message_t * msg_data; 88 generic_message_t * msg_data;
125 msg_data = (generic_message_t *)msg->msg_data; 89 msg_data = (generic_message_t *)msg->msg_data;
126 msg_data->msg_fetched = 1; 90 msg_data->msg_fetched = 1;
127 msg_data->msg_message = body_msg; 91 msg_data->msg_message = message;
128 msg_data->msg_length = strlen(body_msg); 92 msg_data->msg_length = strlen(message);
129 93
94 /* parse the mail */
95 body = parseMail(msg);
130 96
131 memset(&fields, 0, sizeof(struct mailmime_single_fields)); 97 /* clean up */
132 err = mailmessage_get_bodystructure(msg,&mime); 98 mailmessage_free(msg);
133 traverseBody(body,msg,mime); 99 free(message);
134
135 mailmessage_free(msg);
136 100
101 /* finish */
137 return body; 102 return body;
138} 103}
139 104
140void POP3wrapper::listMessages(const QString &, QList<RecMail> &target ) 105void POP3wrapper::listMessages(const QString &, QList<RecMail> &target )
141{ 106{
142 int err = MAILPOP3_NO_ERROR; 107 int err = MAILPOP3_NO_ERROR;
143 char * header = 0; 108 char * header = 0;
144 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ 109 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */
145 size_t length = 0; 110 size_t length = 0;
146 carray * messages = 0; 111 carray * messages = 0;
147 112
148 login(); 113 login();
149 if (!m_pop3) return; 114 if (!m_pop3) return;
150 mailpop3_list( m_pop3, &messages ); 115 mailpop3_list( m_pop3, &messages );
151 116
152 for (unsigned int i = 0; i < carray_count(messages);++i) { 117 for (unsigned int i = 0; i < carray_count(messages);++i) {
153 mailpop3_msg_info *info; 118 mailpop3_msg_info *info;
154 err = mailpop3_get_msg_info(m_pop3,i+1,&info); 119 err = mailpop3_get_msg_info(m_pop3,i+1,&info);
155 if (info->msg_deleted) 120 if (info->msg_deleted)
156 continue; 121 continue;
157 err = mailpop3_header( m_pop3, info->msg_index, &header, &length ); 122 err = mailpop3_header( m_pop3, info->msg_index, &header, &length );
158 if ( err != MAILPOP3_NO_ERROR ) { 123 if ( err != MAILPOP3_NO_ERROR ) {
159 qDebug( "POP3: error retrieving header msgid: %i", info->msg_index ); 124 qDebug( "POP3: error retrieving header msgid: %i", info->msg_index );
160 free(header); 125 free(header);
161 return; 126 return;
162 } 127 }
163 RecMail *mail = parseHeader( header ); 128 RecMail *mail = parseHeader( header );
164 mail->setNumber( info->msg_index ); 129 mail->setNumber( info->msg_index );
165 mail->setWrapper(this); 130 mail->setWrapper(this);
166 mail->setMsgsize(info->msg_size); 131 mail->setMsgsize(info->msg_size);
167 target.append( mail ); 132 target.append( mail );
168 free(header); 133 free(header);
169 } 134 }
170} 135}
171 136
172RecMail *POP3wrapper::parseHeader( const char *header )
173{
174 int err = MAILIMF_NO_ERROR;
175 size_t curTok = 0;
176 RecMail *mail = new RecMail();
177 mailimf_fields *fields;
178 mailimf_references * refs;
179 mailimf_keywords*keys;
180 QString status;
181 QString value;
182 QBitArray mFlags(7);
183
184 err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
185 for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
186 mailimf_field *field = (mailimf_field *) current->data;
187 switch ( field->fld_type ) {
188 case MAILIMF_FIELD_FROM:
189 mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
190 break;
191 case MAILIMF_FIELD_TO:
192 mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
193 break;
194 case MAILIMF_FIELD_CC:
195 mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
196 break;
197 case MAILIMF_FIELD_BCC:
198 mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
199 break;
200 case MAILIMF_FIELD_SUBJECT:
201 mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
202 break;
203 case MAILIMF_FIELD_ORIG_DATE:
204 mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
205 break;
206 case MAILIMF_FIELD_MESSAGE_ID:
207 mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
208 break;
209 case MAILIMF_FIELD_REFERENCES:
210 refs = field->fld_data.fld_references;
211 if (refs && refs->mid_list && clist_count(refs->mid_list)) {
212 char * text = (char*)refs->mid_list->first->data;
213 mail->setReplyto(QString(text));
214 }
215 break;
216 case MAILIMF_FIELD_KEYWORDS:
217 keys = field->fld_data.fld_keywords;
218 for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
219 qDebug("Keyword: %s",(char*)cur->data);
220 }
221 break;
222 case MAILIMF_FIELD_OPTIONAL_FIELD:
223 status = field->fld_data.fld_optional_field->fld_name;
224 value = field->fld_data.fld_optional_field->fld_value;
225 if (status.lower()=="status") {
226 if (value.lower()=="ro") {
227 mFlags.setBit(FLAG_SEEN);
228 }
229 } else if (status.lower()=="x-status") {
230 qDebug("X-Status: %s",value.latin1());
231 if (value.lower()=="a") {
232 mFlags.setBit(FLAG_ANSWERED);
233 }
234 } else {
235// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
236// field->fld_data.fld_optional_field->fld_value);
237 }
238 break;
239 default:
240 qDebug("Non parsed field");
241 break;
242 }
243 }
244 if (fields) mailimf_fields_free(fields);
245 mail->setFlags(mFlags);
246 return mail;
247}
248
249QString POP3wrapper::parseDateTime( mailimf_date_time *date )
250{
251 char tmp[23];
252
253 snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
254 date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
255
256 return QString( tmp );
257}
258
259QString POP3wrapper::parseAddressList( mailimf_address_list *list )
260{
261 QString result( "" );
262
263 bool first = true;
264 for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
265 mailimf_address *addr = (mailimf_address *) current->data;
266
267 if ( !first ) {
268 result.append( "," );
269 } else {
270 first = false;
271 }
272
273 switch ( addr->ad_type ) {
274 case MAILIMF_ADDRESS_MAILBOX:
275 result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
276 break;
277 case MAILIMF_ADDRESS_GROUP:
278 result.append( parseGroup( addr->ad_data.ad_group ) );
279 break;
280 default:
281 qDebug( "POP3: unkown mailimf address type" );
282 break;
283 }
284 }
285
286 return result;
287}
288
289QString POP3wrapper::parseGroup( mailimf_group *group )
290{
291 QString result( "" );
292
293 result.append( group->grp_display_name );
294 result.append( ": " );
295
296 if ( group->grp_mb_list != NULL ) {
297 result.append( parseMailboxList( group->grp_mb_list ) );
298 }
299
300 result.append( ";" );
301
302 return result;
303}
304
305QString POP3wrapper::parseMailbox( mailimf_mailbox *box )
306{
307 QString result( "" );
308
309 if ( box->mb_display_name == NULL ) {
310 result.append( box->mb_addr_spec );
311 } else {
312 result.append( convert_String(box->mb_display_name).latin1() );
313 result.append( " <" );
314 result.append( box->mb_addr_spec );
315 result.append( ">" );
316 }
317
318 return result;
319}
320
321QString POP3wrapper::parseMailboxList( mailimf_mailbox_list *list )
322{
323 QString result( "" );
324
325 bool first = true;
326 for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
327 mailimf_mailbox *box = (mailimf_mailbox *) current->data;
328
329 if ( !first ) {
330 result.append( "," );
331 } else {
332 first = false;
333 }
334
335 result.append( parseMailbox( box ) );
336 }
337
338 return result;
339}
340
341void POP3wrapper::login() 137void POP3wrapper::login()
342{ 138{
343 /* we'll hold the line */ 139 /* we'll hold the line */
344 if ( m_pop3 != NULL ) return; 140 if ( m_pop3 != NULL ) return;
345 141
346 const char *server, *user, *pass; 142 const char *server, *user, *pass;
347 uint16_t port; 143 uint16_t port;
348 int err = MAILPOP3_NO_ERROR; 144 int err = MAILPOP3_NO_ERROR;
349 145
350 server = account->getServer().latin1(); 146 server = account->getServer().latin1();
351 port = account->getPort().toUInt(); 147 port = account->getPort().toUInt();
352 148
353 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { 149 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
354 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); 150 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
355 login.show(); 151 login.show();
356 if ( QDialog::Accepted == login.exec() ) { 152 if ( QDialog::Accepted == login.exec() ) {
357 // ok 153 // ok
358 user = strdup( login.getUser().latin1() ); 154 user = strdup( login.getUser().latin1() );
359 pass = strdup( login.getPassword().latin1() ); 155 pass = strdup( login.getPassword().latin1() );
360 } else { 156 } else {
361 // cancel 157 // cancel
362 qDebug( "POP3: Login canceled" ); 158 qDebug( "POP3: Login canceled" );
363 return; 159 return;
364 } 160 }
365 } else { 161 } else {
366 user = account->getUser().latin1(); 162 user = account->getUser().latin1();
367 pass = account->getPassword().latin1(); 163 pass = account->getPassword().latin1();
368 } 164 }
369 165
370 m_pop3 = mailpop3_new( 200, &pop3_progress ); 166 m_pop3 = mailpop3_new( 200, &pop3_progress );
371 167
372 // connect 168 // connect
373 if (account->getSSL()) { 169 if (account->getSSL()) {
374 err = mailpop3_ssl_connect( m_pop3, (char*)server, port ); 170 err = mailpop3_ssl_connect( m_pop3, (char*)server, port );
375 } else { 171 } else {
376 err = mailpop3_socket_connect( m_pop3, (char*)server, port ); 172 err = mailpop3_socket_connect( m_pop3, (char*)server, port );
377 } 173 }
378 174
379 if ( err != MAILPOP3_NO_ERROR ) { 175 if ( err != MAILPOP3_NO_ERROR ) {
380 qDebug( "pop3: error connecting to %s\n reason: %s", server, 176 qDebug( "pop3: error connecting to %s\n reason: %s", server,
381 m_pop3->pop3_response ); 177 m_pop3->pop3_response );
382 mailpop3_free( m_pop3 ); 178 mailpop3_free( m_pop3 );
383 m_pop3 = NULL; 179 m_pop3 = NULL;
384 return; 180 return;
385 } 181 }
386 qDebug( "POP3: connected!" ); 182 qDebug( "POP3: connected!" );
387 183
388 // login 184 // login
389 // TODO: decide if apop or plain login should be used 185 // TODO: decide if apop or plain login should be used
390 err = mailpop3_login( m_pop3, (char *) user, (char *) pass ); 186 err = mailpop3_login( m_pop3, (char *) user, (char *) pass );
391 if ( err != MAILPOP3_NO_ERROR ) { 187 if ( err != MAILPOP3_NO_ERROR ) {
392 qDebug( "pop3: error logging in: %s", m_pop3->pop3_response ); 188 qDebug( "pop3: error logging in: %s", m_pop3->pop3_response );
393 logout(); 189 logout();
394 return; 190 return;
395 } 191 }
396 192
397 qDebug( "POP3: logged in!" ); 193 qDebug( "POP3: logged in!" );
398} 194}
399 195
400void POP3wrapper::logout() 196void POP3wrapper::logout()
401{ 197{
402 int err = MAILPOP3_NO_ERROR; 198 int err = MAILPOP3_NO_ERROR;
403 if ( m_pop3 == NULL ) return; 199 if ( m_pop3 == NULL ) return;
404 err = mailpop3_quit( m_pop3 ); 200 err = mailpop3_quit( m_pop3 );
405 mailpop3_free( m_pop3 ); 201 mailpop3_free( m_pop3 );
406 m_pop3 = NULL; 202 m_pop3 = NULL;
407} 203}
408 204
409 205
410QList<Folder>* POP3wrapper::listFolders() 206QList<Folder>* POP3wrapper::listFolders()
411{ 207{
412 /* TODO: integrate MH directories 208 /* TODO: integrate MH directories
413 but not before version 0.1 ;) 209 but not before version 0.1 ;)
414 */ 210 */
415 QList<Folder> * folders = new QList<Folder>(); 211 QList<Folder> * folders = new QList<Folder>();
416 folders->setAutoDelete( false ); 212 folders->setAutoDelete( false );
417 Folder*inb=new Folder("INBOX","/"); 213 Folder*inb=new Folder("INBOX","/");
418 folders->append(inb); 214 folders->append(inb);
419 return folders; 215 return folders;
420} 216}
421 217
422QString POP3wrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
423{
424 encodedString*t = fetchDecodedPart(mail,part);
425 QString text=t->Content();
426 delete t;
427 return text;
428}
429
430void POP3wrapper::deleteMail(const RecMail&mail) 218void POP3wrapper::deleteMail(const RecMail&mail)
431{ 219{
432 login(); 220 login();
433 if (!m_pop3) return; 221 if (!m_pop3) return;
434 int err = mailpop3_dele(m_pop3,mail.getNumber()); 222 int err = mailpop3_dele(m_pop3,mail.getNumber());
435 if (err != MAILPOP3_NO_ERROR) { 223 if (err != MAILPOP3_NO_ERROR) {
436 qDebug("error deleting mail"); 224 qDebug("error deleting mail");
437 } 225 }
438} 226}
439 227
440void POP3wrapper::answeredMail(const RecMail&) 228void POP3wrapper::answeredMail(const RecMail&)
441{ 229{
442} 230}
443
444encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
445{
446 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
447 if (it==bodyCache.end()) return new encodedString();
448 encodedString*t = decode_String(it.data(),part.Encoding());
449 return t;
450}
451
452encodedString* POP3wrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
453{
454 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
455 if (it==bodyCache.end()) return new encodedString();
456 encodedString*t = it.data();
457 return t;
458}
459
460void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec)
461{
462 if (current_rec >= 10) {
463 qDebug("too deep recursion!");
464 }
465 if (!message || !mime) {
466 return;
467 }
468 int r;
469 char*data = 0;
470 size_t len;
471 clistiter * cur = 0;
472 int res;
473 QString b;
474 RecPart part;
475
476 switch (mime->mm_type) {
477 case MAILMIME_SINGLE:
478 r = mailmessage_fetch_section(message,mime,&data,&len);
479 part.setSize(len);
480 fillSingleBody(part,message,mime);
481 if (part.Type()=="text" && target.Bodytext().isNull()) {
482 encodedString*r = new encodedString();
483 r->setContent(data,len);
484 encodedString*res = decode_String(r,part.Encoding());
485 b = QString(res->Content());
486 delete r;
487 delete res;
488 target.setBodytext(b);
489 target.setDescription(part);
490 } else {
491 b = gen_attachment_id();
492 part.setIdentifier(b);
493 bodyCache[b]=new encodedString(data,len);
494 target.addPart(part);
495 }
496 break;
497 case MAILMIME_MULTIPLE:
498 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
499 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1);
500 }
501 break;
502 case MAILMIME_MESSAGE:
503 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
504 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1);
505 }
506 break;
507 }
508}
509
510QString POP3wrapper::getencoding(mailmime_mechanism*aEnc)
511{
512 QString enc="7bit";
513 if (!aEnc) return enc;
514 switch(aEnc->enc_type) {
515 case MAILMIME_MECHANISM_7BIT:
516 enc = "7bit";
517 break;
518 case MAILMIME_MECHANISM_8BIT:
519 enc = "8bit";
520 break;
521 case MAILMIME_MECHANISM_BINARY:
522 enc = "binary";
523 break;
524 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
525 enc = "quoted-printable";
526 break;
527 case MAILMIME_MECHANISM_BASE64:
528 enc = "base64";
529 break;
530 case MAILMIME_MECHANISM_TOKEN:
531 default:
532 if (aEnc->enc_token) {
533 enc = QString(aEnc->enc_token);
534 }
535 break;
536 }
537 return enc;
538}
539
540void POP3wrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
541{
542 if (!mime) {
543 return;
544 }
545 mailmime_field*field = 0;
546 mailmime_single_fields fields;
547 memset(&fields, 0, sizeof(struct mailmime_single_fields));
548 if (mime->mm_mime_fields != NULL) {
549 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
550 mime->mm_content_type);
551 }
552
553 mailmime_content*type = fields.fld_content;
554 clistcell*current;
555 if (!type) {
556 target.setType("text");
557 target.setSubtype("plain");
558 } else {
559 target.setSubtype(type->ct_subtype);
560 switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
561 case MAILMIME_DISCRETE_TYPE_TEXT:
562 target.setType("text");
563 break;
564 case MAILMIME_DISCRETE_TYPE_IMAGE:
565 target.setType("image");
566 break;
567 case MAILMIME_DISCRETE_TYPE_AUDIO:
568 target.setType("audio");
569 break;
570 case MAILMIME_DISCRETE_TYPE_VIDEO:
571 target.setType("video");
572 break;
573 case MAILMIME_DISCRETE_TYPE_APPLICATION:
574 target.setType("application");
575 break;
576 case MAILMIME_DISCRETE_TYPE_EXTENSION:
577 default:
578 if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
579 target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
580 }
581 break;
582 }
583 if (type->ct_parameters) {
584 fillParameters(target,type->ct_parameters);
585 }
586 }
587 if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
588 for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
589 field = (mailmime_field*)current->data;
590 switch(field->fld_type) {
591 case MAILMIME_FIELD_TRANSFER_ENCODING:
592 target.setEncoding(getencoding(field->fld_data.fld_encoding));
593 break;
594 case MAILMIME_FIELD_ID:
595 target.setIdentifier(field->fld_data.fld_id);
596 break;
597 case MAILMIME_FIELD_DESCRIPTION:
598 target.setDescription(field->fld_data.fld_description);
599 break;
600 default:
601 break;
602 }
603 }
604 }
605}
606
607void POP3wrapper::fillParameters(RecPart&target,clist*parameters)
608{
609 if (!parameters) {return;}
610 clistcell*current=0;
611 mailmime_parameter*param;
612 for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
613 param = (mailmime_parameter*)current->data;
614 if (param) {
615 target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
616 }
617 }
618}
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 @@
1#ifndef __POP3WRAPPER 1#ifndef __POP3WRAPPER
2#define __POP3WRAPPER 2#define __POP3WRAPPER
3 3
4#include <libetpan/clist.h>
5#include "mailwrapper.h" 4#include "mailwrapper.h"
6#include "abstractmail.h" 5#include "genericwrapper.h"
7#include <qmap.h>
8#include <qstring.h> 6#include <qstring.h>
9 7
10class RecMail;
11class RecBody;
12class encodedString;
13struct mailpop3;
14struct mailmessage;
15struct mailmime;
16struct mailmime_mechanism;
17struct mailimf_mailbox_list;
18struct mailimf_mailbox;
19struct mailimf_date_time;
20struct mailimf_group;
21struct mailimf_address_list;
22 8
23class POP3wrapper : public AbstractMail 9class POP3wrapper : public Genericwrapper
24{ 10{
25 Q_OBJECT 11 Q_OBJECT
26 12
27public: 13public:
28 POP3wrapper( POP3account *a ); 14 POP3wrapper( POP3account *a );
29 virtual ~POP3wrapper(); 15 virtual ~POP3wrapper();
30 /* mailbox will be ignored */ 16 /* mailbox will be ignored */
31 virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); 17 virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
32 virtual QList<Folder>* listFolders(); 18 virtual QList<Folder>* listFolders();
33 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
34 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
35 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
36 19
37 virtual void deleteMail(const RecMail&mail); 20 virtual void deleteMail(const RecMail&mail);
38 virtual void answeredMail(const RecMail&mail); 21 virtual void answeredMail(const RecMail&mail);
39 22
40 RecBody fetchBody( const RecMail &mail ); 23 virtual RecBody fetchBody( const RecMail &mail );
41 static void pop3_progress( size_t current, size_t maximum ); 24 static void pop3_progress( size_t current, size_t maximum );
42 25
43protected: 26protected:
44 void login(); 27 void login();
45 void logout(); 28 void logout();
46 29
47 RecMail *parseHeader( const char *header );
48 RecBody parseMail( char *message );
49 QString parseMailboxList( mailimf_mailbox_list *list );
50 QString parseMailbox( mailimf_mailbox *box );
51 QString parseGroup( mailimf_group *group );
52 QString parseAddressList( mailimf_address_list *list );
53 QString parseDateTime( mailimf_date_time *date );
54
55 void cleanUpCache();
56
57 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
58 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
59 static void fillParameters(RecPart&target,clist*parameters);
60 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
61
62 POP3account *account;
63 mailpop3 *m_pop3;
64 QString msgTempName;
65 unsigned int last_msg_id;
66 QMap<QString,encodedString*> bodyCache;
67}; 30};
68 31
69#endif 32#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 @@
1 CONFIG += qt warn_on debug quick-app 1CONFIG += qt warn_on debug quick-app
2 2
3 HEADERS = defines.h \ 3HEADERS = defines.h \
4 logindialog.h \ 4 logindialog.h \
5 settings.h \ 5 settings.h \
6 editaccounts.h \ 6 editaccounts.h \
7 mailwrapper.h \ 7 mailwrapper.h \
8 composemail.h \ 8 composemail.h \
9 accountview.h \ 9 accountview.h \
10 mainwindow.h \ 10 mainwindow.h \
11 viewmail.h \ 11 viewmail.h \
12 viewmailbase.h \ 12 viewmailbase.h \
13 opiemail.h \ 13 opiemail.h \
14 imapwrapper.h \ 14 imapwrapper.h \
15 mailtypes.h \ 15 mailtypes.h \
16 mailistviewitem.h \ 16 mailistviewitem.h \
17 pop3wrapper.h \ 17 pop3wrapper.h \
18 abstractmail.h \ 18 abstractmail.h \
19 settingsdialog.h \ 19 settingsdialog.h \
20 statuswidget.h \ 20 statuswidget.h \
21 smtpwrapper.h 21 smtpwrapper.h \
22 genericwrapper.h \
23 mboxwrapper.h
22 24
23 SOURCES = main.cpp \ 25SOURCES = main.cpp \
24 opiemail.cpp \ 26 opiemail.cpp \
25 mainwindow.cpp \ 27 mainwindow.cpp \
26 accountview.cpp \ 28 accountview.cpp \
27 composemail.cpp \ 29 composemail.cpp \
28 mailwrapper.cpp \ 30 mailwrapper.cpp \
29 imapwrapper.cpp \ 31 imapwrapper.cpp \
30 addresspicker.cpp \ 32 addresspicker.cpp \
31 editaccounts.cpp \ 33 editaccounts.cpp \
32 logindialog.cpp \ 34 logindialog.cpp \
33 viewmail.cpp \ 35 viewmail.cpp \
34 viewmailbase.cpp \ 36 viewmailbase.cpp \
35 settings.cpp \ 37 settings.cpp \
36 mailtypes.cpp \ 38 mailtypes.cpp \
37 pop3wrapper.cpp \ 39 pop3wrapper.cpp \
38 abstractmail.cpp \ 40 abstractmail.cpp \
39 settingsdialog.cpp \ 41 settingsdialog.cpp \
40 statuswidget.cpp \ 42 statuswidget.cpp \
41 smtpwrapper.cpp 43 smtpwrapper.cpp \
44 genericwrapper.cpp \
45 mboxwrapper.cpp
42 46
43 INTERFACES = editaccountsui.ui \ 47INTERFACES = editaccountsui.ui \
44 selectmailtypeui.ui \ 48 selectmailtypeui.ui \
45 imapconfigui.ui \ 49 imapconfigui.ui \
46 pop3configui.ui \ 50 pop3configui.ui \
47 nntpconfigui.ui \ 51 nntpconfigui.ui \
48 smtpconfigui.ui \ 52 smtpconfigui.ui \
49 addresspickerui.ui \ 53 addresspickerui.ui \
50 logindialogui.ui \ 54 logindialogui.ui \
51 composemailui.ui \ 55 composemailui.ui \
52 settingsdialogui.ui \ 56 settingsdialogui.ui \
53 statuswidgetui.ui 57 statuswidgetui.ui
54 58
55INCLUDEPATH += $(OPIEDIR)/include 59INCLUDEPATH += $(OPIEDIR)/include
56 60
57CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX ) 61CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX )
58contains( CONFTEST, y ){ 62contains( CONFTEST, y ){
59 LIBS += -lqpe -letpan -lssl -lcrypto -lopie -liconv 63 LIBS += -lqpe -letpan -lssl -lcrypto -lopie -liconv
60}else{ 64}else{
61 LIBS += -lqpe -letpan -lssl -lcrypto -lopie 65 LIBS += -lqpe -letpan -lssl -lcrypto -lopie
62} 66}
63 67
64TARGET = opiemail 68TARGET = opiemail
65 69
66include ( $(OPIEDIR)/include.pro ) 70include ( $(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 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include "pop3wrapper.h" 2#include "pop3wrapper.h"
3#include "mailtypes.h" 3#include "mailtypes.h"
4#include "logindialog.h" 4#include "logindialog.h"
5#include <libetpan/mailpop3.h> 5#include <libetpan/mailpop3.h>
6#include <libetpan/mailmime.h> 6#include <libetpan/mailmime.h>
7#include <libetpan/data_message_driver.h> 7#include <libetpan/data_message_driver.h>
8#include <qfile.h> 8#include <qfile.h>
9 9
10/* we don't fetch messages larger than 5 MB */ 10/* we don't fetch messages larger than 5 MB */
11#define HARD_MSG_SIZE_LIMIT 5242880 11#define HARD_MSG_SIZE_LIMIT 5242880
12 12
13POP3wrapper::POP3wrapper( POP3account *a ) 13POP3wrapper::POP3wrapper( POP3account *a )
14 : Genericwrapper()
14{ 15{
15 account = a; 16 account = a;
16 m_pop3 = NULL; 17 m_pop3 = NULL;
17 msgTempName = a->getFileName()+"_msg_cache"; 18 msgTempName = a->getFileName()+"_msg_cache";
18 last_msg_id = 0; 19 last_msg_id = 0;
19 bodyCache.clear();
20} 20}
21 21
22POP3wrapper::~POP3wrapper() 22POP3wrapper::~POP3wrapper()
23{ 23{
24 logout(); 24 logout();
25 QFile msg_cache(msgTempName); 25 QFile msg_cache(msgTempName);
26 if (msg_cache.exists()) { 26 if (msg_cache.exists()) {
27 msg_cache.remove(); 27 msg_cache.remove();
28 } 28 }
29 cleanUpCache();
30}
31
32void POP3wrapper::cleanUpCache()
33{
34 QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
35 for (;it!=bodyCache.end();++it) {
36 encodedString*t = it.data();
37 //it.setValue(0);
38 if (t) delete t;
39 }
40 bodyCache.clear();
41} 29}
42 30
43void POP3wrapper::pop3_progress( size_t current, size_t maximum ) 31void POP3wrapper::pop3_progress( size_t current, size_t maximum )
44{ 32{
45 //qDebug( "POP3: %i of %i", current, maximum ); 33 //qDebug( "POP3: %i of %i", current, maximum );
46} 34}
47 35
48RecBody POP3wrapper::fetchBody( const RecMail &mail ) 36RecBody POP3wrapper::fetchBody( const RecMail &mail )
49{ 37{
50 int err = MAILPOP3_NO_ERROR; 38 int err = MAILPOP3_NO_ERROR;
51 char *message; 39 char *message;
52 size_t length = 0; 40 size_t length = 0;
53 41
54 login(); 42 login();
55 if ( !m_pop3 ) { 43 if ( !m_pop3 ) {
56 return RecBody(); 44 return RecBody();
57 } 45 }
58 46
59 RecBody body; 47 RecBody body;
60 48 mailmessage * msg = 0;
49
61 QFile msg_cache(msgTempName); 50 QFile msg_cache(msgTempName);
62 51
63 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) { 52 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) {
64 qDebug("Message to large: %i",mail.Msgsize()); 53 qDebug("Message to large: %i",mail.Msgsize());
65 return body; 54 return body;
66 } 55 }
67 cleanUpCache(); 56 cleanMimeCache();
68 if (mail.getNumber()!=last_msg_id) { 57 if (mail.getNumber()!=last_msg_id) {
69 if (msg_cache.exists()) { 58 if (msg_cache.exists()) {
70 msg_cache.remove(); 59 msg_cache.remove();
71 } 60 }
72 msg_cache.open(IO_ReadWrite|IO_Truncate); 61 msg_cache.open(IO_ReadWrite|IO_Truncate);
73 last_msg_id = mail.getNumber(); 62 last_msg_id = mail.getNumber();
74 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length ); 63 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length );
75 if ( err != MAILPOP3_NO_ERROR ) { 64 if ( err != MAILPOP3_NO_ERROR ) {
76 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() ); 65 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() );
77 last_msg_id = 0; 66 last_msg_id = 0;
78 return RecBody(); 67 return RecBody();
79 } 68 }
80 msg_cache.writeBlock(message,length); 69 msg_cache.writeBlock(message,length);
81 } else { 70 } else {
82 QString msg=""; 71 QString msg="";
83 msg_cache.open(IO_ReadOnly); 72 msg_cache.open(IO_ReadOnly);
84 message = new char[4096]; 73 message = new char[4096];
85 memset(message,0,4096); 74 memset(message,0,4096);
86 while (msg_cache.readBlock(message,4095)>0) { 75 while (msg_cache.readBlock(message,4095)>0) {
87 msg+=message; 76 msg+=message;
88 memset(message,0,4096); 77 memset(message,0,4096);
89 } 78 }
90 delete message; 79 delete message;
91 message = (char*)malloc(msg.length()+1*sizeof(char)); 80 message = (char*)malloc(msg.length()+1*sizeof(char));
92 memset(message,0,msg.length()+1); 81 memset(message,0,msg.length()+1);
93 memcpy(message,msg.latin1(),msg.length()); 82 memcpy(message,msg.latin1(),msg.length());
94 } 83 }
95 body = parseMail(message);
96 free(message);
97 return body;
98}
99
100RecBody POP3wrapper::parseMail( char *message )
101{
102 int err = MAILIMF_NO_ERROR;
103 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */
104 size_t curTok = 0;
105 mailimf_message *result = 0;
106 mailmessage * msg=0;
107 mailmime_single_fields fields;
108 84
109 /* is bound to msg and will be freed there */ 85 /* transform to libetpan stuff */
110 struct mailmime * mime=0;
111
112 RecBody body;
113
114
115 err = mailimf_message_parse( (char *) message, strlen( message ), &curTok, &result );
116 if ( err != MAILIMF_NO_ERROR ) {
117 if (result) mailimf_message_free(result);
118 return body;
119 }
120
121 char*body_msg = message;
122 msg = mailmessage_new(); 86 msg = mailmessage_new();
123 mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg)); 87 mailmessage_init(msg, NULL, data_message_driver, 0, strlen(message));
124 generic_message_t * msg_data; 88 generic_message_t * msg_data;
125 msg_data = (generic_message_t *)msg->msg_data; 89 msg_data = (generic_message_t *)msg->msg_data;
126 msg_data->msg_fetched = 1; 90 msg_data->msg_fetched = 1;
127 msg_data->msg_message = body_msg; 91 msg_data->msg_message = message;
128 msg_data->msg_length = strlen(body_msg); 92 msg_data->msg_length = strlen(message);
129 93
94 /* parse the mail */
95 body = parseMail(msg);
130 96
131 memset(&fields, 0, sizeof(struct mailmime_single_fields)); 97 /* clean up */
132 err = mailmessage_get_bodystructure(msg,&mime); 98 mailmessage_free(msg);
133 traverseBody(body,msg,mime); 99 free(message);
134
135 mailmessage_free(msg);
136 100
101 /* finish */
137 return body; 102 return body;
138} 103}
139 104
140void POP3wrapper::listMessages(const QString &, QList<RecMail> &target ) 105void POP3wrapper::listMessages(const QString &, QList<RecMail> &target )
141{ 106{
142 int err = MAILPOP3_NO_ERROR; 107 int err = MAILPOP3_NO_ERROR;
143 char * header = 0; 108 char * header = 0;
144 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ 109 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */
145 size_t length = 0; 110 size_t length = 0;
146 carray * messages = 0; 111 carray * messages = 0;
147 112
148 login(); 113 login();
149 if (!m_pop3) return; 114 if (!m_pop3) return;
150 mailpop3_list( m_pop3, &messages ); 115 mailpop3_list( m_pop3, &messages );
151 116
152 for (unsigned int i = 0; i < carray_count(messages);++i) { 117 for (unsigned int i = 0; i < carray_count(messages);++i) {
153 mailpop3_msg_info *info; 118 mailpop3_msg_info *info;
154 err = mailpop3_get_msg_info(m_pop3,i+1,&info); 119 err = mailpop3_get_msg_info(m_pop3,i+1,&info);
155 if (info->msg_deleted) 120 if (info->msg_deleted)
156 continue; 121 continue;
157 err = mailpop3_header( m_pop3, info->msg_index, &header, &length ); 122 err = mailpop3_header( m_pop3, info->msg_index, &header, &length );
158 if ( err != MAILPOP3_NO_ERROR ) { 123 if ( err != MAILPOP3_NO_ERROR ) {
159 qDebug( "POP3: error retrieving header msgid: %i", info->msg_index ); 124 qDebug( "POP3: error retrieving header msgid: %i", info->msg_index );
160 free(header); 125 free(header);
161 return; 126 return;
162 } 127 }
163 RecMail *mail = parseHeader( header ); 128 RecMail *mail = parseHeader( header );
164 mail->setNumber( info->msg_index ); 129 mail->setNumber( info->msg_index );
165 mail->setWrapper(this); 130 mail->setWrapper(this);
166 mail->setMsgsize(info->msg_size); 131 mail->setMsgsize(info->msg_size);
167 target.append( mail ); 132 target.append( mail );
168 free(header); 133 free(header);
169 } 134 }
170} 135}
171 136
172RecMail *POP3wrapper::parseHeader( const char *header )
173{
174 int err = MAILIMF_NO_ERROR;
175 size_t curTok = 0;
176 RecMail *mail = new RecMail();
177 mailimf_fields *fields;
178 mailimf_references * refs;
179 mailimf_keywords*keys;
180 QString status;
181 QString value;
182 QBitArray mFlags(7);
183
184 err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
185 for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
186 mailimf_field *field = (mailimf_field *) current->data;
187 switch ( field->fld_type ) {
188 case MAILIMF_FIELD_FROM:
189 mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
190 break;
191 case MAILIMF_FIELD_TO:
192 mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
193 break;
194 case MAILIMF_FIELD_CC:
195 mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
196 break;
197 case MAILIMF_FIELD_BCC:
198 mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
199 break;
200 case MAILIMF_FIELD_SUBJECT:
201 mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
202 break;
203 case MAILIMF_FIELD_ORIG_DATE:
204 mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
205 break;
206 case MAILIMF_FIELD_MESSAGE_ID:
207 mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
208 break;
209 case MAILIMF_FIELD_REFERENCES:
210 refs = field->fld_data.fld_references;
211 if (refs && refs->mid_list && clist_count(refs->mid_list)) {
212 char * text = (char*)refs->mid_list->first->data;
213 mail->setReplyto(QString(text));
214 }
215 break;
216 case MAILIMF_FIELD_KEYWORDS:
217 keys = field->fld_data.fld_keywords;
218 for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
219 qDebug("Keyword: %s",(char*)cur->data);
220 }
221 break;
222 case MAILIMF_FIELD_OPTIONAL_FIELD:
223 status = field->fld_data.fld_optional_field->fld_name;
224 value = field->fld_data.fld_optional_field->fld_value;
225 if (status.lower()=="status") {
226 if (value.lower()=="ro") {
227 mFlags.setBit(FLAG_SEEN);
228 }
229 } else if (status.lower()=="x-status") {
230 qDebug("X-Status: %s",value.latin1());
231 if (value.lower()=="a") {
232 mFlags.setBit(FLAG_ANSWERED);
233 }
234 } else {
235// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
236// field->fld_data.fld_optional_field->fld_value);
237 }
238 break;
239 default:
240 qDebug("Non parsed field");
241 break;
242 }
243 }
244 if (fields) mailimf_fields_free(fields);
245 mail->setFlags(mFlags);
246 return mail;
247}
248
249QString POP3wrapper::parseDateTime( mailimf_date_time *date )
250{
251 char tmp[23];
252
253 snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
254 date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
255
256 return QString( tmp );
257}
258
259QString POP3wrapper::parseAddressList( mailimf_address_list *list )
260{
261 QString result( "" );
262
263 bool first = true;
264 for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
265 mailimf_address *addr = (mailimf_address *) current->data;
266
267 if ( !first ) {
268 result.append( "," );
269 } else {
270 first = false;
271 }
272
273 switch ( addr->ad_type ) {
274 case MAILIMF_ADDRESS_MAILBOX:
275 result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
276 break;
277 case MAILIMF_ADDRESS_GROUP:
278 result.append( parseGroup( addr->ad_data.ad_group ) );
279 break;
280 default:
281 qDebug( "POP3: unkown mailimf address type" );
282 break;
283 }
284 }
285
286 return result;
287}
288
289QString POP3wrapper::parseGroup( mailimf_group *group )
290{
291 QString result( "" );
292
293 result.append( group->grp_display_name );
294 result.append( ": " );
295
296 if ( group->grp_mb_list != NULL ) {
297 result.append( parseMailboxList( group->grp_mb_list ) );
298 }
299
300 result.append( ";" );
301
302 return result;
303}
304
305QString POP3wrapper::parseMailbox( mailimf_mailbox *box )
306{
307 QString result( "" );
308
309 if ( box->mb_display_name == NULL ) {
310 result.append( box->mb_addr_spec );
311 } else {
312 result.append( convert_String(box->mb_display_name).latin1() );
313 result.append( " <" );
314 result.append( box->mb_addr_spec );
315 result.append( ">" );
316 }
317
318 return result;
319}
320
321QString POP3wrapper::parseMailboxList( mailimf_mailbox_list *list )
322{
323 QString result( "" );
324
325 bool first = true;
326 for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
327 mailimf_mailbox *box = (mailimf_mailbox *) current->data;
328
329 if ( !first ) {
330 result.append( "," );
331 } else {
332 first = false;
333 }
334
335 result.append( parseMailbox( box ) );
336 }
337
338 return result;
339}
340
341void POP3wrapper::login() 137void POP3wrapper::login()
342{ 138{
343 /* we'll hold the line */ 139 /* we'll hold the line */
344 if ( m_pop3 != NULL ) return; 140 if ( m_pop3 != NULL ) return;
345 141
346 const char *server, *user, *pass; 142 const char *server, *user, *pass;
347 uint16_t port; 143 uint16_t port;
348 int err = MAILPOP3_NO_ERROR; 144 int err = MAILPOP3_NO_ERROR;
349 145
350 server = account->getServer().latin1(); 146 server = account->getServer().latin1();
351 port = account->getPort().toUInt(); 147 port = account->getPort().toUInt();
352 148
353 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { 149 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
354 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); 150 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
355 login.show(); 151 login.show();
356 if ( QDialog::Accepted == login.exec() ) { 152 if ( QDialog::Accepted == login.exec() ) {
357 // ok 153 // ok
358 user = strdup( login.getUser().latin1() ); 154 user = strdup( login.getUser().latin1() );
359 pass = strdup( login.getPassword().latin1() ); 155 pass = strdup( login.getPassword().latin1() );
360 } else { 156 } else {
361 // cancel 157 // cancel
362 qDebug( "POP3: Login canceled" ); 158 qDebug( "POP3: Login canceled" );
363 return; 159 return;
364 } 160 }
365 } else { 161 } else {
366 user = account->getUser().latin1(); 162 user = account->getUser().latin1();
367 pass = account->getPassword().latin1(); 163 pass = account->getPassword().latin1();
368 } 164 }
369 165
370 m_pop3 = mailpop3_new( 200, &pop3_progress ); 166 m_pop3 = mailpop3_new( 200, &pop3_progress );
371 167
372 // connect 168 // connect
373 if (account->getSSL()) { 169 if (account->getSSL()) {
374 err = mailpop3_ssl_connect( m_pop3, (char*)server, port ); 170 err = mailpop3_ssl_connect( m_pop3, (char*)server, port );
375 } else { 171 } else {
376 err = mailpop3_socket_connect( m_pop3, (char*)server, port ); 172 err = mailpop3_socket_connect( m_pop3, (char*)server, port );
377 } 173 }
378 174
379 if ( err != MAILPOP3_NO_ERROR ) { 175 if ( err != MAILPOP3_NO_ERROR ) {
380 qDebug( "pop3: error connecting to %s\n reason: %s", server, 176 qDebug( "pop3: error connecting to %s\n reason: %s", server,
381 m_pop3->pop3_response ); 177 m_pop3->pop3_response );
382 mailpop3_free( m_pop3 ); 178 mailpop3_free( m_pop3 );
383 m_pop3 = NULL; 179 m_pop3 = NULL;
384 return; 180 return;
385 } 181 }
386 qDebug( "POP3: connected!" ); 182 qDebug( "POP3: connected!" );
387 183
388 // login 184 // login
389 // TODO: decide if apop or plain login should be used 185 // TODO: decide if apop or plain login should be used
390 err = mailpop3_login( m_pop3, (char *) user, (char *) pass ); 186 err = mailpop3_login( m_pop3, (char *) user, (char *) pass );
391 if ( err != MAILPOP3_NO_ERROR ) { 187 if ( err != MAILPOP3_NO_ERROR ) {
392 qDebug( "pop3: error logging in: %s", m_pop3->pop3_response ); 188 qDebug( "pop3: error logging in: %s", m_pop3->pop3_response );
393 logout(); 189 logout();
394 return; 190 return;
395 } 191 }
396 192
397 qDebug( "POP3: logged in!" ); 193 qDebug( "POP3: logged in!" );
398} 194}
399 195
400void POP3wrapper::logout() 196void POP3wrapper::logout()
401{ 197{
402 int err = MAILPOP3_NO_ERROR; 198 int err = MAILPOP3_NO_ERROR;
403 if ( m_pop3 == NULL ) return; 199 if ( m_pop3 == NULL ) return;
404 err = mailpop3_quit( m_pop3 ); 200 err = mailpop3_quit( m_pop3 );
405 mailpop3_free( m_pop3 ); 201 mailpop3_free( m_pop3 );
406 m_pop3 = NULL; 202 m_pop3 = NULL;
407} 203}
408 204
409 205
410QList<Folder>* POP3wrapper::listFolders() 206QList<Folder>* POP3wrapper::listFolders()
411{ 207{
412 /* TODO: integrate MH directories 208 /* TODO: integrate MH directories
413 but not before version 0.1 ;) 209 but not before version 0.1 ;)
414 */ 210 */
415 QList<Folder> * folders = new QList<Folder>(); 211 QList<Folder> * folders = new QList<Folder>();
416 folders->setAutoDelete( false ); 212 folders->setAutoDelete( false );
417 Folder*inb=new Folder("INBOX","/"); 213 Folder*inb=new Folder("INBOX","/");
418 folders->append(inb); 214 folders->append(inb);
419 return folders; 215 return folders;
420} 216}
421 217
422QString POP3wrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
423{
424 encodedString*t = fetchDecodedPart(mail,part);
425 QString text=t->Content();
426 delete t;
427 return text;
428}
429
430void POP3wrapper::deleteMail(const RecMail&mail) 218void POP3wrapper::deleteMail(const RecMail&mail)
431{ 219{
432 login(); 220 login();
433 if (!m_pop3) return; 221 if (!m_pop3) return;
434 int err = mailpop3_dele(m_pop3,mail.getNumber()); 222 int err = mailpop3_dele(m_pop3,mail.getNumber());
435 if (err != MAILPOP3_NO_ERROR) { 223 if (err != MAILPOP3_NO_ERROR) {
436 qDebug("error deleting mail"); 224 qDebug("error deleting mail");
437 } 225 }
438} 226}
439 227
440void POP3wrapper::answeredMail(const RecMail&) 228void POP3wrapper::answeredMail(const RecMail&)
441{ 229{
442} 230}
443
444encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
445{
446 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
447 if (it==bodyCache.end()) return new encodedString();
448 encodedString*t = decode_String(it.data(),part.Encoding());
449 return t;
450}
451
452encodedString* POP3wrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
453{
454 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
455 if (it==bodyCache.end()) return new encodedString();
456 encodedString*t = it.data();
457 return t;
458}
459
460void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec)
461{
462 if (current_rec >= 10) {
463 qDebug("too deep recursion!");
464 }
465 if (!message || !mime) {
466 return;
467 }
468 int r;
469 char*data = 0;
470 size_t len;
471 clistiter * cur = 0;
472 int res;
473 QString b;
474 RecPart part;
475
476 switch (mime->mm_type) {
477 case MAILMIME_SINGLE:
478 r = mailmessage_fetch_section(message,mime,&data,&len);
479 part.setSize(len);
480 fillSingleBody(part,message,mime);
481 if (part.Type()=="text" && target.Bodytext().isNull()) {
482 encodedString*r = new encodedString();
483 r->setContent(data,len);
484 encodedString*res = decode_String(r,part.Encoding());
485 b = QString(res->Content());
486 delete r;
487 delete res;
488 target.setBodytext(b);
489 target.setDescription(part);
490 } else {
491 b = gen_attachment_id();
492 part.setIdentifier(b);
493 bodyCache[b]=new encodedString(data,len);
494 target.addPart(part);
495 }
496 break;
497 case MAILMIME_MULTIPLE:
498 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
499 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1);
500 }
501 break;
502 case MAILMIME_MESSAGE:
503 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
504 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1);
505 }
506 break;
507 }
508}
509
510QString POP3wrapper::getencoding(mailmime_mechanism*aEnc)
511{
512 QString enc="7bit";
513 if (!aEnc) return enc;
514 switch(aEnc->enc_type) {
515 case MAILMIME_MECHANISM_7BIT:
516 enc = "7bit";
517 break;
518 case MAILMIME_MECHANISM_8BIT:
519 enc = "8bit";
520 break;
521 case MAILMIME_MECHANISM_BINARY:
522 enc = "binary";
523 break;
524 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
525 enc = "quoted-printable";
526 break;
527 case MAILMIME_MECHANISM_BASE64:
528 enc = "base64";
529 break;
530 case MAILMIME_MECHANISM_TOKEN:
531 default:
532 if (aEnc->enc_token) {
533 enc = QString(aEnc->enc_token);
534 }
535 break;
536 }
537 return enc;
538}
539
540void POP3wrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
541{
542 if (!mime) {
543 return;
544 }
545 mailmime_field*field = 0;
546 mailmime_single_fields fields;
547 memset(&fields, 0, sizeof(struct mailmime_single_fields));
548 if (mime->mm_mime_fields != NULL) {
549 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
550 mime->mm_content_type);
551 }
552
553 mailmime_content*type = fields.fld_content;
554 clistcell*current;
555 if (!type) {
556 target.setType("text");
557 target.setSubtype("plain");
558 } else {
559 target.setSubtype(type->ct_subtype);
560 switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
561 case MAILMIME_DISCRETE_TYPE_TEXT:
562 target.setType("text");
563 break;
564 case MAILMIME_DISCRETE_TYPE_IMAGE:
565 target.setType("image");
566 break;
567 case MAILMIME_DISCRETE_TYPE_AUDIO:
568 target.setType("audio");
569 break;
570 case MAILMIME_DISCRETE_TYPE_VIDEO:
571 target.setType("video");
572 break;
573 case MAILMIME_DISCRETE_TYPE_APPLICATION:
574 target.setType("application");
575 break;
576 case MAILMIME_DISCRETE_TYPE_EXTENSION:
577 default:
578 if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
579 target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
580 }
581 break;
582 }
583 if (type->ct_parameters) {
584 fillParameters(target,type->ct_parameters);
585 }
586 }
587 if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
588 for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
589 field = (mailmime_field*)current->data;
590 switch(field->fld_type) {
591 case MAILMIME_FIELD_TRANSFER_ENCODING:
592 target.setEncoding(getencoding(field->fld_data.fld_encoding));
593 break;
594 case MAILMIME_FIELD_ID:
595 target.setIdentifier(field->fld_data.fld_id);
596 break;
597 case MAILMIME_FIELD_DESCRIPTION:
598 target.setDescription(field->fld_data.fld_description);
599 break;
600 default:
601 break;
602 }
603 }
604 }
605}
606
607void POP3wrapper::fillParameters(RecPart&target,clist*parameters)
608{
609 if (!parameters) {return;}
610 clistcell*current=0;
611 mailmime_parameter*param;
612 for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
613 param = (mailmime_parameter*)current->data;
614 if (param) {
615 target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
616 }
617 }
618}
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 @@
1#ifndef __POP3WRAPPER 1#ifndef __POP3WRAPPER
2#define __POP3WRAPPER 2#define __POP3WRAPPER
3 3
4#include <libetpan/clist.h>
5#include "mailwrapper.h" 4#include "mailwrapper.h"
6#include "abstractmail.h" 5#include "genericwrapper.h"
7#include <qmap.h>
8#include <qstring.h> 6#include <qstring.h>
9 7
10class RecMail;
11class RecBody;
12class encodedString;
13struct mailpop3;
14struct mailmessage;
15struct mailmime;
16struct mailmime_mechanism;
17struct mailimf_mailbox_list;
18struct mailimf_mailbox;
19struct mailimf_date_time;
20struct mailimf_group;
21struct mailimf_address_list;
22 8
23class POP3wrapper : public AbstractMail 9class POP3wrapper : public Genericwrapper
24{ 10{
25 Q_OBJECT 11 Q_OBJECT
26 12
27public: 13public:
28 POP3wrapper( POP3account *a ); 14 POP3wrapper( POP3account *a );
29 virtual ~POP3wrapper(); 15 virtual ~POP3wrapper();
30 /* mailbox will be ignored */ 16 /* mailbox will be ignored */
31 virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); 17 virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
32 virtual QList<Folder>* listFolders(); 18 virtual QList<Folder>* listFolders();
33 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
34 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
35 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
36 19
37 virtual void deleteMail(const RecMail&mail); 20 virtual void deleteMail(const RecMail&mail);
38 virtual void answeredMail(const RecMail&mail); 21 virtual void answeredMail(const RecMail&mail);
39 22
40 RecBody fetchBody( const RecMail &mail ); 23 virtual RecBody fetchBody( const RecMail &mail );
41 static void pop3_progress( size_t current, size_t maximum ); 24 static void pop3_progress( size_t current, size_t maximum );
42 25
43protected: 26protected:
44 void login(); 27 void login();
45 void logout(); 28 void logout();
46 29
47 RecMail *parseHeader( const char *header );
48 RecBody parseMail( char *message );
49 QString parseMailboxList( mailimf_mailbox_list *list );
50 QString parseMailbox( mailimf_mailbox *box );
51 QString parseGroup( mailimf_group *group );
52 QString parseAddressList( mailimf_address_list *list );
53 QString parseDateTime( mailimf_date_time *date );
54
55 void cleanUpCache();
56
57 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
58 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
59 static void fillParameters(RecPart&target,clist*parameters);
60 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
61
62 POP3account *account;
63 mailpop3 *m_pop3;
64 QString msgTempName;
65 unsigned int last_msg_id;
66 QMap<QString,encodedString*> bodyCache;
67}; 30};
68 31
69#endif 32#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
@@ -65,306 +65,307 @@ default:
65 /* I did not found a method to make a CONTENT reset on a QTextStream 65 /* I did not found a method to make a CONTENT reset on a QTextStream
66 so I use this construct that the stream will re-constructed in each 66 so I use this construct that the stream will re-constructed in each
67 loop. To let it work, the textstream is packed into a own area of 67 loop. To let it work, the textstream is packed into a own area of
68 code is it will be destructed after finishing its small job. 68 code is it will be destructed after finishing its small job.
69 */ 69 */
70 QTextOStream o(&fsize); 70 QTextOStream o(&fsize);
71 if (w>0) o.precision(2); else o.precision(0); 71 if (w>0) o.precision(2); else o.precision(0);
72 o.setf(QTextStream::fixed); 72 o.setf(QTextStream::fixed);
73 o << s << " " << q << "Byte"; 73 o << s << " " << q << "Byte";
74} 74}
75 75
76curItem=new AttachItem(attachments,curItem,type,"Mailbody","",fsize,-1); 76curItem=new AttachItem(attachments,curItem,type,"Mailbody","",fsize,-1);
77QString filename = ""; 77QString filename = "";
78for (unsigned int i = 0; i < body.Parts().count();++i) { 78for (unsigned int i = 0; i < body.Parts().count();++i) {
79 type = body.Parts()[i].Type()+"/"+body.Parts()[i].Subtype(); 79 type = body.Parts()[i].Type()+"/"+body.Parts()[i].Subtype();
80 part_plist_t::ConstIterator it = body.Parts()[i].Parameters().begin(); 80 part_plist_t::ConstIterator it = body.Parts()[i].Parameters().begin();
81 for (;it!=body.Parts()[i].Parameters().end();++it) { 81 for (;it!=body.Parts()[i].Parameters().end();++it) {
82 qDebug(it.key()); 82 qDebug(it.key());
83 if (it.key().lower()=="name") { 83 if (it.key().lower()=="name") {
84 filename=it.data(); 84 filename=it.data();
85 } 85 }
86 } 86 }
87 s = body.Parts()[i].Size(); 87 s = body.Parts()[i].Size();
88 w = 0; 88 w = 0;
89 while (s>1024) { 89 while (s>1024) {
90 s/=1024; 90 s/=1024;
91 ++w; 91 ++w;
92 if (w>=2) break; 92 if (w>=2) break;
93 } 93 }
94 switch(w) { 94 switch(w) {
95 case 1: 95 case 1:
96 q="k"; 96 q="k";
97 break; 97 break;
98 case 2: 98 case 2:
99 q="M"; 99 q="M";
100 break; 100 break;
101 default: 101 default:
102 q=""; 102 q="";
103 break; 103 break;
104 } 104 }
105 QTextOStream o(&fsize); 105 QTextOStream o(&fsize);
106 if (w>0) o.precision(2); else o.precision(0); 106 if (w>0) o.precision(2); else o.precision(0);
107 o.setf(QTextStream::fixed); 107 o.setf(QTextStream::fixed);
108 o << s << " " << q << "Byte"; 108 o << s << " " << q << "Byte";
109 desc = body.Parts()[i].Description(); 109 desc = body.Parts()[i].Description();
110 curItem=new AttachItem(attachments,curItem,type,desc,filename,fsize,i); 110 curItem=new AttachItem(attachments,curItem,type,desc,filename,fsize,i);
111} 111}
112} 112}
113 113
114 114
115void ViewMail::slotShowHtml( bool state ) { 115void ViewMail::slotShowHtml( bool state ) {
116 m_showHtml = state; 116 m_showHtml = state;
117 setText(); 117 setText();
118} 118}
119 119
120void ViewMail::slotItemClicked( QListViewItem * item , const QPoint & point, int ) { 120void ViewMail::slotItemClicked( QListViewItem * item , const QPoint & point, int ) {
121 if (!item ) 121 if (!item )
122 return; 122 return;
123 123
124 if ( ( ( AttachItem* )item )->Partnumber() == -1 ) { 124 if ( ( ( AttachItem* )item )->Partnumber() == -1 ) {
125 setText(); 125 setText();
126 return; 126 return;
127 } 127 }
128 QPopupMenu *menu = new QPopupMenu(); 128 QPopupMenu *menu = new QPopupMenu();
129 int ret=0; 129 int ret=0;
130 130
131 if ( item->text( 0 ).left( 5 ) == "text/" ) { 131 if ( item->text( 0 ).left( 5 ) == "text/" ) {
132 menu->insertItem( tr( "Show Text" ), 1 ); 132 menu->insertItem( tr( "Show Text" ), 1 );
133 } 133 }
134 menu->insertItem( tr( "Save Attachment" ), 0 ); 134 menu->insertItem( tr( "Save Attachment" ), 0 );
135 menu->insertSeparator(1); 135 menu->insertSeparator(1);
136 136
137 ret = menu->exec( point, 0 ); 137 ret = menu->exec( point, 0 );
138 138
139 switch(ret) { 139 switch(ret) {
140 case 0: 140 case 0:
141 { MimeTypes types; 141 { MimeTypes types;
142 types.insert( "all", "*" ); 142 types.insert( "all", "*" );
143 QString str = OFileDialog::getSaveFileName( 1, 143 QString str = OFileDialog::getSaveFileName( 1,
144 "/", item->text( 2 ) , types, 0 ); 144 "/", item->text( 2 ) , types, 0 );
145 145
146 if( !str.isEmpty() ) { 146 if( !str.isEmpty() ) {
147 encodedString*content = m_recMail.Wrapper()->fetchDecodedPart( m_recMail, m_body.Parts()[ ( ( AttachItem* )item )->Partnumber() ] ); 147 encodedString*content = m_recMail.Wrapper()->fetchDecodedPart( m_recMail, m_body.Parts()[ ( ( AttachItem* )item )->Partnumber() ] );
148 if (content) { 148 if (content) {
149 QFile output(str); 149 QFile output(str);
150 output.open(IO_WriteOnly); 150 output.open(IO_WriteOnly);
151 output.writeBlock(content->Content(),content->Length()); 151 output.writeBlock(content->Content(),content->Length());
152 output.close(); 152 output.close();
153 delete content; 153 delete content;
154 } 154 }
155 } 155 }
156 } 156 }
157 break ; 157 break ;
158 158
159 case 1: 159 case 1:
160 if ( ( ( AttachItem* )item )->Partnumber() == -1 ) { 160 if ( ( ( AttachItem* )item )->Partnumber() == -1 ) {
161 setText(); 161 setText();
162 } else { 162 } else {
163 if ( m_recMail.Wrapper() != 0l ) { // make sure that there is a wrapper , even after delete or simular actions 163 if ( m_recMail.Wrapper() != 0l ) { // make sure that there is a wrapper , even after delete or simular actions
164 browser->setText( m_recMail.Wrapper()->fetchTextPart( m_recMail, m_body.Parts()[ ( ( AttachItem* )item )->Partnumber() ] ) ); 164 browser->setText( m_recMail.Wrapper()->fetchTextPart( m_recMail, m_body.Parts()[ ( ( AttachItem* )item )->Partnumber() ] ) );
165 } 165 }
166 } 166 }
167 break; 167 break;
168 } 168 }
169 delete menu; 169 delete menu;
170} 170}
171 171
172 172
173void ViewMail::setMail( RecMail mail ) { 173void ViewMail::setMail( RecMail mail ) {
174 174
175 m_recMail = mail; 175 m_recMail = mail;
176 176
177 m_mail[0] = mail.getFrom(); 177 m_mail[0] = mail.getFrom();
178 m_mail[1] = mail.getSubject(); 178 m_mail[1] = mail.getSubject();
179 m_mail[3] = mail.getDate(); 179 m_mail[3] = mail.getDate();
180 m_mail[4] = mail.Msgid(); 180 m_mail[4] = mail.Msgid();
181 181
182 m_mail2[0] = mail.To(); 182 m_mail2[0] = mail.To();
183 m_mail2[1] = mail.CC(); 183 m_mail2[1] = mail.CC();
184 m_mail2[2] = mail.Bcc(); 184 m_mail2[2] = mail.Bcc();
185 185
186 setText(); 186 setText();
187} 187}
188 188
189 189
190 190
191ViewMail::ViewMail( QWidget *parent, const char *name, WFlags fl) 191ViewMail::ViewMail( QWidget *parent, const char *name, WFlags fl)
192 : ViewMailBase(parent, name, fl), _inLoop(false) 192 : ViewMailBase(parent, name, fl), _inLoop(false)
193{ 193{
194 m_gotBody = false; 194 m_gotBody = false;
195 deleted = false; 195 deleted = false;
196 196
197 connect( reply, SIGNAL(activated()), SLOT(slotReply())); 197 connect( reply, SIGNAL(activated()), SLOT(slotReply()));
198 connect( forward, SIGNAL(activated()), SLOT(slotForward())); 198 connect( forward, SIGNAL(activated()), SLOT(slotForward()));
199 connect( deleteMail, SIGNAL( activated() ), SLOT( slotDeleteMail( ) ) ); 199 connect( deleteMail, SIGNAL( activated() ), SLOT( slotDeleteMail( ) ) );
200 connect( showHtml, SIGNAL( toggled( bool ) ), SLOT( slotShowHtml( bool ) ) ); 200 connect( showHtml, SIGNAL( toggled( bool ) ), SLOT( slotShowHtml( bool ) ) );
201 201
202 attachments->setEnabled(m_gotBody); 202 attachments->setEnabled(m_gotBody);
203 connect( attachments, SIGNAL( clicked ( QListViewItem *, const QPoint & , int ) ), SLOT( slotItemClicked( QListViewItem *, const QPoint & , int ) ) ); 203 connect( attachments, SIGNAL( clicked ( QListViewItem *, const QPoint & , int ) ), SLOT( slotItemClicked( QListViewItem *, const QPoint & , int ) ) );
204 204
205 readConfig(); 205 readConfig();
206 206
207} 207}
208 208
209void ViewMail::readConfig() { 209void ViewMail::readConfig() {
210 Config cfg( "mail" ); 210 Config cfg( "mail" );
211 cfg.setGroup( "Settings" ); 211 cfg.setGroup( "Settings" );
212 m_showHtml = cfg.readBoolEntry( "showHtml", false ); 212 m_showHtml = cfg.readBoolEntry( "showHtml", false );
213 showHtml->setOn( m_showHtml ); 213 showHtml->setOn( m_showHtml );
214} 214}
215 215
216void ViewMail::setText() 216void ViewMail::setText()
217{ 217{
218 218
219 QString toString; 219 QString toString;
220 QString ccString; 220 QString ccString;
221 QString bccString; 221 QString bccString;
222 222
223 for ( QStringList::Iterator it = ( m_mail2[0] ).begin(); it != ( m_mail2[0] ).end(); ++it ) { 223 for ( QStringList::Iterator it = ( m_mail2[0] ).begin(); it != ( m_mail2[0] ).end(); ++it ) {
224 toString += (*it); 224 toString += (*it);
225 } 225 }
226 for ( QStringList::Iterator it = ( m_mail2[1] ).begin(); it != ( m_mail2[1] ).end(); ++it ) { 226 for ( QStringList::Iterator it = ( m_mail2[1] ).begin(); it != ( m_mail2[1] ).end(); ++it ) {
227 ccString += (*it); 227 ccString += (*it);
228 } 228 }
229 for ( QStringList::Iterator it = ( m_mail2[2] ).begin(); it != ( m_mail2[2] ).end(); ++it ) { 229 for ( QStringList::Iterator it = ( m_mail2[2] ).begin(); it != ( m_mail2[2] ).end(); ++it ) {
230 bccString += (*it); 230 bccString += (*it);
231 } 231 }
232 232
233 setCaption( caption().arg( m_mail[0] ) ); 233 setCaption( caption().arg( m_mail[0] ) );
234 234
235 m_mailHtml = "<html><body>" 235 m_mailHtml = "<html><body>"
236 "<table width=\"100%\" border=\"0\"><tr bgcolor=\"#FFDD76\"><td>" 236 "<table width=\"100%\" border=\"0\"><tr bgcolor=\"#FFDD76\"><td>"
237 "<div align=left><b>" + deHtml( m_mail[1] ) + "</b></div>" 237 "<div align=left><b>" + deHtml( m_mail[1] ) + "</b></div>"
238 "</td></tr><tr bgcolor=\"#EEEEE6\"><td>" 238 "</td></tr><tr bgcolor=\"#EEEEE6\"><td>"
239 "<b>" + tr( "From" ) + ": </b><font color=#6C86C0>" + deHtml( m_mail[0] ) + "</font><br>" 239 "<b>" + tr( "From" ) + ": </b><font color=#6C86C0>" + deHtml( m_mail[0] ) + "</font><br>"
240 "<b>" + tr( "To" ) + ": </b><font color=#6C86C0>" + deHtml( toString ) + "</font><br><b>" + 240 "<b>" + tr( "To" ) + ": </b><font color=#6C86C0>" + deHtml( toString ) + "</font><br><b>" +
241 tr( "Cc" ) + ": </b>" + deHtml( ccString ) + "<br>" 241 tr( "Cc" ) + ": </b>" + deHtml( ccString ) + "<br>"
242 "<b>" + tr( "Date" ) + ": </b> " + m_mail[3] + 242 "<b>" + tr( "Date" ) + ": </b> " + m_mail[3] +
243 "</td></tr></table><font face=fixed>"; 243 "</td></tr></table><font face=fixed>";
244 244
245 if ( !m_showHtml ) { 245 if ( !m_showHtml ) {
246 browser->setText( QString( m_mailHtml) + deHtml( m_mail[2] ) + "</font></html>" ); 246 browser->setText( QString( m_mailHtml) + deHtml( m_mail[2] ) + "</font></html>" );
247 } else { 247 } else {
248 browser->setText( QString( m_mailHtml) + m_mail[2] + "</font></html>" ); 248 browser->setText( QString( m_mailHtml) + m_mail[2] + "</font></html>" );
249 } 249 }
250 // remove later in favor of a real handling 250 // remove later in favor of a real handling
251 m_gotBody = true; 251 m_gotBody = true;
252} 252}
253 253
254 254
255ViewMail::~ViewMail() 255ViewMail::~ViewMail()
256{ 256{
257 m_recMail.Wrapper()->cleanMimeCache();
257 hide(); 258 hide();
258} 259}
259 260
260void ViewMail::hide() 261void ViewMail::hide()
261{ 262{
262 QWidget::hide(); 263 QWidget::hide();
263 264
264 if (_inLoop) { 265 if (_inLoop) {
265 _inLoop = false; 266 _inLoop = false;
266 qApp->exit_loop(); 267 qApp->exit_loop();
267 268
268 } 269 }
269 270
270} 271}
271 272
272void ViewMail::exec() 273void ViewMail::exec()
273{ 274{
274 show(); 275 show();
275 276
276 if (!_inLoop) { 277 if (!_inLoop) {
277 _inLoop = true; 278 _inLoop = true;
278 qApp->enter_loop(); 279 qApp->enter_loop();
279 } 280 }
280 281
281} 282}
282 283
283QString ViewMail::deHtml(const QString &string) 284QString ViewMail::deHtml(const QString &string)
284{ 285{
285 QString string_ = string; 286 QString string_ = string;
286 string_.replace(QRegExp("&"), "&amp;"); 287 string_.replace(QRegExp("&"), "&amp;");
287 string_.replace(QRegExp("<"), "&lt;"); 288 string_.replace(QRegExp("<"), "&lt;");
288 string_.replace(QRegExp(">"), "&gt;"); 289 string_.replace(QRegExp(">"), "&gt;");
289 string_.replace(QRegExp("\\n"), "<br>"); 290 string_.replace(QRegExp("\\n"), "<br>");
290 return string_; 291 return string_;
291} 292}
292 293
293void ViewMail::slotReply() 294void ViewMail::slotReply()
294{ 295{
295 if (!m_gotBody) { 296 if (!m_gotBody) {
296 QMessageBox::information(this, tr("Error"), tr("<p>The mail body is not yet downloaded, so you cannot reply yet."), tr("Ok")); 297 QMessageBox::information(this, tr("Error"), tr("<p>The mail body is not yet downloaded, so you cannot reply yet."), tr("Ok"));
297 return; 298 return;
298 } 299 }
299 300
300 QString rtext; 301 QString rtext;
301 rtext += QString("* %1 wrote on %2:\n") // no i18n on purpose 302 rtext += QString("* %1 wrote on %2:\n") // no i18n on purpose
302 .arg( m_mail[0] ) 303 .arg( m_mail[0] )
303 .arg( m_mail[3] ); 304 .arg( m_mail[3] );
304 305
305 QString text = m_mail[2]; 306 QString text = m_mail[2];
306 QStringList lines = QStringList::split(QRegExp("\\n"), text); 307 QStringList lines = QStringList::split(QRegExp("\\n"), text);
307 QStringList::Iterator it; 308 QStringList::Iterator it;
308 for (it = lines.begin(); it != lines.end(); it++) { 309 for (it = lines.begin(); it != lines.end(); it++) {
309 rtext += "> " + *it + "\n"; 310 rtext += "> " + *it + "\n";
310 } 311 }
311 rtext += "\n"; 312 rtext += "\n";
312 313
313 QString prefix; 314 QString prefix;
314 if ( m_mail[1].find(QRegExp("^Re: *$")) != -1) prefix = ""; 315 if ( m_mail[1].find(QRegExp("^Re: *$")) != -1) prefix = "";
315 else prefix = "Re: "; // no i18n on purpose 316 else prefix = "Re: "; // no i18n on purpose
316 317
317 Settings *settings = new Settings(); 318 Settings *settings = new Settings();
318 ComposeMail composer( settings ,this, 0, true); 319 ComposeMail composer( settings ,this, 0, true);
319 composer.setTo( m_mail[0] ); 320 composer.setTo( m_mail[0] );
320 composer.setSubject( "Re: " + m_mail[1] ); 321 composer.setSubject( "Re: " + m_mail[1] );
321 composer.setMessage( rtext ); 322 composer.setMessage( rtext );
322 composer.showMaximized(); 323 composer.showMaximized();
323 if ( QDialog::Accepted==composer.exec()) { 324 if ( QDialog::Accepted==composer.exec()) {
324 m_recMail.Wrapper()->answeredMail(m_recMail); 325 m_recMail.Wrapper()->answeredMail(m_recMail);
325 } 326 }
326} 327}
327 328
328void ViewMail::slotForward() 329void ViewMail::slotForward()
329{ 330{
330 if (!m_gotBody) { 331 if (!m_gotBody) {
331 QMessageBox::information(this, tr("Error"), tr("<p>The mail body is not yet downloaded, so you cannot forward yet."), tr("Ok")); 332 QMessageBox::information(this, tr("Error"), tr("<p>The mail body is not yet downloaded, so you cannot forward yet."), tr("Ok"));
332 return; 333 return;
333 } 334 }
334 335
335 QString ftext; 336 QString ftext;
336 ftext += QString("\n----- Forwarded message from %1 -----\n\n") 337 ftext += QString("\n----- Forwarded message from %1 -----\n\n")
337 .arg( m_mail[0] ); 338 .arg( m_mail[0] );
338 if (!m_mail[3].isNull()) 339 if (!m_mail[3].isNull())
339 ftext += QString("Date: %1\n") 340 ftext += QString("Date: %1\n")
340 .arg( m_mail[3] ); 341 .arg( m_mail[3] );
341 if (!m_mail[0].isNull()) 342 if (!m_mail[0].isNull())
342 ftext += QString("From: %1\n") 343 ftext += QString("From: %1\n")
343 .arg( m_mail[0] ); 344 .arg( m_mail[0] );
344 if (!m_mail[1].isNull()) 345 if (!m_mail[1].isNull())
345 ftext += QString("Subject: %1\n") 346 ftext += QString("Subject: %1\n")
346 .arg( m_mail[1] ); 347 .arg( m_mail[1] );
347 348
348 ftext += QString("\n%1\n") 349 ftext += QString("\n%1\n")
349 .arg( m_mail[2]); 350 .arg( m_mail[2]);
350 351
351 ftext += QString("----- End forwarded message -----\n"); 352 ftext += QString("----- End forwarded message -----\n");
352 353
353 Settings *settings = new Settings(); 354 Settings *settings = new Settings();
354 ComposeMail composer( settings ,this, 0, true); 355 ComposeMail composer( settings ,this, 0, true);
355 composer.setSubject( "Fwd: " + m_mail[1] ); 356 composer.setSubject( "Fwd: " + m_mail[1] );
356 composer.setMessage( ftext ); 357 composer.setMessage( ftext );
357 composer.showMaximized(); 358 composer.showMaximized();
358 if ( QDialog::Accepted==composer.exec()) { 359 if ( QDialog::Accepted==composer.exec()) {
359 360
360 } 361 }
361} 362}
362 363
363void ViewMail::slotDeleteMail( ) 364void ViewMail::slotDeleteMail( )
364{ 365{
365 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 ) { 366 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 ) {
366 m_recMail.Wrapper()->deleteMail( m_recMail ); 367 m_recMail.Wrapper()->deleteMail( m_recMail );
367 hide(); 368 hide();
368 deleted = true; 369 deleted = true;
369 } 370 }
370} 371}