]> diplodocus.org Git - nmh/blobdiff - uip/mhfixmsg.c
smtp.c: Have function returning char pointer return NULL, not 0.
[nmh] / uip / mhfixmsg.c
index a0c6efda9030b61f157f95d0a8e0a4de1b9d92e8..2bbb0453a4e7282c55c34f2ba11819b2948da388 100644 (file)
@@ -1,5 +1,4 @@
-/*
- * 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
@@ -7,10 +6,18 @@
  */
 
 #include <h/mh.h>
+#include <h/fmt_scan.h>
 #include <h/mime.h>
 #include <h/mhparse.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 <fcntl.h>
 
 #define MHFIXMSG_SWITCHES \
@@ -55,22 +62,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 +78,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 +107,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,7 +116,8 @@ 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);
 
 
@@ -232,11 +224,10 @@ main (int argc, char **argv) {
                     adios (NULL, "missing argument to %s", argp[-2]);
                 }
                 if (! strncasecmp (cp, "multipart/", 10)  ||
-                    ! strncasecmp (cp, "message/", 8)) {
+                    ! strncasecmp (cp, "message/", 8))
                     adios (NULL, "-fixtype %s not allowed", cp);
-                } else if (! strchr (cp, '/')) {
+                if (! strchr (cp, '/'))
                     adios (NULL, "-fixtype requires type/subtype");
-                }
                 if (fx.fixtypes == NULL) { fx.fixtypes = svector_create (10); }
                 svector_push_back (fx.fixtypes, cp);
                 continue;
@@ -287,11 +278,9 @@ main (int argc, char **argv) {
             }
         }
         if (*cp == '+' || *cp == '@') {
-            if (folder) {
+            if (folder)
                 adios (NULL, "only one folder at a time!");
-            } else {
-                folder = pluspath (cp);
-            }
+            folder = pluspath (cp);
         } else {
             if (*cp == '/') {
                 /* Interpret a full path as a filename, not a message. */
@@ -309,12 +298,12 @@ 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));
@@ -372,7 +361,7 @@ main (int argc, char **argv) {
             set_text_ctparams(ct, fx.decodetypes, fx.lf_line_endings);
             *ctp++ = ct;
         } else {
-            advise (NULL, "unable to parse message from file %s", file);
+            inform("unable to parse message from file %s", file);
             status = NOTOK;
 
             /* If there's an outfile, pass the input message unchanged, so the
@@ -386,7 +375,7 @@ main (int argc, char **argv) {
                 }
 
                 if (copy_input_to_output (file, infp, outfile, outfp) != OK) {
-                    advise (NULL, "unable to copy message to %s, "
+                    inform("unable to copy message to %s, "
                             "it might be lost\n", outfile);
                 }
 
@@ -442,7 +431,7 @@ main (int argc, char **argv) {
                     set_text_ctparams(ct, fx.decodetypes, fx.lf_line_endings);
                     *ctp++ = ct;
                 } else {
-                    advise (NULL, "unable to parse message %s", msgnam);
+                    inform("unable to parse message %s", msgnam);
                     status = NOTOK;
 
                     /* If there's an outfile, pass the input message
@@ -465,10 +454,8 @@ main (int argc, char **argv) {
 
                         if (copy_input_to_output (input_filename, infp,
                                                   outfile, outfp) != OK) {
-                            advise (NULL,
-                                    "unable to copy message to %s, "
-                                    "it might be lost\n",
-                                    outfile);
+                            inform("unable to copy message to %s, "
+                                "it might be lost\n", outfile);
                         }
 
                         fclose (infp);
@@ -489,7 +476,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) {
@@ -505,7 +495,7 @@ main (int argc, char **argv) {
         status = 1;
     }
 
-    mh_xfree(maildir);
+    free(maildir);
     free (cts);
 
     if (fx.fixtypes != NULL) { svector_free (fx.fixtypes); }
@@ -516,7 +506,7 @@ main (int argc, char **argv) {
     free (folder);
     free (arguments);
 
-    done (status);
+    done (status == OK ? 0 : 1);
     return NOTOK;
 }
 
@@ -524,7 +514,7 @@ 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) {
     /* Store input filename in case one of the transformations, i.e.,
@@ -608,7 +598,7 @@ mhfixmsgsbr (CT *ctp, char *maildir, const fix_transformations *fx,
            to the output. */
         if (copy_input_to_output (input_filename, *infp, outfile,
                                   *outfp) != OK) {
-            advise (NULL, "unable to copy message to %s, it might be lost\n",
+            inform("unable to copy message to %s, it might be lost\n",
                     outfile);
         }
     }
@@ -692,16 +682,16 @@ fix_boundary (CT *ct, int *message_mods) {
                             }
                         } else {
                             *ct = NULL;
-                            advise (NULL, "unable to parse fixed part");
+                            inform("unable to parse fixed part");
                             status = NOTOK;
                         }
                         free (filename);
                     } else {
-                        advise (NULL, "unable to replace broken boundary");
+                        inform("unable to replace broken boundary");
                         status = NOTOK;
                     }
                 } else {
-                    advise (NULL, "unable to create temporary file in %s",
+                    inform("unable to create temporary file in %s",
                             get_temp_dir());
                     status = NOTOK;
                 }
@@ -767,11 +757,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. */
@@ -822,11 +810,11 @@ replace_boundary (CT ct, char *file, char *boundary) {
     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) {
-        advise (NULL, "missing input filename");
+        inform("missing input filename");
         return NOTOK;
     }
 
@@ -841,10 +829,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++;
@@ -856,7 +845,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 */
             }
 
