dovecot: Added subscriptions setting to namespaces to specify if...

dovecot at dovecot.org dovecot at dovecot.org
Sun Oct 21 19:59:13 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/afc28dd2d4c5
changeset: 6603:afc28dd2d4c5
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Oct 21 19:59:09 2007 +0300
description:
Added subscriptions setting to namespaces to specify if it should handle
subscriptions itself or if the parent namespace should handle them.

diffstat:

9 files changed, 76 insertions(+), 23 deletions(-)
dovecot-example.conf             |    4 ++
src/deliver/deliver.c            |   13 ++++++++-
src/imap/cmd-list.c              |    4 +-
src/imap/cmd-subscribe.c         |    3 +-
src/lib-storage/mail-namespace.c |   52 +++++++++++++++++++++++++++-----------
src/lib-storage/mail-namespace.h |   15 ++++++++--
src/master/mail-process.c        |    3 ++
src/master/master-settings.c     |    4 ++
src/master/master-settings.h     |    1 

diffs (truncated from 314 to 300 lines):

diff -r 3660e9cc06d2 -r afc28dd2d4c5 dovecot-example.conf
--- a/dovecot-example.conf	Sun Oct 21 19:57:03 2007 +0300
+++ b/dovecot-example.conf	Sun Oct 21 19:59:09 2007 +0300
@@ -257,6 +257,10 @@
    # Show the mailboxes under this namespace with LIST command. This makes the
    # namespace visible for clients that don't support NAMESPACE extension.
    #list = yes
+
+   # Namespace handles its own subscriptions. If set to "no", the parent
+   # namespace handles them (empty prefix should always have this as "yes")
+   #subscriptions = yes
 #}
 
 # System user and group used to access mails. If you use multiple, userdb
diff -r 3660e9cc06d2 -r afc28dd2d4c5 src/deliver/deliver.c
--- a/src/deliver/deliver.c	Sun Oct 21 19:57:03 2007 +0300
+++ b/src/deliver/deliver.c	Sun Oct 21 19:59:09 2007 +0300
@@ -223,7 +223,8 @@ static bool setting_is_bool(const char *
 	if (strncmp(name, "NAMESPACE_", 10) == 0) {
 		return strstr(name, "_list") != NULL ||
 			strstr(name, "_inbox") != NULL ||
-			strstr(name, "_hidden") != NULL;
+			strstr(name, "_hidden") != NULL ||
+			strstr(name, "_subscriptions") != NULL;
 	}
 	return FALSE;
 }
@@ -236,6 +237,7 @@ static void config_file_init(const char 
 	int fd, sections = 0;
 	bool lda_section = FALSE, pop3_section = FALSE, plugin_section = FALSE;
 	bool ns_section = FALSE, ns_location = FALSE, ns_list = FALSE;
+	bool ns_subscriptions = FALSE;
 	unsigned int ns_idx = 0;
 	size_t len;
 
@@ -319,6 +321,13 @@ static void config_file_init(const char 
 					env_put(t_strdup_printf(
 						"NAMESPACE_%u_LIST=1", ns_idx));
 				}
+				if (ns_subscriptions)
+					ns_subscriptions = FALSE;
+				else {
+					env_put(t_strdup_printf(
+						"NAMESPACE_%u_SUBSCRIPTIONS=1",
+						ns_idx));
+				}
 			}
 			continue;
 		}
@@ -341,6 +350,8 @@ static void config_file_init(const char 
 				} else {
 					if (strcmp(key, "list") == 0)
 						ns_list = TRUE;
+					if (strcmp(key, "subscriptions") == 0)
+						ns_subscriptions = TRUE;
 					key = t_strdup_printf("NAMESPACE_%u_%s",
 							      ns_idx, key);
 				}
