struct Buffer *spam;
struct STailQHead references; /**< message references (in reverse order) */
struct STailQHead in_reply_to; /**< in-reply-to header content */
- struct List *userhdrs; /**< user defined headers */
+ struct STailQHead userhdrs; /**< user defined headers */
int kwtypes;
bool irt_changed : 1; /**< In-Reply-To changed to link/break threads */
struct Envelope *e = safe_calloc(1, sizeof(struct Envelope));
STAILQ_INIT(&e->references);
STAILQ_INIT(&e->in_reply_to);
+ STAILQ_INIT(&e->userhdrs);
return e;
}
*a = NULL;
}
-static unsigned char *dump_list(struct List *l, unsigned char *d, int *off, int convert)
-{
- unsigned int counter = 0;
- unsigned int start_off = *off;
-
- d = dump_int(0xdeadbeef, d, off);
-
- while (l)
- {
- d = dump_char(l->data, d, off, convert);
- l = l->next;
- counter++;
- }
-
- memcpy(d + start_off, &counter, sizeof(int));
-
- return d;
-}
-
static unsigned char *dump_stailq(struct STailQHead *l, unsigned char *d, int *off, int convert)
{
unsigned int counter = 0;
return d;
}
-static void restore_list(struct List **l, const unsigned char *d, int *off, int convert)
-{
- unsigned int counter;
-
- restore_int(&counter, d, off);
-
- while (counter)
- {
- *l = safe_malloc(sizeof(struct List));
- restore_char(&(*l)->data, d, off, convert);
- l = &(*l)->next;
- counter--;
- }
-
- *l = NULL;
-}
-
static void restore_stailq(struct STailQHead *l, const unsigned char *d, int *off, int convert)
{
unsigned int counter;
d = dump_stailq(&e->references, d, off, 0);
d = dump_stailq(&e->in_reply_to, d, off, 0);
- d = dump_list(e->userhdrs, d, off, convert);
+ d = dump_stailq(&e->userhdrs, d, off, convert);
#ifdef USE_NNTP
d = dump_char(e->xref, d, off, 0);
restore_stailq(&e->references, d, off, 0);
restore_stailq(&e->in_reply_to, d, off, 0);
- restore_list(&e->userhdrs, d, off, convert);
+ restore_stailq(&e->userhdrs, d, off, convert);
#ifdef USE_NNTP
restore_char(&e->xref, d, off, 0);
struct Envelope *n = NULL;
time_t mtime;
struct stat st;
- struct List *cur = NULL, **last = NULL, *tmp = NULL;
mutt_mktemp(path, sizeof(path));
if ((ofp = safe_fopen(path, "w")) == NULL)
}
mutt_unlink(body);
- mutt_free_list(&msg->env->userhdrs);
+ mutt_free_stailq(&msg->env->userhdrs);
/* Read the temp file back in */
if ((ifp = fopen(path, "r")) == NULL)
* fcc: or attach: or pgp: was specified
*/
- cur = msg->env->userhdrs;
- last = &msg->env->userhdrs;
- while (cur)
+ struct STailQNode *np, *tmp;
+ STAILQ_FOREACH_SAFE(np, &msg->env->userhdrs, entries, tmp)
{
keep = true;
- if (fcc && (mutt_strncasecmp("fcc:", cur->data, 4) == 0))
+ if (fcc && (mutt_strncasecmp("fcc:", np->data, 4) == 0))
{
- p = skip_email_wsp(cur->data + 4);
+ p = skip_email_wsp(np->data + 4);
if (*p)
{
strfcpy(fcc, p, fcclen);
}
keep = false;
}
- else if (mutt_strncasecmp("attach:", cur->data, 7) == 0)
+ else if (mutt_strncasecmp("attach:", np->data, 7) == 0)
{
struct Body *body2 = NULL;
struct Body *parts = NULL;
size_t l = 0;
- p = skip_email_wsp(cur->data + 7);
+ p = skip_email_wsp(np->data + 7);
if (*p)
{
for (; *p && *p != ' ' && *p != '\t'; p++)
keep = false;
}
else if ((WithCrypto & APPLICATION_PGP) &&
- (mutt_strncasecmp("pgp:", cur->data, 4) == 0))
+ (mutt_strncasecmp("pgp:", np->data, 4) == 0))
{
- msg->security = mutt_parse_crypt_hdr(cur->data + 4, 0, APPLICATION_PGP);
+ msg->security = mutt_parse_crypt_hdr(np->data + 4, 0, APPLICATION_PGP);
if (msg->security)
msg->security |= APPLICATION_PGP;
keep = false;
}
- if (keep)
+ if (!keep)
{
- last = &cur->next;
- cur = cur->next;
- }
- else
- {
- tmp = cur;
- *last = cur->next;
- cur = cur->next;
- tmp->next = NULL;
- mutt_free_list(&tmp);
+ STAILQ_REMOVE(&msg->env->userhdrs, np, STailQNode, entries);
+ FREE(&np->data);
+ FREE(&np);
}
}
}
struct Header *context_hdr = NULL;
struct Envelope *opts_env = msg->env;
struct stat st;
- struct List *uh = NULL, **last_uhp = NULL;
sendflags |= SENDDRAFTFILE;
mutt_prepare_template(fin, NULL, msg, context_hdr, 0);
/* Scan for mutt header to set OPT_RESUME_DRAFT_FILES */
- for (last_uhp = &msg->env->userhdrs, uh = *last_uhp; uh; uh = *last_uhp)
+ struct STailQNode *np, *tmp;
+ STAILQ_FOREACH_SAFE(np, &msg->env->userhdrs, entries, tmp)
{
- if (mutt_strncasecmp("X-Mutt-Resume-Draft:", uh->data, 20) == 0)
+ if (mutt_strncasecmp("X-Mutt-Resume-Draft:", np->data, 20) == 0)
{
if (option(OPT_RESUME_EDITED_DRAFT_FILES))
set_option(OPT_RESUME_DRAFT_FILES);
- *last_uhp = uh->next;
- uh->next = NULL;
- mutt_free_list(&uh);
+ STAILQ_REMOVE(&msg->env->userhdrs, np, STailQNode, entries);
+ FREE(&np->data);
+ FREE(&np);
}
- else
- last_uhp = &uh->next;
}
rfc822_append(&msg->env->to, opts_env->to, 0);
mutt_free_stailq(&(*p)->references);
mutt_free_stailq(&(*p)->in_reply_to);
- mutt_free_list(&(*p)->userhdrs);
+ mutt_free_stailq(&(*p)->userhdrs);
FREE(p);
}
/* spam and user headers should never be hashed, and the new envelope may
* have better values. Use new versions regardless. */
mutt_buffer_free(&base->spam);
- mutt_free_list(&base->userhdrs);
+ mutt_free_stailq(&base->userhdrs);
MOVE_ELEM(spam);
- MOVE_ELEM(userhdrs);
+ MOVE_STAILQ(userhdrs);
#undef MOVE_ELEM
mutt_free_envelope(extra);
}
int mutt_parse_rfc822_line(struct Envelope *e, struct Header *hdr, char *line,
- char *p, short user_hdrs, short weed, short do_2047,
- struct List **lastp)
+ char *p, short user_hdrs, short weed, short do_2047)
{
int matched = 0;
- struct List *last = NULL;
-
- if (lastp)
- last = *lastp;
switch (tolower(line[0]))
{
/* restore the original line */
line[strlen(line)] = ':';
- if (weed && option(OPT_WEED) && mutt_matches_ignore(line))
- goto done;
-
- if (last)
+ if (!(weed && option(OPT_WEED) && mutt_matches_ignore(line)))
{
- last->next = mutt_new_list();
- last = last->next;
+ struct STailQNode *np = calloc(1, sizeof(struct STailQNode));
+ np->data = safe_strdup(line);
+ STAILQ_INSERT_TAIL(&e->userhdrs, np, entries);
+ if (do_2047)
+ rfc2047_decode(&np->data);
}
- else
- last = e->userhdrs = mutt_new_list();
- last->data = safe_strdup(line);
- if (do_2047)
- rfc2047_decode(&last->data);
}
-done:
-
- if (lastp)
- *lastp = last;
return matched;
}
short user_hdrs, short weed)
{
struct Envelope *e = mutt_new_envelope();
- struct List *last = NULL;
char *line = safe_malloc(LONG_STRING);
char *p = NULL;
LOFF_T loc;
if (!*p)
continue; /* skip empty header fields */
- mutt_parse_rfc822_line(e, hdr, line, p, user_hdrs, weed, 1, &last);
+ mutt_parse_rfc822_line(e, hdr, line, p, user_hdrs, weed, 1);
}
FREE(&line);
{
struct Header *h = NULL;
int code = SENDPOSTPONED;
- struct List *tmp = NULL;
- struct List *last = NULL;
- struct List *next = NULL;
const char *p = NULL;
int opt_delete;
FREE(&PostContext);
- for (tmp = hdr->env->userhdrs; tmp;)
+ struct STailQNode *np, *tmp;
+ STAILQ_FOREACH_SAFE(np, &hdr->env->userhdrs, entries, tmp)
{
- if (mutt_strncasecmp("X-Mutt-References:", tmp->data, 18) == 0)
+ if (mutt_strncasecmp("X-Mutt-References:", np->data, 18) == 0)
{
if (ctx)
{
/* if a mailbox is currently open, look to see if the original message
the user attempted to reply to is in this mailbox */
- p = skip_email_wsp(tmp->data + 18);
+ p = skip_email_wsp(np->data + 18);
if (!ctx->id_hash)
ctx->id_hash = mutt_make_id_hash(ctx);
*cur = hash_find(ctx->id_hash, p);
}
-
- /* Remove the X-Mutt-References: header field. */
- next = tmp->next;
- if (last)
- last->next = tmp->next;
- else
- hdr->env->userhdrs = tmp->next;
- tmp->next = NULL;
- mutt_free_list(&tmp);
- tmp = next;
if (*cur)
code |= SENDREPLY;
}
- else if (mutt_strncasecmp("X-Mutt-Fcc:", tmp->data, 11) == 0)
+ else if (mutt_strncasecmp("X-Mutt-Fcc:", np->data, 11) == 0)
{
- p = skip_email_wsp(tmp->data + 11);
+ p = skip_email_wsp(np->data + 11);
strfcpy(fcc, p, fcclen);
mutt_pretty_mailbox(fcc, fcclen);
- /* remove the X-Mutt-Fcc: header field */
- next = tmp->next;
- if (last)
- last->next = tmp->next;
- else
- hdr->env->userhdrs = tmp->next;
- tmp->next = NULL;
- mutt_free_list(&tmp);
- tmp = next;
/* note that x-mutt-fcc was present. we do this because we want to add a
* default fcc if the header was missing, but preserve the request of the
* user to not make a copy if the header field is present, but empty.
code |= SENDPOSTPONEDFCC;
}
else if ((WithCrypto & APPLICATION_PGP) &&
- ((mutt_strncmp("Pgp:", tmp->data, 4) == 0) /* this is generated
- * by old mutt versions
- */
- || (mutt_strncmp("X-Mutt-PGP:", tmp->data, 11) == 0)))
+ ((mutt_strncmp("Pgp:", np->data, 4) == 0) /* this is generated
+ * by old mutt versions
+ */
+ || (mutt_strncmp("X-Mutt-PGP:", np->data, 11) == 0)))
{
- hdr->security = mutt_parse_crypt_hdr(strchr(tmp->data, ':') + 1, 1, APPLICATION_PGP);
+ hdr->security = mutt_parse_crypt_hdr(strchr(np->data, ':') + 1, 1, APPLICATION_PGP);
hdr->security |= APPLICATION_PGP;
-
- /* remove the pgp field */
- next = tmp->next;
- if (last)
- last->next = tmp->next;
- else
- hdr->env->userhdrs = tmp->next;
- tmp->next = NULL;
- mutt_free_list(&tmp);
- tmp = next;
}
else if ((WithCrypto & APPLICATION_SMIME) &&
- (mutt_strncmp("X-Mutt-SMIME:", tmp->data, 13) == 0))
+ (mutt_strncmp("X-Mutt-SMIME:", np->data, 13) == 0))
{
- hdr->security = mutt_parse_crypt_hdr(strchr(tmp->data, ':') + 1, 1, APPLICATION_SMIME);
+ hdr->security = mutt_parse_crypt_hdr(strchr(np->data, ':') + 1, 1, APPLICATION_SMIME);
hdr->security |= APPLICATION_SMIME;
-
- /* remove the smime field */
- next = tmp->next;
- if (last)
- last->next = tmp->next;
- else
- hdr->env->userhdrs = tmp->next;
- tmp->next = NULL;
- mutt_free_list(&tmp);
- tmp = next;
}
#ifdef MIXMASTER
- else if (mutt_strncmp("X-Mutt-Mix:", tmp->data, 11) == 0)
+ else if (mutt_strncmp("X-Mutt-Mix:", np->data, 11) == 0)
{
char *t = NULL;
mutt_free_list(&hdr->chain);
- t = strtok(tmp->data + 11, " \t\n");
+ t = strtok(np->data + 11, " \t\n");
while (t)
{
hdr->chain = mutt_add_list(hdr->chain, t);
t = strtok(NULL, " \t\n");
}
-
- next = tmp->next;
- if (last)
- last->next = tmp->next;
- else
- hdr->env->userhdrs = tmp->next;
- tmp->next = NULL;
- mutt_free_list(&tmp);
- tmp = next;
}
#endif
else
{
- last = tmp;
- tmp = tmp->next;
+ // skip header removal
+ continue;
}
+
+ // remove the header
+ STAILQ_REMOVE(&hdr->env->userhdrs, np, STailQNode, entries);
+ FREE(&np->data);
+ FREE(&np);
}
if (option(OPT_CRYPT_OPPORTUNISTIC_ENCRYPT))
int mutt_parse_push(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err);
int mutt_parse_rc_line(/* const */ char *line, struct Buffer *token, struct Buffer *err);
int mutt_parse_rfc822_line(struct Envelope *e, struct Header *hdr, char *line, char *p,
- short user_hdrs, short weed, short do_2047, struct List **lastp);
+ short user_hdrs, short weed, short do_2047);
int mutt_parse_score(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err);
int mutt_parse_unscore(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err);
int mutt_parse_unhook(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err);
static void process_user_header(struct Envelope *env)
{
struct List *uh = UserHeader;
- struct List *last = env->userhdrs;
-
- if (last)
- while (last->next)
- last = last->next;
for (; uh; uh = uh->next)
{
(mutt_strncasecmp("subject:", uh->data, 8) != 0) &&
(mutt_strncasecmp("return-path:", uh->data, 12) != 0))
{
- if (last)
- {
- last->next = mutt_new_list();
- last = last->next;
- }
- else
- last = env->userhdrs = mutt_new_list();
- last->data = safe_strdup(uh->data);
+ struct STailQNode *np = safe_calloc(1, sizeof(struct STailQNode));
+ np->data = safe_strdup(uh->data);
+ STAILQ_INSERT_TAIL(&env->userhdrs, np, entries);
}
}
}
{
char buffer[LONG_STRING];
char *p = NULL, *q = NULL;
- struct List *tmp = env->userhdrs;
bool has_agent = false; /* user defined user-agent header field exists */
if (mode == 0 && !privacy)
}
/* Add any user defined headers */
- for (; tmp; tmp = tmp->next)
+ struct STailQNode *tmp;
+ STAILQ_FOREACH(tmp, &env->userhdrs, entries)
{
if ((p = strchr(tmp->data, ':')))
{
return (ferror(fp) == 0 ? 0 : -1);
}
-static void encode_headers(struct List *h)
+static void encode_headers(struct STailQHead *h)
{
char *tmp = NULL;
char *p = NULL;
int i;
- for (; h; h = h->next)
+ struct STailQNode *np;
+ STAILQ_FOREACH(np, h, entries)
{
- if (!(p = strchr(h->data, ':')))
+ if (!(p = strchr(np->data, ':')))
continue;
- i = p - h->data;
+ i = p - np->data;
p = skip_email_wsp(p + 1);
tmp = safe_strdup(p);
continue;
rfc2047_encode_string(&tmp);
- safe_realloc(&h->data, mutt_strlen(h->data) + 2 + mutt_strlen(tmp) + 1);
+ safe_realloc(&np->data, mutt_strlen(np->data) + 2 + mutt_strlen(tmp) + 1);
- sprintf(h->data + i, ": %s", NONULL(tmp));
+ sprintf(np->data + i, ": %s", NONULL(tmp));
FREE(&tmp);
}
{
rfc2047_encode_string(&env->subject);
}
- encode_headers(env->userhdrs);
+ encode_headers(&env->userhdrs);
}
void mutt_unprepare_envelope(struct Envelope *env)
{
- struct List *item = NULL;
-
- for (item = env->userhdrs; item; item = item->next)
+ struct STailQNode *item;
+ STAILQ_FOREACH(item, &env->userhdrs, entries)
+ {
rfc2047_decode(&item->data);
+ }
rfc822_free_address(&env->mail_followup_to);
int rc = -1;
- struct List *last = NULL;
-
if (!(t = strchr(src, ':')))
return -1;
safe_asprintf(&scratch, "%s: %s", tag, value);
scratch[taglen] = 0; /* overwrite the colon as mutt_parse_rfc822_line expects */
value = skip_email_wsp(&scratch[taglen + 1]);
- mutt_parse_rfc822_line(e, NULL, scratch, value, 1, 0, 1, &last);
+ mutt_parse_rfc822_line(e, NULL, scratch, value, 1, 0, 1);
FREE(&scratch);
}
}