<<< Date Index >>>     <<< Thread Index >>>

[PATCH] sendbox



Apologies, I should have used hg email on the previous post.  Plus my
sign-off was the wrong one...

# HG changeset patch
# User Aron Griffis <agriffis@xxxxxxxxx>
# Date 1196810761 18000
# Branch HEAD
# Node ID c7191b0264e54b64314dd01bc4c6f23232d8fdd5
# Parent  5c635c9b59829f70b089aec855ada0bb5c1c9ced
Add sendbox feature

This patch lets mutt use Courier IMAP's Outbox feature.  It adds two
settings: sendbox and use_sendbox.  Sendbox specifies a mailbox to
which sent messages should be saved, and use_sendbox instructs mutt to
use sendbox instead of sendmail.

Signed-off-by: Aron Griffis <agriffis@xxxxxxxxx>

diff -r 5c635c9b5982 -r c7191b0264e5 compose.c
--- a/compose.c Fri Nov 30 10:29:49 2007 +0100
+++ b/compose.c Tue Dec 04 18:26:01 2007 -0500
@@ -1207,7 +1207,7 @@ int mutt_compose_menu (HEADER *msg,   /*
          if (msg->content->next)
            msg->content = mutt_make_multipart (msg->content);
 
-         if (mutt_write_fcc (NONULL (fname), msg, NULL, 1, NULL) < 0)
+         if (mutt_write_fcc (NONULL (fname), msg, NULL, 1, NULL, 0) < 0)
            msg->content = mutt_remove_multipart (msg->content);
          else
            mutt_message _("Message written.");
diff -r 5c635c9b5982 -r c7191b0264e5 copy.c
--- a/copy.c    Fri Nov 30 10:29:49 2007 +0100
+++ b/copy.c    Tue Dec 04 18:26:01 2007 -0500
@@ -65,7 +65,8 @@ mutt_copy_hdr (FILE *in, FILE *out, LOFF
   buf[0] = '\n';
   buf[1] = 0;
 
-  if ((flags & (CH_REORDER | CH_WEED | CH_MIME | CH_DECODE | CH_PREFIX | 
CH_WEED_DELIVERED)) == 0)
+  if ((flags & (CH_REORDER | CH_WEED | CH_MIME | CH_DECODE | CH_PREFIX | 
+               CH_WEED_DELIVERED | CH_WEED_RESENT)) == 0)
   {
     /* Without these flags to complicate things
      * we can do a more efficient line to line copying
@@ -193,6 +194,9 @@ mutt_copy_hdr (FILE *in, FILE *out, LOFF
        continue;
       if ((flags & CH_WEED_DELIVERED) &&
          ascii_strncasecmp ("Delivered-To:", buf, 13) == 0)
+       continue;
+      if ((flags & CH_WEED_RESENT) &&
+         ascii_strncasecmp ("Resent-To:", buf, 10) == 0)
        continue;
       if ((flags & (CH_UPDATE | CH_XMIT | CH_NOSTATUS)) &&
          (ascii_strncasecmp ("Status:", buf, 7) == 0 ||
diff -r 5c635c9b5982 -r c7191b0264e5 globals.h
--- a/globals.h Fri Nov 30 10:29:49 2007 +0100
+++ b/globals.h Tue Dec 04 18:26:01 2007 -0500
@@ -112,6 +112,7 @@ WHERE char *PrintCmd;
 WHERE char *PrintCmd;
 WHERE char *QueryCmd;
 WHERE char *Realname;
+WHERE char *Sendbox;
 WHERE char *SendCharset;
 WHERE char *Sendmail;
 WHERE char *Shell;
diff -r 5c635c9b5982 -r c7191b0264e5 init.h
--- a/init.h    Fri Nov 30 10:29:49 2007 +0100
+++ b/init.h    Tue Dec 04 18:26:01 2007 -0500
@@ -2509,12 +2509,24 @@ struct option_t MuttVars[] = {
   ** In case the text cannot be converted into one of these exactly,
   ** mutt uses ``$$charset'' as a fallback.
   */
+  { "sendbox",         DT_PATH,  R_NONE, UL &Sendbox, 0 },
+  /*
+  ** .pp
+  ** Specifies a special mailbox that will
+  ** \fBsend\fP mail when written, honored when \fIuse_sendbox\fP is \fIset\fP.
+  ** To make use of this, you probably want a Courier IMAP server configured 
for
+  ** sending, see 
+  ** http://www.inter7.com/courierimap/INSTALL.html#imapsend
+  */
   { "sendmail",                DT_PATH, R_NONE, UL &Sendmail, UL SENDMAIL " 
-oem -oi" },
   /*
   ** .pp
   ** Specifies the program and arguments used to deliver mail sent by Mutt.
   ** Mutt expects that the specified program interprets additional
   ** arguments as recipient addresses.
+  ** .pp
+  ** This variable is ignored in favor of \fIsendbox\fP if \fIuse_sendbox\fP
+  ** is \fIset\fP.
   */
   { "sendmail_wait",   DT_NUM,  R_NONE, UL &SendmailWait, 0 },
   /*
@@ -2997,6 +3009,12 @@ struct option_t MuttVars[] = {
   ** Normally, the default should work.
   */
 #endif /* HAVE_GETADDRINFO */
+  { "use_sendbox",     DT_BOOL,  R_NONE, OPTUSESENDBOX, 0 },
+  /*
+  ** .pp
+  ** When \fIset\fP, mutt sends mail using \fIsendbox\fP instead
+  ** of \fIsendmail\fP.
+  */
   { "user_agent",      DT_BOOL, R_NONE, OPTXMAILER, 1},
   /*
   ** .pp
diff -r 5c635c9b5982 -r c7191b0264e5 mutt.h
--- a/mutt.h    Fri Nov 30 10:29:49 2007 +0100
+++ b/mutt.h    Tue Dec 04 18:26:01 2007 -0500
@@ -94,6 +94,7 @@
 #define CH_NOQFROM     (1<<15) /* give CH_FROM precedence over CH_WEED? */
 #define CH_UPDATE_IRT  (1<<16) /* update In-Reply-To: */
 #define CH_UPDATE_REFS (1<<17) /* update References: */
+#define CH_WEED_RESENT (1<<18) /* weed Resent-To: header */
 
 /* flags for mutt_enter_string() */
 #define  M_ALIAS   1      /* do alias "completion" by calling up the 
alias-menu */
@@ -451,6 +452,7 @@ enum
 #ifdef HAVE_GETADDRINFO
   OPTUSEIPV6,
 #endif
+  OPTUSESENDBOX,
   OPTWAITKEY,
   OPTWEED,
   OPTWRAP,
diff -r 5c635c9b5982 -r c7191b0264e5 protos.h
--- a/protos.h  Fri Nov 30 10:29:49 2007 +0100
+++ b/protos.h  Tue Dec 04 18:26:01 2007 -0500
@@ -366,7 +366,7 @@ void mutt_update_num_postponed (void);
 void mutt_update_num_postponed (void);
 int mutt_wait_filter (pid_t);
 int mutt_which_case (const char *);
-int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int, 
char *);
+int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int, 
char *, int);
 int mutt_write_mime_body (BODY *, FILE *);
 int mutt_write_mime_header (BODY *, FILE *);
 int mutt_write_one_header (FILE *fp, const char *tag, const char *value, const 
char *pfx, int wraplen);
diff -r 5c635c9b5982 -r c7191b0264e5 send.c
--- a/send.c    Fri Nov 30 10:29:49 2007 +0100
+++ b/send.c    Tue Dec 04 18:26:01 2007 -0500
@@ -973,6 +973,10 @@ static int send_message (HEADER *msg)
   short old_write_bcc;
 #endif
   
