summaryrefslogtreecommitdiffstats
path: root/recvattach.c
diff options
context:
space:
mode:
Diffstat (limited to 'recvattach.c')
-rw-r--r--recvattach.c357
1 files changed, 65 insertions, 292 deletions
diff --git a/recvattach.c b/recvattach.c
index da82819d..3d72d643 100644
--- a/recvattach.c
+++ b/recvattach.c
@@ -519,17 +519,16 @@ mutt_query_pipe_attachment (char *command, FILE *fp, BODY *body, int filter)
}
}
-static STATE state;
-static void pipe_attachment (FILE *fp, BODY *b)
+static void pipe_attachment (FILE *fp, BODY *b, STATE *state)
{
FILE *ifp;
if (fp)
{
- state.fpin = fp;
- mutt_decode_attachment (b, &state);
+ state->fpin = fp;
+ mutt_decode_attachment (b, state);
if (AttachSep)
- state_puts (AttachSep, &state);
+ state_puts (AttachSep, state);
}
else
{
@@ -538,27 +537,28 @@ static void pipe_attachment (FILE *fp, BODY *b)
mutt_perror ("fopen");
return;
}
- mutt_copy_stream (ifp, state.fpout);
+ mutt_copy_stream (ifp, state->fpout);
fclose (ifp);
if (AttachSep)
- state_puts (AttachSep, &state);
+ state_puts (AttachSep, state);
}
}
static void
-pipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter)
+pipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter,
+ STATE *state)
{
for (; top; top = top->next)
{
if (!tag || top->tagged)
{
if (!filter && !option (OPTATTACHSPLIT))
- pipe_attachment (fp, top);
+ pipe_attachment (fp, top, state);
else
mutt_query_pipe_attachment (command, fp, top, filter);
}
else if (top->parts)
- pipe_attachment_list (command, fp, tag, top->parts, filter);
+ pipe_attachment_list (command, fp, tag, top->parts, filter, state);
if (!tag)
break;
}
@@ -566,6 +566,7 @@ pipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter)
void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter)
{
+ STATE state;
char buf[SHORT_STRING];
pid_t thepid;
@@ -585,13 +586,13 @@ void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter)
{
endwin ();
thepid = mutt_create_filter (buf, &state.fpout, NULL, NULL);
- pipe_attachment_list (buf, fp, tag, top, filter);
+ pipe_attachment_list (buf, fp, tag, top, filter, &state);
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);
+ pipe_attachment_list (buf, fp, tag, top, filter, &state);
}
static int can_print (BODY *top, int tag)
@@ -624,7 +625,7 @@ static int can_print (BODY *top, int tag)
return (1);
}
-static void print_attachment_list (FILE *fp, int tag, BODY *top)
+static void print_attachment_list (FILE *fp, int tag, BODY *top, STATE *state)
{
char type [STRING];
@@ -638,7 +639,7 @@ static void print_attachment_list (FILE *fp, int tag, BODY *top)
{
if (!mutt_strcasecmp ("text/plain", top->subtype) ||
!mutt_strcasecmp ("application/postscript", top->subtype))
- pipe_attachment (fp, top);
+ pipe_attachment (fp, top, state);
else if (mutt_can_decode (top))
{
/* decode and print */
@@ -651,10 +652,10 @@ static void print_attachment_list (FILE *fp, int tag, BODY *top)
{
if ((ifp = fopen (newfile, "r")) != NULL)
{
- mutt_copy_stream (ifp, state.fpout);
+ mutt_copy_stream (ifp, state->fpout);
fclose (ifp);
if (AttachSep)
- state_puts (AttachSep, &state);
+ state_puts (AttachSep, state);
}
}
mutt_unlink (newfile);
@@ -664,7 +665,7 @@ static void print_attachment_list (FILE *fp, int tag, BODY *top)
mutt_print_attachment (fp, top);
}
else if (top->parts)
- print_attachment_list (fp, tag, top->parts);
+ print_attachment_list (fp, tag, top->parts, state);
if (!tag)
return;
}
@@ -672,6 +673,8 @@ static void print_attachment_list (FILE *fp, int tag, BODY *top)
void mutt_print_attachment_list (FILE *fp, int tag, BODY *top)
{
+ STATE state;
+
pid_t thepid;
if (query_quadoption (OPT_PRINT, tag ? _("Print tagged attachment(s)?") : _("Print attachment?")) != M_YES)
return;
@@ -683,255 +686,18 @@ void mutt_print_attachment_list (FILE *fp, int tag, BODY *top)
endwin ();
memset (&state, 0, sizeof (STATE));
thepid = mutt_create_filter (NONULL (PrintCmd), &state.fpout, NULL, NULL);
- print_attachment_list (fp, tag, top);
+ print_attachment_list (fp, tag, top, &state);
fclose (state.fpout);
if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY))
mutt_any_key_to_continue (NULL);
}
else
- print_attachment_list (fp, tag, top);
-}
-
-static void
-bounce_attachment_list (ADDRESS *adr, int tag, BODY *body, HEADER *hdr)
-{
- for (; body; body = body->next)
- {
- if (!tag || body->tagged)
- {
- if (!mutt_is_message_type (body->type, body->subtype))
- {
- mutt_error _("You may only bounce message/rfc822 parts.");
- continue;
- }
- body->hdr->msgno = hdr->msgno;
- mutt_bounce_message (body->hdr, adr);
- }
- else if (body->parts)
- bounce_attachment_list (adr, tag, body->parts, hdr);
- if (!tag)
- break;
- }
-}
-
-static void query_bounce_attachment (int tag, BODY *top, HEADER *hdr)
-{
- char prompt[SHORT_STRING];
- char buf[HUGE_STRING];
- ADDRESS *adr = NULL;
- int rc;
-
- buf[0] = 0;
-
- if(!tag)
- strfcpy(prompt, _("Bounce message to: "), sizeof(prompt));
- else
- strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
-
- rc = mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS);
-
- if (rc || !buf[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), tag ? _("Bounce messages to %s...?")
- : _("Bounce message to %s...?"), buf);
- if (mutt_yesorno (prompt, 1) != 1)
- {
- rfc822_free_address (&adr);
- CLEARLINE (LINES-1);
- return;
- }
- bounce_attachment_list (adr, tag, top, hdr);
- rfc822_free_address (&adr);
-}
-
-static void
-copy_tagged_attachments (FILE *fpout, FILE *fpin, const char *boundary, BODY *bdy)
-{
- for (; bdy; bdy = bdy->next)
- {
- if (bdy->tagged)
- {
- fprintf (fpout, "\n--%s\n", boundary);
- fseek (fpin, bdy->hdr_offset, 0);
- mutt_copy_bytes (fpin, fpout, bdy->length + bdy->offset - bdy->hdr_offset);
- }
- else if (bdy->parts)
- copy_tagged_attachments (fpout, fpin, boundary, bdy->parts);
- }
-}
-
-static int
-create_tagged_message (const char *tempfile,
- int tag,
- CONTEXT *ctx,
- HEADER *cur,
- BODY *body)
-{
- char *boundary;
- MESSAGE *msg, *src;
- CONTEXT tmpctx;
- int magic;
-
- magic = DefaultMagic;
- DefaultMagic = M_MBOX;
- mx_open_mailbox (tempfile, M_APPEND, &tmpctx);
- msg = mx_open_new_message (&tmpctx, cur, M_ADD_FROM);
- src = mx_open_message (ctx, cur->msgno);
-
- if (tag)
- {
- mutt_copy_header (src->fp, cur, msg->fp, CH_XMIT, NULL);
- boundary = mutt_get_parameter ("boundary", cur->content->parameter);
- copy_tagged_attachments (msg->fp, src->fp, boundary, cur->content->parts);
- fprintf (msg->fp, "--%s--\n", boundary);
- }
- else
- {
- /* single attachment */
- mutt_copy_header (src->fp, cur, msg->fp, CH_XMIT | CH_MIME | CH_NONEWLINE, NULL);
- fputs ("Mime-Version: 1.0\n", msg->fp);
- mutt_write_mime_header (body, msg->fp);
- fputc ('\n', msg->fp);
- fseek (src->fp, body->offset, 0);
- mutt_copy_bytes (src->fp, msg->fp, body->length);
- }
-
- mx_commit_message (msg, &tmpctx);
- mx_close_message (&msg);
- mx_close_message (&src);
- mx_close_mailbox (&tmpctx);
- DefaultMagic = magic;
- return 0;
-}
-
-/* op flag to ci_send_message()
- * tag operate on tagged attachments?
- * hdr current message
- * body current attachment
- */
-
-/*
- * XXX - this code looks way too complicated, and rather ineffective.
- * Analyze and fix this.
- */
-
-/*
- * Idea:
- *
- * 1. Forwarding
- *
- * Variant 1: mime_forward is set (or activated by the user). In this case, generate
- * a new message whose main body contains the forwarded message's header, and
- * attach all tagged attachments.
- *
- * Variant 2: mime_forward is not set (or activated). In this case, generate a new
- * message whose main body contains the forwarded message's header, and formatted
- * versions of all attachments we can handle in-line (i.e., hard-coded handlers + auto_view).
- *
- * When there are any tagged attachments we can't handle this way, ask the user
- * whether he wants to ignore or whether he wants to attach them to the new message.
- * Make this a quad-option.
- *
- * 2. Replying
- *
- * Always fall back to the behaviour from forwarding, variant 2.
- *
- * 3. Special handling for message/rfc822 attachments
- *
- * resend-message and bounce should be possible. forward and reply should have
- * special semantics when they are applied ONLY to message/rfc822 body parts.
- *
- * Note: Some of this behaviour is implemented by the current code. However, DO NOT
- * use it - it's horribly slow even on fast machines. We have sufficient information
- * at hand to create the message structures needed by ci_send_message from scratch, and
- * without any temporary folders.
- *
- *
- * (Thanks to Roland Rosenfeld with whom I discussed this stuff.)
- *
- * tlr, Wed, 3 Nov 1999 21:29:19 +0100
- *
- */
-
-static void reply_attachment_list (int op, int tag, HEADER *hdr, BODY *body)
-{
- HEADER *hn;
- char tempfile[_POSIX_PATH_MAX];
- CONTEXT *ctx;
-
- if (!tag && body->hdr)
- {
- hn = body->hdr;
- hn->msgno = hdr->msgno; /* required for MH/maildir */
- hn->replied = hdr->replied;
- hn->read = hdr->read;
- hn->old = hdr->old;
- hn->changed = hdr->changed;
- ctx = Context;
- }
- else
- {
- /* build a fake message which consists of only the tagged attachments */
- mutt_mktemp (tempfile);
- create_tagged_message (tempfile, tag, Context, hdr, body);
- ctx = mx_open_mailbox (tempfile, M_QUIET, NULL);
- hn = ctx->hdrs[0];
- }
-
- if (op == SENDFORWARD && option (OPTFORWATTACH))
- {
- HEADER *newhdr = mutt_new_header();
- char buffer [LONG_STRING];
-
- mutt_message ("Preparing to forward...");
- if (mutt_prepare_template (ctx, newhdr, hn, 0) < 0)
- {
- mutt_clear_error();
- mutt_free_header (&newhdr);
- goto cleanup;
- }
-
- mutt_free_envelope (&newhdr->env);
- newhdr->env = mutt_new_envelope();
- newhdr->received = 0;
- newhdr->date_sent = 0;
-
- /* set the default subject for the message. */
- buffer[0] = 0;
- mutt_make_string (buffer, sizeof (buffer), NONULL(ForwFmt), ctx, hn);
- newhdr->env->subject = safe_strdup (buffer);
-
- mutt_clear_error();
- ci_send_message (0, newhdr, NULL, ctx, NULL);
- }
- else
- ci_send_message (op, NULL, NULL, ctx, hn);
-
- if (hn->replied)
- {
- if (Context != ctx)
- mutt_set_flag (Context, hdr, M_REPLIED, 1);
- else
- _mutt_set_flag (Context, hdr, M_REPLIED, 1, 0);
- }
-
-cleanup:
-
- if (ctx != Context)
- {
- mx_fastclose_mailbox (ctx);
- safe_free ((void **) &ctx);
- unlink (tempfile);
- }
+ print_attachment_list (fp, tag, top, &state);
}
void
-mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, ATTACHPTR **idx)
+mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
+ ATTACHPTR **idx, short idxlen)
{
#if 0
int old_optweed = option (OPTWEED);
@@ -947,7 +713,8 @@ mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, ATTACHPTR **idx)
/* fall through */
case OP_VIEW_ATTACH:
- op = mutt_view_attachment (fp, idx[menu->current]->content, M_REGULAR);
+ op = mutt_view_attachment (fp, idx[menu->current]->content, M_REGULAR,
+ hdr, idx, idxlen);
break;
case OP_NEXT_ENTRY:
@@ -1062,17 +829,19 @@ void mutt_view_attachments (HEADER *hdr)
{
case OP_DISPLAY_HEADERS:
case OP_VIEW_ATTACH:
- mutt_attach_display_loop (menu, op, fp, idx);
+ mutt_attach_display_loop (menu, op, fp, hdr, idx, idxlen);
menu->redraw = REDRAW_FULL;
break;
case OP_ATTACH_VIEW_MAILCAP:
- mutt_view_attachment (fp, idx[menu->current]->content, M_MAILCAP);
+ mutt_view_attachment (fp, idx[menu->current]->content, M_MAILCAP,
+ hdr, idx, idxlen);
menu->redraw = REDRAW_FULL;
break;
case OP_ATTACH_VIEW_TEXT:
- mutt_view_attachment (fp, idx[menu->current]->content, M_AS_TEXT);
+ mutt_view_attachment (fp, idx[menu->current]->content, M_AS_TEXT,
+ hdr, idx, idxlen);
menu->redraw = REDRAW_FULL;
break;
@@ -1080,7 +849,8 @@ void mutt_view_attachments (HEADER *hdr)
#ifdef _PGPPATH
case OP_EXTRACT_KEYS:
- pgp_extract_keys_from_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content);
+ pgp_extract_keys_from_attachment_list (fp, menu->tagprefix,
+ menu->tagprefix ? cur : idx[menu->current]->content);
menu->redraw = REDRAW_FULL;
break;
#endif
@@ -1088,16 +858,20 @@ void mutt_view_attachments (HEADER *hdr)
case OP_PRINT:
- mutt_print_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content);
+ mutt_print_attachment_list (fp, menu->tagprefix,
+ menu->tagprefix ? cur : idx[menu->current]->content);
break;
case OP_PIPE:
- mutt_pipe_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content, 0);
+ mutt_pipe_attachment_list (fp, menu->tagprefix,
+ menu->tagprefix ? cur : idx[menu->current]->content, 0);
break;
case OP_SAVE:
- mutt_save_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content, hdr);
- if (option (OPTRESOLVE) && menu->current < menu->max - 1)
+ mutt_save_attachment_list (fp, menu->tagprefix,
+ menu->tagprefix ? cur : idx[menu->current]->content, hdr);
+
+ if (option (OPTRESOLVE) && menu->current < menu->max - 1)
menu->current++;
menu->redraw = REDRAW_MOTION_RESYNCH | REDRAW_FULL;
@@ -1184,39 +958,38 @@ void mutt_view_attachments (HEADER *hdr)
}
break;
+ case OP_RESEND:
+ CHECK_ATTACH;
+ mutt_attach_resend (fp, hdr, idx, idxlen,
+ menu->tagprefix ? NULL : idx[menu->current]->content);
+ menu->redraw = REDRAW_FULL;
+ break;
+
case OP_BOUNCE_MESSAGE:
CHECK_ATTACH;
- query_bounce_attachment (menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content, hdr);
- break;
+ mutt_attach_bounce (fp, hdr, idx, idxlen,
+ menu->tagprefix ? NULL : idx[menu->current]->content);
+ menu->redraw = REDRAW_FULL;
+ break;
+ case OP_FORWARD_MESSAGE:
+ CHECK_ATTACH;
+ mutt_attach_forward (fp, hdr, idx, idxlen,
+ menu->tagprefix ? NULL : idx[menu->current]->content);
+ menu->redraw = REDRAW_FULL;
+ break;
+
case OP_REPLY:
case OP_GROUP_REPLY:
case OP_LIST_REPLY:
- case OP_FORWARD_MESSAGE:
CHECK_ATTACH;
-
-#ifdef _PGPPATH
- if ((hdr->pgp & PGPENCRYPT) && hdr->content->type == TYPEMULTIPART)
- {
- mutt_error _(
- "This operation is not currently supported for PGP messages.");
- break;
- }
-#endif
-
-
-
- if (op == OP_FORWARD_MESSAGE)
- flags = SENDFORWARD;
- else
- flags = SENDREPLY |
- (op == OP_GROUP_REPLY ? SENDGROUPREPLY : 0) |
- (op == OP_LIST_REPLY ? SENDLISTREPLY : 0);
- reply_attachment_list (flags,
- menu->tagprefix,
- hdr,
- menu->tagprefix ? cur : idx[menu->current]->content);
+
+ flags = SENDREPLY |
+ (op == OP_GROUP_REPLY ? SENDGROUPREPLY : 0) |
+ (op == OP_LIST_REPLY ? SENDLISTREPLY : 0);
+ mutt_attach_reply (fp, hdr, idx, idxlen,
+ menu->tagprefix ? NULL : idx[menu->current]->content, flags);
menu->redraw = REDRAW_FULL;
break;