From: Pietro Cerutti Date: Tue, 14 May 2019 11:53:21 +0000 (+0000) Subject: Convert Alias to use AddressList X-Git-Tag: 2019-10-25~200^2~59 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5fbc1df8b13c37729cec8238bf418e2fa9cfa375;p=neomutt Convert Alias to use AddressList --- diff --git a/addrbook.c b/addrbook.c index 6edc272da..3a92c0e6a 100644 --- a/addrbook.c +++ b/addrbook.c @@ -92,7 +92,7 @@ static const char *alias_format_str(char *buf, size_t buflen, size_t col, int co break; case 'r': addr[0] = '\0'; - mutt_addr_write(addr, sizeof(addr), alias->addr, true); + mutt_addresslist_write(addr, sizeof(addr), &alias->addr, true); snprintf(fmt, sizeof(fmt), "%%%ss", prec); snprintf(buf, buflen, fmt, addr); break; @@ -156,27 +156,32 @@ static int alias_sort_alias(const void *a, const void *b) */ static int alias_sort_address(const void *a, const void *b) { - struct Address *pa = (*(struct Alias **) a)->addr; - struct Address *pb = (*(struct Alias **) b)->addr; + struct AddressList *pal = &(*(struct Alias **) a)->addr; + struct AddressList *pbl = &(*(struct Alias **) b)->addr; int r; - if (pa == pb) + if (pal == pbl) r = 0; - else if (!pa) + else if (!pal) r = -1; - else if (!pb) + else if (!pbl) r = 1; - else if (pa->personal) + else { - if (pb->personal) - r = mutt_str_strcasecmp(pa->personal, pb->personal); + struct Address *pa = TAILQ_FIRST(pal)->addr; + struct Address *pb = TAILQ_FIRST(pbl)->addr; + if (pa->personal) + { + if (pb->personal) + r = mutt_str_strcasecmp(pa->personal, pb->personal); + else + r = 1; + } + else if (pb->personal) + r = -1; else - r = 1; + r = mutt_str_strcasecmp(pa->mailbox, pb->mailbox); } - else if (pb->personal) - r = -1; - else - r = mutt_str_strcasecmp(pa->mailbox, pb->mailbox); return RSORT(r); } @@ -293,14 +298,14 @@ new_aliases: { if (alias_table[i]->tagged) { - mutt_addr_write(buf, buflen, alias_table[i]->addr, true); + mutt_addresslist_write(buf, buflen, &alias_table[i]->addr, true); t = -1; } } if (t != -1) { - mutt_addr_write(buf, buflen, alias_table[t]->addr, true); + mutt_addresslist_write(buf, buflen, &alias_table[t]->addr, true); } mutt_menu_pop_current(menu); diff --git a/address/address.c b/address/address.c index 8cdf10b5f..35f1a41ce 100644 --- a/address/address.c +++ b/address/address.c @@ -459,12 +459,11 @@ void mutt_addresslist_free(struct AddressList **al) * @retval ptr Top of the address list * @retval NULL Error */ -struct Address *mutt_addr_parse_list(struct Address *top, const char *s) +void mutt_addresslist_parse(struct AddressList *al, const char *s) { if (!s) - return NULL; + return; - struct AddressList *al = mutt_addr_to_addresslist(top); char comment[1024], phrase[1024]; size_t phraselen = 0, commentlen = 0; AddressError = 0; @@ -503,8 +502,8 @@ struct Address *mutt_addr_parse_list(struct Address *top, const char *s) s = next_token(s, comment, &commentlen, sizeof(comment) - 1); if (!s) { - mutt_addresslist_free(&al); - return NULL; + mutt_addresslist_free_all(al); + return; } break; @@ -514,8 +513,8 @@ struct Address *mutt_addr_parse_list(struct Address *top, const char *s) s = parse_quote(s + 1, phrase, &phraselen, sizeof(phrase) - 1); if (!s) { - mutt_addresslist_free(&al); - return NULL; + mutt_addresslist_free_all(al); + return; } break; @@ -564,9 +563,9 @@ struct Address *mutt_addr_parse_list(struct Address *top, const char *s) s = parse_route_addr(s + 1, comment, &commentlen, sizeof(comment) - 1, a); if (!s) { - mutt_addresslist_free(&al); + mutt_addresslist_free_all(al); free_address(&a); - return NULL; + return; } mutt_addresslist_append(al, a); phraselen = 0; @@ -580,8 +579,8 @@ struct Address *mutt_addr_parse_list(struct Address *top, const char *s) s = next_token(s, phrase, &phraselen, sizeof(phrase) - 1); if (!s) { - mutt_addresslist_free(&al); - return NULL; + mutt_addresslist_free_all(al); + return; } break; } // switch (*s) @@ -605,9 +604,17 @@ struct Address *mutt_addr_parse_list(struct Address *top, const char *s) last->addr->personal = mutt_str_strdup(comment); } } +} + +struct Address *mutt_addr_parse_list(struct Address *top, const char *s) +{ + if (!s) + return NULL; + struct AddressList *al = mutt_addr_to_addresslist(top); + mutt_addresslist_parse(al, s); top = mutt_addresslist_to_addr(al); - mutt_addresslist_free(&al); + FREE(&al); return top; } @@ -619,10 +626,10 @@ struct Address *mutt_addr_parse_list(struct Address *top, const char *s) * * The email addresses can be separated by whitespace or commas. */ -struct Address *mutt_addr_parse_list2(struct Address *p, const char *s) +void mutt_addresslist_parse2(struct AddressList *al, const char *s) { if (!s) - return NULL; + return; /* check for a simple whitespace separated list of addresses */ const char *q = strpbrk(s, "\"<>():;,\\"); @@ -633,14 +640,24 @@ struct Address *mutt_addr_parse_list2(struct Address *p, const char *s) char *r = tmp->data; while ((r = strtok(r, " \t"))) { - p = mutt_addr_parse_list(p, r); + mutt_addresslist_parse(al, r); r = NULL; } mutt_buffer_free(&tmp); } else - p = mutt_addr_parse_list(p, s); + mutt_addresslist_parse(al, s); +} +struct Address *mutt_addr_parse_list2(struct Address *p, const char *s) +{ + if (!s) + return NULL; + + struct AddressList *al = mutt_addr_to_addresslist(p); + mutt_addresslist_parse2(al, s); + p = mutt_addresslist_to_addr(al); + FREE(&al); return p; } @@ -1202,9 +1219,9 @@ done: * * @note It is assumed that `buf` is nul terminated! */ -size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display) +size_t mutt_addresslist_write(char *buf, size_t buflen, struct AddressList *al, bool display) { - if (!buf || !addr) + if (!buf || !al) return 0; char *pbuf = buf; @@ -1229,7 +1246,6 @@ size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool disp buflen--; } - struct AddressList *al = mutt_addr_to_addresslist(addr); struct AddressNode *np = NULL; TAILQ_FOREACH(np, al, entries) { @@ -1262,14 +1278,20 @@ size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool disp } } - mutt_addresslist_to_addr(al); - FREE(&al); - done: *pbuf = '\0'; return pbuf - buf; } +size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display) +{ + struct AddressList *al = mutt_addr_to_addresslist(addr); + size_t ret = mutt_addresslist_write(buf, buflen, al, display); + mutt_addresslist_to_addr(al); + FREE(&al); + return ret; +} + /** * mutt_addrlist_to_intl - Convert an Address list to Punycode * @param[in] a Address list to modify @@ -1277,7 +1299,7 @@ done: * @retval 0 Success, all addresses converted * @retval -1 Error, err will be set to the failed address */ -int mutt_addrlist_to_intl(struct Address *a, char **err) +int mutt_addresslist_to_intl(struct AddressList *al, char **err) { char *user = NULL, *domain = NULL; char *intl_mailbox = NULL; @@ -1286,7 +1308,6 @@ int mutt_addrlist_to_intl(struct Address *a, char **err) if (err) *err = NULL; - struct AddressList *al = mutt_addr_to_addresslist(a); struct AddressNode *an = NULL; TAILQ_FOREACH(an, al, entries) { @@ -1312,9 +1333,15 @@ int mutt_addrlist_to_intl(struct Address *a, char **err) mutt_addr_set_intl(an->addr, intl_mailbox); } - mutt_addresslist_to_addr(al); - FREE(&al); + return rc; +} +int mutt_addrlist_to_intl(struct Address *a, char **err) +{ + struct AddressList *al = mutt_addr_to_addresslist(a); + int rc = mutt_addresslist_to_intl(al, err); + a = mutt_addresslist_to_addr(al); + FREE(&al); return rc; } diff --git a/address/address.h b/address/address.h index 2428b1e31..46cf871a7 100644 --- a/address/address.h +++ b/address/address.h @@ -103,5 +103,9 @@ void mutt_addresslist_clear(struct AddressList *al); void mutt_addresslist_free(struct AddressList **al); void mutt_addresslist_free_one(struct AddressList *al, struct AddressNode *anode); void mutt_addresslist_free_all(struct AddressList *al); +size_t mutt_addresslist_write(char *buf, size_t buflen, struct AddressList* addr, bool display); +void mutt_addresslist_parse(struct AddressList *top, const char *s); +void mutt_addresslist_parse2(struct AddressList *top, const char *s); +int mutt_addresslist_to_intl(struct AddressList *a, char **err); #endif /* MUTT_EMAIL_ADDRESS_H */ diff --git a/address/group.c b/address/group.c index 400f526ed..61ddc31d8 100644 --- a/address/group.c +++ b/address/group.c @@ -238,19 +238,25 @@ static int group_remove_regex(struct Group *g, const char *s) * @param head GroupList to add to * @param a Address to add */ -void mutt_grouplist_add_addrlist(struct GroupList *head, struct Address *a) +void mutt_grouplist_add_addresslist(struct GroupList *head, struct AddressList *al) { - if (!head || !a) + if (!head || !al) return; - struct AddressList *al = mutt_addr_to_addresslist(a); - struct GroupNode *np = NULL; STAILQ_FOREACH(np, head, entries) { group_add_addrlist(np->group, al); } +} +void mutt_grouplist_add_addrlist(struct GroupList *head, struct Address *a) +{ + if (!head || !a) + return; + + struct AddressList *al = mutt_addr_to_addresslist(a); + mutt_grouplist_add_addresslist(head, al); mutt_addresslist_to_addr(al); FREE(&al); } diff --git a/address/group.h b/address/group.h index 10a905348..000156878 100644 --- a/address/group.h +++ b/address/group.h @@ -56,6 +56,7 @@ void mutt_grouplist_init(void); void mutt_grouplist_free(void); void mutt_grouplist_add(struct GroupList *head, struct Group *group); void mutt_grouplist_add_addrlist(struct GroupList *head, struct Address *a); +void mutt_grouplist_add_addresslist(struct GroupList *head, struct AddressList *a); int mutt_grouplist_add_regex(struct GroupList *head, const char *s, int flags, struct Buffer *err); void mutt_grouplist_destroy(struct GroupList *head); diff --git a/alias.c b/alias.c index dc3c8d8aa..e1e07fca0 100644 --- a/alias.c +++ b/alias.c @@ -60,7 +60,8 @@ */ static struct Address *expand_aliases_r(struct Address *a, struct ListHead *expn) { - struct Address *head = NULL, *last = NULL, *t = NULL, *w = NULL; + struct Address *head = NULL, *last = NULL, *w = NULL; + struct AddressList *t = NULL; bool i; const char *fqdn = NULL; @@ -87,7 +88,9 @@ static struct Address *expand_aliases_r(struct Address *a, struct ListHead *expn if (!i) { mutt_list_insert_head(expn, mutt_str_strdup(a->mailbox)); - w = mutt_addr_copy_list(t, false); + struct AddressList *al2 = mutt_addresslist_copy(t, false); + w = mutt_addresslist_to_addr(al2); + FREE(&al2); w = expand_aliases_r(w, expn); if (head) last->next = w; @@ -99,10 +102,10 @@ static struct Address *expand_aliases_r(struct Address *a, struct ListHead *expn while (last && last->next) last = last->next; } - t = a; + struct Address *tmp = a; a = a->next; - t->next = NULL; - mutt_addr_free(&t); + tmp->next = NULL; + mutt_addr_free(&tmp); continue; } else @@ -142,6 +145,19 @@ static struct Address *expand_aliases_r(struct Address *a, struct ListHead *expn return head; } +/** + * mutt_alias_new - Create a new Alias + * @retval ptr Newly allocated Alias + * + * Free the result with mutt_alias_free() + */ +struct Alias *mutt_alias_new() +{ + struct Alias *a = mutt_mem_calloc(1, sizeof(struct Alias)); + TAILQ_INIT(&a->addr); + return a; +} + /** * write_safe_address - Defang malicious email addresses * @param fp File to write to @@ -276,14 +292,14 @@ static bool string_is_address(const char *str, const char *u, const char *d) * * @note The search is case-insensitive */ -struct Address *mutt_alias_lookup(const char *s) +struct AddressList *mutt_alias_lookup(const char *s) { struct Alias *a = NULL; TAILQ_FOREACH(a, &Aliases, entries) { if (mutt_str_strcasecmp(s, a->name) == 0) - return a->addr; + return &a->addr; } return NULL; } @@ -422,7 +438,7 @@ retry_name: } } - new = mutt_mem_calloc(1, sizeof(struct Alias)); + new = mutt_alias_new(); new->name = mutt_str_strdup(buf); mutt_addrlist_to_local(addr); @@ -442,16 +458,16 @@ retry_name: return; } - new->addr = mutt_addr_parse_list(new->addr, buf); - if (!new->addr) + mutt_addresslist_parse(&new->addr, buf); + if (TAILQ_EMPTY(&new->addr)) BEEP(); - if (mutt_addrlist_to_intl(new->addr, &err)) + if (mutt_addresslist_to_intl(&new->addr, &err)) { mutt_error(_("Bad IDN: '%s'"), err); FREE(&err); continue; } - } while (!new->addr); + } while (TAILQ_EMPTY(&new->addr)); if (addr && addr->personal && !mutt_is_mail_list(addr)) mutt_str_strfcpy(buf, addr->personal, sizeof(buf)); @@ -463,10 +479,10 @@ retry_name: mutt_alias_free(&new); return; } - mutt_str_replace(&new->addr->personal, buf); + mutt_str_replace(&TAILQ_FIRST(&new->addr)->addr->personal, buf); buf[0] = '\0'; - mutt_addr_write(buf, sizeof(buf), new->addr, true); + mutt_addresslist_write(buf, sizeof(buf), &new->addr, true); snprintf(prompt, sizeof(prompt), _("[%s = %s] Accept?"), new->name, buf); if (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES) { @@ -515,7 +531,7 @@ retry_name: recode_buf(buf, sizeof(buf)); fprintf(fp_alias, "alias %s ", buf); buf[0] = '\0'; - mutt_addr_write(buf, sizeof(buf), new->addr, false); + mutt_addresslist_write(buf, sizeof(buf), &new->addr, false); recode_buf(buf, sizeof(buf)); write_safe_address(fp_alias, buf); fputc('\n', fp_alias); @@ -556,12 +572,13 @@ void mutt_alias_add_reverse(struct Alias *t) /* Note that the address mailbox should be converted to intl form * before using as a key in the hash. This is currently done * by all callers, but added here mostly as documentation. */ - mutt_addrlist_to_intl(t->addr, NULL); + mutt_addresslist_to_intl(&t->addr, NULL); - for (struct Address *ap = t->addr; ap; ap = ap->next) + struct AddressNode *an = NULL; + TAILQ_FOREACH(an, &t->addr, entries) { - if (!ap->group && ap->mailbox) - mutt_hash_insert(ReverseAliases, ap->mailbox, ap); + if (!an->addr->group && an->addr->mailbox) + mutt_hash_insert(ReverseAliases, an->addr->mailbox, an->addr); } } @@ -576,12 +593,13 @@ void mutt_alias_delete_reverse(struct Alias *t) /* If the alias addresses were converted to local form, they won't * match the hash entries. */ - mutt_addrlist_to_intl(t->addr, NULL); + mutt_addresslist_to_intl(&t->addr, NULL); - for (struct Address *ap = t->addr; ap; ap = ap->next) + struct AddressNode *an = NULL; + TAILQ_FOREACH(an, &t->addr, entries) { - if (!ap->group && ap->mailbox) - mutt_hash_delete(ReverseAliases, ap->mailbox, ap); + if (!an->addr->group && an->addr->mailbox) + mutt_hash_delete(ReverseAliases, an->addr->mailbox, an->addr); } } @@ -742,7 +760,7 @@ void mutt_alias_free(struct Alias **p) mutt_alias_delete_reverse(*p); FREE(&(*p)->name); - mutt_addr_free(&(*p)->addr); + mutt_addresslist_free_all(&((*p)->addr)); FREE(p); } diff --git a/alias.h b/alias.h index 478c47711..f42522c50 100644 --- a/alias.h +++ b/alias.h @@ -26,8 +26,8 @@ #include #include #include "mutt/mutt.h" +#include "address/address.h" -struct Address; struct Envelope; /** @@ -36,7 +36,7 @@ struct Envelope; struct Alias { char *name; - struct Address *addr; + struct AddressList addr; bool tagged; bool del; short num; @@ -44,10 +44,11 @@ struct Alias }; TAILQ_HEAD(AliasList, Alias); -void mutt_alias_create(struct Envelope *cur, struct Address *iaddr); +struct Alias *mutt_alias_new(void); void mutt_alias_free(struct Alias **p); +void mutt_alias_create(struct Envelope *cur, struct Address *iaddr); void mutt_aliaslist_free(struct AliasList *a_list); -struct Address *mutt_alias_lookup(const char *s); +struct AddressList *mutt_alias_lookup(const char *s); void mutt_expand_aliases_env(struct Envelope *env); struct Address *mutt_expand_aliases(struct Address *a); struct Address *mutt_get_address(struct Envelope *env, const char **pfxp); diff --git a/init.c b/init.c index 18e62fc1a..45749e3bf 100644 --- a/init.c +++ b/init.c @@ -912,7 +912,7 @@ static enum CommandResult parse_alias(struct Buffer *buf, struct Buffer *s, if (!tmp) { /* create a new alias */ - tmp = mutt_mem_calloc(1, sizeof(struct Alias)); + tmp = mutt_alias_new(); tmp->name = mutt_str_strdup(buf->data); TAILQ_INSERT_TAIL(&Aliases, tmp, entries); /* give the main addressbook code a chance */ @@ -923,7 +923,7 @@ static enum CommandResult parse_alias(struct Buffer *buf, struct Buffer *s, { mutt_alias_delete_reverse(tmp); /* override the previous value */ - mutt_addr_free(&tmp->addr); + mutt_addresslist_free_all(&tmp->addr); if (CurrentMenu == MENU_ALIAS) mutt_menu_set_current_redraw_full(); } @@ -931,27 +931,31 @@ static enum CommandResult parse_alias(struct Buffer *buf, struct Buffer *s, mutt_extract_token(buf, s, MUTT_TOKEN_QUOTE | MUTT_TOKEN_SPACE | MUTT_TOKEN_SEMICOLON); mutt_debug(5, "Second token is '%s'\n", buf->data); - tmp->addr = mutt_addr_parse_list2(tmp->addr, buf->data); + mutt_addresslist_parse2(&tmp->addr, buf->data); - if (mutt_addrlist_to_intl(tmp->addr, &estr)) + if (mutt_addresslist_to_intl(&tmp->addr, &estr)) { mutt_buffer_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, tmp->name); FREE(&estr); goto bail; } - mutt_grouplist_add_addrlist(&gc, tmp->addr); + mutt_grouplist_add_addresslist(&gc, &tmp->addr); mutt_alias_add_reverse(tmp); if (C_DebugLevel > LL_DEBUG4) { /* A group is terminated with an empty address, so check a->mailbox */ - for (struct Address *a = tmp->addr; a && a->mailbox; a = a->next) + struct AddressNode *an = NULL; + TAILQ_FOREACH(an, &tmp->addr, entries) { - if (a->group) - mutt_debug(5, " Group %s\n", a->mailbox); + if (!an->addr->mailbox) + break; + + if (an->addr->group) + mutt_debug(5, " Group %s\n", an->addr->mailbox); else - mutt_debug(5, " %s\n", a->mailbox); + mutt_debug(5, " %s\n", an->addr->mailbox); } } mutt_grouplist_destroy(&gc); diff --git a/main.c b/main.c index 93f1ab28f..5c7721381 100644 --- a/main.c +++ b/main.c @@ -759,18 +759,17 @@ int main(int argc, char *argv[], char *envp[]) if (!STAILQ_EMPTY(&alias_queries)) { rc = 0; - struct Address *a = NULL; for (; optind < argc; optind++) mutt_list_insert_tail(&alias_queries, mutt_str_strdup(argv[optind])); struct ListNode *np = NULL; STAILQ_FOREACH(np, &alias_queries, entries) { - a = mutt_alias_lookup(np->data); - if (a) + struct AddressList *al = mutt_alias_lookup(np->data); + if (al) { /* output in machine-readable form */ - mutt_addrlist_to_intl(a, NULL); - mutt_write_address_list(a, stdout, 0, 0); + mutt_addresslist_to_intl(al, NULL); + mutt_write_addresslist(al, stdout, 0, 0); } else { diff --git a/muttlib.c b/muttlib.c index ad20439e2..66978536f 100644 --- a/muttlib.c +++ b/muttlib.c @@ -217,7 +217,9 @@ void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex) case '@': { - struct Address *alias = mutt_alias_lookup(s + 1); + struct AddressList *al = mutt_addresslist_copy(mutt_alias_lookup(s + 1), false); + struct Address *alias = mutt_addresslist_to_addr(al); + FREE(&al); if (alias) { struct Email *e = mutt_email_new(); diff --git a/mx.c b/mx.c index 68f2a9552..5a04ba328 100644 --- a/mx.c +++ b/mx.c @@ -1340,7 +1340,9 @@ int mx_path_canon(char *buf, size_t buflen, const char *folder, enum MailboxType else if (buf[0] == '@') { /* elm compatibility, @ expands alias to user name */ - struct Address *alias = mutt_alias_lookup(buf + 1); + struct AddressList *al = mutt_addresslist_copy(mutt_alias_lookup(buf + 1), false); + struct Address *alias = mutt_addresslist_to_addr(al); + FREE(&al); if (!alias) break; diff --git a/sendlib.c b/sendlib.c index 849d681bd..85d6b9543 100644 --- a/sendlib.c +++ b/sendlib.c @@ -1753,16 +1753,15 @@ struct Body *mutt_remove_multipart(struct Body *b) * So we can handle very large recipient lists without needing a huge temporary * buffer in memory */ -void mutt_write_address_list(struct Address *addr, FILE *fp, int linelen, bool display) +void mutt_write_addresslist(struct AddressList *al, FILE *fp, int linelen, bool display) { - struct Address *tmp = NULL; char buf[1024]; int count = 0; - while (addr) + struct AddressNode *an = NULL; + TAILQ_FOREACH(an, al, entries) { - tmp = addr->next; - addr->next = NULL; + struct Address *addr = an->addr; buf[0] = '\0'; mutt_addr_write(buf, sizeof(buf), addr, display); size_t len = mutt_str_strlen(buf); @@ -1781,17 +1780,23 @@ void mutt_write_address_list(struct Address *addr, FILE *fp, int linelen, bool d linelen += len; } fputs(buf, fp); - addr->next = tmp; - if (!addr->group && addr->next && addr->next->mailbox) + struct AddressNode *next = TAILQ_NEXT(an, entries); + if (!addr->group && next && next->addr->mailbox) { linelen++; fputc(',', fp); } - addr = addr->next; count++; } fputc('\n', fp); } +void mutt_write_address_list(struct Address *addr, FILE *fp, int linelen, bool display) +{ + struct AddressList *al = mutt_addr_to_addresslist(addr); + mutt_write_addresslist(al, fp, linelen, display); + mutt_addresslist_to_addr(al); + FREE(&al); +} /** * mutt_write_references - Add the message references to a list diff --git a/sendlib.h b/sendlib.h index 11ceb1d1b..71c2b05b3 100644 --- a/sendlib.h +++ b/sendlib.h @@ -28,6 +28,7 @@ #include "copy.h" struct Address; +struct AddressList; struct Body; struct Email; struct Envelope; @@ -83,6 +84,7 @@ void mutt_stamp_attachment(struct Body *a); void mutt_unprepare_envelope(struct Envelope *env); void mutt_update_encoding(struct Body *a); void mutt_write_address_list(struct Address *addr, FILE *fp, int linelen, bool display); +void mutt_write_addresslist(struct AddressList *addr, FILE *fp, int linelen, bool display); int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, char *fcc, char **finalpath); int mutt_write_mime_body(struct Body *a, FILE *fp); int mutt_write_mime_header(struct Body *a, FILE *fp);