@@ -871,13 +860,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);
@@ -898,12 +887,12 @@ replace_boundary (CT ct, char *file, char *boundary) {
 
         case LENERR:
         case FMTERR:
-            advise (NULL, "message format error in component #%d", compnum);
+            inform("message format error in component #%d", compnum);
             status = NOTOK;
             break;
 
         default:
-            advise (NULL, "getfld() returned %d", state);
+            inform("getfld() returned %d", state);
             status = NOTOK;
             break;
         }
@@ -985,7 +974,7 @@ fix_types (CT ct, svector_t fixtypes, int *message_mods) {
                             *cp = '\0';
                             ct_subtype = mh_xstrdup(++cp);
                         } else {
-                            advise (NULL, "missing / in MIME type of %s %s",
+                            inform("missing / in MIME type of %s %s",
                                     ct->c_file, ct->c_partno);
                             free (ct_type);
                             return NOTOK;
@@ -1000,7 +989,7 @@ fix_types (CT ct, svector_t fixtypes, int *message_mods) {
                         ct->c_ctinfo.ci_subtype = ct_subtype;
                         if (! replace_substring (&ct->c_ctline, type,
                                                  ct_type_subtype)) {
-                            advise (NULL, "did not find %s in %s",
+                            inform("did not find %s in %s",
                                     type, ct->c_ctline);
                         }
 
@@ -1017,10 +1006,8 @@ fix_types (CT ct, svector_t fixtypes, int *message_mods) {
                                                 type, ct_type_subtype);
                                     }
                                     break;
-                                } else {
-                                    advise (NULL, "did not find %s in %s",
-                                            type, hf->value);
                                 }
+                                inform("did not find %s in %s", type, hf->value);
                             }
                         }
                     }
