]> granicus.if.org Git - mutt/commitdiff
Fix shared attachment functions. (see #3728)
authorKevin McCarthy <kevin@8t8.us>
Fri, 11 Aug 2017 01:18:25 +0000 (18:18 -0700)
committerKevin McCarthy <kevin@8t8.us>
Fri, 11 Aug 2017 01:18:25 +0000 (18:18 -0700)
With nested decryption, the correct FP is associated with the
ATTACHPTR entry.  Also, the BODY entries are not continguous, so the
functions need to iterate over the actx index, not the BODY structure.

attach.h
compose.c
pager.c
recvattach.c
recvcmd.c

index b95230bf1044c151c390c1aaf71b7b7734856c53..12e3ca0413eaf7280bf9b5955efee791edf6a586 100644 (file)
--- a/attach.h
+++ b/attach.h
@@ -61,14 +61,13 @@ void mutt_update_tree (ATTACH_CONTEXT *);
 int mutt_view_attachment (FILE*, BODY *, int, HEADER *, ATTACH_CONTEXT *);
 
 int mutt_tag_attach (MUTTMENU *menu, int n, int m);
-int mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
-                             BODY *cur, ATTACH_CONTEXT *acvtx,
-                             int recv);
+int mutt_attach_display_loop (MUTTMENU *menu, int op, HEADER *hdr,
+                             ATTACH_CONTEXT *acvtx, int recv);
 
 
-void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu);
-void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter);
-void mutt_print_attachment_list (FILE *fp, int tag, BODY *top);
+void mutt_save_attachment_list (ATTACH_CONTEXT *actx, FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu);
+void mutt_pipe_attachment_list (ATTACH_CONTEXT *actx, FILE *fp, int tag, BODY *top, int filter);
+void mutt_print_attachment_list (ATTACH_CONTEXT *actx, FILE *fp, int tag, BODY *top);
 
 void mutt_attach_bounce (FILE *, HEADER *, ATTACH_CONTEXT *, BODY *);
 void mutt_attach_resend (FILE *, HEADER *, ATTACH_CONTEXT *, BODY *);
index ba6d7889aaf567f041914466e9770a9d50660636..80afd97cdb4e631cacbc7217391829677da4e323 100644 (file)
--- a/compose.c
+++ b/compose.c
@@ -1318,27 +1318,27 @@ int mutt_compose_menu (HEADER *msg,   /* structure for new message */
       case OP_VIEW_ATTACH:
       case OP_DISPLAY_HEADERS:
        CHECK_COUNT;
-       mutt_attach_display_loop (menu, op, NULL, NULL, NULL, actx, 0);
+       mutt_attach_display_loop (menu, op, NULL, actx, 0);
        menu->redraw = REDRAW_FULL;
         /* no send2hook, since this doesn't modify the message */
        break;
 
       case OP_SAVE:
        CHECK_COUNT;
-       mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ?  msg->content : CURATTACH->content, NULL, menu);
+       mutt_save_attachment_list (actx, NULL, menu->tagprefix, CURATTACH->content, NULL, menu);
         /* no send2hook, since this doesn't modify the message */
        break;
 
       case OP_PRINT:
        CHECK_COUNT;
-       mutt_print_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : CURATTACH->content);
+       mutt_print_attachment_list (actx, NULL, menu->tagprefix, CURATTACH->content);
         /* no send2hook, since this doesn't modify the message */
        break;
 
       case OP_PIPE:
       case OP_FILTER:
         CHECK_COUNT;
-       mutt_pipe_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : CURATTACH->content, op == OP_FILTER);
+       mutt_pipe_attachment_list (actx, NULL, menu->tagprefix, CURATTACH->content, op == OP_FILTER);
        if (op == OP_FILTER) /* cte might have changed */
          menu->redraw = menu->tagprefix ? REDRAW_FULL : REDRAW_CURRENT;
         menu->redraw |= REDRAW_STATUS;
