summaryrefslogtreecommitdiff
path: root/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
Unidiff
Diffstat (limited to 'noncore/net/mail/libmailwrapper/smtpwrapper.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.cpp333
1 files changed, 201 insertions, 132 deletions
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
index a6a46ba..b81a87f 100644
--- a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
@@ -5,19 +5,15 @@
5#include <fcntl.h> 5#include <fcntl.h>
6#include <string.h> 6#include <string.h>
7#include <qdir.h> 7#include <qdir.h>
8#include <qt.h>
8 9
9#include <libetpan/libetpan.h> 10#include <libetpan/libetpan.h>
10#if 0
11#include <libetpan/mailimf.h>
12#include <libetpan/mailsmtp.h>
13#include <libetpan/mailstorage.h>
14#include <libetpan/maildriver.h>
15#endif
16 11
17#include "smtpwrapper.h" 12#include "smtpwrapper.h"
18#include "mailwrapper.h" 13#include "mailwrapper.h"
19#include "mboxwrapper.h" 14#include "mboxwrapper.h"
20#include "logindialog.h" 15#include "logindialog.h"
16#include "mailtypes.h"
21#include "defines.h" 17#include "defines.h"
22 18
23SMTPwrapper::SMTPwrapper( Settings *s ) 19SMTPwrapper::SMTPwrapper( Settings *s )
@@ -208,84 +204,113 @@ err_free:
208 return NULL; // Error :( 204 return NULL; // Error :(
209} 205}
210 206
211mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype ) 207mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype,const QString&TextContent )
212{ 208{
213 mailmime * filePart; 209 mailmime * filePart = 0;
214 mailmime_fields * fields; 210 mailmime_fields * fields = 0;
215 mailmime_content * content; 211 mailmime_content * content = 0;
216 mailmime_parameter * param = NULL; 212 mailmime_parameter * param = 0;
213 char*name = 0;
214 char*file = 0;
217 int err; 215 int err;
218 216
219 int pos = filename.findRev( '/' ); 217 int pos = filename.findRev( '/' );
220 QString tmp = filename.right( filename.length() - ( pos + 1 ) ); 218
221 char *name = strdup( tmp.latin1() ); // just filename 219 if (filename.length()>0) {
222 char *file = strdup( filename.latin1() ); // full name with path 220 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
221 name = strdup( tmp.latin1() ); // just filename
222 file = strdup( filename.latin1() ); // full name with path
223 }
223 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain 224 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
224 225
225 fields = mailmime_fields_new_filename( 226 int disptype = MAILMIME_DISPOSITION_TYPE_ATTACHMENT;
226 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name, 227 int mechanism = MAILMIME_MECHANISM_BASE64;
227 MAILMIME_MECHANISM_BASE64 ); 228
228 if ( fields == NULL ) goto err_free; 229 if ( mimetype.startsWith( "text/" ) ) {
229
230 content = mailmime_content_new_with_str( mime );
231 if ( content == NULL ) goto err_free_fields;
232
233 if ( mimetype.compare( "text/plain" ) == 0 ) {
234 param = mailmime_parameter_new( strdup( "charset" ), 230 param = mailmime_parameter_new( strdup( "charset" ),
235 strdup( "iso-8859-1" ) ); 231 strdup( "iso-8859-1" ) );
236 if ( param == NULL ) goto err_free_content; 232 disptype = MAILMIME_DISPOSITION_TYPE_INLINE;
237 233 mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
238 err = clist_append( content->ct_parameters, param );
239 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
240 } 234 }
241 235
242 filePart = mailmime_new_empty( content, fields ); 236 fields = mailmime_fields_new_filename(
243 if ( filePart == NULL ) goto err_free_param; 237 disptype, name,
244 238 mechanism );
245 err = mailmime_set_body_file( filePart, file ); 239 content = mailmime_content_new_with_str( mime );
246 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart; 240 if (content!=0 && fields != 0) {
241 if (param) {
242 clist_append(content->ct_parameters,param);
243 param = 0;
244 }
245 if (filename.length()>0) {
246 QFileInfo f(filename);
247 param = mailmime_parameter_new(strdup("name"),strdup(f.fileName().latin1()));
248 clist_append(content->ct_parameters,param);
249 param = 0;
250 }
251 filePart = mailmime_new_empty( content, fields );
252 }
253 if (filePart) {
254 if (filename.length()>0) {
255 err = mailmime_set_body_file( filePart, file );
256 } else {
257 err = mailmime_set_body_text(filePart,strdup(TextContent.ascii()),TextContent.length());
258 }
259 if (err != MAILIMF_NO_ERROR) {
260 qDebug("Error setting body with file %s",file);
261 mailmime_free( filePart );
262 filePart = 0;
263 }
264 }
247 265
266 if (!filePart) {
267 if ( param != NULL ) {
268 mailmime_parameter_free( param );
269 }
270 if (content) {
271 mailmime_content_free( content );
272 } else {
273 if (mime) {
274 free( mime );
275 }
276 }
277 if (fields) {
278 mailmime_fields_free( fields );
279 } else {
280 if (name) {
281 free( name );
282 }
283 if (file) {
284 free( file );
285 }
286 }
287 }
248 return filePart; // Success :) 288 return filePart; // Success :)
249 289
250err_free_filePart:
251 mailmime_free( filePart );
252err_free_param:
253 if ( param != NULL ) mailmime_parameter_free( param );
254err_free_content:
255 mailmime_content_free( content );
256err_free_fields:
257 mailmime_fields_free( fields );
258err_free:
259 free( name );
260 free( mime );
261 free( file );
262 qDebug( "buildFilePart - error" );
263
264 return NULL; // Error :(
265} 290}
266 291
267void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files ) 292void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files )
268{ 293{
269 const Attachment *it; 294 const Attachment *it;
270 /* work around for the brainfucked qlist which can not act with const values */ 295 unsigned int count = files.count();
271 for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) { 296 qDebug("List contains %i values",count);
297 for ( unsigned int i = 0; i < count; ++i ) {
272 qDebug( "Adding file" ); 298 qDebug( "Adding file" );
273 mailmime *filePart; 299 mailmime *filePart;
274 int err; 300 int err;
301 it = ((QList<Attachment>)files).at(i);
275 302
276 filePart = buildFilePart( it->getFileName(), it->getMimeType() ); 303 filePart = buildFilePart( it->getFileName(), it->getMimeType(),"" );
277 if ( filePart == NULL ) goto err_free; 304 if ( filePart == NULL ) {
278 305 qDebug( "addFileParts: error adding file:" );
306 qDebug( it->getFileName() );
307 continue;
308 }
279 err = mailmime_smart_add_part( message, filePart ); 309 err = mailmime_smart_add_part( message, filePart );
280 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart; 310 if ( err != MAILIMF_NO_ERROR ) {
281 311 mailmime_free( filePart );
282 continue; // Success :) 312 qDebug("error smart add");
283 313 }
284 err_free_filePart:
285 mailmime_free( filePart );
286 err_free:
287 qDebug( "addFileParts: error adding file:" );
288 qDebug( it->getFileName() );
289 } 314 }
290} 315}
291 316
@@ -303,7 +328,11 @@ mailmime *SMTPwrapper::createMimeMail(const Mail &mail )
303 328
304 mailmime_set_imf_fields( message, fields ); 329 mailmime_set_imf_fields( message, fields );
305 330
306 txtPart = buildTxtPart( mail.getMessage() ); 331 if (mail.getAttachments().count()==0) {
332 txtPart = buildTxtPart( mail.getMessage() );
333 } else {
334 txtPart = buildFilePart("","text/plain",mail.getMessage());
335 }
307 if ( txtPart == NULL ) goto err_free_message; 336 if ( txtPart == NULL ) goto err_free_message;
308 337
309 err = mailmime_smart_add_part( message, txtPart ); 338 err = mailmime_smart_add_part( message, txtPart );
@@ -391,12 +420,9 @@ clist *SMTPwrapper::createRcptList( mailimf_fields *fields )
391 return rcptList; 420 return rcptList;
392} 421}
393 422
394char *SMTPwrapper::getFrom( mailmime *mail ) 423char *SMTPwrapper::getFrom( mailimf_field *ffrom)
395{ 424{
396 char *from = NULL; 425 char *from = NULL;
397
398 mailimf_field *ffrom;
399 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
400 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM) 426 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
401 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) { 427 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
402 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list; 428 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
@@ -410,7 +436,14 @@ char *SMTPwrapper::getFrom( mailmime *mail )
410 return from; 436 return from;
411} 437}
412 438
413SMTPaccount *SMTPwrapper::getAccount(const QString&from ) 439char *SMTPwrapper::getFrom( mailmime *mail )
440{
441 mailimf_field *ffrom = 0;
442 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
443 return getFrom(ffrom);
444}
445
446SMTPaccount *SMTPwrapper::getAccount(const QString&name )
414{ 447{
415 SMTPaccount *smtp; 448 SMTPaccount *smtp;
416 449
@@ -419,9 +452,9 @@ SMTPaccount *SMTPwrapper::getAccount(const QString&from )
419 for ( it = list.first(); it; it = list.next() ) { 452 for ( it = list.first(); it; it = list.next() ) {
420 if ( it->getType().compare( "SMTP" ) == 0 ) { 453 if ( it->getType().compare( "SMTP" ) == 0 ) {
421 smtp = static_cast<SMTPaccount *>(it); 454 smtp = static_cast<SMTPaccount *>(it);
422 if ( smtp->getMail().compare( from ) == 0 ) { 455 if ( smtp->getName()== name ) {
423 qDebug( "SMTPaccount found for" ); 456 qDebug( "SMTPaccount found for" );
424 qDebug( from ); 457 qDebug( name );
425 return smtp; 458 return smtp;
426 } 459 }
427 } 460 }
@@ -435,9 +468,9 @@ QString SMTPwrapper::getTmpFile() {
435 QString unique; 468 QString unique;
436 469
437 QDir dir( "/tmp" ); 470 QDir dir( "/tmp" );
438 QStringList::Iterator it;
439 471
440 QStringList list = dir.entryList( "opiemail-tmp-*" ); 472 QStringList list = dir.entryList( "opiemail-tmp-*" );
473
441 do { 474 do {
442 unique.setNum( num++ ); 475 unique.setNum( num++ );
443 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 ); 476 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
@@ -483,44 +516,11 @@ void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size )
483 memset(*data,0,msg.length()+1); 516 memset(*data,0,msg.length()+1);
484 memcpy(*data,msg.ascii(),msg.length()); 517 memcpy(*data,msg.ascii(),msg.length());
485 *size=msg.length(); 518 *size=msg.length();
486
487#if 0
488 char *buf;
489 struct stat st;
490 int fd, count = 0, total = 0;
491
492 fd = open( file.latin1(), O_RDONLY, 0 );
493 if ( fd == -1 ) return;
494
495 if ( fstat( fd, &st ) != 0 ) goto err_close;
496 if ( !st.st_size ) goto err_close;
497
498 buf = (char *) malloc( st.st_size );
499 if ( !buf ) goto err_close;
500
501 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
502 count = read( fd, buf + total, st.st_size - total );
503 total += count;
504 }
505 if ( count < 0 ) goto err_free;
506
507 *data = buf;
508 *size = st.st_size;
509
510 close( fd );
511
512 return; // Success :)
513
514err_free:
515 free( buf );
516err_close:
517 close( fd );
518#endif
519} 519}
520 520
521void SMTPwrapper::progress( size_t current, size_t maximum ) 521void SMTPwrapper::progress( size_t current, size_t maximum )
522{ 522{
523 qDebug( "Current: %i of %i", current, maximum ); 523// qDebug( "Current: %i of %i", current, maximum );
524} 524}
525 525
526void SMTPwrapper::storeMail(char*mail, size_t length, const QString&box) 526void SMTPwrapper::storeMail(char*mail, size_t length, const QString&box)
@@ -532,40 +532,43 @@ void SMTPwrapper::storeMail(char*mail, size_t length, const QString&box)
532 delete wrap; 532 delete wrap;
533} 533}
534 534
535void SMTPwrapper::smtpSend( mailmime *mail,bool later ) 535void SMTPwrapper::smtpSend( mailmime *mail,bool later, SMTPaccount *smtp )
536{ 536{
537 mailsmtp *session; 537 clist *rcpts = 0;
538 clist *rcpts; 538 char *from, *data;
539 char *from, *data, *server, *user = NULL, *pass = NULL;
540 size_t size; 539 size_t size;
541 int err;
542 bool ssl;
543 uint16_t port;
544 540
545
546 from = getFrom( mail );
547 SMTPaccount *smtp = getAccount( from );
548 if ( smtp == NULL ) { 541 if ( smtp == NULL ) {
549 free(from);
550 return; 542 return;
551 } 543 }
552 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields ); 544 from = data = 0;
553 545
554 QString file = getTmpFile(); 546 QString file = getTmpFile();
555 writeToFile( file, mail ); 547 writeToFile( file, mail );
556
557 readFromFile( file, &data, &size ); 548 readFromFile( file, &data, &size );
558 QFile f( file ); 549 QFile f( file );
559 f.remove(); 550 f.remove();
560 551
561 storeMail(data,size,(later?"Outgoing":"Sent"));
562
563 if (later) { 552 if (later) {
564 smtp_address_list_free( rcpts ); 553 storeMail(data,size,"Outgoing");
565 if (data) free( data ); 554 if (data) free( data );
566 if (from) free(from);
567 return; 555 return;
568 } 556 }
557 from = getFrom( mail );
558 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
559 smtpSend(from,rcpts,data,size,smtp);
560}
561
562int SMTPwrapper::smtpSend(char*from,clist*rcpts,char*data,size_t size, SMTPaccount *smtp )
563{
564 char *server, *user, *pass;
565 bool ssl;
566 uint16_t port;
567 mailsmtp *session;
568 int err,result;
569
570 result = 1;
571 server = user = pass = 0;
569 server = strdup( smtp->getServer().latin1() ); 572 server = strdup( smtp->getServer().latin1() );
570 ssl = smtp->getSSL(); 573 ssl = smtp->getSSL();
571 port = smtp->getPort().toUInt(); 574 port = smtp->getPort().toUInt();
@@ -581,10 +584,10 @@ void SMTPwrapper::smtpSend( mailmime *mail,bool later )
581 qDebug( "No SSL session" ); 584 qDebug( "No SSL session" );
582 err = mailsmtp_socket_connect( session, server, port ); 585 err = mailsmtp_socket_connect( session, server, port );
583 } 586 }
584 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session; 587 if ( err != MAILSMTP_NO_ERROR ) {result = 0;goto free_mem_session;}
585 588
586 err = mailsmtp_init( session ); 589 err = mailsmtp_init( session );
587 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session; 590 if ( err != MAILSMTP_NO_ERROR ) {result = 0; goto free_con_session;}
588 591
589 qDebug( "INIT OK" ); 592 qDebug( "INIT OK" );
590 593
@@ -598,7 +601,7 @@ void SMTPwrapper::smtpSend( mailmime *mail,bool later )
598 user = strdup( login.getUser().latin1() ); 601 user = strdup( login.getUser().latin1() );
599 pass = strdup( login.getPassword().latin1() ); 602 pass = strdup( login.getPassword().latin1() );
600 } else { 603 } else {
601 goto free_con_session; 604 result = 0; goto free_con_session;
602 } 605 }
603 } else { 606 } else {
604 user = strdup( smtp->getUser().latin1() ); 607 user = strdup( smtp->getUser().latin1() );
@@ -611,35 +614,101 @@ void SMTPwrapper::smtpSend( mailmime *mail,bool later )
611 } 614 }
612 615
613 err = mailsmtp_send( session, from, rcpts, data, size ); 616 err = mailsmtp_send( session, from, rcpts, data, size );
614 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session; 617 if ( err != MAILSMTP_NO_ERROR ) {result = 0; goto free_con_session;}
615 618
616 qDebug( "Mail sent." ); 619 qDebug( "Mail sent." );
620 storeMail(data,size,"Sent");
617 621
618free_con_session: 622free_con_session:
619 mailsmtp_quit( session ); 623 mailsmtp_quit( session );
620free_mem_session: 624free_mem_session:
621 mailsmtp_free( session ); 625 mailsmtp_free( session );
622free_mem: 626free_mem:
623 smtp_address_list_free( rcpts ); 627 if (rcpts) smtp_address_list_free( rcpts );
624 if (data) free( data ); 628 if (data) free( data );
625 if (from) free(from);
626 if (server) free( server ); 629 if (server) free( server );
630 if (from) free( from );
627 if ( smtp->getLogin() ) { 631 if ( smtp->getLogin() ) {
628 free( user ); 632 free( user );
629 free( pass ); 633 free( pass );
630 } 634 }
631 free( from ); 635 return result;
632} 636}
633 637
634void SMTPwrapper::sendMail(const Mail&mail,bool later ) 638void SMTPwrapper::sendMail(const Mail&mail,bool later )
635{ 639{
636 mailmime * mimeMail; 640 mailmime * mimeMail;
637 641
642 SMTPaccount *smtp = getAccount(mail.getName());
643
638 mimeMail = createMimeMail(mail ); 644 mimeMail = createMimeMail(mail );
639 if ( mimeMail == NULL ) { 645 if ( mimeMail == NULL ) {
640 qDebug( "sendMail: error creating mime mail" ); 646 qDebug( "sendMail: error creating mime mail" );
641 } else { 647 } else {
642 smtpSend( mimeMail,later ); 648 smtpSend( mimeMail,later,smtp);
643 mailmime_free( mimeMail ); 649 mailmime_free( mimeMail );
650 qDebug("Clean up done");
651 }
652}
653
654int SMTPwrapper::sendQueuedMail(MBOXwrapper*wrap,SMTPaccount*smtp,RecMail*which)
655{
656 char*data = 0;
657 size_t length = 0;
658 size_t curTok = 0;
659 mailimf_fields *fields = 0;
660 mailimf_field*ffrom = 0;
661 clist *rcpts = 0;
662 char*from = 0;
663
664 wrap->fetchRawBody(*which,&data,&length);
665 if (!data) return 0;
666 int err = mailimf_fields_parse( data, length, &curTok, &fields );
667 if (err != MAILIMF_NO_ERROR) {
668 free(data);
669 delete wrap;
670 return 0;
671 }
672
673 rcpts = createRcptList( fields );
674 ffrom = getField(fields, MAILIMF_FIELD_FROM );
675 from = getFrom(ffrom);
676 qDebug("Size: %i vs. %i",length,strlen(data));
677 if (rcpts && from) {
678 return smtpSend(from,rcpts,data,strlen(data),smtp );
644 } 679 }
680 return 0;
681}
682
683/* this is a special fun */
684void SMTPwrapper::flushOutbox(SMTPaccount*smtp)
685{
686 if (!smtp) return;
687 QString localfolders = (QString) getenv( "HOME" ) + QString("/Applications/opiemail/localmail/");
688 MBOXwrapper*wrap = new MBOXwrapper(localfolders);
689 if (!wrap) {
690 qDebug("memory error");
691 return;
692 }
693 QList<RecMail> mailsToSend;
694 QList<RecMail> mailsToRemove;
695 QString mbox("Outgoing");
696 wrap->listMessages(mbox,mailsToSend);
697 if (mailsToSend.count()==0) {
698 delete wrap;
699 return;
700 }
701 mailsToSend.setAutoDelete(false);
702 while (mailsToSend.count()>0) {
703 if (sendQueuedMail(wrap,smtp,mailsToSend.at(0))==0) {
704 QMessageBox::critical(0,tr("Error sending mail"),
705 tr("Error sending queued mail - breaking"));
706 break;
707 }
708 mailsToRemove.append(mailsToSend.at(0));
709 mailsToSend.removeFirst();
710 }
711 wrap->deleteMails(mbox,mailsToRemove);
712 mailsToSend.setAutoDelete(true);
713 delete wrap;
645} 714}