dovecot-2.0: Added support for mailbox GUIDs.

dovecot at dovecot.org dovecot at dovecot.org
Tue Jun 16 00:37:49 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/f98ec5dffd04
changeset: 9471:f98ec5dffd04
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Jun 15 17:37:15 2009 -0400
description:
Added support for mailbox GUIDs.

diffstat:

15 files changed, 287 insertions(+), 125 deletions(-)
src/lib-storage/index/dbox/dbox-mail.c          |   14 --
src/lib-storage/index/dbox/dbox-save.c          |   26 -----
src/lib-storage/index/dbox/dbox-storage.c       |  108 +++++++++++++++++++--
src/lib-storage/index/dbox/dbox-storage.h       |    8 +
src/lib-storage/index/dbox/dbox-sync-rebuild.c  |   26 +----
src/lib-storage/index/dbox/dbox-sync.c          |   35 +-----
src/lib-storage/index/index-storage.c           |    1 
src/lib-storage/index/maildir/maildir-storage.c |   15 ++
src/lib-storage/index/maildir/maildir-uidlist.c |  118 +++++++++++++++++------
src/lib-storage/index/maildir/maildir-uidlist.h |    5 
src/lib-storage/index/mbox/mbox-storage.c       |   15 ++
src/lib-storage/index/mbox/mbox-storage.h       |    1 
src/lib-storage/index/mbox/mbox-sync.c          |   19 +++
src/lib-storage/mail-storage.h                  |    5 
src/util/idxview.c                              |   16 ++-

diffs (truncated from 787 to 300 lines):

diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-mail.c
--- a/src/lib-storage/index/dbox/dbox-mail.c	Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-mail.c	Mon Jun 15 17:37:15 2009 -0400
@@ -49,9 +49,8 @@ int dbox_mail_lookup(struct dbox_mailbox
 		     uint32_t seq, uint32_t *map_uid_r)
 {
 	const struct dbox_mail_index_record *dbox_rec;
-	const struct dbox_index_header *hdr;
+	struct dbox_index_header hdr;
 	const void *data;
-	size_t data_size;
 	uint32_t cur_map_uid_validity;
 	bool expunged;
 
@@ -63,18 +62,11 @@ int dbox_mail_lookup(struct dbox_mailbox
 	}
 
 	if (mbox->map_uid_validity == 0) {
-		mail_index_get_header_ext(mbox->ibox.view,
-					  mbox->dbox_hdr_ext_id,
-					  &data, &data_size);
-		if (data_size != sizeof(*hdr)) {
-			mail_storage_set_critical(&mbox->storage->storage,
-				"dbox %s: Invalid dbox header size",
-				mbox->ibox.box.path);
+		if (dbox_read_header(mbox, &hdr) < 0) {
 			mbox->storage->sync_rebuild = TRUE;
 			return -1;
 		}
-		hdr = data;
-		mbox->map_uid_validity = hdr->map_uid_validity;
+		mbox->map_uid_validity = hdr.map_uid_validity;
 	}
 	if (dbox_map_open(mbox->storage->map, TRUE) < 0)
 		return -1;
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-save.c
--- a/src/lib-storage/index/dbox/dbox-save.c	Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-save.c	Mon Jun 15 17:37:15 2009 -0400
@@ -319,30 +319,6 @@ void dbox_save_cancel(struct mail_save_c
 	(void)dbox_save_finish(_ctx);
 }
 
-static void dbox_add_missing_map_uidvalidity(struct dbox_save_context *ctx)
-{
-	const struct dbox_index_header *hdr;
-	struct dbox_index_header new_hdr;
-	const void *data;
-	size_t data_size;
-
-	mail_index_get_header_ext(ctx->mbox->ibox.view,
-				  ctx->mbox->dbox_hdr_ext_id,
-				  &data, &data_size);
-	if (data_size == sizeof(*hdr)) {
-		hdr = data;
-		if (hdr->map_uid_validity != 0)
-			return;
-		new_hdr = *hdr;
-	} else {
-		memset(&new_hdr, 0, sizeof(new_hdr));
-	}
-	new_hdr.map_uid_validity =
-		dbox_map_get_uid_validity(ctx->mbox->storage->map);
-	mail_index_update_header_ext(ctx->trans, ctx->mbox->dbox_hdr_ext_id, 0,
-				     &new_hdr, sizeof(new_hdr));
-}
-
 int dbox_transaction_save_commit_pre(struct dbox_save_context *ctx)
 {
 	struct dbox_transaction_context *t =
@@ -392,7 +368,7 @@ int dbox_transaction_save_commit_pre(str
 		unsigned int i, count;
 		uint32_t next_map_uid = first_map_uid;
 
-		dbox_add_missing_map_uidvalidity(ctx);
+		dbox_update_header(ctx->mbox, ctx->trans);
 
 		memset(&rec, 0, sizeof(rec));
 		rec.save_date = ioloop_time;
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c	Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Mon Jun 15 17:37:15 2009 -0400
@@ -191,23 +191,72 @@ uint32_t dbox_get_uidvalidity_next(struc
 	return mailbox_uidvalidity_next(path);
 }
 
+static bool
+dbox_index_header_has_mailbox_guid(const struct dbox_index_header *hdr)
+{
+	unsigned int i;
+
+	for (i = 0; i < sizeof(hdr->mailbox_guid); i++) {
+		if (hdr->mailbox_guid[i] != 0)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+void dbox_set_mailbox_guid(struct dbox_index_header *hdr)
+{
+	if (!dbox_index_header_has_mailbox_guid(hdr))
+		mail_generate_guid_128(hdr->mailbox_guid);
+}
+
+int dbox_read_header(struct dbox_mailbox *mbox, struct dbox_index_header *hdr)
+{
+	const void *data;
+	size_t data_size;
+
+	mail_index_get_header_ext(mbox->ibox.view, mbox->dbox_hdr_ext_id,
+				  &data, &data_size);
+	if (data_size < DBOX_INDEX_HEADER_MIN_SIZE &&
+	    (!mbox->creating || data_size != 0)) {
+		mail_storage_set_critical(&mbox->storage->storage,
+			"dbox %s: Invalid dbox header size",
+			mbox->ibox.box.path);
+		return -1;
+	}
+	memset(hdr, 0, sizeof(*hdr));
+	memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
+	return 0;
+}
+
+void dbox_update_header(struct dbox_mailbox *mbox,
+			struct mail_index_transaction *trans)
+{
+	struct dbox_index_header hdr, new_hdr;
+
+	if (dbox_read_header(mbox, &hdr) < 0)
+		memset(&hdr, 0, sizeof(hdr));
+
+	new_hdr = hdr;
+	dbox_set_mailbox_guid(&new_hdr);
+	new_hdr.map_uid_validity =
+		dbox_map_get_uid_validity(mbox->storage->map);
+	if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
+		mail_index_update_header_ext(trans, mbox->dbox_hdr_ext_id, 0,
+					     &new_hdr, sizeof(new_hdr));
+	}
+}
+
 static int dbox_write_index_header(struct mailbox *box)
 {
 	struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
 	struct mail_index_transaction *trans;
-	struct dbox_index_header hdr;
 	uint32_t uid_validity;
 
 	if (dbox_map_open(mbox->storage->map, TRUE) < 0)
 		return -1;
 
 	trans = mail_index_transaction_begin(mbox->ibox.view, 0);
-
-	/* set dbox header */
-	memset(&hdr, 0, sizeof(hdr));
-	hdr.map_uid_validity = dbox_map_get_uid_validity(mbox->storage->map);
-	mail_index_update_header_ext(trans, mbox->dbox_hdr_ext_id, 0,
-				     &hdr, sizeof(hdr));
+	dbox_update_header(mbox, trans);
 
 	/* set uidvalidity */
 	uid_validity = dbox_get_uidvalidity_next(box->list);
@@ -215,20 +264,30 @@ static int dbox_write_index_header(struc
 		offsetof(struct mail_index_header, uid_validity),
 		&uid_validity, sizeof(uid_validity), TRUE);
 
-	return mail_index_transaction_commit(&trans);
+	if (mail_index_transaction_commit(&trans) < 0) {
+		mail_storage_set_internal_error(box->storage);
+		mail_index_reset_error(mbox->ibox.index);
+		return -1;
+	}
+	return 0;
 }
 
 static int create_dbox(struct mailbox *box)
 {
+	struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
 	mode_t mode;
 	gid_t gid;
+	int ret;
 
 	mailbox_list_get_dir_permissions(box->list, NULL, &mode, &gid);
 	if (mkdir_parents_chown(box->path, mode, (uid_t)-1, gid) == 0) {
 		/* create indexes immediately with the dbox header */
 		if (index_storage_mailbox_open(box) < 0)
 			return -1;
-		if (dbox_write_index_header(box) < 0)
+		mbox->creating = TRUE;
+		ret = dbox_write_index_header(box);
+		mbox->creating = FALSE;
+		if (ret < 0)
 			return -1;
 	} else if (errno != EEXIST) {
 		if (!mail_storage_set_error_from_errno(box->storage)) {
@@ -303,6 +362,35 @@ static void dbox_mailbox_close(struct ma
 
 	maildir_uidlist_deinit(&mbox->maildir_uidlist);
 	index_storage_mailbox_close(box);
+}
+
+static void dbox_storage_get_status_guid(struct mailbox *box,
+					 struct mailbox_status *status_r)
+{
+	struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
+	struct dbox_index_header hdr;
+
+	if (dbox_read_header(mbox, &hdr) < 0)
+		memset(&hdr, 0, sizeof(hdr));
+
+	if (!dbox_index_header_has_mailbox_guid(&hdr)) {
+		/* regenerate it */
+		if (dbox_write_index_header(box) < 0 ||
+		    dbox_read_header(mbox, &hdr) < 0)
+			return;
+	}
+	memcpy(status_r->mailbox_guid, hdr.mailbox_guid,
+	       sizeof(status_r->mailbox_guid));
+}
+
+static void
+dbox_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
+			struct mailbox_status *status_r)
+{
+	index_storage_get_status(box, items, status_r);
+
+	if ((items & STATUS_GUID) != 0)
+		dbox_storage_get_status_guid(box, status_r);
 }
 
 static int
@@ -776,7 +864,7 @@ struct mailbox dbox_mailbox = {
 		index_storage_mailbox_enable,
 		dbox_mailbox_open,
 		dbox_mailbox_close,
-		index_storage_get_status,
+		dbox_storage_get_status,
 		NULL,
 		NULL,
 		dbox_storage_sync_init,
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-storage.h
--- a/src/lib-storage/index/dbox/dbox-storage.h	Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-storage.h	Mon Jun 15 17:37:15 2009 -0400
@@ -30,9 +30,11 @@
 /* Flag specifies if the message should be in primary or alternative storage */
 #define DBOX_INDEX_FLAG_ALT MAIL_INDEX_MAIL_FLAG_BACKEND
 
+#define DBOX_INDEX_HEADER_MIN_SIZE (sizeof(uint32_t))
 struct dbox_index_header {
 	uint32_t map_uid_validity;
 	uint32_t highest_maildir_uid;
+	uint8_t mailbox_guid[MAILBOX_GUID_SIZE];
 };
 
 struct dbox_storage {
@@ -74,6 +76,8 @@ struct dbox_mailbox {
 	uint32_t dbox_ext_id, dbox_hdr_ext_id, guid_ext_id;
 
 	const char *alt_path;
+
+	unsigned int creating:1;
 };
 
 struct dbox_transaction_context {
@@ -104,6 +108,10 @@ int dbox_mail_lookup(struct dbox_mailbox
 int dbox_mail_lookup(struct dbox_mailbox *mbox, struct mail_index_view *view,
 		     uint32_t seq, uint32_t *map_uid_r);
 uint32_t dbox_get_uidvalidity_next(struct mailbox_list *list);
+void dbox_set_mailbox_guid(struct dbox_index_header *hdr);
+int dbox_read_header(struct dbox_mailbox *mbox, struct dbox_index_header *hdr);
+void dbox_update_header(struct dbox_mailbox *mbox,
+			struct mail_index_transaction *trans);
 
 struct mail_save_context *
 dbox_save_alloc(struct mailbox_transaction_context *_t);
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-sync-rebuild.c
--- a/src/lib-storage/index/dbox/dbox-sync-rebuild.c	Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-sync-rebuild.c	Mon Jun 15 17:37:15 2009 -0400
@@ -348,25 +348,17 @@ static int dbox_sync_maildir_finish(stru
 
 static void dbox_sync_update_header(struct dbox_sync_rebuild_context *ctx)
 {
-	const struct dbox_index_header *hdr;
-	struct dbox_index_header new_hdr;
-	const void *data;
-	size_t data_size;
-
-	mail_index_get_header_ext(ctx->mbox->ibox.view,
-				  ctx->mbox->dbox_hdr_ext_id,
-				  &data, &data_size);
-	hdr = data;
-	if (data_size == sizeof(*hdr))
-		new_hdr = *hdr;
-	else
-		memset(&new_hdr, 0, sizeof(new_hdr));
-	if (new_hdr.highest_maildir_uid < ctx->mbox->highest_maildir_uid)
-		new_hdr.highest_maildir_uid = ctx->mbox->highest_maildir_uid;
-	new_hdr.map_uid_validity = !ctx->storage_rebuild ? 0 :
+	struct dbox_index_header hdr;
+
+	if (dbox_read_header(ctx->mbox, &hdr) < 0)


More information about the dovecot-cvs mailing list