static void post_entry (char *s, size_t slen, MUTTMENU *menu, int entry) { CONTEXT *ctx = (CONTEXT *) menu->data; _mutt_make_string (s, slen, NONULL (HdrFmt), ctx, ctx->hdrs[entry], M_FORMAT_ARROWCURSOR); }
static void include_header (int quote, FILE * ifp, struct header * hdr, FILE * ofp, char *_prefix) { int chflags = CH_DECODE; char prefix[SHORT_STRING]; if (bit_val(options, OPTWEED)) chflags |= CH_WEED | CH_REORDER; if (quote) { if (_prefix) strfcpy (prefix, _prefix, sizeof (prefix)); else if (!bit_val(options, OPTTEXTFLOWED)) _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr, 0); else strfcpy (prefix, ">", sizeof (prefix)); chflags |= CH_PREFIX; } mutt_copy_header (ifp, hdr, ofp, chflags, quote ? prefix : NULL); }
int _mutt_copy_message (FILE *fpout, FILE *fpin, HEADER *hdr, BODY *body, int flags, int chflags) { char prefix[SHORT_STRING]; STATE s; LOFF_T new_offset = -1; int rc = 0; if (flags & M_CM_PREFIX) { if (option (OPTTEXTFLOWED)) strfcpy (prefix, ">", sizeof (prefix)); else _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr, 0); } if ((flags & M_CM_NOHEADER) == 0) { if (flags & M_CM_PREFIX) chflags |= CH_PREFIX; else if (hdr->attach_del && (chflags & CH_UPDATE_LEN)) { int new_lines; LOFF_T new_length = body->length; char date[SHORT_STRING]; mutt_make_date (date, sizeof (date)); date[5] = date[mutt_strlen (date) - 1] = '\"'; /* Count the number of lines and bytes to be deleted */ fseeko (fpin, body->offset, SEEK_SET); new_lines = hdr->lines - count_delete_lines (fpin, body, &new_length, mutt_strlen (date)); /* Copy the headers */ if (mutt_copy_header (fpin, hdr, fpout, chflags | CH_NOLEN | CH_NONEWLINE, NULL)) return -1; fprintf (fpout, "Content-Length: " OFF_T_FMT "\n", new_length); if (new_lines <= 0) new_lines = 0; else fprintf (fpout, "Lines: %d\n", new_lines); putc ('\n', fpout); if (ferror (fpout) || feof (fpout)) return -1; new_offset = ftello (fpout); /* Copy the body */ fseeko (fpin, body->offset, SEEK_SET); if (copy_delete_attach (body, fpin, fpout, date)) return -1; #ifdef DEBUG { LOFF_T fail = ((ftello (fpout) - new_offset) - new_length); if (fail) { mutt_error ("The length calculation was wrong by %ld bytes", fail); new_length += fail; mutt_sleep (1); } } #endif /* Update original message if we are sync'ing a mailfolder */ if (flags & M_CM_UPDATE) { hdr->attach_del = 0; hdr->lines = new_lines; body->offset = new_offset; /* update the total size of the mailbox to reflect this deletion */ Context->size -= body->length - new_length; /* * if the message is visible, update the visible size of the mailbox * as well. */ if (Context->v2r[hdr->msgno] != -1) Context->vsize -= body->length - new_length; body->length = new_length; mutt_free_body (&body->parts); } return 0; } if (mutt_copy_header (fpin, hdr, fpout, chflags, (chflags & CH_PREFIX) ? prefix : NULL) == -1) return -1; new_offset = ftello (fpout); } if (flags & M_CM_DECODE) { /* now make a text/plain version of the message */ memset (&s, 0, sizeof (STATE)); s.fpin = fpin; s.fpout = fpout; if (flags & M_CM_PREFIX) s.prefix = prefix; if (flags & M_CM_DISPLAY) s.flags |= M_DISPLAY; if (flags & M_CM_PRINTING) s.flags |= M_PRINTING; if (flags & M_CM_WEED) s.flags |= M_WEED; if (flags & M_CM_CHARCONV) s.flags |= M_CHARCONV; if (flags & M_CM_REPLYING) s.flags |= M_REPLYING; if (WithCrypto && flags & M_CM_VERIFY) s.flags |= M_VERIFY; rc = mutt_body_handler (body, &s); } else if (WithCrypto && (flags & M_CM_DECODE_CRYPT) && (hdr->security & ENCRYPT)) { BODY *cur = NULL; FILE *fp; if ((WithCrypto & APPLICATION_PGP) && (flags & M_CM_DECODE_PGP) && (hdr->security & APPLICATION_PGP) && hdr->content->type == TYPEMULTIPART) { if (crypt_pgp_decrypt_mime (fpin, &fp, hdr->content, &cur)) return (-1); fputs ("MIME-Version: 1.0\n", fpout); } if ((WithCrypto & APPLICATION_SMIME) && (flags & M_CM_DECODE_SMIME) && (hdr->security & APPLICATION_SMIME) && hdr->content->type == TYPEAPPLICATION) { if (crypt_smime_decrypt_mime (fpin, &fp, hdr->content, &cur)) return (-1); } if (!cur) { mutt_error (_("No decryption engine available for message")); return -1; } mutt_write_mime_header (cur, fpout); fputc ('\n', fpout); fseeko (fp, cur->offset, 0); if (mutt_copy_bytes (fp, fpout, cur->length) == -1) { safe_fclose (&fp); mutt_free_body (&cur); return (-1); } mutt_free_body (&cur); safe_fclose (&fp); } else { fseeko (fpin, body->offset, 0); if (flags & M_CM_PREFIX) { int c; size_t bytes = body->length; fputs(prefix, fpout); while((c = fgetc(fpin)) != EOF && bytes--) { fputc(c, fpout); if(c == '\n') { fputs(prefix, fpout); } } } else if (mutt_copy_bytes (fpin, fpout, body->length) == -1) return -1; } if ((flags & M_CM_UPDATE) && (flags & M_CM_NOHEADER) == 0 && new_offset != -1) { body->offset = new_offset; mutt_free_body (&body->parts); } return rc; }
void mutt_attach_reply (FILE * fp, struct header *hdr, ATTACHPTR ** idx, short idxlen, struct body * cur, int flags) { short mime_reply_any = 0; short nattach = 0; struct header *parent = NULL; struct 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 ? cur->hdr : NULL), flags) == -1) { mutt_free_header (&tmphdr); return; } mutt_mktemp (tmpbody, sizeof (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; if (!bit_val(options, OPTTEXTFLOWED)) _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, parent, 0); else strfcpy (prefix, ">", sizeof (prefix)); st.prefix = prefix; st.flags = M_CHARCONV; if (bit_val(options, OPTWEED)) st.flags |= M_WEED; if (bit_val(options, 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); safe_fclose (&tmpfp); return; } } safe_fclose (&tmpfp); if (ci_send_message (flags, tmphdr, tmpbody, NULL, parent ? parent : (cur ? cur->hdr : NULL)) == 0) mutt_set_flag (Context, hdr, M_REPLIED, 1); }
static void attach_forward_bodies (FILE * fp, struct header * hdr, ATTACHPTR ** idx, short idxlen, struct body * cur, short nattach) { short i; short mime_fwd_all = 0; short mime_fwd_any = 1; struct header *parent = NULL; struct header *tmphdr = NULL; struct 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, sizeof (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 (bit_val(options, OPTFORWQUOTE)) { if (!bit_val(options, OPTTEXTFLOWED)) _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, parent, 0); else strfcpy (prefix, ">", sizeof (prefix)); } include_header (bit_val(options, 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 as attachments?"))) == 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 (bit_val(options, OPTFORWQUOTE)) st.prefix = prefix; st.flags = M_CHARCONV; if (bit_val(options, 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 && copy_problematic_attachments (fp, last, idx, idxlen, mime_fwd_all) == NULL) goto bail; } mutt_forward_trailer (tmpfp); safe_fclose (&tmpfp); tmpfp = NULL; /* now that we have the template, send it. */ ci_send_message (0, tmphdr, tmpbody, NULL, parent); return; bail: if (tmpfp) { safe_fclose (&tmpfp); mutt_unlink (tmpbody); } mutt_free_header (&tmphdr); }