* please see the file GPL in the top level source directory.
*/
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-#include <lib-lib/mem.h>
-#include <lib-lib/str.h>
-#include <lib-lib/ascii.h>
-#include <lib-lib/macros.h>
+#include <lib-lib/lib-lib.h>
#include "mutt_idna.h"
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();
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;
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 */
case ')':
level--;
if (!level)
- return s;
+ return s + 1;
break;
case '\\':
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;
s = parse_address(phrase->buf, comment, cur);
if (s && *s && *s != ',' && *s != ';') {
- address_delete(&cur);
+ address_list_wipe(&cur);
return last;
}
stbuf_append_sp(&phrase);
s = next_phrase(s, &phrase);
if (!s) {
- address_delete(&top);
+ address_list_wipe(&top);
return NULL;
}
continue;
stbuf_append_sp(&comment);
s = parse_comment(s + 1, &comment);
if (!s) {
- address_delete(&top);
+ address_list_wipe(&top);
return NULL;
}
continue;
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;
}
}
}
-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;
-
- buflen--; /* save room for the terminal nul */
- pos = m_strnlen(buf, buflen);
+ ssize_t 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;
+}
+