[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-file.c, 1.3, 1.4 mbox-sync-parse.c, 1.22, 1.23 mbox-sync-private.h, 1.27, 1.28 mbox-sync.c, 1.71, 1.72

cras at dovecot.org cras at dovecot.org
Sat Aug 28 20:41:55 EEST 2004


Update of /home/cvs/dovecot/src/lib-storage/index/mbox
In directory talvi:/tmp/cvs-serv29165

Modified Files:
	mbox-file.c mbox-sync-parse.c mbox-sync-private.h mbox-sync.c 
Log Message:
When mbox syncing is dirty, read the message headers to verify that we've
found the correct message.



Index: mbox-file.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-file.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- mbox-file.c	28 Aug 2004 16:39:54 -0000	1.3
+++ mbox-file.c	28 Aug 2004 17:41:52 -0000	1.4
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "istream.h"
 #include "mbox-storage.h"
+#include "mbox-sync-private.h"
 #include "mbox-file.h"
 #include "istream-raw-mbox.h"
 
@@ -126,7 +127,13 @@
 	}
 
 	if (ibox->mbox_sync_dirty) {
-		/* FIXME: we're dirty - make sure this is the correct mail */
+		/* we're dirty - make sure this is the correct mail */
+		ret = mbox_sync_parse_match_mail(ibox, view, seq);
+		if (ret <= 0)
+			return ret;
+
+		ret = istream_raw_mbox_seek(ibox->mbox_stream, offset);
+		i_assert(ret == 0);
 	}
 
 	return 1;

Index: mbox-sync-parse.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-parse.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- mbox-sync-parse.c	22 Aug 2004 03:19:59 -0000	1.22
+++ mbox-sync-parse.c	28 Aug 2004 17:41:52 -0000	1.23
@@ -10,6 +10,7 @@
 #include "write-full.h"
 #include "message-parser.h"
 #include "mail-index.h"
+#include "mbox-storage.h"
 #include "mbox-sync-private.h"
 
 #include <stdlib.h>
@@ -206,18 +207,25 @@
 		}
 	}
 