diff --git a/pager.c b/pager.c
index d435cf8f2040370d65f77c97a335fafa24cb50e4..332bbbf899efa0b750d8bdaf04f603238d1ba590 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -2614,7 +2614,7 @@ search_next:
       case OP_PIPE:
        CHECK_MODE(IsHeader (extra) || IsAttach (extra));
        if (IsAttach (extra))
-         mutt_pipe_attachment_list (extra->fp, 0, extra->bdy, 0);
+         mutt_pipe_attachment_list (extra->actx, extra->fp, 0, extra->bdy, 0);
        else
          mutt_pipe_message (extra->hdr);
        break;
@@ -2622,7 +2622,7 @@ search_next:
       case OP_PRINT:
        CHECK_MODE(IsHeader (extra) || IsAttach (extra));
         if (IsAttach (extra))
-         mutt_print_attachment_list (extra->fp, 0, extra->bdy);
+         mutt_print_attachment_list (extra->actx, extra->fp, 0, extra->bdy);
         else
          mutt_print_message (extra->hdr);
        break;
@@ -2695,7 +2695,7 @@ search_next:
       case OP_SAVE:
        if (IsAttach (extra))
        {
-         mutt_save_attachment_list (extra->fp, 0, extra->bdy, extra->hdr, NULL);
+         mutt_save_attachment_list (extra->actx, extra->fp, 0, extra->bdy, extra->hdr, NULL);
          break;
        }
        /* fall through */
index df98c3538967c60c9ea687af23fc5f15c4265b4b..7137a763c97ac32aaa0ae5d9d457decd27185352 100644 (file)
@@ -491,18 +491,23 @@ static int mutt_query_save_attachment (FILE *fp, BODY *body, HEADER *hdr, char *
   return 0;
 }
     
-void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu)
+void mutt_save_attachment_list (ATTACH_CONTEXT *actx, FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu)
 {
   char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];
   char *directory = NULL;
-  int rc = 1;
+  int i, rc = 1;
   int last = menu ? menu->current : -1;
   FILE *fpout;
 
   buf[0] = 0;
 
-  for (; top; top = top->next)
+  for (i = 0; !tag || i < actx->idxlen; i++)
   {
+    if (tag)
+    {
+      fp = actx->idx[i]->fp;
+      top = actx->idx[i]->content;
+    }
     if (!tag || top->tagged)
     {
       if (!option (OPTATTACHSPLIT))
@@ -553,8 +558,6 @@ void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTM
          break;
       }
     }
-    else if (top->parts)
-      mutt_save_attachment_list (fp, 1, top->parts, hdr, menu);
     if (!tag)
       break;
   }
@@ -636,11 +639,18 @@ static void pipe_attachment (FILE *fp, BODY *b, STATE *state)
 }
 
 static void
-pipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter,
-                     STATE *state)
+pipe_attachment_list (char *command, ATTACH_CONTEXT *actx, FILE *fp, int tag,
+                      BODY *top, int filter, STATE *state)
 {
-  for (; top; top = top->next)
+  int i;
+
+  for (i = 0; !tag || i < actx->idxlen; i++)
   {
+    if (tag)
+    {
+      fp = actx->idx[i]->fp;
+      top = actx->idx[i]->content;
+    }
     if (!tag || top->tagged)
     {
       if (!filter && !option (OPTATTACHSPLIT))
@@ -648,14 +658,12 @@ pipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter,
       else
        mutt_query_pipe_attachment (command, fp, top, filter);
     }
-    else if (top->parts)
-      pipe_attachment_list (command, fp, tag, top->parts, filter, state);
     if (!tag)
       break;
   }
 }
 