+  /* some imap servers can send mail by saving to a special folder */
+  if (option (OPTUSESENDBOX))
+    return mutt_write_fcc (NONULL (Sendbox), msg, NULL, 0, NULL, 1);
+
   /* Write out the message in MIME form. */
   mutt_mktemp (tempfile);
   if ((tempfp = safe_fopen (tempfile, "w")) == NULL)
@@ -1529,7 +1533,7 @@ main_loop:
       mutt_prepare_envelope (msg->env, 0);
       mutt_env_to_idna (msg->env, NULL, NULL); /* Handle bad IDNAs the next 
time. */
 
-      if (!Postponed || mutt_write_fcc (NONULL (Postponed), msg, (cur && 
(flags & SENDREPLY)) ? cur->env->message_id : NULL, 1, fcc) < 0)
+      if (!Postponed || mutt_write_fcc (NONULL (Postponed), msg, (cur && 
(flags & SENDREPLY)) ? cur->env->message_id : NULL, 1, fcc, 0) < 0)
       {
        msg->content = mutt_remove_multipart (msg->content);
        decode_descriptions (msg->content);
@@ -1709,7 +1713,7 @@ full_fcc:
        * message was first postponed.
        */
       msg->received = time (NULL);
-      if (mutt_write_fcc (fcc, msg, NULL, 0, NULL) == -1)
+      if (mutt_write_fcc (fcc, msg, NULL, 0, NULL, 0) == -1)
       {
        /*
         * Error writing FCC, we should abort sending.
diff -r 5c635c9b5982 -r c7191b0264e5 sendlib.c
--- a/sendlib.c Fri Nov 30 10:29:49 2007 +0100
+++ b/sendlib.c Tue Dec 04 18:26:01 2007 -0500
@@ -2376,7 +2376,9 @@ static int _mutt_bounce_message (FILE *f
   int i, ret = 0;
   FILE *f;
   char date[SHORT_STRING], tempfile[_POSIX_PATH_MAX];
-  MESSAGE *msg = NULL;
+  MESSAGE *msg = NULL, *smsg = NULL;
+  CONTEXT sctx;
+  int ch_flags;
 
   if (!h)
   {
@@ -2393,25 +2395,67 @@ static int _mutt_bounce_message (FILE *f
 
   if (!fp) fp = msg->fp;
 
-  mutt_mktemp (tempfile);
-  if ((f = safe_fopen (tempfile, "w")) != NULL)
-  {
-    int ch_flags = CH_XMIT | CH_NONEWLINE | CH_NOQFROM;
-    
-    if (!option (OPTBOUNCEDELIVERED))
-      ch_flags |= CH_WEED_DELIVERED;
-    
-    fseeko (fp, h->offset, 0);
-    fprintf (f, "Resent-From: %s", resent_from);
-    fprintf (f, "\nResent-%s", mutt_make_date (date, sizeof(date)));
-    fprintf (f, "Resent-Message-ID: %s\n", mutt_gen_msgid());
-    fputs ("Resent-To: ", f);
-    mutt_write_address_list (to, f, 11, 0);
-    mutt_copy_header (fp, h, f, ch_flags, NULL);
-    fputc ('\n', f);
-    mutt_copy_bytes (fp, f, h->content->length);
+  ch_flags = CH_XMIT | CH_NONEWLINE | CH_NOQFROM;
+  if (!option (OPTBOUNCEDELIVERED))
+    ch_flags |= CH_WEED_DELIVERED;
+
+  if (option (OPTUSESENDBOX)) {
+    /* some imap servers can send mail by saving to a special folder */
+    if (mx_open_mailbox (NONULL (Sendbox), M_APPEND | M_QUIET, &sctx) == NULL)
+    {
+      dprint (1, (debugfile, "_mutt_bounce_message(): unable to open mailbox 
%s"
+                 "in append-mode, aborting.\n", NONULL (Sendbox)));
+      ret = -1;
+      goto close_msg;
+    }
+    if ((smsg = mx_open_new_message (&sctx, h, M_ADD_FROM)) == NULL)
+    {
+      dprint (1, (debugfile, "_mutt_bounce_message(): mx_open_new_message "
+                 "failed in %s, aborting.\n", NONULL (Sendbox)));
+      mx_close_mailbox (&sctx, NULL);
+      ret = -1;
+      goto close_msg;
+    }
+    f = smsg->fp;
+
+    /* when using sendbox, Resent-To: headers will be unioned by the MTA to
+     * determine the recipient, so weed any old ones
+     */
+    ch_flags |= CH_WEED_RESENT;
+  } else {
+    /* create a temporary message which is the original message with Resent
+     * header fields prepended
+     */
+    mutt_mktemp (tempfile);
+    if ((f = safe_fopen (tempfile, "w")) == NULL) {
+      mutt_perror (tempfile);
+      ret = -1;
+      goto close_msg;
+    }
+  }
+
+  /* prepend the Resent header fields */
+  fprintf (f, "Resent-From: %s", resent_from);
+  fprintf (f, "\nResent-%s", mutt_make_date (date, sizeof(date)));
+  fprintf (f, "Resent-Message-ID: %s\n", mutt_gen_msgid());
+  fputs ("Resent-To: ", f);
+  mutt_write_address_list (to, f, 11, 0);
+
+  /* copy original message */
+  fseeko (fp, h->offset, 0);
+  mutt_copy_header (fp, h, f, ch_flags, NULL);
+  fputc ('\n', f);
+  mutt_copy_bytes (fp, f, h->content->length);
+
+  if (smsg) {
+    /* complete sending via Sendbox */
+    if (mx_commit_message (smsg, &sctx) != 0)
+       ret = -1;
+    mx_close_message (&smsg);
+    mx_close_mailbox (&sctx, NULL);
+  } else {
+    /* complete normal send */
     fclose (f);
-
 #if USE_SMTP
     if (SmtpUrl)
       ret = mutt_smtp_send (env_from, to, NULL, NULL, tempfile,
@@ -2422,6 +2466,7 @@ static int _mutt_bounce_message (FILE *f
                                h->content->encoding == ENC8BIT);
   }
 
+close_msg:
   if (msg)
     mx_close_message (&msg);
 
@@ -2517,7 +2562,8 @@ static void set_noconv_flags (BODY *b, s
   }
 }
 
-int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int 
post, char *fcc)
+int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int 
post, 
+                   char *fcc, int send)
 {
   CONTEXT f;
   MESSAGE *msg;
@@ -2549,7 +2595,7 @@ int mutt_write_fcc (const char *path, HE
     }
   }
 
