⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfc822.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org> *  *     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 <string.h>#include <ctype.h>#include <stdlib.h>#ifndef TESTING#include "mutt.h"#else#define safe_strdup strdup#define safe_malloc malloc#define SKIPWS(x) while(isspace(*x))x++#define FREE(x) safe_free(x)#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"#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;/* 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){  char *w = s;  for (; *s; s++)  {    if (*s == '\\')    {      if (!*++s)	break; /* error? */      *w++ = *s;    }    else if (*s != '\"')    {      if (w != s)	*w = *s;      w++;    }  }  *w = 0;}void rfc822_free_address (ADDRESS **p){  ADDRESS *t;  while (*p)  {    t = *p;    *p = (*p)->next;#ifdef EXACT_ADDRESS    FREE (&t->val);#endif    FREE (&t->personal);    FREE (&t->mailbox);    FREE (&t);  }}static const char *parse_comment (const char *s,	       char *comment, size_t *commentlen, size_t commentmax){  int level = 1;    while (*s && level)  {    if (*s == '(')      level++;    else if (*s == ')')    {      if (--level == 0)      {	s++;	break;      }    }    else if (*s == '\\')    {      if (!*++s)	break;    }    if (*commentlen < commentmax)      comment[(*commentlen)++] = *s;    s++;  }  if (level)  {    RFC822Error = ERR_MISMATCH_PAREN;    return NULL;  }  return s;}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;    }    (*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 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){  const char *ps;  while (*s)  {    SKIPWS (s);    if (strchr (nonspecial, *s) == NULL && is_special (*s))      return s;    if (*s == '(')    {      if (*commentlen && *commentlen < commentmax)	comment[(*commentlen)++] = ' ';      ps = next_token (s, comment, commentlen, commentmax);    }    else      ps = next_token (s, mailbox, mailboxlen, mailboxmax);    if (!ps)      return NULL;    s = ps;  }  return s;}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 *addr){  s = parse_mailboxdomain (s, ".\"(\\",			   token, tokenlen, tokenmax,			   comment, commentlen, commentmax);  if (!s)    return NULL;  if (*s == '@')  {    if (*tokenlen < tokenmax)      token[(*tokenlen)++] = '@';    s = parse_mailboxdomain (s + 1, ".([]\\",			     token, tokenlen, tokenmax,			     comment, commentlen, commentmax);    if (!s)      return NULL;  }  terminate_string (token, *tokenlen, tokenmax);  addr->mailbox = safe_strdup (token);  if (*commentlen && !addr->personal)  {    terminate_string (comment, *commentlen, commentmax);    addr->personal = safe_strdup (comment);  }  return s;}static const char *parse_route_addr (const char *s,		  char *comment, size_t *commentlen, size_t commentmax,		  ADDRESS *addr){  char token[STRING];  size_t tokenlen = 0;  SKIPWS (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 || *s != ':')    {      RFC822Error = ERR_BAD_ROUTE;      return NULL; /* invalid route */    }    if (tokenlen < sizeof (token) - 1)      token[tokenlen++] = ':';    s++;  }  if ((s = parse_address (s, token, &tokenlen, sizeof (token) - 1, comment, commentlen, commentmax, addr)) == NULL)    return NULL;  if (*s != '>')  {    RFC822Error = ERR_BAD_ROUTE_ADDR;    return NULL;  }  if (!addr->mailbox)    addr->mailbox = safe_strdup ("@");  s++;  return s;}static const char *parse_addr_spec (const char *s,		 char *comment, size_t *commentlen, size_t commentmax,		 ADDRESS *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;}static voidadd_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);    return;  }  if (*last)    (*last)->next = cur;  else    *top = cur;  *last = cur;}ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s){  int ws_pending;  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;  ws_pending = isspace ((unsigned char) *s);    SKIPWS (s);  begin = 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 = 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 ();      terminate_buffer (phrase, phraselen);      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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -