?? rfc822.c
字號:
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 part->body.subtype = /* default subtype if necessary */ cpystr (rfc822_default_subtype (part->body.type)); } fs_give ((void **) &s1); /* finished with scratch buffer */ break; default: /* nothing special to do in any other case */ break; }}/* Parse RFC822 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; long i; STRINGLIST *stl; /* 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,ptspecials))) 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,ptspecials))) { 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 */ } } 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,ptspecials))) break; c = *name; /* remember delimiter */ *name = '\0'; /* tie off type */ ucase (s); /* search for body type */ for (i=0; (i<=TYPEMAX) && body_types[i] && strcmp(s,body_types[i]); i++); if (i > TYPEMAX) body->type = TYPEOTHER; else { /* if empty slot, assign it to this type */ if (!body_types[i]) body_types[i] = cpystr (s); body->type = (unsigned short) i; } *name = c; /* restore delimiter */ rfc822_skipws (&name); /* skip whitespace */ if ((*name == '/') && /* subtype? */ (name = rfc822_parse_word ((s = ++name),ptspecials))) { c = *name; /* save delimiter */ *name = '\0'; /* tie off subtype */ rfc822_skipws (&s); /* copy subtype */ if (s) body->subtype = ucase (cpystr (s)); *name = c; /* restore delimiter */ rfc822_skipws (&name); /* skip whitespace */ } else { /* no subtype */ if (!name) { /* did the fool have 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")) { /* flush out any confusing whitespace */ if (t = strchr (ucase (s),' ')) *t = '\0'; /* search for body encoding */ for (i = 0; (i <= ENCMAX) && body_encodings[i] && strcmp (s,body_encodings[i]); i++); if (i > ENCMAX) body->type = ENCOTHER; else { /* if empty slot, assign it to this type */ if (!body_encodings[i]) body_encodings[i] = cpystr (s); body->encoding = (unsigned short) i; } } break; default: /* otherwise unknown */ break; }}/* Parse RFC822 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),ptspecials))) { 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 != '=') || /* missing value is a no-no too */ !(text = rfc822_parse_word ((s = ++text),ptspecials))) param->value = cpystr ("UNKNOWN_PARAMETER_VALUE"); else { /* good, have equals sign */ 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 (!text) { /* must be end of poop */ if (param && param->attribute) sprintf (tmp,"Missing parameter value: %.80s",param->attribute); else strcpy (tmp,"Missing parameter"); mm_log (tmp,PARSE); } else if (*text) { /* must be end of poop */ sprintf (tmp,"Unexpected characters at end of parameters: %.80s",text); mm_log (tmp,PARSE); }}/* Parse RFC822 address list * Accepts: address list to write to * input string * default host name */void rfc822_parse_adrlist (ADDRESS **lst,char *string,char *host){ char c,*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 */ /* got an address? */ 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 = *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); 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 RFC822 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 RFC822 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 RFC822 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 */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -