summaryrefslogtreecommitdiffabout
path: root/kmicromail/libmailwrapper/generatemail.cpp
Unidiff
Diffstat (limited to 'kmicromail/libmailwrapper/generatemail.cpp') (more/less context) (show whitespace changes)
-rw-r--r--kmicromail/libmailwrapper/generatemail.cpp460
1 files changed, 460 insertions, 0 deletions
diff --git a/kmicromail/libmailwrapper/generatemail.cpp b/kmicromail/libmailwrapper/generatemail.cpp
new file mode 100644
index 0000000..49315ba
--- a/dev/null
+++ b/kmicromail/libmailwrapper/generatemail.cpp
@@ -0,0 +1,460 @@
1#include "generatemail.h"
2#include "mailwrapper.h"
3
4#include <libetpan/libetpan.h>
5
6//#include <qt.h>
7
8#include <stdlib.h>
9#include <qfileinfo.h>
10
11using namespace Opie::Core;
12const char* Generatemail::USER_AGENT="OpieMail v0.6";
13
14Generatemail::Generatemail()
15{
16}
17
18Generatemail::~Generatemail()
19{
20}
21
22void Generatemail::addRcpts( clist *list, mailimf_address_list *addr_list ) {
23 clistiter *it, *it2;
24
25 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
26 mailimf_address *addr;
27 addr = (mailimf_address *) it->data;
28
29 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
30 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
31 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
32 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
33 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
34 mailimf_mailbox *mbox;
35 mbox = (mailimf_mailbox *) it2->data;
36 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
37 }
38 }
39 }
40}
41
42char *Generatemail::getFrom( mailimf_field *ffrom) {
43 char *from = NULL;
44 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
45 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
46 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
47 clistiter *it;
48 for ( it = clist_begin( cl ); it; it = it->next ) {
49 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
50 from = strdup( mb->mb_addr_spec );
51 }
52 }
53
54 return from;
55}
56
57char *Generatemail::getFrom( mailmime *mail ) {
58 /* no need to delete - its just a pointer to structure content */
59 mailimf_field *ffrom = 0;
60 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
61 return getFrom(ffrom);
62}
63
64mailimf_field *Generatemail::getField( mailimf_fields *fields, int type ) {
65 mailimf_field *field;
66 clistiter *it;
67
68 it = clist_begin( fields->fld_list );
69 while ( it ) {
70 field = (mailimf_field *) it->data;
71 if ( field->fld_type == type ) {
72 return field;
73 }
74 it = it->next;
75 }
76
77 return NULL;
78}
79
80mailimf_address_list *Generatemail::parseAddresses(const QString&addr ) {
81 mailimf_address_list *addresses;
82
83 if ( addr.isEmpty() )
84 return NULL;
85
86 addresses = mailimf_address_list_new_empty();
87
88 bool literal_open = false;
89 unsigned int startpos = 0;
90 QStringList list;
91 QString s;
92 unsigned int i = 0;
93 for (; i < addr.length();++i) {
94 switch (addr[i]) {
95 case '\"':
96 literal_open = !literal_open;
97 break;
98 case ',':
99 if (!literal_open) {
100 s = addr.mid(startpos,i-startpos);
101 if (!s.isEmpty()) {
102 list.append(s);
103 }
104 // !!!! this is a MUST BE!
105 startpos = ++i;
106 }
107 break;
108 default:
109 break;
110 }
111 }
112 s = addr.mid(startpos,i-startpos);
113 if (!s.isEmpty()) {
114 list.append(s);
115 }
116 QStringList::Iterator it;
117 for ( it = list.begin(); it != list.end(); it++ ) {
118 int err = mailimf_address_list_add_parse( addresses, (char*)(*it).latin1() );
119 if ( err != MAILIMF_NO_ERROR ) {
120 qDebug(" Error parsing"); // *it
121 } else {
122 }
123 }
124 return addresses;
125}
126
127mailmime *Generatemail::buildFilePart(const QString&filename,const QString&mimetype,const QString&TextContent ) {
128 mailmime * filePart = 0;
129 mailmime_fields * fields = 0;
130 mailmime_content * content = 0;
131 mailmime_parameter * param = 0;
132 char*name = 0;
133 char*file = 0;
134 int err;
135
136 int pos = filename.findRev( '/' );
137
138 if (filename.length()>0) {
139 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
140 name = strdup( tmp.latin1() ); // just filename
141 file = strdup( filename.latin1() ); // full name with path
142 }
143
144 int disptype = MAILMIME_DISPOSITION_TYPE_ATTACHMENT;
145 int mechanism = MAILMIME_MECHANISM_BASE64;
146
147 if ( mimetype.startsWith( "text/" ) ) {
148 param = mailmime_parameter_new( strdup( "charset" ),
149 strdup( "iso-8859-1" ) );
150 mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
151 }
152
153 fields = mailmime_fields_new_filename(
154 disptype, name,
155 mechanism );
156 content = mailmime_content_new_with_str( (char*)mimetype.latin1() );
157 if (content!=0 && fields != 0) {
158 if (param) {
159 clist_append(content->ct_parameters,param);
160 param = 0;
161 }
162 if (filename.length()>0) {
163 QFileInfo f(filename);
164 param = mailmime_parameter_new(strdup("name"),strdup(f.fileName().latin1()));
165 clist_append(content->ct_parameters,param);
166 param = 0;
167 }
168 filePart = mailmime_new_empty( content, fields );
169 }
170 if (filePart) {
171 if (filename.length()>0) {
172 err = mailmime_set_body_file( filePart, file );
173 } else {
174 err = mailmime_set_body_text(filePart,strdup(TextContent.data()),TextContent.length());
175 }
176 if (err != MAILIMF_NO_ERROR) {
177 qDebug("Error setting body with file ");
178 mailmime_free( filePart );
179 filePart = 0;
180 }
181 }
182
183 if (!filePart) {
184 if ( param != NULL ) {
185 mailmime_parameter_free( param );
186 }
187 if (content) {
188 mailmime_content_free( content );
189 }
190 if (fields) {
191 mailmime_fields_free( fields );
192 } else {
193 if (name) {
194 free( name );
195 }
196 if (file) {
197 free( file );
198 }
199 }
200 }
201 return filePart; // Success :)
202
203}
204
205void Generatemail::addFileParts( mailmime *message,const QList<Attachment>&files ) {
206 const Attachment *it;
207 unsigned int count = files.count();
208 for ( unsigned int i = 0; i < count; ++i ) {
209 mailmime *filePart;
210 int err;
211 it = ((QList<Attachment>)files).at(i);
212
213 filePart = buildFilePart( it->getFileName(), it->getMimeType(),"" );
214 if ( filePart == NULL ) {
215 continue;
216 }
217 err = mailmime_smart_add_part( message, filePart );
218 if ( err != MAILIMF_NO_ERROR ) {
219 mailmime_free( filePart );
220 }
221 }
222}
223
224mailmime *Generatemail::buildTxtPart(const QString&str ) {
225 mailmime *txtPart;
226 mailmime_fields *fields;
227 mailmime_content *content;
228 mailmime_parameter *param;
229 int err;
230
231 param = mailmime_parameter_new( strdup( "charset" ),
232 strdup( "iso-8859-1" ) );
233 if ( param == NULL )
234 goto err_free;
235
236 content = mailmime_content_new_with_str( "text/plain" );
237 if ( content == NULL )
238 goto err_free_param;
239
240 err = clist_append( content->ct_parameters, param );
241 if ( err != MAILIMF_NO_ERROR )
242 goto err_free_content;
243
244 fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
245 if ( fields == NULL )
246 goto err_free_content;
247
248 txtPart = mailmime_new_empty( content, fields );
249 if ( txtPart == NULL )
250 goto err_free_fields;
251
252 err = mailmime_set_body_text( txtPart, (char*)str.data(), str.length() );
253 if ( err != MAILIMF_NO_ERROR )
254 goto err_free_txtPart;
255
256 return txtPart; // Success :)
257
258err_free_txtPart:
259 mailmime_free( txtPart );
260err_free_fields:
261 mailmime_fields_free( fields );
262err_free_content:
263 mailmime_content_free( content );
264err_free_param:
265 mailmime_parameter_free( param );
266err_free:
267 ;
268
269 return NULL; // Error :(
270}
271
272mailimf_mailbox *Generatemail::newMailbox(const QString&name, const QString&mail ) {
273 return mailimf_mailbox_new( strdup( name.latin1() ),
274 strdup( mail.latin1() ) );
275}
276
277mailimf_fields *Generatemail::createImfFields(const Opie::Core::OSmartPointer<Mail>&mail )
278{
279 mailimf_fields *fields = NULL;
280 mailimf_field *xmailer = NULL;
281 mailimf_mailbox *sender=0,*fromBox=0;
282 mailimf_mailbox_list *from=0;
283 mailimf_address_list *to=0, *cc=0, *bcc=0, *reply=0;
284 clist*in_reply_to = 0;
285 char *subject = strdup( mail->getSubject().latin1() );
286 int err;
287 int res = 1;
288
289 sender = newMailbox( mail->getName(), mail->getMail() );
290 if ( sender == NULL ) {
291 res = 0;
292 }
293
294 if (res) {
295 fromBox = newMailbox( mail->getName(), mail->getMail() );
296 }
297 if ( fromBox == NULL ) {
298 res = 0;
299 }
300
301 if (res) {
302 from = mailimf_mailbox_list_new_empty();
303 }
304 if ( from == NULL ) {
305 res = 0;
306 }
307
308 if (res && from) {
309 err = mailimf_mailbox_list_add( from, fromBox );
310 if ( err != MAILIMF_NO_ERROR ) {
311 res = 0;
312 }
313 }
314
315 if (res) to = parseAddresses( mail->getTo() );
316 if (res) cc = parseAddresses( mail->getCC() );
317 if (res) bcc = parseAddresses( mail->getBCC() );
318 if (res) reply = parseAddresses( mail->getReply() );
319
320 if (res && mail->Inreply().count()>0) {
321 in_reply_to = clist_new();
322 char*c_reply;
323 unsigned int nsize = 0;
324 for (QStringList::ConstIterator it=mail->Inreply().begin();
325 it != mail->Inreply().end();++it) {
326 if ((*it).isEmpty())
327 continue;
328 QString h((*it));
329 while (h.length()>0 && h[0]=='<') {
330 h.remove(0,1);
331 }
332 while (h.length()>0 && h[h.length()-1]=='>') {
333 h.remove(h.length()-1,1);
334 }
335 if (h.isEmpty()) continue;
336 nsize = strlen(h.latin1());
337 /* yes! must be malloc! */
338 c_reply = (char*)malloc( (nsize+1)*sizeof(char));
339 memset(c_reply,0,nsize+1);
340 memcpy(c_reply,h.latin1(),nsize);
341 clist_append(in_reply_to,c_reply);
342 }
343 }
344
345 if (res) {
346 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
347 in_reply_to, NULL, subject );
348 if ( fields == NULL ) {
349 res = 0;
350 }
351 }
352 if (res) xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
353 strdup( USER_AGENT ) );
354 if ( xmailer == NULL ) {
355 res = 0;
356 } else {
357 err = mailimf_fields_add( fields, xmailer );
358 if ( err != MAILIMF_NO_ERROR ) {
359 res = 0;
360 }
361 }
362 if (!res ) {
363 if (xmailer) {
364 mailimf_field_free( xmailer );
365 xmailer = NULL;
366 }
367 if (fields) {
368 mailimf_fields_free( fields );
369 fields = NULL;
370 } else {
371 if (reply)
372 mailimf_address_list_free( reply );
373 if (bcc)
374 mailimf_address_list_free( bcc );
375 if (cc)
376 mailimf_address_list_free( cc );
377 if (to)
378 mailimf_address_list_free( to );
379 if (fromBox) {
380 mailimf_mailbox_free( fromBox );
381 } else if (from) {
382 mailimf_mailbox_list_free( from );
383 }
384 if (sender) {
385 mailimf_mailbox_free( sender );
386 }
387 if (subject) {
388 free( subject );
389 }
390 }
391 }
392 return fields;
393}
394
395mailmime *Generatemail::createMimeMail(const Opie::Core::OSmartPointer<Mail> &mail ) {
396 mailmime *message, *txtPart;
397 mailimf_fields *fields;
398 int err;
399
400 fields = createImfFields( mail );
401 if ( fields == NULL )
402 goto err_free;
403
404 message = mailmime_new_message_data( NULL );
405 if ( message == NULL )
406 goto err_free_fields;
407
408 mailmime_set_imf_fields( message, fields );
409
410 txtPart = buildTxtPart( mail->getMessage() );
411
412 if ( txtPart == NULL )
413 goto err_free_message;
414
415 err = mailmime_smart_add_part( message, txtPart );
416 if ( err != MAILIMF_NO_ERROR )
417 goto err_free_txtPart;
418
419 addFileParts( message, mail->getAttachments() );
420
421 return message; // Success :)
422
423err_free_txtPart:
424 mailmime_free( txtPart );
425err_free_message:
426 mailmime_free( message );
427err_free_fields:
428 mailimf_fields_free( fields );
429err_free:
430 ;
431
432 return NULL; // Error :(
433}
434
435clist *Generatemail::createRcptList( mailimf_fields *fields ) {
436 clist *rcptList;
437 mailimf_field *field;
438
439 rcptList = esmtp_address_list_new();
440
441 field = getField( fields, MAILIMF_FIELD_TO );
442 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
443 && field->fld_data.fld_to->to_addr_list ) {
444 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
445 }
446
447 field = getField( fields, MAILIMF_FIELD_CC );
448 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
449 && field->fld_data.fld_cc->cc_addr_list ) {
450 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
451 }
452
453 field = getField( fields, MAILIMF_FIELD_BCC );
454 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
455 && field->fld_data.fld_bcc->bcc_addr_list ) {
456 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
457 }
458
459 return rcptList;
460}