X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=rfc822.c;h=c9ed975937b6784d578efa38ae2b1d1efa385851;hb=45a6ada4178d3f025823f336dbac3887fa6867f2;hp=7b05e3039b4d3bb859e41ebc9af152cd7f5493a2;hpb=21c1b183e3be19d84ec05838f19332bae52c90a8;p=checkmail.git diff --git a/rfc822.c b/rfc822.c index 7b05e30..c9ed975 100644 --- a/rfc822.c +++ b/rfc822.c @@ -1,50 +1,43 @@ /* + * This code has been adapted from Mutt 1.5.16 which is + * * Copyright (C) 1996-2000 Michael R. Elkins - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif + */ #include #include #include -#ifndef TESTING -#include "mutt.h" -#else -#define safe_strdup strdup -#define safe_malloc malloc +#define safe_strdup xstrdup +#define safe_malloc xmalloc #define SKIPWS(x) while(isspace(*x))x++ -#define FREE(x) safe_free(x) +#define FREE(x) free(*(x)), *(x) = NULL #define ISSPACE isspace #define strfcpy(a,b,c) {if (c) {strncpy(a,b,c);a[c-1]=0;}} #define STRING 128 -#include "rfc822.h" -#endif -#include "mutt_idna.h" +#include "util.h" +#include "rfc822.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) @@ -60,7 +53,7 @@ const char *RFC822Errors[] = { "bad address spec" }; -void rfc822_dequote_comment (char *s) +static void rfc822_dequote_comment (char *s) { char *w = s; @@ -90,9 +83,6 @@ void rfc822_free_address (ADDRESS **p) { t = *p; *p = (*p)->next; -#ifdef EXACT_ADDRESS - FREE (&t->val); -#endif FREE (&t->personal); FREE (&t->mailbox); FREE (&t); @@ -104,7 +94,7 @@ parse_comment (const char *s, char *comment, size_t *commentlen, size_t commentmax) { int level = 1; - + while (*s && level) { if (*s == '(') @@ -321,7 +311,7 @@ add_addrspec (ADDRESS **top, ADDRESS **last, const char *phrase, char *comment, size_t *commentlen, size_t commentmax) { ADDRESS *cur = rfc822_new_address (); - + if (parse_addr_spec (phrase, comment, commentlen, commentmax, cur) == NULL) { rfc822_free_address (&cur); @@ -342,7 +332,7 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s) char comment[STRING], phrase[STRING]; size_t phraselen = 0, commentlen = 0; ADDRESS *cur, *last = NULL; - + RFC822Error = 0; last = top; @@ -350,7 +340,7 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s) last = last->next; ws_pending = isspace ((unsigned char) *s); - + SKIPWS (s); begin = s; while (*s) @@ -368,10 +358,6 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s) last->personal = safe_strdup (comment); } -#ifdef EXACT_ADDRESS - if (last && !last->val) - last->val = mutt_substrdup (begin, s); -#endif commentlen = 0; phraselen = 0; s++; @@ -402,10 +388,6 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s) top = cur; last = cur; -#ifdef EXACT_ADDRESS - last->val = mutt_substrdup (begin, s); -#endif - phraselen = 0; commentlen = 0; s++; @@ -424,10 +406,6 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s) terminate_buffer (comment, commentlen); last->personal = safe_strdup (comment); } -#ifdef EXACT_ADDRESS - if (last && !last->val) - last->val = mutt_substrdup (begin, s); -#endif /* add group terminator */ cur = rfc822_new_address (); @@ -486,7 +464,7 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s) ws_pending = isspace ((unsigned char) *s); SKIPWS (s); } - + if (phraselen) { terminate_buffer (phrase, phraselen); @@ -498,368 +476,6 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s) terminate_buffer (comment, commentlen); last->personal = safe_strdup (comment); } -#ifdef EXACT_ADDRESS - if (last) - last->val = mutt_substrdup (begin, s); -#endif return top; } - -void rfc822_qualify (ADDRESS *addr, const char *host) -{ - char *p; - - for (; addr; addr = addr->next) - if (!addr->group && addr->mailbox && strchr (addr->mailbox, '@') == NULL) - { - p = safe_malloc (mutt_strlen (addr->mailbox) + mutt_strlen (host) + 2); - sprintf (p, "%s@%s", addr->mailbox, host); /* __SPRINTF_CHECKED__ */ - FREE (&addr->mailbox); - addr->mailbox = p; - } -} - -void -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--; - } - *pc++ = '"'; - *pc = 0; - strfcpy (buf, tmp, buflen); - } - else - strfcpy (buf, value, buflen); -} - -void rfc822_write_address_single (char *buf, size_t buflen, ADDRESS *addr, - int display) -{ - size_t len; - char *pbuf = buf; - char *pc; - - if (!addr) - return; - - buflen--; /* save room for the terminal nul */ - -#ifdef EXACT_ADDRESS - if (addr->val) - { - if (!buflen) - goto done; - strfcpy (pbuf, addr->val, buflen); - len = mutt_strlen (pbuf); - pbuf += len; - buflen -= len; - if (addr->group) - { - if (!buflen) - goto done; - *pbuf++ = ':'; - buflen--; - *pbuf = 0; - } - return; - } -#endif - - 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; - strfcpy (pbuf, addr->personal, buflen); - len = mutt_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) - { - strfcpy (pbuf, addr->mailbox, buflen); - len = mutt_strlen (pbuf); - } - else if (ascii_strcmp (addr->mailbox, "@") && display) - { - strfcpy (pbuf, mutt_addr_for_display (addr), buflen); - len = mutt_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--; - } -done: - /* 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! */ -int rfc822_write_address (char *buf, size_t buflen, ADDRESS *addr, int display) -{ - char *pbuf = buf; - size_t len = mutt_strlen (buf); - - buflen--; /* save room for the terminal nul */ - - if (len > 0) - { - if (len > buflen) - return pbuf - buf; /* 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 = mutt_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; - return pbuf - buf; -} - -/* this should be rfc822_cpy_adr */ -ADDRESS *rfc822_cpy_adr_real (ADDRESS *addr) -{ - ADDRESS *p = rfc822_new_address (); - -#ifdef EXACT_ADDRESS - p->val = safe_strdup (addr->val); -#endif - p->personal = safe_strdup (addr->personal); - p->mailbox = safe_strdup (addr->mailbox); - p->group = addr->group; - return p; -} - -/* this should be rfc822_cpy_adrlist */ -ADDRESS *rfc822_cpy_adr (ADDRESS *addr) -{ - ADDRESS *top = NULL, *last = NULL; - - for (; addr; addr = addr->next) - { - if (last) - { - last->next = rfc822_cpy_adr_real (addr); - last = last->next; - } - else - top = last = rfc822_cpy_adr_real (addr); - } - return top; -} - -/* append list 'b' to list 'a' and return the last element in the new list */ -ADDRESS *rfc822_append (ADDRESS **a, ADDRESS *b) -{ - ADDRESS *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; -} - -/* incomplete. Only used to thwart the APOP MD5 attack (#2846). */ -int rfc822_valid_msgid (const char *msgid) -{ - /* msg-id = "<" addr-spec ">" - * addr-spec = local-part "@" domain - * local-part = word *("." word) - * word = atom / quoted-string - * atom = 1* - * CHAR = ( 0.-127. ) - * specials = "(" / ")" / "<" / ">" / "@" - / "," / ";" / ":" / "\" / <"> - / "." / "[" / "]" - * SPACE = ( 32. ) - * CTLS = ( 0.-31., 127.) - * quoted-string = <"> *(qtext/quoted-pair) <"> - * qtext = , "\" and CR> - * CR = ( 13. ) - * quoted-pair = "\" CHAR - * domain = sub-domain *("." sub-domain) - * sub-domain = domain-ref / domain-literal - * domain-ref = atom - * domain-literal = "[" *(dtext / quoted-pair) "]" - */ - - char* dom; - unsigned int l, i; - - if (!msgid || !*msgid) - return -1; - - l = mutt_strlen (msgid); - if (l < 5) /* */ - return -1; - if (msgid[0] != '<' || msgid[l-1] != '>') - return -1; - if (!(dom = strrchr (msgid, '@'))) - return -1; - - /* TODO: complete parser */ - for (i = 0; i < l; i++) - if ((unsigned char)msgid[i] > 127) - return -1; - - return 0; -} - -#ifdef TESTING -int safe_free (void **p) /* __SAFE_FREE_CHECKED__ */ -{ - free(*p); /* __MEM_CHECKED__ */ - *p = 0; -} - -int main (int argc, char **argv) -{ - ADDRESS *list; - char buf[256]; -# if 0 - char *str = "michael, Michael Elkins , testing a really complex address: this example <@contains.a.source.route,@with.multiple.hosts:address@example.com>;, lothar@of.the.hillpeople (lothar)"; -# else - char *str = "a b c "; -# endif - - list = rfc822_parse_adrlist (NULL, str); - buf[0] = 0; - rfc822_write_address (buf, sizeof (buf), list); - rfc822_free_address (&list); - puts (buf); - exit (0); -} -#endif