📄 parse.c
字号:
/* RFC 2369. FIXME: We should ignore whitespace, but don't. */ if (strncmp (p, "NO", 2)) { char *beg, *end; for (beg = strchr (p, '<'); beg; beg = strchr (end, ',')) { ++beg; if (!(end = strchr (beg, '>'))) break; /* Take the first mailto URL */ if (url_check_scheme (beg) == U_MAILTO) { FREE (&e->list_post); e->list_post = mutt_substrdup (beg, end); break; } } } matched = 1; } break; case 'm': if (!ascii_strcasecmp (line + 1, "ime-version")) { if (hdr) hdr->mime = 1; matched = 1; } else if (!ascii_strcasecmp (line + 1, "essage-id")) { /* We add a new "Message-ID:" when building a message */ FREE (&e->message_id); e->message_id = extract_message_id (p); matched = 1; } else if (!ascii_strncasecmp (line + 1, "ail-", 4)) { if (!ascii_strcasecmp (line + 5, "reply-to")) { /* override the Reply-To: field */ rfc822_free_address (&e->reply_to); e->reply_to = rfc822_parse_adrlist (e->reply_to, p); matched = 1; } else if (!ascii_strcasecmp (line + 5, "followup-to")) { e->mail_followup_to = rfc822_parse_adrlist (e->mail_followup_to, p); matched = 1; } } break; case 'r': if (!ascii_strcasecmp (line + 1, "eferences")) { mutt_free_list (&e->references); e->references = mutt_parse_references (p, 0); matched = 1; } else if (!ascii_strcasecmp (line + 1, "eply-to")) { e->reply_to = rfc822_parse_adrlist (e->reply_to, p); matched = 1; } else if (!ascii_strcasecmp (line + 1, "eturn-path")) { e->return_path = rfc822_parse_adrlist (e->return_path, p); matched = 1; } else if (!ascii_strcasecmp (line + 1, "eceived")) { if (hdr && !hdr->received) { char *d = strchr (p, ';'); if (d) hdr->received = mutt_parse_date (d + 1, NULL); } } break; case 's': if (!ascii_strcasecmp (line + 1, "ubject")) { if (!e->subject) e->subject = safe_strdup (p); matched = 1; } else if (!ascii_strcasecmp (line + 1, "ender")) { e->sender = rfc822_parse_adrlist (e->sender, p); matched = 1; } else if (!ascii_strcasecmp (line + 1, "tatus")) { if (hdr) { while (*p) { switch(*p) { case 'r': hdr->replied = 1; break; case 'O': hdr->old = 1; break; case 'R': hdr->read = 1; break; } p++; } } matched = 1; } else if ((!ascii_strcasecmp ("upersedes", line + 1) || !ascii_strcasecmp ("upercedes", line + 1)) && hdr) e->supersedes = safe_strdup (p); break; case 't': if (ascii_strcasecmp (line+1, "o") == 0) { e->to = rfc822_parse_adrlist (e->to, p); matched = 1; } break; case 'x': if (ascii_strcasecmp (line+1, "-status") == 0) { if (hdr) { while (*p) { switch (*p) { case 'A': hdr->replied = 1; break; case 'D': hdr->deleted = 1; break; case 'F': hdr->flagged = 1; break; default: break; } p++; } } matched = 1; } else if (ascii_strcasecmp (line+1, "-label") == 0) { e->x_label = safe_strdup(p); matched = 1; } default: break; } /* Keep track of the user-defined headers */ if (!matched && user_hdrs) { /* restore the original line */ line[strlen (line)] = ':'; if (weed && option (OPTWEED) && mutt_matches_ignore (line, Ignore) && !mutt_matches_ignore (line, UnIgnore)) goto done; if (last) { last->next = mutt_new_list (); last = last->next; } else last = e->userhdrs = mutt_new_list (); last->data = safe_strdup (line); if (do_2047) rfc2047_decode (&last->data); } done: *lastp = last; return matched;} /* mutt_read_rfc822_header() -- parses a RFC822 header * * Args: * * f stream to read from * * hdr header structure of current message (optional). * * user_hdrs If set, store user headers. Used for recall-message and * postpone modes. * * weed If this parameter is set and the user has activated the * $weed option, honor the header weed list for user headers. * Used for recall-message. * * Returns: newly allocated envelope structure. You should free it by * mutt_free_envelope() when envelope stay unneeded. */ENVELOPE *mutt_read_rfc822_header (FILE *f, HEADER *hdr, short user_hdrs, short weed){ ENVELOPE *e = mutt_new_envelope(); LIST *last = NULL; char *line = safe_malloc (LONG_STRING); char *p; LOFF_T loc; int matched; size_t linelen = LONG_STRING; char buf[LONG_STRING+1]; if (hdr) { if (hdr->content == NULL) { hdr->content = mutt_new_body (); /* set the defaults from RFC1521 */ hdr->content->type = TYPETEXT; hdr->content->subtype = safe_strdup ("plain"); hdr->content->encoding = ENC7BIT; hdr->content->length = -1; /* RFC 2183 says this is arbitrary */ hdr->content->disposition = DISPINLINE; } } while ((loc = ftello (f)), *(line = mutt_read_rfc822_line (f, line, &linelen)) != 0) { matched = 0; if ((p = strpbrk (line, ": \t")) == NULL || *p != ':') { char return_path[LONG_STRING]; time_t t; /* some bogus MTAs will quote the original "From " line */ if (mutt_strncmp (">From ", line, 6) == 0) continue; /* just ignore */ else if (is_from (line, return_path, sizeof (return_path), &t)) { /* MH somtimes has the From_ line in the middle of the header! */ if (hdr && !hdr->received) hdr->received = t - mutt_local_tz (t); continue; } fseeko (f, loc, 0); break; /* end of header */ } *buf = '\0'; if (mutt_match_spam_list(line, SpamList, buf, sizeof(buf))) { if (!mutt_match_rx_list(line, NoSpamList)) { /* if spam tag already exists, figure out how to amend it */ if (e->spam && *buf) { /* If SpamSep defined, append with separator */ if (SpamSep) { mutt_buffer_addstr(e->spam, SpamSep); mutt_buffer_addstr(e->spam, buf); } /* else overwrite */ else { e->spam->dptr = e->spam->data; *e->spam->dptr = '\0'; mutt_buffer_addstr(e->spam, buf); } } /* spam tag is new, and match expr is non-empty; copy */ else if (!e->spam && *buf) { e->spam = mutt_buffer_from(NULL, buf); } /* match expr is empty; plug in null string if no existing tag */ else if (!e->spam) { e->spam = mutt_buffer_from(NULL, ""); } if (e->spam && e->spam->data) dprint(5, (debugfile, "p822: spam = %s\n", e->spam->data)); } } *p = 0; p++; SKIPWS (p); if (!*p) continue; /* skip empty header fields */ matched = mutt_parse_rfc822_line (e, hdr, line, p, user_hdrs, weed, 1, &last); } FREE (&line); if (hdr) { hdr->content->hdr_offset = hdr->offset; hdr->content->offset = ftello (f); /* do RFC2047 decoding */ rfc2047_decode_adrlist (e->from); rfc2047_decode_adrlist (e->to); rfc2047_decode_adrlist (e->cc); rfc2047_decode_adrlist (e->bcc); rfc2047_decode_adrlist (e->reply_to); rfc2047_decode_adrlist (e->mail_followup_to); rfc2047_decode_adrlist (e->return_path); rfc2047_decode_adrlist (e->sender); if (e->subject) { regmatch_t pmatch[1]; rfc2047_decode (&e->subject); if (regexec (ReplyRegexp.rx, e->subject, 1, pmatch, 0) == 0) e->real_subj = e->subject + pmatch[0].rm_eo; else e->real_subj = e->subject; } /* check for missing or invalid date */ if (hdr->date_sent <= 0) { dprint(1,(debugfile,"read_rfc822_header(): no date found, using received time from msg separator\n")); hdr->date_sent = hdr->received; } } return (e);}ADDRESS *mutt_parse_adrlist (ADDRESS *p, const char *s){ const char *q; /* check for a simple whitespace separated list of addresses */ if ((q = strpbrk (s, "\"<>():;,\\")) == NULL) { char tmp[HUGE_STRING]; char *r; strfcpy (tmp, s, sizeof (tmp)); r = tmp; while ((r = strtok (r, " \t")) != NULL) { p = rfc822_parse_adrlist (p, r); r = NULL; } } else p = rfc822_parse_adrlist (p, s); return p;}/* Compares mime types to the ok and except lists */int count_body_parts_check(LIST **checklist, BODY *b, int dflt){ LIST *type; ATTACH_MATCH *a; /* If list is null, use default behavior. */ if (! *checklist) { /*return dflt;*/ return 0; } for (type = *checklist; type; type = type->next) { a = (ATTACH_MATCH *)type->data; dprint(5, (debugfile, "cbpc: %s %d/%s ?? %s/%s [%d]... ", dflt ? "[OK] " : "[EXCL] ", b->type, b->subtype, a->major, a->minor, a->major_int)); if ((a->major_int == TYPEANY || a->major_int == b->type) && !regexec(&a->minor_rx, b->subtype, 0, NULL, 0)) { dprint(5, (debugfile, "yes\n")); return 1; } else { dprint(5, (debugfile, "no\n")); } } return 0;}#define AT_COUNT(why) { shallcount = 1; }#define AT_NOCOUNT(why) { shallcount = 0; }int count_body_parts (BODY *body, int flags){ int count = 0; int shallcount, shallrecurse; BODY *bp; if (body == NULL) return 0; for (bp = body; bp != NULL; bp = bp->next) { /* Initial disposition is to count and not to recurse this part. */ AT_COUNT("default"); shallrecurse = 0; dprint(5, (debugfile, "bp: desc=\"%s\"; fn=\"%s\", type=\"%d/%s\"\n", bp->description ? bp->description : ("none"), bp->filename ? bp->filename : bp->d_filename ? bp->d_filename : "(none)", bp->type, bp->subtype ? bp->subtype : "*")); if (bp->type == TYPEMESSAGE) { shallrecurse = 1; /* If it's an external body pointer, don't recurse it. */ if (!ascii_strcasecmp (bp->subtype, "external-body")) shallrecurse = 0; /* Don't count containers if they're top-level. */ if (flags & M_PARTS_TOPLEVEL) AT_NOCOUNT("top-level message/*"); } else if (bp->type == TYPEMULTIPART) { /* Always recurse multiparts, except multipart/alternative. */ shallrecurse = 1; if (!ascii_strcasecmp(bp->subtype, "alternative")) shallrecurse = 0; /* Don't count containers if they're top-level. */ if (flags & M_PARTS_TOPLEVEL) AT_NOCOUNT("top-level multipart"); } if (bp->disposition == DISPINLINE && bp->type != TYPEMULTIPART && bp->type != TYPEMESSAGE && bp == body) AT_NOCOUNT("ignore fundamental inlines"); /* If this body isn't scheduled for enumeration already, don't bother * profiling it further. */ if (shallcount) { /* Turn off shallcount if message type is not in ok list, * or if it is in except list. Check is done separately for * inlines vs. attachments. */ if (bp->disposition == DISPATTACH) { if (!count_body_parts_check(&AttachAllow, bp, 1)) AT_NOCOUNT("attach not allowed"); if (count_body_parts_check(&AttachExclude, bp, 0)) AT_NOCOUNT("attach excluded"); } else { if (!count_body_parts_check(&InlineAllow, bp, 1)) AT_NOCOUNT("inline not allowed"); if (count_body_parts_check(&InlineExclude, bp, 0)) AT_NOCOUNT("excluded"); } } if (shallcount) count++; bp->attach_qualifies = shallcount ? 1 : 0; dprint(5, (debugfile, "cbp: %08x shallcount = %d\n", (unsigned int)bp, shallcount)); if (shallrecurse) { dprint(5, (debugfile, "cbp: %08x pre count = %d\n", (unsigned int)bp, count)); bp->attach_count = count_body_parts(bp->parts, flags & ~M_PARTS_TOPLEVEL); count += bp->attach_count; dprint(5, (debugfile, "cbp: %08x post count = %d\n", (unsigned int)bp, count)); } } dprint(5, (debugfile, "bp: return %d\n", count < 0 ? 0 : count)); return count < 0 ? 0 : count;}int mutt_count_body_parts (CONTEXT *ctx, HEADER *hdr){ short keep_parts = 0; if (hdr->attach_valid) return hdr->attach_total; if (hdr->content->parts) keep_parts = 1; else mutt_parse_mime_message (ctx, hdr); if (AttachAllow || AttachExclude || InlineAllow || InlineExclude) hdr->attach_total = count_body_parts(hdr->content, M_PARTS_TOPLEVEL); else hdr->attach_total = 0; hdr->attach_valid = 1; if (!keep_parts) mutt_free_body (&hdr->content->parts); return hdr->attach_total;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -