dovecot-2.0: Added support for creating/updating mailboxes with ...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jun 26 23:12:09 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/530bbade4e3f
changeset: 9533:530bbade4e3f
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jun 26 16:11:59 2009 -0400
description:
Added support for creating/updating mailboxes with given metadata (guid, uid validity, etc).

diffstat:

29 files changed, 452 insertions(+), 308 deletions(-)
src/imap/cmd-create.c                             |    9 -
src/lib-lda/mail-deliver.c                        |   12 +-
src/lib-storage/index/cydir/cydir-storage.c       |   38 +++++-
src/lib-storage/index/dbox/dbox-save.c            |    2 
src/lib-storage/index/dbox/dbox-storage-rebuild.c |   17 +--
src/lib-storage/index/dbox/dbox-storage.c         |  118 +++++++++++----------
src/lib-storage/index/dbox/dbox-storage.h         |    4 
src/lib-storage/index/dbox/dbox-sync-rebuild.c    |    3 
src/lib-storage/index/index-storage.c             |   26 ++--
src/lib-storage/index/maildir/maildir-storage.c   |   51 ++++++---
src/lib-storage/index/maildir/maildir-uidlist.c   |   30 ++++-
src/lib-storage/index/maildir/maildir-uidlist.h   |    2 
src/lib-storage/index/mbox/mbox-storage.c         |   54 ++++++---
src/lib-storage/index/mbox/mbox-storage.h         |    1 
src/lib-storage/index/mbox/mbox-sync.c            |   45 +++++---
src/lib-storage/index/raw/raw-storage.c           |   22 ++-
src/lib-storage/index/shared/shared-storage.c     |   30 -----
src/lib-storage/mail-storage-private.h            |   10 -
src/lib-storage/mail-storage.c                    |   47 +++++---
src/lib-storage/mail-storage.h                    |   29 +++--
src/lib-storage/test-mail-storage.c               |   12 --
src/lib-storage/test-mailbox.c                    |   21 +++
src/plugins/acl/acl-mailbox.c                     |   37 ++++++
src/plugins/acl/acl-storage.c                     |   33 -----
src/plugins/autocreate/autocreate-plugin.c        |   10 +
src/plugins/convert/convert-storage.c             |   37 +++---
src/plugins/lazy-expunge/lazy-expunge-plugin.c    |   21 +--
src/plugins/listescape/listescape-plugin.c        |   15 --
src/plugins/virtual/virtual-storage.c             |   24 +++-

diffs (truncated from 1586 to 300 lines):

diff -r 29733d23d903 -r 530bbade4e3f src/imap/cmd-create.c
--- a/src/imap/cmd-create.c	Thu Jun 25 14:33:37 2009 -0400
+++ b/src/imap/cmd-create.c	Fri Jun 26 16:11:59 2009 -0400
@@ -7,8 +7,8 @@ bool cmd_create(struct client_command_co
 bool cmd_create(struct client_command_context *cmd)
 {
 	struct mail_namespace *ns;
-	struct mail_storage *storage;
 	const char *mailbox, *full_mailbox;
+	struct mailbox *box;
 	bool directory;
 	size_t len;
 
@@ -40,10 +40,11 @@ bool cmd_create(struct client_command_co
 					CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST))
 		return TRUE;
 
-	storage = mail_namespace_get_default_storage(ns);
-	if (mail_storage_mailbox_create(storage, ns, mailbox, directory) < 0)
-		client_send_storage_error(cmd, storage);
+	box = mailbox_alloc(ns->list, mailbox, NULL, 0);
+	if (mailbox_create(box, NULL, directory) < 0)
+		client_send_storage_error(cmd, mailbox_get_storage(box));
 	else
 		client_send_tagline(cmd, "OK Create completed.");
+	mailbox_close(&box);
 	return TRUE;
 }
