]> granicus.if.org Git - neomutt/commitdiff
Tidy parameter API, switch to TAILQ
authorPietro Cerutti <gahr@gahr.ch>
Fri, 2 Feb 2018 15:46:42 +0000 (15:46 +0000)
committerRichard Russon <rich@flatcap.org>
Mon, 5 Feb 2018 15:29:03 +0000 (15:29 +0000)
22 files changed:
attach.c
body.c
body.h
commands.c
handler.c
hcache/hcache.c
mbox.c
mutt/parameter.c
mutt/parameter.h
ncrypt/crypt.c
ncrypt/crypt_gpgme.c
ncrypt/pgp.c
ncrypt/smime.c
parse.c
postpone.c
protos.h
rfc1524.c
rfc2231.c
rfc2231.h
rfc3676.c
send.c
sendlib.c

index c0aad8e9541bf055bda9f2bb245fd1f2e5afaf43..e67b96d3c26e3b53143642283678a523f0c65cc3 100644 (file)
--- a/attach.c
+++ b/attach.c
@@ -154,11 +154,11 @@ int mutt_compose_attachment(struct Body *a)
           b = mutt_read_mime_header(fp, 0);
           if (b)
           {
-            if (b->parameter)
+            if (!TAILQ_EMPTY(&b->parameter))
             {
               mutt_param_free(&a->parameter);
               a->parameter = b->parameter;
-              b->parameter = NULL;
+              TAILQ_INIT(&b->parameter);
             }
             if (b->description)
             {
diff --git a/body.c b/body.c
index 2308d8ea0523ecefe68976950cf7f95b5e71a549..b84799ac792729c0545d736edddf02a94c656542 100644 (file)
--- a/body.c
+++ b/body.c
@@ -35,6 +35,7 @@ struct Body *mutt_new_body(void)
 
   p->disposition = DISPATTACH;
   p->use_disp = true;
+  TAILQ_INIT(&p->parameter);
   return p;
 }
 
@@ -49,8 +50,6 @@ int mutt_copy_body(FILE *fp, struct Body **tgt, struct Body *src)
   char tmp[_POSIX_PATH_MAX];
   struct Body *b = NULL;
 
-  struct Parameter *par = NULL, **ppar = NULL;
-
   bool use_disp;
 
   if (src->filename)
@@ -72,6 +71,7 @@ int mutt_copy_body(FILE *fp, struct Body **tgt, struct Body *src)
   b = *tgt;
 
   memcpy(b, src, sizeof(struct Body));
+  TAILQ_INIT(&b->parameter);
   b->parts = NULL;
   b->next = NULL;
 
@@ -101,11 +101,13 @@ int mutt_copy_body(FILE *fp, struct Body **tgt, struct Body *src)
     b->hdr = NULL;
 
   /* copy parameters */
-  for (par = b->parameter, ppar = &b->parameter; par; ppar = &(*ppar)->next, par = par->next)
+  struct Parameter *np, *new;
+  TAILQ_FOREACH(np, &src->parameter, entries)
   {
-    *ppar = mutt_param_new();
-    (*ppar)->attribute = mutt_str_strdup(par->attribute);
-    (*ppar)->value = mutt_str_strdup(par->value);
+      new = mutt_param_new();
+      new->attribute = mutt_str_strdup(np->attribute);
+      new->value = mutt_str_strdup(np->value);
+      TAILQ_INSERT_HEAD(&b->parameter, new, entries);
   }
 
   mutt_stamp_attachment(b);
@@ -122,8 +124,7 @@ void mutt_free_body(struct Body **p)
     b = a;
     a = a->next;
 
-    if (b->parameter)
-      mutt_param_free(&b->parameter);
+    mutt_param_free(&b->parameter);
     if (b->filename)
     {
       if (b->unlink)
diff --git a/body.h b/body.h
index 5d90001e7f3b8f81080fa0c6990864ed34fd0e4b..ae03a0491ddf2e7fe7fa6f2be89b80eff33c2d51 100644 (file)
--- a/body.h
+++ b/body.h
@@ -27,6 +27,8 @@
 #include <stdio.h>
 #include <time.h>
 
+#include "mutt/parameter.h"
+
 /**
  * struct Body - The body of an email
  */
@@ -34,7 +36,7 @@ struct Body
 {
   char *xtype;                  /**< content-type if x-unknown */
   char *subtype;                /**< content-type subtype */
-  struct Parameter *parameter;  /**< parameters of the content-type */
+  struct ParameterList parameter;  /**< parameters of the content-type */
   char *description;            /**< content-description */
   char *form_name;              /**< Content-Disposition form-data name param */
   long hdr_offset;              /**< offset in stream where the headers begin.
index 1168d2b9ad7dd8993d33d77ea95f85f10bb8c52e..03a1a41793657b6944b6d1634e9b39e410e82493 100644 (file)
@@ -958,7 +958,6 @@ int mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
   char buf[LONG_STRING];
   char obuf[LONG_STRING];
   char tmp[STRING];
-  struct Parameter *p = NULL;
 
   char charset[STRING];
   char *cp = NULL;
@@ -967,21 +966,19 @@ int mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
   short type_changed = 0;
   short structure_changed = 0;
 
-  cp = mutt_param_get("charset", b->parameter);
+  cp = mutt_param_get(&b->parameter, "charset");
   mutt_str_strfcpy(charset, NONULL(cp), sizeof(charset));
 
   snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
   mutt_str_strfcpy(obuf, buf, sizeof(obuf));
-  if (b->parameter)
+  if (!TAILQ_EMPTY(&b->parameter))
   {
-    size_t l;
-
-    for (p = b->parameter; p; p = p->next)
+    size_t l = strlen(buf);
+    struct Parameter *np;
+    TAILQ_FOREACH(np, &b->parameter, entries)
     {
-      l = strlen(buf);
-
-      mutt_addr_cat(tmp, sizeof(tmp), p->value, MimeSpecials);
-      snprintf(buf + l, sizeof(buf) - l, "; %s=%s", p->attribute, tmp);
+      mutt_addr_cat(tmp, sizeof(tmp), np->value, MimeSpecials);
+      l += snprintf(buf + l, sizeof(buf) - l, "; %s=%s", np->attribute, tmp);
     }
   }
 
@@ -996,7 +993,7 @@ int mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
 
   snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
   type_changed = mutt_str_strcasecmp(tmp, obuf);
-  charset_changed = mutt_str_strcasecmp(charset, mutt_param_get("charset", b->parameter));
+  charset_changed = mutt_str_strcasecmp(charset, mutt_param_get(&b->parameter, "charset"));
 
   /* if in send mode, check for conversion - current setting is default. */
 
@@ -1004,7 +1001,7 @@ int mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
   {
     int r;
     snprintf(tmp, sizeof(tmp), _("Convert to %s upon sending?"),
-             mutt_param_get("charset", b->parameter));
+             mutt_param_get(&b->parameter, "charset"));
     r = mutt_yesorno(tmp, !b->noconv);
     if (r != MUTT_ABORT)
       b->noconv = (r == MUTT_NO);
@@ -1020,7 +1017,7 @@ int mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
     if (type_changed)
       mutt_sleep(1);
     mutt_message(_("Character set changed to %s; %s."),
-                 mutt_param_get("charset", b->parameter),
+                 mutt_param_get(&b->parameter, "charset"),
                  b->noconv ? _("not converting") : _("converting"));
   }
 
index da1ee1668452fa5fc07a330d09afa5f4b0043c94..d6a77ff1862b959492e88349f523218da2894deb 100644 (file)
--- a/handler.c
+++ b/handler.c
@@ -60,7 +60,7 @@ static void print_part_line(struct State *s, struct Body *b, int n)
   char length[5];
   mutt_str_pretty_size(length, sizeof(length), b->length);
   state_mark_attach(s);
-  char *charset = mutt_param_get("charset", b->parameter);
+  char *charset = mutt_param_get(&b->parameter, "charset");
   if (n != 0)
     state_printf(s, _("[-- Alternative Type #%d: "), n);
   else
@@ -1024,7 +1024,7 @@ static int alternative_handler(struct Body *a, struct State *s)
     b = mutt_new_body();
     b->length = (long) st.st_size;
     b->parts = mutt_parse_multipart(
-        s->fpin, mutt_param_get("boundary", a->parameter), (long) st.st_size,
+        s->fpin, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
         (mutt_str_strcasecmp("digest", a->subtype) == 0));
   }
   else
@@ -1286,7 +1286,7 @@ static int multipart_handler(struct Body *a, struct State *s)
     b = mutt_new_body();
     b->length = (long) st.st_size;
     b->parts = mutt_parse_multipart(
-        s->fpin, mutt_param_get("boundary", a->parameter), (long) st.st_size,
+        s->fpin, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
         (mutt_str_strcasecmp("digest", a->subtype) == 0));
   }
   else
