summaryrefslogtreecommitdiffstats
path: root/recvcmd.c
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>1999-11-07 22:19:45 +0000
committerThomas Roessler <roessler@does-not-exist.org>1999-11-07 22:19:45 +0000
commit283cc465b8a09272d2c15e33e026b1d32eb312ae (patch)
tree6adb24f96ab9e5a7a152dbfedb8b3564510c9c62 /recvcmd.c
parent538c400f14c9ceeb83a3836d622ee968a92eb602 (diff)
Rewriting lots of the recvattach code.
Diffstat (limited to 'recvcmd.c')
-rw-r--r--recvcmd.c873
1 files changed, 873 insertions, 0 deletions
diff --git a/recvcmd.c b/recvcmd.c
new file mode 100644
index 00000000..8dff3ba4
--- /dev/null
+++ b/recvcmd.c
@@ -0,0 +1,873 @@
+/*
+ * Copyright (C) 1999 Thomas Roessler <roessler@guug.de>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+ * 02139, USA.
+ */
+
+#include "mutt.h"
+#include "mutt_curses.h"
+#include "mutt_menu.h"
+#include "rfc1524.h"
+#include "mime.h"
+#include "mailbox.h"
+#include "attach.h"
+#include "mapping.h"
+#include "mx.h"
+#include "copy.h"
+
+
+/* some helper functions to verify that we are exclusively operating
+ * on message/rfc822 attachments
+ */
+
+static short check_msg (BODY * b, short err)
+{
+ if (!mutt_is_message_type (b->type, b->subtype))
+ {
+ if (err)
+ mutt_error _("You may only bounce message/rfc822 parts.");
+ return -1;
+ }
+ return 0;
+}
+
+static short check_all_msg (ATTACHPTR ** idx, short idxlen,
+ BODY * cur, short err)
+{
+ short i;
+
+ if (cur && check_msg (cur, err) == -1)
+ return -1;
+ else if (!cur)
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged)
+ {
+ if (check_msg (idx[i]->content, err) == -1)
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/* can we decode all tagged attachments? */
+
+static short check_can_decode (ATTACHPTR ** idx, short idxlen,
+ BODY * cur)
+{
+ short i;
+
+ if (cur)
+ return mutt_can_decode (cur);
+
+ for (i = 0; i < idxlen; i++)
+ if (idx[i]->content->tagged && !mutt_can_decode (idx[i]->content))
+ return 0;
+
+ return 1;
+}
+
+static short count_tagged (ATTACHPTR **idx, short idxlen)
+{
+ short count = 0;
+ short i;
+
+ for (i = 0; i < idxlen; i++)
+ if (idx[i]->content->tagged)
+ count++;
+
+ return count;
+}
+
+/* count the number of tagged children below a multipart or message
+ * attachment.
+ */
+
+static short count_tagged_children (ATTACHPTR ** idx,
+ short idxlen, short i)
+{
+ short level = idx[i]->level;
+ short count = 0;
+
+ while ((++i < idxlen) && (level < idx[i]->level))
+ if (idx[i]->content->tagged)
+ count++;
+
+ return count;
+}
+
+
+
+/**
+ **
+ ** The bounce function, from the attachment menu
+ **
+ **/
+
+void mutt_attach_bounce (FILE * fp, HEADER * hdr,
+ ATTACHPTR ** idx, short idxlen, BODY * cur)
+{
+ short i;
+ short ntagged;
+ char prompt[STRING];
+ char buf[HUGE_STRING];
+ ADDRESS *adr = NULL;
+
+ if (check_all_msg (idx, idxlen, cur, 1) == -1)
+ return;
+
+ ntagged = count_tagged (idx, idxlen);
+
+ if (cur || ntagged == 1)
+ strfcpy (prompt, _("Bounce message to: "), sizeof (prompt));
+ else
+ strfcpy (prompt, _("Bounce tagged messages to: "), sizeof (prompt));
+
+ buf[0] = '\0';
+ if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS)
+ || buf[0] == '\0')
+ return;
+
+ adr = rfc822_parse_adrlist (adr, buf);
+ adr = mutt_expand_aliases (adr);
+ buf[0] = 0;
+ rfc822_write_address (buf, sizeof (buf), adr);
+
+ snprintf (prompt, sizeof (prompt),
+ cur ? _("Bounce message to %s...?") : _("Bounce messages to %s...?"), buf);
+
+ if (mutt_yesorno (prompt, 1) != 1)
+ goto bail;
+
+ if (cur)
+ mutt_bounce_message (fp, cur->hdr, adr);
+ else
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged)
+ mutt_bounce_message (fp, idx[i]->content->hdr, adr);
+ }
+ }
+
+bail:
+
+ rfc822_free_address (&adr);
+ CLEARLINE (LINES - 1);
+}
+
+
+
+/**
+ **
+ ** resend-message, from the attachment menu
+ **
+ **
+ **/
+
+void mutt_attach_resend (FILE * fp, HEADER * hdr, ATTACHPTR ** idx,
+ short idxlen, BODY * cur)
+{
+ short i;
+
+ if (check_all_msg (idx, idxlen, cur, 1) == -1)
+ return;
+
+ if (cur)
+ mutt_resend_message (fp, Context, cur->hdr);
+ else
+ {
+ for (i = 0; i < idxlen; i++)
+ if (idx[i]->content->tagged)
+ mutt_resend_message (fp, Context, idx[i]->content->hdr);
+ }
+}
+
+
+/**
+ **
+ ** forward-message, from the attachment menu
+ **
+ **/
+
+/* try to find a common parent message for the tagged attachments. */
+
+static HEADER *find_common_parent (ATTACHPTR ** idx, short idxlen,
+ short nattach)
+{
+ short i;
+ short nchildren;
+
+ for (i = 0; i < idxlen; i++)
+ if (idx[i]->content->tagged)
+ break;
+
+ while (--i >= 0)
+ {
+ if (mutt_is_message_type (idx[i]->content->type, idx[i]->content->subtype))
+ {
+ nchildren = count_tagged_children (idx, idxlen, i);
+ if (nchildren == nattach)
+ return idx[i]->content->hdr;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * check whether attachment #i is a parent of the attachment
+ * pointed to by cur
+ *
+ * Note: This and the calling procedure could be optimized quite a
+ * bit. For now, it's not worth the effort.
+ */
+
+static int is_parent (short i, ATTACHPTR **idx, short idxlen, BODY *cur)
+{
+ short level = idx[i]->level;
+
+ while ((++i < idxlen) && idx[i]->level > level)
+ {
+ if (idx[i]->content == cur)
+ return 1;
+ }
+
+ return 0;
+}
+
+static HEADER *find_parent (ATTACHPTR **idx, short idxlen, BODY *cur, short nattach)
+{
+ short i;
+ HEADER *parent = NULL;
+
+ if (cur)
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (mutt_is_message_type (idx[i]->content->type, idx[i]->content->subtype)
+ && is_parent (i, idx, idxlen, cur))
+ parent = idx[i]->content->hdr;
+ if (idx[i]->content == cur)
+ break;
+ }
+ }
+ else if (nattach)
+ parent = find_common_parent (idx, idxlen, nattach);
+
+ return parent;
+}
+
+static void include_header (int quote, FILE * ifp,
+ HEADER * hdr, FILE * ofp,
+ char *_prefix)
+{
+ int chflags = CH_DECODE;
+ char prefix[SHORT_STRING];
+
+ if (option (OPTWEED))
+ chflags |= CH_WEED | CH_REORDER;
+
+ if (quote)
+ {
+ if (_prefix)
+ strfcpy (prefix, _prefix, sizeof (prefix));
+ else
+ _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix),
+ Context, hdr, 0);
+
+ chflags |= CH_PREFIX;
+ }
+
+ mutt_copy_header (ifp, hdr, ofp, chflags, quote ? prefix : NULL);
+}
+
+/* Attach all the body parts which can't be decoded.
+ * This code is shared by forwarding and replying. */
+
+static BODY ** copy_problematic_attachments (FILE *fp,
+ BODY **last,
+ ATTACHPTR **idx,
+ short idxlen,
+ short force)
+{
+ short i;
+
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged &&
+ (force || !mutt_can_decode (idx[i]->content)))
+ {
+ if (mutt_copy_body (fp, last, idx[i]->content) == -1)
+ return NULL; /* XXXXX - may lead to crashes */
+ last = &((*last)->next);
+ }
+ }
+ return last;
+}
+
+/*
+ * forward one or several MIME bodies
+ * (non-message types)
+ */
+
+static void attach_forward_bodies (FILE * fp, HEADER * hdr,
+ ATTACHPTR ** idx, short idxlen,
+ BODY * cur,
+ short nattach)
+{
+ short i;
+ short mime_fwd_all = 0;
+ short mime_fwd_any = 1;
+ HEADER *parent = NULL;
+ HEADER *tmphdr = NULL;
+ BODY **last;
+ char tmpbody[_POSIX_PATH_MAX];
+ FILE *tmpfp = NULL;
+
+ char prefix[STRING];
+
+ int rc = 0;
+
+ STATE st;
+
+ /*
+ * First, find the parent message.
+ * Note: This could be made an option by just
+ * putting the following lines into an if block.
+ */
+
+
+ parent = find_parent (idx, idxlen, cur, nattach);
+
+ if (parent == NULL)
+ parent = hdr;
+
+
+ tmphdr = mutt_new_header ();
+ tmphdr->env = mutt_new_envelope ();
+ mutt_make_forward_subject (tmphdr->env, Context, parent);
+
+ mutt_mktemp (tmpbody);
+ if ((tmpfp = safe_fopen (tmpbody, "w")) == NULL)
+ {
+ mutt_error (_("Can't open temporary file %s."), tmpbody);
+ return;
+ }
+
+ mutt_forward_intro (tmpfp, parent);
+
+ /* prepare the prefix here since we'll need it later. */
+
+ if (option (OPTFORWQUOTE))
+ _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context,
+ parent, 0);
+
+ include_header (option (OPTFORWQUOTE), fp, parent,
+ tmpfp, prefix);
+
+
+ /*
+ * Now, we have prepared the first part of the message body: The
+ * original message's header.
+ *
+ * The next part is more interesting: either include the message bodies,
+ * or attach them.
+ */
+
+ if ((!cur || mutt_can_decode (cur)) &&
+ (rc = query_quadoption (OPT_MIMEFWD,
+ _("Forward MIME encapsulated?"))) == M_YES)
+ mime_fwd_all = 1;
+ else if (rc == -1)
+ goto bail;
+
+ /*
+ * shortcut MIMEFWDREST when there is only one attachment. Is
+ * this intuitive?
+ */
+
+ if (!mime_fwd_all && !cur && (nattach > 1)
+ && !check_can_decode (idx, idxlen, cur))
+ {
+ if ((rc = query_quadoption (OPT_MIMEFWDREST,
+_("Can't decode all tagged attachments. MIME-forward the others?"))) == -1)
+ goto bail;
+ else if (rc == M_NO)
+ mime_fwd_any = 0;
+ }
+
+ /* initialize a state structure */
+
+ memset (&st, 0, sizeof (st));
+
+ if (option (OPTFORWQUOTE))
+ st.prefix = prefix;
+ st.flags = M_CHARCONV;
+ if (option (OPTWEED))
+ st.flags |= M_WEED;
+ st.fpin = fp;
+ st.fpout = tmpfp;
+
+ /* where do we append new MIME parts? */
+ last = &tmphdr->content;
+
+ if (cur)
+ {
+ /* single body case */
+
+ if (!mime_fwd_all && mutt_can_decode (cur))
+ {
+ mutt_body_handler (cur, &st);
+ state_putc ('\n', &st);
+ }
+ else
+ {
+ if (mutt_copy_body (fp, last, cur) == -1)
+ goto bail;
+ last = &((*last)->next);
+ }
+ }
+ else
+ {
+ /* multiple body case */
+
+ if (!mime_fwd_all)
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged && mutt_can_decode (idx[i]->content))
+ {
+ mutt_body_handler (idx[i]->content, &st);
+ state_putc ('\n', &st);
+ }
+ }
+ }
+
+ if (mime_fwd_any &&
+ (last = copy_problematic_attachments (fp, last, idx, idxlen, mime_fwd_all)) == NULL)
+ goto bail;
+ }
+
+ mutt_forward_trailer (tmpfp);
+
+ fclose (tmpfp);
+ tmpfp = NULL;
+
+ /* now that we have the template, send it. */
+ ci_send_message (0, tmphdr, tmpbody, NULL, parent);
+ return;
+
+ bail:
+
+ if (tmpfp)
+ {
+ fclose (tmpfp);
+ mutt_unlink (tmpbody);
+ }
+
+ mutt_free_header (&tmphdr);
+}
+
+
+/*
+ * Forward one or several message-type attachments. This
+ * is different from the previous function
+ * since we want to mimic the index menu's behaviour.
+ *
+ * Code reuse from ci_send_message is not possible here -
+ * ci_send_message relies on a context structure to find messages,
+ * while, on the attachment menu, messages are referenced through
+ * the attachment index.
+ */
+
+static void attach_forward_msgs (FILE * fp, HEADER * hdr,
+ ATTACHPTR ** idx, short idxlen, BODY * cur)
+{
+ HEADER *curhdr = NULL;
+ HEADER *tmphdr;
+ short i;
+ int rc;
+
+ BODY **last;
+ char tmpbody[_POSIX_PATH_MAX];
+ FILE *tmpfp = NULL;
+
+ int cmflags = 0;
+ int chflags = CH_XMIT;
+
+ if (cur)
+ curhdr = cur->hdr;
+ else
+ {
+ for (i = 0; i < idxlen; i++)
+ if (idx[i]->content->tagged)
+ {
+ curhdr = idx[i]->content->hdr;
+ break;
+ }
+ }
+
+ tmphdr = mutt_new_header ();
+ tmphdr->env = mutt_new_envelope ();
+ mutt_make_forward_subject (tmphdr->env, Context, curhdr);
+
+
+ tmpbody[0] = '\0';
+
+ if ((rc = query_quadoption (OPT_MIMEFWD,
+ _("Forward MIME encapsulated?"))) == M_NO)
+ {
+
+ /* no MIME encapsulation */
+
+ mutt_mktemp (tmpbody);
+ if (!(tmpfp = safe_fopen (tmpbody, "w")))
+ {
+ mutt_error (_("Can't create %s."), tmpbody);
+ mutt_free_header (&tmphdr);
+ return;
+ }
+
+ if (option (OPTFORWQUOTE))
+ {
+ chflags |= CH_PREFIX;
+ cmflags |= M_CM_PREFIX;
+ }
+
+ if (option (OPTFORWDECODE))
+ {
+ cmflags |= M_CM_DECODE | M_CM_CHARCONV;
+ if (option (OPTWEED))
+ {
+ chflags |= CH_WEED | CH_REORDER;
+ cmflags |= M_CM_WEED;
+ }
+ }
+
+
+ if (cur)
+ {
+ mutt_forward_intro (tmpfp, cur->hdr);
+ _mutt_copy_message (tmpfp, fp, cur->hdr, cur->hdr->content, cmflags, chflags);
+ mutt_forward_trailer (tmpfp);
+ }
+ else
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged)
+ {
+ mutt_forward_intro (tmpfp, idx[i]->content->hdr);
+ _mutt_copy_message (tmpfp, fp, idx[i]->content->hdr,
+ idx[i]->content->hdr->content, cmflags, chflags);
+ mutt_forward_trailer (tmpfp);
+ }
+ }
+ }
+ fclose (tmpfp);
+ }
+ else if (rc == M_YES) /* do MIME encapsulation - we don't need to do much here */
+ {
+ last = &tmphdr->content;
+ if (cur)
+ mutt_copy_body (fp, last, cur);
+ else
+ {
+ for (i = 0; i < idxlen; i++)
+ if (idx[i]->content->tagged)
+ {
+ mutt_copy_body (fp, last, idx[i]->content);
+ last = &((*last)->next);
+ }
+ }
+ }
+ else
+ mutt_free_header (&tmphdr);
+
+ ci_send_message (0, tmphdr, *tmpbody ? tmpbody : NULL,
+ NULL, curhdr);
+
+}
+
+void mutt_attach_forward (FILE * fp, HEADER * hdr,
+ ATTACHPTR ** idx, short idxlen, BODY * cur)
+{
+ short nattach;
+
+
+ if (check_all_msg (idx, idxlen, cur, 0) == 0)
+ attach_forward_msgs (fp, hdr, idx, idxlen, cur);
+ else
+ {
+ nattach = count_tagged (idx, idxlen);
+ attach_forward_bodies (fp, hdr, idx, idxlen, cur, nattach);
+ }
+}
+
+
+
+/**
+ **
+ ** the various reply functions, from the attachment menu
+ **
+ **
+ **/
+
+/* Create the envelope defaults for a reply.
+ *
+ * This function can be invoked in two ways.
+ *
+ * Either, parent is NULL. In this case, all tagged bodies are of a message type,
+ * and the header information is fetched from them.
+ *
+ * Or, parent is non-NULL. In this case, cur is the common parent of all the
+ * tagged attachments.
+ *
+ * Note that this code is horribly similar to envelope_defaults () from send.c.
+ */
+
+static int
+attach_reply_envelope_defaults (ENVELOPE *env, ATTACHPTR **idx, short idxlen,
+ HEADER *parent, int flags)
+{
+ ENVELOPE *curenv = NULL;
+ HEADER *curhdr = NULL;
+ short i;
+
+ if (!parent)
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged)
+ {
+ curhdr = idx[i]->content->hdr;
+ curenv = curhdr->env;
+ break;
+ }
+ }
+ }
+ else
+ {
+ curenv = parent->env;
+ curhdr = parent;
+ }
+
+ if (curenv == NULL || curhdr == NULL)
+ {
+ mutt_error _("Can't find any tagged messages.");
+ return -1;
+ }
+
+ if (parent)
+ {
+ if (mutt_fetch_recips (env, curenv, flags) == -1)
+ return -1;
+ }
+ else
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged
+ && mutt_fetch_recips (env, idx[i]->content->hdr->env, flags) == -1)
+ return -1;
+ }
+ }
+
+ if ((flags & SENDLISTREPLY) && !env->to)
+ {
+ mutt_error _("No mailing lists found!");
+ return (-1);
+ }
+
+ mutt_fix_reply_recipients (env);
+ mutt_make_misc_reply_headers (env, Context, curhdr, curenv);
+
+ if (parent)
+ env->references = mutt_make_references (curenv);
+ else
+ {
+ LIST **p;
+
+ env->references = NULL;
+ p = &env->references;
+
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged)
+ {
+ while (*p) p = &(*p)->next;
+ *p = mutt_make_references (idx[i]->content->hdr->env);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/* This is _very_ similar to send.c's include_reply(). */
+
+static void attach_include_reply (FILE *fp, FILE *tmpfp, HEADER *cur, int flags)
+{
+ int cmflags = M_CM_PREFIX | M_CM_DECODE | M_CM_CHARCONV;
+ int chflags = CH_DECODE;
+
+ mutt_make_attribution (Context, cur, tmpfp);
+
+ if (!option (OPTHEADER))
+ cmflags |= M_CM_NOHEADER;
+ if (option (OPTWEED))
+ {
+ chflags |= CH_WEED;
+ cmflags |= M_CM_WEED;
+ }
+
+ _mutt_copy_message (tmpfp, fp, cur, cur->content, cmflags, chflags);
+ mutt_make_post_indent (Context, cur, tmpfp);
+}
+
+void mutt_attach_reply (FILE * fp, HEADER * hdr,
+ ATTACHPTR ** idx, short idxlen, BODY * cur,
+ int flags)
+{
+ short mime_reply_any = 0;
+
+ short nattach = 0;
+ HEADER *parent = NULL;
+ HEADER *tmphdr = NULL;
+ short i;
+
+ STATE st;
+ char tmpbody[_POSIX_PATH_MAX];
+ FILE *tmpfp;
+
+ char prefix[SHORT_STRING];
+ int rc;
+
+ if (check_all_msg (idx, idxlen, cur, 0) == -1)
+ {
+ nattach = count_tagged (idx, idxlen);
+ if ((parent = find_parent (idx, idxlen, cur, nattach)) == NULL)
+ parent = hdr;
+ }
+
+ if (nattach > 1 && !check_can_decode (idx, idxlen, cur))
+ {
+ if ((rc = query_quadoption (OPT_MIMEFWDREST,
+ _("Can't decode all tagged attachments. MIME-encapsulate the others?"))) == -1)
+ return;
+ else if (rc == M_YES)
+ mime_reply_any = 1;
+ }
+ else if (nattach == 1)
+ mime_reply_any = 1;
+
+ tmphdr = mutt_new_header ();
+ tmphdr->env = mutt_new_envelope ();
+
+ if (attach_reply_envelope_defaults (tmphdr->env, idx, idxlen,
+ parent ? parent : cur->hdr, flags) == -1)
+ {
+ mutt_free_header (&tmphdr);
+ return;
+ }
+
+ mutt_mktemp (tmpbody);
+ if ((tmpfp = safe_fopen (tmpbody, "w")) == NULL)
+ {
+ mutt_error (_("Can't create %s."), tmpbody);
+ mutt_free_header (&tmphdr);
+ return;
+ }
+
+ if (!parent)
+ {
+ if (cur)
+ attach_include_reply (fp, tmpfp, cur->hdr, flags);
+ else
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged)
+ attach_include_reply (fp, tmpfp, idx[i]->content->hdr, flags);
+ }
+ }
+ }
+ else
+ {
+ mutt_make_attribution (Context, parent, tmpfp);
+
+ memset (&st, 0, sizeof (STATE));
+ st.fpin = fp;
+ st.fpout = tmpfp;
+
+ _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix),
+ Context, parent, 0);
+
+ st.prefix = prefix;
+ st.flags = M_CHARCONV;
+
+ if (option (OPTWEED))
+ st.flags |= M_WEED;
+
+ if (option (OPTHEADER))
+ include_header (1, fp, parent, tmpfp, prefix);
+
+ if (cur)
+ {
+ if (mutt_can_decode (cur))
+ {
+ mutt_body_handler (cur, &st);
+ state_putc ('\n', &st);
+ }
+ else
+ mutt_copy_body (fp, &tmphdr->content, cur);
+ }
+ else
+ {
+ for (i = 0; i < idxlen; i++)
+ {
+ if (idx[i]->content->tagged && mutt_can_decode (idx[i]->content))
+ {
+ mutt_body_handler (idx[i]->content, &st);
+ state_putc ('\n', &st);
+ }
+ }
+ }
+
+ mutt_make_post_indent (Context, parent, tmpfp);
+
+ if (mime_reply_any && !cur &&
+ copy_problematic_attachments (fp, &tmphdr->content, idx, idxlen, 0) == NULL)
+ {
+ mutt_free_header (&tmphdr);
+ fclose (tmpfp);
+ return;
+ }
+ }
+
+ fclose (tmpfp);
+
+ if (ci_send_message (flags, tmphdr, tmpbody, NULL, parent) == 0)
+ mutt_set_flag (Context, hdr, M_REPLIED, 1);
+}
+