author | alwin <alwin> | 2003-12-21 10:36:22 (UTC) |
---|---|---|
committer | alwin <alwin> | 2003-12-21 10:36:22 (UTC) |
commit | af0b88049e0c77cb90ef1aca608accc32a2e2828 (patch) (unidiff) | |
tree | ad8a2ce76ae1ab3cf535f4d1d7addbc240ff4209 | |
parent | 8e884631cc002011a9abab37be9223d4a1421ff2 (diff) | |
download | opie-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.
-rw-r--r-- | noncore/net/mail/abstractmail.cpp | 1 | ||||
-rw-r--r-- | noncore/net/mail/composemail.cpp | 3 | ||||
-rw-r--r-- | noncore/net/mail/imapwrapper.cpp | 3 | ||||
-rw-r--r-- | noncore/net/mail/imapwrapper.h | 1 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/abstractmail.cpp | 1 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.cpp | 3 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.h | 1 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/mailwrapper.cpp | 585 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/mailwrapper.h | 35 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/pop3wrapper.h | 6 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/smtpwrapper.cpp | 604 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/smtpwrapper.h | 53 | ||||
-rw-r--r-- | noncore/net/mail/mail.pro | 6 | ||||
-rw-r--r-- | noncore/net/mail/mailwrapper.cpp | 585 | ||||
-rw-r--r-- | noncore/net/mail/mailwrapper.h | 35 | ||||
-rw-r--r-- | noncore/net/mail/pop3wrapper.h | 6 | ||||
-rw-r--r-- | noncore/net/mail/smtpwrapper.cpp | 604 | ||||
-rw-r--r-- | noncore/net/mail/smtpwrapper.h | 53 |
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 | ||
135 | MailWrapper::MailWrapper( Settings *s ) | ||
136 | : QObject() | ||
137 | { | ||
138 | settings = s; | ||
139 | } | ||
140 | |||
141 | QString 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 | |||
183 | mailimf_mailbox *MailWrapper::newMailbox(const QString&name, const QString&mail ) | ||
184 | { | ||
185 | return mailimf_mailbox_new( strdup( name.latin1() ), | ||
186 | strdup( mail.latin1() ) ); | ||
187 | } | ||
188 | |||
189 | mailimf_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 | |||
214 | mailimf_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 | |||
256 | err_free_xmailer: | ||
257 | mailimf_field_free( xmailer ); | ||
258 | err_free_fields: | ||
259 | mailimf_fields_free( fields ); | ||
260 | err_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 ); | ||
265 | err_free_from: | ||
266 | mailimf_mailbox_list_free( from ); | ||
267 | err_free_fromBox: | ||
268 | mailimf_mailbox_free( fromBox ); | ||
269 | err_free_sender: | ||
270 | mailimf_mailbox_free( sender ); | ||
271 | err_free: | ||
272 | free( subject ); | ||
273 | qDebug( "createImfFields - error" ); | ||
274 | |||
275 | return NULL; // Error :( | ||
276 | } | ||
277 | |||
278 | mailmime *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 | |||
308 | err_free_txtPart: | ||
309 | mailmime_free( txtPart ); | ||
310 | err_free_fields: | ||
311 | mailmime_fields_free( fields ); | ||
312 | err_free_content: | ||
313 | mailmime_content_free( content ); | ||
314 | err_free_param: | ||
315 | mailmime_parameter_free( param ); | ||
316 | err_free: | ||
317 | free( txt ); | ||
318 | qDebug( "buildTxtPart - error" ); | ||
319 | |||
320 | return NULL; // Error :( | ||
321 | } | ||
322 | |||
323 | mailmime *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 | |||
362 | err_free_filePart: | ||
363 | mailmime_free( filePart ); | ||
364 | err_free_param: | ||
365 | if ( param != NULL ) mailmime_parameter_free( param ); | ||
366 | err_free_content: | ||
367 | mailmime_content_free( content ); | ||
368 | err_free_fields: | ||
369 | mailmime_fields_free( fields ); | ||
370 | err_free: | ||
371 | free( name ); | ||
372 | free( mime ); | ||
373 | free( file ); | ||
374 | qDebug( "buildFilePart - error" ); | ||
375 | |||
376 | return NULL; // Error :( | ||
377 | } | ||
378 | |||
379 | void 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 | |||
403 | mailmime *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 | |||
427 | err_free_txtPart: | ||
428 | mailmime_free( txtPart ); | ||
429 | err_free_message: | ||
430 | mailmime_free( message ); | ||
431 | err_free_fields: | ||
432 | mailimf_fields_free( fields ); | ||
433 | err_free: | ||
434 | qDebug( "createMimeMail: error" ); | ||
435 | |||
436 | return NULL; // Error :( | ||
437 | } | ||
438 | |||
439 | mailimf_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 | |||
456 | static 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 | |||
477 | clist *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 | |||
505 | char *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 | |||
524 | SMTPaccount *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 | |||
544 | QString 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 | |||
559 | void 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 | |||
580 | void 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 | |||
608 | err_free: | ||
609 | free( buf ); | ||
610 | err_close: | ||
611 | close( fd ); | ||
612 | } | ||
613 | |||
614 | void progress( size_t current, size_t maximum ) | ||
615 | { | ||
616 | qDebug( "Current: %i of %i", current, maximum ); | ||
617 | } | ||
618 | |||
619 | void 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 | |||
692 | free_con_session: | ||
693 | mailsmtp_quit( session ); | ||
694 | free_mem_session: | ||
695 | mailsmtp_free( session ); | ||
696 | free_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 | |||
707 | void 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 | |||
720 | Mail::Mail() | 135 | Mail::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 | ||
96 | class MailWrapper : public QObject | ||
97 | { | ||
98 | Q_OBJECT | ||
99 | |||
100 | public: | ||
101 | MailWrapper( Settings *s ); | ||
102 | void sendMail( Mail mail ); | ||
103 | |||
104 | private: | ||
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; | |||
15 | struct mailmime_mechanism; | 16 | struct mailmime_mechanism; |
17 | struct mailimf_mailbox_list; | ||
18 | struct mailimf_mailbox; | ||
19 | struct mailimf_date_time; | ||
20 | struct mailimf_group; | ||
21 | struct 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 | |||
20 | SMTPwrapper::SMTPwrapper( Settings *s ) | ||
21 | : QObject() | ||
22 | { | ||
23 | settings = s; | ||
24 | } | ||
25 | |||
26 | QString 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 | |||
68 | mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail ) | ||
69 | { | ||
70 | return mailimf_mailbox_new( strdup( name.latin1() ), | ||
71 | strdup( mail.latin1() ) ); | ||
72 | } | ||
73 | |||
74 | mailimf_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 | |||
99 | mailimf_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 | |||
141 | err_free_xmailer: | ||
142 | mailimf_field_free( xmailer ); | ||
143 | err_free_fields: | ||
144 | mailimf_fields_free( fields ); | ||
145 | err_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 ); | ||
150 | err_free_from: | ||
151 | mailimf_mailbox_list_free( from ); | ||
152 | err_free_fromBox: | ||
153 | mailimf_mailbox_free( fromBox ); | ||
154 | err_free_sender: | ||
155 | mailimf_mailbox_free( sender ); | ||
156 | err_free: | ||
157 | free( subject ); | ||
158 | qDebug( "createImfFields - error" ); | ||
159 | |||
160 | return NULL; // Error :( | ||
161 | } | ||
162 | |||
163 | mailmime *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 | |||
193 | err_free_txtPart: | ||
194 | mailmime_free( txtPart ); | ||
195 | err_free_fields: | ||
196 | mailmime_fields_free( fields ); | ||
197 | err_free_content: | ||
198 | mailmime_content_free( content ); | ||
199 | err_free_param: | ||
200 | mailmime_parameter_free( param ); | ||
201 | err_free: | ||
202 | free( txt ); | ||
203 | qDebug( "buildTxtPart - error" ); | ||
204 | |||
205 | return NULL; // Error :( | ||
206 | } | ||
207 | |||
208 | mailmime *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 | |||
247 | err_free_filePart: | ||
248 | mailmime_free( filePart ); | ||
249 | err_free_param: | ||
250 | if ( param != NULL ) mailmime_parameter_free( param ); | ||
251 | err_free_content: | ||
252 | mailmime_content_free( content ); | ||
253 | err_free_fields: | ||
254 | mailmime_fields_free( fields ); | ||
255 | err_free: | ||
256 | free( name ); | ||
257 | free( mime ); | ||
258 | free( file ); | ||
259 | qDebug( "buildFilePart - error" ); | ||
260 | |||
261 | return NULL; // Error :( | ||
262 | } | ||
263 | |||
264 | void 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 | |||
289 | mailmime *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 | |||
313 | err_free_txtPart: | ||
314 | mailmime_free( txtPart ); | ||
315 | err_free_message: | ||
316 | mailmime_free( message ); | ||
317 | err_free_fields: | ||
318 | mailimf_fields_free( fields ); | ||
319 | err_free: | ||
320 | qDebug( "createMimeMail: error" ); | ||
321 | |||
322 | return NULL; // Error :( | ||
323 | } | ||
324 | |||
325 | mailimf_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 | |||
342 | void 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 | |||
363 | clist *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 | |||
391 | char *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 | |||
410 | SMTPaccount *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 | |||
430 | QString 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 | |||
445 | void 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 | |||
466 | void 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 | |||
494 | err_free: | ||
495 | free( buf ); | ||
496 | err_close: | ||
497 | close( fd ); | ||
498 | } | ||
499 | |||
500 | void SMTPwrapper::progress( size_t current, size_t maximum ) | ||
501 | { | ||
502 | qDebug( "Current: %i of %i", current, maximum ); | ||
503 | } | ||
504 | |||
505 | void 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 | |||
578 | free_con_session: | ||
579 | mailsmtp_quit( session ); | ||
580 | free_mem_session: | ||
581 | mailsmtp_free( session ); | ||
582 | free_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 | |||
593 | void 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 | |||
12 | class Mail; | ||
13 | class Attachment; | ||
14 | struct mailimf_fields; | ||
15 | struct mailimf_field; | ||
16 | struct mailimf_mailbox; | ||
17 | struct mailmime; | ||
18 | struct mailimf_address_list; | ||
19 | |||
20 | class SMTPwrapper : public QObject | ||
21 | { | ||
22 | Q_OBJECT | ||
23 | |||
24 | public: | ||
25 | SMTPwrapper( Settings *s ); | ||
26 | virtual ~SMTPwrapper(){} | ||
27 | void sendMail(const Mail& mail ); | ||
28 | |||
29 | protected: | ||
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 | ||
135 | MailWrapper::MailWrapper( Settings *s ) | ||
136 | : QObject() | ||
137 | { | ||
138 | settings = s; | ||
139 | } | ||
140 | |||
141 | QString 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 | |||
183 | mailimf_mailbox *MailWrapper::newMailbox(const QString&name, const QString&mail ) | ||
184 | { | ||
185 | return mailimf_mailbox_new( strdup( name.latin1() ), | ||
186 | strdup( mail.latin1() ) ); | ||
187 | } | ||
188 | |||
189 | mailimf_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 | |||
214 | mailimf_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 | |||
256 | err_free_xmailer: | ||
257 | mailimf_field_free( xmailer ); | ||
258 | err_free_fields: | ||
259 | mailimf_fields_free( fields ); | ||
260 | err_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 ); | ||
265 | err_free_from: | ||
266 | mailimf_mailbox_list_free( from ); | ||
267 | err_free_fromBox: | ||
268 | mailimf_mailbox_free( fromBox ); | ||
269 | err_free_sender: | ||
270 | mailimf_mailbox_free( sender ); | ||
271 | err_free: | ||
272 | free( subject ); | ||
273 | qDebug( "createImfFields - error" ); | ||
274 | |||
275 | return NULL; // Error :( | ||
276 | } | ||
277 | |||
278 | mailmime *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 | |||
308 | err_free_txtPart: | ||
309 | mailmime_free( txtPart ); | ||
310 | err_free_fields: | ||
311 | mailmime_fields_free( fields ); | ||
312 | err_free_content: | ||
313 | mailmime_content_free( content ); | ||
314 | err_free_param: | ||
315 | mailmime_parameter_free( param ); | ||
316 | err_free: | ||
317 | free( txt ); | ||
318 | qDebug( "buildTxtPart - error" ); | ||
319 | |||
320 | return NULL; // Error :( | ||
321 | } | ||
322 | |||
323 | mailmime *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 | |||
362 | err_free_filePart: | ||
363 | mailmime_free( filePart ); | ||
364 | err_free_param: | ||
365 | if ( param != NULL ) mailmime_parameter_free( param ); | ||
366 | err_free_content: | ||
367 | mailmime_content_free( content ); | ||
368 | err_free_fields: | ||
369 | mailmime_fields_free( fields ); | ||
370 | err_free: | ||
371 | free( name ); | ||
372 | free( mime ); | ||
373 | free( file ); | ||
374 | qDebug( "buildFilePart - error" ); | ||
375 | |||
376 | return NULL; // Error :( | ||
377 | } | ||
378 | |||
379 | void 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 | |||
403 | mailmime *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 | |||
427 | err_free_txtPart: | ||
428 | mailmime_free( txtPart ); | ||
429 | err_free_message: | ||
430 | mailmime_free( message ); | ||
431 | err_free_fields: | ||
432 | mailimf_fields_free( fields ); | ||
433 | err_free: | ||
434 | qDebug( "createMimeMail: error" ); | ||
435 | |||
436 | return NULL; // Error :( | ||
437 | } | ||
438 | |||
439 | mailimf_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 | |||
456 | static 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 | |||
477 | clist *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 | |||
505 | char *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 | |||
524 | SMTPaccount *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 | |||
544 | QString 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 | |||
559 | void 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 | |||
580 | void 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 | |||
608 | err_free: | ||
609 | free( buf ); | ||
610 | err_close: | ||
611 | close( fd ); | ||
612 | } | ||
613 | |||
614 | void progress( size_t current, size_t maximum ) | ||
615 | { | ||
616 | qDebug( "Current: %i of %i", current, maximum ); | ||
617 | } | ||
618 | |||
619 | void 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 | |||
692 | free_con_session: | ||
693 | mailsmtp_quit( session ); | ||
694 | free_mem_session: | ||
695 | mailsmtp_free( session ); | ||
696 | free_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 | |||
707 | void 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 | |||
720 | Mail::Mail() | 135 | Mail::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 | ||
96 | class MailWrapper : public QObject | ||
97 | { | ||
98 | Q_OBJECT | ||
99 | |||
100 | public: | ||
101 | MailWrapper( Settings *s ); | ||
102 | void sendMail( Mail mail ); | ||
103 | |||
104 | private: | ||
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; | |||
15 | struct mailmime_mechanism; | 16 | struct mailmime_mechanism; |
17 | struct mailimf_mailbox_list; | ||
18 | struct mailimf_mailbox; | ||
19 | struct mailimf_date_time; | ||
20 | struct mailimf_group; | ||
21 | struct 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 | |||
20 | SMTPwrapper::SMTPwrapper( Settings *s ) | ||
21 | : QObject() | ||
22 | { | ||
23 | settings = s; | ||
24 | } | ||
25 | |||
26 | QString 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 | |||
68 | mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail ) | ||
69 | { | ||
70 | return mailimf_mailbox_new( strdup( name.latin1() ), | ||
71 | strdup( mail.latin1() ) ); | ||
72 | } | ||
73 | |||
74 | mailimf_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 | |||
99 | mailimf_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 | |||
141 | err_free_xmailer: | ||
142 | mailimf_field_free( xmailer ); | ||
143 | err_free_fields: | ||
144 | mailimf_fields_free( fields ); | ||
145 | err_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 ); | ||
150 | err_free_from: | ||
151 | mailimf_mailbox_list_free( from ); | ||
152 | err_free_fromBox: | ||
153 | mailimf_mailbox_free( fromBox ); | ||
154 | err_free_sender: | ||
155 | mailimf_mailbox_free( sender ); | ||
156 | err_free: | ||
157 | free( subject ); | ||
158 | qDebug( "createImfFields - error" ); | ||
159 | |||
160 | return NULL; // Error :( | ||
161 | } | ||
162 | |||
163 | mailmime *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 | |||
193 | err_free_txtPart: | ||
194 | mailmime_free( txtPart ); | ||
195 | err_free_fields: | ||
196 | mailmime_fields_free( fields ); | ||
197 | err_free_content: | ||
198 | mailmime_content_free( content ); | ||
199 | err_free_param: | ||
200 | mailmime_parameter_free( param ); | ||
201 | err_free: | ||
202 | free( txt ); | ||
203 | qDebug( "buildTxtPart - error" ); | ||
204 | |||
205 | return NULL; // Error :( | ||
206 | } | ||
207 | |||
208 | mailmime *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 | |||
247 | err_free_filePart: | ||
248 | mailmime_free( filePart ); | ||
249 | err_free_param: | ||
250 | if ( param != NULL ) mailmime_parameter_free( param ); | ||
251 | err_free_content: | ||
252 | mailmime_content_free( content ); | ||
253 | err_free_fields: | ||
254 | mailmime_fields_free( fields ); | ||
255 | err_free: | ||
256 | free( name ); | ||
257 | free( mime ); | ||
258 | free( file ); | ||
259 | qDebug( "buildFilePart - error" ); | ||
260 | |||
261 | return NULL; // Error :( | ||
262 | } | ||
263 | |||
264 | void 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 | |||
289 | mailmime *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 | |||
313 | err_free_txtPart: | ||
314 | mailmime_free( txtPart ); | ||
315 | err_free_message: | ||
316 | mailmime_free( message ); | ||
317 | err_free_fields: | ||
318 | mailimf_fields_free( fields ); | ||
319 | err_free: | ||
320 | qDebug( "createMimeMail: error" ); | ||
321 | |||
322 | return NULL; // Error :( | ||
323 | } | ||
324 | |||
325 | mailimf_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 | |||
342 | void 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 | |||
363 | clist *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 | |||
391 | char *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 | |||
410 | SMTPaccount *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 | |||
430 | QString 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 | |||
445 | void 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 | |||
466 | void 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 | |||
494 | err_free: | ||
495 | free( buf ); | ||
496 | err_close: | ||
497 | close( fd ); | ||
498 | } | ||
499 | |||
500 | void SMTPwrapper::progress( size_t current, size_t maximum ) | ||
501 | { | ||
502 | qDebug( "Current: %i of %i", current, maximum ); | ||
503 | } | ||
504 | |||
505 | void 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 | |||
578 | free_con_session: | ||
579 | mailsmtp_quit( session ); | ||
580 | free_mem_session: | ||
581 | mailsmtp_free( session ); | ||
582 | free_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 | |||
593 | void 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 | |||
12 | class Mail; | ||
13 | class Attachment; | ||
14 | struct mailimf_fields; | ||
15 | struct mailimf_field; | ||
16 | struct mailimf_mailbox; | ||
17 | struct mailmime; | ||
18 | struct mailimf_address_list; | ||
19 | |||
20 | class SMTPwrapper : public QObject | ||
21 | { | ||
22 | Q_OBJECT | ||
23 | |||
24 | public: | ||
25 | SMTPwrapper( Settings *s ); | ||
26 | virtual ~SMTPwrapper(){} | ||
27 | void sendMail(const Mail& mail ); | ||
28 | |||
29 | protected: | ||
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 | ||