📄 rfc822.c
字号:
* Returns: T if success, NIL if failure */long rfc822_output_address_list (RFC822BUFFER *buf,ADDRESS *adr,long pretty, const char *specials){ long n; /* default to rspecials */ if (!specials) specials = rspecials; for (n = 0; adr; adr = adr->next) { char *base = buf->cur; if (adr->host) { /* ordinary address? */ if (!(pretty && n)) { /* suppress if pretty and in group */ if ( /* use phrase <route-addr> if phrase */#if RFC822 adr->adl || /* or A-D-L */#endif (adr->personal && *adr->personal)) { if (!((adr->personal ? rfc822_output_cat (buf,adr->personal, rspecials) : LONGT) && rfc822_output_string (buf," <") && rfc822_output_address (buf,adr) && rfc822_output_string (buf,">"))) return NIL; } else if (!rfc822_output_address (buf,adr)) return NIL; if (adr->next && adr->next->mailbox && !rfc822_output_string (buf,", ")) return NIL; } } else if (adr->mailbox) { /* start of group? */ /* yes, write group */ if (!(rfc822_output_cat (buf,adr->mailbox,rspecials) && rfc822_output_string (buf,": "))) return NIL; ++n; /* in a group now */ } else if (n) { /* must be end of group (but be paranoid) */ if (!rfc822_output_char (buf,';') || ((!--n && adr->next && adr->next->mailbox) && !rfc822_output_string (buf,", "))) return NIL; } if (pretty && adr->next && /* pretty printing? */ ((pretty += ((buf->cur > base) ? buf->cur - base : (buf->end - base) + (buf->cur - buf->beg))) >= 78)) { if (!(rfc822_output_string (buf,"\015\012") && rfc822_output_string (buf,RFC822CONT))) return NIL; base = buf->cur; /* update base for pretty printing */ pretty = sizeof (RFC822CONT) - 1; } } return LONGT;}/* Write RFC 2822 route-address to string * Accepts: buffer * pointer to single address * Returns: T if success, NIL if failure */long rfc822_output_address (RFC822BUFFER *buf,ADDRESS *adr){ return !adr || !adr->host || (#if RFC822 /* old code with A-D-L support */ (!adr->adl || (rfc822_output_string (buf,adr->adl) && rfc822_output_char (buf,':'))) &&#endif rfc822_output_cat (buf,adr->mailbox,NIL) && ((*adr->host == '@') || /* unless null host (HIGHLY discouraged!) */ (rfc822_output_char (buf,'@') && rfc822_output_cat (buf,adr->host,NIL))));}/* Output RFC 2822 string with concatenation * Accepts: buffer * string to concatenate * list of special characters or NIL for dot-atom format * Returns: T if success, NIL if failure */long rfc822_output_cat (RFC822BUFFER *buf,char *src,const char *specials){ char *s; if (!*src || /* empty string or any specials present? */ (specials ? (T && strpbrk (src,specials)) : (strpbrk (src,wspecials) || (*src == '.') || strstr (src,"..") || (src[strlen (src) - 1] == '.')))) { /* yes, write as quoted string*/ if (!rfc822_output_char (buf,'"')) return NIL; /* embedded quote characters? */ for (; s = strpbrk (src,"\\\""); src = s + 1) { /* yes, insert quoting */ if (!(rfc822_output_data (buf,src,s-src) && rfc822_output_char (buf,'\\') && rfc822_output_char (buf,*s))) return NIL; } /* return string and trailing quote*/ return rfc822_output_string (buf,src) && rfc822_output_char (buf,'"'); } /* easy case */ return rfc822_output_string (buf,src);}/* Output MIME parameter list * Accepts: buffer * parameter list * Returns: T if success, NIL if failure */long rfc822_output_parameter (RFC822BUFFER *buf,PARAMETER *param){ while (param) { if (rfc822_output_string (buf,"; ") && rfc822_output_string (buf,param->attribute) && rfc822_output_char (buf,'=') && rfc822_output_cat (buf,param->value,tspecials)) param = param->next; else return NIL; } return LONGT;}/* Output RFC 2822 stringlist * Accepts: buffer * stringlist * Returns: T if success, NIL if failure */long rfc822_output_stringlist (RFC822BUFFER *buf,STRINGLIST *stl){ while (stl) if (!rfc822_output_cat (buf,(char *) stl->text.data,tspecials) || ((stl = stl->next) && !rfc822_output_string (buf,", "))) return NIL; return LONGT;}/* Output body content header * Accepts: buffer * body to interpret * Returns: T if success, NIL if failure */long rfc822_output_body_header (RFC822BUFFER *buf,BODY *body){ return /* type and subtype*/ rfc822_output_string (buf,"Content-Type: ") && rfc822_output_string (buf,body_types[body->type]) && rfc822_output_char (buf,'/') && rfc822_output_string (buf,body->subtype ? body->subtype : rfc822_default_subtype (body->type)) && /* parameters (w/ US-ASCII default */ (body->parameter ? rfc822_output_parameter (buf,body->parameter) : ((body->type != TYPETEXT) || (rfc822_output_string (buf,"; CHARSET=") && rfc822_output_string (buf,(body->encoding == ENC7BIT) ? "US-ASCII" : "X-UNKNOWN")))) && (!body->encoding || /* note: 7BIT never output as encoding! */ (rfc822_output_string (buf,"\015\012Content-Transfer-Encoding: ") && rfc822_output_string (buf,body_encodings[body->encoding]))) && (!body->id || /* identification */ (rfc822_output_string (buf,"\015\012Content-ID: ") && rfc822_output_string (buf,body->id))) && (!body->description || /* description */ (rfc822_output_string (buf,"\015\012Content-Description: ") && rfc822_output_string (buf,body->description))) && (!body->md5 || /* MD5 checksum */ (rfc822_output_string (buf,"\015\012Content-MD5: ") && rfc822_output_string (buf,body->md5))) && (!body->language || /* language */ (rfc822_output_string (buf,"\015\012Content-Language: ") && rfc822_output_stringlist (buf,body->language))) && (!body->location || /* location */ (rfc822_output_string (buf,"\015\012Content-Location: ") && rfc822_output_string (buf,body->location))) && (!body->disposition.type || /* disposition */ (rfc822_output_string (buf,"\015\012Content-Disposition: ") && rfc822_output_string (buf,body->disposition.type) && rfc822_output_parameter (buf,body->disposition.parameter))) && rfc822_output_string (buf,"\015\012");}/* Encode a body for 7BIT transmittal * Accepts: envelope * body */void rfc822_encode_body_7bit (ENVELOPE *env,BODY *body){ void *f; PART *part; PARAMETER **param; if (body) switch (body->type) { case TYPEMULTIPART: /* multi-part */ for (param = &body->parameter; *param && strcmp ((*param)->attribute,"BOUNDARY"); param = &(*param)->next); if (!*param) { /* cookie not set up yet? */ char tmp[MAILTMPLEN]; /* make cookie not in BASE64 or QUOTEPRINT*/ sprintf (tmp,"%lu-%lu-%lu=:%lu",(unsigned long) gethostid (), (unsigned long) random (),(unsigned long) time (0), (unsigned long) getpid ()); (*param) = mail_newbody_parameter (); (*param)->attribute = cpystr ("BOUNDARY"); (*param)->value = cpystr (tmp); } part = body->nested.part; /* encode body parts */ do rfc822_encode_body_7bit (env,&part->body); while (part = part->next); /* until done */ break; case TYPEMESSAGE: /* encapsulated message */ switch (body->encoding) { case ENC7BIT: break; case ENC8BIT: MM_LOG ("8-bit included message in 7-bit message body",PARSE); break; case ENCBINARY: MM_LOG ("Binary included message in 7-bit message body",PARSE); break; default: fatal ("Invalid rfc822_encode_body_7bit message encoding"); } break; /* can't change encoding */ default: /* all else has some encoding */ switch (body->encoding) { case ENC8BIT: /* encode 8BIT into QUOTED-PRINTABLE */ /* remember old 8-bit contents */ f = (void *) body->contents.text.data; body->contents.text.data = rfc822_8bit (body->contents.text.data, body->contents.text.size,&body->contents.text.size); body->encoding = ENCQUOTEDPRINTABLE; fs_give (&f); /* flush old binary contents */ break; case ENCBINARY: /* encode binary into BASE64 */ /* remember old binary contents */ f = (void *) body->contents.text.data; body->contents.text.data = rfc822_binary ((void *) body->contents.text.data, body->contents.text.size,&body->contents.text.size); body->encoding = ENCBASE64; fs_give (&f); /* flush old binary contents */ default: /* otherwise OK */ break; } break; }}/* Encode a body for 8BIT transmittal * Accepts: envelope * body */void rfc822_encode_body_8bit (ENVELOPE *env,BODY *body){ void *f; PART *part; PARAMETER **param; if (body) switch (body->type) { case TYPEMULTIPART: /* multi-part */ for (param = &body->parameter; *param && strcmp ((*param)->attribute,"BOUNDARY"); param = &(*param)->next); if (!*param) { /* cookie not set up yet? */ char tmp[MAILTMPLEN]; /* make cookie not in BASE64 or QUOTEPRINT*/ sprintf (tmp,"%lu-%lu-%lu=:%lu",(unsigned long) gethostid (), (unsigned long) random (),(unsigned long) time (0), (unsigned long) getpid ()); (*param) = mail_newbody_parameter (); (*param)->attribute = cpystr ("BOUNDARY"); (*param)->value = cpystr (tmp); } part = body->nested.part; /* encode body parts */ do rfc822_encode_body_8bit (env,&part->body); while (part = part->next); /* until done */ break; case TYPEMESSAGE: /* encapsulated message */ switch (body->encoding) { case ENC7BIT: case ENC8BIT: break; case ENCBINARY: MM_LOG ("Binary included message in 8-bit message body",PARSE); break; default: fatal ("Invalid rfc822_encode_body_7bit message encoding"); } break; /* can't change encoding */ default: /* other type, encode binary into BASE64 */ if (body->encoding == ENCBINARY) { /* remember old binary contents */ f = (void *) body->contents.text.data; body->contents.text.data = rfc822_binary ((void *) body->contents.text.data, body->contents.text.size,&body->contents.text.size); body->encoding = ENCBASE64; fs_give (&f); /* flush old binary contents */ } break; }}/* Output RFC 822 text * Accepts: buffer * body * Returns: T if successful, NIL if failure */long rfc822_output_text (RFC822BUFFER *buf,BODY *body){ /* MULTIPART gets special handling */ if (body->type == TYPEMULTIPART) { char *cookie,tmp[MAILTMPLEN]; PARAMETER *param; PART *part; /* find cookie */ for (param = body->parameter; param && strcmp (param->attribute,"BOUNDARY"); param = param->next); if (param) cookie = param->value; else { /* make cookie not in BASE64 or QUOTEPRINT*/ sprintf (cookie = tmp,"%lu-%lu-%lu=:%lu",(unsigned long) gethostid (), (unsigned long) random (),(unsigned long) time (0), (unsigned long) getpid ()); (param = mail_newbody_parameter ())->attribute = cpystr ("BOUNDARY"); param->value = cpystr (tmp); param->next = body->parameter; body->parameter = param; } /* output each part */ for (part = body->nested.part; part; part = part->next) if (!(rfc822_output_string (buf,"--") && rfc822_output_string (buf,cookie) && rfc822_output_string (buf,"\015\012") && rfc822_output_body_header (buf,&part->body) && rfc822_output_string (buf,"\015\012") && rfc822_output_text (buf,&part->body))) return NIL; /* output trailing cookie */ return rfc822_output_string (buf,"--") && rfc822_output_string (buf,cookie) && rfc822_output_string (buf,"--\015\012"); } /* output segment and trailing CRLF */ return (!body->contents.text.data || rfc822_output_string (buf,(char *) body->contents.text.data)) && rfc822_output_string (buf,"\015\012");}/* Body contents encoding/decoding routines *//* Convert BASE64 contents to binary * Accepts: source * length of source * pointer to return destination length * Returns: destination as binary or NIL if error */#define WSP 0176 /* NUL, TAB, LF, FF, CR, SPC */#define JNK 0177#define PAD 0100void *rfc822_base64 (unsigned char *src,unsigned long srcl,unsigned long *len){ char c,*s,tmp[MAILTMPLEN]; void *ret = fs_get ((size_t) ((*len = 4 + ((srcl * 3) / 4))) + 1); char *d = (char *) ret; int e; static char decode[256] = { WSP,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,WSP,WSP,JNK,WSP,WSP,JNK,JNK, JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK, WSP,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,076,JNK,JNK,JNK,077, 064,065,066,067,070,071,072,073,074,075,JNK,JNK,JNK,PAD,JNK,JNK, JNK,000,001,002,003,004,005,006,007,010,011,012,013,014,015,016, 017,020,021,022,023,024,025,026,027,030,031,JNK,JNK,JNK,JNK,JNK, JNK,032,033,034,035,036,037,040,041,042,043,044,045,046,047,050, 051,052,053,054,055,056,057,060,061,062,063,JNK,JNK,JNK,JNK,JNK, JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK,JNK, JNK,JNK,J
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -