diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-09-16 15:32:56 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-09-16 15:50:40 +0300 |
commit | 23321cf7f5561b96d8bf970da217c8968e0175c8 (patch) | |
tree | 81155fcc329c7a3fe0865c95475a00d87be08ef7 | |
parent | 546a1c78efa1bad5536d94e4722d6ac2ef62a685 (diff) | |
download | mailutils-23321cf7f5561b96d8bf970da217c8968e0175c8.tar.gz mailutils-23321cf7f5561b96d8bf970da217c8968e0175c8.tar.bz2 |
If a message cannot be sent, save it in dead.mail.
* mail/send.c (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.
-rw-r--r-- | mail/send.c | 192 |
1 files changed, 113 insertions, 79 deletions
diff --git a/mail/send.c b/mail/send.c index 6538a49c2..71d7b0325 100644 --- a/mail/send.c +++ b/mail/send.c @@ -20,13 +20,13 @@ #include "mail.h" #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> static int isfilename (const char *); -static void msg_to_pipe (const char *cmd, mu_message_t msg); +static int msg_to_pipe (const char *cmd, mu_message_t msg); /* Additional message headers */ struct add_header { int mode; @@ -332,12 +332,88 @@ fill_body (mu_message_t msg, FILE *file) return 1; } return 0; } +static int +save_dead_message (compose_env_t *env) +{ + if (mailvar_get (NULL, "save", mailvar_type_boolean, 0) == 0) + { + FILE *fp = fopen (getenv ("DEAD"), + mailvar_get (NULL, "appenddeadletter", + mailvar_type_boolean, 0) == 0 ? + "a" : "w"); + + if (!fp) + { + util_error (_("Cannot open file %s: %s"), getenv ("DEAD"), + strerror (errno)); + return 1; + } + else + { + char *buf = NULL; + size_t n; + rewind (env->file); + while (getline (&buf, &n, env->file) > 0) + fputs (buf, fp); + fclose (fp); + free (buf); + } + } + return 0; +} + +static int +send_message (mu_message_t msg) +{ + char *sendmail; + int status; + + if (mailvar_get (&sendmail, "sendmail", mailvar_type_string, 0) == 0) + { + if (sendmail[0] == '/') + status = msg_to_pipe (sendmail, msg); + else + { + mu_mailer_t mailer; + + status = mu_mailer_create (&mailer, sendmail); + if (status == 0) + { + if (mailvar_get (NULL, "verbose", mailvar_type_boolean, 0) == 0) + { + mu_debug_t debug = NULL; + mu_mailer_get_debug (mailer, &debug); + mu_debug_set_level (debug, + MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); + } + status = mu_mailer_open (mailer, MU_STREAM_RDWR); + if (status == 0) + { + status = mu_mailer_send_message (mailer, msg, NULL, NULL); + mu_mailer_close (mailer); + } + else + util_error (_("Cannot open mailer: %s"), mu_strerror (status)); + mu_mailer_destroy (&mailer); + } + else + util_error (_("Cannot create mailer: %s"), + mu_strerror (status)); + } + } + else + { + util_error (_("Variable sendmail not set: no mailer")); + status = ENOSYS; + } + return status; +} /* mail_send0(): shared between mail_send() and mail_reply(); If the variable "record" is set, the outgoing message is saved after being sent. If "save_to" argument is non-zero, the name of the save file is derived from "to" argument. Otherwise, @@ -465,47 +541,22 @@ mail_send0 (compose_env_t * env, int save_to) else fprintf (env->file, "%s\n", buf); fflush (env->file); free (buf); } - /* If interrupted dump the file to dead.letter. */ + /* If interrupted, dump the file to dead.letter. */ if (int_cnt) { - if (mailvar_get (NULL, "save", mailvar_type_boolean, 0) == 0) - { - FILE *fp = fopen (getenv ("DEAD"), - mailvar_get (NULL, "appenddeadletter", - mailvar_type_boolean, 0) == 0 ? - "a" : "w"); - - if (!fp) - { - util_error (_("Cannot open file %s: %s"), getenv ("DEAD"), - strerror (errno)); - } - else - { - char *buf = NULL; - size_t n; - rewind (env->file); - while (getline (&buf, &n, env->file) > 0) - fputs (buf, fp); - fclose (fp); - free (buf); - } - } - + save_dead_message (env); fclose (env->file); remove (filename); free (filename); return 1; } - fclose (env->file); /* FIXME: freopen would be better */ - /* In mailx compatibility mode, ask for Cc and Bcc after editing the body of the message */ if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0) == 0) read_cc_bcc (env); /* Prepare the header */ @@ -515,15 +566,15 @@ mail_send0 (compose_env_t * env, int save_to) if (util_header_expand (&env->header) == 0) { file = fopen (filename, "r"); if (file != NULL) { - mu_mailer_t mailer; mu_message_t msg = NULL; int rc; + int status = 0; mu_message_create (&msg, NULL); mu_message_set_header (msg, env->header, NULL); /* Fill the body. */ rc = fill_body (msg, file); @@ -556,17 +607,16 @@ mail_send0 (compose_env_t * env, int save_to) { int i; for (i = 0; i < env->nfiles; i++) { /* Pipe to a cmd. */ if (env->outfiles[i][0] == '|') - msg_to_pipe (&(env->outfiles[i][1]), msg); + status = msg_to_pipe (env->outfiles[i] + 1, msg); /* Save to a file. */ else { - int status; mu_mailbox_t mbx = NULL; status = mu_mailbox_create_default (&mbx, env->outfiles[i]); if (status == 0) { status = mu_mailbox_open (mbx, MU_STREAM_WRITE @@ -580,69 +630,42 @@ mail_send0 (compose_env_t * env, int save_to) mu_mailbox_close (mbx); } mu_mailbox_destroy (&mbx); } if (status) util_error (_("Cannot create mailbox %s: %s"), - env->outfiles[i], mu_strerror (status)); + env->outfiles[i], + mu_strerror (status)); } } } /* Do we need to Send the message on the wire? */ - if (compose_header_get (env, MU_HEADER_TO, NULL) - || compose_header_get (env, MU_HEADER_CC, NULL) - || compose_header_get (env, MU_HEADER_BCC, NULL)) + if (status == 0 && + (compose_header_get (env, MU_HEADER_TO, NULL) || + compose_header_get (env, MU_HEADER_CC, NULL) || + compose_header_get (env, MU_HEADER_BCC, NULL))) { - char *sendmail; - if (mailvar_get (&sendmail, "sendmail", - mailvar_type_string, 0) == 0) - { - if (sendmail[0] == '/') - msg_to_pipe (sendmail, msg); - else - { - int status = mu_mailer_create (&mailer, sendmail); - if (status == 0) - { - if (mailvar_get (NULL, "verbose", - mailvar_type_boolean, 0) == 0) - { - mu_debug_t debug = NULL; - mu_mailer_get_debug (mailer, &debug); - mu_debug_set_level (debug, - MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); - } - status = mu_mailer_open (mailer, MU_STREAM_RDWR); - if (status == 0) - { - mu_mailer_send_message (mailer, msg, - NULL, NULL); - mu_mailer_close (mailer); - } - else - util_error (_("Cannot open mailer: %s"), - mu_strerror (status)); - mu_mailer_destroy (&mailer); - } - else - util_error (_("Cannot create mailer: %s"), - mu_strerror (status)); - } - } - else - util_error (_("Variable sendmail not set: no mailer")); + status = send_message (msg); + if (status) + save_dead_message (env); } } + + fclose (env->file); + mu_message_destroy (&msg, NULL); remove (filename); free (filename); - return 0; + return status; } } - + else + save_dead_message (env); + + fclose (env->file); remove (filename); free (filename); return 1; } /* Starting with '|' '/' or not consider addresses and we cheat @@ -655,29 +678,40 @@ isfilename (const char *p) return 1; return 0; } /* FIXME: Should probably be in util.c. */ /* Call popen(cmd) and write the message to it. */ -static void +static int msg_to_pipe (const char *cmd, mu_message_t msg) { FILE *fp = popen (cmd, "w"); + int status; + if (fp) { mu_stream_t stream = NULL; char buffer[512]; off_t off = 0; size_t n = 0; + int rc; + mu_message_get_stream (msg, &stream); - while (mu_stream_read (stream, buffer, sizeof buffer - 1, off, &n) == 0 + while ((status = mu_stream_read (stream, buffer, + sizeof buffer - 1, off, &n)) == 0 && n != 0) { buffer[n] = '\0'; fprintf (fp, "%s", buffer); off += n; } - pclose (fp); + rc = pclose (fp); + if (status == 0 && rc) + status = errno; } else - util_error (_("Piping %s failed"), cmd); + { + status = errno; + util_error (_("Piping %s failed"), cmd); + } + return status; } |