[dovecot-cvs] dovecot/src/lib-index/mbox mbox-index.c,1.66,1.67 mbox-index.h,1.25,1.26 mbox-rewrite.c,1.53,1.54
cras at procontrol.fi
cras at procontrol.fi
Wed Mar 26 19:29:04 EET 2003
Update of /home/cvs/dovecot/src/lib-index/mbox
In directory danu:/tmp/cvs-serv10853/lib-index/mbox
Modified Files:
mbox-index.c mbox-index.h mbox-rewrite.c
Log Message:
Better handling for multiline headers. Before we skipped headers larger than
input buffer size (8k with read (default), 256k with mmap). The skipping was
also a bit buggy.
Now we parse the lines one at a time. There's also a way to read the header
fully into memory before parsing it, if really needed.
Index: mbox-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-index.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -d -r1.66 -r1.67
--- mbox-index.c 6 Mar 2003 19:23:45 -0000 1.66
+++ mbox-index.c 26 Mar 2003 17:29:02 -0000 1.67
@@ -248,16 +248,14 @@
}
void mbox_header_cb(struct message_part *part __attr_unused__,
- const unsigned char *name, size_t name_len,
- const unsigned char *value, size_t value_len,
- void *context)
+ struct message_header_line *hdr, void *context)
{
struct mbox_header_context *ctx = context;
uoff_t start_offset, end_offset;
size_t i;
int fixed = FALSE;
- if (name_len == 0) {
+ if (hdr == NULL) {
/* End of headers */
if (!ctx->set_read_limit)
return;
@@ -281,99 +279,109 @@
return;
}
+ if (hdr->eoh)
+ return;
+
/* Pretty much copy&pasted from popa3d by Solar Designer */
- switch (*name) {
+ switch (*hdr->name) {
case 'R':
case 'r':
- if (!ctx->received && name_len == 8 &&
- memcasecmp(name, "Received", 8) == 0) {
- ctx->received = TRUE;
+ if (!ctx->received &&
+ strcasecmp(hdr->name, "Received") == 0) {
+ /* get only the first received-header */
fixed = TRUE;
+ if (!hdr->continues)
+ ctx->received = TRUE;
}
break;
case 'C':
case 'c':
- if (name_len == 14 && ctx->set_read_limit &&
- memcasecmp(name, "Content-Length", 14) == 0) {
+ if (ctx->set_read_limit &&
+ strcasecmp(hdr->name, "Content-Length") == 0) {
/* manual parsing, so we can deal with uoff_t */
ctx->content_length = 0;
- for (i = 0; i < value_len; i++) {
- if (value[i] < '0' || value[i] > '9') {
+ for (i = 0; i < hdr->value_len; i++) {
+ if (hdr->value[i] < '0' ||
+ hdr->value[i] > '9') {
/* invalid */
ctx->content_length = 0;
break;
}
ctx->content_length = ctx->content_length * 10 +
- (value[i] - '0');
+ (hdr->value[i] - '0');
}
}
break;
case 'D':
case 'd':
- if (name_len == 12)
- fixed = memcasecmp(name, "Delivered-To", 12) == 0;
- else if (name_len == 4) {
+ if (strcasecmp(hdr->name, "Delivered-To") == 0)
+ fixed = TRUE;
+ else if (!ctx->received && strcasecmp(hdr->name, "Date") == 0) {
/* Received-header contains date too,
and more trusted one */
- fixed = !ctx->received &&
- memcasecmp(name, "Date", 4) == 0;
+ fixed = TRUE;
}
break;
case 'M':
case 'm':
- if (name_len == 10) {
+ if (!ctx->received &&
+ strcasecmp(hdr->name, "Message-ID") == 0) {
/* Received-header contains unique ID too,
and more trusted one */
- fixed = !ctx->received &&
- memcasecmp(name, "Message-ID", 10) == 0;
+ fixed = TRUE;
}
break;
case 'S':
case 's':
- if (name_len == 6 && memcasecmp(name, "Status", 6) == 0) {
+ if (strcasecmp(hdr->name, "Status") == 0) {
/* update message flags */
- ctx->flags |= mbox_get_status_flags(value, value_len);
+ ctx->flags |= mbox_get_status_flags(hdr->value,
+ hdr->value_len);
}
break;
case 'X':
case 'x':
- if (name_len == 13) {
+ if (strcasecmp(hdr->name, "X-Delivery-ID:") == 0) {
/* Let the local delivery agent help generate unique
ID's but don't blindly trust this header alone as
it could just as easily come from the remote. */
- fixed = memcasecmp(name, "X-Delivery-ID:", 13) == 0;
- } else if (name_len == 5 &&
- memcasecmp(name, "X-UID", 5) == 0) {
+ fixed = TRUE;
+ } else if (strcasecmp(hdr->name, "X-UID") == 0) {
ctx->uid = 0;
- for (i = 0; i < value_len; i++) {
- if (value[i] < '0' || value[i] > '9')
+ for (i = 0; i < hdr->value_len; i++) {
+ if (hdr->value[i] < '0' ||
+ hdr->value[i] > '9')
break;
- ctx->uid = ctx->uid * 10 + (value[i]-'0');
+ ctx->uid = ctx->uid * 10 + (hdr->value[i]-'0');
}
- } else if (name_len == 8 &&
- memcasecmp(name, "X-Status", 8) == 0) {
+ } else if (strcasecmp(hdr->name, "X-Status") == 0) {
/* update message flags */
- ctx->flags |= mbox_get_status_flags(value, value_len);
- } else if (name_len == 10 &&
- memcasecmp(name, "X-Keywords", 10) == 0) {
+ ctx->flags |= mbox_get_status_flags(hdr->value,
+ hdr->value_len);
+ } else if (strcasecmp(hdr->name, "X-Keywords") == 0) {
/* update custom message flags */
- ctx->flags |= mbox_get_keyword_flags(value, value_len,
+ ctx->flags |= mbox_get_keyword_flags(hdr->value,
+ hdr->value_len,
ctx->custom_flags);
- } else if (name_len == 10 &&
- memcasecmp(name, "X-IMAPbase", 10) == 0) {
- mbox_parse_imapbase(value, value_len, ctx);
+ } else if (strcasecmp(hdr->name, "X-IMAPbase") == 0) {
+ if (hdr->continues) {
+ hdr->use_full_value = TRUE;
+ break;
+ }
+ mbox_parse_imapbase(hdr->full_value,
+ hdr->full_value_len, ctx);
}
break;
}
if (fixed)
- md5_update(&ctx->md5, value, value_len);
+ md5_update(&ctx->md5, hdr->value, hdr->value_len);
}
void mbox_keywords_parse(const unsigned char *value, size_t len,
Index: mbox-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-index.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- mbox-index.h 6 Mar 2003 19:23:45 -0000 1.25
+++ mbox-index.h 26 Mar 2003 17:29:02 -0000 1.26
@@ -33,10 +33,8 @@
struct mail_index *index,
struct istream *input);
void mbox_header_free_context(struct mbox_header_context *ctx);
-void mbox_header_cb(struct message_part *part __attr_unused__,
- const unsigned char *name, size_t name_len,
- const unsigned char *value, size_t value_len,
- void *context);
+void mbox_header_cb(struct message_part *part,
+ struct message_header_line *hdr, void *context);
void mbox_keywords_parse(const unsigned char *value, size_t len,
const char *custom_flags[MAIL_CUSTOM_FLAGS_COUNT],
void (*func)(const unsigned char *, size_t,
Index: mbox-rewrite.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-rewrite.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- mbox-rewrite.c 6 Mar 2003 19:23:45 -0000 1.53
+++ mbox-rewrite.c 26 Mar 2003 17:29:02 -0000 1.54
@@ -20,7 +20,6 @@
struct mbox_rewrite_context {
struct ostream *output;
- int failed;
uoff_t content_length;
unsigned int seq, uid;
@@ -258,51 +257,96 @@
return str_len(str) == 0 ? NULL : str_c(str);
}
-static void header_cb(struct message_part *part __attr_unused__,
- const unsigned char *name, size_t name_len,
- const unsigned char *value, size_t value_len,
- void *context)
+static int write_header(struct mbox_rewrite_context *ctx,
+ struct message_header_line *hdr)
{
- struct mbox_rewrite_context *ctx = context;
const char *str;
- if (ctx->failed)
- return;
+ switch (hdr->name_len) {
+ case 5:
+ if (strcasecmp(hdr->name, "X-UID") == 0) {
+ if (ctx->xuid_found)
+ return TRUE;
+
+ ctx->xuid_found = TRUE;
+ return mbox_write_xuid(ctx);
+ }
+ break;
+ case 6:
+ if (strcasecmp(hdr->name, "Status") == 0) {
+ if (ctx->status_found)
+ return TRUE;
+ if (hdr->continues) {
+ hdr->use_full_value = TRUE;
+ return TRUE;
+ }
+
+ ctx->status_found = TRUE;
+ str = strip_chars(hdr->full_value,
+ hdr->full_value_len, "RO");
+ return mbox_write_status(ctx, str);
+ }
+ break;
+ case 8:
+ if (strcasecmp(hdr->name, "X-Status") == 0) {
+ if (ctx->xstatus_found)
+ return TRUE;
+ if (hdr->continues) {
+ hdr->use_full_value = TRUE;
+ return TRUE;
+ }
+
+ ctx->xstatus_found = TRUE;
+ str = strip_chars(hdr->full_value,
+ hdr->full_value_len, "ADFT");
+ return mbox_write_xstatus(ctx, str);
+ }
+ break;
+ case 10:
+ if (strcasecmp(hdr->name, "X-Keywords") == 0) {
+ if (ctx->xkeywords_found)
+ return TRUE;
+ if (hdr->continues) {
+ hdr->use_full_value = TRUE;
+ return TRUE;
+ }
+
+ ctx->xkeywords_found = TRUE;
+ str = strip_custom_flags(hdr->full_value,
+ hdr->full_value_len, ctx);
+ return mbox_write_xkeywords(ctx, str);
+ } else if (strcasecmp(hdr->name, "X-IMAPbase") == 0) {
+ if (ctx->seq != 1 || ctx->ximapbase_found)
+ return TRUE;
- if (name_len == 6 && memcasecmp(name, "Status", 6) == 0) {
- ctx->status_found = TRUE;
- str = strip_chars(value, value_len, "RO");
- (void)mbox_write_status(ctx, str);
- } else if (name_len == 8 && memcasecmp(name, "X-Status", 8) == 0) {
- ctx->xstatus_found = TRUE;
- str = strip_chars(value, value_len, "ADFT");
- (void)mbox_write_xstatus(ctx, str);
- } else if (name_len == 10 && memcasecmp(name, "X-Keywords", 10) == 0) {
- ctx->xkeywords_found = TRUE;
- str = strip_custom_flags(value, value_len, ctx);
- (void)mbox_write_xkeywords(ctx, str);
- } else if (name_len == 10 && memcasecmp(name, "X-IMAPbase", 10) == 0) {
- if (ctx->seq == 1) {
ctx->ximapbase_found = TRUE;
- (void)mbox_write_ximapbase(ctx);
+ return mbox_write_ximapbase(ctx);
}
- } else if (name_len == 5 && memcasecmp(name, "X-UID", 5) == 0) {
- ctx->xuid_found = TRUE;
- (void)mbox_write_xuid(ctx);
- } else if (name_len == 14 &&
- memcasecmp(name, "Content-Length", 14) == 0) {
- ctx->content_length_found = TRUE;
- (void)mbox_write_content_length(ctx);
- } else if (name_len > 0) {
+ break;
+ case 14:
+ if (strcasecmp(hdr->name, "Content-Length") == 0) {
+ if (ctx->content_length_found)
+ return TRUE;
+
+ ctx->content_length_found = TRUE;
+ return mbox_write_content_length(ctx);
+ }
+ break;
+ }
+
+ if (!hdr->eoh) {
/* save this header */
- (void)o_stream_send(ctx->output, name, name_len);
- (void)o_stream_send(ctx->output, ": ", 2);
- (void)o_stream_send(ctx->output, value, value_len);
- (void)o_stream_send(ctx->output, "\n", 1);
+ if (!hdr->continued) {
+ (void)o_stream_send(ctx->output, hdr->name,
+ hdr->name_len);
+ (void)o_stream_send(ctx->output, ": ", 2);
+ }
+ (void)o_stream_send(ctx->output, hdr->value, hdr->value_len);
+ if (!hdr->no_newline)
+ (void)o_stream_send(ctx->output, "\n", 1);
}
- if (ctx->output->closed)
- ctx->failed = TRUE;
+ return !ctx->output->closed;
}
static int mbox_write_header(struct mail_index *index,
@@ -323,6 +367,8 @@
Last used UID is also not updated, and set to 0 initially.
*/
struct mbox_rewrite_context ctx;
+ struct message_header_parser_ctx *hdr_ctx;
+ struct message_header_line *hdr;
struct message_size hdr_parsed_size;
if (input->v_offset >= end_offset) {
@@ -346,7 +392,12 @@
ctx.custom_flags = mail_custom_flags_list_get(index->custom_flags);
i_stream_set_read_limit(input, input->v_offset + hdr_size);
- message_parse_header(NULL, input, &hdr_parsed_size, header_cb, &ctx);
+
+ hdr_ctx = message_parse_header_init(input, &hdr_parsed_size);
+ while ((hdr = message_parse_header_next(hdr_ctx)) != NULL)
+ write_header(&ctx, hdr);
+ message_parse_header_deinit(hdr_ctx);
+
i_stream_set_read_limit(input, 0);
i_assert(hdr_parsed_size.physical_size == hdr_size);
More information about the dovecot-cvs
mailing list