From: Paul Fox Date: Wed, 4 Feb 2015 02:55:41 +0000 (-0500) Subject: implement -prefer, for multipart/alternative preferences X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/66d4999b6e82edc2dfcb9f2c46328f4eaef0f737 implement -prefer, for multipart/alternative preferences --- diff --git a/h/mhparse.h b/h/mhparse.h index c3b0b9f1..d1c94420 100644 --- a/h/mhparse.h +++ b/h/mhparse.h @@ -6,7 +6,7 @@ #define NPARTS 50 #define NTYPES 20 -#define NPARMS 10 +#define NPREFS 20 /* * Abstract type for header fields diff --git a/uip/mhlist.c b/uip/mhlist.c index 3e98b871..34655236 100644 --- a/uip/mhlist.c +++ b/uip/mhlist.c @@ -32,6 +32,7 @@ X("file file", 0, FILESW) \ X("part number", 0, PARTSW) \ X("type content", 0, TYPESW) \ + X("prefer content", 0, PREFERSW) \ X("rcache policy", 0, RCACHESW) \ X("wcache policy", 0, WCACHESW) \ X("changecur", 0, CHGSW) \ @@ -62,6 +63,11 @@ extern char *parts[NPARTS + 1]; extern char *types[NTYPES + 1]; extern int userrs; +/* mhparse.c */ +extern char *preferred_types[]; +extern char *preferred_subtypes[]; +extern int npreferred; + /* * This is currently needed to keep mhparse happy. * This needs to be changed. @@ -186,6 +192,18 @@ do_cache: types[ntype++] = cp; continue; + case PREFERSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + if (npreferred >= NPREFS) + adios (NULL, "too many preferred types (starting with %s), %d max", + cp, NPREFS); + preferred_types[npreferred] = cp; + cp = strchr(cp, '/'); + if (cp) *cp++ = '\0'; + preferred_subtypes[npreferred++] = cp; + continue; + case FILESW: if (!(cp = *argp++) || (*cp == '-' && cp[1])) adios (NULL, "missing argument to %s", argp[-2]); diff --git a/uip/mhparse.c b/uip/mhparse.c index 9f636786..00fa61bd 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -43,6 +43,12 @@ int bogus_mp_content; int suppress_extraneous_trailing_semicolon_warning; int extraneous_trailing_semicolon; +/* list of preferred type/subtype pairs, for -prefer */ +char *preferred_types[NPREFS], + *preferred_subtypes[NPREFS]; +int npreferred; + + /* * Structures for TEXT messages */ @@ -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); @@ -1223,8 +1230,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 +1279,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 +1304,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, *next, *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]); +} diff --git a/uip/mhshow.c b/uip/mhshow.c index 63f4fcb0..c8343763 100644 --- a/uip/mhshow.c +++ b/uip/mhshow.c @@ -34,6 +34,7 @@ X("markform formfile", 0, MARKFORMSW) \ X("part number", 0, PARTSW) \ X("type content", 0, TYPESW) \ + X("prefer content", 0, PREFERSW) \ X("rcache policy", 0, RCACHESW) \ X("wcache policy", 0, WCACHESW) \ X("version", 0, VERSIONSW) \ @@ -77,6 +78,11 @@ extern char *parts[NPARTS + 1]; extern char *types[NTYPES + 1]; extern int userrs; +/* mhparse.c */ +extern char *preferred_types[]; +extern char *preferred_subtypes[]; +extern int npreferred; + int debugsw = 0; int verbosw = 0; @@ -203,6 +209,18 @@ do_cache: types[ntype++] = cp; continue; + case PREFERSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + if (npreferred >= NPREFS) + adios (NULL, "too many preferred types (starting with %s), %d max", + cp, NPREFS); + preferred_types[npreferred] = cp; + cp = strchr(cp, '/'); + if (cp) *cp++ = '\0'; + preferred_subtypes[npreferred++] = cp; + continue; + case FILESW: if (!(cp = *argp++) || (*cp == '-' && cp[1])) adios (NULL, "missing argument to %s", argp[-2]); diff --git a/uip/mhstore.c b/uip/mhstore.c index 65d0b34b..a3481034 100644 --- a/uip/mhstore.c +++ b/uip/mhstore.c @@ -29,6 +29,7 @@ X("outfile outfile", 0, OUTFILESW) \ X("part number", 0, PARTSW) \ X("type content", 0, TYPESW) \ + X("prefer content", 0, PREFERSW) \ X("rcache policy", 0, RCACHESW) \ X("wcache policy", 0, WCACHESW) \ X("version", 0, VERSIONSW) \ @@ -58,6 +59,11 @@ extern char *parts[NPARTS + 1]; extern char *types[NTYPES + 1]; extern int userrs; +/* mhparse.c */ +extern char *preferred_types[]; +extern char *preferred_subtypes[]; +extern int npreferred; + #define quitser pipeser /* mhparse.c */ @@ -175,6 +181,18 @@ do_cache: types[ntype++] = cp; continue; + case PREFERSW: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + if (npreferred >= NPREFS) + adios (NULL, "too many preferred types (starting with %s), %d max", + cp, NPREFS); + preferred_types[npreferred] = cp; + cp = strchr(cp, '/'); + if (cp) *cp++ = '\0'; + preferred_subtypes[npreferred++] = cp; + continue; + case FILESW: if (!(cp = *argp++) || (*cp == '-' && cp[1])) adios (NULL, "missing argument to %s", argp[-2]);