edit.c enter.c flags.c init.c filter.c from.c getdomain.c \
handler.c hash.c hdrline.c headers.c help.c hook.c keymap.c \
main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \
- postpone.c query.c recvattach.c \
+ postpone.c query.c recvattach.c recvcmd.c \
rfc822.c rfc1524.c rfc2047.c rfc2231.c \
score.c send.c sendlib.c signal.c sort.c \
status.c system.c thread.c charset.c history.c lib.c \
}
/* returns -1 on error, 0 or the return code from mutt_do_pager() on success */
-int mutt_view_attachment (FILE *fp, BODY *a, int flag)
+int mutt_view_attachment (FILE *fp, BODY *a, int flag, HEADER *hdr,
+ ATTACHPTR **idx, short idxlen)
{
char tempfile[_POSIX_PATH_MAX] = "";
char pagerfile[_POSIX_PATH_MAX] = "";
info.fp = fp;
info.bdy = a;
info.ctx = Context;
+ info.idx = idx;
+ info.idxlen = idxlen;
+ info.hdr = hdr;
+
rc = mutt_do_pager (descrip, pagerfile,
is_message ? M_PAGER_MESSAGE : 0, &info);
}
void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr);
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_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, ATTACHPTR **idx);
+void mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
+ ATTACHPTR **idx, short idxlen);
+
+void mutt_attach_bounce (FILE *, HEADER *, ATTACHPTR **, short, BODY *);
+void mutt_attach_resend (FILE *, HEADER *, ATTACHPTR **, short, BODY *);
+void mutt_attach_forward (FILE *, HEADER *, ATTACHPTR **, short, BODY *);
+void mutt_attach_reply (FILE *, HEADER *, ATTACHPTR **, short, BODY *, int);
b = mutt_make_file_attach (buf);
if (b != NULL)
{
- mutt_view_attachment (NULL, b, M_REGULAR);
+ mutt_view_attachment (NULL, b, M_REGULAR, NULL, NULL, 0);
mutt_free_body (&b);
menu->redraw = REDRAW_FULL;
}
return;
}
- mutt_bounce_message (h, adr);
+ mutt_bounce_message (NULL, h, adr);
rfc822_free_address (&adr);
mutt_message (h ? _("Message bounced.") : _("Messages bounced."));
}
case OP_VIEW_ATTACH:
case OP_DISPLAY_HEADERS:
CHECK_COUNT;
- mutt_attach_display_loop (menu, op, NULL, idx);
+ mutt_attach_display_loop (menu, op, NULL, NULL, idx, idxlen);
menu->redraw = REDRAW_FULL;
mutt_clear_error ();
break;
for (j = 0; j < Context->vcount; j++)
{
if (Context->hdrs[Context->v2r[j]]->tagged)
- ci_send_message (SENDRESEND, NULL, NULL, Context,
- Context->hdrs[Context->v2r[j]]);
+ mutt_resend_message (NULL, Context, Context->hdrs[Context->v2r[j]]);
}
}
else
- ci_send_message (SENDRESEND, NULL, NULL, Context, CURHDR);
+ mutt_resend_message (NULL, Context, CURHDR);
menu->redraw = REDRAW_FULL;
break;
{ "pipe-entry", OP_PIPE, "|" },
{ "view-mailcap", OP_ATTACH_VIEW_MAILCAP, "m" },
{ "reply", OP_REPLY, "r" },
+ { "resend-message", OP_RESEND, "\033e" },
{ "group-reply", OP_GROUP_REPLY, "g" },
{ "list-reply", OP_LIST_REPLY, "L" },
{ "forward-message", OP_FORWARD_MESSAGE, "f" },
** .pp
** Also see the ``$$record'' variable.
*/
- { "forward_attachment", DT_BOOL, R_NONE, OPTFORWATTACH, 0 },
- /*
- ** .pp
- ** When set, and you (tag-)forward attachments from the Attachment menu,
- ** Mutt creates a new message with the specified attachments \fIonly\fP.
- ** ``$$forward_format'' is used to set the default subject.
- ** .pp
- ** When unset, Mutt creates a pseudo-message comprising the tagged
- ** attachments and forwards that. See the section on Forwarding a message
- ** for details.
- ** .pp
- ** For example: if you have a message containing a image/gif,
- ** application/octet-stream, or whatever attachment, you can go to the
- ** Attachment menu and forward ONLY that attachment to someone else.
- ** .pp
- ** Basically, setting this variable produces the same effect as
- ** explicitly saving the attachment(s), composing a new message and then
- ** attaching the saved file(s).
- */
- { "forw_attachment", DT_SYN, R_NONE, UL "forward_attachment", 0 },
- /*
- */
{ "forward_decode", DT_BOOL, R_NONE, OPTFORWDECODE, 1 },
/*
** .pp
/*
*/
+ { "mime_forward_rest", DT_QUAD, R_NONE, OPT_MIMEFWDREST, M_YES },
+ /*
+ ** .pp
+ ** When forwarding multiple attachments of a MIME message from the recvattach
+ ** menu, attachments which cannot be decoded in a reasonable manner will
+ ** be attached to the newly composed message if this option is set.
+ */
+
#ifdef MIXMASTER
{ "mix_entry_format", DT_STR, R_NONE, UL &MixEntryFormat, UL "%4n %c %-16s %a" },
/*
OPT_ABORT,
OPT_RECALL,
OPT_SUBJECT,
+ OPT_MIMEFWDREST,
OPT_MAX
};
OPTFCCATTACH,
OPTFOLLOWUPTO,
OPTFORCENAME,
- OPTFORWATTACH,
OPTFORWDECODE,
OPTFORWQUOTE,
OPTHDRS,
return bn;
}
+/* Modified by blong to accept a "suggestion" for file name. If
+ * that file exists, then construct one with unique name but
+ * keep any extension. This might fail, I guess.
+ * Renamed to mutt_adv_mktemp so I only have to change where it's
+ * called, and not all possible cases.
+ */
+void mutt_adv_mktemp (char *s, size_t l)
+{
+ char buf[_POSIX_PATH_MAX];
+ char tmp[_POSIX_PATH_MAX];
+ char *period;
+ size_t sl;
+ struct stat sb;
+
+ strfcpy (buf, NONULL (Tempdir), sizeof (buf));
+ mutt_expand_path (buf, sizeof (buf));
+ if (s[0] == '\0')
+ {
+ snprintf (s, l, "%s/muttXXXXXX", buf);
+ mktemp (s);
+ }
+ else
+ {
+ strfcpy (tmp, s, sizeof (tmp));
+ snprintf (s, l, "%s/%s", buf, tmp);
+ if (lstat (s, &sb) == -1 && errno == ENOENT)
+ return;
+ if ((period = strrchr (tmp, '.')) != NULL)
+ *period = 0;
+ snprintf (s, l, "%s/%s.XXXXXX", buf, tmp);
+ mktemp (s);
+ if (period != NULL)
+ {
+ *period = '.';
+ sl = mutt_strlen(s);
+ strfcpy(s + sl, period, l - sl);
+ }
+ }
+}
+
+/* create a send-mode duplicate from a receive-mode body */
+
+int mutt_copy_body (FILE *fp, BODY **tgt, BODY *src)
+{
+ char tmp[_POSIX_PATH_MAX];
+ BODY *b;
+
+ PARAMETER *par, **ppar;
+
+ short use_disp;
+
+ if (src->filename)
+ {
+ use_disp = 1;
+ strfcpy (tmp, src->filename, sizeof (tmp));
+ }
+ else
+ {
+ use_disp = 0;
+ tmp[0] = '\0';
+ }
+
+ mutt_adv_mktemp (tmp, sizeof (tmp));
+ if (mutt_save_attachment (fp, src, tmp, 0, NULL) == -1)
+ return -1;
+
+ *tgt = mutt_new_body ();
+ b = *tgt;
+
+ memcpy (b, src, sizeof (BODY));
+ b->parts = NULL;
+ b->next = NULL;
+
+ b->filename = safe_strdup (tmp);
+ b->use_disp = use_disp;
+ b->unlink = 1;
+
+ if (mutt_is_text_type (b->type, b->subtype))
+ b->noconv = 1;
+
+ /* the following code is borrowed from mutt_prepare_template ().
+ * Does someone have a nice function name for it, so we can re-unite
+ * it?
+ */
+
+ b->xtype = safe_strdup (b->xtype);
+ b->subtype = safe_strdup (b->subtype);
+ b->form_name = safe_strdup (b->form_name);
+ b->filename = safe_strdup (b->filename);
+ b->d_filename = safe_strdup (b->d_filename);
+
+ /* copy parameters */
+ for (par = b->parameter, ppar = &b->parameter; par; ppar = &(*ppar)->next, par = par->next)
+ {
+ *ppar = mutt_new_parameter ();
+ (*ppar)->attribute = safe_strdup (par->attribute);
+ (*ppar)->value = safe_strdup (par->value);
+ }
+
+ mutt_stamp_attachment (b);
+
+ return 0;
+
+}
+
+
+
void mutt_free_body (BODY **p)
{
BODY *a = *p, *b;
#define ISHEADER(x) ((x) == MT_COLOR_HEADER || (x) == MT_COLOR_HDEFAULT)
#define IsAttach(x) (x && (x)->bdy)
-#define IsHeader(x) (x && (x)->hdr)
+#define IsRecvAttach(x) (x && (x)->bdy && (x)->fp)
+#define IsSendAttach(x) (x && (x)->bdy && !(x)->fp)
+#define IsMsgAttach(x) (x && (x)->fp && (x)->bdy && (x)->bdy->hdr)
+#define IsHeader(x) (x && (x)->hdr && !(x)->bdy)
static const char *Not_available_in_this_menu = N_("Not available in this menu.");
static const char *Mailbox_is_read_only = N_("Mailbox is read-only.");
COLS-9 < sizeof (buffer) ? COLS-9 : sizeof (buffer),
NONULL (PagerFmt), Context, extra->hdr, M_FORMAT_MAKEPRINT);
}
- printw ("%-*.*s -- (", COLS-10, COLS-10, IsHeader (extra) ? buffer : banner);
+ else if (IsMsgAttach (extra))
+ {
+ _mutt_make_string (buffer,
+ COLS - 9 < sizeof (buffer) ? COLS - 9: sizeof (buffer),
+ NONULL (PagerFmt), Context, extra->bdy->hdr, M_FORMAT_MAKEPRINT);
+ }
+ printw ("%-*.*s -- (", COLS-10, COLS-10,
+ IsHeader (extra) || IsMsgAttach (extra) ? buffer : banner);
if (last_pos < sb.st_size - 1)
printw ("%d%%)", (int) (100 * last_offset / sb.st_size));
else
*/
case OP_BOUNCE_MESSAGE:
- CHECK_MODE(IsHeader (extra));
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra))
CHECK_ATTACH;
- ci_bounce_message (extra->hdr, &redraw);
+ if (IsMsgAttach (extra))
+ mutt_attach_bounce (extra->fp, extra->hdr,
+ extra->idx, extra->idxlen,
+ extra->bdy);
+ else
+ ci_bounce_message (extra->hdr, &redraw);
break;
+ case OP_RESEND:
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra))
+ CHECK_ATTACH;
+ if (IsMsgAttach (extra))
+ mutt_attach_resend (extra->fp, extra->hdr,
+ extra->idx, extra->idxlen,
+ extra->bdy);
+ else
+ mutt_resend_message (NULL, extra->ctx, extra->hdr);
+ break;
+
case OP_CREATE_ALIAS:
- CHECK_MODE(IsHeader (extra));
- mutt_create_alias (extra->hdr->env, NULL);
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
+ if (IsMsgAttach (extra))
+ mutt_create_alias (extra->bdy->hdr->env, NULL);
+ else
+ mutt_create_alias (extra->hdr->env, NULL);
MAYBE_REDRAW (redraw);
break;
break;
case OP_DISPLAY_ADDRESS:
- CHECK_MODE(IsHeader (extra));
- mutt_display_address (extra->hdr->env);
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
+ if (IsMsgAttach (extra))
+ mutt_display_address (extra->bdy->hdr->env);
+ else
+ mutt_display_address (extra->hdr->env);
break;
case OP_ENTER_COMMAND:
break;
case OP_PRINT:
- CHECK_MODE(IsHeader (extra));
- mutt_print_message (extra->hdr);
+ CHECK_MODE(IsHeader (extra) || IsAttach (extra));
+ if (IsAttach (extra))
+ mutt_print_attachment_list (extra->fp, 0, extra->bdy);
+ else
+ mutt_print_message (extra->hdr);
break;
case OP_MAIL:
- CHECK_MODE(IsHeader (extra));
+ CHECK_MODE(IsHeader (extra) && !IsAttach (extra));
CHECK_ATTACH;
ci_send_message (0, NULL, NULL, NULL, NULL);
redraw = REDRAW_FULL;
break;
case OP_REPLY:
- CHECK_MODE(IsHeader (extra));
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
CHECK_ATTACH;
- ci_send_message (SENDREPLY, NULL, NULL, extra->ctx, extra->hdr);
+ if (IsMsgAttach (extra))
+ mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
+ extra->idxlen, extra->bdy,
+ SENDREPLY);
+ else
+ ci_send_message (SENDREPLY, NULL, NULL, extra->ctx, extra->hdr);
redraw = REDRAW_FULL;
break;
break;
case OP_GROUP_REPLY:
- CHECK_MODE(IsHeader (extra));
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
CHECK_ATTACH;
- ci_send_message (SENDREPLY | SENDGROUPREPLY, NULL, NULL, extra->ctx, extra->hdr);
+ if (IsMsgAttach (extra))
+ mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
+ extra->idxlen, extra->bdy, SENDREPLY|SENDGROUPREPLY);
+ else
+ ci_send_message (SENDREPLY | SENDGROUPREPLY, NULL, NULL, extra->ctx, extra->hdr);
redraw = REDRAW_FULL;
break;
case OP_LIST_REPLY:
- CHECK_MODE(IsHeader (extra));
- CHECK_ATTACH;
- ci_send_message (SENDREPLY | SENDLISTREPLY, NULL, NULL, extra->ctx, extra->hdr);
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
+ CHECK_ATTACH;
+ if (IsMsgAttach (extra))
+ mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
+ extra->idxlen, extra->bdy, SENDREPLY|SENDLISTREPLY);
+ else
+ ci_send_message (SENDREPLY | SENDLISTREPLY, NULL, NULL, extra->ctx, extra->hdr);
redraw = REDRAW_FULL;
break;
case OP_FORWARD_MESSAGE:
- CHECK_MODE(IsHeader (extra));
+ CHECK_MODE(IsHeader (extra) && !IsMsgAttach (extra));
CHECK_ATTACH;
- ci_send_message (SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
+ if (IsMsgAttach (extra))
+ mutt_attach_forward (extra->fp, extra->hdr, extra->idx,
+ extra->idxlen, extra->bdy);
+ else
+ ci_send_message (SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
redraw = REDRAW_FULL;
break;
HEADER *hdr; /* current message */
BODY *bdy; /* current attachment */
FILE *fp; /* source stream */
+ ATTACHPTR **idx; /* attachment information */
+ short idxlen;
} pager_t;
int mutt_do_pager (const char *, const char *, int, pager_t *);
return (-1);
}
- if (mutt_prepare_template (PostContext, hdr, h, 0) < 0)
+ if (mutt_prepare_template (NULL, PostContext, hdr, h, 0) < 0)
{
mx_fastclose_mailbox (PostContext);
#ifdef USE_IMAP
}
-int mutt_prepare_template (CONTEXT *ctx, HEADER *newhdr, HEADER *hdr,
+int mutt_prepare_template (FILE *fp, CONTEXT *ctx, HEADER *newhdr, HEADER *hdr,
short weed)
{
PARAMETER *par, **ppar;
- MESSAGE *msg;
+ MESSAGE *msg = NULL;
char file[_POSIX_PATH_MAX];
BODY *b;
LIST *p, **q;
FILE *bfp;
-
- if ((msg = mx_open_message (ctx, hdr->msgno)) == NULL)
+
+ if (!fp && (msg = mx_open_message (ctx, hdr->msgno)) == NULL)
return (-1);
+ if (!fp) fp = msg->fp;
+
/* parse the message header */
- fseek (msg->fp, hdr->offset, 0);
- newhdr->env = mutt_read_rfc822_header (msg->fp, newhdr, 1, weed);
+ fseek (fp, hdr->offset, 0);
+ newhdr->env = mutt_read_rfc822_header (fp, newhdr, 1, weed);
+
+ /* NOTE: We do have easy access to the entire MIME structure of
+ * the message to be recalled here. We could use this to
+ * considerably simplify the code below.
+ */
+
mutt_free_body (&newhdr->content);
/* weed user-agent, x-mailer - we don't want them here */
safe_free ((void **) &newhdr->env->mail_followup_to);
/* make sure we parse the message */
- mutt_parse_part (msg->fp, hdr->content);
+ mutt_parse_part (fp, hdr->content);
#ifdef _PGPPATH
/* decrypt pgp/mime encoded messages */
goto err;
mutt_message _("Invoking PGP...");
- if (pgp_decrypt_mime (msg->fp, &bfp, hdr->content, &b) == -1)
+ if (pgp_decrypt_mime (fp, &bfp, hdr->content, &b) == -1)
{
err:
mx_close_message (&msg);
(*ppar)->value = safe_strdup (par->value);
}
- bfp = msg->fp;
+ bfp = fp;
}
#ifdef _PGPPATH
{
mutt_free_envelope (&newhdr->env);
free_body_list (&newhdr->content);
- if (bfp != msg->fp) fclose (bfp);
- mx_close_message (&msg);
+ if (bfp != fp) fclose (bfp);
+ if (msg) mx_close_message (&msg);
return -1;
}
}
/* that's it. */
- if (bfp != msg->fp) fclose (bfp);
- mx_close_message (&msg);
+ if (bfp != fp) fclose (bfp);
+ if (msg) mx_close_message (&msg);
return 0;
}
BODY *mutt_parse_messageRFC822 (FILE *, BODY *);
BODY *mutt_read_mime_header (FILE *, int);
+LIST *mutt_make_references(ENVELOPE *e);
+
ENVELOPE *mutt_read_rfc822_header (FILE *, HEADER *, short, short);
HEADER *mutt_dup_header (HEADER *);
const char *mutt_fqdn(short);
+void mutt_adv_mktemp (char *, size_t);
void mutt_alias_menu (char *, size_t, ALIAS *);
void mutt_block_signals (void);
void mutt_block_signals_system (void);
void mutt_body_handler (BODY *, STATE *);
-void mutt_bounce_message (HEADER *, ADDRESS *);
+void mutt_bounce_message (FILE *fp, HEADER *, ADDRESS *);
void mutt_buffy (char *);
void mutt_check_rescore (CONTEXT *);
void mutt_clear_error (void);
void mutt_expand_fmt (char *, size_t, const char *, const char *);
void mutt_expand_link (char *, const char *, const char *);
void mutt_fetchPopMail (void);
+void mutt_fix_reply_recipients (ENVELOPE *env);
void mutt_folder_hook (char *);
+void mutt_forward_intro (FILE *fp, HEADER *cur);
+void mutt_forward_trailer (FILE *fp);
void mutt_free_alias (ALIAS **);
void mutt_free_body (BODY **);
void mutt_free_color (int fg, int bg);
void mutt_generate_header (char *, size_t, HEADER *, int);
void mutt_help (int);
void mutt_linearize_tree (CONTEXT *, int);
+void mutt_make_attribution (CONTEXT *ctx, HEADER *cur, FILE *out);
+void mutt_make_forward_subject (ENVELOPE *env, CONTEXT *ctx, HEADER *cur);
void mutt_make_help (char *, size_t, char *, int, int);
+void mutt_make_misc_reply_headers (ENVELOPE *env, CONTEXT *ctx, HEADER *cur, ENVELOPE *curenv);
+void mutt_make_post_indent (CONTEXT *ctx, HEADER *cur, FILE *out);
void mutt_message (const char *, ...);
void mutt_message_to_7bit (BODY *, FILE *);
void mutt_mktemp (char *);
int mutt_var_value_complete (char *, size_t, int);
int mutt_complete (char *, size_t);
int mutt_compose_attachment (BODY *a);
+int mutt_copy_body (FILE *, BODY **, BODY *);
int mutt_decode_save_attachment (FILE *, BODY *, char *, int, int);
int mutt_display_message (HEADER *h);
int mutt_edit_attachment(BODY *);
int mutt_edit_message (CONTEXT *, HEADER *);
+int mutt_fetch_recips (ENVELOPE *out, ENVELOPE *in, int flags);
int mutt_parent_message (CONTEXT *, HEADER *);
-int mutt_prepare_template(CONTEXT *, HEADER *, HEADER *, short);
+int mutt_prepare_template(FILE*, CONTEXT *, HEADER *, HEADER *, short);
+int mutt_resend_message (FILE *, CONTEXT *, HEADER *);
#define mutt_enter_fname(A,B,C,D,E) _mutt_enter_fname(A,B,C,D,E,0,NULL,NULL)
int _mutt_enter_fname (const char *, char *, size_t, int *, int, int, char ***, int *);
#define mutt_enter_string(A,B,C,D,E) _mutt_enter_string(A,B,C,D,E,0,NULL,NULL)
int mutt_thread_set_flag (HEADER *, int, int, int);
int mutt_user_is_recipient (HEADER *);
void mutt_update_num_postponed (void);
-int mutt_view_attachment (FILE*, BODY *, int);
+int mutt_view_attachment (FILE*, BODY *, int, HEADER *, ATTACHPTR **, short);
int mutt_wait_filter (pid_t);
int mutt_which_case (const char *);
int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int, char *);
/* unsorted */
void ci_bounce_message (HEADER *, int *);
-void ci_send_message (int, HEADER *, char *, CONTEXT *, HEADER *);
+int ci_send_message (int, HEADER *, char *, CONTEXT *, HEADER *);
}
}
-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
{
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;
}
void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter)
{
+ STATE state;
char buf[SHORT_STRING];
pid_t thepid;
{
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)
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];
{
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 */
{
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);
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;
}
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;
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);
/* 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:
{
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;
#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
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;
}
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;
--- /dev/null
+/*
+ * 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;
+}
+
+
+\f
+/**
+ **
+ ** 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);
+}
+
+
+\f
+/**
+ **
+ ** 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);
+ }
+}
+
+\f
+/**
+ **
+ ** 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);
+ }
+}
+
+
+\f
+/**
+ **
+ ** 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);
+}
+
return found;
}
-/* Modified by blong to accept a "suggestion" for file name. If
- * that file exists, then construct one with unique name but
- * keep any extension. This might fail, I guess.
- * Renamed to mutt_adv_mktemp so I only have to change where it's
- * called, and not all possible cases.
- */
-void mutt_adv_mktemp (char *s, size_t l)
-{
- char buf[_POSIX_PATH_MAX];
- char tmp[_POSIX_PATH_MAX];
- char *period;
- size_t sl;
- struct stat sb;
-
- strfcpy (buf, NONULL (Tempdir), sizeof (buf));
- mutt_expand_path (buf, sizeof (buf));
- if (s[0] == '\0')
- {
- snprintf (s, l, "%s/muttXXXXXX", buf);
- mktemp (s);
- }
- else
- {
- strfcpy (tmp, s, sizeof (tmp));
- snprintf (s, l, "%s/%s", buf, tmp);
- if (lstat (s, &sb) == -1 && errno == ENOENT)
- return;
- if ((period = strrchr (tmp, '.')) != NULL)
- *period = 0;
- snprintf (s, l, "%s/%s.XXXXXX", buf, tmp);
- mktemp (s);
- if (period != NULL)
- {
- *period = '.';
- sl = mutt_strlen(s);
- strfcpy(s + sl, period, l - sl);
- }
- }
-}
/* This routine will create a _temporary_ filename matching the
* name template given if this needs to be done.
int rfc1524_expand_command (BODY *, char *, char *, char *, int);
int rfc1524_expand_filename (char *, char *, char *, size_t);
int rfc1524_mailcap_lookup (BODY *, char *, rfc1524_entry *, int);
-void mutt_adv_mktemp (char *, size_t);
int mutt_rename_file (char *, char *);
#endif /* _RFC1524_H */
return (l);
}
-static int include_forward (CONTEXT *ctx, HEADER *cur, FILE *out)
+void mutt_forward_intro (FILE *fp, HEADER *cur)
{
char buffer[STRING];
+
+ fputs ("----- Forwarded message from ", fp);
+ buffer[0] = 0;
+ rfc822_write_address (buffer, sizeof (buffer), cur->env->from);
+ fputs (buffer, fp);
+ fputs (" -----\n\n", fp);
+}
+
+void mutt_forward_trailer (FILE *fp)
+{
+ fputs ("\n----- End forwarded message -----\n", fp);
+}
+
+
+static int include_forward (CONTEXT *ctx, HEADER *cur, FILE *out)
+{
int chflags = CH_DECODE, cmflags = 0;
}
#endif /* _PGPPATH */
+ mutt_forward_intro (out, cur);
-
- fputs ("----- Forwarded message from ", out);
- buffer[0] = 0;
- rfc822_write_address (buffer, sizeof (buffer), cur->env->from);
- fputs (buffer, out);
- fputs (" -----\n\n", out);
if (option (OPTFORWDECODE))
{
cmflags |= M_CM_DECODE | M_CM_CHARCONV;
cmflags |= M_CM_PREFIX;
mutt_parse_mime_message (ctx, cur);
mutt_copy_message (out, ctx, cur, cmflags, chflags);
- fputs ("\n----- End forwarded message -----\n", out);
+ mutt_forward_trailer (out);
return 0;
}
-static int include_reply (CONTEXT *ctx, HEADER *cur, FILE *out)
+void mutt_make_attribution (CONTEXT *ctx, HEADER *cur, FILE *out)
+{
+ char buffer[STRING];
+ if (Attribution)
+ {
+ mutt_make_string (buffer, sizeof (buffer), Attribution, ctx, cur);
+ fputs (buffer, out);
+ fputc ('\n', out);
+ }
+}
+
+void mutt_make_post_indent (CONTEXT *ctx, HEADER *cur, FILE *out)
{
char buffer[STRING];
+ if (PostIndentString)
+ {
+ mutt_make_string (buffer, sizeof (buffer), PostIndentString, ctx, cur);
+ fputs (buffer, out);
+ fputc ('\n', out);
+ }
+}
+
+static int include_reply (CONTEXT *ctx, HEADER *cur, FILE *out)
+{
int cmflags = M_CM_PREFIX | M_CM_DECODE | M_CM_CHARCONV;
int chflags = CH_DECODE;
}
#endif /* _PGPPATH */
- if (Attribution)
- {
- mutt_make_string (buffer, sizeof (buffer), Attribution, ctx, cur);
- fputs (buffer, out);
- fputc ('\n', out);
- }
+ mutt_make_attribution (ctx, cur, out);
+
if (!option (OPTHEADER))
cmflags |= M_CM_NOHEADER;
if (option (OPTWEED))
mutt_parse_mime_message (ctx, cur);
mutt_copy_message (out, ctx, cur, cmflags, chflags);
- if (PostIndentString)
- {
- mutt_make_string (buffer, sizeof (buffer), PostIndentString, ctx, cur);
- fputs (buffer, out);
- fputc ('\n', out);
- }
+
+ mutt_make_post_indent (ctx, cur, out);
+
return 0;
}
return (0);
}
-static int fetch_recips (ENVELOPE *out, ENVELOPE *in, int flags)
+int mutt_fetch_recips (ENVELOPE *out, ENVELOPE *in, int flags)
{
ADDRESS *tmp;
if (flags & SENDLISTREPLY)
return 0;
}
-static LIST *make_references(ENVELOPE *e)
+LIST *mutt_make_references(ENVELOPE *e)
{
LIST *t, *l;
return l;
}
+void mutt_fix_reply_recipients (ENVELOPE *env)
+{
+ if (! option (OPTMETOO))
+ {
+ /* the order is important here. do the CC: first so that if the
+ * the user is the only recipient, it ends up on the TO: field
+ */
+ env->cc = remove_user (env->cc, (env->to == NULL));
+ env->to = remove_user (env->to, (env->cc == NULL));
+ }
+
+ /* the CC field can get cluttered, especially with lists */
+ env->to = mutt_remove_duplicates (env->to);
+ env->cc = mutt_remove_duplicates (env->cc);
+ env->cc = mutt_remove_xrefs (env->to, env->cc);
+}
+
+void mutt_make_forward_subject (ENVELOPE *env, CONTEXT *ctx, HEADER *cur)
+{
+ char buffer[STRING];
+
+ /* set the default subject for the message. */
+ mutt_make_string (buffer, sizeof (buffer), NONULL(ForwFmt), ctx, cur);
+ env->subject = safe_strdup (buffer);
+}
+
+void mutt_make_misc_reply_headers (ENVELOPE *env, CONTEXT *ctx,
+ HEADER *cur, ENVELOPE *curenv)
+{
+ LIST *tmp;
+ char buffer[STRING];
+
+ if (curenv->real_subj)
+ {
+ env->subject = safe_malloc (mutt_strlen (curenv->real_subj) + 5);
+ sprintf (env->subject, "Re: %s", curenv->real_subj);
+ }
+ else
+ env->subject = safe_strdup ("Re: your mail");
+
+ /* add the In-Reply-To field */
+ if (InReplyTo)
+ {
+ strfcpy (buffer, "In-Reply-To: ", sizeof (buffer));
+ mutt_make_string (buffer + 13, sizeof (buffer) - 13, InReplyTo, ctx, cur);
+ tmp = env->userhdrs;
+ while (tmp && tmp->next)
+ tmp = tmp->next;
+ if (tmp)
+ {
+ tmp->next = mutt_new_list ();
+ tmp = tmp->next;
+ }
+ else
+ tmp = env->userhdrs = mutt_new_list ();
+ tmp->data = safe_strdup (buffer);
+ }
+}
+
static int
envelope_defaults (ENVELOPE *env, CONTEXT *ctx, HEADER *cur, int flags)
{
ENVELOPE *curenv = NULL;
- LIST *tmp;
- char buffer[STRING];
int i = 0, tag = 0;
if (!cur)
for (i = 0; i < ctx->vcount; i++)
{
h = ctx->hdrs[ctx->v2r[i]];
- if (h->tagged && fetch_recips (env, h->env, flags) == -1)
+ if (h->tagged && mutt_fetch_recips (env, h->env, flags) == -1)
return -1;
}
}
- else if (fetch_recips (env, curenv, flags) == -1)
+ else if (mutt_fetch_recips (env, curenv, flags) == -1)
return -1;
if ((flags & SENDLISTREPLY) && !env->to)
return (-1);
}
- if (! option (OPTMETOO))
- {
- /* the order is important here. do the CC: first so that if the
- * the user is the only recipient, it ends up on the TO: field
- */
- env->cc = remove_user (env->cc, (env->to == NULL));
- env->to = remove_user (env->to, (env->cc == NULL));
- }
-
- /* the CC field can get cluttered, especially with lists */
- env->to = mutt_remove_duplicates (env->to);
- env->cc = mutt_remove_duplicates (env->cc);
- env->cc = mutt_remove_xrefs (env->to, env->cc);
-
- if (curenv->real_subj)
- {
- env->subject = safe_malloc (mutt_strlen (curenv->real_subj) + 5);
- sprintf (env->subject, "Re: %s", curenv->real_subj);
- }
- else
- env->subject = safe_strdup ("Re: your mail");
-
- /* add the In-Reply-To field */
- if (InReplyTo)
- {
- strfcpy (buffer, "In-Reply-To: ", sizeof (buffer));
- mutt_make_string (buffer + 13, sizeof (buffer) - 13, InReplyTo, ctx, cur);
- tmp = env->userhdrs;
- while (tmp && tmp->next)
- tmp = tmp->next;
- if (tmp)
- {
- tmp->next = mutt_new_list ();
- tmp = tmp->next;
- }
- else
- tmp = env->userhdrs = mutt_new_list ();
- tmp->data = safe_strdup (buffer);
- }
-
+ mutt_fix_reply_recipients (env);
+ mutt_make_misc_reply_headers (env, ctx, cur, curenv);
+
if(tag)
{
HEADER *h;
env->references = NULL;
p = &env->references;
-
+
for(i = 0; i < ctx->vcount; i++)
{
while(*p) p = &(*p)->next;
h = ctx->hdrs[ctx->v2r[i]];
if(h->tagged)
- *p = make_references(h->env);
+ *p = mutt_make_references(h->env);
}
}
else
- env->references = make_references(curenv);
+ env->references = mutt_make_references(curenv);
}
else if (flags & SENDFORWARD)
- {
- /* set the default subject for the message. */
- mutt_make_string (buffer, sizeof (buffer), NONULL(ForwFmt), ctx, cur);
- env->subject = safe_strdup (buffer);
- }
+ mutt_make_forward_subject (env, ctx, cur);
return (0);
}
}
}
-void
+int mutt_resend_message (FILE *fp, CONTEXT *ctx, HEADER *cur)
+{
+ HEADER *msg = mutt_new_header ();
+
+ if (mutt_prepare_template (fp, ctx, msg, cur, 1) < 0)
+ return -1;
+
+ return ci_send_message (SENDRESEND, msg, NULL, ctx, cur);
+}
+
+int
ci_send_message (int flags, /* send mode */
HEADER *msg, /* template to use for new message */
char *tempfile, /* file specified by -i or -H */
char *signmic = NULL;
#endif
+ int rv = -1;
+
if (!flags && !msg && quadoption (OPT_RECALL) != M_NO &&
mutt_num_postponed (1))
{
* are any postponed messages first.
*/
if ((i = query_quadoption (OPT_RECALL, _("Recall postponed message?"))) == -1)
- return;
+ return rv;
if(i == M_YES)
flags |= SENDPOSTPONED;
{
msg = mutt_new_header ();
+#if 0
+
+ /* this is no longer used. */
+
if (flags == SENDRESEND)
{
- if (mutt_prepare_template (ctx, msg, cur, 1) < 0)
+ if (mutt_prepare_template (fp, ctx, msg, cur, 1) < 0)
goto cleanup;
}
- else if (flags == SENDPOSTPONED)
+ else
+
+#endif
+
+ if (flags == SENDPOSTPONED)
{
if ((flags = mutt_get_postponed (ctx, msg, &cur, fcc, sizeof (fcc))) < 0)
goto cleanup;
}
else if (! (flags & (SENDPOSTPONED|SENDRESEND)))
{
- if ((flags & (SENDREPLY | SENDFORWARD)) &&
+ if ((flags & (SENDREPLY | SENDFORWARD)) && ctx &&
envelope_defaults (msg->env, ctx, cur, flags) == -1)
goto cleanup;
- /* include replies/forwarded messages */
- if (generate_body (tempfp, msg, flags, ctx, cur) == -1)
+ /* include replies/forwarded messages, unless we are given a template */
+ if (!tempfile && (ctx || !(flags & (SENDREPLY|SENDFORWARD)))
+ && generate_body (tempfp, msg, flags, ctx, cur) == -1)
goto cleanup;
if (! (flags & (SENDMAILX | SENDKEY)) && Editor && mutt_strcmp (Editor, "builtin") != 0)
#ifdef _PGPPATH
- if (! (flags & SENDKEY))
+ if (! (flags & SENDKEY) && tempfp)
{
#endif
if (flags & SENDREPLY)
{
- if (cur)
+ if (cur && ctx)
mutt_set_flag (ctx, cur, M_REPLIED, 1);
else if (!(flags & SENDPOSTPONED) && ctx && ctx->tagged)
{
}
}
+
+ rv = 0;
+
cleanup:
if (tempfp)
fclose (tempfp);
mutt_free_header (&msg);
+
+ return rv;
}
if (!env->message_id)
env->message_id = mutt_gen_msgid ();
}
-
-static void _mutt_bounce_message (HEADER *h, ADDRESS *to, const char *resent_from)
+
+static void _mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to, const char *resent_from)
{
int i;
FILE *f;
char date[SHORT_STRING], tempfile[_POSIX_PATH_MAX];
- MESSAGE *msg;
+ MESSAGE *msg = NULL;
if (!h)
{
for (i=0; i<Context->msgcount; i++)
if (Context->hdrs[i]->tagged)
- _mutt_bounce_message (Context->hdrs[i], to, resent_from);
+ _mutt_bounce_message (fp, Context->hdrs[i], to, resent_from);
return;
}
- if ((msg = mx_open_message (Context, h->msgno)) != NULL)
+ if (!fp && (msg = mx_open_message (Context, h->msgno)) == NULL)
+ return;
+
+ if (!fp) fp = msg->fp;
+
+ mutt_mktemp (tempfile);
+ if ((f = safe_fopen (tempfile, "w")) != NULL)
{
- mutt_mktemp (tempfile);
- if ((f = safe_fopen (tempfile, "w")) != NULL)
- {
- int ch_flags = CH_XMIT | CH_NONEWLINE;
-
- if (!option (OPTBOUNCEDELIVERED))
- ch_flags |= CH_WEED_DELIVERED;
-
- fseek (msg->fp, h->offset, 0);
- mutt_copy_header (msg->fp, h, f, ch_flags, NULL);
- fprintf (f, "Resent-From: %s", resent_from);
- fprintf (f, "\nResent-%s", mutt_make_date (date, sizeof(date)));
- fputs ("Resent-To: ", f);
- mutt_write_address_list (to, f, 11);
- fputc ('\n', f);
- mutt_copy_bytes (msg->fp, f, h->content->length);
- fclose (f);
+ int ch_flags = CH_XMIT | CH_NONEWLINE;
+
+ if (!option (OPTBOUNCEDELIVERED))
+ ch_flags |= CH_WEED_DELIVERED;
+
+ fseek (fp, h->offset, 0);
+ mutt_copy_header (fp, h, f, ch_flags, NULL);
+ fprintf (f, "Resent-From: %s", resent_from);
+ fprintf (f, "\nResent-%s", mutt_make_date (date, sizeof(date)));
+ fputs ("Resent-To: ", f);
+ mutt_write_address_list (to, f, 11);
+ fputc ('\n', f);
+ mutt_copy_bytes (fp, f, h->content->length);
+ fclose (f);
- mutt_invoke_sendmail (to, NULL, NULL, tempfile, h->content->encoding == ENC8BIT);
- }
- mx_close_message (&msg);
+ mutt_invoke_sendmail (to, NULL, NULL, tempfile, h->content->encoding == ENC8BIT);
}
+
+ if (msg)
+ mx_close_message (&msg);
}
-void mutt_bounce_message (HEADER *h, ADDRESS *to)
+void mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to)
{
ADDRESS *from;
const char *fqdn = mutt_fqdn (1);
rfc822_write_address (resent_from, sizeof (resent_from), from);
rfc822_free_address (&from);
- _mutt_bounce_message (h, to, resent_from);
+ _mutt_bounce_message (fp, h, to, resent_from);
}