Rewrite SMTP mailer.
* libproto/mailer/smtp.c: Rewrite using new SMTP API. * libproto/mailer/smtp_quit.c (mu_smtp_quit): Return immediately if already in closed state. * libmailutils/ticket.c (mu_ticket_get_cred): Return MU_ERR_FAILURE if all methods fail. * mail/send.c: Port 23321cf7 from patches-2.2 (msg_to_pipe): Return status code. (save_dead_message, send_message): New functions, extracted from mail_send0. (mail_send0): Call save_dead_message if sending failed.
Showing
4 changed files
with
129 additions
and
96 deletions
... | @@ -211,7 +211,9 @@ mu_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, | ... | @@ -211,7 +211,9 @@ mu_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, |
211 | } | 211 | } |
212 | arg [strlen (arg) - 1] = '\0'; /* nuke the trailing line. */ | 212 | arg [strlen (arg) - 1] = '\0'; /* nuke the trailing line. */ |
213 | } | 213 | } |
214 | 214 | else | |
215 | return MU_ERR_FAILURE; | ||
216 | |||
215 | if (pplain) | 217 | if (pplain) |
216 | { | 218 | { |
217 | *pplain = strdup (arg); | 219 | *pplain = strdup (arg); | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -37,6 +37,8 @@ mu_smtp_quit (mu_smtp_t smtp) | ... | @@ -37,6 +37,8 @@ mu_smtp_quit (mu_smtp_t smtp) |
37 | return EINVAL; | 37 | return EINVAL; |
38 | if (MU_SMTP_FISSET (smtp, _MU_SMTP_ERR)) | 38 | if (MU_SMTP_FISSET (smtp, _MU_SMTP_ERR)) |
39 | return MU_ERR_FAILURE; | 39 | return MU_ERR_FAILURE; |
40 | if (smtp->state == MU_SMTP_CLOS) | ||
41 | return 0; | ||
40 | status = mu_smtp_write (smtp, "QUIT\r\n"); | 42 | status = mu_smtp_write (smtp, "QUIT\r\n"); |
41 | MU_SMTP_CHECK_ERROR (smtp, status); | 43 | MU_SMTP_CHECK_ERROR (smtp, status); |
42 | status = mu_smtp_response (smtp); | 44 | status = mu_smtp_response (smtp); | ... | ... |
... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
23 | #include <fcntl.h> | 23 | #include <fcntl.h> |
24 | 24 | ||
25 | static int isfilename (const char *); | 25 | static int isfilename (const char *); |
26 | static void msg_to_pipe (const char *cmd, mu_message_t msg); | 26 | static int msg_to_pipe (const char *cmd, mu_message_t msg); |
27 | 27 | ||
28 | 28 | ||
29 | /* Additional message headers */ | 29 | /* Additional message headers */ |
... | @@ -338,6 +338,82 @@ fill_body (mu_message_t msg, FILE *file) | ... | @@ -338,6 +338,82 @@ fill_body (mu_message_t msg, FILE *file) |
338 | return 0; | 338 | return 0; |
339 | } | 339 | } |
340 | 340 | ||
341 | static int | ||
342 | save_dead_message (compose_env_t *env) | ||
343 | { | ||
344 | if (mailvar_get (NULL, "save", mailvar_type_boolean, 0) == 0) | ||
345 | { | ||
346 | FILE *fp = fopen (getenv ("DEAD"), | ||
347 | mailvar_get (NULL, "appenddeadletter", | ||
348 | mailvar_type_boolean, 0) == 0 ? | ||
349 | "a" : "w"); | ||
350 | |||
351 | if (!fp) | ||
352 | { | ||
353 | util_error (_("Cannot open file %s: %s"), getenv ("DEAD"), | ||
354 | strerror (errno)); | ||
355 | return 1; | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | char *buf = NULL; | ||
360 | size_t n; | ||
361 | rewind (env->file); | ||
362 | while (getline (&buf, &n, env->file) > 0) | ||
363 | fputs (buf, fp); | ||
364 | fclose (fp); | ||
365 | free (buf); | ||
366 | } | ||
367 | } | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int | ||
372 | send_message (mu_message_t msg) | ||
373 | { | ||
374 | char *sendmail; | ||
375 | int status; | ||
376 | |||
377 | if (mailvar_get (&sendmail, "sendmail", mailvar_type_string, 0) == 0) | ||
378 | { | ||
379 | if (sendmail[0] == '/') | ||
380 | status = msg_to_pipe (sendmail, msg); | ||
381 | else | ||
382 | { | ||
383 | mu_mailer_t mailer; | ||
384 | |||
385 | status = mu_mailer_create (&mailer, sendmail); | ||
386 | if (status == 0) | ||
387 | { | ||
388 | if (mailvar_get (NULL, "verbose", mailvar_type_boolean, 0) == 0) | ||
389 | { | ||
390 | mu_debug_t debug = NULL; | ||
391 | mu_mailer_get_debug (mailer, &debug); | ||
392 | mu_debug_set_level (debug, | ||
393 | MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); | ||
394 | } | ||
395 | status = mu_mailer_open (mailer, MU_STREAM_RDWR); | ||
396 | if (status == 0) | ||
397 | { | ||
398 | status = mu_mailer_send_message (mailer, msg, NULL, NULL); | ||
399 | mu_mailer_close (mailer); | ||
400 | } | ||
401 | else | ||
402 | util_error (_("Cannot open mailer: %s"), mu_strerror (status)); | ||
403 | mu_mailer_destroy (&mailer); | ||
404 | } | ||
405 | else | ||
406 | util_error (_("Cannot create mailer: %s"), | ||
407 | mu_strerror (status)); | ||
408 | } | ||
409 | } | ||
410 | else | ||
411 | { | ||
412 | util_error (_("Variable sendmail not set: no mailer")); | ||
413 | status = ENOSYS; | ||
414 | } | ||
415 | return status; | ||
416 | } | ||
341 | 417 | ||
342 | /* mail_send0(): shared between mail_send() and mail_reply(); | 418 | /* mail_send0(): shared between mail_send() and mail_reply(); |
343 | 419 | ||
... | @@ -471,41 +547,16 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -471,41 +547,16 @@ mail_send0 (compose_env_t * env, int save_to) |
471 | free (buf); | 547 | free (buf); |
472 | } | 548 | } |
473 | 549 | ||
474 | /* If interrupted dump the file to dead.letter. */ | 550 | /* If interrupted, dump the file to dead.letter. */ |
475 | if (int_cnt) | 551 | if (int_cnt) |
476 | { | 552 | { |
477 | if (mailvar_get (NULL, "save", mailvar_type_boolean, 0) == 0) | 553 | save_dead_message (env); |
478 | { | ||
479 | FILE *fp = fopen (getenv ("DEAD"), | ||
480 | mailvar_get (NULL, "appenddeadletter", | ||
481 | mailvar_type_boolean, 0) == 0 ? | ||
482 | "a" : "w"); | ||
483 | |||
484 | if (!fp) | ||
485 | { | ||
486 | util_error (_("Cannot open file %s: %s"), getenv ("DEAD"), | ||
487 | strerror (errno)); | ||
488 | } | ||
489 | else | ||
490 | { | ||
491 | char *buf = NULL; | ||
492 | size_t n; | ||
493 | rewind (env->file); | ||
494 | while (getline (&buf, &n, env->file) > 0) | ||
495 | fputs (buf, fp); | ||
496 | fclose (fp); | ||
497 | free (buf); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | fclose (env->file); | 554 | fclose (env->file); |
502 | remove (filename); | 555 | remove (filename); |
503 | free (filename); | 556 | free (filename); |
504 | return 1; | 557 | return 1; |
505 | } | 558 | } |
506 | 559 | ||
507 | fclose (env->file); /* FIXME: freopen would be better */ | ||
508 | |||
509 | /* In mailx compatibility mode, ask for Cc and Bcc after editing | 560 | /* In mailx compatibility mode, ask for Cc and Bcc after editing |
510 | the body of the message */ | 561 | the body of the message */ |
511 | if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0) == 0) | 562 | if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0) == 0) |
... | @@ -521,12 +572,12 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -521,12 +572,12 @@ mail_send0 (compose_env_t * env, int save_to) |
521 | file = fopen (filename, "r"); | 572 | file = fopen (filename, "r"); |
522 | if (file != NULL) | 573 | if (file != NULL) |
523 | { | 574 | { |
524 | mu_mailer_t mailer; | ||
525 | mu_message_t msg = NULL; | 575 | mu_message_t msg = NULL; |
526 | int rc; | 576 | int rc; |
577 | int status = 0; | ||
527 | 578 | ||
528 | mu_message_create (&msg, NULL); | 579 | mu_message_create (&msg, NULL); |
529 | 580 | ||
530 | /* Fill the body. */ | 581 | /* Fill the body. */ |
531 | rc = fill_body (msg, file); | 582 | rc = fill_body (msg, file); |
532 | fclose (file); | 583 | fclose (file); |
... | @@ -561,11 +612,10 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -561,11 +612,10 @@ mail_send0 (compose_env_t * env, int save_to) |
561 | { | 612 | { |
562 | /* Pipe to a cmd. */ | 613 | /* Pipe to a cmd. */ |
563 | if (env->outfiles[i][0] == '|') | 614 | if (env->outfiles[i][0] == '|') |
564 | msg_to_pipe (&(env->outfiles[i][1]), msg); | 615 | status = msg_to_pipe (env->outfiles[i] + 1, msg); |
565 | /* Save to a file. */ | 616 | /* Save to a file. */ |
566 | else | 617 | else |
567 | { | 618 | { |
568 | int status; | ||
569 | mu_mailbox_t mbx = NULL; | 619 | mu_mailbox_t mbx = NULL; |
570 | status = mu_mailbox_create_default (&mbx, | 620 | status = mu_mailbox_create_default (&mbx, |
571 | env->outfiles[i]); | 621 | env->outfiles[i]); |
... | @@ -585,64 +635,36 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -585,64 +635,36 @@ mail_send0 (compose_env_t * env, int save_to) |
585 | } | 635 | } |
586 | if (status) | 636 | if (status) |
587 | util_error (_("Cannot create mailbox %s: %s"), | 637 | util_error (_("Cannot create mailbox %s: %s"), |
588 | env->outfiles[i], mu_strerror (status)); | 638 | env->outfiles[i], |
639 | mu_strerror (status)); | ||
589 | } | 640 | } |
590 | } | 641 | } |
591 | } | 642 | } |
592 | 643 | ||
593 | /* Do we need to Send the message on the wire? */ | 644 | /* Do we need to Send the message on the wire? */ |
594 | if (compose_header_get (env, MU_HEADER_TO, NULL) | 645 | if (status == 0 && |
595 | || compose_header_get (env, MU_HEADER_CC, NULL) | 646 | (compose_header_get (env, MU_HEADER_TO, NULL) || |
596 | || compose_header_get (env, MU_HEADER_BCC, NULL)) | 647 | compose_header_get (env, MU_HEADER_CC, NULL) || |
648 | compose_header_get (env, MU_HEADER_BCC, NULL))) | ||
597 | { | 649 | { |
598 | char *sendmail; | 650 | mu_message_set_header (msg, env->header, NULL); |
599 | if (mailvar_get (&sendmail, "sendmail", | 651 | env->header = NULL; |
600 | mailvar_type_string, 0) == 0) | 652 | status = send_message (msg); |
601 | { | 653 | if (status) |
602 | mu_message_set_header (msg, env->header, NULL); | 654 | save_dead_message (env); |
603 | env->header = NULL; | ||
604 | if (sendmail[0] == '/') | ||
605 | msg_to_pipe (sendmail, msg); | ||
606 | else | ||
607 | { | ||
608 | int status = mu_mailer_create (&mailer, sendmail); | ||
609 | if (status == 0) | ||
610 | { | ||
611 | if (mailvar_get (NULL, "verbose", | ||
612 | mailvar_type_boolean, 0) == 0) | ||
613 | { | ||
614 | mu_debug_t debug = NULL; | ||
615 | mu_mailer_get_debug (mailer, &debug); | ||
616 | mu_debug_set_level (debug, | ||
617 | MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); | ||
618 | } | ||
619 | status = mu_mailer_open (mailer, MU_STREAM_RDWR); | ||
620 | if (status == 0) | ||
621 | { | ||
622 | mu_mailer_send_message (mailer, msg, | ||
623 | NULL, NULL); | ||
624 | mu_mailer_close (mailer); | ||
625 | } | ||
626 | else | ||
627 | util_error (_("Cannot open mailer: %s"), | ||
628 | mu_strerror (status)); | ||
629 | mu_mailer_destroy (&mailer); | ||
630 | } | ||
631 | else | ||
632 | util_error (_("Cannot create mailer: %s"), | ||
633 | mu_strerror (status)); | ||
634 | } | ||
635 | } | ||
636 | else | ||
637 | util_error (_("Variable sendmail not set: no mailer")); | ||
638 | } | 655 | } |
639 | } | 656 | } |
657 | fclose (env->file); | ||
640 | mu_message_destroy (&msg, NULL); | 658 | mu_message_destroy (&msg, NULL); |
641 | remove (filename); | 659 | remove (filename); |
642 | free (filename); | 660 | free (filename); |
643 | return 0; | 661 | return status; |
644 | } | 662 | } |
645 | } | 663 | } |
664 | else | ||
665 | save_dead_message (env); | ||
666 | |||
667 | fclose (env->file); | ||
646 | 668 | ||
647 | remove (filename); | 669 | remove (filename); |
648 | free (filename); | 670 | free (filename); |
... | @@ -662,26 +684,33 @@ isfilename (const char *p) | ... | @@ -662,26 +684,33 @@ isfilename (const char *p) |
662 | 684 | ||
663 | /* FIXME: Should probably be in util.c. */ | 685 | /* FIXME: Should probably be in util.c. */ |
664 | /* Call popen(cmd) and write the message to it. */ | 686 | /* Call popen(cmd) and write the message to it. */ |
665 | static void | 687 | static int |
666 | msg_to_pipe (const char *cmd, mu_message_t msg) | 688 | msg_to_pipe (const char *cmd, mu_message_t msg) |
667 | { | 689 | { |
668 | FILE *fp = popen (cmd, "w"); | 690 | mu_stream_t progstream, msgstream; |
669 | if (fp) | 691 | int status, rc; |
692 | |||
693 | status = mu_prog_stream_create (&progstream, cmd, MU_STREAM_WRITE); | ||
694 | if (status) | ||
670 | { | 695 | { |
671 | mu_stream_t stream = NULL; | 696 | util_error (_("Cannot pipe to %s: %s"), cmd, mu_strerror (status)); |
672 | char buffer[512]; | 697 | return status; |
673 | size_t n = 0; | ||
674 | /* FIXME: Use mu_stream_copy */ | ||
675 | mu_message_get_streamref (msg, &stream); | ||
676 | while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0 | ||
677 | && n != 0) | ||
678 | { | ||
679 | buffer[n] = '\0'; | ||
680 | fprintf (fp, "%s", buffer); | ||
681 | } | ||
682 | mu_stream_destroy (&stream); | ||
683 | pclose (fp); | ||
684 | } | 698 | } |
685 | else | 699 | |
686 | util_error (_("Piping %s failed"), cmd); | 700 | mu_message_get_streamref (msg, &msgstream); |
701 | status = mu_stream_copy (progstream, msgstream, 0, NULL); | ||
702 | rc = mu_stream_close (progstream); | ||
703 | |||
704 | if (status == 0 && rc) | ||
705 | status = rc; | ||
706 | |||
707 | mu_stream_destroy (&progstream); | ||
708 | mu_stream_destroy (&msgstream); | ||
709 | |||
710 | if (status) | ||
711 | { | ||
712 | util_error (_("Sending data to %s failed: %s"), cmd, | ||
713 | mu_strerror (status)); | ||
714 | } | ||
715 | return status; | ||
687 | } | 716 | } | ... | ... |
-
Please register or sign in to post a comment