-	if (value >= ctx->sync_ctx->next_uid) {
-		/* next_uid broken - fix it */
-		ctx->sync_ctx->next_uid = value+1;
-	}
+	if (ctx->sync_ctx != NULL) {
+		if (value >= ctx->sync_ctx->next_uid) {
+			/* next_uid broken - fix it */
+			ctx->sync_ctx->next_uid = value+1;
+		}
 
-	if (value <= ctx->sync_ctx->prev_msg_uid) {
-		/* broken - UIDs must be growing */
-		return FALSE;
+		if (value <= ctx->sync_ctx->prev_msg_uid) {
+			/* broken - UIDs must be growing */
+			return FALSE;
+		}
+		ctx->sync_ctx->prev_msg_uid = value;
 	}
 
 	ctx->mail.uid = value;
-	ctx->sync_ctx->prev_msg_uid = value;
+
+	if (ctx->sync_ctx == NULL) {
+		/* we're in mbox_sync_parse_match_mail() */
+		return TRUE;
+	}
 
 	if (ctx->sync_ctx->dest_first_mail && !ctx->seen_imapbase) {
 		/* everything was good, except we can't have X-UID before
@@ -328,30 +336,32 @@
 
 static struct header_func header_funcs[] = {
 	{ "Content-Length", parse_content_length },
-	{ "Date", parse_date },
-	{ "Delivered-To", parse_delivered_to },
-	{ "Message-ID", parse_message_id },
-	{ "Received", parse_received },
 	{ "Status", parse_status },
-	{ "X-Delivery-ID", parse_x_delivery_id },
 	{ "X-IMAP", parse_x_imap },
 	{ "X-IMAPbase", parse_x_imap_base },
 	{ "X-Keywords", parse_x_keywords },
 	{ "X-Status", parse_x_status },
 	{ "X-UID", parse_x_uid },
-	{ "X-UIDL", parse_x_uidl },
-	{ NULL, NULL }
+	{ "X-UIDL", parse_x_uidl }
 };
+#define HEADER_FUNCS_COUNT (sizeof(header_funcs) / sizeof(*header_funcs))
 
-static struct header_func *header_func_find(const char *header)
+static struct header_func md5_header_funcs[] = {
+	{ "Date", parse_date },
+	{ "Delivered-To", parse_delivered_to },
+	{ "Message-ID", parse_message_id },
+	{ "Received", parse_received },
+	{ "X-Delivery-ID", parse_x_delivery_id }
+};
+#define MD5_HEADER_FUNCS_COUNT \
+	(sizeof(md5_header_funcs) / sizeof(*md5_header_funcs))
+
+static int bsearch_header_func_cmp(const void *p1, const void *p2)
 {
-	int i;
+	const char *key = p1;
+	const struct header_func *func = p2;
 
-	for (i = 0; header_funcs[i].header != NULL; i++) {
-		if (strcasecmp(header_funcs[i].header, header) == 0)
-			return &header_funcs[i];
-	}
-	return NULL;
+	return strcasecmp(key, func->header);
 }
 
 void mbox_sync_parse_next_mail(struct istream *input,
@@ -391,7 +401,21 @@
 			str_append_n(ctx->header, hdr->middle, hdr->middle_len);
 		}
 
-		func = header_func_find(hdr->name);
+		func = bsearch(hdr->name, md5_header_funcs,
+			       MD5_HEADER_FUNCS_COUNT,
+			       sizeof(*header_funcs), bsearch_header_func_cmp);
+		if (func != NULL) {
+			/* these functions do nothing more than update
+			   MD5 sums */
+			(void)func->func(ctx, hdr);
+			func = NULL;
+		} else {
+			func = bsearch(hdr->name, header_funcs,
+				       HEADER_FUNCS_COUNT,
+				       sizeof(*header_funcs),
+				       bsearch_header_func_cmp);
+		}
+
 		if (func != NULL) {
 			if (hdr->continues) {
 				hdr->use_full_value = TRUE;
@@ -435,3 +459,69 @@
 
 	ctx->body_offset = input->v_offset;
 }
+
+int mbox_sync_parse_match_mail(struct index_mailbox *ibox,
+			       struct mail_index_view *view, uint32_t seq)
+{
+        struct mbox_sync_mail_context ctx;
+	struct message_header_parser_ctx *hdr_ctx;
+	struct message_header_line *hdr;
+	struct header_func *func;
+	const void *data;
+	uint32_t uid;
+	int ret;
+
+	memset(&ctx, 0, sizeof(ctx));
+	md5_init(&ctx.hdr_md5_ctx);
+
+	hdr_ctx = message_parse_header_init(ibox->mbox_stream, NULL, FALSE);
+	while ((ret = message_parse_header_next(hdr_ctx, &hdr)) > 0) {
+		if (hdr->eoh)
+			break;
+
+		func = bsearch(hdr->name, md5_header_funcs,
+			       MD5_HEADER_FUNCS_COUNT,
+			       sizeof(*header_funcs), bsearch_header_func_cmp);
+		if (func != NULL) {
+			/* these functions do nothing more than update
+			   MD5 sums */
+			(void)func->func(&ctx, hdr);
+		} else if (strcasecmp(hdr->name, "X-UID") == 0) {
+			if (hdr->continues) {
+				hdr->use_full_value = TRUE;
+				continue;
+			}
+			(void)parse_x_uid(&ctx, hdr);
+
+			if (ctx.mail.uid != 0)
+				break;
+		}
+	}
+	i_assert(ret != 0);
+	message_parse_header_deinit(hdr_ctx);
+
+	md5_final(&ctx.hdr_md5_ctx, ctx.hdr_md5_sum);
+
+	if (ctx.mail.uid != 0) {
+		/* match by X-UID header */
+		if (mail_index_lookup_uid(view, seq, &uid) < 0) {
+			mail_storage_set_index_error(ibox);
+			return -1;
+		}
+		return ctx.mail.uid == uid;
+	}
+
+	/* match by MD5 sum */
+	if (ibox->md5hdr_extra_idx == 0) {
+		ibox->md5hdr_extra_idx =
+			mail_index_register_record_extra(ibox->index,
+							 "header-md5", 16);
+	}
+
+	if (mail_index_lookup_extra(view, seq, ibox->md5hdr_extra_idx,
+				    &data) < 0) {
+		mail_storage_set_index_error(ibox);
+		return -1;
+	}
+	return memcmp(data, ctx.hdr_md5_sum, 16) == 0;
+}

Index: mbox-sync-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-private.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- mbox-sync-private.h	28 Aug 2004 16:39:54 -0000	1.27
+++ mbox-sync-private.h	28 Aug 2004 17:41:52 -0000	1.28
@@ -115,6 +115,9 @@
 
 void mbox_sync_parse_next_mail(struct istream *input,
 			       struct mbox_sync_mail_context *ctx);
+int mbox_sync_parse_match_mail(struct index_mailbox *ibox,
+			       struct mail_index_view *view, uint32_t seq);
+
 void mbox_sync_update_header(struct mbox_sync_mail_context *ctx,
 			     buffer_t *syncs_buf);
 void mbox_sync_update_header_from(struct mbox_sync_mail_context *ctx,

Index: mbox-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync.c,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -d -r1.71 -r1.72
--- mbox-sync.c	28 Aug 2004 16:39:54 -0000	1.71
+++ mbox-sync.c	28 Aug 2004 17:41:52 -0000	1.72
@@ -705,9 +705,8 @@
 	messages_count = mail_index_view_get_message_count(sync_ctx->sync_view);
 
 	if (min_message_count != 0) {
-		ret = mbox_sync_seek_to_seq(sync_ctx,
-					    partial || messages_count == 0 ?
-					    messages_count : 1);
+		ret = mbox_sync_seek_to_seq(sync_ctx, partial ?
+					    messages_count : 0);
 	} else {
 		/* we sync only what we need to. jump to first record that
 		   needs updating */



More information about the dovecot-cvs mailing list