diff -r 29733d23d903 -r 530bbade4e3f src/lib-lda/mail-deliver.c
--- a/src/lib-lda/mail-deliver.c	Thu Jun 25 14:33:37 2009 -0400
+++ b/src/lib-lda/mail-deliver.c	Fri Jun 26 16:11:59 2009 -0400
@@ -107,13 +107,15 @@ mailbox_open_or_create_synced(struct mai
 
 	storage = mailbox_get_storage(box);
 	*error_r = mail_storage_get_last_error(storage, &error);
-	mailbox_close(&box);
-	if (!ctx->set->lda_mailbox_autocreate || error != MAIL_ERROR_NOTFOUND)
-		return NULL;
+	if (!ctx->set->lda_mailbox_autocreate || error != MAIL_ERROR_NOTFOUND) {
+		mailbox_close(&box);
+		return NULL;
+	}
 
 	/* try creating it. */
-	if (mail_storage_mailbox_create(storage, ns, name, FALSE) < 0) {
+	if (mailbox_create(box, NULL, FALSE) < 0) {
 		*error_r = mail_storage_get_last_error(storage, &error);
+		mailbox_close(&box);
 		return NULL;
 	}
 	if (ctx->set->lda_mailbox_autosubscribe) {
@@ -122,8 +124,6 @@ mailbox_open_or_create_synced(struct mai
 	}
 
 	/* and try opening again */
-	box = mailbox_alloc(ns->list, name, NULL, flags);
-	storage = mailbox_get_storage(box);
 	if (mailbox_open(box) < 0 ||
 	    mailbox_sync(box, 0, 0, NULL) < 0) {
 		*error_r = mail_storage_get_last_error(storage, &error);
diff -r 29733d23d903 -r 530bbade4e3f src/lib-storage/index/cydir/cydir-storage.c
--- a/src/lib-storage/index/cydir/cydir-storage.c	Thu Jun 25 14:33:37 2009 -0400
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Fri Jun 26 16:11:59 2009 -0400
@@ -128,21 +128,46 @@ static int cydir_mailbox_open(struct mai
 }
 
 static int
-cydir_mailbox_create(struct mail_storage *storage, struct mailbox_list *list,
-		     const char *name, bool directory ATTR_UNUSED)
+cydir_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
+{
+	struct cydir_mailbox *mbox = (struct cydir_mailbox *)box;
+	struct mail_index_transaction *trans;
+
+	trans = mail_index_transaction_begin(mbox->ibox.view, 0);
+	if (update->uid_validity != 0) {
+		mail_index_update_header(trans,
+			offsetof(struct mail_index_header, uid_validity),
+			&update->uid_validity, sizeof(update->uid_validity),
+			TRUE);
+	}
+	/* FIXME: update next_uid, highestmodseq. guid is also missing.. */
+	if (mail_index_transaction_commit(&trans) < 0) {
+		mail_storage_set_internal_error(box->storage);
+		return -1;
+	}
+	return 0;
+}
+
+static int
+cydir_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
+		     bool directory)
 {
 	const char *path;
 	struct stat st;
 
-	path = mailbox_list_get_path(list, name,
+	path = mailbox_list_get_path(box->list, box->name,
 				     MAILBOX_LIST_PATH_TYPE_MAILBOX);
 	if (stat(path, &st) == 0) {
-		mail_storage_set_error(storage, MAIL_ERROR_EXISTS,
+		mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
 				       "Mailbox already exists");
 		return -1;
 	}
 
-	return create_cydir(storage, list, path);
+	if (create_cydir(box->storage, box->list, path) < 0)
+		return -1;
+
+	return directory || update == NULL ? 0 :
+		cydir_mailbox_update(box, update);
 }
 
 static int
@@ -345,7 +370,6 @@ struct mail_storage cydir_storage = {
 		cydir_storage_get_list_settings,
 		NULL,
 		cydir_mailbox_alloc,
-		cydir_mailbox_create,
 		NULL
 	}
 };
@@ -361,6 +385,8 @@ struct mailbox cydir_mailbox = {
 		index_storage_mailbox_enable,
 		cydir_mailbox_open,
 		index_storage_mailbox_close,
+		cydir_mailbox_create,
+		cydir_mailbox_update,
 		index_storage_get_status,
 		NULL,
 		NULL,
diff -r 29733d23d903 -r 530bbade4e3f src/lib-storage/index/dbox/dbox-save.c
--- a/src/lib-storage/index/dbox/dbox-save.c	Thu Jun 25 14:33:37 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-save.c	Fri Jun 26 16:11:59 2009 -0400
@@ -368,7 +368,7 @@ int dbox_transaction_save_commit_pre(str
 		unsigned int i, count;
 		uint32_t next_map_uid = first_map_uid;
 
-		dbox_update_header(ctx->mbox, ctx->trans);
+		dbox_update_header(ctx->mbox, ctx->trans, NULL);
 
 		memset(&rec, 0, sizeof(rec));
 		rec.save_date = ioloop_time;
diff -r 29733d23d903 -r 530bbade4e3f src/lib-storage/index/dbox/dbox-storage-rebuild.c
--- a/src/lib-storage/index/dbox/dbox-storage-rebuild.c	Thu Jun 25 14:33:37 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-storage-rebuild.c	Fri Jun 26 16:11:59 2009 -0400
@@ -543,17 +543,20 @@ static int rebuild_restore_msg(struct db
 			break;
 
 		(void)mail_storage_get_last_error(box->storage, &error);
-		mailbox_close(&box);
-		if (error == MAIL_ERROR_TEMP)
-			return -1;
-
 		if (error == MAIL_ERROR_NOTFOUND && !created) {
 			/* mailbox doesn't exist currently? see if creating
 			   it helps. */
 			created = TRUE;
-			(void)mail_storage_mailbox_create(storage,
-				ctx->default_list->ns, mailbox, FALSE);
-		} else if (strcmp(mailbox, "INBOX") != 0) {
+			(void)mailbox_create(box, NULL, FALSE);
+			mailbox_close(&box);
+			continue;
+		}
+
+		mailbox_close(&box);
+		if (error == MAIL_ERROR_TEMP)
+			return -1;
+
+		if (strcmp(mailbox, "INBOX") != 0) {
 			/* see if we can save to INBOX instead. */
 			mailbox = "INBOX";
 		} else {
diff -r 29733d23d903 -r 530bbade4e3f src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c	Thu Jun 25 14:33:37 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Fri Jun 26 16:11:59 2009 -0400
@@ -191,24 +191,6 @@ 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;
@@ -229,7 +211,8 @@ int dbox_read_header(struct dbox_mailbox
 }
 
 void dbox_update_header(struct dbox_mailbox *mbox,
-			struct mail_index_transaction *trans)
+			struct mail_index_transaction *trans,
+			const struct mailbox_update *update)
 {
 	struct dbox_index_header hdr, new_hdr;
 
@@ -237,7 +220,14 @@ void dbox_update_header(struct dbox_mail
 		memset(&hdr, 0, sizeof(hdr));
 
 	new_hdr = hdr;
-	dbox_set_mailbox_guid(&new_hdr);
+
+	if (update != NULL && !mailbox_guid_is_empty(update->mailbox_guid)) {
+		memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
+		       sizeof(new_hdr.mailbox_guid));
+	} else if (!mailbox_guid_is_empty(new_hdr.mailbox_guid)) {
+		mail_generate_guid_128(new_hdr.mailbox_guid);
+	}
+
 	new_hdr.map_uid_validity =
 		dbox_map_get_uid_validity(mbox->storage->map);
 	if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
@@ -246,23 +236,39 @@ void dbox_update_header(struct dbox_mail
 	}
 }
 
-static int dbox_write_index_header(struct mailbox *box)
+static int dbox_write_index_header(struct mailbox *box,
+				   const struct mailbox_update *update)
 {
 	struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
 	struct mail_index_transaction *trans;
-	uint32_t uid_validity;
+	const struct mail_index_header *hdr;
+	uint32_t uid_validity, uid_next;
 
 	if (dbox_map_open(mbox->storage->map, TRUE) < 0)
 		return -1;
 
+	hdr = mail_index_get_header(mbox->ibox.view);
 	trans = mail_index_transaction_begin(mbox->ibox.view, 0);
-	dbox_update_header(mbox, trans);
-
-	/* set uidvalidity */
-	uid_validity = dbox_get_uidvalidity_next(box->list);
-	mail_index_update_header(trans,
-		offsetof(struct mail_index_header, uid_validity),
-		&uid_validity, sizeof(uid_validity), TRUE);
+	dbox_update_header(mbox, trans, update);
+
+	if (update != NULL && update->uid_validity != 0)
+		uid_validity = update->uid_validity;
+	else if (hdr->uid_validity == 0) {
+		/* set uidvalidity */
+		uid_validity = dbox_get_uidvalidity_next(box->list);
+	}
+
+	if (hdr->uid_validity != uid_validity) {
+		mail_index_update_header(trans,
+			offsetof(struct mail_index_header, uid_validity),
+			&uid_validity, sizeof(uid_validity), TRUE);
+	}
+	if (update != NULL && hdr->next_uid < update->min_next_uid) {
+		uid_next = update->min_next_uid;
+		mail_index_update_header(trans,
+			offsetof(struct mail_index_header, next_uid),
+			&uid_next, sizeof(uid_next), TRUE);
+	}
 
 	if (mail_index_transaction_commit(&trans) < 0) {
 		mail_storage_set_internal_error(box->storage);
@@ -272,7 +278,8 @@ static int dbox_write_index_header(struc
 	return 0;
 }
 
-static int create_dbox(struct mailbox *box)
+static int dbox_mailbox_create_indexes(struct mailbox *box,
+				       const struct mailbox_update *update)
 {
 	struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
 	mode_t mode;
@@ -285,7 +292,7 @@ static int create_dbox(struct mailbox *b
 		if (index_storage_mailbox_open(box) < 0)
 			return -1;
 		mbox->creating = TRUE;
-		ret = dbox_write_index_header(box);
+		ret = dbox_write_index_header(box, update);
 		mbox->creating = FALSE;
 		if (ret < 0)
 			return -1;
@@ -336,7 +343,7 @@ int dbox_mailbox_open(struct mailbox *bo
 		if (strcmp(box->name, "INBOX") == 0 &&
 		    (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {


More information about the dovecot-cvs mailing list