dovecot-2.1: lib-storage: Added MAILBOX_LIST_ITER_LIST_PREFIXES ...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Feb 12 02:53:57 EET 2012
details: http://hg.dovecot.org/dovecot-2.1/rev/f5353573d3a0
changeset: 14112:f5353573d3a0
user: Timo Sirainen <tss at iki.fi>
date: Sun Feb 12 02:50:49 2012 +0200
description:
lib-storage: Added MAILBOX_LIST_ITER_LIST_PREFIXES flag.
diffstat:
src/lib-storage/mailbox-list-iter.c | 148 ++++++++++++++++++++++++++---------
src/lib-storage/mailbox-list.h | 3 +
2 files changed, 112 insertions(+), 39 deletions(-)
diffs (209 lines):
diff -r 53cf118fd16c -r f5353573d3a0 src/lib-storage/mailbox-list-iter.c
--- a/src/lib-storage/mailbox-list-iter.c Sun Feb 12 02:30:34 2012 +0200
+++ b/src/lib-storage/mailbox-list-iter.c Sun Feb 12 02:50:49 2012 +0200
@@ -39,8 +39,14 @@
pool_t pool;
const char **patterns, **patterns_ns_match;
enum namespace_type type_mask;
+
+ struct mail_namespace *iter_namespaces;
+ struct mailbox_info ns_info;
};
+static bool ns_match_next(struct ns_list_iterate_context *ctx,
+ struct mail_namespace *ns, const char *pattern);
+
struct mailbox_list_iterate_context *
mailbox_list_iter_init(struct mailbox_list *list, const char *pattern,
enum mailbox_list_iter_flags flags)
@@ -184,46 +190,10 @@
}
static bool
-ns_match_next(struct ns_list_iterate_context *ctx, struct mail_namespace *ns,
- const char *pattern)
+ns_is_match_within_ns(struct ns_list_iterate_context *ctx,
+ struct mail_namespace *ns, const char *prefix_without_sep,
+ const char *pattern, enum imap_match_result result)
{
- struct imap_match_glob *glob;
- enum imap_match_result result;
- const char *prefix_without_sep;
- unsigned int len;
-
- len = ns->prefix_len;
- if (len > 0 && ns->prefix[len-1] == mail_namespace_get_sep(ns))
- len--;
-
- if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
- NAMESPACE_FLAG_LIST_CHILDREN)) == 0) {
- /* non-listable namespace matches only with exact prefix */
- if (strncmp(ns->prefix, pattern, ns->prefix_len) != 0)
- return FALSE;
- }
-
- prefix_without_sep = t_strndup(ns->prefix, len);
- if (*prefix_without_sep == '\0')
- result = IMAP_MATCH_CHILDREN;
- else {
- glob = imap_match_init(pool_datastack_create(), pattern,
- TRUE, mail_namespace_get_sep(ns));
- result = imap_match(glob, prefix_without_sep);
- }
-
- if ((ctx->ctx.flags & MAILBOX_LIST_ITER_STAR_WITHIN_NS) == 0) {
- switch (result) {
- case IMAP_MATCH_YES:
- case IMAP_MATCH_CHILDREN:
- return TRUE;
- case IMAP_MATCH_NO:
- case IMAP_MATCH_PARENT:
- break;
- }
- return FALSE;
- }
-
switch (result) {
case IMAP_MATCH_YES:
/* allow matching prefix only when it's done without
@@ -255,6 +225,50 @@
return FALSE;
}
+static bool ns_match_next(struct ns_list_iterate_context *ctx,
+ struct mail_namespace *ns, const char *pattern)
+{
+ struct imap_match_glob *glob;
+ enum imap_match_result result;
+ const char *prefix_without_sep;
+ unsigned int len;
+
+ len = ns->prefix_len;
+ if (len > 0 && ns->prefix[len-1] == mail_namespace_get_sep(ns))
+ len--;
+
+ if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+ NAMESPACE_FLAG_LIST_CHILDREN)) == 0) {
+ /* non-listable namespace matches only with exact prefix */
+ if (strncmp(ns->prefix, pattern, ns->prefix_len) != 0)
+ return FALSE;
+ }
+
+ prefix_without_sep = t_strndup(ns->prefix, len);
+ if (*prefix_without_sep == '\0')
+ result = IMAP_MATCH_CHILDREN;
+ else {
+ glob = imap_match_init(pool_datastack_create(), pattern,
+ TRUE, mail_namespace_get_sep(ns));
+ result = imap_match(glob, prefix_without_sep);
+ }
+
+ if ((ctx->ctx.flags & MAILBOX_LIST_ITER_STAR_WITHIN_NS) != 0) {
+ return ns_is_match_within_ns(ctx, ns, prefix_without_sep,
+ pattern, result);
+ } else {
+ switch (result) {
+ case IMAP_MATCH_YES:
+ case IMAP_MATCH_CHILDREN:
+ return TRUE;
+ case IMAP_MATCH_NO:
+ case IMAP_MATCH_PARENT:
+ break;
+ }
+ return FALSE;
+ }
+}
+
static bool
ns_match(struct ns_list_iterate_context *ctx, struct mail_namespace *ns)
{
@@ -288,6 +302,49 @@
return ns;
}
+static bool
+iter_next_try_prefix_pattern(struct ns_list_iterate_context *ctx,
+ struct mail_namespace *ns, const char *pattern)
+{
+ struct imap_match_glob *glob;
+ enum imap_match_result result;
+ const char *prefix_without_sep;
+
+ i_assert(ns->prefix_len > 0);
+
+ if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+ NAMESPACE_FLAG_LIST_CHILDREN)) == 0) {
+ /* non-listable namespace matches only with exact prefix */
+ if (strncmp(ns->prefix, pattern, ns->prefix_len) != 0)
+ return FALSE;
+ }
+
+ prefix_without_sep = t_strndup(ns->prefix, ns->prefix_len-1);
+ glob = imap_match_init(pool_datastack_create(), pattern,
+ TRUE, mail_namespace_get_sep(ns));
+ result = imap_match(glob, prefix_without_sep);
+ return result == IMAP_MATCH_YES &&
+ ns_is_match_within_ns(ctx, ns, prefix_without_sep,
+ pattern, result);
+}
+
+static bool iter_next_try_prefix(struct ns_list_iterate_context *ctx,
+ struct mail_namespace *ns)
+{
+ unsigned int i;
+ bool ret = FALSE;
+
+ for (i = 0; ctx->patterns_ns_match[i] != NULL; i++) {
+ T_BEGIN {
+ ret = iter_next_try_prefix_pattern(ctx, ns,
+ ctx->patterns_ns_match[i]);
+ } T_END;
+ if (ret)
+ break;
+ }
+ return ret;
+}
+
static const struct mailbox_info *
mailbox_list_ns_iter_next(struct mailbox_list_iterate_context *_ctx)
{
@@ -295,6 +352,18 @@
(struct ns_list_iterate_context *)_ctx;
const struct mailbox_info *info;
+ while (ctx->iter_namespaces != NULL) {
+ struct mail_namespace *ns = ctx->iter_namespaces;
+
+ ctx->iter_namespaces = ns->next;
+ if (ns->prefix_len > 0 && iter_next_try_prefix(ctx, ns)) {
+ ctx->ns_info.ns = ns;
+ ctx->ns_info.name = p_strndup(ctx->pool, ns->prefix,
+ ns->prefix_len-1);
+ return &ctx->ns_info;
+ }
+ }
+
info = ctx->backend_ctx == NULL ? NULL :
mailbox_list_iter_next(ctx->backend_ctx);
if (info == NULL && ctx->namespaces != NULL) {
@@ -368,6 +437,7 @@
ctx->ctx.list = p_new(pool, struct mailbox_list, 1);
ctx->ctx.list->v.iter_next = mailbox_list_ns_iter_next;
ctx->ctx.list->v.iter_deinit = mailbox_list_ns_iter_deinit;
+ ctx->iter_namespaces = namespaces;
count = str_array_length(patterns);
ctx->patterns = p_new(pool, const char *, count + 1);
diff -r 53cf118fd16c -r f5353573d3a0 src/lib-storage/mailbox-list.h
--- a/src/lib-storage/mailbox-list.h Sun Feb 12 02:30:34 2012 +0200
+++ b/src/lib-storage/mailbox-list.h Sun Feb 12 02:50:49 2012 +0200
@@ -73,6 +73,9 @@
namespace prefixes, if there exists a parent namespace whose children
it matches. */
MAILBOX_LIST_ITER_STAR_WITHIN_NS = 0x000010,
+ /* For mailbox_list_iter_init_namespaces(): List also namespace
+ prefixes if they match */
+ MAILBOX_LIST_ITER_LIST_PREFIXES = 0x000020,
/* List only subscribed mailboxes */
MAILBOX_LIST_ITER_SELECT_SUBSCRIBED = 0x000100,
More information about the dovecot-cvs
mailing list