]> diplodocus.org Git - nmh/blobdiff - uip/mhparse.c
Commit ddf3a8574f65 is a fix to commit af586ebe59b7.
[nmh] / uip / mhparse.c
index 7a8e88de1929a298f1f412326846f58578859174..cb9d2799e781949cc2ca6ce91fd93b0af3a67fee 100644 (file)
@@ -6,6 +6,11 @@
  */
 
 #include "h/mh.h"
+#include "sbr/m_gmprot.h"
+#include "sbr/m_getfld.h"
+#include "sbr/read_yes_or_no_if_tty.h"
+#include "sbr/concat.h"
+#include "sbr/r1bindex.h"
 #include "sbr/ruserpass.h"
 #include "sbr/fmt_rfc2047.h"
 #include "sbr/uprf.h"
 #include "sbr/arglist.h"
 #include "sbr/error.h"
 #include <fcntl.h>
-#include "h/md5.h"
 #include "h/mts.h"
 #include "h/tws.h"
 #include "h/mime.h"
 #include "h/mhparse.h"
 #include "h/utils.h"
 #include "mhmisc.h"
-#include "h/mhcachesbr.h"
 #include "sbr/m_mktemp.h"
 #include "mhfree.h"
 #ifdef HAVE_ICONV
@@ -34,8 +37,6 @@
 
 extern int debugsw;
 
-int checksw = 0;       /* check Content-MD5 field */
-
 /*
  * These are for mhfixmsg to:
  * 1) Instruct parser not to detect invalid Content-Transfer-Encoding
@@ -88,7 +89,6 @@ struct k2v SubMultiPart[] = {
  */
 struct k2v SubMessage[] = {
     { "rfc822",        MESSAGE_RFC822 },
-    { "partial",       MESSAGE_PARTIAL },
     { "external-body", MESSAGE_EXTERNAL },
     { NULL,            MESSAGE_UNKNOWN }       /* this one must be last! */
 };
@@ -136,14 +136,13 @@ static int openBase64 (CT, char **);
 static int InitQuoted (CT);
 static int openQuoted (CT, char **);
 static int Init7Bit (CT);
-static int openExternal (CT, CT, CE, char **, int *);
+static int openExternal (CT, CE, char **, int *);
 static int InitFile (CT);
 static int openFile (CT, char **);
 static int InitFTP (CT);
 static int openFTP (CT, char **);
 static int InitMail (CT);
 static int openMail (CT, char **);
-static int readDigest (CT, char *);
 static int get_leftover_mp_content (CT, int);
 static int InitURL (CT);
 static int openURL (CT, char **);
@@ -504,46 +503,6 @@ get_content (FILE *in, char *file, int toplevel)
            if (s2i->si_init && (*s2i->si_init) (ct) == NOTOK)
                goto out;
        }
-       else if (!strcasecmp (hp->name, MD5_FIELD)) {
-       /* Get Content-MD5 field */
-           char *cp, *dp, *ep;
-
-           if (!checksw)
-               goto next_header;
-
-           if (ct->c_digested) {
-               inform("message %s has multiple %s: fields",
-                       ct->c_file, MD5_FIELD);
-               goto next_header;
-           }
-
-           ep = cp = mh_xstrdup(FENDNULL(hp->value)); /* get a copy */
-
-           while (isspace ((unsigned char) *cp))
-               cp++;
-           for (dp = strchr(cp, '\n'); dp; dp = strchr(dp, '\n'))
-               *dp++ = ' ';
-           for (dp = cp + strlen (cp) - 1; dp >= cp; dp--)
-               if (!isspace ((unsigned char) *dp))
-                   break;
-           *++dp = '\0';
-           if (debugsw)
-               fprintf (stderr, "%s: %s\n", MD5_FIELD, cp);
-
-           if (*cp == '('  &&
-                get_comment (ct->c_file, MD5_FIELD, &cp, NULL) == NOTOK) {
-               free (ep);
-               goto out;
-           }
-
-           for (dp = cp; *dp && !isspace ((unsigned char) *dp); dp++)
-               continue;
-           *dp = '\0';
-
-           readDigest (ct, cp);
-           free (ep);
-           ct->c_digested++;
-       }
        else if (!strcasecmp (hp->name, ID_FIELD)) {
        /* Get Content-ID field */
            ct->c_id = add (hp->value, ct->c_id);
@@ -666,7 +625,7 @@ get_ctinfo (char *cp, CT ct, int magic)
        fprintf (stderr, "%s: %s\n", TYPE_FIELD, cp);
 
     if (*cp == '(' && get_comment (ct->c_file, TYPE_FIELD, &cp,
-                                  &ci->ci_comment) == NOTOK)
+                                  &ci->ci_comment) == NOTOK)
        return NOTOK;
 
     for (dp = cp; istoken (*dp); dp++)
