X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/b9e0388a118e84f002ae0da6c7a31bdbd89a73bb..4bee7e92bbfba118ed9504f2abd89628c2e24933:/uip/mhfixmsg.c diff --git a/uip/mhfixmsg.c b/uip/mhfixmsg.c index 65abd513..5814eaee 100644 --- a/uip/mhfixmsg.c +++ b/uip/mhfixmsg.c @@ -1,5 +1,5 @@ /* - * mhfixmsg.c -- rewrite a message with various tranformations + * mhfixmsg.c -- rewrite a message with various transformations * * This code is Copyright (c) 2002 and 2013, by the authors of nmh. * See the COPYRIGHT file in the root directory of the nmh @@ -91,6 +91,7 @@ typedef struct fix_transformations { int mhfixmsgsbr (CT *, const fix_transformations *, char *); static int fix_boundary (CT *, int *); +static int copy_input_to_output (const char *, const char *); static int get_multipart_boundary (CT, char **); static int replace_boundary (CT, char *, char *); static int fix_types (CT, svector_t, int *); @@ -118,9 +119,9 @@ static int content_encoding (CT, const char **); static int strip_crs (CT, int *); static int convert_charsets (CT, char *, int *); static int fix_always (CT, int *); -static int write_content (CT, char *, char *, int, int); +static int write_content (CT, const char *, char *, int, int); static void set_text_ctparams(CT, char *, int); -static int remove_file (char *); +static int remove_file (const char *); static void report (char *, char *, char *, char *, ...); static void pipeser (int); @@ -176,8 +177,9 @@ main (int argc, char **argv) { done (0); case DECODETEXTSW: - if (! (cp = *argp++) || *cp == '-') + if (! (cp = *argp++) || *cp == '-') { adios (NULL, "missing argument to %s", argp[-2]); + } if (! strcasecmp (cp, "8bit")) { fx.decodetext = CE_8BIT; } else if (! strcasecmp (cp, "7bit")) { @@ -190,8 +192,9 @@ main (int argc, char **argv) { fx.decodetext = 0; continue; case DECODETYPESW: - if (! (cp = *argp++) || *cp == '-') + if (! (cp = *argp++) || *cp == '-') { adios (NULL, "missing argument to %s", argp[-2]); + } fx.decodetypes = cp; continue; case CRLFLINEBREAKSSW: @@ -201,8 +204,9 @@ main (int argc, char **argv) { fx.lf_line_endings = 1; continue; case TEXTCHARSETSW: - if (! (cp = *argp++) || (*cp == '-' && cp[1])) + if (! (cp = *argp++) || (*cp == '-' && cp[1])) { adios (NULL, "missing argument to %s", argp[-2]); + } fx.textcharset = cp; continue; case NTEXTCHARSETSW: @@ -221,8 +225,9 @@ main (int argc, char **argv) { fx.fixcte = 0; continue; case FIXTYPESW: - if (! (cp = *argp++) || (*cp == '-' && cp[1])) + if (! (cp = *argp++) || (*cp == '-' && cp[1])) { adios (NULL, "missing argument to %s", argp[-2]); + } if (! strncasecmp (cp, "multipart/", 10) || ! strncasecmp (cp, "message/", 8)) { adios (NULL, "-fixtype %s not allowed", cp); @@ -245,18 +250,21 @@ main (int argc, char **argv) { fx.replacetextplain = 0; continue; case FILESW: - if (! (cp = *argp++) || (*cp == '-' && cp[1])) + if (! (cp = *argp++) || (*cp == '-' && cp[1])) { adios (NULL, "missing argument to %s", argp[-2]); + } file = *cp == '-' ? add (cp, NULL) : path (cp, TFILE); continue; case OUTFILESW: - if (! (cp = *argp++) || (*cp == '-' && cp[1])) + if (! (cp = *argp++) || (*cp == '-' && cp[1])) { adios (NULL, "missing argument to %s", argp[-2]); + } outfile = *cp == '-' ? add (cp, NULL) : path (cp, TFILE); continue; case RPROCSW: - if (!(rmmproc = *argp++) || *rmmproc == '-') + if (!(rmmproc = *argp++) || *rmmproc == '-') { adios (NULL, "missing argument to %s", argp[-2]); + } continue; case NRPRCSW: rmmproc = NULL; @@ -276,10 +284,11 @@ main (int argc, char **argv) { } } if (*cp == '+' || *cp == '@') { - if (folder) + if (folder) { adios (NULL, "only one folder at a time!"); - else + } else { folder = pluspath (cp); + } } else { if (*cp == '/') { /* Interpret a full path as a filename, not a message. */ @@ -304,11 +313,13 @@ main (int argc, char **argv) { suppress_bogus_mp_content_warning = skip_mp_cte_check = 1; suppress_extraneous_trailing_semicolon_warning = 1; - if (! context_find ("path")) + if (! context_find ("path")) { free (path ("./", TFOLDER)); + } - if (file && msgs.size) + if (file && msgs.size) { adios (NULL, "cannot specify msg and file at same time!"); + } /* * check if message is coming from file @@ -349,6 +360,19 @@ main (int argc, char **argv) { if ((ct = parse_mime (file))) { set_text_ctparams(ct, fx.decodetypes, fx.lf_line_endings); *ctp++ = ct; + } else { + advise (NULL, "unable to parse message from file %s", file); + status = NOTOK; + + /* If there's an outfile, pass the input message unchanged, so the message won't + get dropped from a pipeline. */ + if (outfile) { + /* Something went wrong. Output might be expected, such as if this were run + as a filter. Just copy the input to the output. */ + if (copy_input_to_output (file, outfile) != OK) { + advise (NULL, "unable to copy message to %s, it might be lost\n", outfile); + } + } } } else { /* @@ -356,27 +380,33 @@ main (int argc, char **argv) { */ CT ct; - if (! msgs.size) + if (! msgs.size) { app_msgarg(&msgs, "cur"); - if (! folder) + } + if (! folder) { folder = getfolder (1); + } maildir = m_maildir (folder); - if (chdir (maildir) == NOTOK) + if (chdir (maildir) == NOTOK) { adios (maildir, "unable to change directory to"); + } /* read folder and create message structure */ - if (! (mp = folder_read (folder, 1))) + if (! (mp = folder_read (folder, 1))) { adios (NULL, "unable to read folder %s", folder); + } /* check for empty folder */ - if (mp->nummsg == 0) + if (mp->nummsg == 0) { adios (NULL, "no messages in %s", folder); + } /* parse all the message ranges/sequences and set SELECTED */ for (msgnum = 0; msgnum < msgs.size; msgnum++) - if (! m_convert (mp, msgs.msgs[msgnum])) + if (! m_convert (mp, msgs.msgs[msgnum])) { done (1); + } seq_setprev (mp); /* set the previous-sequence */ if (! (cts = @@ -393,6 +423,21 @@ main (int argc, char **argv) { if ((ct = parse_mime (msgnam))) { set_text_ctparams(ct, fx.decodetypes, fx.lf_line_endings); *ctp++ = ct; + } else { + advise (NULL, "unable to parse message %s", msgnam); + status = NOTOK; + + /* If there's an outfile, pass the input message unchanged, so the message won't + get dropped from a pipeline. */ + if (outfile) { + /* Something went wrong. Output might be expected, such as if this were run + as a filter. Just copy the input to the output. */ + const char *input_filename = path (msgnam, TFILE); + + if (copy_input_to_output (input_filename, outfile) != OK) { + advise (NULL, "unable to copy message to %s, it might be lost\n", outfile); + } + } } } } @@ -425,6 +470,8 @@ main (int argc, char **argv) { if (fx.fixtypes != NULL) { svector_free (fx.fixtypes); } free (outfile); free (file); + free (folder); + free (arguments); /* done is freects_done, which will clean up all of cts. */ done (status); @@ -500,19 +547,9 @@ mhfixmsgsbr (CT *ctp, const fix_transformations *fx, char *outfile) { /* Something went wrong. Output might be expected, such as if this were run as a filter. Just copy the input to the output. */ - int in = open (input_filename, O_RDONLY); - int out = strcmp (outfile, "-") - ? open (outfile, O_WRONLY | O_CREAT, m_gmprot ()) - : STDOUT_FILENO; - - if (in != -1 && out != -1) { - cpydata (in, out, input_filename, outfile); - } else { - status = NOTOK; + if (copy_input_to_output (input_filename, outfile) != OK) { + advise (NULL, "unable to copy message to %s, it might be lost\n", outfile); } - - close (out); - close (in); } if (modify_inplace) { @@ -527,6 +564,29 @@ mhfixmsgsbr (CT *ctp, const fix_transformations *fx, char *outfile) { } +/* Copy input message to output. Assumes not modifying in place, so this + might be running as part of a pipeline. */ +static int +copy_input_to_output (const char *input_filename, const char *output_filename) { + int in = open (input_filename, O_RDONLY); + int out = strcmp (output_filename, "-") + ? open (output_filename, O_WRONLY | O_CREAT, m_gmprot ()) + : STDOUT_FILENO; + int status = OK; + + if (in != -1 && out != -1) { + cpydata (in, out, input_filename, output_filename); + } else { + status = NOTOK; + } + + close (out); + close (in); + + return status; +} + + static int fix_boundary (CT *ct, int *message_mods) { struct multipart *mp; @@ -743,8 +803,9 @@ replace_boundary (CT ct, char *file, char *boundary) { fprintf (fpout, "%s:%s%s\n", np, new_ctline, new_params ? new_params : ""); free(new_ctline); - if (new_params) + if (new_params) { free(new_params); + } } free (vp); @@ -1855,12 +1916,13 @@ decode_text_parts (CT ct, int encoding, const char *decodetypes, int *message_mo ct->c_cefile.ce_file = NULL; } else { int enc; - if (ct_encoding == CE_BINARY) + if (ct_encoding == CE_BINARY) { enc = CE_BINARY; - else if (ct_encoding == CE_8BIT && encoding == CE_7BIT) + } else if (ct_encoding == CE_8BIT && encoding == CE_7BIT) { enc = CE_QUOTED; - else + } else { enc = charset_encoding (ct); + } if (set_ce (ct, enc) == OK) { ++*message_mods; if (verbosw) { @@ -2275,7 +2337,7 @@ fix_always (CT ct, int *message_mods) { static int -write_content (CT ct, char *input_filename, char *outfile, int modify_inplace, +write_content (CT ct, const char *input_filename, char *outfile, int modify_inplace, int message_mods) { int status = OK; @@ -2391,7 +2453,7 @@ set_text_ctparams(CT ct, char *decodetypes, int lf_line_endings) { * use the standard MH backup file. */ static int -remove_file (char *file) { +remove_file (const char *file) { if (rmmproc) { char *rmm_command = concat (rmmproc, " ", file, NULL); int status = system (rmm_command);