summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.cpp183
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.h8
-rw-r--r--noncore/net/mail/pop3wrapper.cpp183
-rw-r--r--noncore/net/mail/pop3wrapper.h8
4 files changed, 318 insertions, 64 deletions
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.cpp b/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
index b0b985c..2c2a42a 100644
--- a/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
@@ -1,273 +1,250 @@
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{ 14{
15 account = a; 15 account = a;
16 m_pop3 = NULL; 16 m_pop3 = NULL;
17 msgTempName = a->getFileName()+"_msg_cache"; 17 msgTempName = a->getFileName()+"_msg_cache";
18 last_msg_id = 0; 18 last_msg_id = 0;
19} 19}
20 20
21POP3wrapper::~POP3wrapper() 21POP3wrapper::~POP3wrapper()
22{ 22{
23 logout(); 23 logout();
24 QFile msg_cache(msgTempName); 24 QFile msg_cache(msgTempName);
25 if (msg_cache.exists()) { 25 if (msg_cache.exists()) {
26 msg_cache.remove(); 26 msg_cache.remove();
27 } 27 }
28} 28}
29 29
30void POP3wrapper::pop3_progress( size_t current, size_t maximum ) 30void POP3wrapper::pop3_progress( size_t current, size_t maximum )
31{ 31{
32 //qDebug( "POP3: %i of %i", current, maximum ); 32 //qDebug( "POP3: %i of %i", current, maximum );
33} 33}
34 34
35RecBody POP3wrapper::fetchBody( const RecMail &mail ) 35RecBody POP3wrapper::fetchBody( const RecMail &mail )
36{ 36{
37 int err = MAILPOP3_NO_ERROR; 37 int err = MAILPOP3_NO_ERROR;
38 char *message; 38 char *message;
39 size_t length = 0; 39 size_t length = 0;
40 40
41 login(); 41 login();
42 if ( !m_pop3 ) { 42 if ( !m_pop3 ) {
43 return RecBody(); 43 return RecBody();
44 } 44 }
45 45
46 RecBody body; 46 RecBody body;
47 47
48 QFile msg_cache(msgTempName); 48 QFile msg_cache(msgTempName);
49 49
50 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) { 50 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) {
51 qDebug("Message to large: %i",mail.Msgsize()); 51 qDebug("Message to large: %i",mail.Msgsize());
52 return body; 52 return body;
53 } 53 }
54 if (mail.getNumber()!=last_msg_id) { 54 if (mail.getNumber()!=last_msg_id) {
55 if (msg_cache.exists()) { 55 if (msg_cache.exists()) {
56 msg_cache.remove(); 56 msg_cache.remove();
57 } 57 }
58 msg_cache.open(IO_ReadWrite|IO_Truncate); 58 msg_cache.open(IO_ReadWrite|IO_Truncate);
59 last_msg_id = mail.getNumber(); 59 last_msg_id = mail.getNumber();
60 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length ); 60 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length );
61 if ( err != MAILPOP3_NO_ERROR ) { 61 if ( err != MAILPOP3_NO_ERROR ) {
62 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() ); 62 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() );
63 last_msg_id = 0; 63 last_msg_id = 0;
64 return RecBody(); 64 return RecBody();
65 } 65 }
66 msg_cache.writeBlock(message,length); 66 msg_cache.writeBlock(message,length);
67 } else { 67 } else {
68 QString msg=""; 68 QString msg="";
69 msg_cache.open(IO_ReadOnly); 69 msg_cache.open(IO_ReadOnly);
70 message = new char[4096]; 70 message = new char[4096];
71 memset(message,0,4096); 71 memset(message,0,4096);
72 while (msg_cache.readBlock(message,4095)>0) { 72 while (msg_cache.readBlock(message,4095)>0) {
73 msg+=message; 73 msg+=message;
74 memset(message,0,4096); 74 memset(message,0,4096);
75 } 75 }
76 delete message; 76 delete message;
77 message = (char*)malloc(msg.length()+1*sizeof(char)); 77 message = (char*)malloc(msg.length()+1*sizeof(char));
78 memset(message,0,msg.length()+1); 78 memset(message,0,msg.length()+1);
79 memcpy(message,msg.latin1(),msg.length()); 79 memcpy(message,msg.latin1(),msg.length());
80 } 80 }
81 body = parseMail(message); 81 body = parseMail(message);
82 free(message); 82 free(message);
83 return body; 83 return body;
84} 84}
85 85
86RecBody POP3wrapper::parseMail( char *message ) 86RecBody POP3wrapper::parseMail( char *message )
87{ 87{
88 int err = MAILIMF_NO_ERROR; 88 int err = MAILIMF_NO_ERROR;
89 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ 89 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */
90 size_t curTok = 0; 90 size_t curTok = 0;
91 mailimf_message *result = 0; 91 mailimf_message *result = 0;
92 mailmessage * msg=0; 92 mailmessage * msg=0;
93 mailmime_single_fields fields;
94
95 /* is bound to msg and will be freed there */
93 struct mailmime * mime=0; 96 struct mailmime * mime=0;
94 struct mailmime_single_fields fields; 97
95
96 RecBody body; 98 RecBody body;
97 99
98 100
99 err = mailimf_message_parse( (char *) message, strlen( message ), &curTok, &result ); 101 err = mailimf_message_parse( (char *) message, strlen( message ), &curTok, &result );
100 if ( err != MAILIMF_NO_ERROR ) { 102 if ( err != MAILIMF_NO_ERROR ) {
101 if (result) mailimf_message_free(result); 103 if (result) mailimf_message_free(result);
102 return body; 104 return body;
103 } 105 }
104 106
105#if 0
106 char*body_msg = message; 107 char*body_msg = message;
107 if ( result && result->msg_body && result->msg_body->bd_text ) {
108 body_msg = (char*)result->msg_body->bd_text;
109 result->msg_body->bd_text = 0;
110 }
111
112 msg = mailmessage_new(); 108 msg = mailmessage_new();
113 mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg)); 109 mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg));
114 generic_message_t * msg_data; 110 generic_message_t * msg_data;
115 msg_data = (generic_message_t *)msg->msg_data; 111 msg_data = (generic_message_t *)msg->msg_data;
116 msg_data->msg_fetched = 1; 112 msg_data->msg_fetched = 1;
117 msg_data->msg_message = body_msg; 113 msg_data->msg_message = body_msg;
118 msg_data->msg_length = strlen(body_msg); 114 msg_data->msg_length = strlen(body_msg);
115
116
119 memset(&fields, 0, sizeof(struct mailmime_single_fields)); 117 memset(&fields, 0, sizeof(struct mailmime_single_fields));
120 err = mailmessage_get_bodystructure(msg,&mime); 118 err = mailmessage_get_bodystructure(msg,&mime);
119 traverseBody(body,msg,mime);
120
121 mailmessage_free(msg);
121 122
122 if (mime->mm_mime_fields != NULL) {
123 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
124 mime->mm_content_type);
125 }
126#endif
127
128#if 1
129 if ( result && result->msg_body && result->msg_body->bd_text ) {
130 qDebug( "POP3: bodytext found" );
131 // when curTok isn't set to 0 this line will fault! 'cause upper line faults!
132 body.setBodytext( QString( result->msg_body->bd_text ) );
133#if 0
134 curTok = 0;
135 mailmime_content*mresult = 0;
136 size_t index = 0;
137 mailmime_content_parse(result->msg_body->bd_text,
138 strlen(result->msg_body->bd_text),&index,&mresult);
139 if (mresult) {
140 mailmime_content_free(mresult);
141 }
142#endif
143 mailimf_message_free(result);
144 }
145#endif
146 return body; 123 return body;
147} 124}
148 125
149void POP3wrapper::listMessages(const QString &, QList<RecMail> &target ) 126void POP3wrapper::listMessages(const QString &, QList<RecMail> &target )
150{ 127{
151 int err = MAILPOP3_NO_ERROR; 128 int err = MAILPOP3_NO_ERROR;
152 char * header = 0; 129 char * header = 0;
153 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ 130 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */
154 size_t length = 0; 131 size_t length = 0;
155 carray * messages = 0; 132 carray * messages = 0;
156 133
157 login(); 134 login();
158 if (!m_pop3) return; 135 if (!m_pop3) return;
159 mailpop3_list( m_pop3, &messages ); 136 mailpop3_list( m_pop3, &messages );
160 137
161 for (unsigned int i = 0; i < carray_count(messages);++i) { 138 for (unsigned int i = 0; i < carray_count(messages);++i) {
162 mailpop3_msg_info *info; 139 mailpop3_msg_info *info;
163 err = mailpop3_get_msg_info(m_pop3,i+1,&info); 140 err = mailpop3_get_msg_info(m_pop3,i+1,&info);
164 if (info->msg_deleted) 141 if (info->msg_deleted)
165 continue; 142 continue;
166 err = mailpop3_header( m_pop3, info->msg_index, &header, &length ); 143 err = mailpop3_header( m_pop3, info->msg_index, &header, &length );
167 if ( err != MAILPOP3_NO_ERROR ) { 144 if ( err != MAILPOP3_NO_ERROR ) {
168 qDebug( "POP3: error retrieving header msgid: %i", info->msg_index ); 145 qDebug( "POP3: error retrieving header msgid: %i", info->msg_index );
169 free(header); 146 free(header);
170 return; 147 return;
171 } 148 }
172 RecMail *mail = parseHeader( header ); 149 RecMail *mail = parseHeader( header );
173 mail->setNumber( info->msg_index ); 150 mail->setNumber( info->msg_index );
174 mail->setWrapper(this); 151 mail->setWrapper(this);
175 mail->setMsgsize(info->msg_size); 152 mail->setMsgsize(info->msg_size);
176 target.append( mail ); 153 target.append( mail );
177 free(header); 154 free(header);
178 } 155 }
179} 156}
180 157
181RecMail *POP3wrapper::parseHeader( const char *header ) 158RecMail *POP3wrapper::parseHeader( const char *header )
182{ 159{
183 int err = MAILIMF_NO_ERROR; 160 int err = MAILIMF_NO_ERROR;
184 size_t curTok = 0; 161 size_t curTok = 0;
185 RecMail *mail = new RecMail(); 162 RecMail *mail = new RecMail();
186 mailimf_fields *fields; 163 mailimf_fields *fields;
187 mailimf_references * refs; 164 mailimf_references * refs;
188 mailimf_keywords*keys; 165 mailimf_keywords*keys;
189 QString status; 166 QString status;
190 QString value; 167 QString value;
191 QBitArray mFlags(7); 168 QBitArray mFlags(7);
192 169
193 err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields ); 170 err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
194 for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) { 171 for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
195 mailimf_field *field = (mailimf_field *) current->data; 172 mailimf_field *field = (mailimf_field *) current->data;
196 switch ( field->fld_type ) { 173 switch ( field->fld_type ) {
197 case MAILIMF_FIELD_FROM: 174 case MAILIMF_FIELD_FROM:
198 mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) ); 175 mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
199 break; 176 break;
200 case MAILIMF_FIELD_TO: 177 case MAILIMF_FIELD_TO:
201 mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) ); 178 mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
202 break; 179 break;
203 case MAILIMF_FIELD_CC: 180 case MAILIMF_FIELD_CC:
204 mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) ); 181 mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
205 break; 182 break;
206 case MAILIMF_FIELD_BCC: 183 case MAILIMF_FIELD_BCC:
207 mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) ); 184 mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
208 break; 185 break;
209 case MAILIMF_FIELD_SUBJECT: 186 case MAILIMF_FIELD_SUBJECT:
210 mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) ); 187 mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
211 break; 188 break;
212 case MAILIMF_FIELD_ORIG_DATE: 189 case MAILIMF_FIELD_ORIG_DATE:
213 mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) ); 190 mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
214 break; 191 break;
215 case MAILIMF_FIELD_MESSAGE_ID: 192 case MAILIMF_FIELD_MESSAGE_ID:
216 mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value)); 193 mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
217 break; 194 break;
218 case MAILIMF_FIELD_REFERENCES: 195 case MAILIMF_FIELD_REFERENCES:
219 refs = field->fld_data.fld_references; 196 refs = field->fld_data.fld_references;
220 if (refs && refs->mid_list && clist_count(refs->mid_list)) { 197 if (refs && refs->mid_list && clist_count(refs->mid_list)) {
221 char * text = (char*)refs->mid_list->first->data; 198 char * text = (char*)refs->mid_list->first->data;
222 mail->setReplyto(QString(text)); 199 mail->setReplyto(QString(text));
223 } 200 }
224 break; 201 break;
225 case MAILIMF_FIELD_KEYWORDS: 202 case MAILIMF_FIELD_KEYWORDS:
226 keys = field->fld_data.fld_keywords; 203 keys = field->fld_data.fld_keywords;
227 for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) { 204 for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
228 qDebug("Keyword: %s",(char*)cur->data); 205 qDebug("Keyword: %s",(char*)cur->data);
229 } 206 }
230 break; 207 break;
231 case MAILIMF_FIELD_OPTIONAL_FIELD: 208 case MAILIMF_FIELD_OPTIONAL_FIELD:
232 status = field->fld_data.fld_optional_field->fld_name; 209 status = field->fld_data.fld_optional_field->fld_name;
233 value = field->fld_data.fld_optional_field->fld_value; 210 value = field->fld_data.fld_optional_field->fld_value;
234 if (status.lower()=="status") { 211 if (status.lower()=="status") {
235 if (value.lower()=="ro") { 212 if (value.lower()=="ro") {
236 mFlags.setBit(FLAG_SEEN); 213 mFlags.setBit(FLAG_SEEN);
237 } 214 }
238 } else if (status.lower()=="x-status") { 215 } else if (status.lower()=="x-status") {
239 qDebug("X-Status: %s",value.latin1()); 216 qDebug("X-Status: %s",value.latin1());
240 if (value.lower()=="a") { 217 if (value.lower()=="a") {
241 mFlags.setBit(FLAG_ANSWERED); 218 mFlags.setBit(FLAG_ANSWERED);
242 } 219 }
243 } else { 220 } else {
244// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name, 221// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
245// field->fld_data.fld_optional_field->fld_value); 222// field->fld_data.fld_optional_field->fld_value);
246 } 223 }
247 break; 224 break;
248 default: 225 default:
249 qDebug("Non parsed field"); 226 qDebug("Non parsed field");
250 break; 227 break;
251 } 228 }
252 } 229 }
253 if (fields) mailimf_fields_free(fields); 230 if (fields) mailimf_fields_free(fields);
254 mail->setFlags(mFlags); 231 mail->setFlags(mFlags);
255 return mail; 232 return mail;
256} 233}
257 234
258QString POP3wrapper::parseDateTime( mailimf_date_time *date ) 235QString POP3wrapper::parseDateTime( mailimf_date_time *date )
259{ 236{
260 char tmp[23]; 237 char tmp[23];
261 238
262 snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i", 239 snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
263 date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone ); 240 date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
264 241
265 return QString( tmp ); 242 return QString( tmp );
266} 243}
267 244
268QString POP3wrapper::parseAddressList( mailimf_address_list *list ) 245QString POP3wrapper::parseAddressList( mailimf_address_list *list )
269{ 246{
270 QString result( "" ); 247 QString result( "" );
271 248
272 bool first = true; 249 bool first = true;
273 for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) { 250 for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
@@ -331,128 +308,270 @@ QString POP3wrapper::parseMailboxList( mailimf_mailbox_list *list )
331{ 308{
332 QString result( "" ); 309 QString result( "" );
333 310
334 bool first = true; 311 bool first = true;
335 for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) { 312 for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
336 mailimf_mailbox *box = (mailimf_mailbox *) current->data; 313 mailimf_mailbox *box = (mailimf_mailbox *) current->data;
337 314
338 if ( !first ) { 315 if ( !first ) {
339 result.append( "," ); 316 result.append( "," );
340 } else { 317 } else {
341 first = false; 318 first = false;
342 } 319 }
343 320
344 result.append( parseMailbox( box ) ); 321 result.append( parseMailbox( box ) );
345 } 322 }
346 323
347 return result; 324 return result;
348} 325}
349 326
350void POP3wrapper::login() 327void POP3wrapper::login()
351{ 328{
352 /* we'll hold the line */ 329 /* we'll hold the line */
353 if ( m_pop3 != NULL ) return; 330 if ( m_pop3 != NULL ) return;
354 331
355 const char *server, *user, *pass; 332 const char *server, *user, *pass;
356 uint16_t port; 333 uint16_t port;
357 int err = MAILPOP3_NO_ERROR; 334 int err = MAILPOP3_NO_ERROR;
358 335
359 server = account->getServer().latin1(); 336 server = account->getServer().latin1();
360 port = account->getPort().toUInt(); 337 port = account->getPort().toUInt();
361 338
362 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { 339 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
363 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); 340 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
364 login.show(); 341 login.show();
365 if ( QDialog::Accepted == login.exec() ) { 342 if ( QDialog::Accepted == login.exec() ) {
366 // ok 343 // ok
367 user = strdup( login.getUser().latin1() ); 344 user = strdup( login.getUser().latin1() );
368 pass = strdup( login.getPassword().latin1() ); 345 pass = strdup( login.getPassword().latin1() );
369 } else { 346 } else {
370 // cancel 347 // cancel
371 qDebug( "POP3: Login canceled" ); 348 qDebug( "POP3: Login canceled" );
372 return; 349 return;
373 } 350 }
374 } else { 351 } else {
375 user = account->getUser().latin1(); 352 user = account->getUser().latin1();
376 pass = account->getPassword().latin1(); 353 pass = account->getPassword().latin1();
377 } 354 }
378 355
379 m_pop3 = mailpop3_new( 200, &pop3_progress ); 356 m_pop3 = mailpop3_new( 200, &pop3_progress );
380 357
381 // connect 358 // connect
382 if (account->getSSL()) { 359 if (account->getSSL()) {
383 err = mailpop3_ssl_connect( m_pop3, (char*)server, port ); 360 err = mailpop3_ssl_connect( m_pop3, (char*)server, port );
384 } else { 361 } else {
385 err = mailpop3_socket_connect( m_pop3, (char*)server, port ); 362 err = mailpop3_socket_connect( m_pop3, (char*)server, port );
386 } 363 }
387 364
388 if ( err != MAILPOP3_NO_ERROR ) { 365 if ( err != MAILPOP3_NO_ERROR ) {
389 qDebug( "pop3: error connecting to %s\n reason: %s", server, 366 qDebug( "pop3: error connecting to %s\n reason: %s", server,
390 m_pop3->pop3_response ); 367 m_pop3->pop3_response );
391 mailpop3_free( m_pop3 ); 368 mailpop3_free( m_pop3 );
392 m_pop3 = NULL; 369 m_pop3 = NULL;
393 return; 370 return;
394 } 371 }
395 qDebug( "POP3: connected!" ); 372 qDebug( "POP3: connected!" );
396 373
397 // login 374 // login
398 // TODO: decide if apop or plain login should be used 375 // TODO: decide if apop or plain login should be used
399 err = mailpop3_login( m_pop3, (char *) user, (char *) pass ); 376 err = mailpop3_login( m_pop3, (char *) user, (char *) pass );
400 if ( err != MAILPOP3_NO_ERROR ) { 377 if ( err != MAILPOP3_NO_ERROR ) {
401 qDebug( "pop3: error logging in: %s", m_pop3->pop3_response ); 378 qDebug( "pop3: error logging in: %s", m_pop3->pop3_response );
402 logout(); 379 logout();
403 return; 380 return;
404 } 381 }
405 382
406 qDebug( "POP3: logged in!" ); 383 qDebug( "POP3: logged in!" );
407} 384}
408 385
409void POP3wrapper::logout() 386void POP3wrapper::logout()
410{ 387{
411 int err = MAILPOP3_NO_ERROR; 388 int err = MAILPOP3_NO_ERROR;
412 if ( m_pop3 == NULL ) return; 389 if ( m_pop3 == NULL ) return;
413 err = mailpop3_quit( m_pop3 ); 390 err = mailpop3_quit( m_pop3 );
414 mailpop3_free( m_pop3 ); 391 mailpop3_free( m_pop3 );
415 m_pop3 = NULL; 392 m_pop3 = NULL;
416} 393}
417 394
418 395
419QList<Folder>* POP3wrapper::listFolders() 396QList<Folder>* POP3wrapper::listFolders()
420{ 397{
421 /* TODO: integrate MH directories 398 /* TODO: integrate MH directories
422 but not before version 0.1 ;) 399 but not before version 0.1 ;)
423 */ 400 */
424 QList<Folder> * folders = new QList<Folder>(); 401 QList<Folder> * folders = new QList<Folder>();
425 folders->setAutoDelete( false ); 402 folders->setAutoDelete( false );
426 Folder*inb=new Folder("INBOX","/"); 403 Folder*inb=new Folder("INBOX","/");
427 folders->append(inb); 404 folders->append(inb);
428 return folders; 405 return folders;
429} 406}
430 407
431QString POP3wrapper::fetchTextPart(const RecMail&,const RecPart&) 408QString POP3wrapper::fetchTextPart(const RecMail&,const RecPart&)
432{ 409{
433 return ""; 410 return "";
434} 411}
435 412
436void POP3wrapper::deleteMail(const RecMail&mail) 413void POP3wrapper::deleteMail(const RecMail&mail)
437{ 414{
438 login(); 415 login();
439 if (!m_pop3) return; 416 if (!m_pop3) return;
440 int err = mailpop3_dele(m_pop3,mail.getNumber()); 417 int err = mailpop3_dele(m_pop3,mail.getNumber());
441 if (err != MAILPOP3_NO_ERROR) { 418 if (err != MAILPOP3_NO_ERROR) {
442 qDebug("error deleting mail"); 419 qDebug("error deleting mail");
443 } 420 }
444} 421}
445 422
446void POP3wrapper::answeredMail(const RecMail&) 423void POP3wrapper::answeredMail(const RecMail&)
447{ 424{
448} 425}
449 426
450encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&) 427encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&)
451{ 428{
452 return new encodedString(); 429 return new encodedString();
453} 430}
454 431
455encodedString* POP3wrapper::fetchRawPart(const RecMail&,const RecPart&) 432encodedString* POP3wrapper::fetchRawPart(const RecMail&,const RecPart&)
456{ 433{
457 return new encodedString(); 434 return new encodedString();
458} 435}
436
437void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec)
438{
439 if (current_rec >= 10) {
440 qDebug("too deep recursion!");
441 }
442 if (!message || !mime) {
443 return;
444 }
445 int r;
446 char*data = 0;
447 size_t len;
448 clistiter * cur = 0;
449 mailmime_single_fields fields;
450 int res;
451 QString b;
452 memset(&fields, 0, sizeof(struct mailmime_single_fields));
453 RecPart part;
454
455 if (mime->mm_mime_fields != NULL) {
456 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
457 mime->mm_content_type);
458 }
459 switch (mime->mm_type) {
460 case MAILMIME_SINGLE:
461 r = mailmessage_fetch_section(message,mime,&data,&len);
462 fillSingleBody(part,message,mime);
463 if (part.Type()=="text" && target.Bodytext().isNull()) {
464 encodedString*r = new encodedString();
465 r->setContent(data,len);
466 encodedString*res = decode_String(r,part.Encoding());
467 b = QString(res->Content());
468 delete r;
469 delete res;
470 target.setBodytext(b);
471 target.setDescription(part);
472 } else {
473 /* TODO: Add the content to a list and store it for later use */
474 if (data) free(data);
475 target.addPart(part);
476 }
477 break;
478 case MAILMIME_MULTIPLE:
479 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
480 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1);
481 }
482 break;
483 case MAILMIME_MESSAGE:
484 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
485 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1);
486 }
487 break;
488 }
489}
490
491QString POP3wrapper::getencoding(mailmime_mechanism*aEnc)
492{
493 QString enc="7bit";
494 if (!aEnc) return enc;
495 switch(aEnc->enc_type) {
496 case MAILMIME_MECHANISM_7BIT:
497 enc = "7bit";
498 break;
499 case MAILMIME_MECHANISM_8BIT:
500 enc = "8bit";
501 break;
502 case MAILMIME_MECHANISM_BINARY:
503 enc = "binary";
504 break;
505 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
506 enc = "quoted-printable";
507 break;
508 case MAILMIME_MECHANISM_BASE64:
509 enc = "base64";
510 break;
511 case MAILMIME_MECHANISM_TOKEN:
512 default:
513 if (aEnc->enc_token) {
514 enc = QString(aEnc->enc_token);
515 }
516 break;
517 }
518 return enc;
519}
520
521void POP3wrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
522{
523 if (!mime) {
524 return;
525 }
526 mailmime_content*type = mime->mm_content_type;
527 mailmime_field*field = 0;
528 clistcell*current;
529 if (!type) {
530 target.setType("text");
531 target.setSubtype("plain");
532 } else {
533 target.setSubtype(type->ct_subtype);
534 switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
535 case MAILMIME_DISCRETE_TYPE_TEXT:
536 target.setType("text");
537 break;
538 case MAILMIME_DISCRETE_TYPE_IMAGE:
539 target.setType("image");
540 break;
541 case MAILMIME_DISCRETE_TYPE_AUDIO:
542 target.setType("audio");
543 break;
544 case MAILMIME_DISCRETE_TYPE_VIDEO:
545 target.setType("video");
546 break;
547 case MAILMIME_DISCRETE_TYPE_APPLICATION:
548 target.setType("application");
549 break;
550 case MAILMIME_DISCRETE_TYPE_EXTENSION:
551 default:
552 if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
553 target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
554 }
555 break;
556 }
557 }
558 if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
559 for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
560 field = (mailmime_field*)current->data;
561 switch(field->fld_type) {
562 case MAILMIME_FIELD_TRANSFER_ENCODING:
563 target.setEncoding(getencoding(field->fld_data.fld_encoding));
564 break;
565 case MAILMIME_FIELD_ID:
566 target.setIdentifier(field->fld_data.fld_id);
567 break;
568 case MAILMIME_FIELD_DESCRIPTION:
569 target.setDescription(field->fld_data.fld_description);
570 break;
571 default:
572 break;
573 }
574 }
575 }
576 // TODO search the parameter list for unique id and so on
577}
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.h b/noncore/net/mail/libmailwrapper/pop3wrapper.h
index a05021c..4171a76 100644
--- a/noncore/net/mail/libmailwrapper/pop3wrapper.h
+++ b/noncore/net/mail/libmailwrapper/pop3wrapper.h
@@ -1,49 +1,57 @@
1#ifndef __POP3WRAPPER 1#ifndef __POP3WRAPPER
2#define __POP3WRAPPER 2#define __POP3WRAPPER
3 3
4#include "mailwrapper.h" 4#include "mailwrapper.h"
5#include "abstractmail.h" 5#include "abstractmail.h"
6 6
7class RecMail; 7class RecMail;
8class RecBody; 8class RecBody;
9class encodedString; 9class encodedString;
10struct mailpop3; 10struct mailpop3;
11struct mailmessage;
12struct mailmime;
13struct mailmime_mechanism;
11 14
12class POP3wrapper : public AbstractMail 15class POP3wrapper : public AbstractMail
13{ 16{
14 Q_OBJECT 17 Q_OBJECT
15 18
16public: 19public:
17 POP3wrapper( POP3account *a ); 20 POP3wrapper( POP3account *a );
18 virtual ~POP3wrapper(); 21 virtual ~POP3wrapper();
19 /* mailbox will be ignored */ 22 /* mailbox will be ignored */
20 virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); 23 virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
21 virtual QList<Folder>* listFolders(); 24 virtual QList<Folder>* listFolders();
22 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); 25 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
23 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); 26 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
24 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); 27 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
25 28
26 virtual void deleteMail(const RecMail&mail); 29 virtual void deleteMail(const RecMail&mail);
27 virtual void answeredMail(const RecMail&mail); 30 virtual void answeredMail(const RecMail&mail);
28 31
29 RecBody fetchBody( const RecMail &mail ); 32 RecBody fetchBody( const RecMail &mail );
30 static void pop3_progress( size_t current, size_t maximum ); 33 static void pop3_progress( size_t current, size_t maximum );
31 34
32protected: 35protected:
33 void login(); 36 void login();
34 void logout(); 37 void logout();
35 38
36 RecMail *parseHeader( const char *header ); 39 RecMail *parseHeader( const char *header );
37 RecBody parseMail( char *message ); 40 RecBody parseMail( char *message );
38 QString parseMailboxList( mailimf_mailbox_list *list ); 41 QString parseMailboxList( mailimf_mailbox_list *list );
39 QString parseMailbox( mailimf_mailbox *box ); 42 QString parseMailbox( mailimf_mailbox *box );
40 QString parseGroup( mailimf_group *group ); 43 QString parseGroup( mailimf_group *group );
41 QString parseAddressList( mailimf_address_list *list ); 44 QString parseAddressList( mailimf_address_list *list );
42 QString parseDateTime( mailimf_date_time *date ); 45 QString parseDateTime( mailimf_date_time *date );
46
47 static 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 QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
50
43 POP3account *account; 51 POP3account *account;
44 mailpop3 *m_pop3; 52 mailpop3 *m_pop3;
45 QString msgTempName; 53 QString msgTempName;
46 unsigned int last_msg_id; 54 unsigned int last_msg_id;
47}; 55};
48 56
49#endif 57#endif
diff --git a/noncore/net/mail/pop3wrapper.cpp b/noncore/net/mail/pop3wrapper.cpp
index b0b985c..2c2a42a 100644
--- a/noncore/net/mail/pop3wrapper.cpp
+++ b/noncore/net/mail/pop3wrapper.cpp
@@ -1,273 +1,250 @@
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{ 14{
15 account = a; 15 account = a;
16 m_pop3 = NULL; 16 m_pop3 = NULL;
17 msgTempName = a->getFileName()+"_msg_cache"; 17 msgTempName = a->getFileName()+"_msg_cache";
18 last_msg_id = 0; 18 last_msg_id = 0;
19} 19}
20 20
21POP3wrapper::~POP3wrapper() 21POP3wrapper::~POP3wrapper()
22{ 22{
23 logout(); 23 logout();
24 QFile msg_cache(msgTempName); 24 QFile msg_cache(msgTempName);
25 if (msg_cache.exists()) { 25 if (msg_cache.exists()) {
26 msg_cache.remove(); 26 msg_cache.remove();
27 } 27 }
28} 28}
29 29
30void POP3wrapper::pop3_progress( size_t current, size_t maximum ) 30void POP3wrapper::pop3_progress( size_t current, size_t maximum )
31{ 31{
32 //qDebug( "POP3: %i of %i", current, maximum ); 32 //qDebug( "POP3: %i of %i", current, maximum );
33} 33}
34 34
35RecBody POP3wrapper::fetchBody( const RecMail &mail ) 35RecBody POP3wrapper::fetchBody( const RecMail &mail )
36{ 36{
37 int err = MAILPOP3_NO_ERROR; 37 int err = MAILPOP3_NO_ERROR;
38 char *message; 38 char *message;
39 size_t length = 0; 39 size_t length = 0;
40 40
41 login(); 41 login();
42 if ( !m_pop3 ) { 42 if ( !m_pop3 ) {
43 return RecBody(); 43 return RecBody();
44 } 44 }
45 45
46 RecBody body; 46 RecBody body;
47 47
48 QFile msg_cache(msgTempName); 48 QFile msg_cache(msgTempName);
49 49
50 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) { 50 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) {
51 qDebug("Message to large: %i",mail.Msgsize()); 51 qDebug("Message to large: %i",mail.Msgsize());
52 return body; 52 return body;
53 } 53 }
54 if (mail.getNumber()!=last_msg_id) { 54 if (mail.getNumber()!=last_msg_id) {
55 if (msg_cache.exists()) { 55 if (msg_cache.exists()) {
56 msg_cache.remove(); 56 msg_cache.remove();
57 } 57 }
58 msg_cache.open(IO_ReadWrite|IO_Truncate); 58 msg_cache.open(IO_ReadWrite|IO_Truncate);
59 last_msg_id = mail.getNumber(); 59 last_msg_id = mail.getNumber();
60 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length ); 60 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length );
61 if ( err != MAILPOP3_NO_ERROR ) { 61 if ( err != MAILPOP3_NO_ERROR ) {
62 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() ); 62 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() );
63 last_msg_id = 0; 63 last_msg_id = 0;
64 return RecBody(); 64 return RecBody();
65 } 65 }
66 msg_cache.writeBlock(message,length); 66 msg_cache.writeBlock(message,length);
67 } else { 67 } else {
68 QString msg=""; 68 QString msg="";
69 msg_cache.open(IO_ReadOnly); 69 msg_cache.open(IO_ReadOnly);
70 message = new char[4096]; 70 message = new char[4096];
71 memset(message,0,4096); 71 memset(message,0,4096);
72 while (msg_cache.readBlock(message,4095)>0) { 72 while (msg_cache.readBlock(message,4095)>0) {
73 msg+=message; 73 msg+=message;
74 memset(message,0,4096); 74 memset(message,0,4096);
75 } 75 }
76 delete message; 76 delete message;
77 message = (char*)malloc(msg.length()+1*sizeof(char)); 77 message = (char*)malloc(msg.length()+1*sizeof(char));
78 memset(message,0,msg.length()+1); 78 memset(message,0,msg.length()+1);
79 memcpy(message,msg.latin1(),msg.length()); 79 memcpy(message,msg.latin1(),msg.length());
80 } 80 }
81 body = parseMail(message); 81 body = parseMail(message);
82 free(message); 82 free(message);
83 return body; 83 return body;
84} 84}
85 85
86RecBody POP3wrapper::parseMail( char *message ) 86RecBody POP3wrapper::parseMail( char *message )
87{ 87{
88 int err = MAILIMF_NO_ERROR; 88 int err = MAILIMF_NO_ERROR;
89 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ 89 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */
90 size_t curTok = 0; 90 size_t curTok = 0;
91 mailimf_message *result = 0; 91 mailimf_message *result = 0;
92 mailmessage * msg=0; 92 mailmessage * msg=0;
93 mailmime_single_fields fields;
94
95 /* is bound to msg and will be freed there */
93 struct mailmime * mime=0; 96 struct mailmime * mime=0;
94 struct mailmime_single_fields fields; 97
95
96 RecBody body; 98 RecBody body;
97 99
98 100
99 err = mailimf_message_parse( (char *) message, strlen( message ), &curTok, &result ); 101 err = mailimf_message_parse( (char *) message, strlen( message ), &curTok, &result );
100 if ( err != MAILIMF_NO_ERROR ) { 102 if ( err != MAILIMF_NO_ERROR ) {
101 if (result) mailimf_message_free(result); 103 if (result) mailimf_message_free(result);
102 return body; 104 return body;
103 } 105 }
104 106
105#if 0
106 char*body_msg = message; 107 char*body_msg = message;
107 if ( result && result->msg_body && result->msg_body->bd_text ) {
108 body_msg = (char*)result->msg_body->bd_text;
109 result->msg_body->bd_text = 0;
110 }
111
112 msg = mailmessage_new(); 108 msg = mailmessage_new();
113 mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg)); 109 mailmessage_init(msg, NULL, data_message_driver, 0, strlen(body_msg));
114 generic_message_t * msg_data; 110 generic_message_t * msg_data;
115 msg_data = (generic_message_t *)msg->msg_data; 111 msg_data = (generic_message_t *)msg->msg_data;
116 msg_data->msg_fetched = 1; 112 msg_data->msg_fetched = 1;
117 msg_data->msg_message = body_msg; 113 msg_data->msg_message = body_msg;
118 msg_data->msg_length = strlen(body_msg); 114 msg_data->msg_length = strlen(body_msg);
115
116
119 memset(&fields, 0, sizeof(struct mailmime_single_fields)); 117 memset(&fields, 0, sizeof(struct mailmime_single_fields));
120 err = mailmessage_get_bodystructure(msg,&mime); 118 err = mailmessage_get_bodystructure(msg,&mime);
119 traverseBody(body,msg,mime);
120
121 mailmessage_free(msg);
121 122
122 if (mime->mm_mime_fields != NULL) {
123 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
124 mime->mm_content_type);
125 }
126#endif
127
128#if 1
129 if ( result && result->msg_body && result->msg_body->bd_text ) {
130 qDebug( "POP3: bodytext found" );
131 // when curTok isn't set to 0 this line will fault! 'cause upper line faults!
132 body.setBodytext( QString( result->msg_body->bd_text ) );
133#if 0
134 curTok = 0;
135 mailmime_content*mresult = 0;
136 size_t index = 0;
137 mailmime_content_parse(result->msg_body->bd_text,
138 strlen(result->msg_body->bd_text),&index,&mresult);
139 if (mresult) {
140 mailmime_content_free(mresult);
141 }
142#endif
143 mailimf_message_free(result);
144 }
145#endif
146 return body; 123 return body;
147} 124}
148 125
149void POP3wrapper::listMessages(const QString &, QList<RecMail> &target ) 126void POP3wrapper::listMessages(const QString &, QList<RecMail> &target )
150{ 127{
151 int err = MAILPOP3_NO_ERROR; 128 int err = MAILPOP3_NO_ERROR;
152 char * header = 0; 129 char * header = 0;
153 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */ 130 /* these vars are used recurcive! set it to 0!!!!!!!!!!!!!!!!! */
154 size_t length = 0; 131 size_t length = 0;
155 carray * messages = 0; 132 carray * messages = 0;
156 133
157 login(); 134 login();
158 if (!m_pop3) return; 135 if (!m_pop3) return;
159 mailpop3_list( m_pop3, &messages ); 136 mailpop3_list( m_pop3, &messages );
160 137
161 for (unsigned int i = 0; i < carray_count(messages);++i) { 138 for (unsigned int i = 0; i < carray_count(messages);++i) {
162 mailpop3_msg_info *info; 139 mailpop3_msg_info *info;
163 err = mailpop3_get_msg_info(m_pop3,i+1,&info); 140 err = mailpop3_get_msg_info(m_pop3,i+1,&info);
164 if (info->msg_deleted) 141 if (info->msg_deleted)
165 continue; 142 continue;
166 err = mailpop3_header( m_pop3, info->msg_index, &header, &length ); 143 err = mailpop3_header( m_pop3, info->msg_index, &header, &length );
167 if ( err != MAILPOP3_NO_ERROR ) { 144 if ( err != MAILPOP3_NO_ERROR ) {
168 qDebug( "POP3: error retrieving header msgid: %i", info->msg_index ); 145 qDebug( "POP3: error retrieving header msgid: %i", info->msg_index );
169 free(header); 146 free(header);
170 return; 147 return;
171 } 148 }
172 RecMail *mail = parseHeader( header ); 149 RecMail *mail = parseHeader( header );
173 mail->setNumber( info->msg_index ); 150 mail->setNumber( info->msg_index );
174 mail->setWrapper(this); 151 mail->setWrapper(this);
175 mail->setMsgsize(info->msg_size); 152 mail->setMsgsize(info->msg_size);
176 target.append( mail ); 153 target.append( mail );
177 free(header); 154 free(header);
178 } 155 }
179} 156}
180 157
181RecMail *POP3wrapper::parseHeader( const char *header ) 158RecMail *POP3wrapper::parseHeader( const char *header )
182{ 159{
183 int err = MAILIMF_NO_ERROR; 160 int err = MAILIMF_NO_ERROR;
184 size_t curTok = 0; 161 size_t curTok = 0;
185 RecMail *mail = new RecMail(); 162 RecMail *mail = new RecMail();
186 mailimf_fields *fields; 163 mailimf_fields *fields;
187 mailimf_references * refs; 164 mailimf_references * refs;
188 mailimf_keywords*keys; 165 mailimf_keywords*keys;
189 QString status; 166 QString status;
190 QString value; 167 QString value;
191 QBitArray mFlags(7); 168 QBitArray mFlags(7);
192 169
193 err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields ); 170 err = mailimf_fields_parse( (char *) header, strlen( header ), &curTok, &fields );
194 for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) { 171 for ( clistiter *current = clist_begin( fields->fld_list ); current != NULL; current = current->next ) {
195 mailimf_field *field = (mailimf_field *) current->data; 172 mailimf_field *field = (mailimf_field *) current->data;
196 switch ( field->fld_type ) { 173 switch ( field->fld_type ) {
197 case MAILIMF_FIELD_FROM: 174 case MAILIMF_FIELD_FROM:
198 mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) ); 175 mail->setFrom( parseMailboxList( field->fld_data.fld_from->frm_mb_list ) );
199 break; 176 break;
200 case MAILIMF_FIELD_TO: 177 case MAILIMF_FIELD_TO:
201 mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) ); 178 mail->setTo( parseAddressList( field->fld_data.fld_to->to_addr_list ) );
202 break; 179 break;
203 case MAILIMF_FIELD_CC: 180 case MAILIMF_FIELD_CC:
204 mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) ); 181 mail->setCC( parseAddressList( field->fld_data.fld_cc->cc_addr_list ) );
205 break; 182 break;
206 case MAILIMF_FIELD_BCC: 183 case MAILIMF_FIELD_BCC:
207 mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) ); 184 mail->setBcc( parseAddressList( field->fld_data.fld_bcc->bcc_addr_list ) );
208 break; 185 break;
209 case MAILIMF_FIELD_SUBJECT: 186 case MAILIMF_FIELD_SUBJECT:
210 mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) ); 187 mail->setSubject(convert_String( field->fld_data.fld_subject->sbj_value ) );
211 break; 188 break;
212 case MAILIMF_FIELD_ORIG_DATE: 189 case MAILIMF_FIELD_ORIG_DATE:
213 mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) ); 190 mail->setDate( parseDateTime( field->fld_data.fld_orig_date->dt_date_time ) );
214 break; 191 break;
215 case MAILIMF_FIELD_MESSAGE_ID: 192 case MAILIMF_FIELD_MESSAGE_ID:
216 mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value)); 193 mail->setMsgid(QString(field->fld_data.fld_message_id->mid_value));
217 break; 194 break;
218 case MAILIMF_FIELD_REFERENCES: 195 case MAILIMF_FIELD_REFERENCES:
219 refs = field->fld_data.fld_references; 196 refs = field->fld_data.fld_references;
220 if (refs && refs->mid_list && clist_count(refs->mid_list)) { 197 if (refs && refs->mid_list && clist_count(refs->mid_list)) {
221 char * text = (char*)refs->mid_list->first->data; 198 char * text = (char*)refs->mid_list->first->data;
222 mail->setReplyto(QString(text)); 199 mail->setReplyto(QString(text));
223 } 200 }
224 break; 201 break;
225 case MAILIMF_FIELD_KEYWORDS: 202 case MAILIMF_FIELD_KEYWORDS:
226 keys = field->fld_data.fld_keywords; 203 keys = field->fld_data.fld_keywords;
227 for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) { 204 for (clistcell*cur = clist_begin(keys->kw_list);cur!=0;cur=clist_next(cur)) {
228 qDebug("Keyword: %s",(char*)cur->data); 205 qDebug("Keyword: %s",(char*)cur->data);
229 } 206 }
230 break; 207 break;
231 case MAILIMF_FIELD_OPTIONAL_FIELD: 208 case MAILIMF_FIELD_OPTIONAL_FIELD:
232 status = field->fld_data.fld_optional_field->fld_name; 209 status = field->fld_data.fld_optional_field->fld_name;
233 value = field->fld_data.fld_optional_field->fld_value; 210 value = field->fld_data.fld_optional_field->fld_value;
234 if (status.lower()=="status") { 211 if (status.lower()=="status") {
235 if (value.lower()=="ro") { 212 if (value.lower()=="ro") {
236 mFlags.setBit(FLAG_SEEN); 213 mFlags.setBit(FLAG_SEEN);
237 } 214 }
238 } else if (status.lower()=="x-status") { 215 } else if (status.lower()=="x-status") {
239 qDebug("X-Status: %s",value.latin1()); 216 qDebug("X-Status: %s",value.latin1());
240 if (value.lower()=="a") { 217 if (value.lower()=="a") {
241 mFlags.setBit(FLAG_ANSWERED); 218 mFlags.setBit(FLAG_ANSWERED);
242 } 219 }
243 } else { 220 } else {
244// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name, 221// qDebug("Optionales feld: %s -> %s)",field->fld_data.fld_optional_field->fld_name,
245// field->fld_data.fld_optional_field->fld_value); 222// field->fld_data.fld_optional_field->fld_value);
246 } 223 }
247 break; 224 break;
248 default: 225 default:
249 qDebug("Non parsed field"); 226 qDebug("Non parsed field");
250 break; 227 break;
251 } 228 }
252 } 229 }
253 if (fields) mailimf_fields_free(fields); 230 if (fields) mailimf_fields_free(fields);
254 mail->setFlags(mFlags); 231 mail->setFlags(mFlags);
255 return mail; 232 return mail;
256} 233}
257 234
258QString POP3wrapper::parseDateTime( mailimf_date_time *date ) 235QString POP3wrapper::parseDateTime( mailimf_date_time *date )
259{ 236{
260 char tmp[23]; 237 char tmp[23];
261 238
262 snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i", 239 snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
263 date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone ); 240 date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
264 241
265 return QString( tmp ); 242 return QString( tmp );
266} 243}
267 244
268QString POP3wrapper::parseAddressList( mailimf_address_list *list ) 245QString POP3wrapper::parseAddressList( mailimf_address_list *list )
269{ 246{
270 QString result( "" ); 247 QString result( "" );
271 248
272 bool first = true; 249 bool first = true;
273 for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) { 250 for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
@@ -331,128 +308,270 @@ QString POP3wrapper::parseMailboxList( mailimf_mailbox_list *list )
331{ 308{
332 QString result( "" ); 309 QString result( "" );
333 310
334 bool first = true; 311 bool first = true;
335 for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) { 312 for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
336 mailimf_mailbox *box = (mailimf_mailbox *) current->data; 313 mailimf_mailbox *box = (mailimf_mailbox *) current->data;
337 314
338 if ( !first ) { 315 if ( !first ) {
339 result.append( "," ); 316 result.append( "," );
340 } else { 317 } else {
341 first = false; 318 first = false;
342 } 319 }
343 320
344 result.append( parseMailbox( box ) ); 321 result.append( parseMailbox( box ) );
345 } 322 }
346 323
347 return result; 324 return result;
348} 325}
349 326
350void POP3wrapper::login() 327void POP3wrapper::login()
351{ 328{
352 /* we'll hold the line */ 329 /* we'll hold the line */
353 if ( m_pop3 != NULL ) return; 330 if ( m_pop3 != NULL ) return;
354 331
355 const char *server, *user, *pass; 332 const char *server, *user, *pass;
356 uint16_t port; 333 uint16_t port;
357 int err = MAILPOP3_NO_ERROR; 334 int err = MAILPOP3_NO_ERROR;
358 335
359 server = account->getServer().latin1(); 336 server = account->getServer().latin1();
360 port = account->getPort().toUInt(); 337 port = account->getPort().toUInt();
361 338
362 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { 339 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
363 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); 340 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
364 login.show(); 341 login.show();
365 if ( QDialog::Accepted == login.exec() ) { 342 if ( QDialog::Accepted == login.exec() ) {
366 // ok 343 // ok
367 user = strdup( login.getUser().latin1() ); 344 user = strdup( login.getUser().latin1() );
368 pass = strdup( login.getPassword().latin1() ); 345 pass = strdup( login.getPassword().latin1() );
369 } else { 346 } else {
370 // cancel 347 // cancel
371 qDebug( "POP3: Login canceled" ); 348 qDebug( "POP3: Login canceled" );
372 return; 349 return;
373 } 350 }
374 } else { 351 } else {
375 user = account->getUser().latin1(); 352 user = account->getUser().latin1();
376 pass = account->getPassword().latin1(); 353 pass = account->getPassword().latin1();
377 } 354 }
378 355
379 m_pop3 = mailpop3_new( 200, &pop3_progress ); 356 m_pop3 = mailpop3_new( 200, &pop3_progress );
380 357
381 // connect 358 // connect
382 if (account->getSSL()) { 359 if (account->getSSL()) {
383 err = mailpop3_ssl_connect( m_pop3, (char*)server, port ); 360 err = mailpop3_ssl_connect( m_pop3, (char*)server, port );
384 } else { 361 } else {
385 err = mailpop3_socket_connect( m_pop3, (char*)server, port ); 362 err = mailpop3_socket_connect( m_pop3, (char*)server, port );
386 } 363 }
387 364
388 if ( err != MAILPOP3_NO_ERROR ) { 365 if ( err != MAILPOP3_NO_ERROR ) {
389 qDebug( "pop3: error connecting to %s\n reason: %s", server, 366 qDebug( "pop3: error connecting to %s\n reason: %s", server,
390 m_pop3->pop3_response ); 367 m_pop3->pop3_response );
391 mailpop3_free( m_pop3 ); 368 mailpop3_free( m_pop3 );
392 m_pop3 = NULL; 369 m_pop3 = NULL;
393 return; 370 return;
394 } 371 }
395 qDebug( "POP3: connected!" ); 372 qDebug( "POP3: connected!" );
396 373
397 // login 374 // login
398 // TODO: decide if apop or plain login should be used 375 // TODO: decide if apop or plain login should be used
399 err = mailpop3_login( m_pop3, (char *) user, (char *) pass ); 376 err = mailpop3_login( m_pop3, (char *) user, (char *) pass );
400 if ( err != MAILPOP3_NO_ERROR ) { 377 if ( err != MAILPOP3_NO_ERROR ) {
401 qDebug( "pop3: error logging in: %s", m_pop3->pop3_response ); 378 qDebug( "pop3: error logging in: %s", m_pop3->pop3_response );
402 logout(); 379 logout();
403 return; 380 return;
404 } 381 }
405 382
406 qDebug( "POP3: logged in!" ); 383 qDebug( "POP3: logged in!" );
407} 384}
408 385
409void POP3wrapper::logout() 386void POP3wrapper::logout()
410{ 387{
411 int err = MAILPOP3_NO_ERROR; 388 int err = MAILPOP3_NO_ERROR;
412 if ( m_pop3 == NULL ) return; 389 if ( m_pop3 == NULL ) return;
413 err = mailpop3_quit( m_pop3 ); 390 err = mailpop3_quit( m_pop3 );
414 mailpop3_free( m_pop3 ); 391 mailpop3_free( m_pop3 );
415 m_pop3 = NULL; 392 m_pop3 = NULL;
416} 393}
417 394
418 395
419QList<Folder>* POP3wrapper::listFolders() 396QList<Folder>* POP3wrapper::listFolders()
420{ 397{
421 /* TODO: integrate MH directories 398 /* TODO: integrate MH directories
422 but not before version 0.1 ;) 399 but not before version 0.1 ;)
423 */ 400 */
424 QList<Folder> * folders = new QList<Folder>(); 401 QList<Folder> * folders = new QList<Folder>();
425 folders->setAutoDelete( false ); 402 folders->setAutoDelete( false );
426 Folder*inb=new Folder("INBOX","/"); 403 Folder*inb=new Folder("INBOX","/");
427 folders->append(inb); 404 folders->append(inb);
428 return folders; 405 return folders;
429} 406}
430 407
431QString POP3wrapper::fetchTextPart(const RecMail&,const RecPart&) 408QString POP3wrapper::fetchTextPart(const RecMail&,const RecPart&)
432{ 409{
433 return ""; 410 return "";
434} 411}
435 412
436void POP3wrapper::deleteMail(const RecMail&mail) 413void POP3wrapper::deleteMail(const RecMail&mail)
437{ 414{
438 login(); 415 login();
439 if (!m_pop3) return; 416 if (!m_pop3) return;
440 int err = mailpop3_dele(m_pop3,mail.getNumber()); 417 int err = mailpop3_dele(m_pop3,mail.getNumber());
441 if (err != MAILPOP3_NO_ERROR) { 418 if (err != MAILPOP3_NO_ERROR) {
442 qDebug("error deleting mail"); 419 qDebug("error deleting mail");
443 } 420 }
444} 421}
445 422
446void POP3wrapper::answeredMail(const RecMail&) 423void POP3wrapper::answeredMail(const RecMail&)
447{ 424{
448} 425}
449 426
450encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&) 427encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&)
451{ 428{
452 return new encodedString(); 429 return new encodedString();
453} 430}
454 431
455encodedString* POP3wrapper::fetchRawPart(const RecMail&,const RecPart&) 432encodedString* POP3wrapper::fetchRawPart(const RecMail&,const RecPart&)
456{ 433{
457 return new encodedString(); 434 return new encodedString();
458} 435}
436
437void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec)
438{
439 if (current_rec >= 10) {
440 qDebug("too deep recursion!");
441 }
442 if (!message || !mime) {
443 return;
444 }
445 int r;
446 char*data = 0;
447 size_t len;
448 clistiter * cur = 0;
449 mailmime_single_fields fields;
450 int res;
451 QString b;
452 memset(&fields, 0, sizeof(struct mailmime_single_fields));
453 RecPart part;
454
455 if (mime->mm_mime_fields != NULL) {
456 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
457 mime->mm_content_type);
458 }
459 switch (mime->mm_type) {
460 case MAILMIME_SINGLE:
461 r = mailmessage_fetch_section(message,mime,&data,&len);
462 fillSingleBody(part,message,mime);
463 if (part.Type()=="text" && target.Bodytext().isNull()) {
464 encodedString*r = new encodedString();
465 r->setContent(data,len);
466 encodedString*res = decode_String(r,part.Encoding());
467 b = QString(res->Content());
468 delete r;
469 delete res;
470 target.setBodytext(b);
471 target.setDescription(part);
472 } else {
473 /* TODO: Add the content to a list and store it for later use */
474 if (data) free(data);
475 target.addPart(part);
476 }
477 break;
478 case MAILMIME_MULTIPLE:
479 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
480 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1);
481 }
482 break;
483 case MAILMIME_MESSAGE:
484 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
485 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1);
486 }
487 break;
488 }
489}
490
491QString POP3wrapper::getencoding(mailmime_mechanism*aEnc)
492{
493 QString enc="7bit";
494 if (!aEnc) return enc;
495 switch(aEnc->enc_type) {
496 case MAILMIME_MECHANISM_7BIT:
497 enc = "7bit";
498 break;
499 case MAILMIME_MECHANISM_8BIT:
500 enc = "8bit";
501 break;
502 case MAILMIME_MECHANISM_BINARY:
503 enc = "binary";
504 break;
505 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
506 enc = "quoted-printable";
507 break;
508 case MAILMIME_MECHANISM_BASE64:
509 enc = "base64";
510 break;
511 case MAILMIME_MECHANISM_TOKEN:
512 default:
513 if (aEnc->enc_token) {
514 enc = QString(aEnc->enc_token);
515 }
516 break;
517 }
518 return enc;
519}
520
521void POP3wrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
522{
523 if (!mime) {
524 return;
525 }
526 mailmime_content*type = mime->mm_content_type;
527 mailmime_field*field = 0;
528 clistcell*current;
529 if (!type) {
530 target.setType("text");
531 target.setSubtype("plain");
532 } else {
533 target.setSubtype(type->ct_subtype);
534 switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
535 case MAILMIME_DISCRETE_TYPE_TEXT:
536 target.setType("text");
537 break;
538 case MAILMIME_DISCRETE_TYPE_IMAGE:
539 target.setType("image");
540 break;
541 case MAILMIME_DISCRETE_TYPE_AUDIO:
542 target.setType("audio");
543 break;
544 case MAILMIME_DISCRETE_TYPE_VIDEO:
545 target.setType("video");
546 break;
547 case MAILMIME_DISCRETE_TYPE_APPLICATION:
548 target.setType("application");
549 break;
550 case MAILMIME_DISCRETE_TYPE_EXTENSION:
551 default:
552 if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
553 target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
554 }
555 break;
556 }
557 }
558 if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
559 for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
560 field = (mailmime_field*)current->data;
561 switch(field->fld_type) {
562 case MAILMIME_FIELD_TRANSFER_ENCODING:
563 target.setEncoding(getencoding(field->fld_data.fld_encoding));
564 break;
565 case MAILMIME_FIELD_ID:
566 target.setIdentifier(field->fld_data.fld_id);
567 break;
568 case MAILMIME_FIELD_DESCRIPTION:
569 target.setDescription(field->fld_data.fld_description);
570 break;
571 default:
572 break;
573 }
574 }
575 }
576 // TODO search the parameter list for unique id and so on
577}
diff --git a/noncore/net/mail/pop3wrapper.h b/noncore/net/mail/pop3wrapper.h
index a05021c..4171a76 100644
--- a/noncore/net/mail/pop3wrapper.h
+++ b/noncore/net/mail/pop3wrapper.h
@@ -1,49 +1,57 @@
1#ifndef __POP3WRAPPER 1#ifndef __POP3WRAPPER
2#define __POP3WRAPPER 2#define __POP3WRAPPER
3 3
4#include "mailwrapper.h" 4#include "mailwrapper.h"
5#include "abstractmail.h" 5#include "abstractmail.h"
6 6
7class RecMail; 7class RecMail;
8class RecBody; 8class RecBody;
9class encodedString; 9class encodedString;
10struct mailpop3; 10struct mailpop3;
11struct mailmessage;
12struct mailmime;
13struct mailmime_mechanism;
11 14
12class POP3wrapper : public AbstractMail 15class POP3wrapper : public AbstractMail
13{ 16{
14 Q_OBJECT 17 Q_OBJECT
15 18
16public: 19public:
17 POP3wrapper( POP3account *a ); 20 POP3wrapper( POP3account *a );
18 virtual ~POP3wrapper(); 21 virtual ~POP3wrapper();
19 /* mailbox will be ignored */ 22 /* mailbox will be ignored */
20 virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); 23 virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
21 virtual QList<Folder>* listFolders(); 24 virtual QList<Folder>* listFolders();
22 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); 25 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
23 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); 26 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
24 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); 27 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
25 28
26 virtual void deleteMail(const RecMail&mail); 29 virtual void deleteMail(const RecMail&mail);
27 virtual void answeredMail(const RecMail&mail); 30 virtual void answeredMail(const RecMail&mail);
28 31
29 RecBody fetchBody( const RecMail &mail ); 32 RecBody fetchBody( const RecMail &mail );
30 static void pop3_progress( size_t current, size_t maximum ); 33 static void pop3_progress( size_t current, size_t maximum );
31 34
32protected: 35protected:
33 void login(); 36 void login();
34 void logout(); 37 void logout();
35 38
36 RecMail *parseHeader( const char *header ); 39 RecMail *parseHeader( const char *header );
37 RecBody parseMail( char *message ); 40 RecBody parseMail( char *message );
38 QString parseMailboxList( mailimf_mailbox_list *list ); 41 QString parseMailboxList( mailimf_mailbox_list *list );
39 QString parseMailbox( mailimf_mailbox *box ); 42 QString parseMailbox( mailimf_mailbox *box );
40 QString parseGroup( mailimf_group *group ); 43 QString parseGroup( mailimf_group *group );
41 QString parseAddressList( mailimf_address_list *list ); 44 QString parseAddressList( mailimf_address_list *list );
42 QString parseDateTime( mailimf_date_time *date ); 45 QString parseDateTime( mailimf_date_time *date );
46
47 static 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 QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
50
43 POP3account *account; 51 POP3account *account;
44 mailpop3 *m_pop3; 52 mailpop3 *m_pop3;
45 QString msgTempName; 53 QString msgTempName;
46 unsigned int last_msg_id; 54 unsigned int last_msg_id;
47}; 55};
48 56
49#endif 57#endif