static int address_header_decode (char **h) { char *s = *h; int l, rp = 0; ADDRESS *a = NULL; ADDRESS *cur = NULL; switch (tolower ((unsigned char) *s)) { case 'r': { if (ascii_strncasecmp (s, "return-path:", 12) == 0) { l = 12; rp = 1; break; } else if (ascii_strncasecmp (s, "reply-to:", 9) == 0) { l = 9; break; } return 0; } case 'f': { if (ascii_strncasecmp (s, "from:", 5)) return 0; l = 5; break; } case 'c': { if (ascii_strncasecmp (s, "cc:", 3)) return 0; l = 3; break; } case 'b': { if (ascii_strncasecmp (s, "bcc:", 4)) return 0; l = 4; break; } case 's': { if (ascii_strncasecmp (s, "sender:", 7)) return 0; l = 7; break; } case 't': { if (ascii_strncasecmp (s, "to:", 3)) return 0; l = 3; break; } case 'm': { if (ascii_strncasecmp (s, "mail-followup-to:", 17)) return 0; l = 17; break; } default: return 0; } if ((a = rfc822_parse_adrlist (a, s + l)) == NULL) return 0; mutt_addrlist_to_local (a); rfc2047_decode_adrlist (a); for (cur = a; cur; cur = cur->next) if (cur->personal) rfc822_dequote_comment (cur->personal); /* angle brackets for return path are mandated by RfC5322, * so leave Return-Path as-is */ if (rp) *h = safe_strdup (s); else { *h = safe_calloc (1, l + 2); strfcpy (*h, s, l + 1); format_address_header (h, a); } rfc822_free_address (&a); FREE (&s); return 1; }
ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s) { const char *begin, *ps; char comment[STRING], phrase[STRING]; size_t phraselen = 0, commentlen = 0; ADDRESS *cur, *last = NULL; RFC822Error = 0; last = top; while (last && last->next) last = last->next; SKIPWS (s); begin = s; while (*s) { if (*s == ',') { if (phraselen) { phrase[phraselen] = 0; add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1); } else if (commentlen && last && !last->personal) { comment[commentlen] = 0; last->personal = safe_strdup (comment); } #ifdef EXACT_ADDRESS if (last && !last->val) last->val = mutt_substrdup (begin, s); #endif commentlen = 0; phraselen = 0; s++; begin = s; SKIPWS (begin); } 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); return NULL; } s = ps; } else if (*s == ':') { cur = rfc822_new_address (); phrase[phraselen] = 0; cur->mailbox = safe_strdup (phrase); cur->group = 1; if (last) last->next = cur; else top = cur; last = cur; #ifdef EXACT_ADDRESS last->val = mutt_substrdup (begin, s); #endif phraselen = 0; commentlen = 0; s++; begin = s; SKIPWS (begin); } else if (*s == ';') { if (phraselen) { phrase[phraselen] = 0; add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1); } else if (commentlen && !last->personal) { comment[commentlen] = 0; 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 (); if (last) { last->next = cur; last = cur; } phraselen = 0; commentlen = 0; s++; begin = s; SKIPWS (begin); } else if (*s == '<') { phrase[phraselen] = 0; cur = rfc822_new_address (); if (phraselen) { if (cur->personal) FREE (&cur->personal); /* if we get something like "Michael R. Elkins" remove the quotes */ rfc822_dequote_comment (phrase); cur->personal = safe_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; phraselen = 0; commentlen = 0; s = ps; } else { if (phraselen && phraselen < sizeof (phrase) - 1) phrase[phraselen++] = ' '; if ((ps = next_token (s, phrase, &phraselen, sizeof (phrase) - 1)) == NULL) { rfc822_free_address (&top); return NULL; } s = ps; } SKIPWS (s); } if (phraselen) { phrase[phraselen] = 0; comment[commentlen] = 0; add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1); } else if (commentlen && last && !last->personal) { comment[commentlen] = 0; last->personal = safe_strdup (comment); } #ifdef EXACT_ADDRESS if (last) last->val = mutt_substrdup (begin, s); #endif return top; }