X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/fe86b6d55ac470e6e832c53ea2c71e680efe5274..9291a5f82480f2458e04cb9ea7e6749bc952b308:/uip/mhfixmsg.c diff --git a/uip/mhfixmsg.c b/uip/mhfixmsg.c index 4cf2014e..dd0d8a23 100644 --- a/uip/mhfixmsg.c +++ b/uip/mhfixmsg.c @@ -1,16 +1,40 @@ -/* - * mhfixmsg.c -- rewrite a message with various transformations +/* 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 * distribution for complete copyright information. */ -#include -#include -#include -#include -#include +#include "h/mh.h" +#include "sbr/fmt_rfc2047.h" +#include "sbr/cpydata.h" +#include "sbr/trimcpy.h" +#include "sbr/m_convert.h" +#include "sbr/m_backup.h" +#include "sbr/getfolder.h" +#include "sbr/folder_read.h" +#include "sbr/context_save.h" +#include "sbr/context_replace.h" +#include "sbr/context_find.h" +#include "sbr/readconfig.h" +#include "sbr/ambigsw.h" +#include "sbr/path.h" +#include "sbr/print_version.h" +#include "sbr/print_help.h" +#include "sbr/error.h" +#include "h/fmt_scan.h" +#include "h/mime.h" +#include "h/mhparse.h" +#include "h/done.h" +#include "h/utils.h" +#include "h/signals.h" +#include "sbr/m_maildir.h" +#include "sbr/m_mktemp.h" +#include "sbr/mime_type.h" +#include "mhmisc.h" +#include "mhfree.h" +#include "mhoutsbr.h" +#include "mhshowsbr.h" #include #define MHFIXMSG_SWITCHES \ @@ -55,22 +79,6 @@ int debugsw; /* Needed by mhparse.c. */ #define quitser pipeser -/* mhparse.c */ -extern int skip_mp_cte_check; /* flag to InitMultiPart */ -extern int suppress_bogus_mp_content_warning; /* flag to InitMultiPart */ -extern int bogus_mp_content; /* flag from InitMultiPart */ -/* flags to/from parse_header_attrs */ -extern int suppress_extraneous_trailing_semicolon_warning; - -/* mhoutsbr.c */ -int output_message_fp (CT, FILE *, char *); - -/* mhmisc.c */ -void flush_errors (void); - -/* mhfree.c */ -extern CT *cts; - /* * static prototypes */ @@ -87,8 +95,8 @@ typedef struct fix_transformations { char *textcharset; } fix_transformations; -int mhfixmsgsbr (CT *, char *, const fix_transformations *, FILE **, char *, - FILE **); +static int mhfixmsgsbr (CT *, char *, const fix_transformations *, + FILE **, char *, FILE **); static int fix_boundary (CT *, int *); static int copy_input_to_output (const char *, FILE *, const char *, FILE *); static int get_multipart_boundary (CT, char **); @@ -116,7 +124,7 @@ static int should_decode(const char *, const char *, const char *); static int content_encoding (CT, const char **); static int strip_crs (CT, int *); static void update_cte (CT); -static int least_restrictive_encoding (CT); +static int least_restrictive_encoding (CT) PURE; static int less_restrictive (int, int); static int convert_charsets (CT, char *, int *); static int fix_always (CT, int *); @@ -125,12 +133,14 @@ static int fix_filename_encoding (CT); static int write_content (CT, const char *, char *, FILE *, int, int); static void set_text_ctparams(CT, char *, int); static int remove_file (const char *); -static void report (char *, char *, char *, char *, ...); +static void report (char *, char *, char *, char *, ...) + CHECK_PRINTF(4, 5); static void pipeser (int); int -main (int argc, char **argv) { +main (int argc, char **argv) +{ int msgnum; char *cp, *file = NULL, *folder = NULL; char *maildir = NULL, buf[100], *outfile = NULL; @@ -139,8 +149,8 @@ main (int argc, char **argv) { struct msgs *mp = NULL; CT *ctp; FILE *fp, *infp = NULL, *outfp = NULL; - int using_stdin = 0; - int chgflag = 1; + bool using_stdin = false; + bool chgflag = true; int status = OK; fix_transformations fx; fx.reformat = fx.fixcompositecte = fx.fixboundary = 1; @@ -151,7 +161,7 @@ main (int argc, char **argv) { fx.lf_line_endings = 0; fx.textcharset = NULL; - if (nmh_init(argv[0], 2)) { return 1; } + if (nmh_init(argv[0], true, false)) { return 1; } arguments = getarguments (invo_name, argc, argv, 1); argp = arguments; @@ -166,7 +176,7 @@ main (int argc, char **argv) { ambigsw (cp, switches); done (1); case UNKWNSW: - adios (NULL, "-%s unknown", cp); + die("-%s unknown", cp); case HELPSW: snprintf (buf, sizeof buf, "%s [+folder] [msgs] [switches]", @@ -179,7 +189,7 @@ main (int argc, char **argv) { case DECODETEXTSW: if (! (cp = *argp++) || *cp == '-') { - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); } if (! strcasecmp (cp, "8bit")) { fx.decodetext = CE_8BIT; @@ -188,7 +198,7 @@ main (int argc, char **argv) { } else if (! strcasecmp (cp, "binary")) { fx.decodetext = CE_BINARY; } else { - adios (NULL, "invalid argument to %s", argp[-2]); + die("invalid argument to %s", argp[-2]); } continue; case NDECODETEXTSW: @@ -196,7 +206,7 @@ main (int argc, char **argv) { continue; case DECODETYPESW: if (! (cp = *argp++) || *cp == '-') { - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); } fx.decodetypes = cp; continue; @@ -208,7 +218,7 @@ main (int argc, char **argv) { continue; case TEXTCHARSETSW: if (! (cp = *argp++) || (*cp == '-' && cp[1])) { - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); } fx.textcharset = cp; continue; @@ -229,14 +239,13 @@ main (int argc, char **argv) { continue; case FIXTYPESW: if (! (cp = *argp++) || (*cp == '-' && cp[1])) { - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); } if (! strncasecmp (cp, "multipart/", 10) || - ! strncasecmp (cp, "message/", 8)) { - adios (NULL, "-fixtype %s not allowed", cp); - } else if (! strchr (cp, '/')) { - adios (NULL, "-fixtype requires type/subtype"); - } + ! strncasecmp (cp, "message/", 8)) + die("-fixtype %s not allowed", cp); + if (! strchr (cp, '/')) + die("-fixtype requires type/subtype"); if (fx.fixtypes == NULL) { fx.fixtypes = svector_create (10); } svector_push_back (fx.fixtypes, cp); continue; @@ -254,29 +263,29 @@ main (int argc, char **argv) { continue; case FILESW: if (! (cp = *argp++) || (*cp == '-' && cp[1])) { - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); } file = *cp == '-' ? mh_xstrdup (cp) : path (cp, TFILE); continue; case OUTFILESW: if (! (cp = *argp++) || (*cp == '-' && cp[1])) { - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); } outfile = *cp == '-' ? mh_xstrdup (cp) : path (cp, TFILE); continue; case RPROCSW: if (!(rmmproc = *argp++) || *rmmproc == '-') { - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); } continue; case NRPRCSW: rmmproc = NULL; continue; case CHGSW: - chgflag = 1; + chgflag = true; continue; case NCHGSW: - chgflag = 0; + chgflag = false; continue; case VERBSW: verbosw = 1; @@ -287,11 +296,9 @@ main (int argc, char **argv) { } } if (*cp == '+' || *cp == '@') { - if (folder) { - adios (NULL, "only one folder at a time!"); - } else { - folder = pluspath (cp); - } + if (folder) + die("only one folder at a time!"); + folder = pluspath (cp); } else { if (*cp == '/') { /* Interpret a full path as a filename, not a message. */ @@ -309,19 +316,19 @@ main (int argc, char **argv) { * Read the standard profile setup */ if ((fp = fopen (cp = etcpath ("mhn.defaults"), "r"))) { - readconfig ((struct node **) 0, fp, cp, 0); + readconfig(NULL, fp, cp, 0); fclose (fp); } - suppress_bogus_mp_content_warning = skip_mp_cte_check = 1; - suppress_extraneous_trailing_semicolon_warning = 1; + suppress_bogus_mp_content_warning = skip_mp_cte_check = true; + suppress_extraneous_trailing_semicolon_warning = true; if (! context_find ("path")) { free (path ("./", TFOLDER)); } if (file && msgs.size) { - adios (NULL, "cannot specify msg and file at same time!"); + die("cannot specify msg and file at same time!"); } if (outfile) { @@ -348,10 +355,10 @@ main (int argc, char **argv) { int fd; char *cp; - using_stdin = 1; + using_stdin = true; if ((cp = m_mktemp2 (NULL, invo_name, &fd, NULL)) == NULL) { - adios (NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } else { free (file); @@ -361,7 +368,7 @@ main (int argc, char **argv) { if (close (fd)) { (void) m_unlink (file); - adios (NULL, "failed to write temporary file"); + die("failed to write temporary file"); } } @@ -416,12 +423,12 @@ main (int argc, char **argv) { /* read folder and create message structure */ if (! (mp = folder_read (folder, 1))) { - adios (NULL, "unable to read folder %s", folder); + die("unable to read folder %s", folder); } /* check for empty folder */ if (mp->nummsg == 0) { - adios (NULL, "no messages in %s", folder); + die("no messages in %s", folder); } /* parse all the message ranges/sequences and set SELECTED */ @@ -487,7 +494,10 @@ main (int argc, char **argv) { if (*cts) { for (ctp = cts; *ctp; ++ctp) { - status += mhfixmsgsbr (ctp, maildir, &fx, &infp, outfile, &outfp); + status = + mhfixmsgsbr (ctp, maildir, &fx, &infp, outfile, &outfp) == OK + ? 0 + : 1; free_content (*ctp); if (using_stdin) { @@ -503,7 +513,7 @@ main (int argc, char **argv) { status = 1; } - mh_xfree(maildir); + free(maildir); free (cts); if (fx.fixtypes != NULL) { svector_free (fx.fixtypes); } @@ -514,7 +524,7 @@ main (int argc, char **argv) { free (folder); free (arguments); - done (status); + done (status == OK ? 0 : 1); return NOTOK; } @@ -522,15 +532,16 @@ main (int argc, char **argv) { /* * Apply transformations to one message. */ -int +static int mhfixmsgsbr (CT *ctp, char *maildir, const fix_transformations *fx, - FILE **infp, char *outfile, FILE **outfp) { + FILE **infp, char *outfile, FILE **outfp) +{ /* Store input filename in case one of the transformations, i.e., fix_boundary(), rewrites to a tmp file. */ char *input_filename = maildir ? concat (maildir, "/", (*ctp)->c_file, NULL) : mh_xstrdup ((*ctp)->c_file); - int modify_inplace = 0; + bool modify_inplace = false; int message_mods = 0; int status = OK; @@ -542,19 +553,19 @@ mhfixmsgsbr (CT *ctp, char *maildir, const fix_transformations *fx, } if (outfile == NULL) { - modify_inplace = 1; + modify_inplace = true; if ((*ctp)->c_file) { char *tempfile; /* outfp will be closed by the caller */ if ((tempfile = m_mktemp2 (NULL, invo_name, NULL, outfp)) == NULL) { - adios (NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } outfile = mh_xstrdup (tempfile); } else { - adios (NULL, "missing both input and output filenames\n"); + die("missing both input and output filenames\n"); } } /* else *outfp was defined by caller */ @@ -631,7 +642,8 @@ mhfixmsgsbr (CT *ctp, char *maildir, const fix_transformations *fx, */ static int copy_input_to_output (const char *input_filename, FILE *infp, - const char *output_filename, FILE *outfp) { + const char *output_filename, FILE *outfp) +{ int in = fileno (infp); int out = fileno (outfp); int status = OK; @@ -650,7 +662,8 @@ copy_input_to_output (const char *input_filename, FILE *infp, * Fix mismatched outer level boundary. */ static int -fix_boundary (CT *ct, int *message_mods) { +fix_boundary (CT *ct, int *message_mods) +{ struct multipart *mp; int status = OK; @@ -726,7 +739,8 @@ fix_boundary (CT *ct, int *message_mods) { * Find boundary at end of multipart. */ static int -get_multipart_boundary (CT ct, char **part_boundary) { +get_multipart_boundary (CT ct, char **part_boundary) +{ char buffer[NMH_BUFSIZ]; char *end_boundary = NULL; off_t begin = (off_t) ct->c_end > (off_t) (ct->c_begin + sizeof buffer) @@ -765,11 +779,9 @@ get_multipart_boundary (CT ct, char **part_boundary) { } } - if (! end_boundary && begin > (off_t) (ct->c_begin + sizeof buffer)) { - begin -= sizeof buffer; - } else { + if (end_boundary || begin <= (off_t) (ct->c_begin + sizeof buffer)) break; - } + begin -= sizeof buffer; } /* Get boundary at beginning of multipart. */ @@ -815,12 +827,13 @@ get_multipart_boundary (CT ct, char **part_boundary) { * Open and copy ct->c_file to file, replacing the multipart boundary. */ static int -replace_boundary (CT ct, char *file, char *boundary) { +replace_boundary (CT ct, char *file, char *boundary) +{ FILE *fpin, *fpout; int compnum, state; char buf[NMH_BUFSIZ], name[NAMESZ]; char *np, *vp; - m_getfld_state_t gstate = 0; + m_getfld_state_t gstate; int status = OK; if (ct->c_file == NULL) { @@ -839,10 +852,11 @@ replace_boundary (CT ct, char *file, char *boundary) { return NOTOK; } + gstate = m_getfld_state_init(fpin); for (compnum = 1;;) { int bufsz = (int) sizeof buf; - switch (state = m_getfld (&gstate, name, buf, &bufsz, fpin)) { + switch (state = m_getfld2(&gstate, name, buf, &bufsz)) { case FLD: case FLDPLUS: compnum++; @@ -854,7 +868,7 @@ replace_boundary (CT ct, char *file, char *boundary) { /* if necessary, get rest of field */ while (state == FLDPLUS) { bufsz = sizeof buf; - state = m_getfld (&gstate, name, buf, &bufsz, fpin); + state = m_getfld2(&gstate, name, buf, &bufsz); vp = add (buf, vp); /* add to previous value */ } @@ -869,13 +883,13 @@ replace_boundary (CT ct, char *file, char *boundary) { new_ctline = concat(" ", ct->c_ctinfo.ci_type, "/", ct->c_ctinfo.ci_subtype, NULL); - new_params = output_params(strlen(TYPE_FIELD) + + new_params = output_params(LEN(TYPE_FIELD) + strlen(new_ctline) + 1, ct->c_ctinfo.ci_first_pm, NULL, 0); fprintf (fpout, "%s:%s%s\n", np, new_ctline, - new_params ? new_params : ""); + FENDNULL(new_params)); free(new_ctline); - mh_xfree(new_params); + free(new_params); } free (vp); @@ -921,7 +935,8 @@ replace_boundary (CT ct, char *file, char *boundary) { * Fix Content-Type header to reflect the content of its part. */ static int -fix_types (CT ct, svector_t fixtypes, int *message_mods) { +fix_types (CT ct, svector_t fixtypes, int *message_mods) +{ int status = OK; switch (ct->c_type) { @@ -1015,10 +1030,8 @@ fix_types (CT ct, svector_t fixtypes, int *message_mods) { type, ct_type_subtype); } break; - } else { - inform("did not find %s in %s", - type, hf->value); } + inform("did not find %s in %s", type, hf->value); } } } @@ -1037,7 +1050,8 @@ fix_types (CT ct, svector_t fixtypes, int *message_mods) { * Replace a substring, allocating space to hold the new one. */ char * -replace_substring (char **str, const char *old, const char *new) { +replace_substring (char **str, const char *old, const char *new) +{ char *cp; if ((cp = strstr (*str, old))) { @@ -1066,9 +1080,10 @@ replace_substring (char **str, const char *old, const char *new) { * Remove a name=value parameter, given just its name, from a header value. */ char * -remove_parameter (char *str, const char *name) { +remove_parameter (char *str, const char *name) +{ /* It looks to me, based on the BNF in RFC 2045, than there can't - be whitespace betwwen the parameter name and the "=", or + be whitespace between the parameter name and the "=", or between the "=" and the parameter value. */ char *param_name = concat (name, "=", NULL); char *cp; @@ -1115,7 +1130,8 @@ remove_parameter (char *str, const char *name) { * 8 bit. */ static int -fix_composite_cte (CT ct, int *message_mods) { +fix_composite_cte (CT ct, int *message_mods) +{ int status = OK; if (ct->c_type == CT_MESSAGE || ct->c_type == CT_MULTIPART) { @@ -1125,12 +1141,12 @@ fix_composite_cte (CT ct, int *message_mods) { for (hf = ct->c_first_hf; hf; hf = hf->next) { char *name = hf->name; - for (; *name && isspace ((unsigned char) *name); ++name) { + for (; isspace((unsigned char)*name); ++name) { continue; } if (! strncasecmp (name, ENCODING_FIELD, - strlen (ENCODING_FIELD))) { + LEN(ENCODING_FIELD))) { char *prefix = "Nmh-REPLACED-INVALID-"; HF h; @@ -1187,13 +1203,14 @@ fix_composite_cte (CT ct, int *message_mods) { * Set content encoding. */ static int -set_ce (CT ct, int encoding) { +set_ce (CT ct, int encoding) +{ const char *ce = ce_str (encoding); const struct str2init *ctinit = get_ce_method (ce); if (ctinit) { char *cte = concat (" ", ce, "\n", NULL); - int found_cte = 0; + bool found_cte = false; HF hf; /* Decoded contents might be in ct->c_cefile.ce_file, if the caller is decode_text_parts (). Save because we'll @@ -1220,7 +1237,7 @@ set_ce (CT ct, int encoding) { /* Update/add Content-Transfer-Encoding header field. */ for (hf = ct->c_first_hf; hf; hf = hf->next) { if (! strcasecmp (ENCODING_FIELD, hf->name)) { - found_cte = 1; + found_cte = true; free (hf->value); hf->value = cte; } @@ -1244,7 +1261,8 @@ set_ce (CT ct, int encoding) { * Make sure each text part has a corresponding text/plain part. */ static int -ensure_text_plain (CT *ct, CT parent, int *message_mods, int replacetextplain) { +ensure_text_plain (CT *ct, CT parent, int *message_mods, int replacetextplain) +{ int status = OK; switch ((*ct)->c_type) { @@ -1355,11 +1373,9 @@ ensure_text_plain (CT *ct, CT parent, int *message_mods, int replacetextplain) { multipart/alternative. */ remove_parameter (hf->value, "type"); break; - } else { - inform("did not find multipart/" - "related in header %s", - hf->value); } + inform("did not find multipart/" + "related in header %s", hf->value); } } } else { @@ -1407,10 +1423,11 @@ ensure_text_plain (CT *ct, CT parent, int *message_mods, int replacetextplain) { */ static int find_textplain_sibling (CT parent, int replacetextplain, - int *new_subpart_number) { + int *new_subpart_number) +{ struct multipart *mp = (struct multipart *) parent->c_ctparams; struct part *part, *prev; - int has_text_plain = 0; + bool has_text_plain = false; for (prev = part = mp->mp_parts; part; part = part->mp_next) { ++*new_subpart_number; @@ -1433,7 +1450,7 @@ find_textplain_sibling (CT parent, int replacetextplain, free_content (old_part->mp_part); free (old_part); } else { - has_text_plain = 1; + has_text_plain = true; } break; } @@ -1448,7 +1465,8 @@ find_textplain_sibling (CT parent, int replacetextplain, * Insert a new text/plain part. */ static int -insert_new_text_plain_part (CT ct, int new_subpart_number, CT parent) { +insert_new_text_plain_part (CT ct, int new_subpart_number, CT parent) +{ struct multipart *mp = (struct multipart *) parent->c_ctparams; struct part *new_part; @@ -1477,7 +1495,8 @@ insert_new_text_plain_part (CT ct, int new_subpart_number, CT parent) { * Create a text/plain part to go along with non-plain sibling part. */ static CT -build_text_plain_part (CT encoded_part) { +build_text_plain_part (CT encoded_part) +{ CT tp_part = divide_part (encoded_part); char *tmp_plain_file = NULL; @@ -1515,7 +1534,8 @@ build_text_plain_part (CT encoded_part) { * Slip new text/plain part into a new multipart/alternative. */ static int -insert_into_new_mp_alt (CT *ct, int *message_mods) { +insert_into_new_mp_alt (CT *ct, int *message_mods) +{ CT tp_part = build_text_plain_part (*ct); int status = OK; @@ -1555,7 +1575,8 @@ insert_into_new_mp_alt (CT *ct, int *message_mods) { * Clone a MIME part. */ static CT -divide_part (CT ct) { +divide_part (CT ct) +{ CT new_part; NEW0(new_part); @@ -1585,7 +1606,8 @@ divide_part (CT ct) { * Copy the content info from one part to another. */ static void -copy_ctinfo (CI dest, CI src) { +copy_ctinfo (CI dest, CI src) +{ PM s_pm, d_pm; dest->ci_type = src->ci_type ? mh_xstrdup (src->ci_type) : NULL; @@ -1611,14 +1633,15 @@ copy_ctinfo (CI dest, CI src) { * Decode content. */ static int -decode_part (CT ct) { +decode_part (CT ct) +{ char *tmp_decoded; int status; FILE *file; char *tempfile; if ((tempfile = m_mktemp2 (NULL, invo_name, NULL, &file)) == NULL) { - adios (NULL, "unable to create temporary file in %s", get_temp_dir()); + die("unable to create temporary file in %s", get_temp_dir()); } tmp_decoded = mh_xstrdup (tempfile); /* The following call will load ct->c_cefile.ce_file with the tmp @@ -1641,7 +1664,8 @@ decode_part (CT ct) { * be in the future for other than text types. */ static int -reformat_part (CT ct, char *file, char *type, char *subtype, int c_type) { +reformat_part (CT ct, char *file, char *type, char *subtype, int c_type) +{ int output_subtype, output_encoding; const char *reason = NULL; char *cp, *cf; @@ -1664,7 +1688,7 @@ reformat_part (CT ct, char *file, char *type, char *subtype, int c_type) { if (strchr (cf, '>')) { inform("'>' prohibited in \"%s\",\nplease fix your " "%s-format-%s/%s profile entry", cf, invo_name, type, - subtype ? subtype : ""); + FENDNULL(subtype)); return NOTOK; } @@ -1707,7 +1731,8 @@ reformat_part (CT ct, char *file, char *type, char *subtype, int c_type) { * Fill in a multipart/alternative part. */ static CT -build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { +build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) +{ char *boundary_prefix = "----=_nmh-multipart"; char *boundary = concat (boundary_prefix, first_alt->c_partno, NULL); char *boundary_indicator = "; boundary="; @@ -1755,8 +1780,7 @@ build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { boundary_in_content (&new_part->c_cefile.ce_fp, new_part->c_cefile.ce_file, boundary)) == NOTOK) { - free_content (ct); - return NULL; + goto return_null; } } @@ -1767,8 +1791,7 @@ build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { boundary_in_content (&new_part->c_fp, new_part->c_file, boundary)) == NOTOK) { - free_content (ct); - return NULL; + goto return_null; } } @@ -1781,15 +1804,14 @@ build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { snprintf (buffer2, sizeof buffer2, "%d", serial); boundary = concat (boundary_prefix, - first_alt->c_partno ? first_alt->c_partno : "", + FENDNULL(first_alt->c_partno), "-", buffer2, NULL); } } if (found_boundary) { inform("giving up trying to find a unique boundary"); - free_content (ct); - return NULL; + goto return_null; } } @@ -1834,6 +1856,11 @@ build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { free (boundary); return ct; + +return_null: + free_content(ct); + free(boundary); + return NULL; } @@ -1841,10 +1868,11 @@ build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { * Check that the boundary does not appear in the content. */ static int -boundary_in_content (FILE **fp, char *file, const char *boundary) { +boundary_in_content (FILE **fp, char *file, const char *boundary) +{ char buffer[NMH_BUFSIZ]; size_t bytes_read; - int found_boundary = 0; + bool found_boundary = false; /* free_content() will close *fp if we fopen it here. */ if (! *fp && (*fp = fopen (file, "r")) == NULL) { @@ -1855,7 +1883,7 @@ boundary_in_content (FILE **fp, char *file, const char *boundary) { fseeko (*fp, 0L, SEEK_SET); while ((bytes_read = fread (buffer, 1, sizeof buffer, *fp)) > 0) { if (find_str (buffer, bytes_read, boundary)) { - found_boundary = 1; + found_boundary = true; break; } } @@ -1868,14 +1896,15 @@ boundary_in_content (FILE **fp, char *file, const char *boundary) { * Remove all non-Content headers. */ static void -transfer_noncontent_headers (CT old, CT new) { +transfer_noncontent_headers (CT old, CT new) +{ HF hp, hp_prev; hp_prev = hp = old->c_first_hf; while (hp) { HF next = hp->next; - if (strncasecmp (XXX_FIELD_PRF, hp->name, strlen (XXX_FIELD_PRF))) { + if (strncasecmp (XXX_FIELD_PRF, hp->name, LEN(XXX_FIELD_PRF))) { if (hp == old->c_last_hf) { if (hp == old->c_first_hf) { old->c_last_hf = old->c_first_hf = NULL; @@ -1912,14 +1941,15 @@ transfer_noncontent_headers (CT old, CT new) { * Set content type. */ static int -set_ct_type (CT ct, int type, int subtype, int encoding) { +set_ct_type (CT ct, int type, int subtype, int encoding) +{ char *typename = ct_type_str (type); char *subtypename = ct_subtype_str (type, subtype); /* E.g, " text/plain" */ char *type_subtypename = concat (" ", typename, "/", subtypename, NULL); /* E.g, " text/plain\n" */ char *name_plus_nl = concat (type_subtypename, "\n", NULL); - int found_content_type = 0; + bool found_content_type = false; HF hf; const char *cp = NULL; char *ctline; @@ -1928,7 +1958,7 @@ set_ct_type (CT ct, int type, int subtype, int encoding) { /* Update/add Content-Type header field. */ for (hf = ct->c_first_hf; hf; hf = hf->next) { if (! strcasecmp (TYPE_FIELD, hf->name)) { - found_content_type = 1; + found_content_type = true; free (hf->value); hf->value = (cp = strchr (ct->c_ctline, ';')) ? concat (type_subtypename, cp, "\n", NULL) @@ -1973,7 +2003,8 @@ set_ct_type (CT ct, int type, int subtype, int encoding) { */ static int decode_text_parts (CT ct, int encoding, const char *decodetypes, - int *message_mods) { + int *message_mods) +{ int status = OK; int lf_line_endings = 0; @@ -2024,8 +2055,7 @@ decode_text_parts (CT ct, int encoding, const char *decodetypes, report (NULL, ct->c_partno, ct->c_file, "will not decode%s because it is binary (%s)", ct->c_partno ? "" - : ct->c_ctline ? ct->c_ctline - : "", + : (FENDNULL(ct->c_ctline)), reason); } (void) m_unlink (ct->c_cefile.ce_file); @@ -2039,8 +2069,7 @@ decode_text_parts (CT ct, int encoding, const char *decodetypes, report (NULL, ct->c_partno, ct->c_file, "will not decode%s because it is 8bit", ct->c_partno ? "" - : ct->c_ctline ? ct->c_ctline - : ""); + : (FENDNULL(ct->c_ctline))); } (void) m_unlink (ct->c_cefile.ce_file); free (ct->c_cefile.ce_file); @@ -2059,7 +2088,7 @@ decode_text_parts (CT ct, int encoding, const char *decodetypes, ++*message_mods; if (verbosw) { report (NULL, ct->c_partno, ct->c_file, "decode%s", - ct->c_ctline ? ct->c_ctline : ""); + FENDNULL(ct->c_ctline)); } if (lf_line_endings) { strip_crs (ct, message_mods); @@ -2095,23 +2124,24 @@ decode_text_parts (CT ct, int encoding, const char *decodetypes, * decodetypes (which came from the -decodetypes switch). */ static int -should_decode(const char *decodetypes, const char *type, const char *subtype) { +should_decode(const char *decodetypes, const char *type, const char *subtype) +{ /* Quick search for matching type[/subtype] in decodetypes: bracket decodetypes with commas, then search for ,type, and ,type/subtype, in it. */ - int found_match = 0; + bool found_match = false; char *delimited_decodetypes = concat(",", decodetypes, ",", NULL); char *delimited_type = concat(",", type, ",", NULL); if (nmh_strcasestr(delimited_decodetypes, delimited_type)) { - found_match = 1; + found_match = true; } else if (subtype != NULL) { char *delimited_type_subtype = concat(",", type, "/", subtype, ",", NULL); if (nmh_strcasestr(delimited_decodetypes, delimited_type_subtype)) { - found_match = 1; + found_match = true; } free(delimited_type_subtype); } @@ -2130,7 +2160,8 @@ should_decode(const char *decodetypes, const char *type, const char *subtype) { * to a string explaining why. */ static int -content_encoding (CT ct, const char **reason) { +content_encoding (CT ct, const char **reason) +{ CE ce = &ct->c_cefile; int encoding = CE_7BIT; @@ -2166,13 +2197,14 @@ content_encoding (CT ct, const char **reason) { *reason = ""; } break; - } else if (*cp == '\n') { + } + if (*cp == '\n') { line_len = 0; } else if (! isascii ((unsigned char) *cp)) { encoding = CE_8BIT; } - last_char_was_cr = *cp == '\r' ? 1 : 0; + last_char_was_cr = *cp == '\r'; } } @@ -2188,7 +2220,8 @@ content_encoding (CT ct, const char **reason) { * Strip carriage returns from content. */ static int -strip_crs (CT ct, int *message_mods) { +strip_crs (CT ct, int *message_mods) +{ char *charset = content_charset (ct); int status = OK; @@ -2205,8 +2238,8 @@ strip_crs (CT ct, int *message_mods) { FILE **fp = NULL; size_t begin; size_t end; - int has_crs = 0; - int opened_input_file = 0; + bool has_crs = false; + bool opened_input_file = false; if (ct->c_cefile.ce_file) { file = &ct->c_cefile.ce_file; @@ -2225,7 +2258,7 @@ strip_crs (CT ct, int *message_mods) { advise (*file, "unable to open for reading"); status = NOTOK; } else { - opened_input_file = 1; + opened_input_file = true; } } } @@ -2245,17 +2278,17 @@ strip_crs (CT ct, int *message_mods) { modify the content. */ char *cp; size_t i; - int last_char_was_cr = 0; + bool last_char_was_cr = false; if (end > 0) { bytes_to_read -= bytes_read; } for (i = 0, cp = buffer; i < bytes_read; ++i, ++cp) { if (*cp == '\n' && last_char_was_cr) { - has_crs = 1; + has_crs = true; break; } - last_char_was_cr = *cp == '\r' ? 1 : 0; + last_char_was_cr = *cp == '\r'; } } @@ -2265,7 +2298,7 @@ strip_crs (CT ct, int *message_mods) { char *tempfile = m_mktemp2 (NULL, invo_name, &fd, NULL); if (tempfile == NULL) { - adios (NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } stripped_content_file = mh_xstrdup (tempfile); @@ -2276,11 +2309,11 @@ strip_crs (CT ct, int *message_mods) { 0) { char *cp; size_t i; - int last_char_was_cr = 0; + bool last_char_was_cr = false; for (i = 0, cp = buffer; i < bytes_read; ++i, ++cp) { if (*cp == '\r') { - last_char_was_cr = 1; + last_char_was_cr = true; } else if (last_char_was_cr) { if (*cp != '\n') { if (write (fd, "\r", 1) < 0) { @@ -2290,12 +2323,12 @@ strip_crs (CT ct, int *message_mods) { if (write (fd, cp, 1) < 0) { advise (tempfile, "write"); } - last_char_was_cr = 0; + last_char_was_cr = false; } else { if (write (fd, cp, 1) < 0) { advise (tempfile, "write"); } - last_char_was_cr = 0; + last_char_was_cr = false; } } } @@ -2304,13 +2337,14 @@ strip_crs (CT ct, int *message_mods) { inform("unable to write temporary file %s, continuing...", stripped_content_file); (void) m_unlink (stripped_content_file); + free(stripped_content_file); status = NOTOK; } else { /* Replace the decoded file with the converted one. */ 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); + free(ct->c_cefile.ce_file); ct->c_cefile.ce_file = stripped_content_file; ct->c_cefile.ce_unlink = 1; @@ -2341,19 +2375,20 @@ strip_crs (CT ct, int *message_mods) { * of the part C-T-E's. */ static void -update_cte (CT ct) { +update_cte (CT ct) +{ const int least_restrictive_enc = least_restrictive_encoding (ct); if (least_restrictive_enc != CE_UNKNOWN && least_restrictive_enc != CE_7BIT) { char *cte = concat (" ", ce_str (least_restrictive_enc), "\n", NULL); HF hf; - int found_cte = 0; + bool found_cte = false; /* Update/add Content-Transfer-Encoding header field. */ for (hf = ct->c_first_hf; hf; hf = hf->next) { if (! strcasecmp (ENCODING_FIELD, hf->name)) { - found_cte = 1; + found_cte = true; free (hf->value); hf->value = cte; } @@ -2370,7 +2405,8 @@ update_cte (CT ct) { * within a message. */ static int -least_restrictive_encoding (CT ct) { +least_restrictive_encoding (CT ct) +{ int encoding = CE_UNKNOWN; switch (ct->c_type) { @@ -2418,7 +2454,8 @@ least_restrictive_encoding (CT ct) { * CE_8BIT is less restrictive than CE_7BIT. */ static int -less_restrictive (int encoding, int second_encoding) { +less_restrictive (int encoding, int second_encoding) +{ switch (second_encoding) { case CE_BINARY: return encoding != CE_BINARY; @@ -2437,7 +2474,8 @@ less_restrictive (int encoding, int second_encoding) { * Convert character set of each part. */ static int -convert_charsets (CT ct, char *dest_charset, int *message_mods) { +convert_charsets (CT ct, char *dest_charset, int *message_mods) +{ int status = OK; switch (ct->c_type) { @@ -2502,7 +2540,8 @@ convert_charsets (CT ct, char *dest_charset, int *message_mods) { * headers, respectively. */ static int -fix_always (CT ct, int *message_mods) { +fix_always (CT ct, int *message_mods) +{ int status = OK; switch (ct->c_type) { @@ -2584,8 +2623,9 @@ fix_always (CT ct, int *message_mods) { * Factor out common code for loops in fix_filename_encoding(). */ static int -fix_filename_param (char *name, char *value, PM *first_pm, PM *last_pm) { - int fixed = 0; +fix_filename_param (char *name, char *value, PM *first_pm, PM *last_pm) +{ + bool fixed = false; if (has_prefix(value, "=?") && has_suffix(value, "?=")) { /* Looks like an RFC 2047 encoded parameter. */ @@ -2594,7 +2634,7 @@ fix_filename_param (char *name, char *value, PM *first_pm, PM *last_pm) { if (decode_rfc2047 (value, decoded, sizeof decoded)) { /* Encode using RFC 2231. */ replace_param (first_pm, last_pm, name, decoded, 0); - fixed = 1; + fixed = true; } else { inform("failed to decode %s parameter %s", name, value); } @@ -2610,7 +2650,8 @@ fix_filename_param (char *name, char *value, PM *first_pm, PM *last_pm) { * headers, respectively. */ static int -fix_filename_encoding (CT ct) { +fix_filename_encoding (CT ct) +{ PM pm; HF hf; int fixed = 0; @@ -2676,7 +2717,8 @@ fix_filename_encoding (CT ct) { */ static int write_content (CT ct, const char *input_filename, char *outfile, FILE *outfp, - int modify_inplace, int message_mods) { + int modify_inplace, int message_mods) +{ int status = OK; if (modify_inplace) { @@ -2724,7 +2766,7 @@ write_content (CT ct, const char *input_filename, char *outfile, FILE *outfp, } } else { inform("unable to remove input file %s, " - "not modifying it, continuing...", infile); + "not modifying it, continuing...", infile); (void) m_unlink (outfile); status = NOTOK; } @@ -2753,7 +2795,8 @@ write_content (CT ct, const char *input_filename, char *outfile, FILE *outfp, * function to do it. It touches the parts the decodetypes identifies. */ static void -set_text_ctparams(CT ct, char *decodetypes, int lf_line_endings) { +set_text_ctparams(CT ct, char *decodetypes, int lf_line_endings) +{ switch (ct->c_type) { case CT_MULTIPART: { struct multipart *m = (struct multipart *) ct->c_ctparams; @@ -2789,7 +2832,8 @@ set_text_ctparams(CT ct, char *decodetypes, int lf_line_endings) { * use the standard MH backup file. */ static int -remove_file (const char *file) { +remove_file (const char *file) +{ if (rmmproc) { char *rmm_command = concat (rmmproc, " ", file, NULL); int status = system (rmm_command); @@ -2808,14 +2852,15 @@ remove_file (const char *file) { * Output formatted message to user. */ static void -report (char *what, char *partno, char *filename, char *message, ...) { +report (char *what, char *partno, char *filename, char *message, ...) +{ va_list args; char *fmt; if (verbosw) { va_start (args, message); fmt = concat (filename, partno ? " part " : ", ", - partno ? partno : "", partno ? ", " : "", message, NULL); + FENDNULL(partno), partno ? ", " : "", message, NULL); advertise (what, NULL, fmt, args);