@@ -1070,7 +1057,7 @@ replace_substring (char **str, const char *old, const char *new) {
 char *
 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;
@@ -1127,12 +1114,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;
 
@@ -1337,9 +1324,8 @@ ensure_text_plain (CT *ct, CT parent, int *message_mods, int replacetextplain) {
                         parent->c_ctinfo.ci_subtype = mh_xstrdup("alternative");
                         if (! replace_substring (&parent->c_ctline, "/related",
                                                  "/alternative")) {
-                            advise (NULL,
-                                    "did not find multipart/related in %s",
-                                    parent->c_ctline);
+                            inform("did not find multipart/related in %s",
+                                parent->c_ctline);
                         }
 
                         /* Update Content-Type header field. */
@@ -1358,11 +1344,9 @@ ensure_text_plain (CT *ct, CT parent, int *message_mods, int replacetextplain) {
                                        multipart/alternative. */
                                     remove_parameter (hf->value, "type");
                                     break;
-                                } else {
-                                    advise (NULL, "did not find multipart/"
-                                                  "related in header %s",
-                                            hf->value);
                                 }
+                                inform("did not find multipart/"
+                                    "related in header %s", hf->value);
                             }
                         }
                     } else {
@@ -1493,7 +1477,7 @@ build_text_plain_part (CT encoded_part) {
 
         /* This m_mktemp2() call closes the temp file. */
         if ((tempfile = m_mktemp2 (NULL, invo_name, NULL, NULL)) == NULL) {
-            advise (NULL, "unable to create temporary file in %s",
+            inform("unable to create temporary file in %s",
                     get_temp_dir());
         } else {
             tmp_plain_file = mh_xstrdup (tempfile);
@@ -1631,7 +1615,7 @@ decode_part (CT ct) {
     (void) m_unlink (tmp_decoded);
     free (tmp_decoded);
     if (fclose (file)) {
-        admonish (NULL, "unable to close temporary file %s", tempfile);
+        inform("unable to close temporary file %s, continuing...", tempfile);
     }
 
     return status;
@@ -1658,16 +1642,16 @@ reformat_part (CT ct, char *file, char *type, char *subtype, int c_type) {
     /* Check for invo_name-format-type/subtype. */
     if ((cf = context_find_by_type ("format", type, subtype)) == NULL) {
         if (verbosw) {
-            advise (NULL, "Don't know how to convert %s, there is no "
+            inform("Don't know how to convert %s, there is no "
                     "%s-format-%s/%s profile entry",
                     ct->c_file, invo_name, type, subtype);
         }
         return NOTOK;
     }
     if (strchr (cf, '>')) {
-        advise (NULL, "'>' prohibited in \"%s\",\nplease fix your "
+        inform("'>' prohibited in \"%s\",\nplease fix your "
                 "%s-format-%s/%s profile entry", cf, invo_name, type,
-                subtype ? subtype : "");
+                FENDNULL(subtype));
 
         return NOTOK;
     }
@@ -1758,8 +1742,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;
                 }
             }
 
@@ -1770,8 +1753,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;
                 }
             }
 
@@ -1784,15 +1766,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) {
-            advise (NULL, "giving up trying to find a unique boundary");
-            free_content (ct);
-            return NULL;
+            inform("giving up trying to find a unique boundary");
+            goto return_null;
         }
     }
 
@@ -1837,6 +1818,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;
 }
 
 
@@ -1878,7 +1864,7 @@ transfer_noncontent_headers (CT old, CT new) {
     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;
@@ -2027,8 +2013,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);
@@ -2042,8 +2027,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);
@@ -2062,7 +2046,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);
@@ -2169,13 +2153,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';
             }
         }
 
@@ -2258,7 +2243,7 @@ strip_crs (CT ct, int *message_mods) {
                         break;
                     }
 
-                    last_char_was_cr = *cp == '\r'  ?  1  :  0;
+                    last_char_was_cr = *cp == '\r';
                 }
             }
 
@@ -2304,16 +2289,17 @@ strip_crs (CT ct, int *message_mods) {
                 }
 
                 if (close (fd)) {
-                    admonish (NULL, "unable to write temporary file %s",
+                    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;
 
@@ -2599,7 +2585,7 @@ fix_filename_param (char *name, char *value, PM *first_pm, PM *last_pm) {
             replace_param (first_pm, last_pm, name, decoded, 0);
             fixed = 1;
         } else {
-            advise (NULL, "failed to decode %s parameter %s", name, value);
+            inform("failed to decode %s parameter %s", name, value);
         }
     }
 
@@ -2664,7 +2650,7 @@ fix_filename_encoding (CT ct) {
                 free((void *)new_params); /* Cast away const.  Sigh. */
                 free((void *)params);
             } else {
-                advise (NULL, "did not find semicolon in %s:%s\n",
+                inform("did not find semicolon in %s:%s\n",
                         hf->name, hf->value);
             }
         }
@@ -2719,15 +2705,15 @@ write_content (CT ct, const char *input_filename, char *outfile, FILE *outfp,
                                expand filename to absolute path. */
                             int file = ct->c_file  &&  ct->c_file[0] == '/';
 
-                            admonish (NULL, "unable to rename %s %s to %s",
+                            inform("unable to rename %s %s to %s, continuing...",
                                       file ? "file" : "message", outfile,
                                       infile);
                             status = NOTOK;
                         }
                     }
                 } else {
-                    admonish (NULL, "unable to remove input file %s, "
-                              "not modifying it", infile);
+                    inform("unable to remove input file %s, "
+                        "not modifying it, continuing...", infile);
                     (void) m_unlink (outfile);
                     status = NOTOK;
                 }
@@ -2818,7 +2804,7 @@ report (char *what, char *partno, char *filename, char *message, ...) {
     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);