[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: */