@@ -688,7 +647,7 @@ get_ctinfo (char *cp, CT ct, int magic)
        cp++;
 
     if (*cp == '(' && get_comment (ct->c_file, TYPE_FIELD, &cp,
-                                  &ci->ci_comment) == NOTOK)
+                                  &ci->ci_comment) == NOTOK)
        return NOTOK;
 
     if (*cp != '/') {
@@ -702,7 +661,7 @@ get_ctinfo (char *cp, CT ct, int magic)
        cp++;
 
     if (*cp == '(' && get_comment (ct->c_file, TYPE_FIELD, &cp,
-                                  &ci->ci_comment) == NOTOK)
+                                  &ci->ci_comment) == NOTOK)
        return NOTOK;
 
     for (dp = cp; istoken (*dp); dp++)
@@ -725,11 +684,11 @@ magic_skip:
        cp++;
 
     if (*cp == '(' && get_comment (ct->c_file, TYPE_FIELD, &cp,
-                                  &ci->ci_comment) == NOTOK)
+                                  &ci->ci_comment) == NOTOK)
        return NOTOK;
 
     if ((status = parse_header_attrs (ct->c_file, TYPE_FIELD, &cp,
-                                     &ci->ci_first_pm, &ci->ci_last_pm,
+                                     &ci->ci_first_pm, &ci->ci_last_pm,
                                      &ci->ci_comment)) != OK) {
        return status == NOTOK ? NOTOK : OK;
     }
@@ -817,7 +776,7 @@ magic_skip:
      */
 
     if (magic && *cp == '*') {
-       /*
+       /*
         * See if it's a CTE we match on
         */
        struct k2v *kv;
@@ -915,7 +874,7 @@ get_dispo (char *cp, CT ct, int buildflag)
        fprintf (stderr, "%s: %s\n", DISPO_FIELD, cp);
 
     if (*cp == '(' && get_comment (ct->c_file, DISPO_FIELD, &cp, NULL) ==
-                                                       NOTOK) {
+                                                       NOTOK) {
        free(dispoheader);
        return NOTOK;
     }
@@ -932,7 +891,7 @@ get_dispo (char *cp, CT ct, int buildflag)
        return NOTOK;
 
     if ((status = parse_header_attrs (ct->c_file, DISPO_FIELD, &cp,
-                                     &ct->c_dispo_first, &ct->c_dispo_last,
+                                     &ct->c_dispo_first, &ct->c_dispo_last,
                                      NULL)) != OK) {
        if (status == NOTOK) {
            free(dispoheader);
@@ -944,7 +903,7 @@ get_dispo (char *cp, CT ct, int buildflag)
     }
 
     if (buildflag)
-       free(dispoheader);
+       free(dispoheader);
     else
        ct->c_dispo = dispoheader;
 
@@ -1193,6 +1152,23 @@ InitMultiPart (CT ct)
        pos += gotlen;
        if (bufp[0] != '-' || bufp[1] != '-')
            continue;
+
+       /*
+        * A bit of a lame hack; if this line ends in \r\n then replace
+        * the \r\n with just a \n so that the boundary markers will match
+        * up properly in case this uses "MS-DOS" line endings.
+        */
+
+       if (gotlen > 2 && bufp[gotlen - 1] == '\n' &&
+           bufp[gotlen - 2] == '\r') {
+               /*
+                * Note we don't change getpos here, because it is used to
+                * calculate multipart offsets.
+                */
+               bufp[gotlen - 2] = '\n';
+               bufp[gotlen - 1] = '\0';
+       }
+
        if (inout) {
            if (strcmp (bufp + 2, m->mp_start))
                continue;
@@ -1431,49 +1407,6 @@ InitMessage (CT ct)
        case MESSAGE_RFC822:
            break;
 
-       case MESSAGE_PARTIAL:
-           {
-               PM pm;
-               struct partial *p;
-
-               NEW0(p);
-               ct->c_ctparams = (void *) p;
-
-               /* scan for parameters "id", "number", and "total" */
-               for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
-                   if (!strcasecmp (pm->pm_name, "id")) {
-                       p->pm_partid = mh_xstrdup(FENDNULL(pm->pm_value));
-                       continue;
-                   }
-                   if (!strcasecmp (pm->pm_name, "number")) {
-                       if (sscanf (pm->pm_value, "%d", &p->pm_partno) != 1
-                               || p->pm_partno < 1) {
-invalid_param:
-                           inform("invalid %s parameter for \"%s/%s\" type in message %s's %s field",
-                                pm->pm_name, ci->ci_type, ci->ci_subtype,
-                                ct->c_file, TYPE_FIELD);
-                           return NOTOK;
-                       }
-                       continue;
-                   }
-                   if (!strcasecmp (pm->pm_name, "total")) {
-                       if (sscanf (pm->pm_value, "%d", &p->pm_maxno) != 1
-                               || p->pm_maxno < 1)
-                           goto invalid_param;
-                       continue;
-                   }
-               }
-
-               if (!p->pm_partid
-                       || !p->pm_partno
-                       || (p->pm_maxno && p->pm_partno > p->pm_maxno)) {
-                   inform("invalid parameters for \"%s/%s\" type in message %s's %s field",
-                        ci->ci_type, ci->ci_subtype, ct->c_file, TYPE_FIELD);
-                   return NOTOK;
-               }
-           }
-           break;
-
        case MESSAGE_EXTERNAL:
            {
                int exresult;
@@ -1639,7 +1572,7 @@ params_external (CT ct, int composing)
            e->eb_url = u = mh_xmalloc(strlen(pm->pm_value) + 1);
 
            for (; *p != '\0'; p++) {
-               if (! isspace((unsigned char) *p))
+               if (! isspace((unsigned char) *p))
                    *u++ = *p;
            }
 
@@ -1763,7 +1696,6 @@ openBase64 (CT ct, char **file)
     CE ce = &ct->c_cefile;
     unsigned char *decoded;
     size_t decoded_len;
-    unsigned char digest[16];
 
     if (ce->ce_fp) {
        fseek (ce->ce_fp, 0L, SEEK_SET);
@@ -1847,8 +1779,8 @@ openBase64 (CT ct, char **file)
     /* decodeBase64() requires null-terminated input. */
     *cp = '\0';
 
-    if (decodeBase64 (buffer, &decoded, &decoded_len, ct->c_type == CT_TEXT,
-                      ct->c_digested ? digest : NULL) != OK)
+    if (decodeBase64 (buffer, &decoded, &decoded_len,
+                     ct->c_type == CT_TEXT) != OK)
         goto clean_up;
 
     {
@@ -1862,18 +1794,6 @@ openBase64 (CT ct, char **file)
             content_error (ce->ce_file, ct, "error writing to");
             goto clean_up;
         }
-
-        if (ct->c_digested) {
-            if (memcmp(digest, ct->c_digest,
-                       sizeof digest)) {
-                content_error (NULL, ct,
-                               "content integrity suspect (digest mismatch) -- continuing");
-            } else {
-                if (debugsw) {
-                    fprintf (stderr, "content integrity confirmed\n");
-                }
-            }
-        }
     }
 
     fseek (ct->c_fp, 0L, SEEK_SET);
@@ -1939,7 +1859,7 @@ InitQuoted (CT ct)
 static int
 openQuoted (CT ct, char **file)
 {
-    int        cc, digested, len, quoted;
+    int        cc, len, quoted;
     bool own_ct_fp = false;
     char *cp, *ep;
     char *bufp = NULL;
@@ -1949,7 +1869,6 @@ openQuoted (CT ct, char **file)
     CE ce = &ct->c_cefile;
     /* sbeck -- handle suffixes */
     CI ci;
-    MD5_CTX mdContext;
 
     if (ce->ce_fp) {
        fseek (ce->ce_fp, 0L, SEEK_SET);
@@ -2008,9 +1927,6 @@ openQuoted (CT ct, char **file)
        own_ct_fp = true;
     }
 
-    if ((digested = ct->c_digested))
-       MD5Init (&mdContext);
-
     quoted = 0;
 
     fseek (ct->c_fp, ct->c_begin, SEEK_SET);
@@ -2043,8 +1959,6 @@ openQuoted (CT ct, char **file)
                    mask <<= 4;
                    mask |= hex2nib[((unsigned char) *cp) & 0x7f];
                    putc (mask, ce->ce_fp);
-                   if (digested)
-                       MD5Update (&mdContext, &mask, 1);
                    if (ferror (ce->ce_fp)) {
                        content_error (ce->ce_file, ct, "error writing to");
                        goto clean_up;
@@ -2082,13 +1996,6 @@ openQuoted (CT ct, char **file)
 
            /* Just show the raw byte. */
            putc (*cp, ce->ce_fp);
-           if (digested) {
-               if (*cp == '\n') {
-                   MD5Update (&mdContext, (unsigned char *) "\r\n",2);
-               } else {
-                   MD5Update (&mdContext, (unsigned char *) cp, 1);
-               }
-           }
            if (ferror (ce->ce_fp)) {
                content_error (ce->ce_file, ct, "error writing to");
                goto clean_up;
@@ -2108,18 +2015,6 @@ openQuoted (CT ct, char **file)
        goto clean_up;
     }
 
-    if (digested) {
-       unsigned char digest[16];
-
-       MD5Final (digest, &mdContext);
-       if (memcmp(digest, ct->c_digest,
-                  sizeof digest))
-           content_error (NULL, ct,
-                          "content integrity suspect (digest mismatch) -- continuing");
-       else if (debugsw)
-            fprintf (stderr, "content integrity confirmed\n");
-    }
-
     fseek (ce->ce_fp, 0L, SEEK_SET);
 
 ready_to_go:
@@ -2319,10 +2214,8 @@ clean_up:
  */
 
 static int
-openExternal (CT ct, CT cb, CE ce, char **file, int *fd)
+openExternal (CT ct, CE ce, char **file, int *fd)
 {
-    char cachefile[BUFSIZ];
-
     if (ce->ce_fp) {
        fseek (ce->ce_fp, 0L, SEEK_SET);
        goto ready_already;
@@ -2336,16 +2229,6 @@ openExternal (CT ct, CT cb, CE ce, char **file, int *fd)
        goto ready_already;
     }
 
-    if (find_cache(ct, rcachesw, NULL, cb->c_id,
-               cachefile, sizeof(cachefile)) != NOTOK) {
-       if ((ce->ce_fp = fopen (cachefile, "r"))) {
-           ce->ce_file = mh_xstrdup(cachefile);
-           ce->ce_unlink = 0;
-           goto ready_already;
-       }
-        admonish (cachefile, "unable to fopen for reading");
-    }
-
     *fd = ce->ce_fp ? fileno (ce->ce_fp) : -1;
     return OK;
 
@@ -2369,12 +2252,11 @@ InitFile (CT ct)
 static int
 openFile (CT ct, char **file)
 {
-    int        fd, cachetype;
-    char cachefile[BUFSIZ];
+    int        fd;
     struct exbody *e = ct->c_ctexbody;
     CE ce = &ct->c_cefile;
 
-    switch (openExternal (e->eb_parent, e->eb_content, ce, file, &fd)) {
+    switch (openExternal (e->eb_parent, ce, file, &fd)) {
        case NOTOK:
            return NOTOK;
 
@@ -2398,39 +2280,6 @@ openFile (CT ct, char **file)
        return NOTOK;
     }
 
-    if ((!e->eb_permission || strcasecmp (e->eb_permission, "read-write"))
-           && find_cache (NULL, wcachesw, &cachetype, e->eb_content->c_id,
-               cachefile, sizeof(cachefile)) != NOTOK) {
-       int mask;
-       FILE *fp;
-
-       mask = umask (cachetype ? ~m_gmprot () : 0222);
-       if ((fp = fopen (cachefile, "w"))) {
-           int cc;
-           char buffer[BUFSIZ];
-           FILE *gp = ce->ce_fp;
-
-           fseek (gp, 0L, SEEK_SET);
-
-           while ((cc = fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
-                      > 0)
-               if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) {
-                   advise ("openFile", "fwrite");
-               }
-           fflush (fp);
-
-           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);
-            }
-           fclose (fp);
-       }
-       umask (mask);
-    }
-
     fseek (ce->ce_fp, 0L, SEEK_SET);
     *file = ce->ce_file;
     return fileno (ce->ce_fp);
@@ -2450,12 +2299,10 @@ InitFTP (CT ct)
 static int
 openFTP (CT ct, char **file)
 {
-    int        cachetype;
-    bool caching;
     int fd;
     int len, buflen;
     char *bp, *ftp, *user, *pass;
-    char buffer[BUFSIZ], cachefile[BUFSIZ];
+    char buffer[BUFSIZ];
     struct exbody *e;
     CE ce = &ct->c_cefile;
     static char *username = NULL;
@@ -2469,7 +2316,7 @@ openFTP (CT ct, char **file)
     if (!ftp)
        return NOTOK;
 
-    switch (openExternal (e->eb_parent, e->eb_content, ce, file, &fd)) {
+    switch (openExternal (e->eb_parent, ce, file, &fd)) {
        case NOTOK:
            return NOTOK;
 
@@ -2527,7 +2374,7 @@ openFTP (CT ct, char **file)
 
     if (e->eb_flags) {
        user = "anonymous";
-       snprintf (buffer, sizeof(buffer), "%s@%s", getusername (),
+       snprintf (buffer, sizeof(buffer), "%s@%s", getusername (1),
                  LocalName (1));
        pass = buffer;
     } else {
@@ -2537,21 +2384,9 @@ openFTP (CT ct, char **file)
     }
 
     ce->ce_unlink = (*file == NULL);
-    caching = false;
-    cachefile[0] = '\0';
-    if ((!e->eb_permission || strcasecmp (e->eb_permission, "read-write"))
-           && find_cache (NULL, wcachesw, &cachetype, e->eb_content->c_id,
-               cachefile, sizeof(cachefile)) != NOTOK) {
-       if (*file == NULL) {
-           ce->ce_unlink = 0;
-           caching = true;
-       }
-    }
 
     if (*file)
        ce->ce_file = mh_xstrdup(*file);
-    else if (caching)
-       ce->ce_file = mh_xstrdup(cachefile);
     else {
        char *tempfile;
        if ((tempfile = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) {
@@ -2579,7 +2414,7 @@ openFTP (CT ct, char **file)
        vec[vecp++] = e->eb_name;
        vec[vecp++] = ce->ce_file,
        vec[vecp++] = e->eb_mode && !strcasecmp (e->eb_mode, "ascii")
-                       ? "ascii" : "binary";
+                       ? "ascii" : "binary";
        vec[vecp] = NULL;
 
        fflush (stdout);
@@ -2608,40 +2443,6 @@ openFTP (CT ct, char **file)
        }
     }
 
-    if (cachefile[0]) {
-       if (caching)
-           chmod (cachefile, cachetype ? m_gmprot () : 0444);
-       else {
-           int mask;
-           FILE *fp;
-
-           mask = umask (cachetype ? ~m_gmprot () : 0222);
-           if ((fp = fopen (cachefile, "w"))) {
-               int cc;
-               FILE *gp = ce->ce_fp;
-
-               fseek (gp, 0L, SEEK_SET);
-
-               while ((cc= fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
-                          > 0)
-                   if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) {
-                       advise ("openFTP", "fwrite");
-                   }
-               fflush (fp);
-
-               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);
-                }
-               fclose (fp);
-           }
-           umask (mask);
-       }
-    }
-
     fseek (ce->ce_fp, 0L, SEEK_SET);
     *file = ce->ce_file;
     return fileno (ce->ce_fp);
@@ -2668,7 +2469,7 @@ openMail (CT ct, char **file)
     struct exbody *e = ct->c_ctexbody;
     CE ce = &ct->c_cefile;
 
-    switch (openExternal (e->eb_parent, e->eb_content, ce, file, &fd)) {
+    switch (openExternal (e->eb_parent, ce, file, &fd)) {
        case NOTOK:
            return NOTOK;
 
@@ -2783,23 +2584,20 @@ openURL (CT ct, char **file)
     struct exbody *e = ct->c_ctexbody;
     CE ce = &ct->c_cefile;
     char *urlprog, *program;
-    char buffer[BUFSIZ], cachefile[BUFSIZ];
     int fd;
-    bool caching;
-    int cachetype;
     struct msgs_array args = { 0, 0, NULL};
     pid_t child_id;
 
     if ((urlprog = context_find(nmhaccessurl)) && *urlprog == '\0')
-       urlprog = NULL;
+       urlprog = NULL;
 
     if (! urlprog) {
-       content_error(NULL, ct, "No entry for nmh-access-url in profile");
-       return NOTOK;
+       content_error(NULL, ct, "No entry for nmh-access-url in profile");
+       return NOTOK;
     }
 
-    switch (openExternal(e->eb_parent, e->eb_content, ce, file, &fd)) {
-       case NOTOK:
+    switch (openExternal(e->eb_parent, ce, file, &fd)) {
+       case NOTOK:
            return NOTOK;
 
        case OK:
@@ -2810,26 +2608,14 @@ openURL (CT ct, char **file)
     }
 
     if (!e->eb_url) {
-       content_error(NULL, ct, "missing url parameter");
+       content_error(NULL, ct, "missing url parameter");
        return NOTOK;
     }
 
     ce->ce_unlink = (*file == NULL);
-    caching = false;
-    cachefile[0] = '\0';
-
-    if (find_cache(NULL, wcachesw, &cachetype, e->eb_content->c_id,
-                  cachefile, sizeof(cachefile)) != NOTOK) {
-       if (*file == NULL) {
-           ce->ce_unlink = 0;
-           caching = true;
-       }
-    }
 
     if (*file)
         ce->ce_file = mh_xstrdup(*file);
-    else if (caching)
-        ce->ce_file = mh_xstrdup(cachefile);
     else {
        char *tempfile;
        if ((tempfile = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) {
@@ -2840,17 +2626,17 @@ openURL (CT ct, char **file)
     }
 
     if ((ce->ce_fp = fopen(ce->ce_file, "w+")) == NULL) {
-       content_error(ce->ce_file, ct, "unable to fopen for read/writing");
+       content_error(ce->ce_file, ct, "unable to fopen for read/writing");
        return NOTOK;
     }
 
     switch (child_id = fork()) {
     case NOTOK:
-       adios ("fork", "unable to");
+       adios ("fork", "unable to");
        /* NOTREACHED */
 
     case OK:
-       argsplit_msgarg(&args, urlprog, &program);
+       argsplit_msgarg(&args, urlprog, &program);
        app_msgarg(&args, e->eb_url);
        app_msgarg(&args, NULL);
        dup2(fileno(ce->ce_fp), 1);
@@ -2862,89 +2648,18 @@ openURL (CT ct, char **file)
        /* NOTREACHED */
 
     default:
-       if (pidXwait(child_id, NULL)) {
+       if (pidXwait(child_id, NULL)) {
            ce->ce_unlink = 1;
            return NOTOK;
        }
     }
 
-    if (cachefile[0]) {
-       if (caching)
-           chmod(cachefile, cachetype ? m_gmprot() : 0444);
-       else {
-           int mask;
-           FILE *fp;
-
-           mask = umask (cachetype ? ~m_gmprot() : 0222);
-           if ((fp = fopen(cachefile, "w"))) {
-               int cc;
-               FILE *gp = ce->ce_fp;
-
-               fseeko(gp, 0, SEEK_SET);
-
-               while ((cc = fread(buffer, sizeof(*buffer),
-                                  sizeof(buffer), gp)) > 0)
-                   if ((int) fwrite(buffer, sizeof(*buffer), cc, fp) < cc) {
-                       advise ("openURL", "fwrite");
-                   }
-
-               fflush(fp);
-
-               if (ferror(gp)) {
-                   admonish(ce->ce_file, "error reading");
-                   (void) m_unlink (cachefile);
-               }
-           }
-           umask(mask);
-       }
-    }
-
     fseeko(ce->ce_fp, 0, SEEK_SET);
     *file = ce->ce_file;
     return fileno(ce->ce_fp);
 }
 
 
-/*
- * Stores MD5 digest (in cp, from Content-MD5 header) in ct->c_digest.  It
- * has to be base64 decoded.
- */
-static int
-readDigest (CT ct, char *cp)
-{
-    unsigned char *digest;
-
-    size_t len;
-    if (decodeBase64 (cp, &digest, &len, 0, NULL) == OK) {
-        const size_t maxlen = sizeof ct->c_digest;
-
-        if (strlen ((char *) digest) <= maxlen) {
-            memcpy (ct->c_digest, digest, maxlen);
-
-            if (debugsw) {
-                size_t i;
-
-                fprintf (stderr, "MD5 digest=");
-                for (i = 0; i < maxlen; ++i) {
-                    fprintf (stderr, "%02x", ct->c_digest[i] & 0xff);
-                }
-                fprintf (stderr, "\n");
-            }
-
-            return OK;
-        }
-        if (debugsw) {
-            fprintf (stderr, "invalid MD5 digest (got %d octets)\n",
-                     (int) strlen ((char *) digest));
-        }
-
-        return NOTOK;
-    }
-
-    return NOTOK;
-}
-
-
 /* Multipart parts might have content before the first subpart and/or
    after the last subpart that hasn't been stored anywhere else, so do
    that. */
@@ -3098,8 +2813,6 @@ ct_subtype_str (int type, int subtype)
         switch (subtype) {
         case MESSAGE_RFC822:
             return "rfc822";
-        case MESSAGE_PARTIAL:
-            return "partial";
         case MESSAGE_EXTERNAL:
             return "external";
         default:
@@ -3346,7 +3059,7 @@ parse_header_attrs (const char *filename, const char *fieldname,
                continue;
            }
             if (*vp == '*' && vp == up - 1) {
-               encoded = true;
+               encoded = true;
            } else if (partial) {
                if (isdigit((unsigned char) *vp))
                    index = *vp - '0' + index * 10;
@@ -3379,7 +3092,7 @@ parse_header_attrs (const char *filename, const char *fieldname,
             * parameter).
             */
            if (index == 0) {
-               vp = dp;
+               vp = dp;
                while (*vp != '\'' && !isspace((unsigned char) *vp) &&
                                                        *vp != '\0')
                    vp++;
@@ -3509,7 +3222,7 @@ bad_quote:
            valptr = mh_xmalloc(len + 1);
 
            if (*dp == '"') {
-               int i;
+               int i;
                for (cp = dp + 1, vp = valptr, i = 0; i < len; i++) {
                    if (*cp == '\\') {
                        cp++;
@@ -3518,7 +3231,7 @@ bad_quote:
                }
                cp++;
            } else {
-               strncpy(valptr, cp = dp, len);
+               strncpy(valptr, cp = dp, len);
                cp += len;
            }
 
@@ -3592,7 +3305,7 @@ bad_quote:
 
            if (index == 0 && encoded) {
                 free(pp->charset);
-               pp->charset = charset;
+               pp->charset = charset;
                 free(pp->lang);
                pp->lang = lang;
            }
@@ -3616,7 +3329,7 @@ bad_quote:
      */
 
     for (pp = phead; pp != NULL; ) {
-       char *p, *q;
+       char *p, *q;
        size_t tlen = 0;
        int pindex = 0;
        for (sp = pp->sechead; sp != NULL; sp = sp->next) {
@@ -3779,7 +3492,7 @@ output_params(size_t initialwidth, PM params, int *offsetout, int external)
 
        if (index > 0) {
            q += snprintf(q, sizeof(line) - (q - line), "%s*%d",
-                         params->pm_name, index);
+                         params->pm_name, index);
        } else {
            strncpy(q, params->pm_name, sizeof(line) - (q - line));
            q += strlen(q);
@@ -3787,10 +3500,10 @@ output_params(size_t initialwidth, PM params, int *offsetout, int external)
 
        if (encode)
            i = encode_param(params, q, sizeof(line) - (q - line),
-                            strlen(params->pm_value + valoff), valoff, index);
+                            strlen(params->pm_value + valoff), valoff, index);
        else
            i = normal_param(params, q, sizeof(line) - (q - line),
-                            strlen(params->pm_value + valoff), valoff);
+                            strlen(params->pm_value + valoff), valoff);
 
        if (i == 0) {
             free(paramout);
@@ -3918,7 +3631,7 @@ param_len(PM pm, int index, size_t valueoff, int *encode, int *cont,
                len += 3;
                maxfit -= 3;
            } else {
-               len++;
+               len++;
                maxfit--;
            }
            /*
@@ -3931,7 +3644,7 @@ param_len(PM pm, int index, size_t valueoff, int *encode, int *cont,
                fitlimit++;
        }
     } else {
-       /*
+       /*
         * Calculate the string length, but add room for quoting \
         * and " if necessary.  Also account for quotes at beginning
         * and end.
@@ -3940,7 +3653,7 @@ param_len(PM pm, int index, size_t valueoff, int *encode, int *cont,
            switch (*p) {
            case '"':
            case '\\':
-               len++;
+               len++;
                maxfit--;
            /* FALLTHRU */
            default:
@@ -4089,7 +3802,7 @@ add_param(PM *first, PM *last, char *name, char *value, int nocopy)
        (*last)->pm_next = pm;
        *last = pm;
     } else {
-       *first = pm;
+       *first = pm;
        *last = pm;
     }
 
@@ -4134,7 +3847,7 @@ get_param(PM first, const char *name, char replace, int fetchonly)
     while (first != NULL) {
        if (strcasecmp(name, first->pm_name) == 0) {
            if (fetchonly)
-               return first->pm_value;
+               return first->pm_value;
             return getcpy(get_param_value(first, replace));
        }
        first = first->pm_next;
@@ -4171,7 +3884,7 @@ get_param_value(PM pm, char replace)
      */
 
     if (!pm->pm_charset || check_charset(pm->pm_charset,
-                                        strlen(pm->pm_charset))) {
+                                        strlen(pm->pm_charset))) {
        return pm->pm_value;
     }