summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2010-09-16 12:32:56 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2010-09-16 12:50:40 (GMT)
commit23321cf7f5561b96d8bf970da217c8968e0175c8 (patch) (side-by-side diff)
tree81155fcc329c7a3fe0865c95475a00d87be08ef7
parent546a1c78efa1bad5536d94e4722d6ac2ef62a685 (diff)
downloadmailutils-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.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--mail/send.c192
1 files changed, 113 insertions, 79 deletions
diff --git a/mail/send.c b/mail/send.c
index 6538a49..71d7b03 100644
--- a/mail/send.c
+++ b/mail/send.c
@@ -23,7 +23,7 @@
#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 */
@@ -335,6 +335,82 @@ fill_body (mu_message_t msg, FILE *file)
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();
@@ -468,41 +544,16 @@ mail_send0 (compose_env_t * env, int save_to)
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)
@@ -518,9 +569,9 @@ mail_send0 (compose_env_t * env, int save_to)
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);
@@ -559,11 +610,10 @@ mail_send0 (compose_env_t * env, int save_to)
{
/* 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]);
@@ -583,63 +633,36 @@ mail_send0 (compose_env_t * env, int save_to)
}
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;
@@ -658,26 +681,37 @@ isfilename (const char *p)
/* 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;
}

Return to:

Send suggestions and report system problems to the System administrator.