+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]);
+}
+
+
+
+/* parse_mime() arranges alternates in reverse (priority) order. This
+ function can be used to reverse them back. This will put, for
+ example, a text/plain part before a text/html part in a
+ multipart/alternative part, for example, where it belongs. */
+void
+reverse_alternative_parts (CT ct) {
+ if (ct->c_type == CT_MULTIPART) {
+ struct multipart *m = (struct multipart *) ct->c_ctparams;
+ struct part *part;
+
+ if (ct->c_subtype == MULTI_ALTERNATE) {
+ reverse_parts (ct);
+ }
+
+ /* And call recursively on each part of a multipart. */
+ for (part = m->mp_parts; part; part = part->mp_next) {
+ reverse_alternative_parts (part->mp_part);
+ }
+ }
+}
+