📄 rfc822.c
字号:
case '\015': /* handle CRLF form */ if (CHR (bs) == '\012'){/* following LF? */ c = SNX (bs); i--; /* yes, slurp it */ } case '\012': /* at start of a line, start with -- ? */ if (!(i && i-- && ((c = SNX (bs)) == '-') && i-- && ((c = SNX (bs)) == '-'))) break; /* see if cookie matches */ if (k = j - 2) for (s = s1; i-- && *s++ == (c = SNX (bs)) && --k;); if (k) break; /* strings didn't match if non-zero */ /* terminating delimiter? */ if ((c = ((i && i--) ? (SNX (bs)) : '\012')) == '-') { if ((i && i--) && ((c = SNX (bs)) == '-') && ((i && i--) ? (((c = SNX (bs)) == '\015') || (c=='\012')):T)) { /* if have a final part calculate its size */ if (part) part->body.mime.text.size = (m > part->body.mime.offset) ? (m - part->body.mime.offset) :0; part = NIL; i = 1; /* terminate scan */ } break; } /* swallow trailing whitespace */ while ((c == ' ') || (c == '\t')) c = ((i && i--) ? (SNX (bs)) : '\012'); switch (c) { /* need newline after all of it */ case '\015': /* handle CRLF form */ if (i && CHR (bs) == '\012') { c = SNX (bs); i--;/* yes, slurp it */ } case '\012': /* new line */ if (part) { /* calculate size of previous */ part->body.mime.text.size = (m > part->body.mime.offset) ? (m-part->body.mime.offset) : 0; /* instantiate next */ part = part->next = mail_newbody_part (); } /* otherwise start new list */ else part = body->nested.part = mail_newbody_part (); /* digest has a different default */ if (f) part->body.type = TYPEMESSAGE; /* note offset from main body */ part->body.mime.offset = GETPOS (bs); break; default: /* whatever it was it wasn't valid */ break; } break; default: /* not at a line */ c = SNX (bs); i--; /* get next character */ break; } } /* calculate size of any final part */ if (part) part->body.mime.text.size = i + ((GETPOS(bs) > part->body.mime.offset) ? (GETPOS(bs) - part->body.mime.offset) : 0); /* make a scratch buffer */ s1 = (char *) fs_get ((size_t) (k = MAILTMPLEN)); /* in case empty multipart */ if (!body->nested.part) body->nested.part = mail_newbody_part (); /* parse non-empty body parts */ for (part = body->nested.part; part; part = part->next) { /* part non-empty (header and/or content)? */ if (i = part->body.mime.text.size) { /* move to that part of the body */ SETPOS (bs,part->body.mime.offset); /* until end of header */ while (i && ((c = CHR (bs)) != '\015') && (c != '\012')) { /* collect text until logical end of line */ for (j = 0,c = ' '; c; ) { /* make sure buffer big enough */ if (j > (k - 10)) fs_resize ((void **) &s1,k += MAILTMPLEN); switch (c1 = SNX (bs)) { case '\015': /* return */ if (i && (CHR (bs) == '\012')) { c1 = SNX (bs); /* eat any LF following */ i--; } case '\012': /* newline, possible end of logical line */ /* tie off unless continuation */ if (!i || ((CHR (bs) != ' ') && (CHR (bs) != '\t'))) s1[j] = c = '\0'; break; case '\t': /* tab */ case ' ': /* insert whitespace if not already there */ if (c != ' ') s1[j++] = c = ' '; break; default: /* all other characters */ s1[j++] = c = c1; /* insert the character into the line */ break; } /* end of data ties off the header */ if (!i || !--i) s1[j++] = c = '\0'; } /* find header item type */ if (((s1[0] == 'C') || (s1[0] == 'c')) && ((s1[1] == 'O') || (s1[1] == 'o')) && ((s1[2] == 'N') || (s1[2] == 'n')) && ((s1[3] == 'T') || (s1[3] == 't')) && ((s1[4] == 'E') || (s1[4] == 'e')) && ((s1[5] == 'N') || (s1[5] == 'n')) && ((s1[6] == 'T') || (s1[6] == 't')) && (s1[7] == '-') && (s = strchr (s1+8,':'))) { /* tie off and flush whitespace */ for (*s++ = '\0'; *s == ' '; s++); /* parse the header */ rfc822_parse_content_header (&part->body,ucase (s1+8),s); } } /* skip header trailing (CR)LF */ if (i && (CHR (bs) =='\015')) {i--; c1 = SNX (bs);} if (i && (CHR (bs) =='\012')) {i--; c1 = SNX (bs);} j = bs->size; /* save upper level size */ /* set offset for next level, fake size to i */ bs->size = GETPOS (bs) + i; part->body.mime.text.size -= i; /* now parse it */ rfc822_parse_content (&part->body,bs,h,depth+1,flags); bs->size = j; /* restore current level size */ } else { /* zero-length part, use default subtype */ part->body.subtype = cpystr (rfc822_default_subtype (part->body.type)); /* see if anything else special to do */ switch (part->body.type) { case TYPETEXT: /* text content */ /* default parameters */ if (!part->body.parameter) { part->body.parameter = mail_newbody_parameter (); part->body.parameter->attribute = cpystr ("CHARSET"); /* only assume US-ASCII if 7BIT */ part->body.parameter->value = cpystr ((part->body.encoding == ENC7BIT) ? "US-ASCII" : "X-UNKNOWN"); } break; case TYPEMESSAGE: /* encapsulated message in digest */ part->body.nested.msg = mail_newmsg (); break; default: break; } } } fs_give ((void **) &s1); /* finished with scratch buffer */ break; default: /* nothing special to do in any other case */ break; }}/* Parse RFC 2822 body content header * Accepts: body to write to * possible content name * remainder of header */void rfc822_parse_content_header (BODY *body,char *name,char *s){ char c,*t,tmp[MAILTMPLEN]; long i; STRINGLIST *stl; rfc822_skipws (&s); /* skip leading comments */ /* flush whitespace */ if (t = strchr (name,' ')) *t = '\0'; switch (*name) { /* see what kind of content */ case 'I': /* possible Content-ID */ if (!(strcmp (name+1,"D") || body->id)) body->id = cpystr (s); break; case 'D': /* possible Content-Description */ if (!(strcmp (name+1,"ESCRIPTION") || body->description)) body->description = cpystr (s); if (!(strcmp (name+1,"ISPOSITION") || body->disposition.type)) { /* get type word */ if (!(name = rfc822_parse_word (s,tspecials))) break; c = *name; /* remember delimiter */ *name = '\0'; /* tie off type */ body->disposition.type = ucase (cpystr (s)); *name = c; /* restore delimiter */ rfc822_skipws (&name); /* skip whitespace */ rfc822_parse_parameter (&body->disposition.parameter,name); } break; case 'L': /* possible Content-Language */ if (!(strcmp (name+1,"ANGUAGE") || body->language)) { stl = NIL; /* process languages */ while (s && (name = rfc822_parse_word (s,tspecials))) { c = *name; /* save delimiter */ *name = '\0'; /* tie off subtype */ if (stl) stl = stl->next = mail_newstringlist (); else stl = body->language = mail_newstringlist (); stl->text.data = (unsigned char *) ucase (cpystr (s)); stl->text.size = strlen ((char *) stl->text.data); *name = c; /* restore delimiter */ rfc822_skipws (&name); /* skip whitespace */ if (*name == ',') { /* any more languages? */ s = ++name; /* advance to it them */ rfc822_skipws (&s); } else s = NIL; /* bogus or end of list */ } } else if (!(strcmp (name+1,"OCATION") || body->location)) body->location = cpystr (s); break; case 'M': /* possible Content-MD5 */ if (!(strcmp (name+1,"D5") || body->md5)) body->md5 = cpystr (s); break; case 'T': /* possible Content-Type/Transfer-Encoding */ if (!(strcmp (name+1,"YPE") || body->subtype || body->parameter)) { /* get type word */ if (!(name = rfc822_parse_word (s,tspecials))) break; c = *name; /* remember delimiter */ *name = '\0'; /* tie off type */ /* search for body type */ for (i = 0,s = rfc822_cpy (s); (i <= TYPEMAX) && body_types[i] && compare_cstring (s,body_types[i]); i++); if (i > TYPEMAX) { /* fell off end of loop? */ body->type = TYPEOTHER; /* coerce to X-UNKNOWN */ sprintf (tmp,"MIME type table overflow: %.100s",s); MM_LOG (tmp,PARSE); } else { /* record body type index */ body->type = (unsigned short) i; /* and name if new type */ if (body_types[body->type]) fs_give ((void **) &s); else { /* major MIME body type unknown to us */ body_types[body->type] = ucase (s); sprintf (tmp,"Unknown MIME type: %.100s",s); MM_LOG (tmp,PARSE); } } *name = c; /* restore delimiter */ rfc822_skipws (&name); /* skip whitespace */ if ((*name == '/') && /* subtype? */ (name = rfc822_parse_word ((s = ++name),tspecials))) { c = *name; /* save delimiter */ *name = '\0'; /* tie off subtype */ rfc822_skipws (&s); /* copy subtype */ if (s) body->subtype = ucase (rfc822_cpy (s)); *name = c; /* restore delimiter */ rfc822_skipws (&name); /* skip whitespace */ } else if (!name) { /* no subtype, was a subtype delimiter? */ name = s; /* barf, restore pointer */ rfc822_skipws (&name); /* skip leading whitespace */ } rfc822_parse_parameter (&body->parameter,name); } else if (!strcmp (name+1,"RANSFER-ENCODING")) { if (!(name = rfc822_parse_word (s,tspecials))) break; c = *name; /* remember delimiter */ *name = '\0'; /* tie off encoding */ /* search for body encoding */ for (i = 0,s = rfc822_cpy (s); (i <= ENCMAX) && body_encodings[i] && compare_cstring (s,body_encodings[i]); i++); if (i > ENCMAX) { /* fell off end of loop? */ body->encoding = ENCOTHER; sprintf (tmp,"MIME encoding table overflow: %.100s",s); MM_LOG (tmp,PARSE); } else { /* record body encoding index */ body->encoding = (unsigned short) i; /* and name if new encoding */ if (body_encodings[body->encoding]) fs_give ((void **) &s); else { body_encodings[body->encoding] = ucase (s); sprintf (tmp,"Unknown MIME transfer encoding: %.100s",s); MM_LOG (tmp,PARSE); } } *name = c; /* restore delimiter */ /* ??check for cruft here?? */ } break; default: /* otherwise unknown */ break; }}/* Parse RFC 2822 body parameter list * Accepts: parameter list to write to * text of list */void rfc822_parse_parameter (PARAMETER **par,char *text){ char c,*s,tmp[MAILTMPLEN]; PARAMETER *param = NIL; /* parameter list? */ while (text && (*text == ';') && (text = rfc822_parse_word ((s = ++text),tspecials))) { c = *text; /* remember delimiter */ *text = '\0'; /* tie off attribute name */ rfc822_skipws (&s); /* skip leading attribute whitespace */ if (!*s) *text = c; /* must have an attribute name */ else { /* instantiate a new parameter */ if (*par) param = param->next = mail_newbody_parameter (); else param = *par = mail_newbody_parameter (); param->attribute = ucase (cpystr (s)); *text = c; /* restore delimiter */ rfc822_skipws (&text); /* skip whitespace before equal sign */ if ((*text == '=') && /* make sure have value */ (text = rfc822_parse_word ((s = ++text),tspecials))) { c = *text; /* remember delimiter */ *text = '\0'; /* tie off value */ rfc822_skipws (&s); /* skip leading value whitespace */ if (*s) param->value = rfc822_cpy (s); *text = c; /* restore delimiter */ rfc822_skipws (&text); } if (!param->value) { /* value not found? */ param->value = cpystr ("MISSING_PARAMETER_VALUE"); sprintf (tmp,"Missing parameter value: %.80s",param->attribute); MM_LOG (tmp,PARSE); } } } /* string not present */ if (!text) MM_LOG ("Missing parameter",PARSE); else if (*text) { /* must be end of poop */ sprintf (tmp,"Unexpected characters at end of parameters: %.80s",text); MM_LOG (tmp,PARSE); }}/* Parse RFC 2822 address list * Accepts: address list to write to * input string * default host name */void rfc822_parse_adrlist (ADDRESS **lst,char *string,char *host){ int c; char *s,tmp[MAILTMPLEN]; ADDRESS *last = *lst; ADDRESS *adr; if (!string) return; /* no string */ rfc822_skipws (&string); /* skip leading WS */ if (!*string) return; /* empty string */ /* run to tail of list */ if (last) while (last->next) last = last->next; while (string) { /* loop until string exhausted */ while (*string == ',') { /* RFC 822 allowed null addresses!! */ ++string; /* skip the comma */ rfc822_skipws (&string); /* and any leading WS */ } if (!*string) string = NIL; /* punt if ran out of string */ /* got an address? */ else if (adr = rfc822_parse_address (lst,last,&string,host,0)) { last = adr; /* new tail address */ if (string) { /* analyze what follows */ rfc822_skipws (&string); switch (c = *(unsigned char *) string) { case ',': /* comma? */ ++string; /* then another address follows */ break; default: s = isalnum (c) ? "Must use comma to separate addresses: %.80s" : "Unexpected characters at end of address: %.80s"; sprintf (tmp,s,string); MM_LOG (tmp,PARSE); last = last->next = mail_newaddr (); last->mailbox = cpystr ("UNEXPECTED_DATA_AFTER_ADDRESS"); last->host = cpystr (errhst); /* falls through */ case '\0': /* null-specified address? */ string = NIL; /* punt remainder of parse */ break; } } } else if (string) { /* bad mailbox */ rfc822_skipws (&string); /* skip WS */ if (!*string) strcpy (tmp,"Missing address after comma"); else sprintf (tmp,"Invalid mailbox list: %.80s",string); MM_LOG (tmp,PARSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -