X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fmhparse.c;h=8d3397ef120638b5761e6e9e38504de2cfb0de84;hp=1839a15ddd544b78a204e254fee8ff2e3668f80e;hb=d2f12554a254e814dcdafb3828fc0d9936154eef;hpb=1691e80890e5d8ba258c51c214a3e91880e1db2b diff --git a/uip/mhparse.c b/uip/mhparse.c index 1839a15..8d3397e 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -3,6 +3,10 @@ * mhparse.c -- routines to parse the contents of MIME messages * * $Id$ + * + * This code is Copyright (c) 2002, by the authors of nmh. See the + * COPYRIGHT file in the root directory of the nmh distribution for + * complete copyright information. */ #include @@ -12,17 +16,17 @@ #include #include #include -#include -#include +#include +#include #include #include +#include #ifdef HAVE_SYS_WAIT_H # include #endif -extern int errno; extern int debugsw; extern int endian; /* mhmisc.c */ @@ -177,7 +181,7 @@ static struct str2init str2ces[] = { { "quoted-printable", CE_QUOTED, InitQuoted }, { "8bit", CE_8BIT, Init7Bit }, { "7bit", CE_7BIT, Init7Bit }, - { "binary", CE_BINARY, NULL }, + { "binary", CE_BINARY, Init7Bit }, { NULL, CE_EXTENSION, NULL }, /* these two must be last! */ { NULL, CE_UNKNOWN, NULL }, }; @@ -205,8 +209,7 @@ pidcheck (int status) fflush (stdout); fflush (stderr); - done (1); - /* NOTREACHED */ + return done (1); } @@ -257,7 +260,6 @@ parse_mime (char *file) if (!(ct = get_content (fp, file, 1))) { if (is_stdin) unlink (file); - fclose (fp); advise (NULL, "unable to decode %s", file); return NULL; } @@ -291,6 +293,7 @@ parse_mime (char *file) * toplevel = 0 # we are inside message type or multipart type * # other than multipart/digest * toplevel = -1 # we are inside multipart/digest + * NB: on failure we will fclose(in)! */ static CT @@ -372,7 +375,7 @@ get_content (FILE *in, char *file, int toplevel) hp = ct->c_first_hf; /* start at first header field */ while (hp) { /* Get MIME-Version field */ - if (!strcasecmp (hp->name, VRSN_FIELD)) { + if (!mh_strcasecmp (hp->name, VRSN_FIELD)) { int ucmp; char c, *cp, *dp; @@ -404,14 +407,14 @@ get_content (FILE *in, char *file, int toplevel) continue; c = *dp; *dp = '\0'; - ucmp = !strcasecmp (cp, VRSN_VALUE); + ucmp = !mh_strcasecmp (cp, VRSN_VALUE); *dp = c; if (!ucmp) { admonish (NULL, "message %s has unknown value for %s: field (%s)", ct->c_file, VRSN_FIELD, cp); } } - else if (!strcasecmp (hp->name, TYPE_FIELD)) { + else if (!mh_strcasecmp (hp->name, TYPE_FIELD)) { /* Get Content-Type field */ struct str2init *s2i; CI ci = &ct->c_ctinfo; @@ -432,14 +435,14 @@ get_content (FILE *in, char *file, int toplevel) * flag for this content type. */ for (s2i = str2cts; s2i->si_key; s2i++) - if (!strcasecmp (ci->ci_type, s2i->si_key)) + if (!mh_strcasecmp (ci->ci_type, s2i->si_key)) break; if (!s2i->si_key && !uprf (ci->ci_type, "X-")) s2i++; ct->c_type = s2i->si_val; ct->c_ctinitfnx = s2i->si_init; } - else if (!strcasecmp (hp->name, ENCODING_FIELD)) { + else if (!mh_strcasecmp (hp->name, ENCODING_FIELD)) { /* Get Content-Transfer-Encoding field */ char c, *cp, *dp; struct str2init *s2i; @@ -469,7 +472,7 @@ get_content (FILE *in, char *file, int toplevel) * for this transfer encoding. */ for (s2i = str2ces; s2i->si_key; s2i++) - if (!strcasecmp (cp, s2i->si_key)) + if (!mh_strcasecmp (cp, s2i->si_key)) break; if (!s2i->si_key && !uprf (cp, "X-")) s2i++; @@ -480,7 +483,7 @@ 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)) { + else if (!mh_strcasecmp (hp->name, MD5_FIELD)) { /* Get Content-MD5 field */ char *cp, *dp, *ep; @@ -519,11 +522,11 @@ get_content (FILE *in, char *file, int toplevel) free (ep); ct->c_digested++; } - else if (!strcasecmp (hp->name, ID_FIELD)) { + else if (!mh_strcasecmp (hp->name, ID_FIELD)) { /* Get Content-ID field */ ct->c_id = add (hp->value, ct->c_id); } - else if (!strcasecmp (hp->name, DESCR_FIELD)) { + else if (!mh_strcasecmp (hp->name, DESCR_FIELD)) { /* Get Content-Description field */ ct->c_descr = add (hp->value, ct->c_descr); } @@ -582,8 +585,7 @@ add_header (CT ct, char *name, char *value) HF hp; /* allocate header field structure */ - if (!(hp = malloc (sizeof(*hp)))) - adios (NULL, "out of memory"); + hp = mh_xmalloc (sizeof(*hp)); /* link data into header structure */ hp->name = name; @@ -905,7 +907,7 @@ InitText (CT ct) /* match subtype */ for (kv = SubText; kv->kv_key; kv++) - if (!strcasecmp (ci->ci_subtype, kv->kv_key)) + if (!mh_strcasecmp (ci->ci_subtype, kv->kv_key)) break; ct->c_subtype = kv->kv_value; @@ -916,7 +918,7 @@ InitText (CT ct) /* scan for charset parameter */ for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) - if (!strcasecmp (*ap, "charset")) + if (!mh_strcasecmp (*ap, "charset")) break; if (*ap) @@ -926,7 +928,7 @@ InitText (CT ct) /* match character set, or set to unknown */ for (kv = Charset; kv->kv_key; kv++) - if (!strcasecmp (chset, kv->kv_key)) + if (!mh_strcasecmp (chset, kv->kv_key)) break; t->tx_charset = kv->kv_value; @@ -977,7 +979,7 @@ InitMultiPart (CT ct) /* match subtype */ for (kv = SubMultiPart; kv->kv_key; kv++) - if (!strcasecmp (ci->ci_subtype, kv->kv_key)) + if (!mh_strcasecmp (ci->ci_subtype, kv->kv_key)) break; ct->c_subtype = kv->kv_value; @@ -985,8 +987,9 @@ InitMultiPart (CT ct) * Check for "boundary" parameter, which is * required for multipart messages. */ + bp = 0; for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - if (!strcasecmp (*ap, "boundary")) { + if (!mh_strcasecmp (*ap, "boundary")) { bp = *ep; break; } @@ -1053,7 +1056,6 @@ next_part: if (!(p = get_content (fp, ct->c_file, ct->c_subtype == MULTI_DIGEST ? -1 : 0))) { - fclose (ct->c_fp); ct->c_fp = NULL; return NOTOK; } @@ -1194,9 +1196,9 @@ InitMessage (CT ct) struct k2v *kv; CI ci = &ct->c_ctinfo; - if (ct->c_encoding != CE_7BIT) { + if ((ct->c_encoding != CE_7BIT) && (ct->c_encoding != CE_8BIT)) { admonish (NULL, - "\"%s/%s\" type in message %s should be encoded in 7bit", + "\"%s/%s\" type in message %s should be encoded in 7bit or 8bit", ci->ci_type, ci->ci_subtype, ct->c_file); return NOTOK; } @@ -1207,7 +1209,7 @@ InitMessage (CT ct) /* match subtype */ for (kv = SubMessage; kv->kv_key; kv++) - if (!strcasecmp (ci->ci_subtype, kv->kv_key)) + if (!mh_strcasecmp (ci->ci_subtype, kv->kv_key)) break; ct->c_subtype = kv->kv_value; @@ -1226,11 +1228,11 @@ InitMessage (CT ct) /* scan for parameters "id", "number", and "total" */ for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - if (!strcasecmp (*ap, "id")) { + if (!mh_strcasecmp (*ap, "id")) { p->pm_partid = add (*ep, NULL); continue; } - if (!strcasecmp (*ap, "number")) { + if (!mh_strcasecmp (*ap, "number")) { if (sscanf (*ep, "%d", &p->pm_partno) != 1 || p->pm_partno < 1) { invalid_param: @@ -1242,7 +1244,7 @@ invalid_param: } continue; } - if (!strcasecmp (*ap, "total")) { + if (!mh_strcasecmp (*ap, "total")) { if (sscanf (*ep, "%d", &p->pm_maxno) != 1 || p->pm_maxno < 1) goto invalid_param; @@ -1282,7 +1284,6 @@ invalid_param: fseek (fp = ct->c_fp, ct->c_begin, SEEK_SET); if (!(p = get_content (fp, ct->c_file, 0))) { - fclose (ct->c_fp); ct->c_fp = NULL; return NOTOK; } @@ -1302,8 +1303,7 @@ invalid_param: goto no_body; } - if ((e->eb_body = bp = malloc ((unsigned) size)) == NULL) - adios (NULL, "out of memory"); + e->eb_body = bp = mh_xmalloc ((unsigned) size); fseek (p->c_fp, p->c_begin, SEEK_SET); while (size > 0) switch (cc = fread (bp, sizeof(*bp), size, p->c_fp)) { @@ -1364,12 +1364,12 @@ params_external (CT ct, int composing) CI ci = &ct->c_ctinfo; for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - if (!strcasecmp (*ap, "access-type")) { + if (!mh_strcasecmp (*ap, "access-type")) { struct str2init *s2i; CT p = e->eb_content; for (s2i = str2methods; s2i->si_key; s2i++) - if (!strcasecmp (*ep, s2i->si_key)) + if (!mh_strcasecmp (*ep, s2i->si_key)) break; if (!s2i->si_key) { e->eb_access = *ep; @@ -1386,39 +1386,39 @@ params_external (CT ct, int composing) return NOTOK; continue; } - if (!strcasecmp (*ap, "name")) { + if (!mh_strcasecmp (*ap, "name")) { e->eb_name = *ep; continue; } - if (!strcasecmp (*ap, "permission")) { + if (!mh_strcasecmp (*ap, "permission")) { e->eb_permission = *ep; continue; } - if (!strcasecmp (*ap, "site")) { + if (!mh_strcasecmp (*ap, "site")) { e->eb_site = *ep; continue; } - if (!strcasecmp (*ap, "directory")) { + if (!mh_strcasecmp (*ap, "directory")) { e->eb_dir = *ep; continue; } - if (!strcasecmp (*ap, "mode")) { + if (!mh_strcasecmp (*ap, "mode")) { e->eb_mode = *ep; continue; } - if (!strcasecmp (*ap, "size")) { + if (!mh_strcasecmp (*ap, "size")) { sscanf (*ep, "%lu", &e->eb_size); continue; } - if (!strcasecmp (*ap, "server")) { + if (!mh_strcasecmp (*ap, "server")) { e->eb_server = *ep; continue; } - if (!strcasecmp (*ap, "subject")) { + if (!mh_strcasecmp (*ap, "subject")) { e->eb_subject = *ep; continue; } - if (composing && !strcasecmp (*ap, "body")) { + if (composing && !mh_strcasecmp (*ap, "body")) { e->eb_body = getcpy (*ep); continue; } @@ -1447,7 +1447,7 @@ InitApplication (CT ct) /* match subtype */ for (kv = SubApplication; kv->kv_key; kv++) - if (!strcasecmp (ci->ci_subtype, kv->kv_key)) + if (!mh_strcasecmp (ci->ci_subtype, kv->kv_key)) break; ct->c_subtype = kv->kv_value; @@ -1569,6 +1569,8 @@ openBase64 (CT ct, char **file) unsigned long bits; unsigned char value, *b, *b1, *b2, *b3; char *cp, *ep, buffer[BUFSIZ]; + /* sbeck -- handle prefixes */ + CI ci; CE ce; MD5_CTX mdContext; @@ -1599,6 +1601,19 @@ openBase64 (CT ct, char **file) ce->ce_unlink = 0; } + /* sbeck@cise.ufl.edu -- handle suffixes */ + ci = &ct->c_ctinfo; + snprintf (buffer, sizeof(buffer), "%s-suffix-%s/%s", + invo_name, ci->ci_type, ci->ci_subtype); + cp = context_find (buffer); + if (cp == NULL || *cp == '\0') { + snprintf (buffer, sizeof(buffer), "%s-suffix-%s", invo_name, + ci->ci_type); + cp = context_find (buffer); + } + if (cp != NULL && *cp != '\0') + ce->ce_file = add (cp, ce->ce_file); + if ((ce->ce_fp = fopen (ce->ce_file, "w+")) == NULL) { content_error (ce->ce_file, ct, "unable to fopen for reading/writing"); return NOTOK; @@ -1768,6 +1783,8 @@ openQuoted (CT ct, char **file) char buffer[BUFSIZ]; unsigned char mask; CE ce; + /* sbeck -- handle prefixes */ + CI ci; MD5_CTX mdContext; ce = ct->c_cefile; @@ -1792,6 +1809,24 @@ openQuoted (CT ct, char **file) ce->ce_unlink = 0; } + /* sbeck@cise.ufl.edu -- handle suffixes */ + ci = &ct->c_ctinfo; + snprintf (buffer, sizeof(buffer), "%s-suffix-%s/%s", + invo_name, ci->ci_type, ci->ci_subtype); + cp = context_find (buffer); + if (cp == NULL || *cp == '\0') { + snprintf (buffer, sizeof(buffer), "%s-suffix-%s", invo_name, + ci->ci_type); + cp = context_find (buffer); + } + if (cp != NULL && *cp != '\0') + ce->ce_file = add (cp, ce->ce_file); + + if ((ce->ce_fp = fopen (ce->ce_file, "w+")) == NULL) { + content_error (ce->ce_file, ct, "unable to fopen for reading/writing"); + return NOTOK; + } + if ((ce->ce_fp = fopen (ce->ce_file, "w+")) == NULL) { content_error (ce->ce_file, ct, "unable to fopen for reading/writing"); return NOTOK; @@ -1966,6 +2001,9 @@ open7Bit (CT ct, char **file) { int cc, fd, len; char buffer[BUFSIZ]; + /* sbeck -- handle prefixes */ + char *cp; + CI ci; CE ce; ce = ct->c_cefile; @@ -1990,6 +2028,19 @@ open7Bit (CT ct, char **file) ce->ce_unlink = 0; } + /* sbeck@cise.ufl.edu -- handle suffixes */ + ci = &ct->c_ctinfo; + snprintf (buffer, sizeof(buffer), "%s-suffix-%s/%s", + invo_name, ci->ci_type, ci->ci_subtype); + cp = context_find (buffer); + if (cp == NULL || *cp == '\0') { + snprintf (buffer, sizeof(buffer), "%s-suffix-%s", invo_name, + ci->ci_type); + cp = context_find (buffer); + } + if (cp != NULL && *cp != '\0') + ce->ce_file = add (cp, ce->ce_file); + if ((ce->ce_fp = fopen (ce->ce_file, "w+")) == NULL) { content_error (ce->ce_file, ct, "unable to fopen for reading/writing"); return NOTOK; @@ -2174,7 +2225,7 @@ openFile (CT ct, char **file) return NOTOK; } - if ((!e->eb_permission || strcasecmp (e->eb_permission, "read-write")) + if ((!e->eb_permission || mh_strcasecmp (e->eb_permission, "read-write")) && find_cache (NULL, wcachesw, &cachetype, e->eb_content->c_id, cachefile, sizeof(cachefile)) != NOTOK) { int mask; @@ -2322,7 +2373,7 @@ openFTP (CT ct, char **file) ce->ce_unlink = (*file == NULL); caching = 0; cachefile[0] = '\0'; - if ((!e->eb_permission || strcasecmp (e->eb_permission, "read-write")) + if ((!e->eb_permission || mh_strcasecmp (e->eb_permission, "read-write")) && find_cache (NULL, wcachesw, &cachetype, e->eb_content->c_id, cachefile, sizeof(cachefile)) != NOTOK) { if (*file == NULL) { @@ -2358,7 +2409,7 @@ openFTP (CT ct, char **file) vec[vecp++] = e->eb_dir; vec[vecp++] = e->eb_name; vec[vecp++] = ce->ce_file, - vec[vecp++] = e->eb_mode && !strcasecmp (e->eb_mode, "ascii") + vec[vecp++] = e->eb_mode && !mh_strcasecmp (e->eb_mode, "ascii") ? "ascii" : "binary"; vec[vecp] = NULL; @@ -2395,12 +2446,12 @@ losing_ftp: else if (ftp_get (e->eb_site, user, pass, e->eb_dir, e->eb_name, ce->ce_file, - e->eb_mode && !strcasecmp (e->eb_mode, "ascii"), 0) + e->eb_mode && !mh_strcasecmp (e->eb_mode, "ascii"), 0) == NOTOK) goto losing_ftp; #endif - if (cachefile[0]) + if (cachefile[0]) { if (caching) chmod (cachefile, cachetype ? m_gmprot () : 0444); else { @@ -2414,7 +2465,7 @@ losing_ftp: fseek (gp, 0L, SEEK_SET); - while ((cc = fread (buffer, sizeof(*buffer), sizeof(buffer), gp)) + while ((cc= fread (buffer, sizeof(*buffer), sizeof(buffer), gp)) > 0) fwrite (buffer, sizeof(*buffer), cc, fp); fflush (fp); @@ -2432,6 +2483,7 @@ losing_ftp: } umask (mask); } + } fseek (ce->ce_fp, 0L, SEEK_SET); *file = ce->ce_file;