X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/21d1fd096d82870eb175efbf3ee44498e47ede58..e62400a894407812a6774c1a0eddde91142a42eb:/uip/mhfixmsg.c?ds=sidebyside diff --git a/uip/mhfixmsg.c b/uip/mhfixmsg.c index 372dbb9c..b7f1917a 100644 --- a/uip/mhfixmsg.c +++ b/uip/mhfixmsg.c @@ -71,7 +71,6 @@ void flush_errors (void); /* mhfree.c */ extern CT *cts; -void freects_done (int) NORETURN; /* * static prototypes @@ -89,7 +88,7 @@ typedef struct fix_transformations { char *textcharset; } fix_transformations; -int mhfixmsgsbr (CT *, const fix_transformations *, char *); +int mhfixmsgsbr (CT *, char *, 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 **); @@ -134,7 +133,7 @@ int main (int argc, char **argv) { int msgnum; char *cp, *file = NULL, *folder = NULL; - char *maildir, buf[100], *outfile = NULL; + char *maildir = NULL, buf[100], *outfile = NULL; char **argp, **arguments; struct msgs_array msgs = { 0, 0, NULL }; struct msgs *mp = NULL; @@ -154,8 +153,6 @@ main (int argc, char **argv) { if (nmh_init(argv[0], 2)) { return 1; } - done = freects_done; - arguments = getarguments (invo_name, argc, argv, 1); argp = arguments; @@ -392,6 +389,8 @@ main (int argc, char **argv) { } maildir = m_maildir (folder); + /* chdir so that error messages, esp. from MIME parser, just + refer to the message and not its path. */ if (chdir (maildir) == NOTOK) { adios (maildir, "unable to change directory to"); } @@ -418,9 +417,8 @@ main (int argc, char **argv) { for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { if (is_selected(mp, msgnum)) { - char *msgnam; + char *msgnam = m_name (msgnum); - msgnam = m_name (msgnum); if ((ct = parse_mime (msgnam))) { set_text_ctparams(ct, fx.decodetypes, fx.lf_line_endings); *ctp++ = ct; @@ -428,16 +426,25 @@ main (int argc, char **argv) { 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 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); + /* Something went wrong. Output might be expected, + such as if this were run as a filter. Just copy + the input to the output. */ + /* Can't use path() here because 1) it might have been + called before and it caches the pwd, and 2) we call + chdir() after that. */ + char *input_filename = + concat (maildir, "/", msgnam, NULL); if (copy_input_to_output (input_filename, outfile) != OK) { - advise (NULL, "unable to copy message to %s, it might be lost\n", outfile); + advise (NULL, + "unable to copy message to %s, it might be lost\n", + outfile); } + free (input_filename); } } } @@ -453,7 +460,8 @@ main (int argc, char **argv) { if (*cts) { for (ctp = cts; *ctp; ++ctp) { - status += mhfixmsgsbr (ctp, &fx, outfile); + status += mhfixmsgsbr (ctp, maildir, &fx, outfile); + free_content (*ctp); if (using_stdin) { (void) m_unlink (file); @@ -464,6 +472,8 @@ main (int argc, char **argv) { } } } + + free (cts); } else { status = 1; } @@ -474,7 +484,6 @@ main (int argc, char **argv) { free (folder); free (arguments); - /* done is freects_done, which will clean up all of cts. */ done (status); return NOTOK; } @@ -484,10 +493,13 @@ main (int argc, char **argv) { * Apply transformations to one message. */ int -mhfixmsgsbr (CT *ctp, const fix_transformations *fx, char *outfile) { +mhfixmsgsbr (CT *ctp, char *maildir, const fix_transformations *fx, + char *outfile) { /* Store input filename in case one of the transformations, i.e., fix_boundary(), rewrites to a tmp file. */ - char *input_filename = add ((*ctp)->c_file, NULL); + char *input_filename = maildir + ? concat (maildir, "/", (*ctp)->c_file, NULL) + : add ((*ctp)->c_file, NULL); int modify_inplace = 0; int message_mods = 0; int status = OK; @@ -676,7 +688,7 @@ fix_boundary (CT *ct, int *message_mods) { */ static int get_multipart_boundary (CT ct, char **part_boundary) { - char buffer[BUFSIZ]; + char buffer[NMH_BUFSIZ]; char *end_boundary = NULL; off_t begin = (off_t) ct->c_end > (off_t) (ct->c_begin + sizeof buffer) ? (off_t) (ct->c_end - sizeof buffer) @@ -684,10 +696,10 @@ get_multipart_boundary (CT ct, char **part_boundary) { size_t bytes_read; int status = OK; - /* This will fail if the boundary spans fread() calls. BUFSIZ should + /* This will fail if the boundary spans fread() calls. NMH_BUFSIZ should be big enough, even if it's just 1024, to make that unlikely. */ - /* free_content() will close ct->c_fp. */ + /* free_content() will close ct->c_fp if bogus MP boundary is fixed. */ if (! ct->c_fp && (ct->c_fp = fopen (ct->c_file, "r")) == NULL) { advise (ct->c_file, "unable to open for reading"); return NOTOK; @@ -744,6 +756,11 @@ get_multipart_boundary (CT ct, char **part_boundary) { status = NOTOK; } + if (ct->c_fp) { + fclose (ct->c_fp); + ct->c_fp = NULL; + } + if (status == OK) { *part_boundary = end_boundary; } else { @@ -762,7 +779,7 @@ static int replace_boundary (CT ct, char *file, char *boundary) { FILE *fpin, *fpout; int compnum, state; - char buf[BUFSIZ], name[NAMESZ]; + char buf[NMH_BUFSIZ], name[NAMESZ]; char *np, *vp; m_getfld_state_t gstate = 0; int status = OK; @@ -819,9 +836,7 @@ 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) { - free(new_params); - } + mh_xfree(new_params); } free (vp); @@ -1631,7 +1646,8 @@ reformat_part (CT ct, char *file, char *type, char *subtype, int c_type) { } output_encoding = content_encoding (ct, &reason); - if (set_ct_type (ct, c_type, output_subtype, output_encoding) == OK) { + if (status == OK && + set_ct_type (ct, c_type, output_subtype, output_encoding) == OK) { ct->c_cefile.ce_file = file; ct->c_cefile.ce_unlink = 1; } else { @@ -1781,7 +1797,7 @@ build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { */ static int boundary_in_content (FILE **fp, char *file, const char *boundary) { - char buffer[BUFSIZ]; + char buffer[NMH_BUFSIZ]; size_t bytes_read; int found_boundary = 0; @@ -2075,7 +2091,7 @@ content_encoding (CT ct, const char **reason) { if (ce->ce_file) { size_t line_len = 0; - char buffer[BUFSIZ]; + char buffer[NMH_BUFSIZ]; size_t inbytes; if (! ce->ce_fp && (ce->ce_fp = fopen (ce->ce_file, "r")) == NULL) { @@ -2170,7 +2186,7 @@ strip_crs (CT ct, int *message_mods) { } if (fp && *fp) { - char buffer[BUFSIZ]; + char buffer[NMH_BUFSIZ]; size_t bytes_read; size_t bytes_to_read = end > 0 && end > begin ? end - begin : sizeof buffer; @@ -2246,12 +2262,10 @@ strip_crs (CT ct, int *message_mods) { status = NOTOK; } else { /* Replace the decoded file with the converted one. */ - if (ct->c_cefile.ce_file) { - if (ct->c_cefile.ce_unlink) { - (void) m_unlink (ct->c_cefile.ce_file); - } - free (ct->c_cefile.ce_file); - } + if (ct->c_cefile.ce_file && ct->c_cefile.ce_unlink) + (void) m_unlink (ct->c_cefile.ce_file); + + mh_xfree(ct->c_cefile.ce_file); ct->c_cefile.ce_file = stripped_content_file; ct->c_cefile.ce_unlink = 1; @@ -2526,12 +2540,9 @@ fix_always (CT ct, int *message_mods) { */ static int fix_filename_param (char *name, char *value, PM *first_pm, PM *last_pm) { - size_t value_len; int fixed = 0; - if (((value_len = strlen (value)) > 0) && - strncmp (value, "=?", 2) == 0 && - strncmp (&value[value_len - 2], "?=", 2) == 0) { + if (HasPrefix(value, "=?") && HasSuffix(value, "?=")) { /* Looks like an RFC 2047 encoded parameter. */ char decoded[PATH_MAX + 1]; @@ -2602,8 +2613,8 @@ fix_filename_encoding (CT ct) { const char *const new_params = concat (params, "\n", NULL); replace_substring (&hf->value, semicolon_loc, new_params); - free ((char *) new_params); - free ((char *) params); + free((void *)new_params); /* Cast away const. Sigh. */ + free((void *)params); } else { advise (NULL, "did not find semicolon in %s:%s\n", hf->name, hf->value); @@ -2641,7 +2652,7 @@ write_content (CT ct, const char *input_filename, char *outfile, int modify_inpl int i = -1; if (old != -1 && new != -1) { - char buffer[BUFSIZ]; + char buffer[NMH_BUFSIZ]; while ((i = read (old, buffer, sizeof buffer)) > 0) {