int _mutt_append_message (CONTEXT *dest, FILE *fpin, CONTEXT *src, HEADER *hdr, BODY *body, int flags, int chflags) { char buf[STRING]; MESSAGE *msg; int r; fseeko (fpin, hdr->offset, 0); if (fgets (buf, sizeof (buf), fpin) == NULL) return -1; if ((msg = mx_open_new_message (dest, hdr, is_from (buf, NULL, 0, NULL) ? 0 : M_ADD_FROM)) == NULL) return -1; if (dest->magic == M_MBOX || dest->magic == M_MMDF) chflags |= CH_FROM | CH_FORCE_FROM; chflags |= (dest->magic == M_MAILDIR ? CH_NOSTATUS : CH_UPDATE); r = _mutt_copy_message (msg->fp, fpin, hdr, body, flags, chflags); if (mx_commit_message (msg, dest) != 0) r = -1; #ifdef USE_NOTMUCH if (hdr && msg->commited_path && dest->magic == M_MAILDIR && src->magic == M_NOTMUCH) nm_update_filename(src, NULL, msg->commited_path, hdr); #endif mx_close_message (&msg); return r; }
/* should be made to return -1 on fatal errors, and 1 on non-fatal errors * like partial decode, where it is worth displaying as much as possible */ int mutt_copy_message (FILE *fpout, CONTEXT *src, HEADER *hdr, int flags, int chflags) { MESSAGE *msg; int r; if ((msg = mx_open_message (src, hdr->msgno)) == NULL) return -1; if ((r = _mutt_copy_message (fpout, msg->fp, hdr, hdr->content, flags, chflags)) == 0 && (ferror (fpout) || feof (fpout))) { dprint (1, (debugfile, "_mutt_copy_message failed to detect EOF!\n")); r = -1; } mx_close_message (&msg); return r; }
static void attach_include_reply (FILE *fp, FILE *tmpfp, struct header *cur, int flags) { int cmflags = M_CM_PREFIX | M_CM_DECODE | M_CM_CHARCONV; int chflags = CH_DECODE; /* mutt_message_hook (cur, M_MESSAGEHOOK); */ mutt_make_attribution (Context, cur, tmpfp); if (!bit_val(options, OPTHEADER)) cmflags |= M_CM_NOHEADER; if (bit_val(options, 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); }
/* returns 0 on success, -1 on error */ int mutt_save_attachment (FILE *fp, BODY *m, char *path, int flags, HEADER *hdr) { if (fp) { /* recv mode */ if(hdr && m->hdr && m->encoding != ENCBASE64 && m->encoding != ENCQUOTEDPRINTABLE && mutt_is_message_type(m->type, m->subtype)) { /* message type attachments are written to mail folders. */ char buf[HUGE_STRING]; HEADER *hn; CONTEXT ctx; MESSAGE *msg; int chflags = 0; int r = -1; hn = m->hdr; hn->msgno = hdr->msgno; /* required for MH/maildir */ hn->read = 1; fseeko (fp, m->offset, 0); if (fgets (buf, sizeof (buf), fp) == NULL) return -1; if (mx_open_mailbox(path, M_APPEND | M_QUIET, &ctx) == NULL) return -1; if ((msg = mx_open_new_message (&ctx, hn, is_from (buf, NULL, 0, NULL) ? 0 : M_ADD_FROM)) == NULL) { mx_close_mailbox(&ctx, NULL); return -1; } if (ctx.magic == M_MBOX || ctx.magic == M_MMDF) chflags = CH_FROM | CH_UPDATE_LEN; chflags |= (ctx.magic == M_MAILDIR ? CH_NOSTATUS : CH_UPDATE); if (_mutt_copy_message (msg->fp, fp, hn, hn->content, 0, chflags) == 0 && mx_commit_message (msg, &ctx) == 0) r = 0; else r = -1; mx_close_message (&msg); mx_close_mailbox (&ctx, NULL); return r; } else { /* In recv mode, extract from folder and decode */ STATE s; memset (&s, 0, sizeof (s)); s.flags |= M_CHARCONV; if ((s.fpout = mutt_save_attachment_open (path, flags)) == NULL) { mutt_perror ("fopen"); mutt_sleep (2); return (-1); } fseeko ((s.fpin = fp), m->offset, 0); mutt_decode_attachment (m, &s); if (fclose (s.fpout) != 0) { mutt_perror ("fclose"); mutt_sleep (2); return (-1); } } } else { /* In send mode, just copy file */ FILE *ofp, *nfp; if ((ofp = fopen (m->filename, "r")) == NULL) { mutt_perror ("fopen"); return (-1); } if ((nfp = mutt_save_attachment_open (path, flags)) == NULL) { mutt_perror ("fopen"); safe_fclose (&ofp); return (-1); } if (mutt_copy_stream (ofp, nfp) == -1) { mutt_error _("Write fault!"); safe_fclose (&ofp); safe_fclose (&nfp); return (-1); } safe_fclose (&ofp); safe_fclose (&nfp); } return 0; }
static void attach_forward_msgs (FILE * fp, struct header *hdr, ATTACHPTR ** idx, short idxlen, struct body * cur) { struct header *curhdr = NULL; struct header *tmphdr; short i; int rc; struct 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, sizeof (tmpbody)); if (!(tmpfp = safe_fopen (tmpbody, "w"))) { mutt_error (("Can't create %s."), tmpbody); mutt_free_header (&tmphdr); return; } if (bit_val(options, OPTFORWQUOTE)) { chflags |= CH_PREFIX; cmflags |= M_CM_PREFIX; } if (bit_val(options, OPTFORWDECODE)) { cmflags |= M_CM_DECODE | M_CM_CHARCONV; if (bit_val(options, OPTWEED)) { chflags |= CH_WEED | CH_REORDER; cmflags |= M_CM_WEED; } } if (cur) { /* mutt_message_hook (cur->hdr, M_MESSAGEHOOK); */ 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_message_hook (idx[i]->content->hdr, M_MESSAGEHOOK); */ 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); } } } safe_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); }