X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/5864389bd6a997e8d804b7d92d1ef94101c5cfbc..8023f7eb111623d44bfa5c0b13961f8e901d252c:/uip/mhfixmsg.c diff --git a/uip/mhfixmsg.c b/uip/mhfixmsg.c index 150600a8..2d2fde13 100644 --- a/uip/mhfixmsg.c +++ b/uip/mhfixmsg.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #ifdef HAVE_ICONV # include @@ -307,8 +305,7 @@ main (int argc, char **argv) { adios (NULL, "out of memory"); ctp = cts; - if ((ct = parse_mime (file))) - *ctp++ = ct; + if ((ct = parse_mime (file))) *ctp++ = ct; } else { /* * message(s) are coming from a folder @@ -347,24 +344,14 @@ main (int argc, char **argv) { char *msgnam; msgnam = m_name (msgnum); - if ((ct = parse_mime (msgnam))) - *ctp++ = ct; + if ((ct = parse_mime (msgnam))) *ctp++ = ct; } } - /* - * This is a hack. If we are using an external rmmproc, - * then save the current folder to the context file, - * so the external rmmproc will remove files from the correct - * directory. This should be moved to folder_delmsgs(). - */ - if (rmmproc) { - context_replace (pfolder, folder);/* update current folder */ - seq_setcur (mp, mp->hghsel); /* update current message */ - seq_save (mp); /* synchronize sequences */ - context_save (); /* save the context file */ - fflush (stdout); - } + seq_setcur (mp, mp->hghsel); /* update current message */ + seq_save (mp); /* synchronize sequences */ + context_replace (pfolder, folder);/* update current folder */ + context_save (); /* save the context file */ } if (*cts) { @@ -468,6 +455,7 @@ mhfixmsgsbr (CT *ctp, const fix_transformations *fx, char *outfile) { } if (modify_inplace) { + if (status != OK) unlink (outfile); free (outfile); outfile = NULL; } @@ -528,12 +516,14 @@ fix_boundary (CT *ct, int *message_mods) { char *filename = add ((*ct)->c_file, NULL); free_content (*ct); - *ct = parse_mime (fixed); - (*ct)->c_unlink = 1; - - ++*message_mods; - if (verbosw) { - report (NULL, filename, "fix multipart boundary"); + if ((*ct = parse_mime (fixed))) { + (*ct)->c_unlink = 1; + + ++*message_mods; + if (verbosw) { + report (NULL, filename, + "fix multipart boundary"); + } } free (filename); } else { @@ -609,15 +599,18 @@ get_multipart_boundary (CT ct, char **part_boundary) { if (cp && cp - buffer >= 2 && *--cp == '-' && *--cp == '-' && (cp > buffer && *--cp == '\n')) { + status = OK; break; } - /* Else the start and end boundaries didn't match, or - the start boundary doesn't begin with "\n--" (or - "--" if at the beginning of buffer). Keep trying. */ } else { + /* The start and end boundaries didn't match, or the + start boundary doesn't begin with "\n--" (or "--" + if at the beginning of buffer). Keep trying. */ status = NOTOK; } } + } else { + status = NOTOK; } if (status == OK) { @@ -933,27 +926,33 @@ ensure_text_plain (CT *ct, CT parent, int *message_mods) { } else { /* Slip new text/plain part into a new multipart/alternative. */ CT tp_part = build_text_plain_part (*ct); - CT mp_alt = build_multipart_alt (*ct, tp_part, CT_MULTIPART, - MULTI_ALTERNATE); - struct multipart *mp = (struct multipart *) mp_alt->c_ctparams; - - if (mp && mp->mp_parts && (mp->mp_parts->mp_part = tp_part)) { - /* Make the new multipart/alternative the parent. */ - *ct = mp_alt; - - ++*message_mods; - if (verbosw) { - report ((*ct)->c_partno, (*ct)->c_file, - "insert text/plain part"); + + if (tp_part) { + CT mp_alt = build_multipart_alt (*ct, tp_part, CT_MULTIPART, + MULTI_ALTERNATE); + if (mp_alt) { + struct multipart *mp = + (struct multipart *) mp_alt->c_ctparams; + + if (mp && mp->mp_parts) { + mp->mp_parts->mp_part = tp_part; + /* Make the new multipart/alternative the parent. */ + *ct = mp_alt; + + ++*message_mods; + if (verbosw) { + report ((*ct)->c_partno, (*ct)->c_file, + "insert text/plain part"); + } + } else { + free_content (tp_part); + free_content (mp_alt); + status = NOTOK; + } + } else { + status = NOTOK; } } else { - free_content (tp_part); - - /* Undo enough of what build_multipart_alt() did so - that free_content() can be called on mp_alt. */ - mp->mp_parts->mp_part = NULL; - mp->mp_parts->mp_next->mp_part = NULL; - free_content (mp_alt); status = NOTOK; } } @@ -1463,7 +1462,9 @@ decode_text_parts (CT ct, int encoding, int *message_mods) { unlink (ct->c_cefile.ce_file); free (ct->c_cefile.ce_file); ct->c_cefile.ce_file = NULL; - } else if (ct_encoding == CE_8BIT && encoding == CE_7BIT) { + status = NOTOK; + } else if (ct->c_encoding == CE_QUOTED && + ct_encoding == CE_8BIT && encoding == CE_7BIT) { if (verbosw) { report (ct->c_partno, ct->c_file, "will not decode%s because it is 8bit", @@ -1474,10 +1475,15 @@ decode_text_parts (CT ct, int encoding, int *message_mods) { unlink (ct->c_cefile.ce_file); free (ct->c_cefile.ce_file); ct->c_cefile.ce_file = NULL; + status = NOTOK; } else { - int enc = ct_encoding == CE_BINARY - ? CE_BINARY - : charset_encoding (ct); + int enc; + if (ct_encoding == CE_BINARY) + enc = CE_BINARY; + else if (ct_encoding == CE_8BIT && encoding == CE_7BIT) + enc = CE_QUOTED; + else + enc = charset_encoding (ct); if (set_ce (ct, enc) == OK) { ++*message_mods; if (verbosw) { @@ -1784,14 +1790,39 @@ write_content (CT ct, char *input_filename, char *outfile, int modify_inplace, if (remove_file (infile) == OK) { if (rename (outfile, infile)) { - /* The -file argument processing used path() to - expand filename to absolute path. */ - int file = ct->c_file && ct->c_file[0] == '/'; - - admonish (NULL, "unable to rename %s %s to %s", - file ? "file" : "message", outfile, infile); + /* Rename didn't work, possibly because of an + attempt to rename across filesystems. Try + brute force copy. */ + int old = open (outfile, O_RDONLY); + int new = + open (infile, O_WRONLY | O_CREAT, m_gmprot ()); + int i = -1; + + if (old != -1 && new != -1) { + char buffer[BUFSIZ]; + + while ((i = read (old, buffer, sizeof buffer)) > + 0) { + if (write (new, buffer, i) != i) { + i = -1; + break; + } + } + } + if (new != -1) close (new); + if (old != -1) close (old); unlink (outfile); - status = NOTOK; + + if (i < 0) { + /* The -file argument processing used path() to + expand filename to absolute path. */ + int file = ct->c_file && ct->c_file[0] == '/'; + + admonish (NULL, "unable to rename %s %s to %s", + file ? "file" : "message", outfile, + infile); + status = NOTOK; + } } } else { admonish (NULL, "unable to remove input file %s, " @@ -1801,6 +1832,8 @@ write_content (CT ct, char *input_filename, char *outfile, int modify_inplace, } free (infile); + } else { + status = NOTOK; } } else { /* No modifications and didn't need the tmp outfile. */