]> diplodocus.org Git - nmh/blobdiff - uip/mhparse.c
cppflags.m4: Don't trample CFLAGS and CPPFLAGS.
[nmh] / uip / mhparse.c
index 238fc1a30d4cfe3c21f4a7a7760d5b9a4267aaa9..71405616cba9a7b0f5bd4b5a1008d936e36a0353 100644 (file)
@@ -13,6 +13,8 @@
 #include <h/mime.h>
 #include <h/mhparse.h>
 #include <h/utils.h>
+#include <h/mhcachesbr.h>
+#include "../sbr/m_mktemp.h"
 #include "mhfree.h"
 #ifdef HAVE_ICONV
 # include <iconv.h>
 
 extern int debugsw;
 
-/* cache policies */
-extern int rcachesw;   /* mhcachesbr.c */
-extern int wcachesw;   /* mhcachesbr.c */
-
 int checksw = 0;       /* check Content-MD5 field */
 
 /*
@@ -108,9 +106,6 @@ static struct k2v EncodingType[] = {
 };
 
 
-/* mhcachesbr.c */
-int find_cache (CT, int, int *, char *, char *, int);
-
 /* mhmisc.c */
 int part_ok (CT);
 int type_ok (CT, int);
@@ -300,7 +295,7 @@ get_content (FILE *in, char *file, int toplevel)
     char *np, *vp;
     CT ct;
     HF hp;
-    m_getfld_state_t gstate = 0;
+    m_getfld_state_t gstate;
 
     /* allocate the content structure */
     NEW0(ct);
@@ -312,10 +307,11 @@ get_content (FILE *in, char *file, int toplevel)
      * Parse the header fields for this
      * content into a linked list.
      */
-    m_getfld_track_filepos (&gstate, in);
+    gstate = m_getfld_state_init(in);
+    m_getfld_track_filepos2(&gstate);
     for (compnum = 1;;) {
        int bufsz = sizeof buf;
-       switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) {
+       switch (state = m_getfld2(&gstate, name, buf, &bufsz)) {
        case FLD:
        case FLDPLUS:
            compnum++;
@@ -327,7 +323,7 @@ get_content (FILE *in, char *file, int toplevel)
            /* if necessary, get rest of field */
            while (state == FLDPLUS) {
                bufsz = sizeof buf;
-               state = m_getfld (&gstate, name, buf, &bufsz, in);
+               state = m_getfld2(&gstate, name, buf, &bufsz);
                vp = add (buf, vp);     /* add to previous value */
            }
 
@@ -339,12 +335,25 @@ get_content (FILE *in, char *file, int toplevel)
            continue;
 
        case BODY:
+            /* There are two cases.  The unusual one is when there is no
+             * blank line between the headers and the body.  This is
+             * indicated by the name of the header starting with `:'.
+             *
+             * For both cases, normal first, `1' is the desired c_begin
+             * file position for the start of the body, and `2' is the
+             * file position when buf is returned.
+             *
+             *     f o o :   b a r \n \n b o d y \n    bufsz = 6
+             *                          1          2   move -5
+             *     f o o :   b a r \n b o d y \n       bufsz = 4
+             *                       1       2         move -4
+             *
+             * For the normal case, bufsz includes the
+             * header-terminating `\n', even though it is not in buf,
+             * but bufsz isn't affected when it's missing in the unusual
+             * case. */
            if (name[0] == ':') {
-               /* Special case:  no blank line between header and body.  The
-                  file position indicator is on the newline at the end of the
-                  line, but it needs to be one prior to the beginning of the
-                  line.  So subtract the length of the line, bufsz, plus 1. */
-               ct->c_begin = ftell (in) - (bufsz + 1);
+               ct->c_begin = ftell(in) - bufsz;
            } else {
                ct->c_begin = ftell (in) - (bufsz - 1);
            }
@@ -856,8 +865,8 @@ magic_skip:
            }
         }
        else
-           inform("extraneous information in message %s's %s: field\n%*s(%s)",
-                ct->c_file, TYPE_FIELD, strlen(invo_name) + 2, "", cp);
+            inform("extraneous information in message %s's %s: field\n"
+                "    (%s)", ct->c_file, TYPE_FIELD, cp);
     }
 
     return OK;
@@ -925,8 +934,8 @@ get_dispo (char *cp, CT ct, int buildflag)
            return NOTOK;
        }
     } else if (*cp) {
-       inform("extraneous information in message %s's %s: field\n%*s(%s)",
-            ct->c_file, DISPO_FIELD, strlen(invo_name) + 2, "", cp);
+        inform("extraneous information in message %s's %s: field\n    (%s)",
+            ct->c_file, DISPO_FIELD, cp);
     }
 
     if (buildflag)
@@ -1846,7 +1855,7 @@ openBase64 (CT ct, char **file)
 
         if (ct->c_digested) {
             if (memcmp(digest, ct->c_digest,
-                       sizeof(digest) / sizeof(digest[0]))) {
+                       sizeof digest)) {
                 content_error (NULL, ct,
                                "content integrity suspect (digest mismatch) -- continuing");
             } else {
@@ -2098,7 +2107,7 @@ openQuoted (CT ct, char **file)
 
        MD5Final (digest, &mdContext);
        if (memcmp((char *) digest, (char *) ct->c_digest,
-                  sizeof(digest) / sizeof(digest[0])))
+                  sizeof digest))
            content_error (NULL, ct,
                           "content integrity suspect (digest mismatch) -- continuing");
        else
@@ -2331,7 +2340,7 @@ openExternal (CT ct, CT cb, CE ce, char **file, int *fd)
         admonish (cachefile, "unable to fopen for reading");
     }
 
