changeset 12656:b281619735c6

lib-storage: mailbox_exists() can now return if it's selectable or non-selectable.
author Timo Sirainen <tss@iki.fi>
date Sat, 12 Feb 2011 04:50:03 +0200
parents 28f43332ba12
children 03a8767cb9e5
files src/imap/cmd-subscribe.c src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/lib-storage/test-mailbox.c src/plugins/acl/acl-mailbox.c src/plugins/autocreate/autocreate-plugin.c
diffstat 9 files changed, 54 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/cmd-subscribe.c	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/imap/cmd-subscribe.c	Sat Feb 12 04:50:03 2011 +0200
@@ -8,13 +8,14 @@
 static bool
 subscribe_is_valid_name(struct client_command_context *cmd, struct mailbox *box)
 {
+	enum mailbox_existence existence;
 	int ret;
 
-	if ((ret = mailbox_exists(box)) < 0) {
+	if ((ret = mailbox_exists(box, &existence)) < 0) {
 		client_send_storage_error(cmd, mailbox_get_storage(box));
 		return FALSE;
 	}
-	if (ret == 0) {
+	if (existence == MAILBOX_EXISTENCE_NONE) {
 		client_send_tagline(cmd, t_strdup_printf(
 			"NO "MAIL_ERRSTR_MAILBOX_NOT_FOUND,
 			mailbox_get_vname(box)));
--- a/src/lib-storage/index/index-storage.c	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/lib-storage/index/index-storage.c	Sat Feb 12 04:50:03 2011 +0200
@@ -150,31 +150,44 @@
 					  box->index_prefix);
 }
 
-int index_storage_mailbox_exists(struct mailbox *box)
+int index_storage_mailbox_exists(struct mailbox *box,
+				 enum mailbox_existence *existence_r)
 {
 	struct stat st;
-	const char *path;
+	const char *path, *path2;
 
 	if (strcmp(box->name, "INBOX") == 0 &&
 	    (box->list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) {
 		/* INBOX always exists */
-		return 1;
+		*existence_r = MAILBOX_EXISTENCE_SELECT;
+		return 0;
 	}
 
+	/* see if it's selectable */
 	path = mailbox_list_get_path(box->list, box->name,
 				     MAILBOX_LIST_PATH_TYPE_MAILBOX);
-	if (stat(path, &st) == 0)
-		return 1;
-	else if (ENOTFOUND(errno) || errno == EACCES)
+	if (stat(path, &st) == 0) {
+		*existence_r = MAILBOX_EXISTENCE_SELECT;
 		return 0;
-	else {
+	}
+	if (!ENOTFOUND(errno) && errno != EACCES) {
 		mail_storage_set_critical(box->storage,
 					  "stat(%s) failed: %m", path);
 		return -1;
 	}
+
+	/* see if it's non-selectable */
+	path2 = mailbox_list_get_path(box->list, box->name,
+				      MAILBOX_LIST_PATH_TYPE_DIR);
+	if (strcmp(path, path2) != 0 &&
+	    stat(path2, &st) == 0) {
+		*existence_r = MAILBOX_EXISTENCE_NOSELECT;
+		return 0;
+	}
+	*existence_r = MAILBOX_EXISTENCE_NONE;
+	return 0;
 }
 
-
 int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory)
 {
 	struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
--- a/src/lib-storage/index/index-storage.h	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/lib-storage/index/index-storage.h	Sat Feb 12 04:50:03 2011 +0200
@@ -63,7 +63,8 @@
 void index_storage_mailbox_alloc(struct mailbox *box, const char *vname,
 				 enum mailbox_flags flags,
 				 const char *index_prefix);
-int index_storage_mailbox_exists(struct mailbox *box);
+int index_storage_mailbox_exists(struct mailbox *box,
+				 enum mailbox_existence *existence_r);
 int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory);
 int index_storage_mailbox_enable(struct mailbox *box,
 				 enum mailbox_feature feature);
--- a/src/lib-storage/mail-storage-private.h	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/lib-storage/mail-storage-private.h	Sat Feb 12 04:50:03 2011 +0200
@@ -106,7 +106,7 @@
 	bool (*allow_new_keywords)(struct mailbox *box);
 
 	int (*enable)(struct mailbox *box, enum mailbox_feature features);
-	int (*exists)(struct mailbox *box);
+	int (*exists)(struct mailbox *box, enum mailbox_existence *existence_r);
 	int (*open)(struct mailbox *box);
 	void (*close)(struct mailbox *box);
 	void (*free)(struct mailbox *box);
--- a/src/lib-storage/mail-storage.c	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/lib-storage/mail-storage.c	Sat Feb 12 04:50:03 2011 +0200
@@ -617,7 +617,7 @@
 	return FALSE;
 }
 
-int mailbox_exists(struct mailbox *box)
+int mailbox_exists(struct mailbox *box, enum mailbox_existence *existence_r)
 {
 	if (!mailbox_list_is_valid_existing_name(box->list, box->name)) {
 		mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS,
@@ -628,10 +628,11 @@
 	if (have_listable_namespace_prefix(box->storage->user->namespaces,
 					   box->vname)) {
 		/* listable namespace prefix always exists */
-		return 1;
+		*existence_r = MAILBOX_EXISTENCE_NOSELECT;
+		return 0;
 	}
 
-	return box->v.exists(box);
+	return box->v.exists(box, existence_r);
 }
 
 static int mailbox_check_mismatching_separators(struct mailbox *box)
--- a/src/lib-storage/mail-storage.h	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/lib-storage/mail-storage.h	Sat Feb 12 04:50:03 2011 +0200
@@ -56,6 +56,12 @@
 	MAILBOX_FEATURE_QRESYNC		= 0x02
 };
 
+enum mailbox_existence {
+	MAILBOX_EXISTENCE_NONE,
+	MAILBOX_EXISTENCE_NOSELECT,
+	MAILBOX_EXISTENCE_SELECT
+};
+
 enum mailbox_status_items {
 	STATUS_MESSAGES		= 0x01,
 	STATUS_RECENT		= 0x02,
@@ -343,9 +349,8 @@
    with possibly different readonly-state. */
 struct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname,
 			      enum mailbox_flags flags);
-/* Returns 1 if mailbox exists (even if it's unselectable),
-   0 if not and -1 if some error occurred. */
-int mailbox_exists(struct mailbox *box);
+/* Get mailbox existence state */
+int mailbox_exists(struct mailbox *box, enum mailbox_existence *existence_r);
 /* Open the mailbox. If this function isn't called explicitly, it's also called
    internally by lib-storage when necessary. */
 int mailbox_open(struct mailbox *box);
--- a/src/lib-storage/test-mailbox.c	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/lib-storage/test-mailbox.c	Sat Feb 12 04:50:03 2011 +0200
@@ -25,9 +25,11 @@
 	return 0;
 }
 
-static int test_mailbox_exists(struct mailbox *box ATTR_UNUSED)
+static int test_mailbox_exists(struct mailbox *box ATTR_UNUSED,
+			       enum mailbox_existence *existence_r)
 {
-	return 1;
+	*existence_r = MAILBOX_EXISTENCE_SELECT;
+	return 0;
 }
 
 static int test_mailbox_open(struct mailbox *box ATTR_UNUSED)
--- a/src/plugins/acl/acl-mailbox.c	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/plugins/acl/acl-mailbox.c	Sat Feb 12 04:50:03 2011 +0200
@@ -428,7 +428,8 @@
 	return abox->module_ctx.super.transaction_commit(ctx, changes_r);
 }
 
