]> diplodocus.org Git - nmh/blobdiff - uip/mhparse.c
Add gcc's const function attribute.
[nmh] / uip / mhparse.c
index 238fc1a30d4cfe3c21f4a7a7760d5b9a4267aaa9..ca01545f3ffa9720dcb35fd36695902c1ef41e53 100644 (file)
@@ -13,6 +13,8 @@
 #include <h/mime.h>
 #include <h/mhparse.h>
 #include <h/utils.h>
 #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>
 #include "mhfree.h"
 #ifdef HAVE_ICONV
 # include <iconv.h>
 
 extern int debugsw;
 
 
 extern int debugsw;
 
-/* cache policies */
-extern int rcachesw;   /* mhcachesbr.c */
-extern int wcachesw;   /* mhcachesbr.c */
-
 int checksw = 0;       /* check Content-MD5 field */
 
 /*
 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);
 /* mhmisc.c */
 int part_ok (CT);
 int type_ok (CT, int);
@@ -178,7 +173,7 @@ struct str2init str2ces[] = {
 /*
  * NOTE WELL: si_key MUST NOT have value of NOTOK
  *
 /*
  * NOTE WELL: si_key MUST NOT have value of NOTOK
  *
- * si_key is 1 if access method is anonymous.
+ * si_val is 1 if access method is anonymous.
  */
 struct str2init str2methods[] = {
     { "afs",         1,        InitFile },
  */
 struct str2init str2methods[] = {
     { "afs",         1,        InitFile },
@@ -300,7 +295,7 @@ get_content (FILE *in, char *file, int toplevel)
     char *np, *vp;
     CT ct;
     HF hp;
     char *np, *vp;
     CT ct;
     HF hp;
-    m_getfld_state_t gstate = 0;
+    m_getfld_state_t gstate;
 
     /* allocate the content structure */
     NEW0(ct);
 
     /* 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.
      */
      * 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;
     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++;
        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;
            /* 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 */
            }
 
                vp = add (buf, vp);     /* add to previous value */
            }
 
@@ -339,12 +335,25 @@ get_content (FILE *in, char *file, int toplevel)
            continue;
 
        case BODY:
            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] == ':') {
            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);
            }
            } else {
                ct->c_begin = ftell (in) - (bufsz - 1);
            }
@@ -856,8 +865,8 @@ magic_skip:
            }
         }
        else
            }
         }
        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;
     }
 
     return OK;
@@ -925,8 +934,8 @@ get_dispo (char *cp, CT ct, int buildflag)
            return NOTOK;
        }
     } else if (*cp) {
            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)
     }
 
     if (buildflag)
@@ -1832,7 +1841,10 @@ openBase64 (CT ct, char **file)
     *cp = '\0';
 
     if (decodeBase64 (buffer, &decoded, &decoded_len, ct->c_type == CT_TEXT,
     *cp = '\0';
 
     if (decodeBase64 (buffer, &decoded, &decoded_len, ct->c_type == CT_TEXT,
-                      ct->c_digested ? digest : NULL) == OK) {
+                      ct->c_digested ? digest : NULL) != OK)
+        goto clean_up;
+
+    {
         size_t i;
         unsigned char *decoded_p = decoded;
         for (i = 0; i < decoded_len; ++i) {
         size_t i;
         unsigned char *decoded_p = decoded;
         for (i = 0; i < decoded_len; ++i) {
@@ -1846,7 +1858,7 @@ openBase64 (CT ct, char **file)
 
         if (ct->c_digested) {
             if (memcmp(digest, ct->c_digest,
 
         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 {
                 content_error (NULL, ct,
                                "content integrity suspect (digest mismatch) -- continuing");
             } else {
@@ -1855,8 +1867,6 @@ openBase64 (CT ct, char **file)
                 }
             }
         }
                 }
             }
         }
-    } else {
-        goto clean_up;
     }
 
     fseek (ct->c_fp, 0L, SEEK_SET);
     }
 
     fseek (ct->c_fp, 0L, SEEK_SET);
@@ -2098,12 +2108,11 @@ openQuoted (CT ct, char **file)
 
        MD5Final (digest, &mdContext);
        if (memcmp((char *) digest, (char *) ct->c_digest,
 
        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");
            content_error (NULL, ct,
                           "content integrity suspect (digest mismatch) -- continuing");
-       else
-           if (debugsw)
-               fprintf (stderr, "content integrity confirmed\n");
+       else if (debugsw)
+            fprintf (stderr, "content integrity confirmed\n");
     }
 
     fseek (ce->ce_fp, 0L, SEEK_SET);
     }
 
     fseek (ce->ce_fp, 0L, SEEK_SET);
