dovecot-2.0: lib-storage: STATUS_GUID moved to mailbox_get_guid(...

dovecot at dovecot.org dovecot at dovecot.org
Tue Feb 9 19:50:21 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/3609c8a35c36
changeset: 10685:3609c8a35c36
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Feb 09 19:50:17 2010 +0200
description:
lib-storage: STATUS_GUID moved to mailbox_get_guid() that can fail.

diffstat:

17 files changed, 130 insertions(+), 117 deletions(-)
src/dsync/dsync-worker-local.c                    |   25 +++----
src/imap/cmd-list.c                               |   13 ++--
src/imap/cmd-status.c                             |   10 +--
src/imap/imap-status.c                            |   68 +++++++++++----------
src/imap/imap-status.h                            |   21 ++++--
src/lib-storage/index/cydir/cydir-storage.c       |    1 
src/lib-storage/index/dbox-multi/mdbox-storage.c  |   25 ++-----
src/lib-storage/index/dbox-single/sdbox-storage.c |   25 ++-----
src/lib-storage/index/index-storage.c             |    7 +-
src/lib-storage/index/maildir/maildir-storage.c   |   14 +---
src/lib-storage/index/mbox/mbox-storage.c         |   15 +---
src/lib-storage/index/raw/raw-storage.c           |    1 
src/lib-storage/mail-storage-private.h            |    1 
src/lib-storage/mail-storage.c                    |   13 ++++
src/lib-storage/mail-storage.h                    |    6 -
src/lib-storage/test-mailbox.c                    |    1 
src/plugins/virtual/virtual-storage.c             |    1 

diffs (truncated from 650 to 300 lines):

diff -r e202b2b86702 -r 3609c8a35c36 src/dsync/dsync-worker-local.c
--- a/src/dsync/dsync-worker-local.c	Tue Feb 09 18:55:04 2010 +0200
+++ b/src/dsync/dsync-worker-local.c	Tue Feb 09 19:50:17 2010 +0200
@@ -471,6 +471,7 @@ local_worker_mailbox_iter_next(struct ds
 	const char *storage_name;
 	struct mailbox *box;
 	struct mailbox_status status;
+	uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
 	struct local_dsync_mailbox_change *change;
 	struct local_dsync_dir_change *dir_change;
 	const char *const *fields;
@@ -505,7 +506,8 @@ local_worker_mailbox_iter_next(struct ds
 	}
 
 	box = mailbox_alloc(info->ns->list, storage_name, NULL, flags);
-	if (mailbox_sync(box, 0) < 0) {
+	if (mailbox_sync(box, 0) < 0 ||
+	    mailbox_get_guid(box, mailbox_guid) < 0) {
 		struct mail_storage *storage = mailbox_get_storage(box);
 
 		i_error("Failed to sync mailbox %s: %s", info->name,
@@ -516,17 +518,15 @@ local_worker_mailbox_iter_next(struct ds
 	}
 
 	mailbox_get_status(box, STATUS_UIDNEXT | STATUS_UIDVALIDITY |
-			   STATUS_HIGHESTMODSEQ | STATUS_GUID |
-			   STATUS_CACHE_FIELDS, &status);
-
-	change = hash_table_lookup(worker->mailbox_changes_hash,
-				   status.mailbox_guid);
+			   STATUS_HIGHESTMODSEQ | STATUS_CACHE_FIELDS, &status);
+
+	change = hash_table_lookup(worker->mailbox_changes_hash, mailbox_guid);
 	if (change != NULL) {
 		/* it shouldn't be marked as deleted, but drop it to be sure */
 		change->deleted_mailbox = FALSE;
 	}
 
-	memcpy(dsync_box_r->mailbox_guid.guid, status.mailbox_guid,
+	memcpy(dsync_box_r->mailbox_guid.guid, mailbox_guid,
 	       sizeof(dsync_box_r->mailbox_guid.guid));
 	dsync_box_r->uid_validity = status.uidvalidity;
 	dsync_box_r->uid_next = status.uidnext;
@@ -691,7 +691,7 @@ static int local_mailbox_open(struct loc
 	enum mailbox_flags flags = MAILBOX_FLAG_KEEP_RECENT;
 	struct local_dsync_mailbox *lbox;
 	struct mailbox *box;
-	struct mailbox_status status;
+	uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
 
 	lbox = hash_table_lookup(worker->mailbox_hash, guid);
 	if (lbox == NULL) {
@@ -701,7 +701,8 @@ static int local_mailbox_open(struct loc
 	}
 
 	box = mailbox_alloc(lbox->ns->list, lbox->storage_name, NULL, flags);
-	if (mailbox_sync(box, 0) < 0) {
+	if (mailbox_sync(box, 0) < 0 ||
+	    mailbox_get_guid(box, mailbox_guid) < 0) {
 		struct mail_storage *storage = mailbox_get_storage(box);
 
 		i_error("Failed to sync mailbox %s: %s", lbox->storage_name,
@@ -710,12 +711,10 @@ static int local_mailbox_open(struct loc
 		return -1;
 	}
 
-	mailbox_get_status(box, STATUS_GUID, &status);
-	if (memcmp(status.mailbox_guid, guid->guid, sizeof(guid->guid)) != 0) {
+	if (memcmp(mailbox_guid, guid->guid, sizeof(guid->guid)) != 0) {
 		i_error("Mailbox %s changed its GUID (%s -> %s)",
 			lbox->storage_name, dsync_guid_to_str(guid),
-			binary_to_hex(status.mailbox_guid,
-				      sizeof(status.mailbox_guid)));
+			binary_to_hex(mailbox_guid, sizeof(mailbox_guid)));
 		mailbox_free(&box);
 		return -1;
 	}
diff -r e202b2b86702 -r 3609c8a35c36 src/imap/cmd-list.c
--- a/src/imap/cmd-list.c	Tue Feb 09 18:55:04 2010 +0200
+++ b/src/imap/cmd-list.c	Tue Feb 09 19:50:17 2010 +0200
@@ -15,7 +15,7 @@ struct cmd_list_context {
 	const char *ref;
 	const char *const *patterns;
 	enum mailbox_list_iter_flags list_flags;
-	enum mailbox_status_items status_items;
+	struct imap_status_items status_items;
 
 	struct mail_namespace *ns;
 	struct mailbox_list_iterate_context *list_iter;
@@ -30,6 +30,7 @@ struct cmd_list_context {
 	unsigned int cur_ns_send_prefix:1;
 	unsigned int cur_ns_skip_trailing_sep:1;
 	unsigned int used_listext:1;
+	unsigned int used_status:1;
 };
 
 static void
@@ -151,11 +152,11 @@ parse_return_flags(struct cmd_list_conte
 			list_flags |= MAILBOX_LIST_ITER_RETURN_CHILDREN;
 		else if (strcasecmp(atom, "STATUS") == 0 &&
 			 args[1].type == IMAP_ARG_LIST) {
-			/* FIXME: this should probably be a plugin.. */
 			if (imap_status_parse_items(ctx->cmd,
 						IMAP_ARG_LIST_ARGS(&args[1]),
 						&ctx->status_items) < 0)
 				return FALSE;
+			ctx->used_status = TRUE;
 			args++;
 		} else {
 			/* skip also optional list value */
@@ -326,18 +327,18 @@ list_namespace_send_prefix(struct cmd_li
 
 static void list_send_status(struct cmd_list_context *ctx, const char *name)
 {
-	struct mailbox_status status;
+	struct imap_status_result result;
 	const char *storage_name, *error;
 
 	storage_name = mail_namespace_get_storage_name(ctx->ns, name);
 	if (imap_status_get(ctx->cmd, ctx->ns, storage_name,
-			    ctx->status_items, &status, &error) < 0) {
+			    &ctx->status_items, &result, &error) < 0) {
 		client_send_line(ctx->cmd->client,
 				 t_strconcat("* ", error, NULL));
 		return;
 	}
 
-	imap_status_send(ctx->cmd->client, name, ctx->status_items, &status);
+	imap_status_send(ctx->cmd->client, name, &ctx->status_items, &result);
 }
 
 static int
@@ -399,7 +400,7 @@ list_namespace_mailboxes(struct cmd_list
 		mailbox_childinfo2str(ctx, str, flags);
 
 		ret = client_send_line(ctx->cmd->client, str_c(str));
-		if (ctx->status_items != 0 &&
+		if (ctx->used_status &&
 		    (flags & (MAILBOX_NONEXISTENT | MAILBOX_NOSELECT)) == 0) {
 			T_BEGIN {
 				list_send_status(ctx, name);
diff -r e202b2b86702 -r 3609c8a35c36 src/imap/cmd-status.c
--- a/src/imap/cmd-status.c	Tue Feb 09 18:55:04 2010 +0200
+++ b/src/imap/cmd-status.c	Tue Feb 09 19:50:17 2010 +0200
@@ -10,8 +10,8 @@ bool cmd_status(struct client_command_co
 {
 	struct client *client = cmd->client;
 	const struct imap_arg *args;
-	struct mailbox_status status;
-	enum mailbox_status_items items;
+	struct imap_status_items items;
+	struct imap_status_result result;
 	struct mail_namespace *ns;
 	const char *mailbox, *real_mailbox, *error;
 	bool selected_mailbox;
@@ -38,13 +38,13 @@ bool cmd_status(struct client_command_co
 
 	selected_mailbox = client->mailbox != NULL &&
 		mailbox_equals(client->mailbox, ns, real_mailbox);
-	if (imap_status_get(cmd, ns, real_mailbox, items,
-			    &status, &error) < 0) {
+	if (imap_status_get(cmd, ns, real_mailbox, &items,
+			    &result, &error) < 0) {
 		client_send_tagline(cmd, error);
 		return TRUE;
 	}
 
-	imap_status_send(client, mailbox, items, &status);
+	imap_status_send(client, mailbox, &items, &result);
 	if (!selected_mailbox)
 		client_send_tagline(cmd, "OK Status completed.");
 	else {
diff -r e202b2b86702 -r 3609c8a35c36 src/imap/imap-status.c
--- a/src/imap/imap-status.c	Tue Feb 09 18:55:04 2010 +0200
+++ b/src/imap/imap-status.c	Tue Feb 09 19:50:17 2010 +0200
@@ -8,11 +8,12 @@
 
 int imap_status_parse_items(struct client_command_context *cmd,
 			    const struct imap_arg *args,
-			    enum mailbox_status_items *items_r)
+			    struct imap_status_items *items_r)
 {
 	const char *item;
 	enum mailbox_status_items items;
 
+	memset(items_r, 0, sizeof(*items_r));
 	items = 0;
 	for (; args->type != IMAP_ARG_EOL; args++) {
 		if (args->type != IMAP_ARG_ATOM) {
@@ -37,7 +38,7 @@ int imap_status_parse_items(struct clien
 		else if (strcmp(item, "HIGHESTMODSEQ") == 0)
 			items |= STATUS_HIGHESTMODSEQ;
 		else if (strcmp(item, "X-GUID") == 0)
-			items |= STATUS_GUID;
+			items_r->guid = TRUE;
 		else {
 			client_send_tagline(cmd, t_strconcat(
 				"BAD Invalid status item ", item, NULL));
@@ -45,14 +46,14 @@ int imap_status_parse_items(struct clien
 		}
 	}
 
-	*items_r = items;
+	items_r->mailbox_items = items;
 	return 0;
 }
 
 int imap_status_get(struct client_command_context *cmd,
 		    struct mail_namespace *ns,
-		    const char *mailbox, enum mailbox_status_items items,
-		    struct mailbox_status *status_r, const char **error_r)
+		    const char *mailbox, const struct imap_status_items *items,
+		    struct imap_status_result *result_r, const char **error_r)
 {
 	struct client *client = cmd->client;
 	struct mailbox *box;
@@ -62,36 +63,43 @@ int imap_status_get(struct client_comman
 	if (client->mailbox != NULL &&
 	    mailbox_equals(client->mailbox, ns, mailbox)) {
 		/* this mailbox is selected */
-		mailbox_get_status(client->mailbox, items, status_r);
-		return TRUE;
+		box = client->mailbox;
+	} else {
+		/* open the mailbox */
+		box = mailbox_alloc(ns->list, mailbox, NULL,
+				    MAILBOX_FLAG_READONLY |
+				    MAILBOX_FLAG_KEEP_RECENT);
+		if (client->enabled_features != 0)
+			mailbox_enable(box, client->enabled_features);
 	}
 
-	/* open the mailbox */
-	box = mailbox_alloc(ns->list, mailbox, NULL, MAILBOX_FLAG_READONLY |
-			    MAILBOX_FLAG_KEEP_RECENT);
+	if ((items->mailbox_items & STATUS_HIGHESTMODSEQ) != 0)
+		client_enable(client, MAILBOX_FEATURE_CONDSTORE);
 
-	if ((items & STATUS_HIGHESTMODSEQ) != 0)
-		client_enable(client, MAILBOX_FEATURE_CONDSTORE);
-	if (client->enabled_features != 0)
-		mailbox_enable(box, client->enabled_features);
+	ret = box == client->mailbox ? 0 : mailbox_sync(box, 0);
+	if (ret == 0) {
+		mailbox_get_status(box, items->mailbox_items,
+				   &result_r->status);
+		if (items->guid)
+			ret = mailbox_get_guid(box, result_r->mailbox_guid);
+	}
 
-	ret = mailbox_sync(box, 0);
-	if (ret == 0)
-		mailbox_get_status(box, items, status_r);
-	else {
+	if (ret < 0) {
 		struct mail_storage *storage = mailbox_get_storage(box);
 
 		*error_r = mail_storage_get_last_error(storage, &error);
 		*error_r = imap_get_error_string(cmd, *error_r, error);
 	}
-	mailbox_free(&box);
+	if (box != client->mailbox)
+		mailbox_free(&box);
 	return ret;
 }
 
 void imap_status_send(struct client *client, const char *mailbox,
-		      enum mailbox_status_items items,
-		      const struct mailbox_status *status)
+		      const struct imap_status_items *items,
+		      const struct imap_status_result *result)
 {
+	const struct mailbox_status *status = &result->status;
 	string_t *str;
 
 	str = t_str_new(128);
@@ -99,24 +107,24 @@ void imap_status_send(struct client *cli
         imap_quote_append_string(str, mailbox, FALSE);
 	str_append(str, " (");
 
-	if (items & STATUS_MESSAGES)
+	if ((items->mailbox_items & STATUS_MESSAGES) != 0)
 		str_printfa(str, "MESSAGES %u ", status->messages);
-	if (items & STATUS_RECENT)
+	if ((items->mailbox_items & STATUS_RECENT) != 0)
 		str_printfa(str, "RECENT %u ", status->recent);
-	if (items & STATUS_UIDNEXT)
+	if ((items->mailbox_items & STATUS_UIDNEXT) != 0)
 		str_printfa(str, "UIDNEXT %u ", status->uidnext);
-	if (items & STATUS_UIDVALIDITY)
+	if ((items->mailbox_items & STATUS_UIDVALIDITY) != 0)
 		str_printfa(str, "UIDVALIDITY %u ", status->uidvalidity);
-	if (items & STATUS_UNSEEN)
+	if ((items->mailbox_items & STATUS_UNSEEN) != 0)
 		str_printfa(str, "UNSEEN %u ", status->unseen);
-	if (items & STATUS_HIGHESTMODSEQ) {
+	if ((items->mailbox_items & STATUS_HIGHESTMODSEQ) != 0) {
 		str_printfa(str, "HIGHESTMODSEQ %llu ",
 			    (unsigned long long)status->highest_modseq);
 	}


More information about the dovecot-cvs mailing list