dovecot-1.2: Subscription handling fixes for subscriptions=no na...

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 18 17:07:46 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/4296aa3fbb75
changeset: 8291:4296aa3fbb75
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Oct 18 17:07:42 2008 +0300
description:
Subscription handling fixes for subscriptions=no namespaces and shared mailboxes.

diffstat:

5 files changed, 61 insertions(+), 11 deletions(-)
src/imap/cmd-subscribe.c                          |   25 ++++++++++++++++----
src/lib-storage/index/shared/shared-storage.c     |    3 +-
src/lib-storage/list/mailbox-list-subscriptions.c |   26 +++++++++++++++++----
src/lib-storage/mail-namespace.c                  |   10 +++++++-
src/lib-storage/mail-namespace.h                  |    8 +++++-

diffs (149 lines):

diff -r 4402563ad86e -r 4296aa3fbb75 src/imap/cmd-subscribe.c
--- a/src/imap/cmd-subscribe.c	Sat Oct 18 16:26:04 2008 +0300
+++ b/src/imap/cmd-subscribe.c	Sat Oct 18 17:07:42 2008 +0300
@@ -27,19 +27,36 @@ static bool have_listable_namespace_pref
 
 bool cmd_subscribe_full(struct client_command_context *cmd, bool subscribe)
 {
-	struct mail_namespace *ns;
-	const char *mailbox, *verify_name;
+	struct mail_namespace *ns, *real_ns;
+	struct mail_storage *storage;
+	const char *mailbox, *verify_name, *real_name;
 
 	/* <mailbox> */
 	if (!client_read_string_args(cmd, 1, &mailbox))
 		return FALSE;
+	verify_name = mailbox;
 
-	verify_name = mailbox;
+	real_name = mailbox;
+	storage = client_find_storage(cmd, &real_name);
+	if (storage == NULL)
+		return TRUE;
+
+	/* now find a namespace where the subscription can be added to */
 	ns = mail_namespace_find_subscribable(cmd->client->user->namespaces,
 					      &mailbox);
 	if (ns == NULL) {
-		client_send_tagline(cmd, "NO Unknown namespace.");
+		client_send_tagline(cmd, "NO Unknown subscription namespace.");
 		return TRUE;
+	}
+
+	real_ns = mail_storage_get_namespace(storage);
+	if (ns != real_ns) {
+		/* subscription is being written to a different namespace
+		   than where the mailbox exists. */
+		mailbox = t_strconcat(real_ns->prefix, real_name, NULL);
+		/* drop the common prefix */
+		i_assert(strncmp(ns->prefix, mailbox, strlen(ns->prefix)) == 0);
+		mailbox += strlen(ns->prefix);
 	}
 
 	if ((client_workarounds & WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 &&
diff -r 4402563ad86e -r 4296aa3fbb75 src/lib-storage/index/shared/shared-storage.c
--- a/src/lib-storage/index/shared/shared-storage.c	Sat Oct 18 16:26:04 2008 +0300
+++ b/src/lib-storage/index/shared/shared-storage.c	Sat Oct 18 17:07:42 2008 +0300
@@ -181,7 +181,8 @@ int shared_storage_get_namespace(struct 
 	ns->type = NAMESPACE_SHARED;
 	ns->user = user;
 	ns->prefix = p_strdup(user->pool, str_c(prefix));
-	ns->flags = NAMESPACE_FLAG_LIST | NAMESPACE_FLAG_HIDDEN;
+	ns->flags = NAMESPACE_FLAG_LIST | NAMESPACE_FLAG_HIDDEN |
+		NAMESPACE_FLAG_AUTOCREATED;
 	ns->sep = _storage->ns->sep;
 
 	location = t_str_new(256);
diff -r 4402563ad86e -r 4296aa3fbb75 src/lib-storage/list/mailbox-list-subscriptions.c
--- a/src/lib-storage/list/mailbox-list-subscriptions.c	Sat Oct 18 16:26:04 2008 +0300
+++ b/src/lib-storage/list/mailbox-list-subscriptions.c	Sat Oct 18 17:07:42 2008 +0300
@@ -12,10 +12,12 @@ mailbox_list_subscriptions_fill_real(str
 				     struct imap_match_glob *glob,
 				     bool update_only)
 {
-	struct mail_namespace *ns = ctx->list->ns;
+	struct mail_namespace *default_ns = ctx->list->ns;
+	struct mail_namespace *namespaces = default_ns->user->namespaces;
 	struct mailbox_list_iter_update_context update_ctx;
 	struct subsfile_list_context *subsfile_ctx;
-	const char *path, *name;
+	struct mail_namespace *ns;
+	const char *path, *name, *name2, *full_name;
 	string_t *vname;
 
 	vname = t_str_new(256);
@@ -35,10 +37,26 @@ mailbox_list_subscriptions_fill_real(str
 	update_ctx.match_parents =
 		(ctx->flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0;
 
-	while ((name = subsfile_list_next(subsfile_ctx)) != NULL) {
+	while ((name = subsfile_list_next(subsfile_ctx)) != NULL) T_BEGIN {
+		full_name = name2 =
+			t_strconcat(default_ns->prefix, name, NULL);
+		ns = mail_namespace_find_unsubscribable(namespaces, &name2);
+		if (ns == NULL)
+			ns = default_ns;
+		else if (ns->type == NAMESPACE_SHARED &&
+			 (ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) {
+			/* we'll need to get the namespace autocreated. */
+			(void)mailbox_list_is_valid_existing_name(ns->list,
+								  name2);
+			name = full_name;
+			ns = mail_namespace_find_unsubscribable(namespaces,
+								&name);
+		} else {
+			name = name2;
+		}
 		name = mail_namespace_get_vname(ns, vname, name);
 		mailbox_list_iter_update(&update_ctx, name);
-	}
+	} T_END;
 	return subsfile_list_deinit(subsfile_ctx);
 }
 
diff -r 4402563ad86e -r 4296aa3fbb75 src/lib-storage/mail-namespace.c
--- a/src/lib-storage/mail-namespace.c	Sat Oct 18 16:26:04 2008 +0300
+++ b/src/lib-storage/mail-namespace.c	Sat Oct 18 17:07:42 2008 +0300
@@ -382,7 +382,15 @@ mail_namespace_find_subscribable(struct 
 {
 	return mail_namespace_find_mask(namespaces, mailbox,
 					NAMESPACE_FLAG_SUBSCRIPTIONS,
-					 NAMESPACE_FLAG_SUBSCRIPTIONS);
+					NAMESPACE_FLAG_SUBSCRIPTIONS);
+}
+
+struct mail_namespace *
+mail_namespace_find_unsubscribable(struct mail_namespace *namespaces,
+				   const char **mailbox)
+{
+	return mail_namespace_find_mask(namespaces, mailbox,
+					0, NAMESPACE_FLAG_SUBSCRIPTIONS);
 }
 
 struct mail_namespace *
diff -r 4402563ad86e -r 4296aa3fbb75 src/lib-storage/mail-namespace.h
--- a/src/lib-storage/mail-namespace.h	Sat Oct 18 16:26:04 2008 +0300
+++ b/src/lib-storage/mail-namespace.h	Sat Oct 18 17:07:42 2008 +0300
@@ -20,7 +20,9 @@ enum namespace_flags {
 	NAMESPACE_FLAG_SUBSCRIPTIONS	= 0x10,
 
 	/* Namespace is created for internal use only. */
-	NAMESPACE_FLAG_INTERNAL		= 0x1000
+	NAMESPACE_FLAG_INTERNAL		= 0x1000,
+	/* Namespace was created automatically (for shared mailboxes) */
+	NAMESPACE_FLAG_AUTOCREATED	= 0x2000
 };
 
 struct mail_namespace {
@@ -71,6 +73,10 @@ struct mail_namespace *
 struct mail_namespace *
 mail_namespace_find_subscribable(struct mail_namespace *namespaces,
 				 const char **mailbox);
+/* Like above, but find only from namespaces with subscriptions flag not set. */
+struct mail_namespace *
+mail_namespace_find_unsubscribable(struct mail_namespace *namespaces,
+				   const char **mailbox);
 /* Returns the INBOX namespace */
 struct mail_namespace *
 mail_namespace_find_inbox(struct mail_namespace *namespaces);


More information about the dovecot-cvs mailing list