bug-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-mailutils] Using GMail smtp server for sending mail


From: Sergey Poznyakoff
Subject: Re: [bug-mailutils] Using GMail smtp server for sending mail
Date: Thu, 16 Sep 2010 16:00:13 +0300

BVK Chaitanya <address@hidden> ha escrit:

> It seems if USER or PASS are wrong by mistake, mail program simply
> exits with zero return status, is it possible or I am doing something
> wrong?

Mail behaves this way when in mailx compatibility mode, i.e. when the
`mailx' variable is set (see the manual, subsection 2.4.6 "How to Alter
the Behavior of `mail'").  If you want it to exit with a non-zero exit
code when it could not sent mail, disable this mode by removing `set
mailx' from your configuration file.  If `mailx' is set in your
/etc/mail.rc and you want to retain it there, put `set nomailx' in
your user configuration file (~/.mailrc).

> Also, where will be the to be sent message place, if sending
> fails due to network error?

Normally it should go to the dead letter file as set by the DEAD
environment variable.  It was only partially implemented, though.
Thanks for reminding me about it.  Find attached a patch which
implements this behavior.

Regards,
Sergey

>From 34a7c96269a858cf9f465cdd258fc2de6b2310d0 Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <address@hidden>
Date: Thu, 16 Sep 2010 15:32:56 +0300
Subject: [PATCH] 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.
---
 mail/send.c |  192 +++++++++++++++++++++++++++++++++++------------------------
 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;
 }
-- 
1.6.0.3


reply via email to

[Prev in Thread] Current Thread [Next in Thread]