summaryrefslogtreecommitdiff
path: root/noncore/net/mail/libmailwrapper/genericwrapper.cpp
Unidiff
Diffstat (limited to 'noncore/net/mail/libmailwrapper/genericwrapper.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/libmailwrapper/genericwrapper.cpp393
1 files changed, 393 insertions, 0 deletions
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}