X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-mime%2Frfc822address.c;h=c6b12ab7d750927025ff707a81fbdc06cda94179;hp=9009d4072ba0df7d843e1dc9149ea1faa6fff876;hb=16534e98723674fa391e3fc29d2a07ce419c13dd;hpb=b934795055e8c16e6cb7c9687a4dce815cb300e6 diff --git a/lib-mime/rfc822address.c b/lib-mime/rfc822address.c index 9009d40..c6b12ab 100644 --- a/lib-mime/rfc822address.c +++ b/lib-mime/rfc822address.c @@ -26,40 +26,26 @@ * please see the file GPL in the top level source directory. */ -#include -#include -#include - -#include -#include -#include -#include +#include #include "mutt_idna.h" -void address_wipe(address_t *addr) -{ - p_delete(&addr->personal); - p_delete(&addr->mailbox); - address_delete(&addr->next); -} - - void rfc822_qualify(address_t *addr, const char *host) { - char *p; + if (!host) + return; for (; addr; addr = addr->next) { if (!addr->group && addr->mailbox && !strchr(addr->mailbox, '@')) { - p = p_new(char, m_strlen(addr->mailbox) + m_strlen(host) + 2); - sprintf(p, "%s@%s", addr->mailbox, host); /* __SPRINTF_CHECKED__ */ + char *p = p_new(char, m_strlen(addr->mailbox) + m_strlen(host) + 2); + sprintf(p, "%s@%s", addr->mailbox, host); p_delete(&addr->mailbox); addr->mailbox = p; } } } -address_t *address_dup(address_t *addr) +address_t *address_dup(const address_t *addr) { address_t *res = address_new(); @@ -69,7 +55,7 @@ address_t *address_dup(address_t *addr) return res; } -address_t *address_list_dup(address_t *addr) +address_t *address_list_dup(const address_t *addr) { address_t *res = NULL, **resp = &res; @@ -81,6 +67,26 @@ address_t *address_list_dup(address_t *addr) return res; } +/* given a list of addresses, return a list of unique addresses */ +void address_list_uniq(address_t *a) +{ + for (; a; a = a->next) { + address_t **b = &a->next; + + if (!a->mailbox) + continue; + + while (*b) { + if ((*b)->mailbox && !ascii_strcasecmp((*b)->mailbox, a->mailbox)) + { + address_t *pop = address_list_pop(b); + address_delete(&pop); + } else { + b = &(*b)->next; + } + } + } +} /****************************************************************************/ /* Parsing functions */ @@ -139,7 +145,7 @@ static const char *parse_comment(const char *s, static_buf *buf) case ')': level--; if (!level) - return s; + return s + 1; break; case '\\': @@ -250,7 +256,7 @@ parse_address(const char *s, static_buf *comment, address_t *cur) return s; } -address_t **rfc822_eotoken(address_t **last, static_buf *phrase, static_buf *comment) +static address_t **rfc822_eotoken(address_t **last, static_buf *phrase, static_buf *comment) { if (phrase->len) { const char *s; @@ -258,7 +264,7 @@ address_t **rfc822_eotoken(address_t **last, static_buf *phrase, static_buf *com s = parse_address(phrase->buf, comment, cur); if (s && *s && *s != ',' && *s != ';') { - address_delete(&cur); + address_list_wipe(&cur); return last; } @@ -289,7 +295,7 @@ address_t *rfc822_parse_adrlist(address_t *top, const char *s) stbuf_append_sp(&phrase); s = next_phrase(s, &phrase); if (!s) { - address_delete(&top); + address_list_wipe(&top); return NULL; } continue; @@ -298,7 +304,7 @@ address_t *rfc822_parse_adrlist(address_t *top, const char *s) stbuf_append_sp(&comment); s = parse_comment(s + 1, &comment); if (!s) { - address_delete(&top); + address_list_wipe(&top); return NULL; } continue; @@ -313,8 +319,8 @@ address_t *rfc822_parse_adrlist(address_t *top, const char *s) s = parse_address(skipspaces(s + 1), &comment, cur); if (!s || *s != '>' || !cur->mailbox) { - address_delete(&top); - address_delete(&cur); + address_list_wipe(&top); + address_list_wipe(&cur); return NULL; } @@ -383,90 +389,75 @@ rfc822_strcpy(char *buf, ssize_t buflen, const char *p, const char *specials) } } -ssize_t rfc822_write_address_single(char *buf, ssize_t buflen, - address_t *addr, int display) +ssize_t +rfc822_addrcpy(char *buf, ssize_t buflen, address_t *addr, int display) { ssize_t pos = 0; if (!addr) return 0; - buflen--; /* save room for the terminal nul */ - if (addr->personal) { pos = rfc822_strcpy(buf, buflen, addr->personal, RFC822Specials); - if (pos + 2 >= buflen) - goto done; - - buf[pos++] = ' '; - buf[pos++] = '<'; + pos += m_strcpy(buf + pos, buflen - pos, " <"); } if (addr->mailbox) { - if (!display) { - pos += m_strcpy(buf + pos, buflen - pos, addr->mailbox); - } else { - pos += m_strcpy(buf + pos, buflen - pos, mutt_addr_for_display(addr)); - } + pos += m_strcpy(buf + pos, buflen - pos, + display ? mutt_addr_for_display(addr) : addr->mailbox); if (addr->personal) { - if (pos + 1 >= buflen) - goto done; - buf[pos++] = '>'; + pos += m_strputc(buf + pos, buflen - pos, '>'); } if (addr->group) { - if (pos + 1 >= buflen) - goto done; - buf[pos++] = ':'; + pos += m_strputc(buf + pos, buflen - pos, ':'); } } else { - if (pos + 1 >= buflen) - goto done; - buf[pos++] = ';'; + pos += m_strputc(buf + pos, buflen - pos, ';'); } - done: - /* no need to check for length here since we already save space at the - beginning of this routine */ - buf[pos] = 0; return pos; } /* note: it is assumed that `buf' is nul terminated! */ ssize_t -rfc822_write_address(char *buf, ssize_t buflen, address_t *addr, int display) +rfc822_addrcat(char *buf, ssize_t buflen, address_t *addr, int display) { - ssize_t pos; + ssize_t pos = m_strnlen(buf, buflen); - buflen--; /* save room for the terminal nul */ - pos = m_strnlen(buf, buflen); - - if (pos) { - if (pos + 2 >= buflen) - goto done; - - buf[pos++] = ','; - buf[pos++] = ' '; - } + if (pos) + pos += m_strcpy(buf + pos, buflen - pos, ", "); for (; addr; addr = addr->next) { - pos += rfc822_write_address_single(buf + pos, buflen + 1 - pos, - addr, display); + pos += rfc822_addrcpy(buf + pos, buflen - pos, addr, display); if (!addr->group && addr->next && addr->next->mailbox) { /* if there is another address, and its not a group mailbox name or group terminator, add a comma to separate the addresses */ - if (pos + 2 >= buflen) - break; - - buf[pos++] = ','; - buf[pos++] = ' '; + pos += m_strcpy(buf + pos, buflen - pos, ", "); } } - done: - buf[pos] = '\0'; return pos; } +address_t *mutt_parse_adrlist(address_t *p, const char *s) +{ + /* check for a simple whitespace separated list of addresses */ + char *q = strpbrk(s, "\"<>():;,\\"); + char tmp[HUGE_STRING]; + + if (q) + return rfc822_parse_adrlist(p, s); + + m_strcpy(tmp, sizeof(tmp), s); + q = tmp; + while ((q = strtok(q, " \t"))) { + p = rfc822_parse_adrlist(p, q); + q = NULL; + } + + return p; +} +