@@ -2331,7 +2340,7 @@ openExternal (CT ct, CT cb, CE ce, char **file, int *fd)
         admonish (cachefile, "unable to fopen for reading");
     }
 
         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:
     return OK;
 
 ready_already:
@@ -2407,12 +2416,10 @@ openFile (CT ct, char **file)
            if (ferror (gp)) {
                admonish (ce->ce_file, "error reading");
                (void) m_unlink (cachefile);
            if (ferror (gp)) {
                admonish (ce->ce_file, "error reading");
                (void) m_unlink (cachefile);
-           }
-           else
-               if (ferror (fp)) {
-                   admonish (cachefile, "error writing");
-                   (void) m_unlink (cachefile);
-               }
+           } else if (ferror (fp)) {
+                admonish (cachefile, "error writing");
+                (void) m_unlink (cachefile);
+            }
            fclose (fp);
        }
        umask (mask);
            fclose (fp);
        }
        umask (mask);
@@ -2618,12 +2625,10 @@ openFTP (CT ct, char **file)
                if (ferror (gp)) {
                    admonish (ce->ce_file, "error reading");
                    (void) m_unlink (cachefile);
                if (ferror (gp)) {
                    admonish (ce->ce_file, "error reading");
                    (void) m_unlink (cachefile);
-               }
-               else
-                   if (ferror (fp)) {
-                       admonish (cachefile, "error writing");
-                       (void) m_unlink (cachefile);
-                   }
+               } else if (ferror (fp)) {
+                    admonish (cachefile, "error writing");
+                    (void) m_unlink (cachefile);
+                }
                fclose (fp);
            }
            umask (mask);
                fclose (fp);
            }
            umask (mask);
@@ -2888,7 +2893,7 @@ openURL (CT ct, char **file)
 
     fseeko(ce->ce_fp, 0, SEEK_SET);
     *file = ce->ce_file;
 
     fseeko(ce->ce_fp, 0, SEEK_SET);
     *file = ce->ce_file;
-    return fd;
+    return fileno(ce->ce_fp);
 }
 
 
 }
 
 
@@ -2903,7 +2908,7 @@ readDigest (CT ct, char *cp)
 
     size_t len;
     if (decodeBase64 (cp, &digest, &len, 0, NULL) == OK) {
 
     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);
 
         if (strlen ((char *) digest) <= maxlen) {
             memcpy (ct->c_digest, digest, maxlen);
@@ -3296,9 +3301,9 @@ parse_header_attrs (const char *filename, const char *fieldname,
        for (up = dp; isspace ((unsigned char) *dp);)
            dp++;
        if (dp == cp || *dp != '=') {
        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;
        }
 
            return NOTOK;
        }
 
@@ -3329,9 +3334,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                if (isdigit((unsigned char) *vp))
                    index = *vp - '0' + index * 10;
                else {
                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 {
                    return NOTOK;
                }
            } else {
@@ -3373,9 +3377,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                    }
                    vp++;
                } else {
                    }
                    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;
                }
                    free(nameptr);
                    return NOTOK;
                }
@@ -3396,9 +3399,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                    }
                    vp++;
                } else {
                    }
                    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;
                    free(nameptr);
                     mh_xfree(charset);
                    return NOTOK;
@@ -3420,10 +3422,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                                !isxdigit((unsigned char) *(vp + 1)) ||
                                *(vp + 2) == '\0' ||
                                !isxdigit((unsigned char) *(vp + 2))) {
                                !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);
                        free(nameptr);
                         mh_xfree(charset);
                         mh_xfree(lang);
@@ -3463,9 +3463,8 @@ parse_header_attrs (const char *filename, const char *fieldname,
                    switch (*cp++) {
                    case '\0':
 bad_quote:
                    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);
                        free(nameptr);
                         mh_xfree(charset);
                         mh_xfree(lang);
@@ -3549,10 +3548,9 @@ bad_quote:
            } else {
                for (sp2 = pp->sechead; sp2 != NULL; sp2 = sp2->next) {
                    if (sp2->index == sp->index) {
            } 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 &&
                        return NOTOK;
                    }
                    if (sp2->index < sp->index &&
@@ -3564,10 +3562,9 @@ bad_quote:
                }
 
                if (sp2 == NULL) {
                }
 
                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;
                }
            }
                    return NOTOK;
                }
            }
@@ -3607,10 +3604,9 @@ bad_quote:
        int pindex = 0;
        for (sp = pp->sechead; sp != NULL; sp = sp->next) {
            if (sp->index != pindex++) {
        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;
                return NOTOK;
            }
            tlen += sp->len;