]> granicus.if.org Git - mutt/commitdiff
Add $forward_attachments quadoption for inline-forward mode.
authorKevin McCarthy <kevin@8t8.us>
Fri, 26 Apr 2019 02:41:04 +0000 (19:41 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sat, 27 Apr 2019 23:03:05 +0000 (16:03 -0700)
When set or answered yes, non text-decodable parts will be attached to
the new message.  The default value is "ask-yes", because I believe
this is something people will want to use, and should be made aware of
the new possible behavior.

The option presents a nice middle ground between previous
inline-forwarding behavior (where all the non-text parts were
dropped), and $mime_forward where the entire email was included as an
attachment.

This was previously difficult to achieve, but after the
recv-attachment refactoring: (a19e5266^..faabd621)
it became possible to use the ATTACH_CONTEXT and the recvattach.c
helper mutt_generate_recvattach_list() to properly deal with nesting
and multiple file-handles.

attach.h
doc/manual.xml.head
init.h
mutt.h
recvattach.c
send.c

index 7ac0e5a560b828ecb893de3f1273a8ba3d4176e2..2cda87daad4469aa41d986a4d3fe4b2534ff2bf2 100644 (file)
--- a/attach.h
+++ b/attach.h
@@ -81,4 +81,8 @@ void mutt_actx_add_body (ATTACH_CONTEXT *actx, BODY *new_body);
 void mutt_actx_free_entries (ATTACH_CONTEXT *actx);
 void mutt_free_attach_context (ATTACH_CONTEXT **pactx);
 
+/* This function is also used in send.c for inline-forwarding attachments */
+void mutt_generate_recvattach_list (ATTACH_CONTEXT *actx, HEADER *hdr, BODY *parts,
+                                    FILE *fp, int parent_type, int level, int decrypted);
+
 #endif /* _ATTACH_H_ */
index 87fbe86ed197d8d4d9e68fd938463654fc083616..06f606772ae3795ca2f374f740fe3854a5a9ef1d 100644 (file)
@@ -1788,6 +1788,18 @@ therefore <link linkend="mime-forward">$mime_forward</link> is a
 quadoption which, for example, can be set to <quote>ask-no</quote>.
 </para>
 
+<para>
+Mutt's default (<link
+linkend="mime-forward">$mime_forward</link>=<quote>no</quote> and
+<link
+linkend="forward-decode">$forward_decode</link>=<quote>yes</quote>) is
+to use standard inline forwarding.  In that mode all text-decodable
+parts are included in the new message body.  Other attachments from
+the original email can also attached to the new message, based on the
+quadoption <link
+linkend="forward-attachments">$forward_attachments</link>.
+</para>
+
 <para>
 The inclusion of headers is controlled by the current setting of the
 <link linkend="weed">$weed</link> variable, unless <link
@@ -1796,7 +1808,8 @@ linkend="mime-forward">$mime_forward</link> is set.
 
 <para>
 Editing the message to forward follows the same procedure as sending or
-replying to a message does.
+replying to a message does, but can be disabled via the quadoption
+<link linkend="forward-edit">$forward_edit</link>.
 </para>
 
 </sect1>
diff --git a/init.h b/init.h
index 8bfe2684090ed4b47de49fda8ebb648b56012960..3a18ab3cad2d5ba6a9ef1a87da18b523fe8528e2 100644 (file)
--- a/init.h
+++ b/init.h
@@ -1013,6 +1013,15 @@ struct option_t MuttVars[] = {
   ** .pp
   ** Also see the $$record variable.
   */
+  { "forward_attachments", DT_QUAD, R_NONE, OPT_FORWATTS, MUTT_ASKYES },
+  /*
+  ** .pp
+  ** When forwarding inline (i.e. $$mime_forward \fIunset\fP or
+  ** answered with ``no'' and $$forward_decode \fIset\fP), attachments
+  ** which cannot be decoded in a reasonable manner will be attached
+  ** to the newly composed message if this quadoption is \fIset\fP or
+  ** answered with ``yes''.
+  */
   { "forward_attribution_intro", DT_STR, R_NONE, UL &ForwardAttrIntro, UL "----- Forwarded message from %f -----" },
   /*
   ** .pp
diff --git a/mutt.h b/mutt.h
index 0ce50fab9f901634d586f0b518555378db180f77..71b666579cbcec574821f14da33a81a0ff96f20d 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -306,6 +306,7 @@ enum
   OPT_BOUNCE,
   OPT_COPY,
   OPT_DELETE,
+  OPT_FORWATTS,
   OPT_FORWEDIT,
   OPT_FCCATTACH,
   OPT_INCLUDE,
index cc083ce1df3ae2124c50a7804a648720e2290627..27131fff317b9e7dca7301f90989f99f5d34bd93 100644 (file)
@@ -923,13 +923,13 @@ mutt_attach_display_loop (MUTTMENU *menu, int op, HEADER *hdr,
   return op;
 }
 
-static void mutt_generate_recvattach_list (ATTACH_CONTEXT *actx,
-                                           HEADER *hdr,
-                                           BODY *parts,
-                                           FILE *fp,
-                                           int parent_type,
-                                           int level,
-                                           int decrypted)
+void mutt_generate_recvattach_list (ATTACH_CONTEXT *actx,
+                                    HEADER *hdr,
+                                    BODY *parts,
+                                    FILE *fp,
+                                    int parent_type,
+                                    int level,
+                                    int decrypted)
 {
   ATTACHPTR *new;
   BODY *m;
diff --git a/send.c b/send.c
index 137d0153d57cf000e1d0bc5cfc221101dc8f1d04..c04910cdade5f222458ce0e49d9188ee5e2ec219 100644 (file)
--- a/send.c
+++ b/send.c
@@ -31,6 +31,7 @@
 #include "mutt_idna.h"
 #include "url.h"
 #include "rfc3676.h"
+#include "attach.h"
 
 #include <ctype.h>
 #include <stdlib.h>
@@ -391,6 +392,112 @@ static int include_forward (CONTEXT *ctx, HEADER *cur, FILE *out)
   return 0;
 }
 
+static int inline_forward_attachments (CONTEXT *ctx, HEADER *cur,
+                                       BODY ***plast, int *forwardq)
+{
+  BODY **last = *plast, *body;
+  MESSAGE *msg = NULL;
+  ATTACH_CONTEXT *actx = NULL;
+  int rc = 0, i;
+
+  mutt_parse_mime_message (ctx, cur);
+  mutt_message_hook (ctx, cur, MUTT_MESSAGEHOOK);
+
+  if ((msg = mx_open_message (ctx, cur->msgno)) == NULL)
+    return -1;
+
+  actx = safe_calloc (sizeof(ATTACH_CONTEXT), 1);
+  actx->hdr = cur;
+  actx->root_fp = msg->fp;
+
+  mutt_generate_recvattach_list (actx, actx->hdr, actx->hdr->content,
+                                 actx->root_fp, -1, 0, 0);
+
+  for (i = 0; i < actx->idxlen; i++)
+  {
+    body = actx->idx[i]->content;
+    if ((body->type != TYPEMULTIPART) &&
+       !mutt_can_decode (body) &&
+        !(body->type == TYPEAPPLICATION &&
+          (!ascii_strcasecmp (body->subtype, "pgp-signature") ||
+           !ascii_strcasecmp (body->subtype, "x-pkcs7-signature") ||
+           !ascii_strcasecmp (body->subtype, "pkcs7-signature"))))
+    {
+      /* Ask the quadoption only once */
+      if (*forwardq == -1)
+      {
+        *forwardq = query_quadoption (OPT_FORWATTS,
+        /* L10N:
+           This is the prompt for $forward_attachments.
+           When inline forwarding ($mime_forward answered "no"), this prompts
+           whether to add non-decodable attachments from the original email.
+           Text/plain parts and the like will be already be included in the
+           message contents, but other attachment, such as PDF files, will also
+           be added as attachments to the new mail, is this is answered yes.
+        */
+                                      _("Forward attachments?"));
+        if (*forwardq != MUTT_YES)
+        {
+          if (*forwardq == -1)
+            rc = -1;
+          goto cleanup;
+        }
+      }
+      if (mutt_copy_body (actx->idx[i]->fp, last, body) == -1)
+      {
+        rc = -1;
+       goto cleanup;
+      }
+      last = &((*last)->next);
+    }
+  }
+
+cleanup:
+  *plast = last;
+  mx_close_message (ctx, &msg);
+  mutt_free_attach_context (&actx);
+  return rc;
+}
+
+int mutt_inline_forward (CONTEXT *ctx, HEADER *msg, HEADER *cur, FILE *out)
+{
+  int i, forwardq = -1;
+  BODY **last;
+
+  if (cur)
+    include_forward (ctx, cur, out);
+  else
+    for (i = 0; i < ctx->vcount; i++)
+      if (ctx->hdrs[ctx->v2r[i]]->tagged)
+        include_forward (ctx, ctx->hdrs[ctx->v2r[i]], out);
+
+  if (option (OPTFORWDECODE) && (quadoption (OPT_FORWATTS) != MUTT_NO))
+  {
+    last = &msg->content;
+    while (*last)
+      last = &((*last)->next);
+
+    if (cur)
+    {
+      if (inline_forward_attachments (ctx, cur, &last, &forwardq) != 0)
+        return -1;
+    }
+    else
+      for (i = 0; i < ctx->vcount; i++)
+        if (ctx->hdrs[ctx->v2r[i]]->tagged)
+        {
+          if (inline_forward_attachments (ctx, ctx->hdrs[ctx->v2r[i]],
+                                          &last, &forwardq) != 0)
+            return -1;
+          if (forwardq == MUTT_NO)
+            break;
+        }
+  }
+
+  return 0;
+}
+
+
 void mutt_make_attribution (CONTEXT *ctx, HEADER *cur, FILE *out)
 {
   char buffer[LONG_STRING];
@@ -838,12 +945,8 @@ generate_body (FILE *tempfp,       /* stream for outgoing message */
     }
     else if (i != -1)
     {
-      if (cur)
-       include_forward (ctx, cur, tempfp);
-      else
-       for (i=0; i < ctx->vcount; i++)
-         if (ctx->hdrs[ctx->v2r[i]]->tagged)
-           include_forward (ctx, ctx->hdrs[ctx->v2r[i]], tempfp);
+      if (mutt_inline_forward (ctx, msg, cur, tempfp) != 0)
+        return -1;
     }
     else if (i == -1)
       return -1;