-static int acl_mailbox_exists(struct mailbox *box)
+static int acl_mailbox_exists(struct mailbox *box,
+			      enum mailbox_existence *existence_r)
 {
 	struct acl_mailbox *abox = ACL_CONTEXT(box);
 	const char *const *rights;
@@ -447,8 +448,9 @@
 		if (strcmp(rights[i], MAIL_ACL_LOOKUP) == 0 ||
 		    strcmp(rights[i], MAIL_ACL_READ) == 0 ||
 		    strcmp(rights[i], MAIL_ACL_INSERT) == 0)
-			return abox->module_ctx.super.exists(box);
+			return abox->module_ctx.super.exists(box, existence_r);
 	}
+	*existence_r = MAILBOX_EXISTENCE_NONE;
 	return 0;
 }
 
--- a/src/plugins/autocreate/autocreate-plugin.c	Sat Feb 12 00:48:47 2011 +0200
+++ b/src/plugins/autocreate/autocreate-plugin.c	Sat Feb 12 04:50:03 2011 +0200
@@ -133,14 +133,17 @@
 	return ret;
 }
 
-static int autocreate_mailbox_exists(struct mailbox *box)
+static int autocreate_mailbox_exists(struct mailbox *box,
+				     enum mailbox_existence *existence_r)
 {
 	union mailbox_module_context *abox = AUTOCREATE_CONTEXT(box);
 
-	if (is_autocreated(box->storage->user, box->vname))
-		return 1;
+	if (is_autocreated(box->storage->user, box->vname)) {
+		*existence_r = MAILBOX_EXISTENCE_SELECT;
+		return 0;
+	}
 
-	return abox->super.exists(box);
+	return abox->super.exists(box, existence_r);
 }
 
 static int