X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/fb19d1fe7b522a05366f513387fef4456c336de8..b19b165203124e56cdcb89539efa6f93ed14f99d:/uip/mhparse.c diff --git a/uip/mhparse.c b/uip/mhparse.c index 58f3a81c..d12fbb30 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -80,6 +80,19 @@ struct k2v SubApplication[] = { { NULL, APPLICATION_UNKNOWN } /* this one must be last! */ }; +/* + * Mapping of names of CTE types in mhbuild directives + */ +static struct k2v EncodingType[] = { + { "8bit", CE_8BIT }, + { "qp", CE_QUOTED }, + { "q-p", CE_QUOTED }, + { "quoted-printable", CE_QUOTED }, + { "b64", CE_BASE64 }, + { "base64", CE_BASE64 }, + { NULL, 0 }, +}; + /* mhcachesbr.c */ int find_cache (CT, int, int *, char *, char *, int); @@ -205,12 +218,12 @@ parse_mime (char *file) fflush (fp); if (ferror (stdin)) { - unlink (file); + (void) m_unlink (file); advise ("stdin", "error reading"); return NULL; } if (ferror (fp)) { - unlink (file); + (void) m_unlink (file); advise (file, "error writing"); return NULL; } @@ -222,7 +235,7 @@ parse_mime (char *file) if (!(ct = get_content (fp, file, 1))) { if (is_stdin) - unlink (file); + (void) m_unlink (file); advise (NULL, "unable to decode %s", file); return NULL; } @@ -838,6 +851,47 @@ magic_skip: cp++; } + /* + * Get any extension directives (right now just the content transfer + * encoding, but maybe others) that we care about. + */ + + if (magic && *cp == '*') { + /* + * See if it's a CTE we match on + */ + struct k2v *kv; + + dp = ++cp; + while (*cp != '\0' && ! isspace((unsigned char) *cp)) + cp++; + + if (dp == cp) { + advise (NULL, "invalid null transfer encoding specification"); + return NOTOK; + } + + if (*cp != '\0') + *cp++ = '\0'; + + ct->c_reqencoding = CE_UNKNOWN; + + for (kv = EncodingType; kv->kv_key; kv++) { + if (strcasecmp(kv->kv_key, dp) == 0) { + ct->c_reqencoding = kv->kv_value; + break; + } + } + + if (ct->c_reqencoding == CE_UNKNOWN) { + advise (NULL, "invalid CTE specification: \"%s\"", dp); + return NOTOK; + } + + while (isspace ((unsigned char) *cp)) + cp++; + } + /* * Check if anything is left over */ @@ -1623,7 +1677,7 @@ static int openBase64 (CT ct, char **file) { int bitno, cc, digested; - int fd, len, skip, own_ct_fp = 0; + int fd, len, skip, own_ct_fp = 0, text = ct->c_type == CT_TEXT; uint32_t bits; unsigned char value, b; char *cp, *ep, buffer[BUFSIZ]; @@ -1735,17 +1789,20 @@ openBase64 (CT ct, char **file) test_end: if ((bitno -= 6) < 0) { b = (bits >> 16) & 0xff; - putc ((char) b, ce->ce_fp); + if (!text || b != '\r') + putc ((char) b, ce->ce_fp); if (digested) MD5Update (&mdContext, &b, 1); if (skip < 2) { b = (bits >> 8) & 0xff; - putc ((char) b, ce->ce_fp); + if (! text || b != '\r') + putc ((char) b, ce->ce_fp); if (digested) MD5Update (&mdContext, &b, 1); if (skip < 1) { b = bits & 0xff; - putc ((char) b, ce->ce_fp); + if (! text || b != '\r') + putc ((char) b, ce->ce_fp); if (digested) MD5Update (&mdContext, &b, 1); } @@ -2340,12 +2397,12 @@ openFile (CT ct, char **file) if (ferror (gp)) { admonish (ce->ce_file, "error reading"); - unlink (cachefile); + (void) m_unlink (cachefile); } else if (ferror (fp)) { admonish (cachefile, "error writing"); - unlink (cachefile); + (void) m_unlink (cachefile); } fclose (fp); } @@ -2556,12 +2613,12 @@ openFTP (CT ct, char **file) if (ferror (gp)) { admonish (ce->ce_file, "error reading"); - unlink (cachefile); + (void) m_unlink (cachefile); } else if (ferror (fp)) { admonish (cachefile, "error writing"); - unlink (cachefile); + (void) m_unlink (cachefile); } fclose (fp); } @@ -2831,7 +2888,7 @@ openURL (CT ct, char **file) if (ferror(gp)) { admonish(ce->ce_file, "error reading"); - unlink(cachefile); + (void) m_unlink (cachefile); } } umask(mask);