int main (int argc, char **argv) { char line[5000]; size_t length; rfc822parse_t msg; msg = rfc822parse_open (msg_cb, NULL); if (!msg) abort (); while (fgets (line, sizeof (line), stdin)) { length = strlen (line); if (length && line[length - 1] == '\n') line[--length] = 0; if (length && line[length - 1] == '\r') line[--length] = 0; if (rfc822parse_insert (msg, line, length)) abort (); } dump_structure (msg, NULL, 0); rfc822parse_close (msg); return 0; }
/* Read a message from FP and process it according to the global options. */ static void parse_message (FILE *fp) { char line[2000]; unsigned char buffer[1000]; size_t buflen = 0; size_t length; rfc822parse_t msg; unsigned int lineno = 0; int no_cr_reported = 0; struct parse_info_s info; int body_lines = 0; int skip_leading_empty_lines = 0; restart: memset (&info, 0, sizeof info); msg = rfc822parse_open (message_cb, &info); if (!msg) die ("can't open parser: %s", strerror (errno)); /* Fixme: We should not use fgets because it can't cope with embedded nul characters. */ while (fgets (line, sizeof (line), fp)) { lineno++; if (lineno == 1 && !strncmp (line, "From ", 5)) continue; /* We better ignore a leading From line. */ length = strlen (line); if (length && line[length - 1] == '\n') line[--length] = 0; else if (verbose) err ("line number %u too long or last line not terminated", lineno); if (length && line[length - 1] == '\r') line[--length] = 0; else if (verbose && !no_cr_reported) { err ("non canonical ended line detected (line %u)", lineno); no_cr_reported = 1; } if (skip_leading_empty_lines) { if (skip_leading_empty_lines == 1) { /* Sometimes additional information follows the indication line indicated by 6 dashes. Skip them before detecting empty lines. */ if (length && !strncmp (line , "------ ", 7)) continue; skip_leading_empty_lines++; } if (!length) continue; skip_leading_empty_lines = 0; } if (rfc822parse_insert (msg, line, length)) die ("parser failed: %s", strerror (errno)); if (info.no_mime && body_lines < 50) { body_lines++; if (!strncmp (line, "------ This is a copy of the message, " "including all the headers.", 64)) { /* This may be followed by empty lines, thus we set a flag to skip them. */ skip_leading_empty_lines = 1; body_lines = 500; /* Avoid going here a second time. */ rfc822parse_close (msg); goto restart; } } if (info.got_probe && buflen) { info.got_probe = 0; buffer[buflen] = 0; buflen = decode_base64 (buffer); if (debug) { int i; printf ("# %4d bytes base64:", (int)buflen); for (i=0; i < buflen; i++) { if (i && !(i % 16)) printf ("\n# 0x%04X:", i); printf (" %02X", buffer[i]); } putchar ('\n'); } identify_binary (buffer, buflen); } if (info.test_base64) { if (info.test_base64 == 1) { /* This is the empty marker line. */ buflen = 0; } else { if (length > sizeof buffer - 1 - buflen) { length = sizeof buffer - 1 - buflen; info.got_probe = 1; /* We got enough. */ } if (length) { memcpy (buffer+buflen, line, length); buflen += length; } } if (info.got_probe) info.test_base64 = 0; else info.test_base64++; } } rfc822parse_close (msg); }