summaryrefslogtreecommitdiff
authoralwin <alwin>2003-12-21 10:36:22 (UTC)
committer alwin <alwin>2003-12-21 10:36:22 (UTC)
commitaf0b88049e0c77cb90ef1aca608accc32a2e2828 (patch) (unidiff)
treead8a2ce76ae1ab3cf535f4d1d7addbc240ff4209
parent8e884631cc002011a9abab37be9223d4a1421ff2 (diff)
downloadopie-af0b88049e0c77cb90ef1aca608accc32a2e2828.zip
opie-af0b88049e0c77cb90ef1aca608accc32a2e2828.tar.gz
opie-af0b88049e0c77cb90ef1aca608accc32a2e2828.tar.bz2
- MailWrapper -> SMTPwrapper
- made dependies from libetpan includes somewhat cleaner - removed standalone static funs and moved to class based static methods - arguements in SMTPwrapper now always const references and not deep copies TODO: clean up GOTO statements, change QList to QValueList for a better handling of "const" arguments, store mails in queue and/or a local "Sent" folder.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/abstractmail.cpp1
-rw-r--r--noncore/net/mail/composemail.cpp3
-rw-r--r--noncore/net/mail/imapwrapper.cpp3
-rw-r--r--noncore/net/mail/imapwrapper.h1
-rw-r--r--noncore/net/mail/libmailwrapper/abstractmail.cpp1
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.cpp3
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.h1
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.cpp585
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.h35
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.h6
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.cpp604
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.h53
-rw-r--r--noncore/net/mail/mail.pro6
-rw-r--r--noncore/net/mail/mailwrapper.cpp585
-rw-r--r--noncore/net/mail/mailwrapper.h35
-rw-r--r--noncore/net/mail/pop3wrapper.h6
-rw-r--r--noncore/net/mail/smtpwrapper.cpp604
-rw-r--r--noncore/net/mail/smtpwrapper.h53
18 files changed, 1340 insertions, 1245 deletions
diff --git a/noncore/net/mail/abstractmail.cpp b/noncore/net/mail/abstractmail.cpp
index 626b9aa..3cb8f7d 100644
--- a/noncore/net/mail/abstractmail.cpp
+++ b/noncore/net/mail/abstractmail.cpp
@@ -10,2 +10,3 @@
10#include <libetpan/mailmime_content.h> 10#include <libetpan/mailmime_content.h>
11#include <libetpan/mailmime.h>
11 12
diff --git a/noncore/net/mail/composemail.cpp b/noncore/net/mail/composemail.cpp
index cfccdbb..048fa85 100644
--- a/noncore/net/mail/composemail.cpp
+++ b/noncore/net/mail/composemail.cpp
@@ -6,2 +6,3 @@
6#include "composemail.h" 6#include "composemail.h"
7#include "smtpwrapper.h"
7 8
@@ -184,3 +185,3 @@ void ComposeMail::accept()
184 185
185 MailWrapper wrapper( settings ); 186 SMTPwrapper wrapper( settings );
186 wrapper.sendMail( *mail ); 187 wrapper.sendMail( *mail );
diff --git a/noncore/net/mail/imapwrapper.cpp b/noncore/net/mail/imapwrapper.cpp
index cce3d34..30eb678 100644
--- a/noncore/net/mail/imapwrapper.cpp
+++ b/noncore/net/mail/imapwrapper.cpp
@@ -3,2 +3,4 @@
3 3
4#include <libetpan/mailimap.h>
5
4#include "imapwrapper.h" 6#include "imapwrapper.h"
@@ -6,3 +8,2 @@
6#include "logindialog.h" 8#include "logindialog.h"
7#include <libetpan/mailimap.h>
8 9
diff --git a/noncore/net/mail/imapwrapper.h b/noncore/net/mail/imapwrapper.h
index aeebda8..f046297 100644
--- a/noncore/net/mail/imapwrapper.h
+++ b/noncore/net/mail/imapwrapper.h
@@ -6,2 +6,3 @@
6#include "abstractmail.h" 6#include "abstractmail.h"
7#include <libetpan/clist.h>
7 8
diff --git a/noncore/net/mail/libmailwrapper/abstractmail.cpp b/noncore/net/mail/libmailwrapper/abstractmail.cpp
index 626b9aa..3cb8f7d 100644
--- a/noncore/net/mail/libmailwrapper/abstractmail.cpp
+++ b/noncore/net/mail/libmailwrapper/abstractmail.cpp
@@ -10,2 +10,3 @@
10#include <libetpan/mailmime_content.h> 10#include <libetpan/mailmime_content.h>
11#include <libetpan/mailmime.h>
11 12
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
index cce3d34..30eb678 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
@@ -3,2 +3,4 @@
3 3
4#include <libetpan/mailimap.h>
5
4#include "imapwrapper.h" 6#include "imapwrapper.h"
@@ -6,3 +8,2 @@
6#include "logindialog.h" 8#include "logindialog.h"
7#include <libetpan/mailimap.h>
8 9
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h
index aeebda8..f046297 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.h
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.h
@@ -6,2 +6,3 @@
6#include "abstractmail.h" 6#include "abstractmail.h"
7#include <libetpan/clist.h>
7 8
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.cpp b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
index 75c06f9..c5d4265 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
@@ -134,587 +134,2 @@ QString IMAPFolder::decodeFolderName( const QString &name )
134 134
135MailWrapper::MailWrapper( Settings *s )
136 : QObject()
137{
138 settings = s;
139}
140
141QString MailWrapper::mailsmtpError( int errnum )
142{
143 switch ( errnum ) {
144 case MAILSMTP_NO_ERROR:
145 return tr( "No error" );
146 case MAILSMTP_ERROR_UNEXPECTED_CODE:
147 return tr( "Unexpected error code" );
148 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
149 return tr( "Service not available" );
150 case MAILSMTP_ERROR_STREAM:
151 return tr( "Stream error" );
152 case MAILSMTP_ERROR_HOSTNAME:
153 return tr( "gethostname() failed" );
154 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
155 return tr( "Not implemented" );
156 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
157 return tr( "Error, action not taken" );
158 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
159 return tr( "Data exceeds storage allocation" );
160 case MAILSMTP_ERROR_IN_PROCESSING:
161 return tr( "Error in processing" );
162 // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
163 // return tr( "Insufficient system storage" );
164 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
165 return tr( "Mailbox unavailable" );
166 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
167 return tr( "Mailbox name not allowed" );
168 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
169 return tr( "Bad command sequence" );
170 case MAILSMTP_ERROR_USER_NOT_LOCAL:
171 return tr( "User not local" );
172 case MAILSMTP_ERROR_TRANSACTION_FAILED:
173 return tr( "Transaction failed" );
174 case MAILSMTP_ERROR_MEMORY:
175 return tr( "Memory error" );
176 case MAILSMTP_ERROR_CONNECTION_REFUSED:
177 return tr( "Connection refused" );
178 default:
179 return tr( "Unknown error code" );
180 }
181}
182
183mailimf_mailbox *MailWrapper::newMailbox(const QString&name, const QString&mail )
184{
185 return mailimf_mailbox_new( strdup( name.latin1() ),
186 strdup( mail.latin1() ) );
187}
188
189mailimf_address_list *MailWrapper::parseAddresses(const QString&addr )
190{
191 mailimf_address_list *addresses;
192
193 if ( addr.isEmpty() ) return NULL;
194
195 addresses = mailimf_address_list_new_empty();
196
197 QStringList list = QStringList::split( ',', addr );
198 QStringList::Iterator it;
199 for ( it = list.begin(); it != list.end(); it++ ) {
200 char *str = strdup( (*it).latin1() );
201 int err = mailimf_address_list_add_parse( addresses, str );
202 if ( err != MAILIMF_NO_ERROR ) {
203 qDebug( "Error parsing" );
204 qDebug( *it );
205 free( str );
206 } else {
207 qDebug( "Parse success! :)" );
208 }
209 }
210
211 return addresses;
212}
213
214mailimf_fields *MailWrapper::createImfFields( Mail *mail )
215{
216 mailimf_fields *fields;
217 mailimf_field *xmailer;
218 mailimf_mailbox *sender, *fromBox;
219 mailimf_mailbox_list *from;
220 mailimf_address_list *to, *cc, *bcc, *reply;
221 char *subject = strdup( mail->getSubject().latin1() );
222 int err;
223
224 sender = newMailbox( mail->getName(), mail->getMail() );
225 if ( sender == NULL ) goto err_free;
226
227 fromBox = newMailbox( mail->getName(), mail->getMail() );
228 if ( fromBox == NULL ) goto err_free_sender;
229
230 from = mailimf_mailbox_list_new_empty();
231 if ( from == NULL ) goto err_free_fromBox;
232
233 err = mailimf_mailbox_list_add( from, fromBox );
234 if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
235
236 to = parseAddresses( mail->getTo() );
237 if ( to == NULL ) goto err_free_from;
238
239 cc = parseAddresses( mail->getCC() );
240 bcc = parseAddresses( mail->getBCC() );
241 reply = parseAddresses( mail->getReply() );
242
243 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
244 NULL, NULL, subject );
245 if ( fields == NULL ) goto err_free_reply;
246
247 xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
248 strdup( USER_AGENT ) );
249 if ( xmailer == NULL ) goto err_free_fields;
250
251 err = mailimf_fields_add( fields, xmailer );
252 if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
253
254 return fields; // Success :)
255
256err_free_xmailer:
257 mailimf_field_free( xmailer );
258err_free_fields:
259 mailimf_fields_free( fields );
260err_free_reply:
261 mailimf_address_list_free( reply );
262 mailimf_address_list_free( bcc );
263 mailimf_address_list_free( cc );
264 mailimf_address_list_free( to );
265err_free_from:
266 mailimf_mailbox_list_free( from );
267err_free_fromBox:
268 mailimf_mailbox_free( fromBox );
269err_free_sender:
270 mailimf_mailbox_free( sender );
271err_free:
272 free( subject );
273 qDebug( "createImfFields - error" );
274
275 return NULL; // Error :(
276}
277
278mailmime *MailWrapper::buildTxtPart( QString str )
279{
280 mailmime *txtPart;
281 mailmime_fields *fields;
282 mailmime_content *content;
283 mailmime_parameter *param;
284 char *txt = strdup( str.latin1() );
285 int err;
286
287 param = mailmime_parameter_new( strdup( "charset" ),
288 strdup( "iso-8859-1" ) );
289 if ( param == NULL ) goto err_free;
290
291 content = mailmime_content_new_with_str( "text/plain" );
292 if ( content == NULL ) goto err_free_param;
293
294 err = clist_append( content->ct_parameters, param );
295 if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
296
297 fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
298 if ( fields == NULL ) goto err_free_content;
299
300 txtPart = mailmime_new_empty( content, fields );
301 if ( txtPart == NULL ) goto err_free_fields;
302
303 err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
304 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
305
306 return txtPart; // Success :)
307
308err_free_txtPart:
309 mailmime_free( txtPart );
310err_free_fields:
311 mailmime_fields_free( fields );
312err_free_content:
313 mailmime_content_free( content );
314err_free_param:
315 mailmime_parameter_free( param );
316err_free:
317 free( txt );
318 qDebug( "buildTxtPart - error" );
319
320 return NULL; // Error :(
321}
322
323mailmime *MailWrapper::buildFilePart( QString filename, QString mimetype )
324{
325 mailmime * filePart;
326 mailmime_fields * fields;
327 mailmime_content * content;
328 mailmime_parameter * param = NULL;
329 int err;
330
331 int pos = filename.findRev( '/' );
332 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
333 char *name = strdup( tmp.latin1() ); // just filename
334 char *file = strdup( filename.latin1() ); // full name with path
335 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
336
337 fields = mailmime_fields_new_filename(
338 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
339 MAILMIME_MECHANISM_BASE64 );
340 if ( fields == NULL ) goto err_free;
341
342 content = mailmime_content_new_with_str( mime );
343 if ( content == NULL ) goto err_free_fields;
344
345 if ( mimetype.compare( "text/plain" ) == 0 ) {
346 param = mailmime_parameter_new( strdup( "charset" ),
347 strdup( "iso-8859-1" ) );
348 if ( param == NULL ) goto err_free_content;
349
350 err = clist_append( content->ct_parameters, param );
351 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
352 }
353
354 filePart = mailmime_new_empty( content, fields );
355 if ( filePart == NULL ) goto err_free_param;
356
357 err = mailmime_set_body_file( filePart, file );
358 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
359
360 return filePart; // Success :)
361
362err_free_filePart:
363 mailmime_free( filePart );
364err_free_param:
365 if ( param != NULL ) mailmime_parameter_free( param );
366err_free_content:
367 mailmime_content_free( content );
368err_free_fields:
369 mailmime_fields_free( fields );
370err_free:
371 free( name );
372 free( mime );
373 free( file );
374 qDebug( "buildFilePart - error" );
375
376 return NULL; // Error :(
377}
378
379void MailWrapper::addFileParts( mailmime *message, QList<Attachment> files )
380{
381 Attachment *it;
382 for ( it = files.first(); it; it = files.next() ) {
383 qDebug( "Adding file" );
384 mailmime *filePart;
385 int err;
386
387 filePart = buildFilePart( it->getFileName(), it->getMimeType() );
388 if ( filePart == NULL ) goto err_free;
389
390 err = mailmime_smart_add_part( message, filePart );
391 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
392
393 continue; // Success :)
394
395 err_free_filePart:
396 mailmime_free( filePart );
397 err_free:
398 qDebug( "addFileParts: error adding file:" );
399 qDebug( it->getFileName() );
400 }
401}
402
403mailmime *MailWrapper::createMimeMail( Mail *mail )
404{
405 mailmime *message, *txtPart;
406 mailimf_fields *fields;
407 int err;
408
409 fields = createImfFields( mail );
410 if ( fields == NULL ) goto err_free;
411
412 message = mailmime_new_message_data( NULL );
413 if ( message == NULL ) goto err_free_fields;
414
415 mailmime_set_imf_fields( message, fields );
416
417 txtPart = buildTxtPart( mail->getMessage() );
418 if ( txtPart == NULL ) goto err_free_message;
419
420 err = mailmime_smart_add_part( message, txtPart );
421 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
422
423 addFileParts( message, mail->getAttachments() );
424
425 return message; // Success :)
426
427err_free_txtPart:
428 mailmime_free( txtPart );
429err_free_message:
430 mailmime_free( message );
431err_free_fields:
432 mailimf_fields_free( fields );
433err_free:
434 qDebug( "createMimeMail: error" );
435
436 return NULL; // Error :(
437}
438
439mailimf_field *MailWrapper::getField( mailimf_fields *fields, int type )
440{
441 mailimf_field *field;
442 clistiter *it;
443
444 it = clist_begin( fields->fld_list );
445 while ( it ) {
446 field = (mailimf_field *) it->data;
447 if ( field->fld_type == type ) {
448 return field;
449 }
450 it = it->next;
451 }
452
453 return NULL;
454}
455
456static void addRcpts( clist *list, mailimf_address_list *addr_list )
457{
458 clistiter *it, *it2;
459
460 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
461 mailimf_address *addr;
462 addr = (mailimf_address *) it->data;
463
464 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
465 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
466 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
467 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
468 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
469 mailimf_mailbox *mbox;
470 mbox = (mailimf_mailbox *) it2->data;
471 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
472 }
473 }
474 }
475}
476
477clist *MailWrapper::createRcptList( mailimf_fields *fields )
478{
479 clist *rcptList;
480 mailimf_field *field;
481
482 rcptList = esmtp_address_list_new();
483
484 field = getField( fields, MAILIMF_FIELD_TO );
485 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
486 && field->fld_data.fld_to->to_addr_list ) {
487 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
488 }
489
490 field = getField( fields, MAILIMF_FIELD_CC );
491 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
492 && field->fld_data.fld_cc->cc_addr_list ) {
493 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
494 }
495
496 field = getField( fields, MAILIMF_FIELD_BCC );
497 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
498 && field->fld_data.fld_bcc->bcc_addr_list ) {
499 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
500 }
501
502 return rcptList;
503}
504
505char *MailWrapper::getFrom( mailmime *mail )
506{
507 char *from = NULL;
508
509 mailimf_field *ffrom;
510 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
511 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
512 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
513 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
514 clistiter *it;
515 for ( it = clist_begin( cl ); it; it = it->next ) {
516 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
517 from = strdup( mb->mb_addr_spec );
518 }
519 }
520
521 return from;
522}
523
524SMTPaccount *MailWrapper::getAccount( QString from )
525{
526 SMTPaccount *smtp;
527
528 QList<Account> list = settings->getAccounts();
529 Account *it;
530 for ( it = list.first(); it; it = list.next() ) {
531 if ( it->getType().compare( "SMTP" ) == 0 ) {
532 smtp = static_cast<SMTPaccount *>(it);
533 if ( smtp->getMail().compare( from ) == 0 ) {
534 qDebug( "SMTPaccount found for" );
535 qDebug( from );
536 return smtp;
537 }
538 }
539 }
540
541 return NULL;
542}
543
544QString MailWrapper::getTmpFile() {
545 int num = 0;
546 QString unique;
547
548 QDir dir( "/tmp" );
549 QStringList::Iterator it;
550
551 QStringList list = dir.entryList( "opiemail-tmp-*" );
552 do {
553 unique.setNum( num++ );
554 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
555
556 return "/tmp/opiemail-tmp-" + unique;
557}
558
559void MailWrapper::writeToFile( QString file, mailmime *mail )
560{
561 FILE *f;
562 int err, col = 0;
563
564 f = fopen( file.latin1(), "w" );
565 if ( f == NULL ) {
566 qDebug( "writeToFile: error opening file" );
567 return;
568 }
569
570 err = mailmime_write( f, &col, mail );
571 if ( err != MAILIMF_NO_ERROR ) {
572 fclose( f );
573 qDebug( "writeToFile: error writing mailmime" );
574 return;
575 }
576
577 fclose( f );
578}
579
580void MailWrapper::readFromFile( QString file, char **data, size_t *size )
581{
582 char *buf;
583 struct stat st;
584 int fd, count = 0, total = 0;
585
586 fd = open( file.latin1(), O_RDONLY, 0 );
587 if ( fd == -1 ) return;
588
589 if ( fstat( fd, &st ) != 0 ) goto err_close;
590 if ( !st.st_size ) goto err_close;
591
592 buf = (char *) malloc( st.st_size );
593 if ( !buf ) goto err_close;
594
595 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
596 count = read( fd, buf + total, st.st_size - total );
597 total += count;
598 }
599 if ( count < 0 ) goto err_free;
600
601 *data = buf;
602 *size = st.st_size;
603
604 close( fd );
605
606 return; // Success :)
607
608err_free:
609 free( buf );
610err_close:
611 close( fd );
612}
613
614void progress( size_t current, size_t maximum )
615{
616 qDebug( "Current: %i of %i", current, maximum );
617}
618
619void MailWrapper::smtpSend( mailmime *mail )
620{
621 mailsmtp *session;
622 clist *rcpts;
623 char *from, *data, *server, *user = NULL, *pass = NULL;
624 size_t size;
625 int err;
626 bool ssl;
627 uint16_t port;
628
629
630 from = getFrom( mail );
631 SMTPaccount *smtp = getAccount( from );
632 if ( smtp == NULL ) {
633 free(from);
634 return;
635 }
636 server = strdup( smtp->getServer().latin1() );
637 ssl = smtp->getSSL();
638 port = smtp->getPort().toUInt();
639 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
640
641 QString file = getTmpFile();
642 writeToFile( file, mail );
643 readFromFile( file, &data, &size );
644 QFile f( file );
645 f.remove();
646
647 session = mailsmtp_new( 20, &progress );
648 if ( session == NULL ) goto free_mem;
649
650 qDebug( "Servername %s at port %i", server, port );
651 if ( ssl ) {
652 qDebug( "SSL session" );
653 err = mailsmtp_ssl_connect( session, server, port );
654 } else {
655 qDebug( "No SSL session" );
656 err = mailsmtp_socket_connect( session, server, port );
657 }
658 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
659
660 err = mailsmtp_init( session );
661 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
662
663 qDebug( "INIT OK" );
664
665 if ( smtp->getLogin() ) {
666 if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
667 // get'em
668 LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
669 login.show();
670 if ( QDialog::Accepted == login.exec() ) {
671 // ok
672 user = strdup( login.getUser().latin1() );
673 pass = strdup( login.getPassword().latin1() );
674 } else {
675 goto free_con_session;
676 }
677 } else {
678 user = strdup( smtp->getUser().latin1() );
679 pass = strdup( smtp->getPassword().latin1() );
680 }
681 qDebug( "session->auth: %i", session->auth);
682 err = mailsmtp_auth( session, user, pass );
683 if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
684 qDebug( "Done auth!" );
685 }
686
687 err = mailsmtp_send( session, from, rcpts, data, size );
688 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
689
690 qDebug( "Mail sent." );
691
692free_con_session:
693 mailsmtp_quit( session );
694free_mem_session:
695 mailsmtp_free( session );
696free_mem:
697 smtp_address_list_free( rcpts );
698 free( data );
699 free( server );
700 if ( smtp->getLogin() ) {
701 free( user );
702 free( pass );
703 }
704 free( from );
705}
706
707void MailWrapper::sendMail( Mail mail )
708{
709 mailmime *mimeMail;
710
711 mimeMail = createMimeMail( &mail );
712 if ( mimeMail == NULL ) {
713 qDebug( "sendMail: error creating mime mail" );
714 } else {
715 smtpSend( mimeMail );
716 mailmime_free( mimeMail );
717 }
718}
719
720Mail::Mail() 135Mail::Mail()
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.h b/noncore/net/mail/libmailwrapper/mailwrapper.h
index 02fe4b7..8fd886f 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.h
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.h
@@ -5,7 +5,2 @@
5 5
6#include <libetpan/mailmime.h>
7#include <libetpan/mailimf.h>
8#include <libetpan/mailsmtp.h>
9#include <libetpan/mailstorage.h>
10#include <libetpan/maildriver.h>
11#include <qbitarray.h> 6#include <qbitarray.h>
@@ -95,32 +90,2 @@ class IMAPFolder : public Folder
95 90
96class MailWrapper : public QObject
97{
98 Q_OBJECT
99
100public:
101 MailWrapper( Settings *s );
102 void sendMail( Mail mail );
103
104private:
105 mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
106 mailimf_address_list *parseAddresses(const QString&addr );
107 mailimf_fields *createImfFields( Mail *mail );
108 mailmime *buildTxtPart( QString str );
109 mailmime *buildFilePart( QString filename, QString mimetype );
110 void addFileParts( mailmime *message, QList<Attachment> files );
111 mailmime *createMimeMail( Mail *mail );
112 void smtpSend( mailmime *mail );
113 mailimf_field *getField( mailimf_fields *fields, int type );
114 clist *createRcptList( mailimf_fields *fields );
115 char *getFrom( mailmime *mail );
116 SMTPaccount *getAccount( QString from );
117 void writeToFile( QString file, mailmime *mail );
118 void readFromFile( QString file, char **data, size_t *size );
119 static QString mailsmtpError( int err );
120 static QString getTmpFile();
121
122 Settings *settings;
123
124};
125
126#endif 91#endif
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.h b/noncore/net/mail/libmailwrapper/pop3wrapper.h
index a31a145..75d70f8 100644
--- a/noncore/net/mail/libmailwrapper/pop3wrapper.h
+++ b/noncore/net/mail/libmailwrapper/pop3wrapper.h
@@ -3,2 +3,3 @@
3 3
4#include <libetpan/clist.h>
4#include "mailwrapper.h" 5#include "mailwrapper.h"
@@ -15,2 +16,7 @@ struct mailmime;
15struct mailmime_mechanism; 16struct mailmime_mechanism;
17struct mailimf_mailbox_list;
18struct mailimf_mailbox;
19struct mailimf_date_time;
20struct mailimf_group;
21struct mailimf_address_list;
16 22
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
new file mode 100644
index 0000000..162b1b9
--- a/dev/null
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
@@ -0,0 +1,604 @@
1#include <stdlib.h>
2#include <sys/stat.h>
3#include <sys/types.h>
4#include <unistd.h>
5#include <fcntl.h>
6#include <string.h>
7#include <qdir.h>
8
9#include <libetpan/mailmime.h>
10#include <libetpan/mailimf.h>
11#include <libetpan/mailsmtp.h>
12#include <libetpan/mailstorage.h>
13#include <libetpan/maildriver.h>
14
15#include "smtpwrapper.h"
16#include "mailwrapper.h"
17#include "logindialog.h"
18#include "defines.h"
19
20SMTPwrapper::SMTPwrapper( Settings *s )
21 : QObject()
22{
23 settings = s;
24}
25
26QString SMTPwrapper::mailsmtpError( int errnum )
27{
28 switch ( errnum ) {
29 case MAILSMTP_NO_ERROR:
30 return tr( "No error" );
31 case MAILSMTP_ERROR_UNEXPECTED_CODE:
32 return tr( "Unexpected error code" );
33 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
34 return tr( "Service not available" );
35 case MAILSMTP_ERROR_STREAM:
36 return tr( "Stream error" );
37 case MAILSMTP_ERROR_HOSTNAME:
38 return tr( "gethostname() failed" );
39 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
40 return tr( "Not implemented" );
41 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
42 return tr( "Error, action not taken" );
43 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
44 return tr( "Data exceeds storage allocation" );
45 case MAILSMTP_ERROR_IN_PROCESSING:
46 return tr( "Error in processing" );
47 // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
48 // return tr( "Insufficient system storage" );
49 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
50 return tr( "Mailbox unavailable" );
51 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
52 return tr( "Mailbox name not allowed" );
53 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
54 return tr( "Bad command sequence" );
55 case MAILSMTP_ERROR_USER_NOT_LOCAL:
56 return tr( "User not local" );
57 case MAILSMTP_ERROR_TRANSACTION_FAILED:
58 return tr( "Transaction failed" );
59 case MAILSMTP_ERROR_MEMORY:
60 return tr( "Memory error" );
61 case MAILSMTP_ERROR_CONNECTION_REFUSED:
62 return tr( "Connection refused" );
63 default:
64 return tr( "Unknown error code" );
65 }
66}
67
68mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail )
69{
70 return mailimf_mailbox_new( strdup( name.latin1() ),
71 strdup( mail.latin1() ) );
72}
73
74mailimf_address_list *SMTPwrapper::parseAddresses(const QString&addr )
75{
76 mailimf_address_list *addresses;
77
78 if ( addr.isEmpty() ) return NULL;
79
80 addresses = mailimf_address_list_new_empty();
81
82 QStringList list = QStringList::split( ',', addr );
83 QStringList::Iterator it;
84 for ( it = list.begin(); it != list.end(); it++ ) {
85 char *str = strdup( (*it).latin1() );
86 int err = mailimf_address_list_add_parse( addresses, str );
87 if ( err != MAILIMF_NO_ERROR ) {
88 qDebug( "Error parsing" );
89 qDebug( *it );
90 free( str );
91 } else {
92 qDebug( "Parse success! :)" );
93 }
94 }
95
96 return addresses;
97}
98
99mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail )
100{
101 mailimf_fields *fields;
102 mailimf_field *xmailer;
103 mailimf_mailbox *sender, *fromBox;
104 mailimf_mailbox_list *from;
105 mailimf_address_list *to, *cc, *bcc, *reply;
106 char *subject = strdup( mail.getSubject().latin1() );
107 int err;
108
109 sender = newMailbox( mail.getName(), mail.getMail() );
110 if ( sender == NULL ) goto err_free;
111
112 fromBox = newMailbox( mail.getName(), mail.getMail() );
113 if ( fromBox == NULL ) goto err_free_sender;
114
115 from = mailimf_mailbox_list_new_empty();
116 if ( from == NULL ) goto err_free_fromBox;
117
118 err = mailimf_mailbox_list_add( from, fromBox );
119 if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
120
121 to = parseAddresses( mail.getTo() );
122 if ( to == NULL ) goto err_free_from;
123
124 cc = parseAddresses( mail.getCC() );
125 bcc = parseAddresses( mail.getBCC() );
126 reply = parseAddresses( mail.getReply() );
127
128 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
129 NULL, NULL, subject );
130 if ( fields == NULL ) goto err_free_reply;
131
132 xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
133 strdup( USER_AGENT ) );
134 if ( xmailer == NULL ) goto err_free_fields;
135
136 err = mailimf_fields_add( fields, xmailer );
137 if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
138
139 return fields; // Success :)
140
141err_free_xmailer:
142 mailimf_field_free( xmailer );
143err_free_fields:
144 mailimf_fields_free( fields );
145err_free_reply:
146 mailimf_address_list_free( reply );
147 mailimf_address_list_free( bcc );
148 mailimf_address_list_free( cc );
149 mailimf_address_list_free( to );
150err_free_from:
151 mailimf_mailbox_list_free( from );
152err_free_fromBox:
153 mailimf_mailbox_free( fromBox );
154err_free_sender:
155 mailimf_mailbox_free( sender );
156err_free:
157 free( subject );
158 qDebug( "createImfFields - error" );
159
160 return NULL; // Error :(
161}
162
163mailmime *SMTPwrapper::buildTxtPart(const QString&str )
164{
165 mailmime *txtPart;
166 mailmime_fields *fields;
167 mailmime_content *content;
168 mailmime_parameter *param;
169 char *txt = strdup( str.latin1() );
170 int err;
171
172 param = mailmime_parameter_new( strdup( "charset" ),
173 strdup( "iso-8859-1" ) );
174 if ( param == NULL ) goto err_free;
175
176 content = mailmime_content_new_with_str( "text/plain" );
177 if ( content == NULL ) goto err_free_param;
178
179 err = clist_append( content->ct_parameters, param );
180 if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
181
182 fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
183 if ( fields == NULL ) goto err_free_content;
184
185 txtPart = mailmime_new_empty( content, fields );
186 if ( txtPart == NULL ) goto err_free_fields;
187
188 err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
189 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
190
191 return txtPart; // Success :)
192
193err_free_txtPart:
194 mailmime_free( txtPart );
195err_free_fields:
196 mailmime_fields_free( fields );
197err_free_content:
198 mailmime_content_free( content );
199err_free_param:
200 mailmime_parameter_free( param );
201err_free:
202 free( txt );
203 qDebug( "buildTxtPart - error" );
204
205 return NULL; // Error :(
206}
207
208mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype )
209{
210 mailmime * filePart;
211 mailmime_fields * fields;
212 mailmime_content * content;
213 mailmime_parameter * param = NULL;
214 int err;
215
216 int pos = filename.findRev( '/' );
217 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
218 char *name = strdup( tmp.latin1() ); // just filename
219 char *file = strdup( filename.latin1() ); // full name with path
220 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
221
222 fields = mailmime_fields_new_filename(
223 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
224 MAILMIME_MECHANISM_BASE64 );
225 if ( fields == NULL ) goto err_free;
226
227 content = mailmime_content_new_with_str( mime );
228 if ( content == NULL ) goto err_free_fields;
229
230 if ( mimetype.compare( "text/plain" ) == 0 ) {
231 param = mailmime_parameter_new( strdup( "charset" ),
232 strdup( "iso-8859-1" ) );
233 if ( param == NULL ) goto err_free_content;
234
235 err = clist_append( content->ct_parameters, param );
236 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
237 }
238
239 filePart = mailmime_new_empty( content, fields );
240 if ( filePart == NULL ) goto err_free_param;
241
242 err = mailmime_set_body_file( filePart, file );
243 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
244
245 return filePart; // Success :)
246
247err_free_filePart:
248 mailmime_free( filePart );
249err_free_param:
250 if ( param != NULL ) mailmime_parameter_free( param );
251err_free_content:
252 mailmime_content_free( content );
253err_free_fields:
254 mailmime_fields_free( fields );
255err_free:
256 free( name );
257 free( mime );
258 free( file );
259 qDebug( "buildFilePart - error" );
260
261 return NULL; // Error :(
262}
263
264void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files )
265{
266 const Attachment *it;
267 /* work around for the brainfucked qlist which can not act with const values */
268 for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) {
269 qDebug( "Adding file" );
270 mailmime *filePart;
271 int err;
272
273 filePart = buildFilePart( it->getFileName(), it->getMimeType() );
274 if ( filePart == NULL ) goto err_free;
275
276 err = mailmime_smart_add_part( message, filePart );
277 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
278
279 continue; // Success :)
280
281 err_free_filePart:
282 mailmime_free( filePart );
283 err_free:
284 qDebug( "addFileParts: error adding file:" );
285 qDebug( it->getFileName() );
286 }
287}
288
289mailmime *SMTPwrapper::createMimeMail(const Mail &mail )
290{
291 mailmime *message, *txtPart;
292 mailimf_fields *fields;
293 int err;
294
295 fields = createImfFields( mail );
296 if ( fields == NULL ) goto err_free;
297
298 message = mailmime_new_message_data( NULL );
299 if ( message == NULL ) goto err_free_fields;
300
301 mailmime_set_imf_fields( message, fields );
302
303 txtPart = buildTxtPart( mail.getMessage() );
304 if ( txtPart == NULL ) goto err_free_message;
305
306 err = mailmime_smart_add_part( message, txtPart );
307 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
308
309 addFileParts( message, mail.getAttachments() );
310
311 return message; // Success :)
312
313err_free_txtPart:
314 mailmime_free( txtPart );
315err_free_message:
316 mailmime_free( message );
317err_free_fields:
318 mailimf_fields_free( fields );
319err_free:
320 qDebug( "createMimeMail: error" );
321
322 return NULL; // Error :(
323}
324
325mailimf_field *SMTPwrapper::getField( mailimf_fields *fields, int type )
326{
327 mailimf_field *field;
328 clistiter *it;
329
330 it = clist_begin( fields->fld_list );
331 while ( it ) {
332 field = (mailimf_field *) it->data;
333 if ( field->fld_type == type ) {
334 return field;
335 }
336 it = it->next;
337 }
338
339 return NULL;
340}
341
342void SMTPwrapper::addRcpts( clist *list, mailimf_address_list *addr_list )
343{
344 clistiter *it, *it2;
345
346 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
347 mailimf_address *addr;
348 addr = (mailimf_address *) it->data;
349
350 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
351 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
352 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
353 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
354 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
355 mailimf_mailbox *mbox;
356 mbox = (mailimf_mailbox *) it2->data;
357 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
358 }
359 }
360 }
361}
362
363clist *SMTPwrapper::createRcptList( mailimf_fields *fields )
364{
365 clist *rcptList;
366 mailimf_field *field;
367
368 rcptList = esmtp_address_list_new();
369
370 field = getField( fields, MAILIMF_FIELD_TO );
371 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
372 && field->fld_data.fld_to->to_addr_list ) {
373 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
374 }
375
376 field = getField( fields, MAILIMF_FIELD_CC );
377 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
378 && field->fld_data.fld_cc->cc_addr_list ) {
379 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
380 }
381
382 field = getField( fields, MAILIMF_FIELD_BCC );
383 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
384 && field->fld_data.fld_bcc->bcc_addr_list ) {
385 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
386 }
387
388 return rcptList;
389}
390
391char *SMTPwrapper::getFrom( mailmime *mail )
392{
393 char *from = NULL;
394
395 mailimf_field *ffrom;
396 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
397 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
398 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
399 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
400 clistiter *it;
401 for ( it = clist_begin( cl ); it; it = it->next ) {
402 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
403 from = strdup( mb->mb_addr_spec );
404 }
405 }
406
407 return from;
408}
409
410SMTPaccount *SMTPwrapper::getAccount(const QString&from )
411{
412 SMTPaccount *smtp;
413
414 QList<Account> list = settings->getAccounts();
415 Account *it;
416 for ( it = list.first(); it; it = list.next() ) {
417 if ( it->getType().compare( "SMTP" ) == 0 ) {
418 smtp = static_cast<SMTPaccount *>(it);
419 if ( smtp->getMail().compare( from ) == 0 ) {
420 qDebug( "SMTPaccount found for" );
421 qDebug( from );
422 return smtp;
423 }
424 }
425 }
426
427 return NULL;
428}
429
430QString SMTPwrapper::getTmpFile() {
431 int num = 0;
432 QString unique;
433
434 QDir dir( "/tmp" );
435 QStringList::Iterator it;
436
437 QStringList list = dir.entryList( "opiemail-tmp-*" );
438 do {
439 unique.setNum( num++ );
440 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
441
442 return "/tmp/opiemail-tmp-" + unique;
443}
444
445void SMTPwrapper::writeToFile(const QString&file, mailmime *mail )
446{
447 FILE *f;
448 int err, col = 0;
449
450 f = fopen( file.latin1(), "w" );
451 if ( f == NULL ) {
452 qDebug( "writeToFile: error opening file" );
453 return;
454 }
455
456 err = mailmime_write( f, &col, mail );
457 if ( err != MAILIMF_NO_ERROR ) {
458 fclose( f );
459 qDebug( "writeToFile: error writing mailmime" );
460 return;
461 }
462
463 fclose( f );
464}
465
466void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size )
467{
468 char *buf;
469 struct stat st;
470 int fd, count = 0, total = 0;
471
472 fd = open( file.latin1(), O_RDONLY, 0 );
473 if ( fd == -1 ) return;
474
475 if ( fstat( fd, &st ) != 0 ) goto err_close;
476 if ( !st.st_size ) goto err_close;
477
478 buf = (char *) malloc( st.st_size );
479 if ( !buf ) goto err_close;
480
481 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
482 count = read( fd, buf + total, st.st_size - total );
483 total += count;
484 }
485 if ( count < 0 ) goto err_free;
486
487 *data = buf;
488 *size = st.st_size;
489
490 close( fd );
491
492 return; // Success :)
493
494err_free:
495 free( buf );
496err_close:
497 close( fd );
498}
499
500void SMTPwrapper::progress( size_t current, size_t maximum )
501{
502 qDebug( "Current: %i of %i", current, maximum );
503}
504
505void SMTPwrapper::smtpSend( mailmime *mail )
506{
507 mailsmtp *session;
508 clist *rcpts;
509 char *from, *data, *server, *user = NULL, *pass = NULL;
510 size_t size;
511 int err;
512 bool ssl;
513 uint16_t port;
514
515
516 from = getFrom( mail );
517 SMTPaccount *smtp = getAccount( from );
518 if ( smtp == NULL ) {
519 free(from);
520 return;
521 }
522 server = strdup( smtp->getServer().latin1() );
523 ssl = smtp->getSSL();
524 port = smtp->getPort().toUInt();
525 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
526
527 QString file = getTmpFile();
528 writeToFile( file, mail );
529 readFromFile( file, &data, &size );
530 QFile f( file );
531 f.remove();
532
533 session = mailsmtp_new( 20, &progress );
534 if ( session == NULL ) goto free_mem;
535
536 qDebug( "Servername %s at port %i", server, port );
537 if ( ssl ) {
538 qDebug( "SSL session" );
539 err = mailsmtp_ssl_connect( session, server, port );
540 } else {
541 qDebug( "No SSL session" );
542 err = mailsmtp_socket_connect( session, server, port );
543 }
544 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
545
546 err = mailsmtp_init( session );
547 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
548
549 qDebug( "INIT OK" );
550
551 if ( smtp->getLogin() ) {
552 if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
553 // get'em
554 LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
555 login.show();
556 if ( QDialog::Accepted == login.exec() ) {
557 // ok
558 user = strdup( login.getUser().latin1() );
559 pass = strdup( login.getPassword().latin1() );
560 } else {
561 goto free_con_session;
562 }
563 } else {
564 user = strdup( smtp->getUser().latin1() );
565 pass = strdup( smtp->getPassword().latin1() );
566 }
567 qDebug( "session->auth: %i", session->auth);
568 err = mailsmtp_auth( session, user, pass );
569 if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
570 qDebug( "Done auth!" );
571 }
572
573 err = mailsmtp_send( session, from, rcpts, data, size );
574 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
575
576 qDebug( "Mail sent." );
577
578free_con_session:
579 mailsmtp_quit( session );
580free_mem_session:
581 mailsmtp_free( session );
582free_mem:
583 smtp_address_list_free( rcpts );
584 free( data );
585 free( server );
586 if ( smtp->getLogin() ) {
587 free( user );
588 free( pass );
589 }
590 free( from );
591}
592
593void SMTPwrapper::sendMail(const Mail&mail )
594{
595 mailmime *mimeMail;
596
597 mimeMail = createMimeMail(mail );
598 if ( mimeMail == NULL ) {
599 qDebug( "sendMail: error creating mime mail" );
600 } else {
601 smtpSend( mimeMail );
602 mailmime_free( mimeMail );
603 }
604}
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.h b/noncore/net/mail/libmailwrapper/smtpwrapper.h
new file mode 100644
index 0000000..8fdb07d
--- a/dev/null
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.h
@@ -0,0 +1,53 @@
1#ifndef SMTPwrapper_H
2#define SMTPwrapper_H
3
4#include <qpe/applnk.h>
5
6#include <qbitarray.h>
7#include <qdatetime.h>
8#include <libetpan/clist.h>
9
10#include "settings.h"
11
12class Mail;
13class Attachment;
14struct mailimf_fields;
15struct mailimf_field;
16struct mailimf_mailbox;
17struct mailmime;
18struct mailimf_address_list;
19
20class SMTPwrapper : public QObject
21{
22 Q_OBJECT
23
24public:
25 SMTPwrapper( Settings *s );
26 virtual ~SMTPwrapper(){}
27 void sendMail(const Mail& mail );
28
29protected:
30 mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
31 mailimf_fields *createImfFields(const Mail &mail );
32 mailmime *createMimeMail(const Mail&mail );
33
34 mailimf_address_list *parseAddresses(const QString&addr );
35 void addFileParts( mailmime *message,const QList<Attachment>&files );
36 mailmime *buildTxtPart(const QString&str );
37 mailmime *buildFilePart(const QString&filename,const QString&mimetype );
38 void smtpSend( mailmime *mail );
39 mailimf_field *getField( mailimf_fields *fields, int type );
40 clist *createRcptList( mailimf_fields *fields );
41 char *getFrom( mailmime *mail );
42 SMTPaccount *getAccount(const QString&from );
43 void writeToFile(const QString&file, mailmime *mail );
44 void readFromFile(const QString&file, char **data, size_t *size );
45
46 static QString mailsmtpError( int err );
47 static QString getTmpFile();
48 static void progress( size_t current, size_t maximum );
49 static void addRcpts( clist *list, mailimf_address_list *addr_list );
50 Settings *settings;
51};
52
53#endif
diff --git a/noncore/net/mail/mail.pro b/noncore/net/mail/mail.pro
index 49be889..2542344 100644
--- a/noncore/net/mail/mail.pro
+++ b/noncore/net/mail/mail.pro
@@ -19,3 +19,4 @@ HEADERS = defines.h \
19 settingsdialog.h \ 19 settingsdialog.h \
20 statuswidget.h 20 statuswidget.h \
21 smtpwrapper.h
21 22
@@ -38,3 +39,4 @@ SOURCES = main.cpp \
38 settingsdialog.cpp \ 39 settingsdialog.cpp \
39 statuswidget.cpp 40 statuswidget.cpp \
41 smtpwrapper.cpp
40 42
diff --git a/noncore/net/mail/mailwrapper.cpp b/noncore/net/mail/mailwrapper.cpp
index 75c06f9..c5d4265 100644
--- a/noncore/net/mail/mailwrapper.cpp
+++ b/noncore/net/mail/mailwrapper.cpp
@@ -134,587 +134,2 @@ QString IMAPFolder::decodeFolderName( const QString &name )
134 134
135MailWrapper::MailWrapper( Settings *s )
136 : QObject()
137{
138 settings = s;
139}
140
141QString MailWrapper::mailsmtpError( int errnum )
142{
143 switch ( errnum ) {
144 case MAILSMTP_NO_ERROR:
145 return tr( "No error" );
146 case MAILSMTP_ERROR_UNEXPECTED_CODE:
147 return tr( "Unexpected error code" );
148 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
149 return tr( "Service not available" );
150 case MAILSMTP_ERROR_STREAM:
151 return tr( "Stream error" );
152 case MAILSMTP_ERROR_HOSTNAME:
153 return tr( "gethostname() failed" );
154 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
155 return tr( "Not implemented" );
156 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
157 return tr( "Error, action not taken" );
158 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
159 return tr( "Data exceeds storage allocation" );
160 case MAILSMTP_ERROR_IN_PROCESSING:
161 return tr( "Error in processing" );
162 // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
163 // return tr( "Insufficient system storage" );
164 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
165 return tr( "Mailbox unavailable" );
166 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
167 return tr( "Mailbox name not allowed" );
168 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
169 return tr( "Bad command sequence" );
170 case MAILSMTP_ERROR_USER_NOT_LOCAL:
171 return tr( "User not local" );
172 case MAILSMTP_ERROR_TRANSACTION_FAILED:
173 return tr( "Transaction failed" );
174 case MAILSMTP_ERROR_MEMORY:
175 return tr( "Memory error" );
176 case MAILSMTP_ERROR_CONNECTION_REFUSED:
177 return tr( "Connection refused" );
178 default:
179 return tr( "Unknown error code" );
180 }
181}
182
183mailimf_mailbox *MailWrapper::newMailbox(const QString&name, const QString&mail )
184{
185 return mailimf_mailbox_new( strdup( name.latin1() ),
186 strdup( mail.latin1() ) );
187}
188
189mailimf_address_list *MailWrapper::parseAddresses(const QString&addr )
190{
191 mailimf_address_list *addresses;
192
193 if ( addr.isEmpty() ) return NULL;
194
195 addresses = mailimf_address_list_new_empty();
196
197 QStringList list = QStringList::split( ',', addr );
198 QStringList::Iterator it;
199 for ( it = list.begin(); it != list.end(); it++ ) {
200 char *str = strdup( (*it).latin1() );
201 int err = mailimf_address_list_add_parse( addresses, str );
202 if ( err != MAILIMF_NO_ERROR ) {
203 qDebug( "Error parsing" );
204 qDebug( *it );
205 free( str );
206 } else {
207 qDebug( "Parse success! :)" );
208 }
209 }
210
211 return addresses;
212}
213
214mailimf_fields *MailWrapper::createImfFields( Mail *mail )
215{
216 mailimf_fields *fields;
217 mailimf_field *xmailer;
218 mailimf_mailbox *sender, *fromBox;
219 mailimf_mailbox_list *from;
220 mailimf_address_list *to, *cc, *bcc, *reply;
221 char *subject = strdup( mail->getSubject().latin1() );
222 int err;
223
224 sender = newMailbox( mail->getName(), mail->getMail() );
225 if ( sender == NULL ) goto err_free;
226
227 fromBox = newMailbox( mail->getName(), mail->getMail() );
228 if ( fromBox == NULL ) goto err_free_sender;
229
230 from = mailimf_mailbox_list_new_empty();
231 if ( from == NULL ) goto err_free_fromBox;
232
233 err = mailimf_mailbox_list_add( from, fromBox );
234 if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
235
236 to = parseAddresses( mail->getTo() );
237 if ( to == NULL ) goto err_free_from;
238
239 cc = parseAddresses( mail->getCC() );
240 bcc = parseAddresses( mail->getBCC() );
241 reply = parseAddresses( mail->getReply() );
242
243 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
244 NULL, NULL, subject );
245 if ( fields == NULL ) goto err_free_reply;
246
247 xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
248 strdup( USER_AGENT ) );
249 if ( xmailer == NULL ) goto err_free_fields;
250
251 err = mailimf_fields_add( fields, xmailer );
252 if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
253
254 return fields; // Success :)
255
256err_free_xmailer:
257 mailimf_field_free( xmailer );
258err_free_fields:
259 mailimf_fields_free( fields );
260err_free_reply:
261 mailimf_address_list_free( reply );
262 mailimf_address_list_free( bcc );
263 mailimf_address_list_free( cc );
264 mailimf_address_list_free( to );
265err_free_from:
266 mailimf_mailbox_list_free( from );
267err_free_fromBox:
268 mailimf_mailbox_free( fromBox );
269err_free_sender:
270 mailimf_mailbox_free( sender );
271err_free:
272 free( subject );
273 qDebug( "createImfFields - error" );
274
275 return NULL; // Error :(
276}
277
278mailmime *MailWrapper::buildTxtPart( QString str )
279{
280 mailmime *txtPart;
281 mailmime_fields *fields;
282 mailmime_content *content;
283 mailmime_parameter *param;
284 char *txt = strdup( str.latin1() );
285 int err;
286
287 param = mailmime_parameter_new( strdup( "charset" ),
288 strdup( "iso-8859-1" ) );
289 if ( param == NULL ) goto err_free;
290
291 content = mailmime_content_new_with_str( "text/plain" );
292 if ( content == NULL ) goto err_free_param;
293
294 err = clist_append( content->ct_parameters, param );
295 if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
296
297 fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
298 if ( fields == NULL ) goto err_free_content;
299
300 txtPart = mailmime_new_empty( content, fields );
301 if ( txtPart == NULL ) goto err_free_fields;
302
303 err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
304 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
305
306 return txtPart; // Success :)
307
308err_free_txtPart:
309 mailmime_free( txtPart );
310err_free_fields:
311 mailmime_fields_free( fields );
312err_free_content:
313 mailmime_content_free( content );
314err_free_param:
315 mailmime_parameter_free( param );
316err_free:
317 free( txt );
318 qDebug( "buildTxtPart - error" );
319
320 return NULL; // Error :(
321}
322
323mailmime *MailWrapper::buildFilePart( QString filename, QString mimetype )
324{
325 mailmime * filePart;
326 mailmime_fields * fields;
327 mailmime_content * content;
328 mailmime_parameter * param = NULL;
329 int err;
330
331 int pos = filename.findRev( '/' );
332 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
333 char *name = strdup( tmp.latin1() ); // just filename
334 char *file = strdup( filename.latin1() ); // full name with path
335 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
336
337 fields = mailmime_fields_new_filename(
338 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
339 MAILMIME_MECHANISM_BASE64 );
340 if ( fields == NULL ) goto err_free;
341
342 content = mailmime_content_new_with_str( mime );
343 if ( content == NULL ) goto err_free_fields;
344
345 if ( mimetype.compare( "text/plain" ) == 0 ) {
346 param = mailmime_parameter_new( strdup( "charset" ),
347 strdup( "iso-8859-1" ) );
348 if ( param == NULL ) goto err_free_content;
349
350 err = clist_append( content->ct_parameters, param );
351 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
352 }
353
354 filePart = mailmime_new_empty( content, fields );
355 if ( filePart == NULL ) goto err_free_param;
356
357 err = mailmime_set_body_file( filePart, file );
358 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
359
360 return filePart; // Success :)
361
362err_free_filePart:
363 mailmime_free( filePart );
364err_free_param:
365 if ( param != NULL ) mailmime_parameter_free( param );
366err_free_content:
367 mailmime_content_free( content );
368err_free_fields:
369 mailmime_fields_free( fields );
370err_free:
371 free( name );
372 free( mime );
373 free( file );
374 qDebug( "buildFilePart - error" );
375
376 return NULL; // Error :(
377}
378
379void MailWrapper::addFileParts( mailmime *message, QList<Attachment> files )
380{
381 Attachment *it;
382 for ( it = files.first(); it; it = files.next() ) {
383 qDebug( "Adding file" );
384 mailmime *filePart;
385 int err;
386
387 filePart = buildFilePart( it->getFileName(), it->getMimeType() );
388 if ( filePart == NULL ) goto err_free;
389
390 err = mailmime_smart_add_part( message, filePart );
391 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
392
393 continue; // Success :)
394
395 err_free_filePart:
396 mailmime_free( filePart );
397 err_free:
398 qDebug( "addFileParts: error adding file:" );
399 qDebug( it->getFileName() );
400 }
401}
402
403mailmime *MailWrapper::createMimeMail( Mail *mail )
404{
405 mailmime *message, *txtPart;
406 mailimf_fields *fields;
407 int err;
408
409 fields = createImfFields( mail );
410 if ( fields == NULL ) goto err_free;
411
412 message = mailmime_new_message_data( NULL );
413 if ( message == NULL ) goto err_free_fields;
414
415 mailmime_set_imf_fields( message, fields );
416
417 txtPart = buildTxtPart( mail->getMessage() );
418 if ( txtPart == NULL ) goto err_free_message;
419
420 err = mailmime_smart_add_part( message, txtPart );
421 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
422
423 addFileParts( message, mail->getAttachments() );
424
425 return message; // Success :)
426
427err_free_txtPart:
428 mailmime_free( txtPart );
429err_free_message:
430 mailmime_free( message );
431err_free_fields:
432 mailimf_fields_free( fields );
433err_free:
434 qDebug( "createMimeMail: error" );
435
436 return NULL; // Error :(
437}
438
439mailimf_field *MailWrapper::getField( mailimf_fields *fields, int type )
440{
441 mailimf_field *field;
442 clistiter *it;
443
444 it = clist_begin( fields->fld_list );
445 while ( it ) {
446 field = (mailimf_field *) it->data;
447 if ( field->fld_type == type ) {
448 return field;
449 }
450 it = it->next;
451 }
452
453 return NULL;
454}
455
456static void addRcpts( clist *list, mailimf_address_list *addr_list )
457{
458 clistiter *it, *it2;
459
460 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
461 mailimf_address *addr;
462 addr = (mailimf_address *) it->data;
463
464 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
465 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
466 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
467 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
468 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
469 mailimf_mailbox *mbox;
470 mbox = (mailimf_mailbox *) it2->data;
471 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
472 }
473 }
474 }
475}
476
477clist *MailWrapper::createRcptList( mailimf_fields *fields )
478{
479 clist *rcptList;
480 mailimf_field *field;
481
482 rcptList = esmtp_address_list_new();
483
484 field = getField( fields, MAILIMF_FIELD_TO );
485 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
486 && field->fld_data.fld_to->to_addr_list ) {
487 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
488 }
489
490 field = getField( fields, MAILIMF_FIELD_CC );
491 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
492 && field->fld_data.fld_cc->cc_addr_list ) {
493 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
494 }
495
496 field = getField( fields, MAILIMF_FIELD_BCC );
497 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
498 && field->fld_data.fld_bcc->bcc_addr_list ) {
499 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
500 }
501
502 return rcptList;
503}
504
505char *MailWrapper::getFrom( mailmime *mail )
506{
507 char *from = NULL;
508
509 mailimf_field *ffrom;
510 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
511 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
512 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
513 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
514 clistiter *it;
515 for ( it = clist_begin( cl ); it; it = it->next ) {
516 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
517 from = strdup( mb->mb_addr_spec );
518 }
519 }
520
521 return from;
522}
523
524SMTPaccount *MailWrapper::getAccount( QString from )
525{
526 SMTPaccount *smtp;
527
528 QList<Account> list = settings->getAccounts();
529 Account *it;
530 for ( it = list.first(); it; it = list.next() ) {
531 if ( it->getType().compare( "SMTP" ) == 0 ) {
532 smtp = static_cast<SMTPaccount *>(it);
533 if ( smtp->getMail().compare( from ) == 0 ) {
534 qDebug( "SMTPaccount found for" );
535 qDebug( from );
536 return smtp;
537 }
538 }
539 }
540
541 return NULL;
542}
543
544QString MailWrapper::getTmpFile() {
545 int num = 0;
546 QString unique;
547
548 QDir dir( "/tmp" );
549 QStringList::Iterator it;
550
551 QStringList list = dir.entryList( "opiemail-tmp-*" );
552 do {
553 unique.setNum( num++ );
554 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
555
556 return "/tmp/opiemail-tmp-" + unique;
557}
558
559void MailWrapper::writeToFile( QString file, mailmime *mail )
560{
561 FILE *f;
562 int err, col = 0;
563
564 f = fopen( file.latin1(), "w" );
565 if ( f == NULL ) {
566 qDebug( "writeToFile: error opening file" );
567 return;
568 }
569
570 err = mailmime_write( f, &col, mail );
571 if ( err != MAILIMF_NO_ERROR ) {
572 fclose( f );
573 qDebug( "writeToFile: error writing mailmime" );
574 return;
575 }
576
577 fclose( f );
578}
579
580void MailWrapper::readFromFile( QString file, char **data, size_t *size )
581{
582 char *buf;
583 struct stat st;
584 int fd, count = 0, total = 0;
585
586 fd = open( file.latin1(), O_RDONLY, 0 );
587 if ( fd == -1 ) return;
588
589 if ( fstat( fd, &st ) != 0 ) goto err_close;
590 if ( !st.st_size ) goto err_close;
591
592 buf = (char *) malloc( st.st_size );
593 if ( !buf ) goto err_close;
594
595 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
596 count = read( fd, buf + total, st.st_size - total );
597 total += count;
598 }
599 if ( count < 0 ) goto err_free;
600
601 *data = buf;
602 *size = st.st_size;
603
604 close( fd );
605
606 return; // Success :)
607
608err_free:
609 free( buf );
610err_close:
611 close( fd );
612}
613
614void progress( size_t current, size_t maximum )
615{
616 qDebug( "Current: %i of %i", current, maximum );
617}
618
619void MailWrapper::smtpSend( mailmime *mail )
620{
621 mailsmtp *session;
622 clist *rcpts;
623 char *from, *data, *server, *user = NULL, *pass = NULL;
624 size_t size;
625 int err;
626 bool ssl;
627 uint16_t port;
628
629
630 from = getFrom( mail );
631 SMTPaccount *smtp = getAccount( from );
632 if ( smtp == NULL ) {
633 free(from);
634 return;
635 }
636 server = strdup( smtp->getServer().latin1() );
637 ssl = smtp->getSSL();
638 port = smtp->getPort().toUInt();
639 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
640
641 QString file = getTmpFile();
642 writeToFile( file, mail );
643 readFromFile( file, &data, &size );
644 QFile f( file );
645 f.remove();
646
647 session = mailsmtp_new( 20, &progress );
648 if ( session == NULL ) goto free_mem;
649
650 qDebug( "Servername %s at port %i", server, port );
651 if ( ssl ) {
652 qDebug( "SSL session" );
653 err = mailsmtp_ssl_connect( session, server, port );
654 } else {
655 qDebug( "No SSL session" );
656 err = mailsmtp_socket_connect( session, server, port );
657 }
658 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
659
660 err = mailsmtp_init( session );
661 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
662
663 qDebug( "INIT OK" );
664
665 if ( smtp->getLogin() ) {
666 if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
667 // get'em
668 LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
669 login.show();
670 if ( QDialog::Accepted == login.exec() ) {
671 // ok
672 user = strdup( login.getUser().latin1() );
673 pass = strdup( login.getPassword().latin1() );
674 } else {
675 goto free_con_session;
676 }
677 } else {
678 user = strdup( smtp->getUser().latin1() );
679 pass = strdup( smtp->getPassword().latin1() );
680 }
681 qDebug( "session->auth: %i", session->auth);
682 err = mailsmtp_auth( session, user, pass );
683 if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
684 qDebug( "Done auth!" );
685 }
686
687 err = mailsmtp_send( session, from, rcpts, data, size );
688 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
689
690 qDebug( "Mail sent." );
691
692free_con_session:
693 mailsmtp_quit( session );
694free_mem_session:
695 mailsmtp_free( session );
696free_mem:
697 smtp_address_list_free( rcpts );
698 free( data );
699 free( server );
700 if ( smtp->getLogin() ) {
701 free( user );
702 free( pass );
703 }
704 free( from );
705}
706
707void MailWrapper::sendMail( Mail mail )
708{
709 mailmime *mimeMail;
710
711 mimeMail = createMimeMail( &mail );
712 if ( mimeMail == NULL ) {
713 qDebug( "sendMail: error creating mime mail" );
714 } else {
715 smtpSend( mimeMail );
716 mailmime_free( mimeMail );
717 }
718}
719
720Mail::Mail() 135Mail::Mail()
diff --git a/noncore/net/mail/mailwrapper.h b/noncore/net/mail/mailwrapper.h
index 02fe4b7..8fd886f 100644
--- a/noncore/net/mail/mailwrapper.h
+++ b/noncore/net/mail/mailwrapper.h
@@ -5,7 +5,2 @@
5 5
6#include <libetpan/mailmime.h>
7#include <libetpan/mailimf.h>
8#include <libetpan/mailsmtp.h>
9#include <libetpan/mailstorage.h>
10#include <libetpan/maildriver.h>
11#include <qbitarray.h> 6#include <qbitarray.h>
@@ -95,32 +90,2 @@ class IMAPFolder : public Folder
95 90
96class MailWrapper : public QObject
97{
98 Q_OBJECT
99
100public:
101 MailWrapper( Settings *s );
102 void sendMail( Mail mail );
103
104private:
105 mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
106 mailimf_address_list *parseAddresses(const QString&addr );
107 mailimf_fields *createImfFields( Mail *mail );
108 mailmime *buildTxtPart( QString str );
109 mailmime *buildFilePart( QString filename, QString mimetype );
110 void addFileParts( mailmime *message, QList<Attachment> files );
111 mailmime *createMimeMail( Mail *mail );
112 void smtpSend( mailmime *mail );
113 mailimf_field *getField( mailimf_fields *fields, int type );
114 clist *createRcptList( mailimf_fields *fields );
115 char *getFrom( mailmime *mail );
116 SMTPaccount *getAccount( QString from );
117 void writeToFile( QString file, mailmime *mail );
118 void readFromFile( QString file, char **data, size_t *size );
119 static QString mailsmtpError( int err );
120 static QString getTmpFile();
121
122 Settings *settings;
123
124};
125
126#endif 91#endif
diff --git a/noncore/net/mail/pop3wrapper.h b/noncore/net/mail/pop3wrapper.h
index a31a145..75d70f8 100644
--- a/noncore/net/mail/pop3wrapper.h
+++ b/noncore/net/mail/pop3wrapper.h
@@ -3,2 +3,3 @@
3 3
4#include <libetpan/clist.h>
4#include "mailwrapper.h" 5#include "mailwrapper.h"
@@ -15,2 +16,7 @@ struct mailmime;
15struct mailmime_mechanism; 16struct mailmime_mechanism;
17struct mailimf_mailbox_list;
18struct mailimf_mailbox;
19struct mailimf_date_time;
20struct mailimf_group;
21struct mailimf_address_list;
16 22
diff --git a/noncore/net/mail/smtpwrapper.cpp b/noncore/net/mail/smtpwrapper.cpp
new file mode 100644
index 0000000..162b1b9
--- a/dev/null
+++ b/noncore/net/mail/smtpwrapper.cpp
@@ -0,0 +1,604 @@
1#include <stdlib.h>
2#include <sys/stat.h>
3#include <sys/types.h>
4#include <unistd.h>
5#include <fcntl.h>
6#include <string.h>
7#include <qdir.h>
8
9#include <libetpan/mailmime.h>
10#include <libetpan/mailimf.h>
11#include <libetpan/mailsmtp.h>
12#include <libetpan/mailstorage.h>
13#include <libetpan/maildriver.h>
14
15#include "smtpwrapper.h"
16#include "mailwrapper.h"
17#include "logindialog.h"
18#include "defines.h"
19
20SMTPwrapper::SMTPwrapper( Settings *s )
21 : QObject()
22{
23 settings = s;
24}
25
26QString SMTPwrapper::mailsmtpError( int errnum )
27{
28 switch ( errnum ) {
29 case MAILSMTP_NO_ERROR:
30 return tr( "No error" );
31 case MAILSMTP_ERROR_UNEXPECTED_CODE:
32 return tr( "Unexpected error code" );
33 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
34 return tr( "Service not available" );
35 case MAILSMTP_ERROR_STREAM:
36 return tr( "Stream error" );
37 case MAILSMTP_ERROR_HOSTNAME:
38 return tr( "gethostname() failed" );
39 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
40 return tr( "Not implemented" );
41 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
42 return tr( "Error, action not taken" );
43 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
44 return tr( "Data exceeds storage allocation" );
45 case MAILSMTP_ERROR_IN_PROCESSING:
46 return tr( "Error in processing" );
47 // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
48 // return tr( "Insufficient system storage" );
49 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
50 return tr( "Mailbox unavailable" );
51 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
52 return tr( "Mailbox name not allowed" );
53 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
54 return tr( "Bad command sequence" );
55 case MAILSMTP_ERROR_USER_NOT_LOCAL:
56 return tr( "User not local" );
57 case MAILSMTP_ERROR_TRANSACTION_FAILED:
58 return tr( "Transaction failed" );
59 case MAILSMTP_ERROR_MEMORY:
60 return tr( "Memory error" );
61 case MAILSMTP_ERROR_CONNECTION_REFUSED:
62 return tr( "Connection refused" );
63 default:
64 return tr( "Unknown error code" );
65 }
66}
67
68mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail )
69{
70 return mailimf_mailbox_new( strdup( name.latin1() ),
71 strdup( mail.latin1() ) );
72}
73
74mailimf_address_list *SMTPwrapper::parseAddresses(const QString&addr )
75{
76 mailimf_address_list *addresses;
77
78 if ( addr.isEmpty() ) return NULL;
79
80 addresses = mailimf_address_list_new_empty();
81
82 QStringList list = QStringList::split( ',', addr );
83 QStringList::Iterator it;
84 for ( it = list.begin(); it != list.end(); it++ ) {
85 char *str = strdup( (*it).latin1() );
86 int err = mailimf_address_list_add_parse( addresses, str );
87 if ( err != MAILIMF_NO_ERROR ) {
88 qDebug( "Error parsing" );
89 qDebug( *it );
90 free( str );
91 } else {
92 qDebug( "Parse success! :)" );
93 }
94 }
95
96 return addresses;
97}
98
99mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail )
100{
101 mailimf_fields *fields;
102 mailimf_field *xmailer;
103 mailimf_mailbox *sender, *fromBox;
104 mailimf_mailbox_list *from;
105 mailimf_address_list *to, *cc, *bcc, *reply;
106 char *subject = strdup( mail.getSubject().latin1() );
107 int err;
108
109 sender = newMailbox( mail.getName(), mail.getMail() );
110 if ( sender == NULL ) goto err_free;
111
112 fromBox = newMailbox( mail.getName(), mail.getMail() );
113 if ( fromBox == NULL ) goto err_free_sender;
114
115 from = mailimf_mailbox_list_new_empty();
116 if ( from == NULL ) goto err_free_fromBox;
117
118 err = mailimf_mailbox_list_add( from, fromBox );
119 if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
120
121 to = parseAddresses( mail.getTo() );
122 if ( to == NULL ) goto err_free_from;
123
124 cc = parseAddresses( mail.getCC() );
125 bcc = parseAddresses( mail.getBCC() );
126 reply = parseAddresses( mail.getReply() );
127
128 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
129 NULL, NULL, subject );
130 if ( fields == NULL ) goto err_free_reply;
131
132 xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
133 strdup( USER_AGENT ) );
134 if ( xmailer == NULL ) goto err_free_fields;
135
136 err = mailimf_fields_add( fields, xmailer );
137 if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
138
139 return fields; // Success :)
140
141err_free_xmailer:
142 mailimf_field_free( xmailer );
143err_free_fields:
144 mailimf_fields_free( fields );
145err_free_reply:
146 mailimf_address_list_free( reply );
147 mailimf_address_list_free( bcc );
148 mailimf_address_list_free( cc );
149 mailimf_address_list_free( to );
150err_free_from:
151 mailimf_mailbox_list_free( from );
152err_free_fromBox:
153 mailimf_mailbox_free( fromBox );
154err_free_sender:
155 mailimf_mailbox_free( sender );
156err_free:
157 free( subject );
158 qDebug( "createImfFields - error" );
159
160 return NULL; // Error :(
161}
162
163mailmime *SMTPwrapper::buildTxtPart(const QString&str )
164{
165 mailmime *txtPart;
166 mailmime_fields *fields;
167 mailmime_content *content;
168 mailmime_parameter *param;
169 char *txt = strdup( str.latin1() );
170 int err;
171
172 param = mailmime_parameter_new( strdup( "charset" ),
173 strdup( "iso-8859-1" ) );
174 if ( param == NULL ) goto err_free;
175
176 content = mailmime_content_new_with_str( "text/plain" );
177 if ( content == NULL ) goto err_free_param;
178
179 err = clist_append( content->ct_parameters, param );
180 if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
181
182 fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
183 if ( fields == NULL ) goto err_free_content;
184
185 txtPart = mailmime_new_empty( content, fields );
186 if ( txtPart == NULL ) goto err_free_fields;
187
188 err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
189 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
190
191 return txtPart; // Success :)
192
193err_free_txtPart:
194 mailmime_free( txtPart );
195err_free_fields:
196 mailmime_fields_free( fields );
197err_free_content:
198 mailmime_content_free( content );
199err_free_param:
200 mailmime_parameter_free( param );
201err_free:
202 free( txt );
203 qDebug( "buildTxtPart - error" );
204
205 return NULL; // Error :(
206}
207
208mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype )
209{
210 mailmime * filePart;
211 mailmime_fields * fields;
212 mailmime_content * content;
213 mailmime_parameter * param = NULL;
214 int err;
215
216 int pos = filename.findRev( '/' );
217 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
218 char *name = strdup( tmp.latin1() ); // just filename
219 char *file = strdup( filename.latin1() ); // full name with path
220 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
221
222 fields = mailmime_fields_new_filename(
223 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
224 MAILMIME_MECHANISM_BASE64 );
225 if ( fields == NULL ) goto err_free;
226
227 content = mailmime_content_new_with_str( mime );
228 if ( content == NULL ) goto err_free_fields;
229
230 if ( mimetype.compare( "text/plain" ) == 0 ) {
231 param = mailmime_parameter_new( strdup( "charset" ),
232 strdup( "iso-8859-1" ) );
233 if ( param == NULL ) goto err_free_content;
234
235 err = clist_append( content->ct_parameters, param );
236 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
237 }
238
239 filePart = mailmime_new_empty( content, fields );
240 if ( filePart == NULL ) goto err_free_param;
241
242 err = mailmime_set_body_file( filePart, file );
243 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
244
245 return filePart; // Success :)
246
247err_free_filePart:
248 mailmime_free( filePart );
249err_free_param:
250 if ( param != NULL ) mailmime_parameter_free( param );
251err_free_content:
252 mailmime_content_free( content );
253err_free_fields:
254 mailmime_fields_free( fields );
255err_free:
256 free( name );
257 free( mime );
258 free( file );
259 qDebug( "buildFilePart - error" );
260
261 return NULL; // Error :(
262}
263
264void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files )
265{
266 const Attachment *it;
267 /* work around for the brainfucked qlist which can not act with const values */
268 for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) {
269 qDebug( "Adding file" );
270 mailmime *filePart;
271 int err;
272
273 filePart = buildFilePart( it->getFileName(), it->getMimeType() );
274 if ( filePart == NULL ) goto err_free;
275
276 err = mailmime_smart_add_part( message, filePart );
277 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
278
279 continue; // Success :)
280
281 err_free_filePart:
282 mailmime_free( filePart );
283 err_free:
284 qDebug( "addFileParts: error adding file:" );
285 qDebug( it->getFileName() );
286 }
287}
288
289mailmime *SMTPwrapper::createMimeMail(const Mail &mail )
290{
291 mailmime *message, *txtPart;
292 mailimf_fields *fields;
293 int err;
294
295 fields = createImfFields( mail );
296 if ( fields == NULL ) goto err_free;
297
298 message = mailmime_new_message_data( NULL );
299 if ( message == NULL ) goto err_free_fields;
300
301 mailmime_set_imf_fields( message, fields );
302
303 txtPart = buildTxtPart( mail.getMessage() );
304 if ( txtPart == NULL ) goto err_free_message;
305
306 err = mailmime_smart_add_part( message, txtPart );
307 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
308
309 addFileParts( message, mail.getAttachments() );
310
311 return message; // Success :)
312
313err_free_txtPart:
314 mailmime_free( txtPart );
315err_free_message:
316 mailmime_free( message );
317err_free_fields:
318 mailimf_fields_free( fields );
319err_free:
320 qDebug( "createMimeMail: error" );
321
322 return NULL; // Error :(
323}
324
325mailimf_field *SMTPwrapper::getField( mailimf_fields *fields, int type )
326{
327 mailimf_field *field;
328 clistiter *it;
329
330 it = clist_begin( fields->fld_list );
331 while ( it ) {
332 field = (mailimf_field *) it->data;
333 if ( field->fld_type == type ) {
334 return field;
335 }
336 it = it->next;
337 }
338
339 return NULL;
340}
341
342void SMTPwrapper::addRcpts( clist *list, mailimf_address_list *addr_list )
343{
344 clistiter *it, *it2;
345
346 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
347 mailimf_address *addr;
348 addr = (mailimf_address *) it->data;
349
350 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
351 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
352 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
353 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
354 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
355 mailimf_mailbox *mbox;
356 mbox = (mailimf_mailbox *) it2->data;
357 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
358 }
359 }
360 }
361}
362
363clist *SMTPwrapper::createRcptList( mailimf_fields *fields )
364{
365 clist *rcptList;
366 mailimf_field *field;
367
368 rcptList = esmtp_address_list_new();
369
370 field = getField( fields, MAILIMF_FIELD_TO );
371 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
372 && field->fld_data.fld_to->to_addr_list ) {
373 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
374 }
375
376 field = getField( fields, MAILIMF_FIELD_CC );
377 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
378 && field->fld_data.fld_cc->cc_addr_list ) {
379 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
380 }
381
382 field = getField( fields, MAILIMF_FIELD_BCC );
383 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
384 && field->fld_data.fld_bcc->bcc_addr_list ) {
385 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
386 }
387
388 return rcptList;
389}
390
391char *SMTPwrapper::getFrom( mailmime *mail )
392{
393 char *from = NULL;
394
395 mailimf_field *ffrom;
396 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
397 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
398 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
399 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
400 clistiter *it;
401 for ( it = clist_begin( cl ); it; it = it->next ) {
402 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
403 from = strdup( mb->mb_addr_spec );
404 }
405 }
406
407 return from;
408}
409
410SMTPaccount *SMTPwrapper::getAccount(const QString&from )
411{
412 SMTPaccount *smtp;
413
414 QList<Account> list = settings->getAccounts();
415 Account *it;
416 for ( it = list.first(); it; it = list.next() ) {
417 if ( it->getType().compare( "SMTP" ) == 0 ) {
418 smtp = static_cast<SMTPaccount *>(it);
419 if ( smtp->getMail().compare( from ) == 0 ) {
420 qDebug( "SMTPaccount found for" );
421 qDebug( from );
422 return smtp;
423 }
424 }
425 }
426
427 return NULL;
428}
429
430QString SMTPwrapper::getTmpFile() {
431 int num = 0;
432 QString unique;
433
434 QDir dir( "/tmp" );
435 QStringList::Iterator it;
436
437 QStringList list = dir.entryList( "opiemail-tmp-*" );
438 do {
439 unique.setNum( num++ );
440 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
441
442 return "/tmp/opiemail-tmp-" + unique;
443}
444
445void SMTPwrapper::writeToFile(const QString&file, mailmime *mail )
446{
447 FILE *f;
448 int err, col = 0;
449
450 f = fopen( file.latin1(), "w" );
451 if ( f == NULL ) {
452 qDebug( "writeToFile: error opening file" );
453 return;
454 }
455
456 err = mailmime_write( f, &col, mail );
457 if ( err != MAILIMF_NO_ERROR ) {
458 fclose( f );
459 qDebug( "writeToFile: error writing mailmime" );
460 return;
461 }
462
463 fclose( f );
464}
465
466void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size )
467{
468 char *buf;
469 struct stat st;
470 int fd, count = 0, total = 0;
471
472 fd = open( file.latin1(), O_RDONLY, 0 );
473 if ( fd == -1 ) return;
474
475 if ( fstat( fd, &st ) != 0 ) goto err_close;
476 if ( !st.st_size ) goto err_close;
477
478 buf = (char *) malloc( st.st_size );
479 if ( !buf ) goto err_close;
480
481 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
482 count = read( fd, buf + total, st.st_size - total );
483 total += count;
484 }
485 if ( count < 0 ) goto err_free;
486
487 *data = buf;
488 *size = st.st_size;
489
490 close( fd );
491
492 return; // Success :)
493
494err_free:
495 free( buf );
496err_close:
497 close( fd );
498}
499
500void SMTPwrapper::progress( size_t current, size_t maximum )
501{
502 qDebug( "Current: %i of %i", current, maximum );
503}
504
505void SMTPwrapper::smtpSend( mailmime *mail )
506{
507 mailsmtp *session;
508 clist *rcpts;
509 char *from, *data, *server, *user = NULL, *pass = NULL;
510 size_t size;
511 int err;
512 bool ssl;
513 uint16_t port;
514
515
516 from = getFrom( mail );
517 SMTPaccount *smtp = getAccount( from );
518 if ( smtp == NULL ) {
519 free(from);
520 return;
521 }
522 server = strdup( smtp->getServer().latin1() );
523 ssl = smtp->getSSL();
524 port = smtp->getPort().toUInt();
525 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
526
527 QString file = getTmpFile();
528 writeToFile( file, mail );
529 readFromFile( file, &data, &size );
530 QFile f( file );
531 f.remove();
532
533 session = mailsmtp_new( 20, &progress );
534 if ( session == NULL ) goto free_mem;
535
536 qDebug( "Servername %s at port %i", server, port );
537 if ( ssl ) {
538 qDebug( "SSL session" );
539 err = mailsmtp_ssl_connect( session, server, port );
540 } else {
541 qDebug( "No SSL session" );
542 err = mailsmtp_socket_connect( session, server, port );
543 }
544 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
545
546 err = mailsmtp_init( session );
547 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
548
549 qDebug( "INIT OK" );
550
551 if ( smtp->getLogin() ) {
552 if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
553 // get'em
554 LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
555 login.show();
556 if ( QDialog::Accepted == login.exec() ) {
557 // ok
558 user = strdup( login.getUser().latin1() );
559 pass = strdup( login.getPassword().latin1() );
560 } else {
561 goto free_con_session;
562 }
563 } else {
564 user = strdup( smtp->getUser().latin1() );
565 pass = strdup( smtp->getPassword().latin1() );
566 }
567 qDebug( "session->auth: %i", session->auth);
568 err = mailsmtp_auth( session, user, pass );
569 if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
570 qDebug( "Done auth!" );
571 }
572
573 err = mailsmtp_send( session, from, rcpts, data, size );
574 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
575
576 qDebug( "Mail sent." );
577
578free_con_session:
579 mailsmtp_quit( session );
580free_mem_session:
581 mailsmtp_free( session );
582free_mem:
583 smtp_address_list_free( rcpts );
584 free( data );
585 free( server );
586 if ( smtp->getLogin() ) {
587 free( user );
588 free( pass );
589 }
590 free( from );
591}
592
593void SMTPwrapper::sendMail(const Mail&mail )
594{
595 mailmime *mimeMail;
596
597 mimeMail = createMimeMail(mail );
598 if ( mimeMail == NULL ) {
599 qDebug( "sendMail: error creating mime mail" );
600 } else {
601 smtpSend( mimeMail );
602 mailmime_free( mimeMail );
603 }
604}
diff --git a/noncore/net/mail/smtpwrapper.h b/noncore/net/mail/smtpwrapper.h
new file mode 100644
index 0000000..8fdb07d
--- a/dev/null
+++ b/noncore/net/mail/smtpwrapper.h
@@ -0,0 +1,53 @@
1#ifndef SMTPwrapper_H
2#define SMTPwrapper_H
3
4#include <qpe/applnk.h>
5
6#include <qbitarray.h>
7#include <qdatetime.h>
8#include <libetpan/clist.h>
9
10#include "settings.h"
11
12class Mail;
13class Attachment;
14struct mailimf_fields;
15struct mailimf_field;
16struct mailimf_mailbox;
17struct mailmime;
18struct mailimf_address_list;
19
20class SMTPwrapper : public QObject
21{
22 Q_OBJECT
23
24public:
25 SMTPwrapper( Settings *s );
26 virtual ~SMTPwrapper(){}
27 void sendMail(const Mail& mail );
28
29protected:
30 mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
31 mailimf_fields *createImfFields(const Mail &mail );
32 mailmime *createMimeMail(const Mail&mail );
33
34 mailimf_address_list *parseAddresses(const QString&addr );
35 void addFileParts( mailmime *message,const QList<Attachment>&files );
36 mailmime *buildTxtPart(const QString&str );
37 mailmime *buildFilePart(const QString&filename,const QString&mimetype );
38 void smtpSend( mailmime *mail );
39 mailimf_field *getField( mailimf_fields *fields, int type );
40 clist *createRcptList( mailimf_fields *fields );
41 char *getFrom( mailmime *mail );
42 SMTPaccount *getAccount(const QString&from );
43 void writeToFile(const QString&file, mailmime *mail );
44 void readFromFile(const QString&file, char **data, size_t *size );
45
46 static QString mailsmtpError( int err );
47 static QString getTmpFile();
48 static void progress( size_t current, size_t maximum );
49 static void addRcpts( clist *list, mailimf_address_list *addr_list );
50 Settings *settings;
51};
52
53#endif