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

📄 rfc822.c

📁 mgcp协议源代码。支持多种编码:g711
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Program:	RFC-822 routines (originally from SMTP) * * Author:	Mark Crispin *		Networks and Distributed Computing *		Computing & Communications *		University of Washington *		Administration Building, AG-44 *		Seattle, WA  98195 *		Internet: MRC@CAC.Washington.EDU * * Date:	27 July 1988 * Last Edited:	13 July 1999 * * Sponsorship:	The original version of this work was developed in the *		Symbolic Systems Resources Group of the Knowledge Systems *		Laboratory at Stanford University in 1987-88, and was funded *		by the Biomedical Research Technology Program of the National *		Institutes of Health under grant number RR-00785. * * Original version Copyright 1988 by The Leland Stanford Junior University * Copyright 1999 by the University of Washington * *  Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notices appear in all copies and that both the * above copyright notices and this permission notice appear in supporting * documentation, and that the name of the University of Washington or The * Leland Stanford Junior University not be used in advertising or publicity * pertaining to distribution of the software without specific, written prior * permission.  This software is made available "as is", and * THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY * DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE, * INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF * WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */#include <ctype.h>#include <stdio.h>#include <time.h>#include "mail.h"#include "osdep.h"#include "rfc822.h"#include "misc.h"/* RFC-822 static data */char *errhst = ERRHOST;		/* syntax error host string *//* Body formats constant strings, must match definitions in mail.h */char *body_types[TYPEMAX+1] = {  "TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO",  "MODEL", "X-UNKNOWN"};char *body_encodings[ENCMAX+1] = {  "7BIT", "8BIT", "BINARY", "BASE64", "QUOTED-PRINTABLE", "X-UNKNOWN"};/* Token delimiting special characters */				/* full RFC-822 specials */const char *rspecials =  "()<>@,;:\\\"[].";				/* body token specials */const char *tspecials = " ()<>@,;:\\\"[]./?=";/* Once upon a time, CSnet had a mailer which assigned special semantics to * dot in e-mail addresses.  For the sake of that mailer, dot was added to * the RFC-822 definition of `specials', even though it had numerous bad side * effects: *   1)	It broke mailbox names on systems which had dots in user names, such as *	Multics and TOPS-20.  RFC-822's syntax rules require that `Admin . MRC' *	be considered equivalent to `Admin.MRC'.  Fortunately, few people ever *	tried this in practice. *   2) It required that all personal names with an initial be quoted, a widely *	detested user interface misfeature. *   3)	It made the parsing of host names be non-atomic for no good reason. * To work around these problems, the following alternate specials lists are * defined.  hspecials and wspecials are used in lieu of rspecials, and * ptspecials are used in lieu of tspecials.  These alternate specials lists * make the parser work a lot better in the real world.  It ain't politically * correct, but it lets the users get their job done! */				/* parse-word specials */const char *wspecials = " ()<>@,;:\\\"[]";				/* parse-token specials for parsing */const char *ptspecials = " ()<>@,;:\\\"[]/?=";/* RFC822 writing routines *//* Write RFC822 header from message structure * Accepts: scratch buffer to write into *	    message envelope *	    message body */void rfc822_header (char *header,ENVELOPE *env,BODY *body){  if (env->remail) {		/* if remailing */    long i = strlen (env->remail);    strcpy (header,env->remail);/* start with remail header */				/* flush extra blank line */    if (i > 4 && header[i-4] == '\015') header[i-2] = '\0';  }  else *header = '\0';		/* else initialize header to null */  rfc822_header_line (&header,"Newsgroups",env,env->newsgroups);  rfc822_header_line (&header,"Date",env,env->date);  rfc822_address_line (&header,"From",env,env->from);  rfc822_address_line (&header,"Sender",env,env->sender);  rfc822_address_line (&header,"Reply-To",env,env->reply_to);  rfc822_header_line (&header,"Subject",env,env->subject);  if (env->bcc && !(env->to || env->cc))    strcat (header,"To: undisclosed recipients: ;\015\012");  rfc822_address_line (&header,"To",env,env->to);  rfc822_address_line (&header,"cc",env,env->cc);/* bcc's are never written... * rfc822_address_line (&header,"bcc",env,env->bcc); */  rfc822_header_line (&header,"In-Reply-To",env,env->in_reply_to);  rfc822_header_line (&header,"Message-ID",env,env->message_id);  rfc822_header_line (&header,"Followup-to",env,env->followup_to);  rfc822_header_line (&header,"References",env,env->references);  if (body && !env->remail) {	/* not if remail or no body structure */    strcat (header,"MIME-Version: 1.0\015\012");    rfc822_write_body_header (&header,body);  }  strcat (header,"\015\012");	/* write terminating blank line */}/* Write RFC822 address from header line * Accepts: pointer to destination string pointer *	    pointer to header type *	    message to interpret *	    address to interpret */void rfc822_address_line (char **header,char *type,ENVELOPE *env,ADDRESS *adr){  char *s = (*header += strlen (*header));  if (adr) {			/* do nothing if no addresses */    if (env && env->remail) strcat (s,"ReSent-");    strcat (s,type);		/* write header name */    strcat (s,": ");    s = rfc822_write_address_full (s + strlen (s),adr,*header);				/* tie off header line */    *s++ = '\015'; *s++ = '\012'; *s = '\0';    *header = s;		/* set return value */  }}/* Write RFC822 text from header line * Accepts: pointer to destination string pointer *	    pointer to header type *	    message to interpret *	    pointer to text */void rfc822_header_line (char **header,char *type,ENVELOPE *env,char *text){  if (text) sprintf ((*header += strlen (*header)),"%s%s: %s\015\012",		     env->remail ? "ReSent-" : "",type,text);}/* Write RFC822 address list * Accepts: pointer to destination string *	    address to interpret *	    header base if pretty-printing * Returns: end of destination string */				/* RFC822 continuation, must start with CRLF */#define RFC822CONT "\015\012    "char *rfc822_write_address_full (char *dest,ADDRESS *adr,char *base){  long i,n;  for (n = 0; adr; adr = adr->next) {    if (adr->host) {		/* ordinary address? */      if (!(base && n)) {	/* only write if exact form or not in group */				/* simple case? */	if (!(adr->personal || adr->adl)) rfc822_address (dest,adr);	else {			/* no, must use phrase <route-addr> form */	  if (adr->personal) rfc822_cat (dest,adr->personal,rspecials);	  strcat (dest," <");	/* write address delimiter */	  rfc822_address (dest,adr);	  strcat (dest,">");	/* closing delimiter */	}	if (adr->next && adr->next->mailbox) strcat (dest,", ");      }    }    else if (adr->mailbox) {	/* start of group? */				/* yes, write group name */      rfc822_cat (dest,adr->mailbox,rspecials);      strcat (dest,": ");	/* write group identifier */      n++;			/* in a group */    }    else if (n) {		/* must be end of group (but be paranoid) */      strcat (dest,";");				/* no longer in that group */      if (!--n && adr->next && adr->next->mailbox) strcat (dest,", ");    }    i = strlen (dest);		/* length of what we just wrote */				/* write continuation if doesn't fit */    if (base && (dest > (base + 4)) && ((dest + i) > (base + 78))) {      memmove (dest + sizeof (RFC822CONT) - 1,dest,i + 1);      memcpy (dest,RFC822CONT,sizeof (RFC822CONT) - 1);      base = dest + 2;		/* new base */      dest += i + sizeof (RFC822CONT) - 1;    }    else dest += i;		/* new end of string */  }  return dest;			/* return end of string */}/* Write RFC822 route-address to string * Accepts: pointer to destination string *	    address to interpret */void rfc822_address (char *dest,ADDRESS *adr){  if (adr && adr->host) {	/* no-op if no address */    if (adr->adl) {		/* have an A-D-L? */      strcat (dest,adr->adl);      strcat (dest,":");    }				/* write mailbox name */    rfc822_cat (dest,adr->mailbox,wspecials);    if (*adr->host != '@') {	/* unless null host (HIGHLY discouraged!) */      strcat (dest,"@");	/* host delimiter */      strcat (dest,adr->host);	/* write host name */    }  }}/* Concatenate RFC822 string * Accepts: pointer to destination string *	    pointer to string to concatenate *	    list of special characters */void rfc822_cat (char *dest,char *src,const char *specials){  char *s;  if (strpbrk (src,specials)) {	/* any specials present? */    strcat (dest,"\"");		/* opening quote */				/* truly bizarre characters in there? */    while (s = strpbrk (src,"\\\"")) {      strncat (dest,src,s-src);	/* yes, output leader */      strcat (dest,"\\");	/* quoting */      strncat (dest,s,1);	/* output the bizarre character */      src = ++s;		/* continue after the bizarre character */    }    if (*src) strcat (dest,src);/* output non-bizarre string */    strcat (dest,"\"");		/* closing quote */  }  else strcat (dest,src);	/* otherwise it's the easy case */}/* Write body content header * Accepts: pointer to destination string pointer *	    pointer to body to interpret */void rfc822_write_body_header (char **dst,BODY *body){  char *s;  STRINGLIST *stl;  PARAMETER *param = body->parameter;  sprintf (*dst += strlen (*dst),"Content-Type: %s",body_types[body->type]);  s = body->subtype ? body->subtype : rfc822_default_subtype (body->type);  sprintf (*dst += strlen (*dst),"/%s",s);  if (param) do {    sprintf (*dst += strlen (*dst),"; %s=",param->attribute);    rfc822_cat (*dst,param->value,tspecials);  } while (param = param->next);  else if (body->type == TYPETEXT) strcat (*dst,"; CHARSET=US-ASCII");  strcpy (*dst += strlen (*dst),"\015\012");  if (body->encoding)		/* note: encoding 7BIT never output! */    sprintf (*dst += strlen (*dst),"Content-Transfer-Encoding: %s\015\012",	     body_encodings[body->encoding]);  if (body->id) sprintf (*dst += strlen (*dst),"Content-ID: %s\015\012",			 body->id);  if (body->description)    sprintf (*dst += strlen (*dst),"Content-Description: %s\015\012",	     body->description);  if (body->md5)    sprintf (*dst += strlen (*dst),"Content-MD5: %s\015\012",body->md5);  if (stl = body->language) {    strcpy (*dst += strlen (*dst),"Content-Language: ");    do {      rfc822_cat (*dst,(char *) stl->text.data,tspecials);      if (stl = stl->next) strcat (*dst += strlen (*dst),", ");    }    while (stl);    strcpy (*dst += strlen (*dst),"\015\012");  }  if (body->disposition.type) {    sprintf (*dst += strlen (*dst),"Content-Disposition: %s",	     body->disposition.type);    if (param = body->disposition.parameter) do {      sprintf (*dst += strlen (*dst),"; %s=",param->attribute);      rfc822_cat (*dst,param->value,tspecials);    } while (param = param->next);    strcpy (*dst += strlen (*dst),"\015\012");  }}/* Subtype defaulting (a no-no, but regretably necessary...) * Accepts: type code * Returns: default subtype name */char *rfc822_default_subtype (unsigned short type){  switch (type) {  case TYPETEXT:		/* default is TEXT/PLAIN */    return "PLAIN";  case TYPEMULTIPART:		/* default is MULTIPART/MIXED */    return "MIXED";  case TYPEMESSAGE:		/* default is MESSAGE/RFC822 */    return "RFC822";  case TYPEAPPLICATION:		/* default is APPLICATION/OCTET-STREAM */    return "OCTET-STREAM";  case TYPEAUDIO:		/* default is AUDIO/BASIC */    return "BASIC";  default:			/* others have no default subtype */    return "UNKNOWN";  }}/* RFC822 parsing routines *//* Parse an RFC822 message * Accepts: pointer to return envelope *	    pointer to return body *	    pointer to header *	    header byte count *	    pointer to body stringstruct *	    pointer to local host name *	    recursion depth

⌨️ 快捷键说明

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