msg.c
来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 1,781 行 · 第 1/3 页
C
1,781 行
c = headChar(0); if(c == '@'){ for(;;){ c = headChar(1); if(c != '@'){ e = nil; break; } headDomain(e); c = headChar(1); if(c != ','){ e = s; break; } } if(c != ':') e = nil; } if(e != nil) e = headAddrSpec(s, nil); if(headChar(1) != '>') e = nil; } /* * e points to @host, or nil if an error occured */ if(e == nil){ free(personal); addr = nil; }else{ if(*e != '\0') *e++ = '\0'; else e = site; addr = MKZ(MAddr); addr->personal = personal; addr->box = estrdup(s); addr->host = estrdup(e); } free(s); return addr;}/* * phrase : word * | phrase word * w is the optional initial word of the phrase * returns the end of the phrase, or nil if a failure occured */static char*headPhrase(char *e, char *w){ int c; for(;;){ if(w == nil){ w = headWord(); if(w == nil) return nil; } if(w[0] == '"') stripQuotes(w); strcpy(e, w); free(w); w = nil; e = strchr(e, '\0'); c = headChar(0); if(c <= ' ' || strchr(headAtomStop, c) != nil && c != '"') break; *e++ = ' '; *e = '\0'; } return e;}/* * addr-spec : local-part '@' domain * | local-part extension to allow ! and local names * local-part : word * | local-part '.' word * * if no '@' is present, rewrite d!e!f!u as @d,@e:u@f, * where d, e, f are valid domain components. * the @d,@e: is ignored, since routes are ignored. * perhaps they should be rewritten as e!f!u@d, but that is inconsistent with upas. * * returns a pointer to '@', the end if none, or nil if there was an error */static char*headAddrSpec(char *e, char *w){ char *s, *at, *b, *bang, *dom; int c; s = e; for(;;){ if(w == nil){ w = headWord(); if(w == nil) return nil; } strcpy(e, w); free(w); w = nil; e = strchr(e, '\0'); lastWhite = headStr; c = headChar(0); if(c != '.') break; headChar(1); *e++ = '.'; *e = '\0'; } if(c != '@'){ /* * extenstion: allow name without domain * check for domain!xxx */ bang = domBang(s); if(bang == nil) return e; /* * if dom1!dom2!xxx, ignore dom1! */ dom = s; for(; b = domBang(bang + 1); bang = b) dom = bang + 1; /* * convert dom!mbox into mbox@dom */ *bang = '@'; strrev(dom, bang); strrev(bang+1, e); strrev(dom, e); bang = &dom[e - bang - 1]; if(dom > s){ bang -= dom - s; for(e = s; *e = *dom; e++) dom++; } /* * eliminate a trailing '.' */ if(e[-1] == '.') e[-1] = '\0'; return bang; } headChar(1); at = e; *e++ = '@'; *e = '\0'; if(!headDomain(e)) return nil; return at;}/* * find the ! in domain!rest, where domain must have at least * one internal '.' */static char*domBang(char *s){ int dot, c; dot = 0; for(; c = *s; s++){ if(c == '!'){ if(!dot || dot == 1 && s[-1] == '.' || s[1] == '\0') return nil; return s; } if(c == '"') break; if(c == '.') dot++; } return nil;}/* * domain : sub-domain * | domain '.' sub-domain * returns the end of the domain, or nil if a failure occured */static char*headDomain(char *e){ char *w; for(;;){ w = headSubDomain(); if(w == nil) return nil; strcpy(e, w); free(w); e = strchr(e, '\0'); lastWhite = headStr; if(headChar(0) != '.') break; headChar(1); *e++ = '.'; *e = '\0'; } return e;}/* * id : 'content-id' ':' msg-id * msg-id : '<' addr-spec '>' */static voidmimeId(Header *h){ char *s, *e, *w; if(headChar(1) != ':') return; if(headChar(1) != '<') return; s = emalloc(strlen((char*)headStr) + 3); e = s; *e++ = '<'; e = headAddrSpec(e, nil); if(e == nil || headChar(1) != '>'){ free(s); return; } e = strchr(e, '\0'); *e++ = '>'; e[0] = '\0'; w = strdup(s); free(s); h->id = mkMimeHdr(w, nil, nil);}/* * description : 'content-description' ':' *text */static voidmimeDescription(Header *h){ if(headChar(1) != ':') return; headSkipWhite(0); h->description = mkMimeHdr(headText(), nil, nil);}/* * disposition : 'content-disposition' ':' token params */static voidmimeDisposition(Header *h){ char *s; if(headChar(1) != ':') return; s = headAtom(mimeTokenStop); if(s == nil) return; h->disposition = mkMimeHdr(s, nil, mimeParams());}/* * md5 : 'content-md5' ':' token */static voidmimeMd5(Header *h){ char *s; if(headChar(1) != ':') return; s = headAtom(mimeTokenStop); if(s == nil) return; h->md5 = mkMimeHdr(s, nil, nil);}/* * language : 'content-language' ':' langs * langs : token * | langs commas token * commas : ',' * | commas ',' */static voidmimeLanguage(Header *h){ MimeHdr head, *last; char *s; head.next = nil; last = &head; for(;;){ s = headAtom(mimeTokenStop); if(s == nil) break; last->next = mkMimeHdr(s, nil, nil); last = last->next; while(headChar(0) != ',') headChar(1); } h->language = head.next;}/* * token : 1*<char 33-255, except "()<>@,;:\\\"/[]?=" aka mimeTokenStop> * atom : 1*<chars 33-255, except "()<>@,;:\\\".[]" aka headAtomStop> * note this allows 8 bit characters, which occur in utf. */static char*headAtom(char *disallowed){ char *s; int c, ns, as; headSkipWhite(0); s = emalloc(StrAlloc); as = StrAlloc; ns = 0; for(;;){ c = *headStr++; if(c <= ' ' || strchr(disallowed, c) != nil){ headStr--; break; } s[ns++] = c; if(ns >= as){ as += StrAlloc; s = erealloc(s, as); } } if(ns == 0){ free(s); return 0; } s[ns] = '\0'; return s;}/* * sub-domain : atom | domain-lit */static char *headSubDomain(void){ if(headChar(0) == '[') return headQuoted('[', ']'); return headAtom(headAtomStop);}/* * word : atom | quoted-str */static char *headWord(void){ if(headChar(0) == '"') return headQuoted('"', '"'); return headAtom(headAtomStop);}/* * q is a quoted string. remove enclosing " and and \ escapes */static voidstripQuotes(char *q){ char *s; int c; if(q == nil) return; s = q++; while(c = *q++){ if(c == '\\'){ c = *q++; if(!c) return; } *s++ = c; } s[-1] = '\0';}/* * quoted-str : '"' *(any char but '"\\\r', or '\' any char, or linear-white-space) '"' * domain-lit : '[' *(any char but '[]\\\r', or '\' any char, or linear-white-space) ']' */static char *headQuoted(int start, int stop){ char *s; int c, ns, as; if(headChar(1) != start) return nil; s = emalloc(StrAlloc); as = StrAlloc; ns = 0; s[ns++] = start; for(;;){ c = *headStr; if(c == stop){ headStr++; break; } if(c == '\0'){ free(s); return nil; } if(c == '\r'){ headStr++; continue; } if(c == '\n'){ headStr++; while(*headStr == ' ' || *headStr == '\t' || *headStr == '\r' || *headStr == '\n') headStr++; c = ' '; }else if(c == '\\'){ headStr++; s[ns++] = c; c = *headStr; if(c == '\0'){ free(s); return nil; } headStr++; }else headStr++; s[ns++] = c; if(ns + 1 >= as){ /* leave room for \c or "0 */ as += StrAlloc; s = erealloc(s, as); } } s[ns++] = stop; s[ns] = '\0'; return s;}/* * headText : contents of rest of header line */static char *headText(void){ uchar *v; char *s; v = headStr; headToEnd(); s = emalloc(headStr - v + 1); memmove(s, v, headStr - v); s[headStr - v] = '\0'; return s;}/* * white space is ' ' '\t' or nested comments. * skip white space. * if com and a comment is seen, * return it's contents and stop processing white space. */static char*headSkipWhite(int com){ char *s; int c, incom, as, ns; s = nil; as = StrAlloc; ns = 0; if(com) s = emalloc(StrAlloc); incom = 0; for(; c = *headStr; headStr++){ switch(c){ case ' ': case '\t': case '\r': c = ' '; break; case '\n': c = headStr[1]; if(c != ' ' && c != '\t') goto breakout; c = ' '; break; case '\\': if(com && incom) s[ns++] = c; c = headStr[1]; if(c == '\0') goto breakout; headStr++; break; case '(': incom++; if(incom == 1) continue; break; case ')': incom--; if(com && !incom){ s[ns] = '\0'; return s; } break; default: if(!incom) goto breakout; break; } if(com && incom && (c != ' ' || ns > 0 && s[ns-1] != ' ')){ s[ns++] = c; if(ns + 1 >= as){ /* leave room for \c or 0 */ as += StrAlloc; s = erealloc(s, as); } } }breakout:; free(s); return nil;}/* * return the next non-white character */static intheadChar(int eat){ int c; headSkipWhite(0); c = *headStr; if(eat && c != '\0' && c != '\n') headStr++; return c;}static voidheadToEnd(void){ uchar *s; int c; for(;;){ s = headStr; c = *s++; while(c == '\r') c = *s++; if(c == '\n'){ c = *s++; if(c != ' ' && c != '\t') return; } if(c == '\0') return; headStr = s; }}static voidheadSkip(void){ int c; while(c = *headStr){ headStr++; if(c == '\n'){ c = *headStr; if(c == ' ' || c == '\t') continue; return; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?