?? rfc822.c
字號:
rfc822_skipws (string); /* skip WS in the normal way */ } else adr = rfc822_parse_addrspec (s,string,defaulthost); } return adr; /* return the address */}/* Check if address is a phrase only * Accepts: pointer to end of phrase * Returns: T if phrase only, else NIL; */long rfc822_phraseonly (char *end){ while (*end == ' ') ++end; /* call rfc822_skipws() instead?? */ switch (*end) { case '\0': case ',': case ';': return LONGT; /* is a phrase only */ } return NIL; /* something other than phase is here */}/* Parse RFC822 route-address * Accepts: string pointer * pointer to string pointer to update * Returns: address * * Updates string pointer */ADDRESS *rfc822_parse_routeaddr (char *string,char **ret,char *defaulthost){ char tmp[MAILTMPLEN]; ADDRESS *adr; char *adl = NIL; char *routeend = NIL; if (!string) return NIL; rfc822_skipws (&string); /* flush leading whitespace */ /* must start with open broket */ if (*string != '<') return NIL; if (string[1] == '@') { /* have an A-D-L? */ adl = ++string; /* yes, remember that fact */ while (*string != ':') { /* search for end of A-D-L */ /* punt if never found */ if (!*string) return NIL; ++string; /* try next character */ } *string = '\0'; /* tie off A-D-L */ routeend = string; /* remember in case need to put back */ } /* parse address spec */ if (!(adr = rfc822_parse_addrspec (++string,ret,defaulthost))) { if (adl) *routeend = ':'; /* put colon back since parse barfed */ return NIL; } /* have an A-D-L? */ if (adl) adr->adl = cpystr (adl); if (*ret) if (**ret == '>') { /* make sure terminated OK */ ++*ret; /* skip past the broket */ rfc822_skipws (ret); /* flush trailing WS */ if (!**ret) *ret = NIL; /* wipe pointer if at end of string */ return adr; /* return the address */ } sprintf (tmp,"Unterminated mailbox: %.80s@%.80s",adr->mailbox, *adr->host == '@' ? "<null>" : adr->host); mm_log (tmp,PARSE); adr->next = mail_newaddr (); adr->next->mailbox = cpystr ("MISSING_MAILBOX_TERMINATOR"); adr->next->host = cpystr (errhst); return adr; /* return the address */}/* Parse RFC822 address-spec * Accepts: string pointer * pointer to string pointer to update * default host * Returns: address * * Updates string pointer */ADDRESS *rfc822_parse_addrspec (char *string,char **ret,char *defaulthost){ ADDRESS *adr; char *end; char c,*s,*t; if (!string) return NIL; /* no string */ rfc822_skipws (&string); /* flush leading whitespace */ if (!*string) return NIL; /* empty string */ /* find end of mailbox */ if (!(end = rfc822_parse_word (string,NIL))) return NIL; adr = mail_newaddr (); /* create address block */ c = *end; /* remember delimiter */ *end = '\0'; /* tie off mailbox */ /* copy mailbox */ adr->mailbox = rfc822_cpy (string); *end = c; /* restore delimiter */ t = end; /* remember end of mailbox for no host case */ rfc822_skipws (&end); /* skip whitespace */ if (*end == '@') { /* have host name? */ ++end; /* skip delimiter */ rfc822_skipws (&end); /* skip whitespace */ if (*end == '[') { /* domain literal? */ string = end; /* start of domain literal */ if (end = rfc822_parse_word (string + 1,"]\\")) { size_t len = ++end - string; strncpy (adr->host = (char *) fs_get (len + 1),string,len); adr->host[len] = '\0'; /* tie off literal */ } else { mm_log ("Invalid domain literal after @",PARSE); adr->host = cpystr (errhst); } } /* search for end of host */ else if (end = rfc822_parse_word ((string = end),wspecials)) { c = *end; /* remember delimiter */ *end = '\0'; /* tie off host */ /* copy host */ adr->host = rfc822_cpy (string); *end = c; /* restore delimiter */ } else { mm_log ("Missing or invalid host name after @",PARSE); adr->host = cpystr (errhst); } } else end = t; /* make person name default start after mbx */ /* default host if missing */ if (!adr->host) adr->host = cpystr (defaulthost); if (end && !adr->personal) { /* try person name in comments if missing */ while (*end == ' ') ++end; /* see if we can find a person name here */ if ((*end == '(') && (s = rfc822_skip_comment (&end,LONGT)) && strlen (s)) adr->personal = rfc822_cpy (s); rfc822_skipws (&end); /* skip any other WS in the normal way */ } /* set return to end pointer */ *ret = (end && *end) ? end : NIL; return adr; /* return the address we got */}/* Parse RFC822 phrase * Accepts: string pointer * Returns: pointer to end of phrase */char *rfc822_parse_phrase (char *s){ char *curpos; if (!s) return NIL; /* no-op if no string */ /* find first word of phrase */ curpos = rfc822_parse_word (s,NIL); if (!curpos) return NIL; /* no words means no phrase */ if (!*curpos) return curpos; /* check if string ends with word */ s = curpos; /* sniff past the end of this word and WS */ rfc822_skipws (&s); /* skip whitespace */ /* recurse to see if any more */ return (s = rfc822_parse_phrase (s)) ? s : curpos;}/* Parse RFC822 word * Accepts: string pointer * 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 */ /* default delimiters to standard */ if (!delimiters) delimiters = wspecials; str = s; /* hunt pointer for strpbrk */ while (T) { /* look for delimiter */ if (!(st = strpbrk (str,delimiters))) { while (*s) ++s; /* no delimiter, hunt for end */ return s; /* return it */ } 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 RFC822 format string * Accepts: string * Returns: copy of string */char *rfc822_cpy (char *src){ /* copy and unquote */ return rfc822_quote (cpystr (src));}/* Unquote an RFC822 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 RFC822 whitespace * Accepts: pointer to string pointer */void rfc822_skipws (char **s){ while (T) { if (**s == ' ') ++*s; /* skip space */ else if ((**s != '(') || !rfc822_skip_comment (s,(long) NIL)) return; }}/* Skips RFC822 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 */}/* Body contents utility and encoding/decoding routines *//* Output RFC 822 message * Accepts: temporary buffer * envelope * body * I/O routine * stream for I/O routine * non-zero if 8-bit output desired * Returns: T if successful, NIL if failure */long rfc822_output (char *t,ENVELOPE *env,BODY *body,soutr_t f,void *s, long ok8bit){ rfc822out_t r822o = (rfc822out_t) mail_parameters (NIL,GET_RFC822OUTPUT,NIL); /* call external RFC822 output generator */ if (r822o) return (*r822o) (t,env,body,f,s,ok8bit); /* encode body as necessary */ if (ok8bit) rfc822_encode_body_8bit (env,body); else rfc822_encode_body_7bit (env,body); rfc822_header (t,env,body); /* build RFC822 header */ /* output header and body */ return (*f) (s,t) && (body ? rfc822_output_body (body,f,s) : T);}/* Encode a body for 7BIT transmittal * Accepts: envelope * body */void rfc822_encode_body_7bit (ENVELOPE *env,BODY *body){ void *f; PART *part;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -