From: Kevin McCarthy Date: Fri, 26 Apr 2019 02:41:04 +0000 (-0700) Subject: Add $forward_attachments quadoption for inline-forward mode. X-Git-Tag: mutt-1-12-rel~34 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=24965a7d355ac5d9bc1d103a88827e48b87e3ce2;p=mutt Add $forward_attachments quadoption for inline-forward mode. 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. --- diff --git a/attach.h b/attach.h index 7ac0e5a5..2cda87da 100644 --- 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_ */ diff --git a/doc/manual.xml.head b/doc/manual.xml.head index 87fbe86e..06f60677 100644 --- a/doc/manual.xml.head +++ b/doc/manual.xml.head @@ -1788,6 +1788,18 @@ therefore $mime_forward is a quadoption which, for example, can be set to ask-no. + +Mutt's default ($mime_forward=no and +$forward_decode=yes) 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 $forward_attachments. + + The inclusion of headers is controlled by the current setting of the $weed variable, unless $mime_forward is set. 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 +$forward_edit. diff --git a/init.h b/init.h index 8bfe2684..3a18ab3c 100644 --- 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 0ce50fab..71b66657 100644 --- 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, diff --git a/recvattach.c b/recvattach.c index cc083ce1..27131fff 100644 --- a/recvattach.c +++ b/recvattach.c @@ -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 137d0153..c04910cd 100644 --- a/send.c +++ b/send.c @@ -31,6 +31,7 @@ #include "mutt_idna.h" #include "url.h" #include "rfc3676.h" +#include "attach.h" #include #include @@ -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;