summaryrefslogtreecommitdiff
path: root/noncore/net/mail/libmailwrapper/mailwrapper.cpp
Unidiff
Diffstat (limited to 'noncore/net/mail/libmailwrapper/mailwrapper.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.cpp585
1 files changed, 0 insertions, 585 deletions
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
@@ -132,591 +132,6 @@ QString IMAPFolder::decodeFolderName( const QString &name )
132 return QString::fromUtf8( dst.data() ); 132 return QString::fromUtf8( dst.data() );
133} 133}
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()
721 :name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("") 136 :name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("")
722{ 137{