summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-09-16 15:32:56 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-09-16 15:50:40 +0300
commit23321cf7f5561b96d8bf970da217c8968e0175c8 (patch)
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.
-rw-r--r--mail/send.c192
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;
}

Return to:

Send suggestions and report system problems to the System administrator.