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

📄 rfc822.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
      string = NIL;      (adr = mail_newaddr ())->mailbox = cpystr ("INVALID_ADDRESS");      adr->host = cpystr (errhst);      if (last) last = last->next = adr;      else *lst = last = adr;      break;    }  }}/* Parse RFC 2822 address * Accepts: address list to write to *	    tail of address list *	    pointer to input string *	    default host name *	    group nesting depth * Returns: new list tail */ADDRESS *rfc822_parse_address (ADDRESS **lst,ADDRESS *last,char **string,			       char *defaulthost,unsigned long depth){  ADDRESS *adr;  if (!*string) return NIL;	/* no string */  rfc822_skipws (string);	/* skip leading WS */  if (!**string) return NIL;	/* empty string */  if (adr = rfc822_parse_group (lst,last,string,defaulthost,depth)) last = adr;				/* got an address? */  else if (adr = rfc822_parse_mailbox (string,defaulthost)) {    if (!*lst) *lst = adr;	/* yes, first time through? */    else last->next = adr;	/* no, append to the list */				/* set for subsequent linking */    for (last = adr; last->next; last = last->next);  }  else if (*string) return NIL;  return last;}/* Parse RFC 2822 group * Accepts: address list to write to *	    pointer to tail of address list *	    pointer to input string *	    default host name *	    group nesting depth */ADDRESS *rfc822_parse_group (ADDRESS **lst,ADDRESS *last,char **string,			     char *defaulthost,unsigned long depth){  char tmp[MAILTMPLEN];  char *p,*s;  ADDRESS *adr;  if (depth > MAXGROUPDEPTH) {	/* excessively deep recursion? */    MM_LOG ("Ignoring excessively deep group recursion",PARSE);    return NIL;			/* probably abusive */  }  if (!*string) return NIL;	/* no string */  rfc822_skipws (string);	/* skip leading WS */  if (!**string ||		/* trailing whitespace or not group */      ((*(p = *string) != ':') && !(p = rfc822_parse_phrase (*string))))    return NIL;  s = p;			/* end of candidate phrase */  rfc822_skipws (&s);		/* find delimiter */  if (*s != ':') return NIL;	/* not really a group */  *p = '\0';			/* tie off group name */  p = ++s;			/* continue after the delimiter */  rfc822_skipws (&p);		/* skip subsequent whitespace */				/* write as address */  (adr = mail_newaddr ())->mailbox = rfc822_cpy (*string);  if (!*lst) *lst = adr;	/* first time through? */  else last->next = adr;	/* no, append to the list */  last = adr;			/* set for subsequent linking */  *string = p;			/* continue after this point */  while (*string && **string && (**string != ';')) {    if (adr = rfc822_parse_address (lst,last,string,defaulthost,depth+1)) {      last = adr;		/* new tail address */      if (*string) {		/* anything more? */	rfc822_skipws (string);	/* skip whitespace */	switch (**string) {	/* see what follows */	case ',':		/* another address? */	  ++*string;		/* yes, skip past the comma */	case ';':		/* end of group? */	case '\0':		/* end of string */	  break;	default:	  sprintf (tmp,"Unexpected characters after address in group: %.80s",		   *string);	  MM_LOG (tmp,PARSE);	  *string = NIL;	/* cancel remainder of parse */	  last = last->next = mail_newaddr ();	  last->mailbox = cpystr ("UNEXPECTED_DATA_AFTER_ADDRESS_IN_GROUP");	  last->host = cpystr (errhst);	}      }    }    else {			/* bogon */      sprintf (tmp,"Invalid group mailbox list: %.80s",*string);      MM_LOG (tmp,PARSE);      *string = NIL;		/* cancel remainder of parse */      (adr = mail_newaddr ())->mailbox = cpystr ("INVALID_ADDRESS_IN_GROUP");      adr->host = cpystr (errhst);      last = last->next = adr;    }  }  if (*string) {		/* skip close delimiter */    if (**string == ';') ++*string;    rfc822_skipws (string);  }				/* append end of address mark to the list */  last->next = (adr = mail_newaddr ());  last = adr;			/* set for subsequent linking */  return last;			/* return the tail */}/* Parse RFC 2822 mailbox * Accepts: pointer to string pointer *	    default host * Returns: address list * * Updates string pointer */ADDRESS *rfc822_parse_mailbox (char **string,char *defaulthost){  ADDRESS *adr = NIL;  char *s,*end;  parsephrase_t pp = (parsephrase_t) mail_parameters (NIL,GET_PARSEPHRASE,NIL);  if (!*string) return NIL;	/* no string */  rfc822_skipws (string);	/* flush leading whitespace */  if (!**string) return NIL;	/* empty string */  if (*(s = *string) == '<') 	/* note start, handle case of phraseless RA */    adr = rfc822_parse_routeaddr (s,string,defaulthost);				/* otherwise, expect at least one word */  else if (end = rfc822_parse_phrase (s)) {    if ((adr = rfc822_parse_routeaddr (end,string,defaulthost))) {				/* phrase is a personal name */      if (adr->personal) fs_give ((void **) &adr->personal);      *end = '\0';		/* tie off phrase */      adr->personal = rfc822_cpy (s);    }				/* call external phraseparser if phrase only */    else if (pp && rfc822_phraseonly (end) &&	     (adr = (*pp) (s,end,defaulthost))) {      *string = end;		/* update parse pointer */      rfc822_skipws (string);	/* skip WS in the normal way */    }    else adr = rfc822_parse_addrspec (s,string,defaulthost);  }  return adr;			/* return the address */}/* Check if address is a phrase only * Accepts: pointer to end of phrase * Returns: T if phrase only, else NIL; */long rfc822_phraseonly (char *end){  while (*end == ' ') ++end;	/* call rfc822_skipws() instead?? */  switch (*end) {  case '\0': case ',': case ';':    return LONGT;		/* is a phrase only */  }  return NIL;			/* something other than phase is here */}/* Parse RFC 2822 route-address * Accepts: string pointer *	    pointer to string pointer to update * Returns: address * * Updates string pointer */ADDRESS *rfc822_parse_routeaddr (char *string,char **ret,char *defaulthost){  char tmp[MAILTMPLEN];  ADDRESS *adr;  char *s,*t,*adl;  size_t adllen,i;  if (!string) return NIL;  rfc822_skipws (&string);	/* flush leading whitespace */				/* must start with open broket */  if (*string != '<') return NIL;  t = ++string;			/* see if A-D-L there */  rfc822_skipws (&t);		/* flush leading whitespace */  for (adl = NIL,adllen = 0;	/* parse possible A-D-L */       (*t == '@') && (s = rfc822_parse_domain (t+1,&t));) {    i = strlen (s) + 2;		/* @ plus domain plus delimiter or NUL */    if (adl) {			/* have existing A-D-L? */      fs_resize ((void **) &adl,adllen + i);      sprintf (adl + adllen - 1,",@%s",s);    }				/* write initial A-D-L */    else sprintf (adl = (char *) fs_get (i),"@%s",s);    adllen += i;		/* new A-D-L length */    fs_give ((void **) &s);	/* don't need domain any more */    rfc822_skipws (&t);		/* skip WS */    if (*t != ',') break;	/* put if not comma */    t++;			/* skip the comma */    rfc822_skipws (&t);		/* skip WS */  }  if (adl) {			/* got an A-D-L? */    if (*t != ':') {		/* make sure syntax good */      sprintf (tmp,"Unterminated at-domain-list: %.80s%.80s",adl,t);      MM_LOG (tmp,PARSE);    }    else string = ++t;		/* continue parse from this point */  }				/* parse address spec */  if (!(adr = rfc822_parse_addrspec (string,ret,defaulthost))) {    if (adl) fs_give ((void **) &adl);    return NIL;  }  if (adl) adr->adl = adl;	/* have an A-D-L? */  if (*ret) if (**ret == '>') {	/* make sure terminated OK */    ++*ret;			/* skip past the broket */    rfc822_skipws (ret);	/* flush trailing WS */    if (!**ret) *ret = NIL;	/* wipe pointer if at end of string */    return adr;			/* return the address */  }  sprintf (tmp,"Unterminated mailbox: %.80s@%.80s",adr->mailbox,	   *adr->host == '@' ? "<null>" : adr->host);  MM_LOG (tmp,PARSE);  adr->next = mail_newaddr ();  adr->next->mailbox = cpystr ("MISSING_MAILBOX_TERMINATOR");  adr->next->host = cpystr (errhst);  return adr;			/* return the address */}/* Parse RFC 2822 address-spec * Accepts: string pointer *	    pointer to string pointer to update *	    default host * Returns: address * * Updates string pointer */ADDRESS *rfc822_parse_addrspec (char *string,char **ret,char *defaulthost){  ADDRESS *adr;  char c,*s,*t,*v,*end;  if (!string) return NIL;	/* no string */  rfc822_skipws (&string);	/* flush leading whitespace */  if (!*string) return NIL;	/* empty string */				/* find end of mailbox */  if (!(t = rfc822_parse_word (string,wspecials))) return NIL;  adr = mail_newaddr ();	/* create address block */  c = *t;			/* remember delimiter */  *t = '\0';			/* tie off mailbox */				/* copy mailbox */  adr->mailbox = rfc822_cpy (string);  *t = c;			/* restore delimiter */  end = t;			/* remember end of mailbox */  rfc822_skipws (&t);		/* skip whitespace */  while (*t == '.') {		/* some cretin taking RFC 822 too seriously? */    string = ++t;		/* skip past the dot and any WS */    rfc822_skipws (&string);				/* get next word of mailbox */    if (t = rfc822_parse_word (string,wspecials)) {      end = t;			/* remember new end of mailbox */      c = *t;			/* remember delimiter */      *t = '\0';		/* tie off word */      s = rfc822_cpy (string);	/* copy successor part */      *t = c;			/* restore delimiter */				/* build new mailbox */      sprintf (v = (char *) fs_get (strlen (adr->mailbox) + strlen (s) + 2),	       "%s.%s",adr->mailbox,s);      fs_give ((void **) &adr->mailbox);      adr->mailbox = v;		/* new host name */      rfc822_skipws (&t);	/* skip WS after mailbox */    }    else {			/* barf */      MM_LOG ("Invalid mailbox part after .",PARSE);      break;    }  }  t = end;			/* remember delimiter in case no host */  rfc822_skipws (&end);		/* sniff ahead at what follows */#if RFC733			/* RFC 733 used "at" instead of "@" */  if (((*end == 'a') || (*end == 'A')) &&      ((end[1] == 't') || (end[1] == 'T')) &&      ((end[2] == ' ') || (end[2] == '\t') || (end[2] == '\015') ||       (end[2] == '\012') || (end[2] == '(')))    *++end = '@';#endif  if (*end != '@') end = t;	/* host name missing */				/* otherwise parse host name */  else if (!(adr->host = rfc822_parse_domain (++end,&end)))    adr->host = cpystr (errhst);				/* default host if missing */  if (!adr->host) adr->host = cpystr (defaulthost);				/* try person name in comments if missing */  if (end && !(adr->personal && *adr->personal)) {    while (*end == ' ') ++end;	/* see if we can find a person name here */    if ((*end == '(') && (s = rfc822_skip_comment (&end,LONGT)) && strlen (s))      adr->personal = rfc822_cpy (s);    rfc822_skipws (&end);	/* skip any other WS in the normal way */  }				/* set return to end pointer */  *ret = (end && *end) ? end : NIL;  return adr;			/* return the address we got */}/* Parse RFC 2822 domain * Accepts: string pointer *	    pointer to return end of domain * Returns: domain name or NIL if failure */char *rfc822_parse_domain (char *string,char **end){  char *ret = NIL;  char c,*s,*t,*v;  rfc822_skipws (&string);	/* skip whitespace */  if (*string == '[') {		/* domain literal? */    if (!(*end = rfc822_parse_word (string + 1,"]\\")))      MM_LOG ("Empty domain literal",PARSE);    else if (**end != ']') MM_LOG ("Unterminated domain literal",PARSE);    else {      size_t len = ++*end - string;      strncpy (ret = (char *) fs_get (len + 1),string,len);      ret[len] = '\0';		/* tie off literal */    }  }				/* search for end of host */  else if (t = rfc822_parse_word (string,wspecials)) {    c = *t;			/* remember delimiter */    *t = '\0';			/* tie off host */    ret = rfc822_cpy (string);	/* copy host */    *t = c;			/* restore delimiter */    *end = t;			/* remember end of domain */    rfc822_skipws (&t);		/* skip WS after host */    while (*t == '.') {		/* some cretin taking RFC 822 too seriously? */      string = ++t;		/* skip past the dot and any WS */      rfc822_skipws (&string);      if (string = rfc822_parse_domain (string,&t)) {	*end = t;		/* remember new end of domain */	c = *t;			/* remember delimiter */	*t = '\0';		/* tie off host */	s = rfc822_cpy (string);/* copy successor part */	*t = c;			/* restore delimiter */				/* build new domain */	sprintf (v = (char *) fs_get (strlen (ret) + strlen (s) + 2),		 "%s.%s",ret,s);	fs_give ((void **) &ret);	ret = v;		/* new host name */	rfc822_skipws (&t);	/* skip WS after domain */      }      else {			/* barf */	MM_LOG ("Invalid domain part after .",PARSE);	break;      }    }  }  else MM_LOG ("Missing or invalid host name after @",PARSE);  return ret;}/* Parse RFC 2822 phrase * Accepts: string pointer * Returns: pointer to end of phrase */char *rfc822_parse_phrase (char *s){  char *curpos;  if (!s) return NIL;		/* no-op if no string */				/* find first word of phrase */  curpos = rfc822_parse_word (s,NIL);  if (!curpos) return NIL;	/* no words means no phrase */  if (!*curpos) return curpos;	/* check if string ends with word */  s = curpos;			/* sniff past the end of this word and WS */  rfc822_skipws (&s);		/* skip whitespace */				/* recurse to see if any more */  return (s = rfc822_parse_phrase (s)) ? s : curpos;}

⌨️ 快捷键说明

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