return 1;
}
-static int handle_from(char *line)
+static int handle_from(char *in_line)
{
- char *at = strchr(line, '@');
+ char line[1000];
+ char *at;
char *dst;
+ strcpy(line, in_line);
+ at = strchr(line, '@');
if (!at)
return bogus_from(line);
#define SEEN_FROM 01
#define SEEN_DATE 02
#define SEEN_SUBJECT 04
-#define SEEN_PREFIX 0x08
+#define SEEN_BOGUS_UNIX_FROM 010
+#define SEEN_PREFIX 020
/* First lines of body can have From:, Date:, and Subject: */
static void handle_inbody_header(int *seen, char *line)
{
- if (*seen & SEEN_PREFIX)
- return;
+ if (!memcmp(">From", line, 5) && isspace(line[5])) {
+ if (!(*seen & SEEN_BOGUS_UNIX_FROM)) {
+ *seen |= SEEN_BOGUS_UNIX_FROM;
+ return;
+ }
+ }
if (!memcmp("From:", line, 5) && isspace(line[5])) {
if (!(*seen & SEEN_FROM) && handle_from(line+6)) {
*seen |= SEEN_FROM;
check_header(line, header);
}
+static int is_rfc2822_header(char *line)
+{
+ /*
+ * The section that defines the loosest possible
+ * field name is "3.6.8 Optional fields".
+ *
+ * optional-field = field-name ":" unstructured CRLF
+ * field-name = 1*ftext
+ * ftext = %d33-57 / %59-126
+ */
+ int ch;
+ char *cp = line;
+ while ((ch = *cp++)) {
+ if (ch == ':')
+ return cp != line;
+ if ((33 <= ch && ch <= 57) ||
+ (59 <= ch && ch <= 126))
+ continue;
+ break;
+ }
+ return 0;
+}
+
static int read_one_header_line(char *line, int sz, FILE *in)
{
int ofs = 0;
while (ofs < sz) {
int peek, len;
if (fgets(line + ofs, sz - ofs, in) == NULL)
- return ofs;
+ break;
len = eatspace(line + ofs);
if (len == 0)
- return ofs;
- peek = fgetc(in); ungetc(peek, in);
- if (peek == ' ' || peek == '\t') {
- /* Yuck, 2822 header "folding" */
- ofs += len;
- continue;
+ break;
+ if (!is_rfc2822_header(line)) {
+ /* Re-add the newline */
+ line[ofs + len] = '\n';
+ line[ofs + len + 1] = '\0';
+ break;
}
- return ofs + len;
+ ofs += len;
+ /* Yuck, 2822 header "folding" */
+ peek = fgetc(in); ungetc(peek, in);
+ if (peek != ' ' && peek != '\t')
+ break;
}
+ /* Count mbox From headers as headers */
+ if (!ofs && !memcmp(line, "From ", 5))
+ ofs = 1;
return ofs;
}