?? rfc822.c
字號:
* source driver flags */void rfc822_parse_msg_full (ENVELOPE **en,BODY **bdy,char *s,unsigned long i, STRING *bs,char *host,unsigned long depth, unsigned long flags){ char c,*t,*d; char *tmp = (char *) fs_get ((size_t) i + 100); ENVELOPE *env = (*en = mail_newenvelope ()); BODY *body = bdy ? (*bdy = mail_newbody ()) : NIL; long MIMEp = -1; /* flag that MIME semantics are in effect */ long PathP = NIL; /* flag that a Path: was seen */ parseline_t pl = (parseline_t) mail_parameters (NIL,GET_PARSELINE,NIL); while (i && *s != '\n') { /* until end of header */ t = tmp; /* initialize buffer pointer */ c = ' '; /* and previous character */ while (i && c) { /* collect text until logical end of line */ switch (c = *s++) { /* slurp a character */ case '\015': /* return, possible end of logical line */ if (*s == '\n') break; /* ignore if LF follows */ case '\012': /* LF, possible end of logical line */ /* tie off unless next line starts with WS */ if (*s != ' ' && *s != '\t') *t++ = c = '\0'; break; case '\t': /* tab */ *t++ = ' '; /* coerce to space */ break; default: /* all other characters */ *t++ = c; /* insert the character into the line */ break; } if (!--i) *t++ = '\0'; /* see if end of header */ } /* find header item type */ if (t = d = strchr (tmp,':')) { *d++ = '\0'; /* tie off header item, point at its data */ while (*d == ' ') d++; /* flush whitespace */ while ((tmp < t--) && (*t == ' ')) *t = '\0'; ucase (tmp); /* coerce to uppercase */ /* external callback */ if (pl) (*pl) (env,tmp,d,host); switch (*tmp) { /* dispatch based on first character */ case '>': /* possible >From: */ if (!strcmp (tmp+1,"FROM")) rfc822_parse_adrlist (&env->from,d,host); break; case 'B': /* possible bcc: */ if (!strcmp (tmp+1,"CC")) rfc822_parse_adrlist (&env->bcc,d,host); break; case 'C': /* possible cc: or Content-<mumble>*/ if (!strcmp (tmp+1,"C")) rfc822_parse_adrlist (&env->cc,d,host); else if ((tmp[1] == 'O') && (tmp[2] == 'N') && (tmp[3] == 'T') && (tmp[4] == 'E') && (tmp[5] == 'N') && (tmp[6] == 'T') && (tmp[7] == '-') && body) switch (MIMEp) { case -1: /* unknown if MIME or not */ if (MIMEp = search ((unsigned char *) s-1,i, (unsigned char *)"\012MIME-Version", (long) 13)) case T: /* definitely MIME */ rfc822_parse_content_header (body,tmp+8,d); } break; case 'D': /* possible Date: */ if (!env->date && !strcmp (tmp+1,"ATE")) env->date = cpystr (d); break; case 'F': /* possible From: */ if (!strcmp (tmp+1,"ROM")) rfc822_parse_adrlist (&env->from,d,host); else if (!strcmp (tmp+1,"OLLOWUP-TO")) { t = env->followup_to = (char *) fs_get (1 + strlen (d)); while (c = *d++) if (c != ' ') *t++ = c; *t++ = '\0'; } break; case 'I': /* possible In-Reply-To: */ if (!env->in_reply_to && !strcmp (tmp+1,"N-REPLY-TO")) env->in_reply_to = cpystr (d); break; case 'M': /* possible Message-ID: or MIME-Version: */ env->message_id = cpystr (d); else if (!strcmp (tmp+1,"IME-VERSION")) { /* tie off at end of phrase */ if (t = rfc822_parse_phrase (d)) *t = '\0'; rfc822_skipws (&d); /* skip whitespace */ /* known version? */ if (strcmp (d,"1.0") && strcmp (d,"RFC-XXXX")) mm_log ("Warning: message has unknown MIME version",PARSE); MIMEp = T; /* note that we are MIME */ } break; case 'N': /* possible Newsgroups: */ if (!env->newsgroups && !strcmp (tmp+1,"EWSGROUPS")) { t = env->newsgroups = (char *) fs_get (1 + strlen (d)); while (c = *d++) if (c != ' ') *t++ = c; *t++ = '\0'; } break; case 'P': /* possible Path: */ if (!strcmp (tmp+1,"ATH")) PathP = T; break; case 'R': /* possible Reply-To: */ if (!strcmp (tmp+1,"EPLY-TO")) rfc822_parse_adrlist (&env->reply_to,d,host); else if (!env->references && !strcmp (tmp+1,"EFERENCES")) env->references = cpystr (d); break; case 'S': /* possible Subject: or Sender: */ if (!env->subject && !strcmp (tmp+1,"UBJECT")) env->subject = cpystr (d); else if (!strcmp (tmp+1,"ENDER")) rfc822_parse_adrlist (&env->sender,d,host); break; case 'T': /* possible To: */ if (!strcmp (tmp+1,"O")) rfc822_parse_adrlist (&env->to,d,host); break; default: break; } } } /* We require a Path: header and/or a Message-ID belonging to a known * winning mail program, in order to believe Newsgroups:. This is because * of the unfortunate existance of certain cretins who believe that it * is reasonable to transmit messages via SMTP with a "Newsgroups" header * that were not actually posted to any of the named newsgroups. * The authors of other high-quality email/news software are encouraged to * use similar methods to indentify messages as coming from their software, * and having done so, to tell us so they too can be blessed in this list. * * May 1998 update: as was predicted back in March 1995 when this kludge was * first added, mail/news unifying programs are now the norm. However, the * encouragement in the previous paragraph didn't take, and there's no good * way to determine bogons accurately. Consequently, we no longer remove the * newsgroup information from the envelope on the bogon test; we just light * a bogon bit and let the main program worry about what to do. */ if (env->newsgroups && !PathP && env->message_id && strncmp (env->message_id,"<Pine.",6) && strncmp (env->message_id,"<MS-C.",6) && strncmp (env->message_id,"<MailManager.",13) && strncmp (env->message_id,"<EasyMail.",11) && strncmp (env->message_id,"<ML-",4)) env->ngbogus = T; fs_give ((void **) &tmp); /* done with scratch buffer */ /* default Sender: and Reply-To: to From: */ if (!env->sender) env->sender = rfc822_cpy_adr (env->from); if (!env->reply_to) env->reply_to = rfc822_cpy_adr (env->from); /* now parse the body */ if (body) rfc822_parse_content (body,bs,host,depth,flags);}/* Parse a message body content * Accepts: pointer to body structure * body string * pointer to local host name * recursion depth * source driver flags */void rfc822_parse_content (BODY *body,STRING *bs,char *h,unsigned long depth, unsigned long flags){ char c,c1,*s,*s1; int f; unsigned long i,j,k,m; PARAMETER *param; PART *part = NIL; if (depth > MAXMIMEDEPTH) { /* excessively deep recursion? */ body->type = TYPETEXT; /* yes, probably a malicious MIMEgram */ mm_log ("Ignoring excessively deep MIME recursion",PARSE); } if (!body->subtype) /* default subtype if still unknown */ body->subtype = cpystr (rfc822_default_subtype (body->type)); /* note offset and sizes */ body->contents.offset = GETPOS (bs); /* note internal body size in all cases */ body->size.bytes = body->contents.text.size = i = SIZE (bs); if (!(flags & DR_CRLF)) body->size.bytes = strcrlflen (bs); switch (body->type) { /* see if anything else special to do */ case TYPETEXT: /* text content */ if (!body->parameter) { /* default parameters */ body->parameter = mail_newbody_parameter (); body->parameter->attribute = cpystr ("CHARSET"); body->parameter->value = cpystr ("US-ASCII"); } /* count number of lines */ while (i--) if ((SNX (bs)) == '\n') body->size.lines++; break; case TYPEMESSAGE: /* encapsulated message */ body->nested.msg = mail_newmsg (); /* encapsulated RFC-822 message? */ if (!strcmp (body->subtype,"RFC822")) { switch (body->encoding) { /* make sure valid encoding */ case ENC7BIT: /* these are valid nested encodings */ case ENC8BIT: case ENCBINARY: break; default: mm_log ("Ignoring nested encoding of message contents",PARSE); } /* hunt for blank line */ for (c = '\012',j = 0; (i > j) && ((c != '\012') || (CHR(bs) != '\012')); j++) if ((c1 = SNX (bs)) != '\015') c = c1; if (i > j) { /* unless no more text */ c1 = SNX (bs); /* body starts here */ j++; /* advance count */ } /* note body text offset and header size */ body->nested.msg->header.text.size = j; body->nested.msg->text.text.size = body->contents.text.size - j; body->nested.msg->text.offset = GETPOS (bs); body->nested.msg->full.offset = body->nested.msg->header.offset = body->contents.offset; body->nested.msg->full.text.size = body->contents.text.size; /* copy header string */ SETPOS (bs,body->contents.offset); s = (char *) fs_get ((size_t) j + 1); for (s1 = s,k = j; k--; *s1++ = SNX (bs)); s[j] = '\0'; /* tie off string (not really necessary) */ /* now parse the body */ rfc822_parse_msg_full (&body->nested.msg->env,&body->nested.msg->body,s, j,bs,h,depth+1,flags); fs_give ((void **) &s); /* free header string */ /* restore position */ SETPOS (bs,body->contents.offset); } /* count number of lines */ while (i--) if (SNX (bs) == '\n') body->size.lines++; break; case TYPEMULTIPART: /* multiple parts */ switch (body->encoding) { /* make sure valid encoding */ case ENC7BIT: /* these are valid nested encodings */ case ENC8BIT: case ENCBINARY: break; default: mm_log ("Ignoring nested encoding of multipart contents",PARSE); } /* remember if digest */ f = !strcmp (body->subtype,"DIGEST"); /* find cookie */ for (s1 = NIL,param = body->parameter; param && !s1; param = param->next) if (!strcmp (param->attribute,"BOUNDARY")) s1 = param->value; if (!(s1 && *s1)) s1 = "-"; /* yucky default */ j = strlen (s1); /* length of cookie and header */ c = '\012'; /* initially at beginning of line */ while (i > j) { /* examine data */ if (m = GETPOS (bs)) m--; /* get position in front of character */ switch (c) { /* examine each line */ 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-- && ((c = SNX (bs)) == '-') && i-- && ((c = SNX (bs)) == '-')) { /* see if cookie matches */ for (k = j,s = s1; i-- && *s++ == (c = SNX (bs)) && --k;); if (k) break; /* strings didn't match if non-zero */ /* look at what follows cookie */ if (i && i--) switch (c = SNX (bs)) { case '-': /* at end if two dashes */ 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; 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)); /* parse non-empty body parts */ for (part = body->nested.part; part; part = part->next) { 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) 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);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -