X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/e2eebc77cc570f77d906bc0cc6890092068468cb..f345b9b480296b4b6a8469d6221752893c5d1420:/uip/mhparse.c?ds=inline diff --git a/uip/mhparse.c b/uip/mhparse.c index a3a80f9a..ca5558ae 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -42,6 +41,13 @@ int suppress_bogus_mp_content_warning; int bogus_mp_content; int suppress_extraneous_trailing_semicolon_warning; int extraneous_trailing_semicolon; +int suppress_multiple_mime_version_warning = 1; + +/* list of preferred type/subtype pairs, for -prefer */ +char *preferred_types[NPREFS], + *preferred_subtypes[NPREFS]; +int npreferred; + /* * Structures for TEXT messages @@ -104,7 +110,7 @@ static struct k2v EncodingType[] = { int find_cache (CT, int, int *, char *, char *, int); /* mhmisc.c */ -int part_ok (CT, int); +int part_ok (CT); int type_ok (CT, int); void content_error (char *, CT, char *, ...); @@ -121,6 +127,7 @@ static int InitGeneric (CT); static int InitText (CT); static int InitMultiPart (CT); static void reverse_parts (CT); +static void prefer_parts(CT ct); static int InitMessage (CT); static int InitApplication (CT); static int init_encoding (CT, OpenCEFunc); @@ -359,16 +366,12 @@ get_content (FILE *in, char *file, int toplevel) if (!strcasecmp (hp->name, VRSN_FIELD)) { int ucmp; char c, *cp, *dp; + char *vrsn; - if (ct->c_vrsn) { - advise (NULL, "message %s has multiple %s: fields", - ct->c_file, VRSN_FIELD); - goto next_header; - } - ct->c_vrsn = add (hp->value, NULL); + vrsn = add (hp->value, NULL); /* Now, cleanup this field */ - cp = ct->c_vrsn; + cp = vrsn; while (isspace ((unsigned char) *cp)) cp++; @@ -395,6 +398,14 @@ get_content (FILE *in, char *file, int toplevel) admonish (NULL, "message %s has unknown value for %s: field (%s)", ct->c_file, VRSN_FIELD, cp); } + if (!ct->c_vrsn) { + ct->c_vrsn = vrsn; + } else { + if (! suppress_multiple_mime_version_warning) + advise (NULL, "message %s has multiple %s: fields", + ct->c_file, VRSN_FIELD); + free(vrsn); + } } else if (!strcasecmp (hp->name, TYPE_FIELD)) { /* Get Content-Type field */ @@ -1090,8 +1101,9 @@ InitMultiPart (CT ct) admonish (NULL, "\"%s/%s\" type in message %s must be encoded in\n" - "7bit, 8bit, or binary, per RFC 2045 (6.4). One workaround " - "is to\nmanually edit the file and change the \"%s\"\n" + "7bit, 8bit, or binary, per RFC 2045 (6.4). " + "mhfixmsg -fixcte can fix it, or\n" + "manually edit the file and change the \"%s\"\n" "Content-Transfer-Encoding to one of those. For now", ci->ci_type, ci->ci_subtype, ct->c_file, bp); free (cte); @@ -1223,8 +1235,10 @@ end_part: last_part: /* reverse the order of the parts for multipart/alternative */ - if (ct->c_subtype == MULTI_ALTERNATE) + if (ct->c_subtype == MULTI_ALTERNATE) { reverse_parts (ct); + prefer_parts (ct); + } /* * label all subparts with part number, and @@ -1270,9 +1284,15 @@ last_part: /* - * reverse the order of the parts of a multipart/alternative + * reverse the order of the parts of a multipart/alternative, + * presumably to put the "most favored" alternative first, for + * ease of choosing/displaying it later on. from a mail message on + * nmh-workers, from kenh: + * "Stock" MH 6.8.5 did not have a reverse_parts() function, but I + * see code in mhn that did the same thing... Acccording to the RCS + * logs, that code was around from the initial checkin of mhn.c by + * John Romine in 1992, which is as far back as we have." */ - static void reverse_parts (CT ct) { @@ -1289,6 +1309,60 @@ reverse_parts (CT ct) } } +static void +move_preferred_part (CT ct, char *type, char *subtype) +{ + struct multipart *m = (struct multipart *) ct->c_ctparams; + struct part *part, *prev, *head, *nhead, *ntail; + struct part h, n; + CI ci; + + /* move the matching part(s) to the head of the list: walk the + * list of parts, move matching parts to a new list (maintaining + * their order), and finally, concatenate the old list onto the + * new. + */ + + head = &h; + nhead = &n; + + head->mp_next = m->mp_parts; + nhead->mp_next = NULL; + ntail = nhead; + + prev = head; + part = head->mp_next; + while (part != NULL) { + ci = &part->mp_part->c_ctinfo; + if (!strcasecmp(ci->ci_type, type) && + (!subtype || !strcasecmp(ci->ci_subtype, subtype))) { + prev->mp_next = part->mp_next; + part->mp_next = NULL; + ntail->mp_next = part; + ntail = part; + part = prev->mp_next; + } else { + prev = part; + part = prev->mp_next; + } + } + ntail->mp_next = head->mp_next; + m->mp_parts = nhead->mp_next; + +} + +/* + * move parts that match the user's preferences (-prefer) to the head + * of the line. process preferences in reverse so first one given + * ends up first in line + */ +static void +prefer_parts(CT ct) +{ + int i; + for (i = npreferred-1; i >= 0; i--) + move_preferred_part(ct, preferred_types[i], preferred_subtypes[i]); +} @@ -2509,7 +2583,7 @@ openFTP (CT ct, char **file) /* * Now, check the answer */ - if (!getanswer (buffer)) + if (!read_yes_or_no_if_tty (buffer)) return NOTOK; if (e->eb_flags) { @@ -2696,7 +2770,7 @@ openMail (CT ct, char **file) e->eb_subject ? e->eb_subject : e->eb_body); /* Now, check answer */ - if (!getanswer (buffer)) + if (!read_yes_or_no_if_tty (buffer)) return NOTOK; vecp = 0; @@ -4260,7 +4334,7 @@ char *get_param_value(PM pm, char replace) } if (utf8) { for (++p, --inbytes; - inbytes > 0 && (((unsigned char) *q) & 0xc0) == 0x80; + inbytes > 0 && (((unsigned char) *p) & 0xc0) == 0x80; ++p, --inbytes) continue; } else {