diff -r 3660e9cc06d2 -r afc28dd2d4c5 src/imap/cmd-list.c
--- a/src/imap/cmd-list.c	Sun Oct 21 19:57:03 2007 +0300
+++ b/src/imap/cmd-list.c	Sun Oct 21 19:59:09 2007 +0300
@@ -594,9 +594,9 @@ static void list_namespace_init(struct c
 	cur_ns_prefix = ns->prefix;
 	cur_ref = ctx->ref;
 
-	if ((ns->flags & NAMESPACE_FLAG_HIDDEN) != 0 &&
+	if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0 &&
 	    (ctx->list_flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) {
-		/* ignore hidden namespaces */
+		/* ignore namespaces which don't have subscriptions */
 		return;
 	}
 
diff -r 3660e9cc06d2 -r afc28dd2d4c5 src/imap/cmd-subscribe.c
--- a/src/imap/cmd-subscribe.c	Sun Oct 21 19:57:03 2007 +0300
+++ b/src/imap/cmd-subscribe.c	Sun Oct 21 19:59:09 2007 +0300
@@ -16,7 +16,8 @@ bool cmd_subscribe_full(struct client_co
 		return FALSE;
 
 	verify_name = mailbox;
-	ns = mail_namespace_find_visible(cmd->client->namespaces, &mailbox);
+	ns = mail_namespace_find_subscribable(cmd->client->namespaces,
+					      &mailbox);
 	if (ns == NULL) {
 		client_send_tagline(cmd, "NO Unknown namespace.");
 		return TRUE;
diff -r 3660e9cc06d2 -r afc28dd2d4c5 src/lib-storage/mail-namespace.c
--- a/src/lib-storage/mail-namespace.c	Sun Oct 21 19:57:03 2007 +0300
+++ b/src/lib-storage/mail-namespace.c	Sun Oct 21 19:59:09 2007 +0300
@@ -45,6 +45,8 @@ namespace_add_env(pool_t pool, const cha
 		ns->flags |= NAMESPACE_FLAG_HIDDEN;
 	if (getenv(t_strdup_printf("NAMESPACE_%u_LIST", num)) != NULL)
 		ns->flags |= NAMESPACE_FLAG_LIST;
+	if (getenv(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS", num)) != NULL)
+		ns->flags |= NAMESPACE_FLAG_SUBSCRIPTIONS;
 
 	if (type == NULL || *type == '\0' || strncmp(type, "private", 7) == 0)
 		ns->type = NAMESPACE_PRIVATE;
@@ -62,11 +64,13 @@ namespace_add_env(pool_t pool, const cha
 
 	if ((flags & MAIL_STORAGE_FLAG_DEBUG) != 0) {
 		i_info("Namespace: type=%s, prefix=%s, sep=%s, "
-		       "inbox=%s, hidden=%s, list=%s",
+		       "inbox=%s, hidden=%s, list=%s, subscriptions=%s",
 		       type == NULL ? "" : type, prefix, sep == NULL ? "" : sep,
 		       (ns->flags & NAMESPACE_FLAG_INBOX) ? "yes" : "no",
 		       (ns->flags & NAMESPACE_FLAG_HIDDEN) ? "yes" : "no",
-		       (ns->flags & NAMESPACE_FLAG_LIST) ? "yes" : "no");
+		       (ns->flags & NAMESPACE_FLAG_LIST) ? "yes" : "no",
+		       (ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) ?
+		       "yes" : "no");
 	}
 
 	ns->prefix = p_strdup(pool, prefix);
@@ -86,6 +90,7 @@ static bool namespaces_check(struct mail
 {
 	struct mail_namespace *ns, *inbox_ns = NULL, *private_ns = NULL;
 	unsigned int private_ns_count = 0;
+	unsigned int subscriptions_count = 0;
 	char list_sep = '\0';
 
 	for (ns = namespaces; ns != NULL; ns = ns->next) {
@@ -126,6 +131,8 @@ static bool namespaces_check(struct mail
 				"Empty prefix requires list=yes");
 			return FALSE;
 		}
+		if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0)
+			subscriptions_count++;
 	}
 
 	if (inbox_ns == NULL) {
@@ -144,6 +151,11 @@ static bool namespaces_check(struct mail
 			"no list=yes namespaces");
 		return FALSE;
 	}
+	if (subscriptions_count == 0) {
+		i_error("namespace configuration error: "
+			"no subscriptions=yes namespaces");
+		return FALSE;
+	}
 	return TRUE;
 }
 
@@ -219,7 +231,8 @@ int mail_namespaces_init(pool_t pool, co
 
 	ns = p_new(pool, struct mail_namespace, 1);
 	ns->type = NAMESPACE_PRIVATE;
-	ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST;
+	ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST |
+		NAMESPACE_FLAG_SUBSCRIPTIONS;
 	ns->prefix = "";
 
 	if (mail_storage_create(ns, NULL, mail, user, flags, lock_method,
@@ -247,7 +260,8 @@ struct mail_namespace *mail_namespaces_i
 
 	ns = p_new(pool, struct mail_namespace, 1);
 	ns->prefix = "";
-	ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST;
+	ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST |
+		NAMESPACE_FLAG_SUBSCRIPTIONS;
 	return ns;
 }
 
@@ -286,11 +300,11 @@ char mail_namespace_get_root_sep(struct 
 }
 
 static struct mail_namespace *
-mail_namespace_find_int(struct mail_namespace *namespaces, const char **mailbox,
-			bool show_hidden)
-{
-#define CHECK_VISIBILITY(ns, show_hidden) \
-	(((ns)->flags & NAMESPACE_FLAG_HIDDEN) == 0 || (show_hidden))
+mail_namespace_find_mask(struct mail_namespace *namespaces,
+			 const char **mailbox,
+			 enum namespace_flags flags,
+			 enum namespace_flags mask)
+{
         struct mail_namespace *ns = namespaces;
 	const char *box = *mailbox;
 	struct mail_namespace *best = NULL;
@@ -303,7 +317,7 @@ mail_namespace_find_int(struct mail_name
 		*mailbox = "INBOX";
 		while (ns != NULL) {
 			if ((ns->flags & NAMESPACE_FLAG_INBOX) != 0 &&
-			    CHECK_VISIBILITY(ns, show_hidden))
+			    (ns->flags & mask) == flags)
 				return ns;
 			if (*ns->prefix == '\0')
 				best = ns;
@@ -317,7 +331,7 @@ mail_namespace_find_int(struct mail_name
 		    (strncmp(ns->prefix, box, ns->prefix_len) == 0 ||
 		     (inbox && strncmp(ns->prefix, "INBOX", 5) == 0 &&
 		      strncmp(ns->prefix+5, box+5, ns->prefix_len-5) == 0)) &&
-		    CHECK_VISIBILITY(ns, show_hidden)) {
+		    (ns->flags & mask) == flags) {
 			best = ns;
 			best_len = ns->prefix_len;
 		}
@@ -338,14 +352,24 @@ struct mail_namespace *
 struct mail_namespace *
 mail_namespace_find(struct mail_namespace *namespaces, const char **mailbox)
 {
-	return mail_namespace_find_int(namespaces, mailbox, TRUE);
+	return mail_namespace_find_mask(namespaces, mailbox, 0, 0);
 }
 
 struct mail_namespace *
 mail_namespace_find_visible(struct mail_namespace *namespaces,
 			    const char **mailbox)
 {
-	return mail_namespace_find_int(namespaces, mailbox, FALSE);
+	return mail_namespace_find_mask(namespaces, mailbox, 0,
+					NAMESPACE_FLAG_HIDDEN);
+}
+
+struct mail_namespace *
+mail_namespace_find_subscribable(struct mail_namespace *namespaces,
+				 const char **mailbox)
+{
+	return mail_namespace_find_mask(namespaces, mailbox,
+					NAMESPACE_FLAG_SUBSCRIPTIONS,
+					 NAMESPACE_FLAG_SUBSCRIPTIONS);
 }
 
 struct mail_namespace *
@@ -363,7 +387,7 @@ bool mail_namespace_update_name(struct m
 
 	/* FIXME: a bit kludgy.. */
 	tmp_ns.next = NULL;
-	return mail_namespace_find_int(&tmp_ns, mailbox, TRUE) != NULL;
+	return mail_namespace_find_mask(&tmp_ns, mailbox, 0, 0) != NULL;
 }
 
 struct mail_namespace *
diff -r 3660e9cc06d2 -r afc28dd2d4c5 src/lib-storage/mail-namespace.h
--- a/src/lib-storage/mail-namespace.h	Sun Oct 21 19:57:03 2007 +0300
+++ b/src/lib-storage/mail-namespace.h	Sun Oct 21 19:59:09 2007 +0300
@@ -9,13 +9,16 @@ enum namespace_type {
 
 enum namespace_flags {
 	/* Namespace contains the INBOX mailbox (there can be only one) */
-	NAMESPACE_FLAG_INBOX	= 0x01,
+	NAMESPACE_FLAG_INBOX		= 0x01,
 	/* Namespace is visible only by explicitly using its full prefix */
-	NAMESPACE_FLAG_HIDDEN	= 0x02,
+	NAMESPACE_FLAG_HIDDEN		= 0x02,
 	/* Namespace is visible with LIST */
-	NAMESPACE_FLAG_LIST	= 0x04,
+	NAMESPACE_FLAG_LIST		= 0x04,
+	/* Namespace uses its own subscriptions. */
+	NAMESPACE_FLAG_SUBSCRIPTIONS	= 0x10,
+
 	/* Namespace is created for internal use only. */
-	NAMESPACE_FLAG_INTERNAL	= 0x10
+	NAMESPACE_FLAG_INTERNAL		= 0x1000
 };
 
 struct mail_namespace {
@@ -56,6 +59,10 @@ struct mail_namespace *
 struct mail_namespace *
 mail_namespace_find_visible(struct mail_namespace *namespaces,
 			    const char **mailbox);
+/* Like above, but find only from namespaces with subscriptions flag set. */
+struct mail_namespace *
+mail_namespace_find_subscribable(struct mail_namespace *namespaces,
+				 const char **mailbox);
 /* Returns the INBOX namespace */
 struct mail_namespace *
 mail_namespace_find_inbox(struct mail_namespace *namespaces);
diff -r 3660e9cc06d2 -r afc28dd2d4c5 src/master/mail-process.c
--- a/src/master/mail-process.c	Sun Oct 21 19:57:03 2007 +0300
+++ b/src/master/mail-process.c	Sun Oct 21 19:59:09 2007 +0300
@@ -275,6 +275,9 @@ env_put_namespace(struct namespace_setti
 			env_put(t_strdup_printf("NAMESPACE_%u_HIDDEN=1", i));
 		if (ns->list)
 			env_put(t_strdup_printf("NAMESPACE_%u_LIST=1", i));
+		if (ns->subscriptions)
+			env_put(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS=1",
+						i));
 		t_pop();
 	}
 }
diff -r 3660e9cc06d2 -r afc28dd2d4c5 src/master/master-settings.c
--- a/src/master/master-settings.c	Sun Oct 21 19:57:03 2007 +0300
+++ b/src/master/master-settings.c	Sun Oct 21 19:59:09 2007 +0300
@@ -160,6 +160,7 @@ static struct setting_def namespace_sett
 	DEF_BOOL(inbox),
 	DEF_BOOL(hidden),
 	DEF_BOOL(list),
+	DEF_BOOL(subscriptions),
 
 	{ 0, NULL, 0 }
 };
@@ -352,7 +353,8 @@ struct namespace_settings default_namesp
 
 	MEMBER(inbox) FALSE,
 	MEMBER(hidden) FALSE,
-	MEMBER(list) TRUE
+	MEMBER(list) TRUE,
+	MEMBER(subscriptions) TRUE


More information about the dovecot-cvs mailing list