dovecot-1.2: Added list=children option for namespaces.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Nov 21 17:03:31 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/659667d89f69
changeset: 8461:659667d89f69
user: Timo Sirainen <tss at iki.fi>
date: Fri Nov 21 17:03:27 2008 +0200
description:
Added list=children option for namespaces.
diffstat:
9 files changed, 97 insertions(+), 27 deletions(-)
src/imap/cmd-list.c | 26 +++++++++++++---
src/imap/cmd-subscribe.c | 3 +
src/lib-storage/index/shared/shared-list.c | 40 +++++++++++++++++++++++--
src/lib-storage/index/shared/shared-storage.c | 3 +
src/lib-storage/mail-namespace.c | 27 ++++++++++------
src/lib-storage/mail-namespace.h | 6 ++-
src/master/mail-process.c | 6 ++-
src/master/master-settings.c | 11 +++++-
src/master/master-settings.h | 2 -
diffs (truncated from 348 to 300 lines):
diff -r 8dfb193bb30c -r 659667d89f69 src/imap/cmd-list.c
--- a/src/imap/cmd-list.c Fri Nov 21 17:03:02 2008 +0200
+++ b/src/imap/cmd-list.c Fri Nov 21 17:03:27 2008 +0200
@@ -222,7 +222,7 @@ list_namespace_send_prefix(struct cmd_li
enum mailbox_info_flags flags;
const char *name;
string_t *str;
-
+
ctx->cur_ns_send_prefix = FALSE;
/* see if we already listed this as a valid mailbox in another
@@ -255,6 +255,19 @@ list_namespace_send_prefix(struct cmd_li
} else {
flags |= MAILBOX_NOCHILDREN;
}
+ }
+
+ if ((ctx->ns->flags & NAMESPACE_FLAG_LIST_CHILDREN) != 0) {
+ if (have_children) {
+ /* children are going to be listed. */
+ return;
+ }
+ if ((flags & MAILBOX_CHILDREN) == 0) {
+ /* namespace has no children. don't show it. */
+ return;
+ }
+ /* namespace has children but they don't match the list
+ pattern. the prefix itself matches though, so show it. */
}
name = ctx->cur_ns_skip_trailing_sep ?
@@ -504,8 +517,10 @@ list_want_send_prefix(struct cmd_list_co
if ((ctx->list_flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0)
return FALSE;
- /* send the prefix if namespace is listable.. */
- if ((ctx->ns->flags & NAMESPACE_FLAG_LIST) != 0)
+ /* send the prefix if namespace is listable. if children are listable
+ we may or may not need to send it. */
+ if ((ctx->ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+ NAMESPACE_FLAG_LIST_CHILDREN)) != 0)
return TRUE;
/* ..or if pattern is exactly the same as namespace prefix.
@@ -550,7 +565,8 @@ list_namespace_match_pattern(struct cmd_
}
/* hidden and non-listable namespaces are invisible to wildcards */
- if ((ns->flags & NAMESPACE_FLAG_LIST) == 0 &&
+ if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+ NAMESPACE_FLAG_LIST_CHILDREN)) == 0 &&
list_pattern_has_wildcards(cur_pattern))
return FALSE;
@@ -623,7 +639,7 @@ static void list_namespace_init(struct c
/* it's possible that the namespace prefix matched,
even though its children didn't */
if (ctx->cur_ns_send_prefix)
- list_namespace_send_prefix(ctx, TRUE);
+ list_namespace_send_prefix(ctx, FALSE);
return;
}
/* we should still list INBOX */
diff -r 8dfb193bb30c -r 659667d89f69 src/imap/cmd-subscribe.c
--- a/src/imap/cmd-subscribe.c Fri Nov 21 17:03:02 2008 +0200
+++ b/src/imap/cmd-subscribe.c Fri Nov 21 17:03:27 2008 +0200
@@ -10,7 +10,8 @@ static bool have_listable_namespace_pref
unsigned int name_len = strlen(name);
for (; ns != NULL; ns = ns->next) {
- if ((ns->flags & NAMESPACE_FLAG_LIST) == 0)
+ if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+ NAMESPACE_FLAG_LIST_CHILDREN)) == 0)
continue;
if (ns->prefix_len <= name_len)
diff -r 8dfb193bb30c -r 659667d89f69 src/lib-storage/index/shared/shared-list.c
--- a/src/lib-storage/index/shared/shared-list.c Fri Nov 21 17:03:02 2008 +0200
+++ b/src/lib-storage/index/shared/shared-list.c Fri Nov 21 17:03:27 2008 +0200
@@ -1,12 +1,16 @@
/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
+#include "imap-match.h"
#include "mailbox-list-private.h"
#include "index-storage.h"
#include "shared-storage.h"
struct shared_mailbox_list_iterate_context {
struct mailbox_list_iterate_context ctx;
+ struct mail_namespace *cur_ns;
+ struct imap_match_glob *glob;
+ struct mailbox_info info;
};
extern struct mailbox_list shared_mailbox_list;
@@ -149,8 +153,11 @@ shared_list_iter_init(struct mailbox_lis
ctx = i_new(struct shared_mailbox_list_iterate_context, 1);
ctx->ctx.list = list;
ctx->ctx.flags = flags;
-
- /* FIXME */
+ ctx->cur_ns = list->ns->user->namespaces;
+ ctx->info.ns = list->ns;
+ ctx->info.flags = MAILBOX_NONEXISTENT;
+ ctx->glob = imap_match_init_multiple(default_pool, patterns,
+ FALSE, list->ns->sep);
return &ctx->ctx;
}
@@ -159,7 +166,34 @@ shared_list_iter_next(struct mailbox_lis
{
struct shared_mailbox_list_iterate_context *ctx =
(struct shared_mailbox_list_iterate_context *)_ctx;
-
+ struct mail_namespace *ns = ctx->cur_ns;
+
+ for (; ns != NULL; ns = ns->next) {
+ if (ns->type != NAMESPACE_SHARED ||
+ (ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0)
+ continue;
+ if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+ NAMESPACE_FLAG_LIST_CHILDREN)) == 0)
+ continue;
+
+ if (ns->prefix_len < ctx->info.ns->prefix_len ||
+ strncmp(ns->prefix, ctx->info.ns->prefix,
+ ctx->info.ns->prefix_len) != 0)
+ continue;
+
+ /* visible and listable namespace under ourself, see if the
+ prefix matches without the trailing separator */
+ i_assert(ns->prefix_len > 0);
+ ctx->info.name = t_strndup(ns->prefix, ns->prefix_len - 1);
+ if ((_ctx->flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) == 0)
+ ctx->info.name += ctx->info.ns->prefix_len;
+ if (imap_match(ctx->glob, ctx->info.name) == IMAP_MATCH_YES) {
+ ctx->cur_ns = ns->next;
+ return &ctx->info;
+ }
+ }
+
+ ctx->cur_ns = NULL;
return NULL;
}
diff -r 8dfb193bb30c -r 659667d89f69 src/lib-storage/index/shared/shared-storage.c
--- a/src/lib-storage/index/shared/shared-storage.c Fri Nov 21 17:03:02 2008 +0200
+++ b/src/lib-storage/index/shared/shared-storage.c Fri Nov 21 17:03:27 2008 +0200
@@ -269,7 +269,7 @@ int shared_storage_get_namespace(struct
ns->type = NAMESPACE_SHARED;
ns->user = user;
ns->prefix = i_strdup(str_c(prefix));
- ns->flags = NAMESPACE_FLAG_LIST | NAMESPACE_FLAG_HIDDEN |
+ ns->flags = NAMESPACE_FLAG_LIST_PREFIX | NAMESPACE_FLAG_HIDDEN |
NAMESPACE_FLAG_AUTOCREATED;
ns->sep = _storage->ns->sep;
@@ -285,6 +285,7 @@ int shared_storage_get_namespace(struct
return -1;
}
mail_user_add_namespace(user, ns);
+ _storage->ns->flags |= NAMESPACE_FLAG_USABLE;
*_name = mail_namespace_fix_sep(ns, name);
*ns_r = ns;
diff -r 8dfb193bb30c -r 659667d89f69 src/lib-storage/mail-namespace.c
--- a/src/lib-storage/mail-namespace.c Fri Nov 21 17:03:02 2008 +0200
+++ b/src/lib-storage/mail-namespace.c Fri Nov 21 17:03:27 2008 +0200
@@ -39,19 +39,24 @@ namespace_add_env(const char *data, unsi
enum file_lock_method lock_method)
{
struct mail_namespace *ns;
- const char *sep, *type, *prefix, *driver, *error;
+ const char *sep, *type, *prefix, *driver, *error, *list;
ns = i_new(struct mail_namespace, 1);
sep = getenv(t_strdup_printf("NAMESPACE_%u_SEP", num));
type = getenv(t_strdup_printf("NAMESPACE_%u_TYPE", num));
prefix = getenv(t_strdup_printf("NAMESPACE_%u_PREFIX", num));
+ list = getenv(t_strdup_printf("NAMESPACE_%u_LIST", num));
if (getenv(t_strdup_printf("NAMESPACE_%u_INBOX", num)) != NULL)
ns->flags |= NAMESPACE_FLAG_INBOX;
if (getenv(t_strdup_printf("NAMESPACE_%u_HIDDEN", num)) != NULL)
ns->flags |= NAMESPACE_FLAG_HIDDEN;
- if (getenv(t_strdup_printf("NAMESPACE_%u_LIST", num)) != NULL)
- ns->flags |= NAMESPACE_FLAG_LIST;
+ if (list != NULL) {
+ if (strcmp(list, "children") == 0)
+ ns->flags |= NAMESPACE_FLAG_LIST_CHILDREN;
+ else
+ ns->flags |= NAMESPACE_FLAG_LIST_PREFIX;
+ }
if (getenv(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS", num)) != NULL)
ns->flags |= NAMESPACE_FLAG_SUBSCRIPTIONS;
@@ -76,7 +81,7 @@ namespace_add_env(const char *data, unsi
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",
+ list,
(ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) ?
"yes" : "no");
}
@@ -88,6 +93,7 @@ namespace_add_env(const char *data, unsi
if (ns->type == NAMESPACE_SHARED && strchr(ns->prefix, '%') != NULL) {
/* dynamic shared namespace */
+ ns->flags |= NAMESPACE_FLAG_INTERNAL;
driver = "shared";
} else {
driver = NULL;
@@ -124,14 +130,15 @@ static bool namespaces_check(struct mail
private_ns_count++;
}
if (*ns->prefix != '\0' &&
- (ns->flags & NAMESPACE_FLAG_LIST) != 0 &&
+ (ns->flags & NAMESPACE_FLAG_LIST_PREFIX) != 0 &&
ns->prefix[strlen(ns->prefix)-1] != ns->sep) {
i_error("namespace configuration error: "
"list=yes requires prefix=%s "
"to end with separator", ns->prefix);
return FALSE;
}
- if ((ns->flags & NAMESPACE_FLAG_LIST) != 0) {
+ if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+ NAMESPACE_FLAG_LIST_CHILDREN)) != 0) {
if (list_sep == '\0')
list_sep = ns->sep;
else if (list_sep != ns->sep) {
@@ -142,7 +149,7 @@ static bool namespaces_check(struct mail
}
}
if (*ns->prefix == '\0' &&
- (ns->flags & NAMESPACE_FLAG_LIST) == 0) {
+ (ns->flags & NAMESPACE_FLAG_LIST_PREFIX) == 0) {
i_error("namespace configuration error: "
"Empty prefix requires list=yes");
return FALSE;
@@ -236,7 +243,7 @@ int mail_namespaces_init(struct mail_use
ns = i_new(struct mail_namespace, 1);
ns->type = NAMESPACE_PRIVATE;
- ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST |
+ ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST_PREFIX |
NAMESPACE_FLAG_SUBSCRIPTIONS;
ns->prefix = i_strdup("");
ns->user = user;
@@ -270,7 +277,7 @@ mail_namespaces_init_empty(struct mail_u
ns = i_new(struct mail_namespace, 1);
ns->user = user;
ns->prefix = i_strdup("");
- ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST |
+ ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST_PREFIX |
NAMESPACE_FLAG_SUBSCRIPTIONS;
user->namespaces = ns;
return ns;
@@ -342,7 +349,7 @@ const char *mail_namespace_get_vname(str
char mail_namespace_get_root_sep(const struct mail_namespace *namespaces)
{
- while ((namespaces->flags & NAMESPACE_FLAG_LIST) == 0)
+ while ((namespaces->flags & NAMESPACE_FLAG_LIST_PREFIX) == 0)
namespaces = namespaces->next;
return namespaces->sep;
}
diff -r 8dfb193bb30c -r 659667d89f69 src/lib-storage/mail-namespace.h
--- a/src/lib-storage/mail-namespace.h Fri Nov 21 17:03:02 2008 +0200
+++ b/src/lib-storage/mail-namespace.h Fri Nov 21 17:03:27 2008 +0200
@@ -14,8 +14,10 @@ enum namespace_flags {
NAMESPACE_FLAG_INBOX = 0x01,
/* Namespace is visible only by explicitly using its full prefix */
NAMESPACE_FLAG_HIDDEN = 0x02,
- /* Namespace is visible with LIST */
- NAMESPACE_FLAG_LIST = 0x04,
+ /* Namespace prefix is visible with LIST */
+ NAMESPACE_FLAG_LIST_PREFIX = 0x04,
+ /* Namespace prefix isn't visible with LIST, but child mailboxes are */
+ NAMESPACE_FLAG_LIST_CHILDREN = 0x08,
/* Namespace uses its own subscriptions. */
NAMESPACE_FLAG_SUBSCRIPTIONS = 0x10,
diff -r 8dfb193bb30c -r 659667d89f69 src/master/mail-process.c
--- a/src/master/mail-process.c Fri Nov 21 17:03:02 2008 +0200
+++ b/src/master/mail-process.c Fri Nov 21 17:03:27 2008 +0200
@@ -279,8 +279,10 @@ env_put_namespace(struct namespace_setti
env_put(t_strdup_printf("NAMESPACE_%u_INBOX=1", i));
if (ns->hidden)
env_put(t_strdup_printf("NAMESPACE_%u_HIDDEN=1", i));
- if (ns->list)
- env_put(t_strdup_printf("NAMESPACE_%u_LIST=1", i));
+ if (strcmp(ns->list, "no") != 0) {
+ env_put(t_strdup_printf("NAMESPACE_%u_LIST=%s",
+ i, ns->list));
+ }
if (ns->subscriptions)
env_put(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS=1",
More information about the dovecot-cvs
mailing list