-  hdr->read = !post; /* make sure to put it in the `cur' directory (maildir) */
+  hdr->read = !(post || send); /* make sure to put it in the `cur' directory 
(maildir) */
   if ((msg = mx_open_new_message (&f, hdr, M_ADD_FROM)) == NULL)
   {
     mx_close_mailbox (&f, NULL);
@@ -2560,6 +2606,10 @@ int mutt_write_fcc (const char *path, HE
    * post == 0 => Normal mode. Set mode = 0 in mutt_write_rfc822_header() 
    * */
   mutt_write_rfc822_header (msg->fp, hdr->env, hdr->content, post ? -post : 0, 
0);
+
+  /* set RO flag if this is not a send or post operation */
+  if (hdr->read)
+    fprintf (msg->fp, "Status: RO\n");
 
   /* (postponment) if this was a reply of some sort, <msgid> contians the
    * Message-ID: of message replied to.  Save it using a special X-Mutt-
@@ -2575,9 +2625,6 @@ int mutt_write_fcc (const char *path, HE
    */
   if (post && fcc)
     fprintf (msg->fp, "X-Mutt-Fcc: %s\n", fcc);
-  fprintf (msg->fp, "Status: RO\n");
-
-
 
   /* (postponment) if the mail is to be signed or encrypted, save this info */
   if ((WithCrypto & APPLICATION_PGP)
@@ -2696,3 +2743,5 @@ int mutt_write_fcc (const char *path, HE
   
   return r;
 }
+
+/* vim: set sw=2: */