]> diplodocus.org Git - nmh/blobdiff - uip/mhparse.c
Added all of mhshow's documented switches to show's handling, on the
[nmh] / uip / mhparse.c
index a3a80f9a1b4b0242c5b395a382df5ca7664d37ba..6f8ebaf1e6d102ed37df87fadcba7404a6e027fc 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <h/mh.h>
 #include <fcntl.h>
-#include <h/signals.h>
 #include <h/md5.h>
 #include <h/mts.h>
 #include <h/tws.h>
@@ -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]);
+}