@@ -1477,7 +1477,7 @@ static int external_body_handler(struct Body *b, struct State *s)
   const char *expiration = NULL;
   time_t expire;
 
-  access_type = mutt_param_get("access-type", b->parameter);
+  access_type = mutt_param_get(&b->parameter, "access-type");
   if (!access_type)
   {
     if (s->flags & MUTT_DISPLAY)
@@ -1492,7 +1492,7 @@ static int external_body_handler(struct Body *b, struct State *s)
       return -1;
   }
 
-  expiration = mutt_param_get("expiration", b->parameter);
+  expiration = mutt_param_get(&b->parameter, "expiration");
   if (expiration)
     expire = mutt_date_parse_date(expiration, NULL);
   else
@@ -1507,7 +1507,7 @@ static int external_body_handler(struct Body *b, struct State *s)
 
       state_mark_attach(s);
       state_printf(s, _("[-- This %s/%s attachment "), TYPE(b->parts), b->parts->subtype);
-      length = mutt_param_get("length", b->parameter);
+      length = mutt_param_get(&b->parameter, "length");
       if (length)
       {
         mutt_str_pretty_size(pretty_size, sizeof(pretty_size), strtol(length, NULL, 10));
@@ -1570,7 +1570,7 @@ void mutt_decode_attachment(struct Body *b, struct State *s)
 
   if (istext && s->flags & MUTT_CHARCONV)
   {
-    char *charset = mutt_param_get("charset", b->parameter);
+    char *charset = mutt_param_get(&b->parameter, "charset");
     if (!charset && AssumedCharset && *AssumedCharset)
       charset = mutt_ch_get_default_charset();
     if (charset && Charset)
@@ -1831,7 +1831,7 @@ int mutt_body_handler(struct Body *b, struct State *s)
       if ((WithCrypto & APPLICATION_PGP) && mutt_is_application_pgp(b))
         handler = crypt_pgp_application_pgp_handler;
       else if (ReflowText &&
-               (mutt_str_strcasecmp("flowed", mutt_param_get("format", b->parameter)) == 0))
+               (mutt_str_strcasecmp("flowed", mutt_param_get(&b->parameter, "format")) == 0))
       {
         handler = rfc3676_handler;
       }
@@ -1865,7 +1865,7 @@ int mutt_body_handler(struct Body *b, struct State *s)
     }
     else if (WithCrypto && (mutt_str_strcasecmp("signed", b->subtype) == 0))
     {
-      p = mutt_param_get("protocol", b->parameter);
+      p = mutt_param_get(&b->parameter, "protocol");
 
       if (!p)
         mutt_error(_("Error: multipart/signed has no protocol."));
index 5fd98777eea28f0d879ec87ce99f1cf97922d360..4c0187de4dc238e0046c1affa296ef23d6e02b07 100644 (file)
@@ -342,7 +342,7 @@ static void restore_buffer(struct Buffer **b, const unsigned char *d, int *off,
   (*b)->destroy = used;
 }
 
-static unsigned char *dump_parameter(struct Parameter *p, unsigned char *d,
+static unsigned char *dump_parameter(struct ParameterList *p, unsigned char *d,
                                      int *off, bool convert)
 {
   unsigned int counter = 0;
@@ -350,11 +350,11 @@ static unsigned char *dump_parameter(struct Parameter *p, unsigned char *d,
 
   d = dump_int(0xdeadbeef, d, off);
 
-  while (p)
+  struct Parameter *np;
+  TAILQ_FOREACH(np, p, entries)
   {
-    d = dump_char(p->attribute, d, off, false);
-    d = dump_char(p->value, d, off, convert);
-    p = p->next;
+    d = dump_char(np->attribute, d, off, false);
+    d = dump_char(np->value, d, off, convert);
     counter++;
   }
 
@@ -363,23 +363,22 @@ static unsigned char *dump_parameter(struct Parameter *p, unsigned char *d,
   return d;
 }
 
-static void restore_parameter(struct Parameter **p, const unsigned char *d,
+static void restore_parameter(struct ParameterList *p, const unsigned char *d,
                               int *off, bool convert)
 {
   unsigned int counter;
 
   restore_int(&counter, d, off);
 
+  struct Parameter *np;
   while (counter)
   {
-    *p = mutt_mem_malloc(sizeof(struct Parameter));
-    restore_char(&(*p)->attribute, d, off, false);
-    restore_char(&(*p)->value, d, off, convert);
-    p = &(*p)->next;
+    np = mutt_param_new();
+    restore_char(&np->attribute, d, off, false);
+    restore_char(&np->value, d, off, convert);
+    TAILQ_INSERT_TAIL(p, np, entries);
     counter--;
   }
-
-  *p = NULL;
 }
 
 static unsigned char *dump_body(struct Body *c, unsigned char *d, int *off, bool convert)
@@ -403,7 +402,7 @@ static unsigned char *dump_body(struct Body *c, unsigned char *d, int *off, bool
   d = dump_char(nb.xtype, d, off, false);
   d = dump_char(nb.subtype, d, off, false);
 
-  d = dump_parameter(nb.parameter, d, off, convert);
+  d = dump_parameter(&nb.parameter, d, off, convert);
 
   d = dump_char(nb.description, d, off, convert);
   d = dump_char(nb.form_name, d, off, convert);
@@ -421,6 +420,7 @@ static void restore_body(struct Body *c, const unsigned char *d, int *off, bool
   restore_char(&c->xtype, d, off, false);
   restore_char(&c->subtype, d, off, false);
 
+  TAILQ_INIT(&c->parameter);
   restore_parameter(&c->parameter, d, off, convert);
 
   restore_char(&c->description, d, off, convert);
diff --git a/mbox.c b/mbox.c
index e00b27b50c052a6e41fb027ff6df7808de543ef8..c4848551c8e8a2a8a7629669b906c3ccfb5645d5 100644 (file)
--- a/mbox.c
+++ b/mbox.c
@@ -556,7 +556,7 @@ static int strict_cmp_bodies(const struct Body *b1, const struct Body *b2)
   if (b1->type != b2->type || b1->encoding != b2->encoding ||
       (mutt_str_strcmp(b1->subtype, b2->subtype) != 0) ||
       (mutt_str_strcmp(b1->description, b2->description) != 0) ||
-      !mutt_param_cmp_strict(b1->parameter, b2->parameter) || b1->length != b2->length)
+      !mutt_param_cmp_strict(&b1->parameter, &b2->parameter) || b1->length != b2->length)
     return 0;
   return 1;
 }
index d9f74ee14de795bf938e764af4115edea380de69..a8f79a59ca1cd0e6362badd8cfc141cda3f6f134 100644 (file)
  *
  * | Function                | Description
  * | :---------------------- | :------------------------------
- * | mutt_param_cmp_strict() | Strictly compare two Parameters
+ * | mutt_param_cmp_strict() | Strictly compare two ParameterLists
  * | mutt_param_delete()     | Delete a matching Parameter
- * | mutt_param_free()       | Free a Parameter
+ * | mutt_param_free()       | Free a ParameterList
+ * | mutt_param_free_one()   | Free a Parameter
  * | mutt_param_get()        | Find a matching Parameter
  * | mutt_param_new()        | Create a new Parameter
  * | mutt_param_set()        | Set a Parameter
@@ -50,117 +51,151 @@ struct Parameter *mutt_param_new(void)
 }
 
 /**
- * mutt_param_free - Free a Parameter
+ * mutt_param_free_one - Free a Parameter
  * @param p Parameter to free
  */
-void mutt_param_free(struct Parameter **p)
+void mutt_param_free_one(struct Parameter **p)
 {
-  struct Parameter *t = *p;
-  struct Parameter *o = NULL;
+  FREE(&(*p)->attribute);
+  FREE(&(*p)->value);
+  FREE(p);
+}
+
+/**
+ * mutt_param_free - Free a ParameterList
+ * @param p ParameterList to free
+ */
+void mutt_param_free(struct ParameterList *p)
+{
+  if (!p)
+    return;
 
-  while (t)
+  struct Parameter *np = TAILQ_FIRST(p), *next = NULL;
+  while (np)
   {
-    FREE(&t->attribute);
-    FREE(&t->value);
-    o = t;
-    t = t->next;
-    FREE(&o);
+    next = TAILQ_NEXT(np, entries);
+    mutt_param_free_one(&np);
+    np = next;
   }
-  *p = 0;
+  TAILQ_INIT(p);
 }
 
 /**
  * mutt_param_get - Find a matching Parameter
+ * @param p ParameterList
  * @param s String to match
- * @param p Parameter list
  * @retval ptr Matching Parameter
  * @retval NULL No match
  */
-char *mutt_param_get(const char *s, struct Parameter *p)
+char *mutt_param_get(const struct ParameterList *p, const char *s)
 {
-  for (; p; p = p->next)
-    if (mutt_str_strcasecmp(s, p->attribute) == 0)
-      return p->value;
+  if (!p)
+    return NULL;
+
+  struct Parameter *np;
+  TAILQ_FOREACH(np, p, entries)
+  {
+    if (mutt_str_strcasecmp(s, np->attribute) == 0)
+      return np->value;
+  }
 
   return NULL;
 }
 
 /**
  * mutt_param_set - Set a Parameter
+ * @param[in]  p         ParameterList
  * @param[in]  attribute Attribute to match
  * @param[in]  value     Value to set
- * @param[out] p         Parameter that was set
  *
  * @note If value is NULL, the Parameter will be deleted
  *
  * @note If a matching Parameter isn't found a new one will be allocated.
  *       The new Parameter will be inserted at the front of the list.
  */
-void mutt_param_set(const char *attribute, const char *value, struct Parameter **p)
+void mutt_param_set(struct ParameterList* p, const char *attribute, const char *value)
 {
-  struct Parameter *q = NULL;
+  if (!p)
+    return;
 
   if (!value)
   {
-    mutt_param_delete(attribute, p);
+    mutt_param_delete(p, attribute);
     return;
   }
 
-  for (q = *p; q; q = q->next)
+  struct Parameter *np;
+  TAILQ_FOREACH(np, p, entries)
   {
-    if (mutt_str_strcasecmp(attribute, q->attribute) == 0)
+    if (mutt_str_strcasecmp(attribute, np->attribute) == 0)
     {
-      mutt_str_replace(&q->value, value);
+      mutt_str_replace(&np->value, value);
       return;
     }
   }
 
-  q = mutt_param_new();
-  q->attribute = mutt_str_strdup(attribute);
-  q->value = mutt_str_strdup(value);
-  q->next = *p;
-  *p = q;
+  np = mutt_param_new();
+  np->attribute = mutt_str_strdup(attribute);
+  np->value = mutt_str_strdup(value);
+  TAILQ_INSERT_HEAD(p, np, entries);
 }
 
 /**
  * mutt_param_delete - Delete a matching Parameter
+ * @param[in[  p         ParameterList
  * @param[in]  attribute Attribute to match
- * @param[out] p         Parameter after the deleted Parameter
  */
-void mutt_param_delete(const char *attribute, struct Parameter **p)
+void mutt_param_delete(struct ParameterList *p, const char *attribute)
 {
-  for (struct Parameter *q = *p; q; p = &q->next, q = q->next)
+  if (!p)
+    return;
+
+  struct Parameter *np;
+  TAILQ_FOREACH(np, p, entries)
   {
-    if (mutt_str_strcasecmp(attribute, q->attribute) == 0)
+    if (mutt_str_strcasecmp(attribute, np->attribute) == 0)
     {
-      *p = q->next;
-      q->next = NULL;
-      mutt_param_free(&q);
+      TAILQ_REMOVE(p, np, entries);
+      mutt_param_free_one(&np);
       return;
     }
   }
 }
 
 /**
- * mutt_param_cmp_strict - Strictly compare two Parameters
+ * mutt_param_cmp_strict - Strictly compare two ParameterLists
  * @param p1 First parameter
  * @param p2 Second parameter
  * @retval true Parameters are strictly identical
  */
-int mutt_param_cmp_strict(const struct Parameter *p1, const struct Parameter *p2)
+int mutt_param_cmp_strict(const struct ParameterList *p1, const struct ParameterList *p2)
 {
-  while (p1 && p2)
+  if (!p1 && !p2)
+  {
+    return 0;
+  }
+
+  if ((p1 == NULL) ^ (p2 == NULL))
   {
-    if ((mutt_str_strcmp(p1->attribute, p2->attribute) != 0) ||
-        (mutt_str_strcmp(p1->value, p2->value) != 0))
+    return 1;
+  }
+
+  struct Parameter *np1 = TAILQ_FIRST(p1);
+  struct Parameter *np2 = TAILQ_FIRST(p2);
+
+  while (np1 && np2)
+  {
+    if ((mutt_str_strcmp(np1->attribute, np2->attribute) != 0) ||
+        (mutt_str_strcmp(np1->value, np2->value) != 0))
     {
       return 0;
     }
 
-    p1 = p1->next;
-    p2 = p2->next;
+    np1 = TAILQ_NEXT(np1, entries);
+    np2 = TAILQ_NEXT(np2, entries);
   }
-  if (p1 || p2)
+
+  if (np1 || np2)
     return 0;
 
   return 1;
index 7f1e8ea2de64591b140a81a3183965e1d775fa2b..b1b9f76b8d6651fafd8320dc3b4421b885b6bb22 100644 (file)
 #ifndef _MUTT_PARAMETER_H
 #define _MUTT_PARAMETER_H
 
+#include "queue.h"
+
+/**
+ * struct ParameterList - List of parameters.
+ */
+TAILQ_HEAD(ParameterList, Parameter);
+
 /**
  * struct Parameter - Attribute associated with a MIME part
  */
@@ -30,14 +37,15 @@ struct Parameter
 {
   char *attribute;
   char *value;
-  struct Parameter *next;
+  TAILQ_ENTRY(Parameter) entries;
 };
 
 struct Parameter *mutt_param_new(void);
-int               mutt_param_cmp_strict(const struct Parameter *p1, const struct Parameter *p2);
-void              mutt_param_delete(const char *attribute, struct Parameter **p);
-void              mutt_param_free(struct Parameter **p);
-char *            mutt_param_get(const char *s, struct Parameter *p);
-void              mutt_param_set(const char *attribute, const char *value, struct Parameter **p);
+int               mutt_param_cmp_strict(const struct ParameterList *p1, const struct ParameterList *p2);
+void              mutt_param_delete(struct ParameterList *p, const char *attribute);
+void              mutt_param_free(struct ParameterList *p);
+void              mutt_param_free_one(struct Parameter **p);
+char *            mutt_param_get(const struct ParameterList *p, const char *s);
+void              mutt_param_set(struct ParameterList *p, const char *attribute, const char *value);
 
 #endif /* _MUTT_PARAMETER_H */
index 2e1eefa86e4fecc486fc0a11c4af940817698551..2a395096a082d808b4bedfcdb5d828c2d012531a 100644 (file)
@@ -156,7 +156,7 @@ int mutt_protect(struct Header *msg, char *keylist)
       }
     }
     else if (!mutt_str_strcasecmp("flowed",
-                                  mutt_param_get("format", msg->content->parameter)))
+                                  mutt_param_get(&msg->content->parameter, "format")))
     {
       if ((query_quadoption(PgpMimeAuto,
                             _("Inline PGP can't be used with format=flowed.  "
@@ -316,7 +316,7 @@ int mutt_is_multipart_signed(struct Body *b)
     return 0;
   }
 
-  p = mutt_param_get("protocol", b->parameter);
+  p = mutt_param_get(&b->parameter, "protocol");
   if (!p)
     return 0;
 
@@ -351,7 +351,7 @@ int mutt_is_multipart_encrypted(struct Body *b)
 
     if (!b || b->type != TYPEMULTIPART || !b->subtype ||
         (mutt_str_strcasecmp(b->subtype, "encrypted") != 0) ||
-        !(p = mutt_param_get("protocol", b->parameter)) ||
+        !(p = mutt_param_get(&b->parameter, "protocol")) ||
         (mutt_str_strcasecmp(p, "application/pgp-encrypted") != 0))
       return 0;
 
@@ -445,14 +445,14 @@ int mutt_is_application_pgp(struct Body *m)
     if ((mutt_str_strcasecmp(m->subtype, "pgp") == 0) ||
         (mutt_str_strcasecmp(m->subtype, "x-pgp-message") == 0))
     {
-      p = mutt_param_get("x-action", m->parameter);
+      p = mutt_param_get(&m->parameter, "x-action");
       if (p && ((mutt_str_strcasecmp(p, "sign") == 0) ||
                 (mutt_str_strcasecmp(p, "signclear") == 0)))
       {
         t |= PGPSIGN;
       }
 
-      p = mutt_param_get("format", m->parameter);
+      p = mutt_param_get(&m->parameter, "format");
       if (p && (mutt_str_strcasecmp(p, "keys-only") == 0))
       {
         t |= PGPKEY;
@@ -470,9 +470,9 @@ int mutt_is_application_pgp(struct Body *m)
   }
   else if (m->type == TYPETEXT && (mutt_str_strcasecmp("plain", m->subtype) == 0))
   {
-    if (((p = mutt_param_get("x-mutt-action", m->parameter)) ||
-         (p = mutt_param_get("x-action", m->parameter)) ||
-         (p = mutt_param_get("action", m->parameter))) &&
+    if (((p = mutt_param_get(&m->parameter, "x-mutt-action")) ||
+         (p = mutt_param_get(&m->parameter, "x-action")) ||
+         (p = mutt_param_get(&m->parameter, "action"))) &&
         (mutt_str_strncasecmp("pgp-sign", p, 8) == 0))
       t |= PGPSIGN;
     else if (p && (mutt_str_strncasecmp("pgp-encrypt", p, 11) == 0))
@@ -501,7 +501,7 @@ int mutt_is_application_smime(struct Body *m)
     if ((mutt_str_strcasecmp(m->subtype, "x-pkcs7-mime") == 0) ||
         (mutt_str_strcasecmp(m->subtype, "pkcs7-mime") == 0))
     {
-      t = mutt_param_get("smime-type", m->parameter);
+      t = mutt_param_get(&m->parameter, "smime-type");
       if (t)
       {
         if (mutt_str_strcasecmp(t, "enveloped-data") == 0)
@@ -522,7 +522,7 @@ int mutt_is_application_smime(struct Body *m)
     else if (mutt_str_strcasecmp(m->subtype, "octet-stream") != 0)
       return 0;
 
-    t = mutt_param_get("name", m->parameter);
+    t = mutt_param_get(&m->parameter, "name");
 
     if (!t)
       t = m->d_filename;
@@ -973,7 +973,7 @@ int mutt_signed_handler(struct Body *a, struct State *s)
     /* A null protocol value is already checked for in mutt_body_handler() */
     state_printf(s, _("[-- Error: "
                       "Unknown multipart/signed protocol %s! --]\n\n"),
-                 mutt_param_get("protocol", b->parameter));
+                 mutt_param_get(&b->parameter, "protocol"));
     return mutt_body_handler(a, s);
   }
 
index 2bf3b9f20e49627c9ad92d14e3ca469cb15c9c97..1fc8560b46f2eb5824cb1c1ed7e700b41dec117a 100644 (file)
@@ -1057,16 +1057,15 @@ static struct Body *sign_message(struct Body *a, int use_smime)
   t->disposition = DISPINLINE;
 
   mutt_generate_boundary(&t->parameter);
-  mutt_param_set("protocol",
+  mutt_param_set(&t->parameter, "protocol",
                  use_smime ? "application/pkcs7-signature" :
-                             "application/pgp-signature",
-                 &t->parameter);
+                             "application/pgp-signature");
   /* Get the micalg from gpgme.  Old gpgme versions don't support this
      for S/MIME so we assume sha-1 in this case. */
   if (!get_micalg(ctx, use_smime, buf, sizeof(buf)))
-    mutt_param_set("micalg", buf, &t->parameter);
+    mutt_param_set(&t->parameter, "micalg", buf);
   else if (use_smime)
-    mutt_param_set("micalg", "sha1", &t->parameter);
+    mutt_param_set(&t->parameter, "micalg", "sha1");
   gpgme_release(ctx);
 
   t->parts = a;
@@ -1078,7 +1077,7 @@ static struct Body *sign_message(struct Body *a, int use_smime)
   if (use_smime)
   {
     t->subtype = mutt_str_strdup("pkcs7-signature");
-    mutt_param_set("name", "smime.p7s", &t->parameter);
+    mutt_param_set(&t->parameter, "name", "smime.p7s");
     t->encoding = ENCBASE64;
     t->use_disp = true;
     t->disposition = DISPATTACH;
@@ -1087,7 +1086,7 @@ static struct Body *sign_message(struct Body *a, int use_smime)
   else
   {
     t->subtype = mutt_str_strdup("pgp-signature");
-    mutt_param_set("name", "signature.asc", &t->parameter);
+    mutt_param_set(&t->parameter, "name", "signature.asc");
     t->use_disp = false;
     t->disposition = DISPNONE;
     t->encoding = ENC7BIT;
@@ -1152,7 +1151,7 @@ struct Body *pgp_gpgme_encrypt_message(struct Body *a, char *keylist, int sign)
   t->disposition = DISPINLINE;
 
   mutt_generate_boundary(&t->parameter);
-  mutt_param_set("protocol", "application/pgp-encrypted", &t->parameter);
+  mutt_param_set(&t->parameter, "protocol", "application/pgp-encrypted");
 
   t->parts = mutt_new_body();
   t->parts->type = TYPEAPPLICATION;
@@ -1214,8 +1213,8 @@ struct Body *smime_gpgme_build_smime_entity(struct Body *a, char *keylist)
   t = mutt_new_body();
   t->type = TYPEAPPLICATION;
   t->subtype = mutt_str_strdup("pkcs7-mime");
-  mutt_param_set("name", "smime.p7m", &t->parameter);
-  mutt_param_set("smime-type", "enveloped-data", &t->parameter);
+  mutt_param_set(&t->parameter, "name", "smime.p7m");
+  mutt_param_set(&t->parameter, "smime-type", "enveloped-data");
   t->encoding = ENCBASE64; /* The output of OpenSSL SHOULD be binary */
   t->use_disp = true;
   t->disposition = DISPATTACH;
@@ -2353,8 +2352,8 @@ static int pgp_check_traditional_one_body(FILE *fp, struct Body *b)
 
   /* fix the content type */
 
-  mutt_param_set("format", "fixed", &b->parameter);
-  mutt_param_set("x-action", enc ? "pgp-encrypted" : "pgp-signed", &b->parameter);
+  mutt_param_set(&b->parameter, "format", "fixed");
+  mutt_param_set(&b->parameter, "x-action", enc ? "pgp-encrypted" : "pgp-signed");
 
   return 1;
 }
index 96dfe77d1725a0cce99b7b3b0514a0fdfae4213a..309d6d4146d2d612664a4572a00b9cb2c99f0f50 100644 (file)
@@ -665,13 +665,13 @@ static int pgp_check_traditional_one_body(FILE *fp, struct Body *b)
 
   /* fix the content type */
 
-  mutt_param_set("format", "fixed", &b->parameter);
+  mutt_param_set(&b->parameter, "format", "fixed");
   if (enc)
-    mutt_param_set("x-action", "pgp-encrypted", &b->parameter);
+    mutt_param_set(&b->parameter, "x-action", "pgp-encrypted");
   else if (sgn)
-    mutt_param_set("x-action", "pgp-signed", &b->parameter);
+    mutt_param_set(&b->parameter, "x-action", "pgp-signed");
   else if (key)
-    mutt_param_set("x-action", "pgp-keys", &b->parameter);
+    mutt_param_set(&b->parameter, "x-action", "pgp-keys");
 
   return 1;
 }
@@ -1208,8 +1208,8 @@ struct Body *pgp_sign_message(struct Body *a)
   t->disposition = DISPINLINE;
 
   mutt_generate_boundary(&t->parameter);
-  mutt_param_set("protocol", "application/pgp-signature", &t->parameter);
-  mutt_param_set("micalg", pgp_micalg(sigfile), &t->parameter);
+  mutt_param_set(&t->parameter, "protocol", "application/pgp-signature");
+  mutt_param_set(&t->parameter, "micalg", pgp_micalg(sigfile));
 
   t->parts = a;
   a = t;
@@ -1223,7 +1223,7 @@ struct Body *pgp_sign_message(struct Body *a)
   t->disposition = DISPNONE;
   t->encoding = ENC7BIT;
   t->unlink = true; /* ok to remove this file after sending. */
-  mutt_param_set("name", "signature.asc", &t->parameter);
+  mutt_param_set(&t->parameter, "name", "signature.asc");
 
   return a;
 }
@@ -1464,7 +1464,7 @@ struct Body *pgp_encrypt_message(struct Body *a, char *keylist, int sign)
   t->disposition = DISPINLINE;
 
   mutt_generate_boundary(&t->parameter);
-  mutt_param_set("protocol", "application/pgp-encrypted", &t->parameter);
+  mutt_param_set(&t->parameter, "protocol", "application/pgp-encrypted");
 
   t->parts = mutt_new_body();
   t->parts->type = TYPEAPPLICATION;
@@ -1642,8 +1642,8 @@ struct Body *pgp_traditional_encryptsign(struct Body *a, int flags, char *keylis
   b->type = TYPETEXT;
   b->subtype = mutt_str_strdup("plain");
 
-  mutt_param_set("x-action", flags & ENCRYPT ? "pgp-encrypted" : "pgp-signed", &b->parameter);
-  mutt_param_set("charset", send_charset, &b->parameter);
+  mutt_param_set(&b->parameter, "x-action", flags & ENCRYPT ? "pgp-encrypted" : "pgp-signed");
+  mutt_param_set(&b->parameter, "charset", send_charset);
 
   b->filename = mutt_str_strdup(pgpoutfile);
 
index 5b59318280d62b32afe6e7f7c551591c1cd0ac78..fa5f2a59c7c9356e7e97f52438feb73717cadd28 100644 (file)
@@ -1440,8 +1440,8 @@ struct Body *smime_build_smime_entity(struct Body *a, char *certlist)
   t = mutt_new_body();
   t->type = TYPEAPPLICATION;
   t->subtype = mutt_str_strdup("x-pkcs7-mime");
-  mutt_param_set("name", "smime.p7m", &t->parameter);
-  mutt_param_set("smime-type", "enveloped-data", &t->parameter);
+  mutt_param_set(&t->parameter, "name", "smime.p7m");
+  mutt_param_set(&t->parameter, "smime-type", "enveloped-data");
   t->encoding = ENCBASE64; /* The output of OpenSSL SHOULD be binary */
   t->use_disp = true;
   t->disposition = DISPATTACH;
@@ -1599,10 +1599,10 @@ struct Body *smime_sign_message(struct Body *a)
   mutt_generate_boundary(&t->parameter);
 
   micalg = openssl_md_to_smime_micalg(SmimeSignDigestAlg);
-  mutt_param_set("micalg", micalg, &t->parameter);
+  mutt_param_set(&t->parameter, "micalg", micalg);
   FREE(&micalg);
 
-  mutt_param_set("protocol", "application/x-pkcs7-signature", &t->parameter);
+  mutt_param_set(&t->parameter, "protocol", "application/x-pkcs7-signature");
 
   t->parts = a;
   a = t;
diff --git a/parse.c b/parse.c
index 49397e4ae8933536c5f313678bfedf3463bfeebf..37cf03103755e7d6f5e81e56ad047cf90d6ed407 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -146,9 +146,9 @@ int mutt_check_encoding(const char *c)
     return ENCOTHER;
 }
 
-static struct Parameter *parse_parameters(const char *s)
+static void parse_parameters(struct ParameterList *param, const char *s)
 {
-  struct Parameter *head = NULL, *cur = NULL, *new = NULL;
+  struct Parameter *new = NULL;
   char buffer[LONG_STRING];
   const char *p = NULL;
   size_t i;
@@ -238,13 +238,7 @@ static struct Parameter *parse_parameters(const char *s)
                    new->attribute ? new->attribute : "", new->value ? new->value : "");
 
         /* Add this parameter to the list */
-        if (head)
-        {
-          cur->next = new;
-          cur = cur->next;
-        }
-        else
-          head = cur = new;
+        TAILQ_INSERT_HEAD(param, new, entries);
       }
     }
     else
@@ -266,8 +260,7 @@ static struct Parameter *parse_parameters(const char *s)
 
 bail:
 
-  rfc2231_decode_parameters(&head);
-  return head;
+  rfc2231_decode_parameters(param);
 }
 
 int mutt_check_mime_type(const char *s)
@@ -315,18 +308,18 @@ void mutt_parse_content_type(char *s, struct Body *ct)
     *pc++ = 0;
     while (*pc && ISSPACE(*pc))
       pc++;
-    ct->parameter = parse_parameters(pc);
+    parse_parameters(&ct->parameter, pc);
 
     /* Some pre-RFC1521 gateways still use the "name=filename" convention,
      * but if a filename has already been set in the content-disposition,
      * let that take precedence, and don't set it here */
-    pc = mutt_param_get("name", ct->parameter);
+    pc = mutt_param_get(&ct->parameter, "name");
     if (pc && !ct->filename)
       ct->filename = mutt_str_strdup(pc);
 
 #ifdef SUN_ATTACHMENT
     /* this is deep and utter perversion */
-    pc = mutt_param_get("conversions", ct->parameter);
+    pc = mutt_param_get(&ct->parameter, "conversions");
     if (pc)
       ct->encoding = mutt_check_encoding(pc);
 #endif
@@ -382,19 +375,19 @@ void mutt_parse_content_type(char *s, struct Body *ct)
   /* Default character set for text types. */
   if (ct->type == TYPETEXT)
   {
-    pc = mutt_param_get("charset", ct->parameter);
+    pc = mutt_param_get(&ct->parameter, "charset");
     if (!pc)
-      mutt_param_set("charset",
+      mutt_param_set(&ct->parameter, "charset",
                      (AssumedCharset && *AssumedCharset) ?
                          (const char *) mutt_ch_get_default_charset() :
-                         "us-ascii",
-                     &ct->parameter);
+                         "us-ascii");
   }
 }
 
 static void parse_content_disposition(const char *s, struct Body *ct)
 {
-  struct Parameter *parms = NULL;
+  struct ParameterList parms;
+  TAILQ_INIT(&parms);
 
   if (mutt_str_strncasecmp("inline", s, 6) == 0)
     ct->disposition = DISPINLINE;
@@ -408,10 +401,11 @@ static void parse_content_disposition(const char *s, struct Body *ct)
   if (s)
   {
     s = mutt_str_skip_email_wsp(s + 1);
-    s = mutt_param_get("filename", (parms = parse_parameters(s)));
+    parse_parameters(&parms, s);
+    s = mutt_param_get(&parms, "filename");
     if (s)
       mutt_str_replace(&ct->filename, s);
-    s = mutt_param_get("name", parms);
+    s = mutt_param_get(&parms, "name");
     if (s)
       ct->form_name = mutt_str_strdup(s);
     mutt_param_free(&parms);
@@ -478,7 +472,7 @@ struct Body *mutt_read_mime_header(FILE *fp, int digest)
       else if (mutt_str_strcasecmp("encoding-info", line + 6) == 0)
         p->encoding = mutt_check_encoding(c);
       else if (mutt_str_strcasecmp("content-lines", line + 6) == 0)
-        mutt_param_set("content-lines", c, &(p->parameter));
+        mutt_param_set(&p->parameter, "content-lines", c);
       else if (mutt_str_strcasecmp("data-description", line + 6) == 0)
       {
         mutt_str_replace(&p->description, c);
@@ -510,7 +504,7 @@ void mutt_parse_part(FILE *fp, struct Body *b)
         bound = "--------";
       else
 #endif
-        bound = mutt_param_get("boundary", b->parameter);
+        bound = mutt_param_get(&b->parameter, "boundary");
 
       fseeko(fp, b->offset, SEEK_SET);
       b->parts = mutt_parse_multipart(fp, bound, b->offset + b->length,
@@ -633,9 +627,9 @@ struct Body *mutt_parse_multipart(FILE *fp, const char *boundary, LOFF_T end_off
         new = mutt_read_mime_header(fp, digest);
 
 #ifdef SUN_ATTACHMENT
-        if (mutt_param_get("content-lines", new->parameter))
+        if (mutt_param_get(&new->parameter, "content-lines"))
         {
-          if (mutt_str_atoi(mutt_param_get("content-lines", new->parameter), &lines) < 0)
+          if (mutt_str_atoi(mutt_param_get(&new->parameter, "content-lines"), &lines) < 0)
             lines = 0;
           for (; lines; lines--)
             if (ftello(fp) >= end_off || fgets(buffer, LONG_STRING, fp) == NULL)
index fceacf1934514d61edae99380a418155c0510270..6facda200811496f5c8724e34d6d370b7e22f2ba 100644 (file)
@@ -602,7 +602,7 @@ int mutt_prepare_template(FILE *fp, struct Context *ctx, struct Header *newhdr,
   {
     newhdr->security |= SIGN;
     if ((WithCrypto & APPLICATION_PGP) &&
-        (mutt_str_strcasecmp(mutt_param_get("protocol", newhdr->content->parameter),
+        (mutt_str_strcasecmp(mutt_param_get(&newhdr->content->parameter, "protocol"),
                              "application/pgp-signature") == 0))
       newhdr->security |= APPLICATION_PGP;
     else if ((WithCrypto & APPLICATION_SMIME))
@@ -653,7 +653,7 @@ int mutt_prepare_template(FILE *fp, struct Context *ctx, struct Header *newhdr,
 
     if (b->type == TYPETEXT)
     {
-      if (mutt_str_strcasecmp("yes", mutt_param_get("x-mutt-noconv", b->parameter)) == 0)
+      if (mutt_str_strcasecmp("yes", mutt_param_get(&b->parameter, "x-mutt-noconv")) == 0)
         b->noconv = true;
       else
       {
@@ -661,7 +661,7 @@ int mutt_prepare_template(FILE *fp, struct Context *ctx, struct Header *newhdr,
         b->noconv = false;
       }
 
-      mutt_param_delete("x-mutt-noconv", &b->parameter);
+      mutt_param_delete(&b->parameter, "x-mutt-noconv");
     }
 
     mutt_adv_mktemp(file, sizeof(file));
@@ -689,7 +689,7 @@ int mutt_prepare_template(FILE *fp, struct Context *ctx, struct Header *newhdr,
 
       b->type = TYPETEXT;
       mutt_str_replace(&b->subtype, "plain");
-      mutt_param_delete("x-action", &b->parameter);
+      mutt_param_delete(&b->parameter, "x-action");
     }
     else if ((WithCrypto & APPLICATION_SMIME) &&
              ((sec_type = mutt_is_application_smime(b)) & (ENCRYPT | SIGN)))
index 75b42288affad64f9a361f1aea8563e236b559e1..f1b71fc825a99db7d6ace14aa21ce87a44e1d9db 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -33,6 +33,7 @@
 #include <time.h>
 #include <wctype.h>
 #include "mutt.h"
+#include "mutt/mutt.h"
 #include "format_flags.h"
 #include "options.h"
 
@@ -85,7 +86,7 @@ void mutt_free_opts(void);
 int mutt_system(const char *cmd);
 
 void mutt_parse_content_type(char *s, struct Body *ct);
-void mutt_generate_boundary(struct Parameter **parm);
+void mutt_generate_boundary(struct ParameterList *parm);
 
 #ifdef USE_NOTMUCH
 int mutt_parse_virtual_mailboxes(struct Buffer *path, struct Buffer *s, unsigned long data, struct Buffer *err);
index c1a7ffeaaa1ae1eb5faf62ce50bf86847588af32..993dd079dbede3125c1a9b2f2a49b368d29a2f95 100644 (file)
--- a/rfc1524.c
+++ b/rfc1524.c
@@ -92,7 +92,7 @@ int rfc1524_expand_command(struct Body *a, char *filename, char *type, char *com
           param[z++] = command[x++];
         param[z] = '\0';
 
-        pvalue2 = mutt_param_get(param, a->parameter);
+        pvalue2 = mutt_param_get(&a->parameter, param);
         mutt_str_strfcpy(pvalue, NONULL(pvalue2), sizeof(pvalue));
         if (MailcapSanitize)
           mutt_file_sanitize_filename(pvalue, 0);
index d5bf7e1239629767ef7dd45fb605eea5584dc1cf..c8fa91fe76a4bb8ed5e569c0874edd5791cd2991 100644 (file)
--- a/rfc2231.c
+++ b/rfc2231.c
@@ -52,21 +52,16 @@ struct Rfc2231Parameter
   struct Rfc2231Parameter *next;
 };
 
-static void purge_empty_parameters(struct Parameter **headp)
+static void purge_empty_parameters(struct ParameterList *p)
 {
-  struct Parameter *p = NULL, *q = NULL, **last = NULL;
-
-  for (last = headp, p = *headp; p; p = q)
+  struct Parameter *np, *tmp;
+  TAILQ_FOREACH_SAFE(np, p, entries, tmp)
   {
-    q = p->next;
-    if (!p->attribute || !p->value)
+    if (!np->attribute || !np->value)
     {
-      *last = q;
-      p->next = NULL;
-      mutt_param_free(&p);
+      TAILQ_REMOVE(p, np, entries);
+      mutt_param_free_one(&np);
     }
-    else
-      last = &p->next;
   }
 }
 
@@ -154,8 +149,9 @@ static void rfc2231_free_parameter(struct Rfc2231Parameter **p)
 /**
  * rfc2231_join_continuations - process continuation parameters
  */
-static void rfc2231_join_continuations(struct Parameter **head, struct Rfc2231Parameter *par)
+static void rfc2231_join_continuations(struct ParameterList *p, struct Rfc2231Parameter *par)
 {
+  struct Parameter *np;
   struct Rfc2231Parameter *q = NULL;
 
   char attribute[STRING];
@@ -199,19 +195,16 @@ static void rfc2231_join_continuations(struct Parameter **head, struct Rfc2231Pa
 
     if (encoded)
       mutt_ch_convert_string(&value, charset, Charset, MUTT_ICONV_HOOK_FROM);
-    *head = mutt_param_new();
-    (*head)->attribute = mutt_str_strdup(attribute);
-    (*head)->value = value;
-    head = &(*head)->next;
+
+    np = mutt_param_new();
+    np->attribute = mutt_str_strdup(attribute);
+    np->value = value;
+    TAILQ_INSERT_HEAD(p, np, entries);
   }
 }
 
-void rfc2231_decode_parameters(struct Parameter **headp)
+void rfc2231_decode_parameters(struct ParameterList *p)
 {
-  struct Parameter *head = NULL;
-  struct Parameter **last = NULL;
-  struct Parameter *p = NULL, *q = NULL;
-
   struct Rfc2231Parameter *conthead = NULL;
   struct Rfc2231Parameter *conttmp = NULL;
 
@@ -222,16 +215,15 @@ void rfc2231_decode_parameters(struct Parameter **headp)
   int index;
   bool dirty = false; /* set to 1 when we may have created
                        * empty parameters. */
-  if (!headp)
+  if (!p)
     return;
 
-  purge_empty_parameters(headp);
+  purge_empty_parameters(p);
 
-  for (last = &head, p = *headp; p; p = q)
+  struct Parameter *np;
+  TAILQ_FOREACH(np, p, entries)
   {
-    q = p->next;
-
-    s = strchr(p->attribute, '*');
+    s = strchr(np->attribute, '*');
     if (!s)
     {
       /*
@@ -241,28 +233,19 @@ void rfc2231_decode_parameters(struct Parameter **headp)
        * Internet Gateways.  So we actually decode it.
        */
 
-      if (Rfc2047Parameters && p->value && strstr(p->value, "=?"))
-        mutt_rfc2047_decode(&p->value);
+      if (Rfc2047Parameters && np->value && strstr(np->value, "=?"))
+        mutt_rfc2047_decode(&np->value);
       else if (AssumedCharset && *AssumedCharset)
-        mutt_ch_convert_nonmime_string(&p->value);
-
-      *last = p;
-      last = &p->next;
-      p->next = NULL;
+        mutt_ch_convert_nonmime_string(&np->value);
     }
     else if (*(s + 1) == '\0')
     {
       *s = '\0';
 
-      s = rfc2231_get_charset(p->value, charset, sizeof(charset));
-      rfc2231_decode_one(p->value, s);
-      mutt_ch_convert_string(&p->value, charset, Charset, MUTT_ICONV_HOOK_FROM);
-      mutt_mb_filter_unprintable(&p->value);
-
-      *last = p;
-      last = &p->next;
-      p->next = NULL;
-
+      s = rfc2231_get_charset(np->value, charset, sizeof(charset));
+      rfc2231_decode_one(np->value, s);
+      mutt_ch_convert_string(&np->value, charset, Charset, MUTT_ICONV_HOOK_FROM);
+      mutt_mb_filter_unprintable(&np->value);
       dirty = true;
     }
     else
@@ -277,13 +260,13 @@ void rfc2231_decode_parameters(struct Parameter **headp)
       index = atoi(s);
 
       conttmp = rfc2231_new_parameter();
-      conttmp->attribute = p->attribute;
-      conttmp->value = p->value;
+      conttmp->attribute = np->attribute;
+      conttmp->value = np->value;
       conttmp->encoded = encoded;
       conttmp->index = index;
 
-      p->attribute = NULL;
-      p->value = NULL;
+      np->attribute = NULL;
+      np->value = NULL;
       FREE(&p);
 
       rfc2231_list_insert(&conthead, conttmp);
@@ -292,14 +275,12 @@ void rfc2231_decode_parameters(struct Parameter **headp)
 
   if (conthead)
   {
-    rfc2231_join_continuations(last, conthead);
+    rfc2231_join_continuations(p, conthead);
     dirty = true;
   }
 
-  *headp = head;
-
   if (dirty)
-    purge_empty_parameters(headp);
+    purge_empty_parameters(p);
 }
 
 int rfc2231_encode_string(char **pd)
index ba6ce55c4dcfcfad04f763c3c0764a35e56a2e6f..ad766a2779fdbb7da41cd181657849e44534cabf 100644 (file)
--- a/rfc2231.h
+++ b/rfc2231.h
@@ -23,9 +23,9 @@
 #ifndef _MUTT_RFC2231_H
 #define _MUTT_RFC2231_H
 
-struct Parameter;
+struct ParameterList;
 
-void rfc2231_decode_parameters(struct Parameter **headp);
+void rfc2231_decode_parameters(struct ParameterList *p);
 int rfc2231_encode_string(char **pd);
 
 #endif /* _MUTT_RFC2231_H */
index 5ebc8e6cbd209b84631bcf26347eb02d9ef96842..67d716dfd27fd3fe46e713fb9094f00bf57607e3 100644 (file)
--- a/rfc3676.c
+++ b/rfc3676.c
@@ -275,7 +275,7 @@ int rfc3676_handler(struct Body *a, struct State *s)
   memset(&fst, 0, sizeof(fst));
 
   /* respect DelSp of RFC3676 only with f=f parts */
-  t = mutt_param_get("delsp", a->parameter);
+  t = mutt_param_get(&a->parameter, "delsp");
   if (t)
   {
     delsp = mutt_str_strlen(t) == 3 && (mutt_str_strncasecmp(t, "yes", 3) == 0);
diff --git a/send.c b/send.c
index 3863429b1ae7338c7633d48b80f26ced4e6e1ca7..6d6e05061eb05c8a24bd1e5c4ea284cb0e5a9d77 100644 (file)
--- a/send.c
+++ b/send.c
@@ -1533,7 +1533,7 @@ int ci_send_message(int flags, struct Header *msg, char *tempfile,
       if (TextFlowed && msg->content->type == TYPETEXT &&
           (mutt_str_strcasecmp(msg->content->subtype, "plain") == 0))
       {
-        mutt_param_set("format", "flowed", &msg->content->parameter);
+        mutt_param_set(&msg->content->parameter, "format", "flowed");
       }
     }
 
@@ -1647,7 +1647,7 @@ int ci_send_message(int flags, struct Header *msg, char *tempfile,
       if (TextFlowed && msg->content->type == TYPETEXT &&
           (mutt_str_strcasecmp("plain", msg->content->subtype) == 0))
       {
-        char *p = mutt_param_get("format", msg->content->parameter);
+        char *p = mutt_param_get(&msg->content->parameter, "format");
         if (mutt_str_strcasecmp("flowed", NONULL(p)) != 0)
           rfc3676_space_stuff(msg);
       }
index ed4176e5c4c4d3eb62fe132dc86a01aa83f91e2c..792e3009dbef18b9731db26a835c4fec25eaab31 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -312,21 +312,22 @@ int mutt_write_mime_header(struct Body *a, FILE *f)
 
   fprintf(f, "Content-Type: %s/%s", TYPE(a), a->subtype);
 
-  if (a->parameter)
+  if (!TAILQ_EMPTY(&a->parameter))
   {
     len = 25 + mutt_str_strlen(a->subtype); /* approximate len. of content-type */
 
-    for (struct Parameter *p = a->parameter; p; p = p->next)
+    struct Parameter *np;
+    TAILQ_FOREACH(np, &a->parameter, entries)
     {
       char *tmp = NULL;
 
-      if (!p->value)
+      if (!np->value)
         continue;
 
       fputc(';', f);
 
       buffer[0] = 0;
-      tmp = mutt_str_strdup(p->value);
+      tmp = mutt_str_strdup(np->value);
       encode = rfc2231_encode_string(&tmp);
       mutt_addr_cat(buffer, sizeof(buffer), tmp, MimeSpecials);
 
@@ -335,12 +336,12 @@ int mutt_write_mime_header(struct Body *a, FILE *f)
        * even when they aren't needed.
        */
 
-      if ((mutt_str_strcasecmp(p->attribute, "boundary") == 0) && (strcmp(buffer, tmp) == 0))
+      if ((mutt_str_strcasecmp(np->attribute, "boundary") == 0) && (strcmp(buffer, tmp) == 0))
         snprintf(buffer, sizeof(buffer), "\"%s\"", tmp);
 
       FREE(&tmp);
 
-      tmplen = mutt_str_strlen(buffer) + mutt_str_strlen(p->attribute) + 1;
+      tmplen = mutt_str_strlen(buffer) + mutt_str_strlen(np->attribute) + 1;
 
       if (len + tmplen + 2 > 76)
       {
@@ -353,7 +354,7 @@ int mutt_write_mime_header(struct Body *a, FILE *f)
         len += tmplen + 1;
       }
 
-      fprintf(f, "%s%s=%s", p->attribute, encode ? "*" : "", buffer);
+      fprintf(f, "%s%s=%s", np->attribute, encode ? "*" : "", buffer);
     }
   }
 
@@ -427,7 +428,7 @@ int mutt_write_mime_body(struct Body *a, FILE *f)
   if (a->type == TYPEMULTIPART)
   {
     /* First, find the boundary to use */
-    p = mutt_param_get("boundary", a->parameter);
+    p = mutt_param_get(&a->parameter, "boundary");
     if (!p)
     {
       mutt_debug(1, "no boundary parameter found!\n");
@@ -495,13 +496,13 @@ int mutt_write_mime_body(struct Body *a, FILE *f)
 
 #undef write_as_text_part
 
-void mutt_generate_boundary(struct Parameter **parm)
+void mutt_generate_boundary(struct ParameterList *parm)
 {
   char rs[MUTT_RANDTAG_LEN + 1];
 
   mutt_rand_base32(rs, sizeof(rs) - 1);
   rs[MUTT_RANDTAG_LEN] = 0;
-  mutt_param_set("boundary", rs, parm);
+  mutt_param_set(parm, "boundary", rs);
 }
 
 /**
@@ -935,7 +936,7 @@ struct Content *mutt_get_content_info(const char *fname, struct Body *b)
 
   if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset))
   {
-    char *chs = mutt_param_get("charset", b->parameter);
+    char *chs = mutt_param_get(&b->parameter, "charset");
     char *fchs = b->use_disp ?
                      ((AttachCharset && *AttachCharset) ? AttachCharset : Charset) :
                      Charset;
@@ -946,7 +947,7 @@ struct Content *mutt_get_content_info(const char *fname, struct Body *b)
       if (!chs)
       {
         mutt_ch_canonical_charset(chsbuf, sizeof(chsbuf), tocode);
-        mutt_param_set("charset", chsbuf, &b->parameter);
+        mutt_param_set(&b->parameter, "charset", chsbuf);
       }
       FREE(&b->charset);
       b->charset = fromcode;
@@ -964,10 +965,10 @@ struct Content *mutt_get_content_info(const char *fname, struct Body *b)
   mutt_file_fclose(&fp);
 
   if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset))
-    mutt_param_set("charset",
+    mutt_param_set(&b->parameter, "charset",
                    (!info->hibin ? "us-ascii" :
-                                   Charset && !mutt_ch_is_us_ascii(Charset) ? Charset : "unknown-8bit"),
-                   &b->parameter);
+                                   Charset && !mutt_ch_is_us_ascii(Charset)
+                                   ? Charset : "unknown-8bit"));
 
   return info;
 }
@@ -1312,7 +1313,7 @@ char *mutt_get_body_charset(char *d, size_t dlen, struct Body *b)
     return NULL;
 
   if (b)
-    p = mutt_param_get("charset", b->parameter);
+    p = mutt_param_get(&b->parameter, "charset");
 
   if (p)
     mutt_ch_canonical_charset(d, dlen, p);
@@ -1337,7 +1338,7 @@ void mutt_update_encoding(struct Body *a)
     a->noconv = false;
 
   if (!a->force_charset && !a->noconv)
-    mutt_param_delete("charset", &a->parameter);
+    mutt_param_delete(&a->parameter, "charset");
 
   info = mutt_get_content_info(a->filename, a);
   if (!info)
@@ -1552,7 +1553,7 @@ static bool check_boundary(const char *boundary, struct Body *b)
   if (b->next && check_boundary(boundary, b->next))
     return true;
 
-  p = mutt_param_get("boundary", b->parameter);
+  p = mutt_param_get(&b->parameter, "boundary");
   if (p && (mutt_str_strcmp(p, boundary) == 0))
   {
     return true;
@@ -1571,9 +1572,9 @@ struct Body *mutt_make_multipart(struct Body *b)
   do
   {
     mutt_generate_boundary(&new->parameter);
-    if (check_boundary(mutt_param_get("boundary", new->parameter), b))
-      mutt_param_delete("boundary", &new->parameter);
-  } while (!mutt_param_get("boundary", new->parameter));
+    if (check_boundary(mutt_param_get(&new->parameter, "boundary"), b))
+      mutt_param_delete(&new->parameter, "boundary");
+  } while (!mutt_param_get(&new->parameter, "boundary"));
   new->use_disp = false;
   new->disposition = DISPINLINE;
   new->parts = b;
@@ -2883,9 +2884,9 @@ static void set_noconv_flags(struct Body *b, short flag)
     else if (b->type == TYPETEXT && b->noconv)
     {
       if (flag)
-        mutt_param_set("x-mutt-noconv", "yes", &b->parameter);
+        mutt_param_set(&b->parameter, "x-mutt-noconv", "yes");
       else
-        mutt_param_delete("x-mutt-noconv", &b->parameter);
+        mutt_param_delete(&b->parameter, "x-mutt-noconv");
     }
   }
 }