#include "mutt_idna.h"
-
-#define terminate_string(a, b, c) do { if ((b) < (c)) a[(b)] = 0; else \
- a[(c)] = 0; } while (0)
-
-#define terminate_buffer(a, b) terminate_string(a, b, sizeof (a) - 1)
-
-
const char RFC822Specials[] = "@.,:;<>[]\\\"()";
-#define is_special(x) strchr(RFC822Specials,x)
-
-int RFC822Error = 0;
+void address_wipe(address_t *addr)
+{
+ p_delete(&addr->personal);
+ p_delete(&addr->mailbox);
+ address_delete(&addr->next);
+}
-/* these must defined in the same order as the numerated errors given in rfc822.h */
-const char *RFC822Errors[] = {
- "out of memory",
- "mismatched parenthesis",
- "mismatched quotes",
- "bad route in <>",
- "bad address in <>",
- "bad address spec"
-};
-void rfc822_dequote_comment (char *s)
+void rfc822_qualify(address_t *addr, const char *host)
{
- char *w = s;
-
- for (; *s; s++) {
- if (*s == '\\') {
- if (!*++s)
- break; /* error? */
- *w++ = *s;
- }
- else if (*s != '\"') {
- if (w != s)
- *w = *s;
- w++;
+ char *p;
+
+ 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__ */
+ p_delete(&addr->mailbox);
+ addr->mailbox = p;
+ }
}
- }
- *w = 0;
}
-void rfc822_free_address (address_t ** p)
+address_t *address_dup(address_t *addr)
{
- address_t *t;
-
- while (*p) {
- t = *p;
- *p = (*p)->next;
- p_delete(&t->personal);
- p_delete(&t->mailbox);
- p_delete(&t);
- }
+ address_t *res = address_new();
+
+ res->personal = m_strdup(addr->personal);
+ res->mailbox = m_strdup(addr->mailbox);
+ res->group = addr->group;
+ return res;
}
-static const char *parse_comment (const char *s,
- char *comment, size_t * commentlen,
- size_t commentmax)
+address_t *address_list_dup(address_t *addr)
{
- int level = 1;
+ address_t *res = NULL, **resp = &res;
- while (*s && level) {
- if (*s == '(')
- level++;
- else if (*s == ')') {
- if (--level == 0) {
- s++;
- break;
- }
+ for (; addr; addr = addr->next) {
+ *resp = address_dup(addr);
+ resp = &(*resp)->next;
}
- else if (*s == '\\') {
- if (!*++s)
- break;
- }
- if (*commentlen < commentmax)
- comment[(*commentlen)++] = *s;
- s++;
- }
- if (level) {
- RFC822Error = ERR_MISMATCH_PAREN;
- return NULL;
- }
- return s;
+
+ return res;
}
-static const char *parse_quote (const char *s, char *token, size_t * tokenlen,
- size_t tokenmax)
-{
- if (*tokenlen < tokenmax)
- token[(*tokenlen)++] = '"';
- while (*s) {
- if (*tokenlen < tokenmax)
- token[*tokenlen] = *s;
- if (*s == '"') {
- (*tokenlen)++;
- return (s + 1);
- }
- if (*s == '\\') {
- if (!*++s)
- break;
- if (*tokenlen < tokenmax)
- token[*tokenlen] = *s;
+/****************************************************************************/
+/* Parsing functions */
+/****************************************************************************/
+
+typedef struct static_buf {
+ char buf[STRING];
+ int len;
+} static_buf;
+
+static inline void stbuf_append(static_buf *buf, int c) {
+ if (buf->len < ssizeof(buf->buf) - 1) {
+ buf->buf[buf->len++] = c;
+ buf->buf[buf->len] = '\0';
}
- (*tokenlen)++;
- s++;
- }
- RFC822Error = ERR_MISMATCH_QUOTE;
- return NULL;
}
-static const char *next_token (const char *s, char *token, size_t * tokenlen,
- size_t tokenmax)
-{
- if (*s == '(')
- return (parse_comment (s + 1, token, tokenlen, tokenmax));
- if (*s == '"')
- return (parse_quote (s + 1, token, tokenlen, tokenmax));
- if (is_special (*s)) {
- if (*tokenlen < tokenmax)
- token[(*tokenlen)++] = *s;
- return (s + 1);
- }
- while (*s) {
- if (ISSPACE ((unsigned char) *s) || is_special (*s))
- break;
- if (*tokenlen < tokenmax)
- token[(*tokenlen)++] = *s;
- s++;
- }
- return s;
+static inline void stbuf_append_sp(static_buf *buf) {
+ if (buf->len)
+ stbuf_append(buf, ' ');
}
-static const char *parse_mailboxdomain (const char *s, const char *nonspecial,
- char *mailbox, size_t * mailboxlen,
- size_t mailboxmax, char *comment,
- size_t * commentlen,
- size_t commentmax)
+static char *rfc822_dequote_comment(static_buf *buf)
{
- const char *ps;
-
- while (*s) {
- s = vskipspaces(s);
- if (strchr (nonspecial, *s) == NULL && is_special (*s))
- return s;
+ char *res = p_new(char, buf->len + 1);
+ char *q = res;
+ char *p = buf->buf;
+ int i;
+
+ for (i = 0; i < buf->len; i++) {
+ if (p[i] == '\"')
+ continue;
+
+ if (p[i] == '\\') {
+ if (++i >= buf->len) /* should not happen */
+ break;
+ }
- if (*s == '(') {
- if (*commentlen && *commentlen < commentmax)
- comment[(*commentlen)++] = ' ';
- ps = next_token (s, comment, commentlen, commentmax);
+ *q++ = p[i];
}
- else
- ps = next_token (s, mailbox, mailboxlen, mailboxmax);
- if (!ps)
- return NULL;
- s = ps;
- }
-
- return s;
+
+ *q++ = '\0';
+ return res;
}
-static const char *parse_address (const char *s,
- char *token, size_t * tokenlen,
- size_t tokenmax, char *comment,
- size_t * commentlen, size_t commentmax,
- address_t * addr)
+static const char *parse_comment(const char *s, static_buf *buf)
{
- s = parse_mailboxdomain (s, ".\"(\\",
- token, tokenlen, tokenmax,
- comment, commentlen, commentmax);
- if (!s)
- return NULL;
+ int level = 1;
+
+ for (; *s; s++) {
+ switch (*s) {
+ case '(':
+ level++;
+ break;
+
+ case ')':
+ level--;
+ if (!level)
+ return s;
+ break;
+
+ case '\\':
+ s++; /* if *++s is NUL it will be an error anyway */
+ break;
+
+ default:
+ break;
+ }
- if (*s == '@') {
- if (*tokenlen < tokenmax)
- token[(*tokenlen)++] = '@';
- s = parse_mailboxdomain (s + 1, ".([]\\",
- token, tokenlen, tokenmax,
- comment, commentlen, commentmax);
- if (!s)
- return NULL;
- }
+ stbuf_append(buf, *s);
+ }
- terminate_string (token, *tokenlen, tokenmax);
- addr->mailbox = m_strdup(token);
+ return NULL;
+}
- if (*commentlen && !addr->personal) {
- terminate_string (comment, *commentlen, commentmax);
- addr->personal = m_strdup(comment);
- }
+static const char *parse_quote(const char *s, static_buf *buf)
+{
+ for (; *s; s++) {
+ switch (*s) {
+ case '"':
+ stbuf_append(buf, *s);
+ return s + 1;
+
+ case '\\':
+ if (!*++s)
+ return NULL;
+ /* fallthrough */
+
+ default:
+ stbuf_append(buf, *s);
+ break;
+ }
+ }
- return s;
+ return NULL;
}
-static const char *parse_route_addr (const char *s,
- char *comment, size_t * commentlen,
- size_t commentmax, address_t * addr)
+#define is_special(x) strchr(RFC822Specials,x)
+
+static const char *next_phrase(const char *s, static_buf *buf)
{
- char token[STRING];
- size_t tokenlen = 0;
-
- s = vskipspaces(s);
-
- /* find the end of the route */
- if (*s == '@') {
- while (s && *s == '@') {
- if (tokenlen < sizeof (token) - 1)
- token[tokenlen++] = '@';
- s = parse_mailboxdomain (s + 1, ",.\\[](", token,
- &tokenlen, sizeof (token) - 1,
- comment, commentlen, commentmax);
+ if (*s == '"') {
+ stbuf_append(buf, '"');
+ return parse_quote(s + 1, buf);
}
- if (!s || *s != ':') {
- RFC822Error = ERR_BAD_ROUTE;
- return NULL; /* invalid route */
+
+ if (is_special(*s)) {
+ stbuf_append(buf, *s);
+ return s + 1;
}
- if (tokenlen < sizeof (token) - 1)
- token[tokenlen++] = ':';
- s++;
- }
+ while (*s) {
+ if (ISSPACE(*s) || is_special(*s))
+ break;
+ stbuf_append(buf, *s++);
+ }
- if ((s =
- parse_address (s, token, &tokenlen, sizeof (token) - 1, comment,
- commentlen, commentmax, addr)) == NULL)
- return NULL;
+ return s;
+}
- if (*s != '>') {
- RFC822Error = ERR_BAD_ROUTE_ADDR;
- return NULL;
- }
+static const char *
+parse_mailboxdomain(const char *s, const char *nonspecial, static_buf *mbox,
+ static_buf *comment)
+{
+ while (*s) {
+ s = skipspaces(s);
- if (!addr->mailbox)
- addr->mailbox = m_strdup("@");
+ if (!strchr(nonspecial, *s) && is_special(*s))
+ return s;
- s++;
- return s;
-}
+ if (*s == '(') {
+ stbuf_append_sp(comment);
+ s = parse_comment(s + 1, comment);
+ } else {
+ s = next_phrase(s, mbox);
+ }
-static const char *parse_addr_spec (const char *s,
- char *comment, size_t * commentlen,
- size_t commentmax, address_t * addr)
-{
- char token[STRING];
- size_t tokenlen = 0;
-
- s =
- parse_address (s, token, &tokenlen, sizeof (token) - 1, comment,
- commentlen, commentmax, addr);
- if (s && *s && *s != ',' && *s != ';') {
- RFC822Error = ERR_BAD_ADDR_SPEC;
- return NULL;
- }
- return s;
-}
+ if (!s)
+ return NULL;
+ }
-static void
-add_addrspec (address_t ** top, address_t ** last, const char *phrase,
- char *comment, size_t * commentlen, size_t commentmax)
-{
- address_t *cur = rfc822_new_address ();
-
- if (parse_addr_spec (phrase, comment, commentlen, commentmax, cur) == NULL) {
- rfc822_free_address (&cur);
- return;
- }
-
- if (*last)
- (*last)->next = cur;
- else
- *top = cur;
- *last = cur;
+ return s;
}
-address_t *rfc822_parse_adrlist (address_t * top, const char *s)
+static const char *
+parse_address(const char *s, static_buf *comment, address_t *cur)
{
- int ws_pending;
- const char *begin, *ps;
- char comment[STRING], phrase[STRING];
- size_t phraselen = 0, commentlen = 0;
- address_t *cur, *last = NULL;
-
- RFC822Error = 0;
-
- last = top;
- while (last && last->next)
- last = last->next;
-
- ws_pending = isspace ((unsigned char) *s);
-
- begin = s = vskipspaces(s);
- while (*s) {
- if (*s == ',') {
- if (phraselen) {
- terminate_buffer (phrase, phraselen);
- add_addrspec (&top, &last, phrase, comment, &commentlen,
- sizeof (comment) - 1);
- }
- else if (commentlen && last && !last->personal) {
- terminate_buffer (comment, commentlen);
- last->personal = m_strdup(comment);
- }
-
- commentlen = 0;
- phraselen = 0;
- s++;
- begin = vskipspaces(s);
- }
- else if (*s == '(') {
- if (commentlen && commentlen < sizeof (comment) - 1)
- comment[commentlen++] = ' ';
- if ((ps =
- next_token (s, comment, &commentlen,
- sizeof (comment) - 1)) == NULL) {
- rfc822_free_address (&top);
+ static_buf token = {"", 0};
+
+ s = parse_mailboxdomain(s, ".\"(\\", &token, comment);
+ if (!s)
return NULL;
- }
- s = ps;
- }
- else if (*s == ':') {
- cur = rfc822_new_address ();
- terminate_buffer (phrase, phraselen);
- cur->mailbox = m_strdup(phrase);
- cur->group = 1;
-
- if (last)
- last->next = cur;
- else
- top = cur;
- last = cur;
-
- phraselen = 0;
- commentlen = 0;
- s++;
- begin = vskipspaces(s);
- }
- else if (*s == ';') {
- if (phraselen) {
- terminate_buffer (phrase, phraselen);
- add_addrspec (&top, &last, phrase, comment, &commentlen,
- sizeof (comment) - 1);
- }
- else if (commentlen && last && !last->personal) {
- terminate_buffer (comment, commentlen);
- last->personal = m_strdup(comment);
- }
-
- /* add group terminator */
- cur = rfc822_new_address ();
- if (last) {
- last->next = cur;
- last = cur;
- }
-
- phraselen = 0;
- commentlen = 0;
- s++;
- begin = vskipspaces(s);
+
+ if (*s == '@') {
+ stbuf_append(&token, '@');
+ s = parse_mailboxdomain(s + 1, ".([]\\", &token, comment);
+ if (!s)
+ return NULL;
}
- else if (*s == '<') {
- terminate_buffer (phrase, phraselen);
- cur = rfc822_new_address ();
- if (phraselen) {
- if (cur->personal)
- p_delete(&cur->personal);
- /* if we get something like "Michael R. Elkins" remove the quotes */
- rfc822_dequote_comment (phrase);
- cur->personal = m_strdup(phrase);
- }
- if ((ps =
- parse_route_addr (s + 1, comment, &commentlen,
- sizeof (comment) - 1, cur)) == NULL) {
- rfc822_free_address (&top);
- rfc822_free_address (&cur);
- return NULL;
- }
- if (last)
- last->next = cur;
- else
- top = cur;
- last = cur;
+ cur->mailbox = p_dupstr(token.buf, token.len);
- phraselen = 0;
- commentlen = 0;
- s = ps;
+ if (comment->len && !cur->personal) {
+ cur->personal = p_dupstr(comment->buf, comment->len);
}
- else {
- if (phraselen && phraselen < sizeof (phrase) - 1 && ws_pending)
- phrase[phraselen++] = ' ';
- if ((ps =
- next_token (s, phrase, &phraselen, sizeof (phrase) - 1)) == NULL) {
- rfc822_free_address (&top);
- return NULL;
- }
- s = ps;
+
+ return s;
+}
+
+address_t **rfc822_eotoken(address_t **last, static_buf *phrase, static_buf *comment)
+{
+ if (phrase->len) {
+ const char *s;
+ address_t *cur = address_new();
+
+ s = parse_address(phrase->buf, comment, cur);
+ if (s && *s && *s != ',' && *s != ';') {
+ address_delete(&cur);
+ return last;
+ }
+
+ *last = cur;
+ return &(*last)->next;
}
- ws_pending = isspace ((unsigned char) *s);
- s = vskipspaces(s);
- }
-
- if (phraselen) {
- terminate_buffer (phrase, phraselen);
- terminate_buffer (comment, commentlen);
- add_addrspec (&top, &last, phrase, comment, &commentlen,
- sizeof (comment) - 1);
- }
- else if (commentlen && last && !last->personal) {
- terminate_buffer (comment, commentlen);
- last->personal = m_strdup(comment);
- }
-
- return top;
+
+ return last;
}
-void rfc822_qualify (address_t * addr, const char *host)
+address_t *rfc822_parse_adrlist(address_t *top, const char *s)
{
- char *p;
-
- for (; addr; addr = addr->next)
- if (!addr->group && addr->mailbox && strchr (addr->mailbox, '@') == NULL) {
- p = p_new(char, m_strlen(addr->mailbox) + m_strlen(host) + 2);
- sprintf (p, "%s@%s", addr->mailbox, host); /* __SPRINTF_CHECKED__ */
- p_delete(&addr->mailbox);
- addr->mailbox = p;
+ static_buf comment = {"", 0};
+ static_buf phrase = {"", 0};
+
+ address_t **last = address_list_last(&top);
+ int ws_pending = 0;
+
+ for (;;) {
+ ws_pending = ISSPACE(*s);
+ s = skipspaces(s);
+
+ switch (*s) {
+ address_t *cur;
+
+ default:
+ if (ws_pending)
+ stbuf_append_sp(&phrase);
+ s = next_phrase(s, &phrase);
+ if (!s) {
+ address_delete(&top);
+ return NULL;
+ }
+ continue;
+
+ case '(':
+ stbuf_append_sp(&comment);
+ s = parse_comment(s + 1, &comment);
+ if (!s) {
+ address_delete(&top);
+ return NULL;
+ }
+ continue;
+
+
+ case '<':
+ cur = address_new();
+ if (phrase.len) {
+ /* if we get something like "Michael R. Elkins" remove the quotes */
+ cur->personal = rfc822_dequote_comment(&phrase);
+ }
+
+ s = parse_address(skipspaces(s + 1), &comment, cur);
+ if (!s || *s != '>' || !cur->mailbox) {
+ address_delete(&top);
+ address_delete(&cur);
+ return NULL;
+ }
+
+ *last = cur;
+ last = &(*last)->next;
+ break;
+
+ case ',':
+ last = rfc822_eotoken(last, &phrase, &comment);
+ break;
+
+ case ':': /* group start */
+ *last = address_new();
+ (*last)->mailbox = p_dupstr(phrase.buf, phrase.len);
+ (*last)->group = 1;
+ last = &(*last)->next;
+ break;
+
+ case ';':
+ last = rfc822_eotoken(last, &phrase, &comment);
+ /* add group terminator */
+ *last = address_new();
+ last = &(*last)->next;
+ break;
+
+ case '\0':
+ last = rfc822_eotoken(last, &phrase, &comment);
+ return top;
+ }
+
+ comment.len = phrase.len = 0;
+ s++;
}
+
+ return NULL;
}
+
+/****************************************************************************/
+/* Output functions */
+/****************************************************************************/
+
void
-rfc822_cat (char *buf, size_t buflen, const char *value, const char *specials)
+rfc822_cat(char *buf, size_t buflen, const char *value, const char *specials)
{
- if (strpbrk (value, specials)) {
- char tmp[256], *pc = tmp;
- size_t tmplen = sizeof (tmp) - 3;
-
- *pc++ = '"';
- for (; *value && tmplen > 1; value++) {
- if (*value == '\\' || *value == '"') {
- *pc++ = '\\';
- tmplen--;
- }
- *pc++ = *value;
- tmplen--;
+ if (strpbrk(value, specials)) {
+ char tmp[256], *pc = tmp;
+ size_t tmplen = sizeof (tmp) - 3;
+
+ *pc++ = '"';
+ for (; *value && tmplen > 1; value++) {
+ if (*value == '\\' || *value == '"') {
+ *pc++ = '\\';
+ tmplen--;
+ }
+ *pc++ = *value;
+ tmplen--;
+ }
+ *pc++ = '"';
+ *pc = 0;
+ m_strcpy(buf, buflen, tmp);
+ } else {
+ m_strcpy(buf, buflen, value);
}
- *pc++ = '"';
- *pc = 0;
- m_strcpy(buf, buflen, tmp);
- }
- else
- m_strcpy(buf, buflen, value);
}
-void rfc822_write_address_single (char *buf, size_t buflen, address_t * addr,
- int display)
+void rfc822_write_address_single(char *buf, size_t buflen, address_t * addr,
+ int display)
{
- size_t len;
- char *pbuf = buf;
- char *pc;
-
- if (!addr)
- return;
-
- buflen--; /* save room for the terminal nul */
-
- if (addr->personal) {
- if (strpbrk (addr->personal, RFC822Specials)) {
- if (!buflen)
- goto done;
- *pbuf++ = '"';
- buflen--;
- for (pc = addr->personal; *pc && buflen > 0; pc++) {
- if (*pc == '"' || *pc == '\\') {
- if (!buflen)
- goto done;
- *pbuf++ = '\\';
- buflen--;
+ size_t len;
+ char *pbuf = buf;
+ char *pc;
+
+ if (!addr)
+ return;
+
+ buflen--; /* save room for the terminal nul */
+
+ if (addr->personal) {
+ if (strpbrk (addr->personal, RFC822Specials)) {
+ if (!buflen)
+ goto done;
+ *pbuf++ = '"';
+ buflen--;
+ for (pc = addr->personal; *pc && buflen > 0; pc++) {
+ if (*pc == '"' || *pc == '\\') {
+ if (!buflen)
+ goto done;
+ *pbuf++ = '\\';
+ buflen--;
+ }
+ if (!buflen)
+ goto done;
+ *pbuf++ = *pc;
+ buflen--;
+ }
+ if (!buflen)
+ goto done;
+ *pbuf++ = '"';
+ buflen--;
}
+ else {
+ if (!buflen)
+ goto done;
+ m_strcpy(pbuf, buflen, addr->personal);
+ len = m_strlen(pbuf);
+ pbuf += len;
+ buflen -= len;
+ }
+
if (!buflen)
- goto done;
- *pbuf++ = *pc;
+ goto done;
+ *pbuf++ = ' ';
buflen--;
- }
- if (!buflen)
- goto done;
- *pbuf++ = '"';
- buflen--;
- }
- else {
- if (!buflen)
- goto done;
- m_strcpy(pbuf, buflen, addr->personal);
- len = m_strlen(pbuf);
- pbuf += len;
- buflen -= len;
- }
-
- if (!buflen)
- goto done;
- *pbuf++ = ' ';
- buflen--;
- }
-
- if (addr->personal || (addr->mailbox && *addr->mailbox == '@')) {
- if (!buflen)
- goto done;
- *pbuf++ = '<';
- buflen--;
- }
-
- if (addr->mailbox) {
- if (!buflen)
- goto done;
- if (ascii_strcmp (addr->mailbox, "@") && !display) {
- m_strcpy(pbuf, buflen, addr->mailbox);
- len = m_strlen(pbuf);
}
- else if (ascii_strcmp (addr->mailbox, "@") && display) {
- m_strcpy(pbuf, buflen, mutt_addr_for_display(addr));
- len = m_strlen(pbuf);
- }
- else {
- *pbuf = '\0';
- len = 0;
- }
- pbuf += len;
- buflen -= len;
if (addr->personal || (addr->mailbox && *addr->mailbox == '@')) {
- if (!buflen)
- goto done;
- *pbuf++ = '>';
- buflen--;
+ if (!buflen)
+ goto done;
+ *pbuf++ = '<';
+ buflen--;
}
- if (addr->group) {
- if (!buflen)
- goto done;
- *pbuf++ = ':';
- buflen--;
- if (!buflen)
- goto done;
- *pbuf++ = ' ';
- buflen--;
+ if (addr->mailbox) {
+ if (!buflen)
+ goto done;
+ if (ascii_strcmp (addr->mailbox, "@") && !display) {
+ m_strcpy(pbuf, buflen, addr->mailbox);
+ len = m_strlen(pbuf);
+ }
+ else if (ascii_strcmp (addr->mailbox, "@") && display) {
+ m_strcpy(pbuf, buflen, mutt_addr_for_display(addr));
+ len = m_strlen(pbuf);
+ }
+ else {
+ *pbuf = '\0';
+ len = 0;
+ }
+ pbuf += len;
+ buflen -= len;
+
+ if (addr->personal || (addr->mailbox && *addr->mailbox == '@')) {
+ if (!buflen)
+ goto done;
+ *pbuf++ = '>';
+ buflen--;
+ }
+
+ if (addr->group) {
+ if (!buflen)
+ goto done;
+ *pbuf++ = ':';
+ buflen--;
+ if (!buflen)
+ goto done;
+ *pbuf++ = ' ';
+ buflen--;
+ }
+ }
+ else {
+ if (!buflen)
+ goto done;
+ *pbuf++ = ';';
+ buflen--;
}
- }
- else {
- if (!buflen)
- goto done;
- *pbuf++ = ';';
- buflen--;
- }
done:
- /* no need to check for length here since we already save space at the
- beginning of this routine */
- *pbuf = 0;
+ /* no need to check for length here since we already save space at the
+ beginning of this routine */
+ *pbuf = 0;
}
/* note: it is assumed that `buf' is nul terminated! */
void rfc822_write_address (char *buf, size_t buflen, address_t * addr,
int display)
{
- char *pbuf = buf;
- size_t len = m_strlen(buf);
-
- buflen--; /* save room for the terminal nul */
-
- if (len > 0) {
- if (len > buflen)
- return; /* safety check for bogus arguments */
-
- pbuf += len;
- buflen -= len;
- if (!buflen)
- goto done;
- *pbuf++ = ',';
- buflen--;
- if (!buflen)
- goto done;
- *pbuf++ = ' ';
- buflen--;
- }
-
- for (; addr && buflen > 0; addr = addr->next) {
- /* use buflen+1 here because we already saved space for the trailing
- nul char, and the subroutine can make use of it */
- rfc822_write_address_single (pbuf, buflen + 1, addr, display);
-
- /* this should be safe since we always have at least 1 char passed into
- the above call, which means `pbuf' should always be nul terminated */
- len = m_strlen(pbuf);
- pbuf += len;
- buflen -= len;
-
- /* if there is another address, and its not a group mailbox name or
- group terminator, add a comma to separate the addresses */
- if (addr->next && addr->next->mailbox && !addr->group) {
- if (!buflen)
- goto done;
- *pbuf++ = ',';
- buflen--;
- if (!buflen)
- goto done;
- *pbuf++ = ' ';
- buflen--;
- }
- }
-done:
- *pbuf = 0;
-}
+ char *pbuf = buf;
+ size_t len = m_strlen(buf);
-/* this should be rfc822_cpy_adr */
-address_t *rfc822_cpy_adr_real (address_t * addr)
-{
- address_t *p = rfc822_new_address ();
+ buflen--; /* save room for the terminal nul */
- p->personal = m_strdup(addr->personal);
- p->mailbox = m_strdup(addr->mailbox);
- p->group = addr->group;
- return p;
-}
+ if (len > 0) {
+ if (len > buflen)
+ return; /* safety check for bogus arguments */
-/* this should be rfc822_cpy_adrlist */
-address_t *rfc822_cpy_adr (address_t * addr)
-{
- address_t *top = NULL, *last = NULL;
+ pbuf += len;
+ buflen -= len;
+ if (!buflen)
+ goto done;
+ *pbuf++ = ',';
+ buflen--;
+ if (!buflen)
+ goto done;
+ *pbuf++ = ' ';
+ buflen--;
+ }
- for (; addr; addr = addr->next) {
- if (last) {
- last->next = rfc822_cpy_adr_real (addr);
- last = last->next;
+ for (; addr && buflen > 0; addr = addr->next) {
+ /* use buflen+1 here because we already saved space for the trailing
+ nul char, and the subroutine can make use of it */
+ rfc822_write_address_single (pbuf, buflen + 1, addr, display);
+
+ /* this should be safe since we always have at least 1 char passed into
+ the above call, which means `pbuf' should always be nul terminated */
+ len = m_strlen(pbuf);
+ pbuf += len;
+ buflen -= len;
+
+ /* if there is another address, and its not a group mailbox name or
+ group terminator, add a comma to separate the addresses */
+ if (addr->next && addr->next->mailbox && !addr->group) {
+ if (!buflen)
+ goto done;
+ *pbuf++ = ',';
+ buflen--;
+ if (!buflen)
+ goto done;
+ *pbuf++ = ' ';
+ buflen--;
+ }
}
- else
- top = last = rfc822_cpy_adr_real (addr);
- }
- return top;
+done:
+ *pbuf = 0;
}
-/* append list 'b' to list 'a' and return the last element in the new list */
-address_t *rfc822_append (address_t ** a, address_t * b)
-{
- address_t *tmp = *a;
-
- while (tmp && tmp->next)
- tmp = tmp->next;
- if (!b)
- return tmp;
- if (tmp)
- tmp->next = rfc822_cpy_adr (b);
- else
- tmp = *a = rfc822_cpy_adr (b);
- while (tmp && tmp->next)
- tmp = tmp->next;
- return tmp;
-}