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

📄 rfc822.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Parse RFC 2822 word * Accepts: string pointer *	    delimiter (or NIL for phrase word parsing) * Returns: pointer to end of word */char *rfc822_parse_word (char *s,const char *delimiters){  char *st,*str;  if (!s) return NIL;		/* no string */  rfc822_skipws (&s);		/* flush leading whitespace */  if (!*s) return NIL;		/* empty string */  str = s;			/* hunt pointer for strpbrk */  while (T) {			/* look for delimiter, return if none */    if (!(st = strpbrk (str,delimiters ? delimiters : wspecials)))      return str + strlen (str);				/* ESC in phrase */    if (!delimiters && (*st == I2C_ESC)) {      str = ++st;		/* always skip past ESC */      switch (*st) {		/* special hack for RFC 1468 (ISO-2022-JP) */      case I2C_MULTI:		/* multi byte sequence */	switch (*++st) {	case I2CS_94x94_JIS_OLD:/* old JIS (1978) */	case I2CS_94x94_JIS_NEW:/* new JIS (1983) */	  str = ++st;		/* skip past the shift to JIS */	  while (st = strchr (st,I2C_ESC))	    if ((*++st == I2C_G0_94) && ((st[1] == I2CS_94_ASCII) ||					 (st[1] == I2CS_94_JIS_ROMAN) ||					 (st[1] == I2CS_94_JIS_BUGROM))) {	      str = st += 2;	/* skip past the shift back to ASCII */	      break;	    }				/* eats entire text if no shift back */	  if (!st || !*st) return str + strlen (str);	}	break;      case I2C_G0_94:		/* single byte sequence */	switch (st[1]) {	case I2CS_94_ASCII:	/* shift to ASCII */	case I2CS_94_JIS_ROMAN:	/* shift to JIS-Roman */	case I2CS_94_JIS_BUGROM:/* old buggy definition of JIS-Roman */	  str = st + 2;		/* skip past the shift */	  break;	}      }    }    else switch (*st) {		/* dispatch based on delimiter */    case '"':			/* quoted string */				/* look for close quote */      while (*++st != '"') switch (*st) {      case '\0':		/* unbalanced quoted string */	return NIL;		/* sick sick sick */      case '\\':		/* quoted character */	if (!*++st) return NIL;	/* skip the next character */      default:			/* ordinary character */	break;			/* no special action */      }      str = ++st;		/* continue parse */      break;    case '\\':			/* quoted character */      /* This is wrong; a quoted-pair can not be part of a word.  However,       * domain-literal is parsed as a word and quoted-pairs can be used       * *there*.  Either way, it's pretty pathological.       */      if (st[1]) {		/* not on NUL though... */	str = st + 2;		/* skip quoted character and go on */	break;      }    default:			/* found a word delimiter */      return (st == s) ? NIL : st;    }  }}/* Copy an RFC 2822 format string * Accepts: string * Returns: copy of string */char *rfc822_cpy (char *src){				/* copy and unquote */  return rfc822_quote (cpystr (src));}/* Unquote an RFC 2822 format string * Accepts: string * Returns: string */char *rfc822_quote (char *src){  char *ret = src;  if (strpbrk (src,"\\\"")) {	/* any quoting in string? */    char *dst = ret;    while (*src) {		/* copy string */      if (*src == '\"') src++;	/* skip double quote entirely */      else {	if (*src == '\\') src++;/* skip over single quote, copy next always */	*dst++ = *src++;	/* copy character */      }    }    *dst = '\0';		/* tie off string */  }  return ret;			/* return our string */}/* Copy address list * Accepts: address list * Returns: address list */ADDRESS *rfc822_cpy_adr (ADDRESS *adr){  ADDRESS *dadr;  ADDRESS *ret = NIL;  ADDRESS *prev = NIL;  while (adr) {			/* loop while there's still an MAP adr */    dadr = mail_newaddr ();	/* instantiate a new address */    if (!ret) ret = dadr;	/* note return */    if (prev) prev->next = dadr;/* tie on to the end of any previous */    dadr->personal = cpystr (adr->personal);    dadr->adl = cpystr (adr->adl);    dadr->mailbox = cpystr (adr->mailbox);    dadr->host = cpystr (adr->host);    prev = dadr;		/* this is now the previous */    adr = adr->next;		/* go to next address in list */  }  return (ret);			/* return the MTP address list */}/* Skips RFC 2822 whitespace * Accepts: pointer to string pointer */void rfc822_skipws (char **s){  while (T) switch (**s) {  case ' ': case '\t': case '\015': case '\012':    ++*s;			/* skip all forms of LWSP */    break;  case '(':			/* start of comment */    if (rfc822_skip_comment (s,(long) NIL)) break;  default:    return;			/* end of whitespace */  }}/* Skips RFC 2822 comment * Accepts: pointer to string pointer *	    trim flag * Returns: pointer to first non-blank character of comment */char *rfc822_skip_comment (char **s,long trim){  char *ret,tmp[MAILTMPLEN];  char *s1 = *s;  char *t = NIL;				/* skip past whitespace */  for (ret = ++s1; *ret == ' '; ret++);  do switch (*s1) {		/* get character of comment */  case '(':			/* nested comment? */    if (!rfc822_skip_comment (&s1,(long) NIL)) return NIL;    t = --s1;			/* last significant char at end of comment */    break;  case ')':			/* end of comment? */    *s = ++s1;			/* skip past end of comment */    if (trim) {			/* if level 0, must trim */      if (t) t[1] = '\0';	/* tie off comment string */      else *ret = '\0';		/* empty comment */    }    return ret;  case '\\':			/* quote next character? */    if (*++s1) {		/* next character non-null? */      t = s1;			/* update last significant character pointer */      break;			/* all OK */    }  case '\0':			/* end of string */    sprintf (tmp,"Unterminated comment: %.80s",*s);    MM_LOG (tmp,PARSE);    **s = '\0';			/* nuke duplicate messages in case reparse */    return NIL;			/* this is wierd if it happens */  case ' ':			/* whitespace isn't significant */    break;  default:			/* random character */    t = s1;			/* update last significant character pointer */    break;  } while (s1++);  return NIL;			/* impossible, but pacify lint et al */}/* Buffered output routines *//* Output character to buffer * Accepts: buffer *	    character to write * Returns: T if success, NIL if error */static long rfc822_output_char (RFC822BUFFER *buf,int c){  if ((buf->cur == buf->end) && !rfc822_output_flush (buf)) return NIL;  *buf->cur++ = c;		/* add character, soutr buffer if full */  return (buf->cur == buf->end) ? rfc822_output_flush (buf) : LONGT;}/* Output data to buffer * Accepts: buffer *	    data to write *	    size of data * Returns: T if success, NIL if error */static long rfc822_output_data (RFC822BUFFER *buf,char *string,long len){  while (len) {			/* until request satified */    long i;    if (i = min (len,buf->end - buf->cur)) {      memcpy (buf->cur,string,i);      buf->cur += i;		/* blat data */      string += i;      len -= i;    }				/* soutr buffer now if full */    if ((len || (buf->cur == buf->end)) && !rfc822_output_flush (buf))      return NIL;  }  return LONGT;}/* Output string to buffer * Accepts: buffer *	    string to write * Returns: T if success, NIL if error */static long rfc822_output_string (RFC822BUFFER *buf,char *string){  return rfc822_output_data (buf,string,strlen (string));}/* Flush buffer * Accepts: buffer *	    I/O routine *	    stream for I/O routine * Returns: T if success, NIL if error */long rfc822_output_flush (RFC822BUFFER *buf){  *buf->cur = '\0';		/* tie off buffer at this point */  return (*buf->f) (buf->s,buf->cur = buf->beg);}/* Message writing routines *//* Output RFC 822 message * Accepts: temporary buffer as a SIZEDTEXT *	    envelope *	    body *	    I/O routine *	    stream for I/O routine *	    non-zero if 8-bit output desired * Returns: T if successful, NIL if failure * * This routine always uses standard specials for phrases and does not write * bcc entries, since it is called from the SMTP and NNTP routines.  If you * need to do something different you need to arm an rfc822outfull_t and/or * rfc822out_t function. */long rfc822_output_full (RFC822BUFFER *buf,ENVELOPE *env,BODY *body,long ok8){  rfc822outfull_t r822of =    (rfc822outfull_t) mail_parameters (NIL,GET_RFC822OUTPUTFULL,NIL);  rfc822out_t r822o = (rfc822out_t) mail_parameters (NIL,GET_RFC822OUTPUT,NIL);				/* call external RFC 2822 output generator */  if (r822of) return (*r822of) (buf,env,body,ok8);  else if (r822o) return (*r822o) (buf->cur,env,body,buf->f,buf->s,ok8);				/* encode body as necessary */  if (ok8) rfc822_encode_body_8bit (env,body);  else rfc822_encode_body_7bit (env,body);				/* output header and body */  return rfc822_output_header (buf,env,body,NIL,NIL) &&    rfc822_output_text (buf,body) && rfc822_output_flush (buf);}/* Output RFC 822 header * Accepts: buffer *	    envelope *	    body *	    non-standard specials to be used for phrases if non-NIL *	    flags (non-zero to include bcc * Returns: T if success, NIL if failure */long rfc822_output_header (RFC822BUFFER *buf,ENVELOPE *env,BODY *body,			   const char *specials,long flags){  long i = env->remail ? strlen (env->remail) : 0;  return			/* write header */    (!i ||		      /* snip extra CRLF from remail header */     rfc822_output_data (buf,env->remail,			 ((i > 4) && (env->remail[i-4] == '\015')) ?			 i - 2 : i)) &&    rfc822_output_header_line (buf,"Newsgroups",i,env->newsgroups) &&    rfc822_output_header_line (buf,"Date",i,env->date) &&    rfc822_output_address_line (buf,"From",i,env->from,specials) &&    rfc822_output_address_line (buf,"Sender",i,env->sender,specials) &&    rfc822_output_address_line (buf,"Reply-To",i,env->reply_to,specials) &&    rfc822_output_header_line (buf,"Subject",i,env->subject) &&    ((env->bcc && !(env->to || env->cc)) ?     rfc822_output_string (buf,"To: undisclosed recipients: ;\015\012") :     LONGT) &&    rfc822_output_address_line (buf,"To",i,env->to,specials) &&    rfc822_output_address_line (buf,"cc",i,env->cc,specials) &&    (flags ? rfc822_output_address_line (buf,"bcc",i,env->bcc,specials) : T) &&    rfc822_output_header_line (buf,"In-Reply-To",i,env->in_reply_to) &&    rfc822_output_header_line (buf,"Message-ID",i,env->message_id) &&    rfc822_output_header_line (buf,"Followup-to",i,env->followup_to) &&    rfc822_output_header_line (buf,"References",i,env->references) &&    (env->remail || !body ||     (rfc822_output_string (buf,"MIME-Version: 1.0\015\012") &&      rfc822_output_body_header (buf,body))) &&				/* write terminating blank line */    rfc822_output_string (buf,"\015\012");}/* Output RFC 2822 header text line * Accepts: buffer *	    pointer to header type *	    non-NIL if resending *	    pointer to text * Returns: T if success, NIL if failure */long rfc822_output_header_line (RFC822BUFFER *buf,char *type,long resent,				char *text){  return !text ||    ((resent ? rfc822_output_string (buf,resentprefix) : LONGT) &&     rfc822_output_string (buf,type) && rfc822_output_string (buf,": ") &&     rfc822_output_string (buf,text) && rfc822_output_string (buf,"\015\012"));}/* Output RFC 2822 header address line * Accepts: buffer *	    pointer to header type *	    non-NIL if resending *	    address(s) to interpret *	    non-standard specials to be used for phrases if non-NIL * Returns: T if success, NIL if failure */long rfc822_output_address_line (RFC822BUFFER *buf,char *type,long resent,				 ADDRESS *adr,const char *specials){  long pretty = strlen (type);  return !adr ||    ((resent ? rfc822_output_string (buf,resentprefix) : LONGT) &&     rfc822_output_data (buf,type,pretty) && rfc822_output_string (buf,": ") &&     rfc822_output_address_list (buf,adr,				 resent ? pretty + sizeof (RESENTPREFIX) - 1 :				 pretty,specials) &&     rfc822_output_string (buf,"\015\012"));}/* Output RFC 2822 address list * Accepts: buffer *	    pointer to address list *	    non-zero if pretty-printing *	    non-standard specials to be used for phrases if non-NIL

⌨️ 快捷键说明

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