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)
{
p->disposition = DISPATTACH;
p->use_disp = true;
+ TAILQ_INIT(&p->parameter);
return p;
}
char tmp[_POSIX_PATH_MAX];
struct Body *b = NULL;
- struct Parameter *par = NULL, **ppar = NULL;
-
bool use_disp;
if (src->filename)
b = *tgt;
memcpy(b, src, sizeof(struct Body));
+ TAILQ_INIT(&b->parameter);
b->parts = NULL;
b->next = NULL;
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);
b = a;
a = a->next;
- if (b->parameter)
- mutt_param_free(&b->parameter);
+ mutt_param_free(&b->parameter);
if (b->filename)
{
if (b->unlink)
#include <stdio.h>
#include <time.h>
+#include "mutt/parameter.h"
+
/**
* struct Body - The body of an email
*/
{
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.
char buf[LONG_STRING];
char obuf[LONG_STRING];
char tmp[STRING];
- struct Parameter *p = NULL;
char charset[STRING];
char *cp = NULL;
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);
}
}
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. */
{
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);
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"));
}
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
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
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
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)
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
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));
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)
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;
}
}
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."));
(*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;
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++;
}
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)
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);
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);
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;
}
*
* | 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
}
/**
- * 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;
#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
*/
{
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 */
}
}
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. "
return 0;
}
- p = mutt_param_get("protocol", b->parameter);
+ p = mutt_param_get(&b->parameter, "protocol");
if (!p)
return 0;
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;
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;
}
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))
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)
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;
/* 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);
}
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;
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;
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;
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;
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;
/* 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;
}
/* 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;
}
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;
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;
}
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;
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);
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;
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;
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;
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
bail:
- rfc2231_decode_parameters(&head);
- return head;
+ rfc2231_decode_parameters(param);
}
int mutt_check_mime_type(const char *s)
*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
/* 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;
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);
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);
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,
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)
{
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))
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
{
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));
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)))
#include <time.h>
#include <wctype.h>
#include "mutt.h"
+#include "mutt/mutt.h"
#include "format_flags.h"
#include "options.h"
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);
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);
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;
}
}
/**
* 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];
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;
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)
{
/*
* 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
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);
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)
#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 */
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);
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");
}
}
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);
}
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);
* 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)
{
len += tmplen + 1;
}
- fprintf(f, "%s%s=%s", p->attribute, encode ? "*" : "", buffer);
+ fprintf(f, "%s%s=%s", np->attribute, encode ? "*" : "", buffer);
}
}
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");
#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);
}
/**
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;
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;
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;
}
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);
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)
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;
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;
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");
}
}
}