-    *fd = fileno (ce->ce_fp);
+    *fd = ce->ce_fp ? fileno (ce->ce_fp) : -1;
     return OK;
 
 ready_already:
@@ -2903,7 +2912,7 @@ readDigest (CT ct, char *cp)
 
     size_t len;
     if (decodeBase64 (cp, &digest, &len, 0, NULL) == OK) {
-        const size_t maxlen = sizeof ct->c_digest / sizeof ct->c_digest[0];
+        const size_t maxlen = sizeof ct->c_digest;
 
         if (strlen ((char *) digest) <= maxlen) {
             memcpy (ct->c_digest, digest, maxlen);
@@ -3296,9 +3305,9 @@ parse_header_attrs (const char *filename, const char *fieldname,
        for (up = dp; isspace ((unsigned char) *dp);)
            dp++;
        if (dp == cp || *dp != '=') {
-           inform("invalid parameter in message %s's %s: "
-                "field\n%*sparameter %s (error detected at offset %d)",
-                filename, fieldname, strlen(invo_name) + 2, "",cp, dp - cp);
+            inform("invalid parameter in message %s's %s: field\n"
+                "    parameter %s (error detected at offset %ld)",
+                filename, fieldname, cp, (long)(dp - cp));
            return NOTOK;
        }
 
@@ -3329,9 +3338,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                if (isdigit((unsigned char) *vp))
                    index = *vp - '0' + index * 10;
                else {
-                   inform("invalid parameter index in message %s's "
-                           "%s: field\n%*s(parameter %s)", filename,
-                           fieldname, strlen(invo_name) + 2, "", cp);
+                    inform("invalid parameter index in message %s's %s: field"
+                        "\n    (parameter %s)", filename, fieldname, cp);
                    return NOTOK;
                }
            } else {
@@ -3373,9 +3381,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                    }
                    vp++;
                } else {
-                   inform("missing charset in message %s's %s: "
-                          "field\n%*s(parameter %s)", filename, fieldname,
-                          strlen(invo_name) + 2, "", nameptr);
+                    inform("missing charset in message %s's %s: field\n"
+                        "    (parameter %s)", filename, fieldname, nameptr);
                    free(nameptr);
                    return NOTOK;
                }
@@ -3396,9 +3403,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                    }
                    vp++;
                } else {
-                   inform("missing language tag in message %s's %s: "
-                          "field\n%*s(parameter %s)", filename, fieldname,
-                          strlen(invo_name) + 2, "", nameptr);
+                    inform("missing language tag in message %s's %s: field\n"
+                        "    (parameter %s)", filename, fieldname, nameptr);
                    free(nameptr);
                     mh_xfree(charset);
                    return NOTOK;
@@ -3420,10 +3426,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                                !isxdigit((unsigned char) *(vp + 1)) ||
                                *(vp + 2) == '\0' ||
                                !isxdigit((unsigned char) *(vp + 2))) {
-                       inform("invalid encoded sequence in message "
-                              "%s's %s: field\n%*s(parameter %s)",
-                              filename, fieldname, strlen(invo_name) + 2,
-                              "", nameptr);
+                        inform("invalid encoded sequence in message %s's %s: field\n"
+                            "    (parameter %s)", filename, fieldname, nameptr);
                        free(nameptr);
                         mh_xfree(charset);
                         mh_xfree(lang);
@@ -3463,9 +3467,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                    switch (*cp++) {
                    case '\0':
 bad_quote:
-                       inform("invalid quoted-string in message %s's %s: "
-                            "field\n%*s(parameter %s)", filename,
-                            fieldname, strlen(invo_name) + 2, "", nameptr);
+                        inform("invalid quoted-string in message %s's %s: field\n"
+                            "    (parameter %s)", filename, fieldname, nameptr);
                        free(nameptr);
                         mh_xfree(charset);
                         mh_xfree(lang);
@@ -3549,10 +3552,9 @@ bad_quote:
            } else {
                for (sp2 = pp->sechead; sp2 != NULL; sp2 = sp2->next) {
                    if (sp2->index == sp->index) {
-                       inform("duplicate index (%d) in message "
-                               "%s's %s: field\n%*s(parameter %s)", sp->index,
-                               filename, fieldname, strlen(invo_name) + 2, "",
-                               nameptr);
+                        inform("duplicate index (%d) in message %s's %s: field"
+                            "\n    (parameter %s)", sp->index, filename,
+                            fieldname, nameptr);
                        return NOTOK;
                    }
                    if (sp2->index < sp->index &&
@@ -3564,10 +3566,9 @@ bad_quote:
                }
 
                if (sp2 == NULL) {
-                   inform("Internal error: cannot insert partial "
-                          "param in message %s's %s: field\n%*s(parameter %s)",
-                          filename, fieldname, strlen(invo_name) + 2, "",
-                          nameptr);
+                    inform("Internal error: cannot insert partial param "
+                        "in message %s's %s: field\n    (parameter %s)",
+                        filename, fieldname, nameptr);
                    return NOTOK;
                }
            }
@@ -3607,10 +3608,9 @@ bad_quote:
        int pindex = 0;
        for (sp = pp->sechead; sp != NULL; sp = sp->next) {
            if (sp->index != pindex++) {
-               inform("missing section %d for parameter in "
-                      "message %s's %s: field\n%*s(parameter %s)", pindex - 1,
-                      filename, fieldname, strlen(invo_name) + 2, "",
-                      pp->name);
+                inform("missing section %d for parameter in message "
+                    "%s's %s: field\n    (parameter %s)", pindex - 1,
+                    filename, fieldname, pp->name);
                return NOTOK;
            }
            tlen += sp->len;