-void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter)
+void mutt_pipe_attachment_list (ATTACH_CONTEXT *actx, FILE *fp, int tag, BODY *top, int filter)
 {
   STATE state;
   char buf[SHORT_STRING];
@@ -679,21 +687,24 @@ void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter)
   {
     mutt_endwin (NULL);
     thepid = mutt_create_filter (buf, &state.fpout, NULL, NULL);
-    pipe_attachment_list (buf, fp, tag, top, filter, &state);
+    pipe_attachment_list (buf, actx, fp, tag, top, filter, &state);
     safe_fclose (&state.fpout);
     if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY))
       mutt_any_key_to_continue (NULL);
   }
   else
-    pipe_attachment_list (buf, fp, tag, top, filter, &state);
+    pipe_attachment_list (buf, actx, fp, tag, top, filter, &state);
 }
 
-static int can_print (BODY *top, int tag)
+static int can_print (ATTACH_CONTEXT *actx, BODY *top, int tag)
 {
   char type [STRING];
+  int i;
 
-  for (; top; top = top->next)
+  for (i = 0; !tag || i < actx->idxlen; i++)
   {
+    if (tag)
+      top = actx->idx[i]->content;
     snprintf (type, sizeof (type), "%s/%s", TYPE (top), top->subtype);
     if (!tag || top->tagged)
     {
@@ -710,21 +721,24 @@ static int can_print (BODY *top, int tag)
        }
       }
     }
-    else if (top->parts)
-      return (can_print (top->parts, tag));
     if (!tag)
       break;
   }
   return (1);
 }
 
-static void print_attachment_list (FILE *fp, int tag, BODY *top, STATE *state)
+static void print_attachment_list (ATTACH_CONTEXT *actx, FILE *fp, int tag, BODY *top, STATE *state)
 {
+  int i;
   char type [STRING];
 
-
-  for (; top; top = top->next)
+  for (i = 0; !tag || i < actx->idxlen; i++)
   {
+    if (tag)
+    {
+      fp = actx->idx[i]->fp;
+      top = actx->idx[i]->content;
+    }
     if (!tag || top->tagged)
     {
       snprintf (type, sizeof (type), "%s/%s", TYPE (top), top->subtype);
@@ -757,14 +771,12 @@ static void print_attachment_list (FILE *fp, int tag, BODY *top, STATE *state)
       else
        mutt_print_attachment (fp, top);
     }
-    else if (top->parts)
-      print_attachment_list (fp, tag, top->parts, state);
     if (!tag)
-      return;
+      break;
   }
 }
 
-void mutt_print_attachment_list (FILE *fp, int tag, BODY *top)
+void mutt_print_attachment_list (ATTACH_CONTEXT *actx, FILE *fp, int tag, BODY *top)
 {
   STATE state;
   
@@ -774,24 +786,24 @@ void mutt_print_attachment_list (FILE *fp, int tag, BODY *top)
 
   if (!option (OPTATTACHSPLIT))
   {
-    if (!can_print (top, tag))
+    if (!can_print (actx, top, tag))
       return;
     mutt_endwin (NULL);
     memset (&state, 0, sizeof (STATE));
     thepid = mutt_create_filter (NONULL (PrintCmd), &state.fpout, NULL, NULL);
-    print_attachment_list (fp, tag, top, &state);
+    print_attachment_list (actx, fp, tag, top, &state);
     safe_fclose (&state.fpout);
     if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY))
       mutt_any_key_to_continue (NULL);
   }
   else
-    print_attachment_list (fp, tag, top, &state);
+    print_attachment_list (actx, fp, tag, top, &state);
 }
 
 
 int
-mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
-                         BODY *cur, ATTACH_CONTEXT *actx, int recv)
+mutt_attach_display_loop (MUTTMENU *menu, int op, HEADER *hdr,
+                         ATTACH_CONTEXT *actx, int recv)
 {
   int i;
 
@@ -804,7 +816,7 @@ mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
        /* fall through */
 
       case OP_VIEW_ATTACH:
-       op = mutt_view_attachment (fp, CURATTACH->content, MUTT_REGULAR,
+       op = mutt_view_attachment (CURATTACH->fp, CURATTACH->content, MUTT_REGULAR,
                                   hdr, actx);
        break;
 
@@ -831,7 +843,7 @@ mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
       case OP_EDIT_TYPE:
        /* when we edit the content-type, we should redisplay the attachment
           immediately */
-       mutt_edit_content_type (hdr, CURATTACH->content, fp);
+       mutt_edit_content_type (hdr, CURATTACH->content, CURATTACH->fp);
         if (recv)
         {
           /* Editing the content type can rewrite the body structure. */
@@ -964,10 +976,12 @@ decrypt_failed:
       new->level = level;
       new->decrypted = decrypted;
 
-      if (m->type == TYPEMULTIPART ||
-          mutt_is_message_type(m->type, m->subtype))
-      {
+      if (m->type == TYPEMULTIPART)
         mutt_generate_recvattach_list (actx, hdr, m->parts, fp, m->type, level + 1, decrypted);
+      else if (mutt_is_message_type (m->type, m->subtype))
+      {
+        mutt_generate_recvattach_list (actx, m->hdr, m->parts, fp, m->type, level + 1, decrypted);
+        hdr->security |= m->hdr->security;
       }
     }
   }
@@ -1085,20 +1099,20 @@ void mutt_view_attachments (HEADER *hdr)
     switch (op)
     {
       case OP_ATTACH_VIEW_MAILCAP:
-       mutt_view_attachment (fp, CURATTACH->content, MUTT_MAILCAP,
+       mutt_view_attachment (CURATTACH->fp, CURATTACH->content, MUTT_MAILCAP,
                              hdr, actx);
        menu->redraw = REDRAW_FULL;
        break;
 
       case OP_ATTACH_VIEW_TEXT:
-       mutt_view_attachment (fp, CURATTACH->content, MUTT_AS_TEXT,
+       mutt_view_attachment (CURATTACH->fp, CURATTACH->content, MUTT_AS_TEXT,
                              hdr, actx);
        menu->redraw = REDRAW_FULL;
        break;
 
       case OP_DISPLAY_HEADERS:
       case OP_VIEW_ATTACH:
-        op = mutt_attach_display_loop (menu, op, fp, hdr, cur, actx, 1);
+        op = mutt_attach_display_loop (menu, op, hdr, actx, 1);
         menu->redraw = REDRAW_FULL;
         continue;
 
@@ -1137,22 +1151,22 @@ void mutt_view_attachments (HEADER *hdr)
         break;
 
       case OP_PRINT:
-       mutt_print_attachment_list (fp, menu->tagprefix, 
-                 menu->tagprefix ? cur : CURATTACH->content);
+       mutt_print_attachment_list (actx, CURATTACH->fp, menu->tagprefix,
+                                    CURATTACH->content);
        break;
 
       case OP_PIPE:
-       mutt_pipe_attachment_list (fp, menu->tagprefix, 
-                 menu->tagprefix ? cur : CURATTACH->content, 0);
+       mutt_pipe_attachment_list (actx, CURATTACH->fp, menu->tagprefix,
+                                   CURATTACH->content, 0);
        break;
 
       case OP_SAVE:
-       mutt_save_attachment_list (fp, menu->tagprefix, 
-                 menu->tagprefix ?  cur : CURATTACH->content, hdr, menu);
+       mutt_save_attachment_list (actx, CURATTACH->fp, menu->tagprefix,
+                                   CURATTACH->content, hdr, menu);
 
         if (!menu->tagprefix && option (OPTRESOLVE) && menu->current < menu->max - 1)
          menu->current++;
-      
+
         menu->redraw = REDRAW_MOTION_RESYNCH | REDRAW_FULL;
        break;
 
@@ -1247,35 +1261,35 @@ void mutt_view_attachments (HEADER *hdr)
 
       case OP_RESEND:
         CHECK_ATTACH;
-        mutt_attach_resend (fp, hdr, actx,
-                            menu->tagprefix ? NULL : CURATTACH->content);
+        mutt_attach_resend (CURATTACH->fp, hdr, actx,
+                            menu->tagprefix ? NULL : CURATTACH->content);
         menu->redraw = REDRAW_FULL;
        break;
-      
+
       case OP_BOUNCE_MESSAGE:
         CHECK_ATTACH;
-        mutt_attach_bounce (fp, hdr, actx,
-                            menu->tagprefix ? NULL : CURATTACH->content);
+        mutt_attach_bounce (CURATTACH->fp, hdr, actx,
+                            menu->tagprefix ? NULL : CURATTACH->content);
         menu->redraw = REDRAW_FULL;
        break;
 
       case OP_FORWARD_MESSAGE:
         CHECK_ATTACH;
-        mutt_attach_forward (fp, hdr, actx,
+        mutt_attach_forward (CURATTACH->fp, hdr, actx,
                             menu->tagprefix ? NULL : CURATTACH->content);
         menu->redraw = REDRAW_FULL;
         break;
-      
+
       case OP_REPLY:
       case OP_GROUP_REPLY:
       case OP_LIST_REPLY:
 
         CHECK_ATTACH;
-      
-        flags = SENDREPLY | 
+
+        flags = SENDREPLY |
          (op == OP_GROUP_REPLY ? SENDGROUPREPLY : 0) |
          (op == OP_LIST_REPLY ? SENDLISTREPLY : 0);
-        mutt_attach_reply (fp, hdr, actx,
+        mutt_attach_reply (CURATTACH->fp, hdr, actx,
                           menu->tagprefix ? NULL : CURATTACH->content, flags);
        menu->redraw = REDRAW_FULL;
        break;
index 26a0c9cc4221947ea3cd0cf1eb785ab46bf7bc05..775a0648c93579e9bebcb47d7681a26a7788957c 100644 (file)
--- a/recvcmd.c
+++ b/recvcmd.c
@@ -228,7 +228,7 @@ void mutt_attach_bounce (FILE * fp, HEADER * hdr,
     for (i = 0; i < actx->idxlen; i++)
     {
       if (actx->idx[i]->content->tagged)
-       if (mutt_bounce_message (fp, actx->idx[i]->content->hdr, adr))
+       if (mutt_bounce_message (actx->idx[i]->fp, actx->idx[i]->content->hdr, adr))
          ret = 1;
     }
   }
@@ -237,6 +237,8 @@ void mutt_attach_bounce (FILE * fp, HEADER * hdr,
     mutt_message (p ? _("Message bounced.") : _("Messages bounced."));
   else
     mutt_error (p ? _("Error bouncing message!") : _("Error bouncing messages!"));
+
+  rfc822_free_address (&adr);
 }
 
 
@@ -262,7 +264,7 @@ void mutt_attach_resend (FILE * fp, HEADER * hdr, ATTACH_CONTEXT *actx,
   {
     for (i = 0; i < actx->idxlen; i++)
       if (actx->idx[i]->content->tagged)
-       mutt_resend_message (fp, Context, actx->idx[i]->content->hdr);
+       mutt_resend_message (actx->idx[i]->fp, Context, actx->idx[i]->content->hdr);
   }
 }
 
@@ -275,7 +277,7 @@ void mutt_attach_resend (FILE * fp, HEADER * hdr, ATTACH_CONTEXT *actx,
   
 /* try to find a common parent message for the tagged attachments. */
 
-static HEADER *find_common_parent (ATTACH_CONTEXT *actx, short nattach)
+static ATTACHPTR *find_common_parent (ATTACH_CONTEXT *actx, short nattach)
 {
   short i;
   short nchildren;
@@ -290,7 +292,7 @@ static HEADER *find_common_parent (ATTACH_CONTEXT *actx, short nattach)
     {
       nchildren = count_tagged_children (actx, i);
       if (nchildren == nattach)
-       return actx->idx[i]->content->hdr;
+       return actx->idx[i];
     }
   }
 
@@ -318,10 +320,10 @@ static int is_parent (short i, ATTACH_CONTEXT *actx, BODY *cur)
   return 0;
 }
 
-static HEADER *find_parent (ATTACH_CONTEXT *actx, BODY *cur, short nattach)
+static ATTACHPTR *find_parent (ATTACH_CONTEXT *actx, BODY *cur, short nattach)
 {
   short i;
-  HEADER *parent = NULL;
+  ATTACHPTR *parent = NULL;
   
   if (cur)
   {
@@ -329,7 +331,7 @@ static HEADER *find_parent (ATTACH_CONTEXT *actx, BODY *cur, short nattach)
     {
       if (mutt_is_message_type (actx->idx[i]->content->type, actx->idx[i]->content->subtype) 
          && is_parent (i, actx, cur))
-       parent = actx->idx[i]->content->hdr;
+       parent = actx->idx[i];
       if (actx->idx[i]->content == cur)
        break;
     }
@@ -369,8 +371,7 @@ static void include_header (int quote, FILE * ifp,
 /* 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, 
+static BODY ** copy_problematic_attachments (BODY **last, 
                                             ATTACH_CONTEXT *actx,
                                             short force)
 {
@@ -381,7 +382,7 @@ static BODY ** copy_problematic_attachments (FILE *fp,
     if (actx->idx[i]->content->tagged && 
        (force || !mutt_can_decode (actx->idx[i]->content)))
     {
-      if (mutt_copy_body (fp, last, actx->idx[i]->content) == -1)
+      if (mutt_copy_body (actx->idx[i]->fp, last, actx->idx[i]->content) == -1)
        return NULL;            /* XXXXX - may lead to crashes */
       last = &((*last)->next);
     }
@@ -402,7 +403,9 @@ static void attach_forward_bodies (FILE * fp, HEADER * hdr,
   short i;
   short mime_fwd_all = 0;
   short mime_fwd_any = 1;
-  HEADER *parent = NULL;
+  ATTACHPTR *parent = NULL;
+  HEADER *parent_hdr;
+  FILE *parent_fp;
   HEADER *tmphdr = NULL;
   BODY **last;
   char tmpbody[_POSIX_PATH_MAX];
@@ -422,14 +425,21 @@ static void attach_forward_bodies (FILE * fp, HEADER * hdr,
 
 
   parent = find_parent (actx, cur, nattach);
-  
-  if (parent == NULL)
-    parent = hdr;
+  if (parent)
+  {
+    parent_hdr = parent->content->hdr;
+    parent_fp = parent->fp;
+  }
+  else
+  {
+    parent_hdr = hdr;
+    parent_fp = actx->root_fp;
+  }
 
 
   tmphdr = mutt_new_header ();
   tmphdr->env = mutt_new_envelope ();
-  mutt_make_forward_subject (tmphdr->env, Context, parent);
+  mutt_make_forward_subject (tmphdr->env, Context, parent_hdr);
 
   mutt_mktemp (tmpbody, sizeof (tmpbody));
   if ((tmpfp = safe_fopen (tmpbody, "w")) == NULL)
@@ -438,7 +448,7 @@ static void attach_forward_bodies (FILE * fp, HEADER * hdr,
     return;
   }
 
-  mutt_forward_intro (Context, parent, tmpfp);
+  mutt_forward_intro (Context, parent_hdr, tmpfp);
 
   /* prepare the prefix here since we'll need it later. */
 
@@ -446,12 +456,12 @@ static void attach_forward_bodies (FILE * fp, HEADER * hdr,
   {
     if (!option (OPTTEXTFLOWED))
       _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context,
-                        parent, 0);
+                        parent_hdr, 0);
     else
       strfcpy (prefix, ">", sizeof (prefix));
   }
     
-  include_header (option (OPTFORWQUOTE), fp, parent,
+  include_header (option (OPTFORWQUOTE), parent_fp, parent_hdr,
                  tmpfp, prefix);
 
 
@@ -494,7 +504,6 @@ _("Can't decode all tagged attachments.  MIME-forward the others?"))) == -1)
   st.flags = MUTT_CHARCONV;
   if (option (OPTWEED))
     st.flags |= MUTT_WEED;
-  st.fpin = fp;
   st.fpout = tmpfp;
 
   /* where do we append new MIME parts? */
@@ -506,6 +515,7 @@ _("Can't decode all tagged attachments.  MIME-forward the others?"))) == -1)
 
     if (!mime_fwd_all && mutt_can_decode (cur))
     {
+      st.fpin = fp;
       mutt_body_handler (cur, &st);
       state_putc ('\n', &st);
     }
@@ -526,6 +536,7 @@ _("Can't decode all tagged attachments.  MIME-forward the others?"))) == -1)
       {
        if (actx->idx[i]->content->tagged && mutt_can_decode (actx->idx[i]->content))
        {
+          st.fpin = actx->idx[i]->fp;
          mutt_body_handler (actx->idx[i]->content, &st);
          state_putc ('\n', &st);
        }
@@ -533,17 +544,17 @@ _("Can't decode all tagged attachments.  MIME-forward the others?"))) == -1)
     }
 
     if (mime_fwd_any && 
-       copy_problematic_attachments (fp, last, actx, mime_fwd_all) == NULL)
+       copy_problematic_attachments (last, actx, mime_fwd_all) == NULL)
       goto bail;
   }
   
