Commit a122673f authored by Richard Curnow's avatar Richard Curnow

Display message path in warning messages from rfc822 parsing.

Original rev  : rc@rc0.org.uk--2004-mairix/mairix--dev--0.16--patch-28
parent 49ccc8fd
...@@ -22,6 +22,7 @@ NEW IN VERSION 0.16 ...@@ -22,6 +22,7 @@ NEW IN VERSION 0.16
wanted folder with the matches. wanted folder with the matches.
* Implement dot-locking on the database file to prevent corruption due to * Implement dot-locking on the database file to prevent corruption due to
concurrent updates. Add --unlock file to forcibly remove a stray lockfile. concurrent updates. Add --unlock file to forcibly remove a stray lockfile.
* Display message path in warning messages from rfc822 parsing.
NEW IN VERSION 0.15 NEW IN VERSION 0.15
=================== ===================
......
...@@ -685,7 +685,7 @@ static void scan_new_messages(struct database *db, int start_at)/*{{{*/ ...@@ -685,7 +685,7 @@ static void scan_new_messages(struct database *db, int start_at)/*{{{*/
free_rfc822(msg); free_rfc822(msg);
} }
else else
fprintf(stderr, "Skipping...\n"); fprintf(stderr, "Skipping %s (could not parse message)\n", db->msgs[i].src.mpf.path);
} }
} }
/*}}}*/ /*}}}*/
......
...@@ -233,6 +233,13 @@ struct string_list {/*{{{*/ ...@@ -233,6 +233,13 @@ struct string_list {/*{{{*/
}; };
/*}}}*/ /*}}}*/
struct msg_src {
enum {MS_FILE, MS_MBOX} type;
char *filename;
off_t start;
size_t len;
};
extern int verbose; /* cmd line -v switch */ extern int verbose; /* cmd line -v switch */
/* Lame fix for systems where NAME_MAX isn't defined after including the above /* Lame fix for systems where NAME_MAX isn't defined after including the above
...@@ -271,7 +278,7 @@ int filter_is_mh(const char *path, struct stat *sb); ...@@ -271,7 +278,7 @@ int filter_is_mh(const char *path, struct stat *sb);
/* In rfc822.c */ /* In rfc822.c */
struct rfc822 *make_rfc822(char *filename); struct rfc822 *make_rfc822(char *filename);
void free_rfc822(struct rfc822 *msg); void free_rfc822(struct rfc822 *msg);
struct rfc822 *data_to_rfc822(char *data, int length); struct rfc822 *data_to_rfc822(struct msg_src *src, char *data, int length);
void create_ro_mapping(const char *filename, unsigned char **data, int *len); void create_ro_mapping(const char *filename, unsigned char **data, int *len);
/* In tok.c */ /* In tok.c */
......
...@@ -837,6 +837,16 @@ void build_mbox_lists(struct database *db, const char *folder_base, /*{{{*/ ...@@ -837,6 +837,16 @@ void build_mbox_lists(struct database *db, const char *folder_base, /*{{{*/
} }
/*}}}*/ /*}}}*/
static struct msg_src *setup_msg_src(char *filename, off_t start, size_t len)/*{{{*/
{
static struct msg_src result;
result.type = MS_MBOX;
result.filename = filename;
result.start = start;
result.len = len;
return &result;
}
/*}}}*/
int add_mbox_messages(struct database *db)/*{{{*/ int add_mbox_messages(struct database *db)/*{{{*/
{ {
int i, j; int i, j;
...@@ -852,6 +862,7 @@ int add_mbox_messages(struct database *db)/*{{{*/ ...@@ -852,6 +862,7 @@ int add_mbox_messages(struct database *db)/*{{{*/
off_t start; off_t start;
size_t len; size_t len;
struct rfc822 *r8; struct rfc822 *r8;
struct msg_src *msg_src;
maybe_grow_message_arrays(db); maybe_grow_message_arrays(db);
n = db->n_msgs; n = db->n_msgs;
db->type[n] = MTY_MBOX; db->type[n] = MTY_MBOX;
...@@ -868,7 +879,8 @@ int add_mbox_messages(struct database *db)/*{{{*/ ...@@ -868,7 +879,8 @@ int add_mbox_messages(struct database *db)/*{{{*/
start = mb->start[j]; start = mb->start[j];
len = mb->len[j]; len = mb->len[j];
r8 = data_to_rfc822(va + start, len); msg_src = setup_msg_src(mb->path, start, len);
r8 = data_to_rfc822(msg_src, va + start, len);
if (r8) { if (r8) {
if (verbose) { if (verbose) {
printf("Scanning %s[%d] at [%d,%d)\n", mb->path, j, (int)start, (int)(start + len)); printf("Scanning %s[%d] at [%d,%d)\n", mb->path, j, (int)start, (int)(start + len));
......
...@@ -576,7 +576,36 @@ static char *unencode_data(char *input, int input_len, char *enc, int *output_le ...@@ -576,7 +576,36 @@ static char *unencode_data(char *input, int input_len, char *enc, int *output_le
return result; return result;
} }
/*}}}*/ /*}}}*/
static int split_and_splice_header(char *data, struct line *header, char **body_start)/*{{{*/ static char *format_msg_src(struct msg_src *src)/*{{{*/
{
static char *buffer = NULL;
static int buffer_len = 0;
char *result;
int len;
switch (src->type) {
case MS_FILE:
result = src->filename;
break;
case MS_MBOX:
len = strlen(src->filename);
len += 32;
if (!buffer || (len > buffer_len)) {
free(buffer);
buffer = new_array(char, len);
buffer_len = len;
}
sprintf(buffer, "%s[%d,%d)", src->filename,
(int) src->start, (int) (src->start + src->len));
result = buffer;
break;
default:
result = NULL;
break;
}
return result;
}
/*}}}*/
static int split_and_splice_header(struct msg_src *src, char *data, struct line *header, char **body_start)/*{{{*/
{ {
char *sol, *eol; char *sol, *eol;
int blank_line; int blank_line;
...@@ -604,7 +633,8 @@ static int split_and_splice_header(char *data, struct line *header, char **body_ ...@@ -604,7 +633,8 @@ static int split_and_splice_header(char *data, struct line *header, char **body_
} }
sol = eol + 1; /* Start of next line */ sol = eol + 1; /* Start of next line */
} else { /* must be null char */ } else { /* must be null char */
fprintf(stderr, "Got null character whilst processing header\n"); fprintf(stderr, "Got null character whilst processing header of %s\n",
format_msg_src(src));
return -1; /* & leak memory */ return -1; /* & leak memory */
} }
} while (!blank_line); } while (!blank_line);
...@@ -625,9 +655,9 @@ static int split_and_splice_header(char *data, struct line *header, char **body_ ...@@ -625,9 +655,9 @@ static int split_and_splice_header(char *data, struct line *header, char **body_
/*}}}*/ /*}}}*/
/* Forward prototypes */ /* Forward prototypes */
static void do_multipart(char *input, int input_len, char *boundary, struct attachment *atts); static void do_multipart(struct msg_src *src, char *input, int input_len, char *boundary, struct attachment *atts);
static void do_body(char *body_start, int body_len, char *content_type, char *content_transfer_encoding, struct attachment *atts)/*{{{*/ static void do_body(struct msg_src *src, char *body_start, int body_len, char *content_type, char *content_transfer_encoding, struct attachment *atts)/*{{{*/
{ {
char *decoded_body; char *decoded_body;
int decoded_body_len; int decoded_body_len;
...@@ -638,7 +668,7 @@ static void do_body(char *body_start, int body_len, char *content_type, char *co ...@@ -638,7 +668,7 @@ static void do_body(char *body_start, int body_len, char *content_type, char *co
struct content_type_header ct; struct content_type_header ct;
parse_content_type(content_type, &ct); parse_content_type(content_type, &ct);
if (!strcasecmp(ct.major, "multipart")) { if (!strcasecmp(ct.major, "multipart")) {
do_multipart(decoded_body, decoded_body_len, ct.boundary, atts); do_multipart(src, decoded_body, decoded_body_len, ct.boundary, atts);
/* Don't need decoded body any longer - copies have been taken if /* Don't need decoded body any longer - copies have been taken if
* required when handling multipart attachments. */ * required when handling multipart attachments. */
...@@ -663,7 +693,7 @@ static void do_body(char *body_start, int body_len, char *content_type, char *co ...@@ -663,7 +693,7 @@ static void do_body(char *body_start, int body_len, char *content_type, char *co
} }
if (new_att->ct == CT_MESSAGE_RFC822) { if (new_att->ct == CT_MESSAGE_RFC822) {
new_att->data.rfc822 = data_to_rfc822(decoded_body, decoded_body_len); new_att->data.rfc822 = data_to_rfc822(src, decoded_body, decoded_body_len);
free(decoded_body); /* data no longer needed */ free(decoded_body); /* data no longer needed */
} else { } else {
new_att->data.normal.len = decoded_body_len; new_att->data.normal.len = decoded_body_len;
...@@ -688,15 +718,16 @@ static void do_body(char *body_start, int body_len, char *content_type, char *co ...@@ -688,15 +718,16 @@ static void do_body(char *body_start, int body_len, char *content_type, char *co
} }
} }
/*}}}*/ /*}}}*/
static void do_attachment(char *start, char *after_end, struct attachment *atts)/*{{{*/ static void do_attachment(struct msg_src *src, char *start, char *after_end, struct attachment *atts)/*{{{*/
{ {
/* decode attachment and add to attachment list */ /* decode attachment and add to attachment list */
struct line header, *x, *nx; struct line header, *x, *nx;
char *body_start; char *body_start;
int body_len; int body_len;
char *content_type, *content_transfer_encoding; char *content_type, *content_transfer_encoding;
if (split_and_splice_header(start, &header, &body_start) < 0) { if (split_and_splice_header(src, start, &header, &body_start) < 0) {
fprintf(stderr, "Giving up on attachment with bad header\n"); fprintf(stderr, "Giving up on attachment with bad header in %s\n",
format_msg_src(src));
return; return;
} }
...@@ -711,11 +742,12 @@ static void do_attachment(char *start, char *after_end, struct attachment *atts) ...@@ -711,11 +742,12 @@ static void do_attachment(char *start, char *after_end, struct attachment *atts)
if (body_start > after_end) { if (body_start > after_end) {
/* This is a (maliciously?) b0rken attachment, e.g. maybe empty */ /* This is a (maliciously?) b0rken attachment, e.g. maybe empty */
if (verbose) { if (verbose) {
fprintf(stderr, "This message contains an invalid attachment, length=%d bytes\n", (int)(after_end - start)); fprintf(stderr, "Message %s contains an invalid attachment, length=%d bytes\n",
format_msg_src(src), (int)(after_end - start));
} }
} else { } else {
body_len = after_end - body_start; body_len = after_end - body_start;
do_body(body_start, body_len, content_type, content_transfer_encoding, atts); do_body(src, body_start, body_len, content_type, content_transfer_encoding, atts);
} }
/* Free header memory */ /* Free header memory */
...@@ -729,7 +761,7 @@ static void do_attachment(char *start, char *after_end, struct attachment *atts) ...@@ -729,7 +761,7 @@ static void do_attachment(char *start, char *after_end, struct attachment *atts)
if (content_transfer_encoding) free(content_transfer_encoding); if (content_transfer_encoding) free(content_transfer_encoding);
} }
/*}}}*/ /*}}}*/
static void do_multipart(char *input, int input_len, char *boundary, struct attachment *atts)/*{{{*/ static void do_multipart(struct msg_src *src, char *input, int input_len, char *boundary, struct attachment *atts)/*{{{*/
{ {
char *normal_boundary, *end_boundary; char *normal_boundary, *end_boundary;
char *b0, *b1, *be; char *b0, *b1, *be;
...@@ -738,7 +770,8 @@ static void do_multipart(char *input, int input_len, char *boundary, struct atta ...@@ -738,7 +770,8 @@ static void do_multipart(char *input, int input_len, char *boundary, struct atta
int looking_at_end_boundary; int looking_at_end_boundary;
if (!boundary) { if (!boundary) {
fprintf(stderr, "Can't process multipart message with no boundary string!\n"); fprintf(stderr, "Can't process multipart message %s with no boundary string\n",
format_msg_src(src));
return; return;
} }
...@@ -757,7 +790,8 @@ static void do_multipart(char *input, int input_len, char *boundary, struct atta ...@@ -757,7 +790,8 @@ static void do_multipart(char *input, int input_len, char *boundary, struct atta
/* Scan input to look for boundary markers */ /* Scan input to look for boundary markers */
be = strstr(input, end_boundary); be = strstr(input, end_boundary);
if (!be) { if (!be) {
fprintf(stderr, "Can't find end boundary in multipart message!\n"); fprintf(stderr, "Can't find end boundary in multipart message %s\n",
format_msg_src(src));
be = strchr(input, 0); /* tolerate missing end boundary */ be = strchr(input, 0); /* tolerate missing end boundary */
} }
...@@ -772,7 +806,8 @@ static void do_multipart(char *input, int input_len, char *boundary, struct atta ...@@ -772,7 +806,8 @@ static void do_multipart(char *input, int input_len, char *boundary, struct atta
if (!b1) { if (!b1) {
if (*be) { if (*be) {
fprintf(stderr, "Oops, didn't find another normal boundary?\n"); fprintf(stderr, "Oops, didn't find another normal boundary in %s\n",
format_msg_src(src));
goto cleanup; goto cleanup;
} else { } else {
b1 = be; /* tolerate missing end boundary */ b1 = be; /* tolerate missing end boundary */
...@@ -791,7 +826,7 @@ static void do_multipart(char *input, int input_len, char *boundary, struct atta ...@@ -791,7 +826,7 @@ static void do_multipart(char *input, int input_len, char *boundary, struct atta
if (b0) { if (b0) {
/* don't treat preamble as an attachment */ /* don't treat preamble as an attachment */
do_attachment(line_after_b0, b1, atts); do_attachment(src, line_after_b0, b1, atts);
} }
b0 = b1; b0 = b1;
...@@ -866,7 +901,7 @@ tough_cheese: ...@@ -866,7 +901,7 @@ tough_cheese:
return (time_t) -1; /* default value */ return (time_t) -1; /* default value */
} }
/*}}}*/ /*}}}*/
struct rfc822 *data_to_rfc822(char *data, int length)/*{{{*/ struct rfc822 *data_to_rfc822(struct msg_src *src, char *data, int length)/*{{{*/
{ {
struct rfc822 *result; struct rfc822 *result;
char *body_start; char *body_start;
...@@ -879,9 +914,10 @@ struct rfc822 *data_to_rfc822(char *data, int length)/*{{{*/ ...@@ -879,9 +914,10 @@ struct rfc822 *data_to_rfc822(char *data, int length)/*{{{*/
init_headers(&result->hdrs); init_headers(&result->hdrs);
result->atts.next = result->atts.prev = &result->atts; result->atts.next = result->atts.prev = &result->atts;
if (split_and_splice_header(data, &header, &body_start) < 0) { if (split_and_splice_header(src, data, &header, &body_start) < 0) {
if (verbose) { if (verbose) {
fprintf(stderr, "Giving up on message with bad header\n"); fprintf(stderr, "Giving up on message %s with bad header\n",
format_msg_src(src));
} }
return NULL; return NULL;
} }
...@@ -908,7 +944,7 @@ struct rfc822 *data_to_rfc822(char *data, int length)/*{{{*/ ...@@ -908,7 +944,7 @@ struct rfc822 *data_to_rfc822(char *data, int length)/*{{{*/
/* Process body */ /* Process body */
body_len = length - (body_start - data); body_len = length - (body_start - data);
do_body(body_start, body_len, content_type, content_transfer_encoding, &result->atts); do_body(src, body_start, body_len, content_type, content_transfer_encoding, &result->atts);
/* Free header memory */ /* Free header memory */
for (x=header.next; x!=&header; x=nx) { for (x=header.next; x!=&header; x=nx) {
...@@ -964,6 +1000,14 @@ void create_ro_mapping(const char *filename, unsigned char **data, int *len)/*{{ ...@@ -964,6 +1000,14 @@ void create_ro_mapping(const char *filename, unsigned char **data, int *len)/*{{
} }
} }
/*}}}*/ /*}}}*/
static struct msg_src *setup_msg_src(char *filename)/*{{{*/
{
static struct msg_src result;
result.type = MS_FILE;
result.filename = filename;
return &result;
}
/*}}}*/
struct rfc822 *make_rfc822(char *filename)/*{{{*/ struct rfc822 *make_rfc822(char *filename)/*{{{*/
{ {
int len; int len;
...@@ -977,8 +1021,10 @@ struct rfc822 *make_rfc822(char *filename)/*{{{*/ ...@@ -977,8 +1021,10 @@ struct rfc822 *make_rfc822(char *filename)/*{{{*/
if (data) if (data)
{ {
/* Now process the data */ struct msg_src *src;
result = data_to_rfc822(data, len); /* Now process the data */
src = setup_msg_src(filename);
result = data_to_rfc822(src, data, len);
if (munmap(data, (size_t) len) < 0) { if (munmap(data, (size_t) len) < 0) {
perror("Could not munmap"); perror("Could not munmap");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment