+ /*
+ * Read the content headers. We will parse the
+ * MIME related header fields into their various
+ * structures and set internal flags related to
+ * content type/subtype, etc.
+ */
+
+ hp = ct->c_first_hf; /* start at first header field */
+ while (hp) {
+ /* Get MIME-Version field */
+ if (!mh_strcasecmp (hp->name, VRSN_FIELD)) {
+ int ucmp;
+ char c;
+ unsigned char *cp, *dp;
+
+ 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);
+
+ /* Now, cleanup this field */
+ cp = ct->c_vrsn;
+
+ while (isspace (*cp))
+ cp++;
+ for (dp = strchr(cp, '\n'); dp; dp = strchr(dp, '\n'))
+ *dp++ = ' ';
+ for (dp = cp + strlen (cp) - 1; dp >= cp; dp--)
+ if (!isspace (*dp))
+ break;
+ *++dp = '\0';
+ if (debugsw)
+ fprintf (stderr, "%s: %s\n", VRSN_FIELD, cp);
+
+ if (*cp == '(' && get_comment (ct, &cp, 0) == NOTOK)
+ goto out;
+
+ for (dp = cp; istoken (*dp); dp++)
+ continue;
+ c = *dp;
+ *dp = '\0';
+ 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 (!mh_strcasecmp (hp->name, TYPE_FIELD)) {
+ /* Get Content-Type field */
+ struct str2init *s2i;
+ CI ci = &ct->c_ctinfo;
+
+ /* Check if we've already seen a Content-Type header */
+ if (ct->c_ctline) {
+ advise (NULL, "message %s has multiple %s: fields",
+ ct->c_file, TYPE_FIELD);
+ goto next_header;
+ }
+
+ /* Parse the Content-Type field */
+ if (get_ctinfo (hp->value, ct, 0) == NOTOK)
+ goto out;
+
+ /*
+ * Set the Init function and the internal
+ * flag for this content type.
+ */
+ for (s2i = str2cts; s2i->si_key; s2i++)
+ 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 (!mh_strcasecmp (hp->name, ENCODING_FIELD)) {
+ /* Get Content-Transfer-Encoding field */
+ char c;
+ unsigned char *cp, *dp;
+ struct str2init *s2i;
+
+ /*
+ * Check if we've already seen the
+ * Content-Transfer-Encoding field
+ */
+ if (ct->c_celine) {
+ advise (NULL, "message %s has multiple %s: fields",
+ ct->c_file, ENCODING_FIELD);
+ goto next_header;
+ }
+
+ /* get copy of this field */
+ ct->c_celine = cp = add (hp->value, NULL);
+
+ while (isspace (*cp))
+ cp++;
+ for (dp = cp; istoken (*dp); dp++)
+ continue;
+ c = *dp;
+ *dp = '\0';
+
+ /*
+ * Find the internal flag and Init function
+ * for this transfer encoding.
+ */
+ for (s2i = str2ces; s2i->si_key; s2i++)
+ if (!mh_strcasecmp (cp, s2i->si_key))
+ break;
+ if (!s2i->si_key && !uprf (cp, "X-"))
+ s2i++;
+ *dp = c;
+ ct->c_encoding = s2i->si_val;
+
+ /* Call the Init function for this encoding */
+ if (s2i->si_init && (*s2i->si_init) (ct) == NOTOK)
+ goto out;
+ }
+ else if (!mh_strcasecmp (hp->name, MD5_FIELD)) {
+ /* Get Content-MD5 field */
+ unsigned char *cp, *dp;
+ char *ep;
+
+ if (!checksw)
+ goto next_header;
+
+ if (ct->c_digested) {
+ advise (NULL, "message %s has multiple %s: fields",
+ ct->c_file, MD5_FIELD);
+ goto next_header;
+ }
+
+ ep = cp = add (hp->value, NULL); /* get a copy */
+
+ while (isspace (*cp))
+ cp++;
+ for (dp = strchr(cp, '\n'); dp; dp = strchr(dp, '\n'))
+ *dp++ = ' ';
+ for (dp = cp + strlen (cp) - 1; dp >= cp; dp--)
+ if (!isspace (*dp))
+ break;
+ *++dp = '\0';
+ if (debugsw)
+ fprintf (stderr, "%s: %s\n", MD5_FIELD, cp);
+
+ if (*cp == '(' && get_comment (ct, &cp, 0) == NOTOK) {
+ free (ep);
+ goto out;
+ }
+
+ for (dp = cp; *dp && !isspace (*dp); dp++)
+ continue;
+ *dp = '\0';
+
+ readDigest (ct, cp);
+ free (ep);
+ ct->c_digested++;
+ }
+ else if (!mh_strcasecmp (hp->name, ID_FIELD)) {
+ /* Get Content-ID field */
+ ct->c_id = add (hp->value, ct->c_id);
+ }
+ else if (!mh_strcasecmp (hp->name, DESCR_FIELD)) {
+ /* Get Content-Description field */
+ ct->c_descr = add (hp->value, ct->c_descr);
+ }
+ else if (!mh_strcasecmp (hp->name, DISPO_FIELD)) {
+ /* Get Content-Disposition field */
+ ct->c_dispo = add (hp->value, ct->c_dispo);
+ }
+