-  mutt_forward_trailer (Context, parent, tmpfp);
+  mutt_forward_trailer (Context, parent_hdr, tmpfp);
   
   safe_fclose (&tmpfp);
   tmpfp = NULL;
 
   /* now that we have the template, send it. */
-  ci_send_message (0, tmphdr, tmpbody, NULL, parent);
+  ci_send_message (0, tmphdr, tmpbody, NULL, parent_hdr);
   return;
   
   bail:
@@ -649,7 +660,7 @@ static void attach_forward_msgs (FILE * fp, HEADER * hdr,
        {
          /* mutt_message_hook (idx[i]->content->hdr, MUTT_MESSAGEHOOK); */ 
          mutt_forward_intro (Context, actx->idx[i]->content->hdr, tmpfp);
-         _mutt_copy_message (tmpfp, fp, actx->idx[i]->content->hdr,
+         _mutt_copy_message (tmpfp, actx->idx[i]->fp, actx->idx[i]->content->hdr,
                              actx->idx[i]->content->hdr->content, cmflags, chflags);
          mutt_forward_trailer (Context, actx->idx[i]->content->hdr, tmpfp);
        }
@@ -667,7 +678,7 @@ static void attach_forward_msgs (FILE * fp, HEADER * hdr,
       for (i = 0; i < actx->idxlen; i++)
        if (actx->idx[i]->content->tagged)
        {
-         mutt_copy_body (fp, last, actx->idx[i]->content);
+         mutt_copy_body (actx->idx[i]->fp, last, actx->idx[i]->content);
          last = &((*last)->next);
        }
     }
@@ -820,7 +831,9 @@ void mutt_attach_reply (FILE * fp, HEADER * hdr,
   short mime_reply_any = 0;
   
   short nattach = 0;
-  HEADER *parent = NULL;
+  ATTACHPTR *parent = NULL;
+  HEADER *parent_hdr = NULL;
+  FILE *parent_fp = NULL;
   HEADER *tmphdr = NULL;
   short i;
 
@@ -834,8 +847,16 @@ void mutt_attach_reply (FILE * fp, HEADER * hdr,
   if (check_all_msg (actx, cur, 0) == -1)
   {
     nattach = count_tagged (actx);
-    if ((parent = find_parent (actx, cur, nattach)) == NULL)
-      parent = hdr;
+    if ((parent = find_parent (actx, cur, nattach)) != NULL)
+    {
+      parent_hdr = parent->content->hdr;
+      parent_fp = parent->fp;
+    }
+    else
+    {
+      parent_hdr = hdr;
+      parent_fp = actx->root_fp;
+    }
   }
 
   if (nattach > 1 && !check_can_decode (actx, cur))
@@ -853,7 +874,7 @@ void mutt_attach_reply (FILE * fp, HEADER * hdr,
   tmphdr->env = mutt_new_envelope ();
 
   if (attach_reply_envelope_defaults (tmphdr->env, actx,
-                                     parent ? parent : (cur ? cur->hdr : NULL), flags) == -1)
+                                     parent ? parent_hdr : (cur ? cur->hdr : NULL), flags) == -1)
   {
     mutt_free_header (&tmphdr);
     return;
@@ -876,21 +897,20 @@ void mutt_attach_reply (FILE * fp, HEADER * hdr,
       for (i = 0; i < actx->idxlen; i++)
       {
        if (actx->idx[i]->content->tagged)
-         attach_include_reply (fp, tmpfp, actx->idx[i]->content->hdr, flags);
+         attach_include_reply (actx->idx[i]->fp, tmpfp, actx->idx[i]->content->hdr, flags);
       }
     }
   }
   else
   {
-    mutt_make_attribution (Context, parent, tmpfp);
+    mutt_make_attribution (Context, parent_hdr, tmpfp);
     
     memset (&st, 0, sizeof (STATE));
-    st.fpin = fp;
     st.fpout = tmpfp;
 
     if (!option (OPTTEXTFLOWED))
       _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), 
-                        Context, parent, 0);
+                        Context, parent_hdr, 0);
     else
       strfcpy (prefix, ">", sizeof (prefix));
 
@@ -901,12 +921,13 @@ void mutt_attach_reply (FILE * fp, HEADER * hdr,
       st.flags |= MUTT_WEED;
 
     if (option (OPTHEADER))
-      include_header (1, fp, parent, tmpfp, prefix);
+      include_header (1, parent_fp, parent_hdr, tmpfp, prefix);
 
     if (cur)
     {
       if (mutt_can_decode (cur))
       {
+        st.fpin = fp;
        mutt_body_handler (cur, &st);
        state_putc ('\n', &st);
       }
@@ -919,16 +940,17 @@ void mutt_attach_reply (FILE * fp, HEADER * hdr,
       {
        if (actx->idx[i]->content->tagged && mutt_can_decode (actx->idx[i]->content))
        {
+          st.fpin = actx->idx[i]->fp;
          mutt_body_handler (actx->idx[i]->content, &st);
          state_putc ('\n', &st);
        }
       }
     }
 
-    mutt_make_post_indent (Context, parent, tmpfp);
+    mutt_make_post_indent (Context, parent_hdr, tmpfp);
 
     if (mime_reply_any && !cur && 
-       copy_problematic_attachments (fp, &tmphdr->content, actx, 0) == NULL)
+       copy_problematic_attachments (&tmphdr->content, actx, 0) == NULL)
     {
       mutt_free_header (&tmphdr);
       safe_fclose (&tmpfp);
@@ -939,7 +961,7 @@ void mutt_attach_reply (FILE * fp, HEADER * hdr,
   safe_fclose (&tmpfp);
   
   if (ci_send_message (flags, tmphdr, tmpbody, NULL,
-                         parent ? parent : (cur ? cur->hdr : NULL)) == 0)
+                         parent ? parent_hdr : (cur ? cur->hdr : NULL)) == 0)
     mutt_set_flag (Context, hdr, MUTT_REPLIED, 1);
 }