dovecot-2.2: lib-storage: Moved mailbox-list-iter.c to list/

dovecot at dovecot.org dovecot at dovecot.org
Tue Sep 4 16:23:48 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/72805776f84b
changeset: 15018:72805776f84b
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Sep 04 16:05:26 2012 +0300
description:
lib-storage: Moved mailbox-list-iter.c to list/

diffstat:

 src/lib-storage/Makefile.am              |     1 -
 src/lib-storage/list/Makefile.am         |     1 +
 src/lib-storage/list/mailbox-list-iter.c |  1052 ++++++++++++++++++++++++++++++
 src/lib-storage/mailbox-list-iter.c      |  1052 ------------------------------
 4 files changed, 1053 insertions(+), 1053 deletions(-)

diffs (truncated from 2134 to 300 lines):

diff -r 1d2122f10411 -r 72805776f84b src/lib-storage/Makefile.am
--- a/src/lib-storage/Makefile.am	Tue Sep 04 15:03:17 2012 +0300
+++ b/src/lib-storage/Makefile.am	Tue Sep 04 16:05:26 2012 +0300
@@ -42,7 +42,6 @@
 	mailbox-header.c \
 	mailbox-keywords.c \
 	mailbox-list.c \
-	mailbox-list-iter.c \
 	mailbox-list-notify.c \
 	mailbox-search-result.c \
 	mailbox-tree.c \
diff -r 1d2122f10411 -r 72805776f84b src/lib-storage/list/Makefile.am
--- a/src/lib-storage/list/Makefile.am	Tue Sep 04 15:03:17 2012 +0300
+++ b/src/lib-storage/list/Makefile.am	Tue Sep 04 16:05:26 2012 +0300
@@ -18,6 +18,7 @@
 	mailbox-list-index-notify.c \
 	mailbox-list-index-status.c \
 	mailbox-list-index-sync.c \
+	mailbox-list-iter.c \
 	mailbox-list-maildir.c \
 	mailbox-list-maildir-iter.c \
 	mailbox-list-none.c \
diff -r 1d2122f10411 -r 72805776f84b src/lib-storage/list/mailbox-list-iter.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/list/mailbox-list-iter.c	Tue Sep 04 16:05:26 2012 +0300
@@ -0,0 +1,1052 @@
+/* Copyright (c) 2006-2012 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "imap-match.h"
+#include "mail-storage.h"
+#include "mailbox-tree.h"
+#include "mailbox-list-private.h"
+
+enum autocreate_match_result {
+	/* list contains the mailbox */
+	AUTOCREATE_MATCH_RESULT_YES		= 0x01,
+	/* list contains children of the mailbox */
+	AUTOCREATE_MATCH_RESULT_CHILDREN	= 0x02,
+	/* list contains parents of the mailbox */
+	AUTOCREATE_MATCH_RESULT_PARENT		= 0x04
+};
+
+struct autocreate_box {
+	const char *name;
+	const struct mailbox_settings *set;
+	enum mailbox_info_flags flags;
+	bool child_listed;
+};
+
+ARRAY_DEFINE_TYPE(mailbox_settings, struct mailbox_settings *);
+struct mailbox_list_autocreate_iterate_context {
+	unsigned int idx;
+	struct mailbox_info new_info;
+	ARRAY(struct autocreate_box) boxes;
+	ARRAY_TYPE(mailbox_settings) box_sets;
+	ARRAY_TYPE(mailbox_settings) all_ns_box_sets;
+};
+
+struct ns_list_iterate_context {
+	struct mailbox_list_iterate_context ctx;
+	struct mailbox_list_iterate_context *backend_ctx;
+	struct mail_namespace *namespaces, *cur_ns;
+	struct mailbox_list *error_list;
+	pool_t pool;
+	const char **patterns, **patterns_ns_match;
+	enum mail_namespace_type type_mask;
+
+	struct mailbox_info ns_info;
+	struct mailbox_info inbox_info;
+	const struct mailbox_info *pending_backend_info;
+
+	unsigned int cur_ns_prefix_sent:1;
+	unsigned int inbox_list:1;
+	unsigned int inbox_listed:1;
+};
+
+static bool ns_match_next(struct ns_list_iterate_context *ctx, 
+			  struct mail_namespace *ns, const char *pattern);
+static int mailbox_list_match_anything(struct ns_list_iterate_context *ctx,
+				       struct mail_namespace *ns,
+				       const char *prefix);
+
+struct mailbox_list_iterate_context *
+mailbox_list_iter_init(struct mailbox_list *list, const char *pattern,
+		       enum mailbox_list_iter_flags flags)
+{
+	const char *patterns[2];
+
+	patterns[0] = pattern;
+	patterns[1] = NULL;
+	return mailbox_list_iter_init_multiple(list, patterns, flags);
+}
+
+static int mailbox_list_subscriptions_refresh(struct mailbox_list *list)
+{
+	struct mail_namespace *ns = list->ns;
+
+	if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0) {
+		/* no subscriptions in this namespace. find where they are. */
+		ns = mail_namespace_find_subscribable(ns->user->namespaces,
+						      ns->prefix);
+		if (ns == NULL) {
+			/* no subscriptions. avoid crashes by initializing
+			   a subscriptions tree. */
+			if (list->subscriptions == NULL) {
+				char sep = mail_namespace_get_sep(list->ns);
+				list->subscriptions = mailbox_tree_init(sep);
+			}
+			return 0;
+		}
+	}
+	return ns->list->v.subscriptions_refresh(ns->list, list);
+}
+
+static struct mailbox_settings *
+mailbox_settings_add_ns_prefix(pool_t pool, struct mail_namespace *ns,
+			       struct mailbox_settings *in_set)
+{
+	struct mailbox_settings *out_set;
+
+	if (ns->prefix_len == 0 || strcasecmp(in_set->name, "INBOX") == 0)
+		return in_set;
+
+	out_set = p_new(pool, struct mailbox_settings, 1);
+	*out_set = *in_set;
+	if (*in_set->name == '\0') {
+		/* namespace prefix itself */
+		out_set->name = p_strndup(pool, ns->prefix, ns->prefix_len-1);
+	} else {
+		out_set->name =
+			p_strconcat(pool, ns->prefix, in_set->name, NULL);
+	}
+	return out_set;
+}
+
+static void
+mailbox_list_iter_init_autocreate(struct mailbox_list_iterate_context *ctx)
+{
+	struct mail_namespace *ns = ctx->list->ns;
+	struct mailbox_list_autocreate_iterate_context *actx;
+	struct mailbox_settings *const *box_sets, *set;
+	struct autocreate_box *autobox;
+	unsigned int i, count;
+
+	if (!array_is_created(&ns->set->mailboxes))
+		return;
+	box_sets = array_get(&ns->set->mailboxes, &count);
+	if (count == 0)
+		return;
+
+	actx = p_new(ctx->pool, struct mailbox_list_autocreate_iterate_context, 1);
+	ctx->autocreate_ctx = actx;
+
+	/* build the list of mailboxes we need to consider as existing */
+	p_array_init(&actx->boxes, ctx->pool, 16);
+	p_array_init(&actx->box_sets, ctx->pool, 16);
+	p_array_init(&actx->all_ns_box_sets, ctx->pool, 16);
+	for (i = 0; i < count; i++) {
+		if (strcmp(box_sets[i]->autocreate, MAILBOX_SET_AUTO_NO) == 0)
+			continue;
+
+		set = mailbox_settings_add_ns_prefix(ctx->pool,
+						     ns, box_sets[i]);
+
+		/* autocreate mailbox belongs to listed namespace */
+		array_append(&actx->all_ns_box_sets, &set, 1);
+		if ((ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0 ||
+		    strcmp(set->autocreate, MAILBOX_SET_AUTO_SUBSCRIBE) == 0) {
+			array_append(&actx->box_sets, &set, 1);
+			autobox = array_append_space(&actx->boxes);
+			autobox->name = set->name;
+			autobox->set = set;
+		}
+	}
+}
+
+struct mailbox_list_iterate_context *
+mailbox_list_iter_init_multiple(struct mailbox_list *list,
+				const char *const *patterns,
+				enum mailbox_list_iter_flags flags)
+{
+	struct mailbox_list_iterate_context *ctx;
+	int ret = 0;
+
+	i_assert(*patterns != NULL);
+
+	if ((flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
+		      MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0)
+		ret = mailbox_list_subscriptions_refresh(list);
+
+	ctx = list->v.iter_init(list, patterns, flags);
+	if (ret < 0)
+		ctx->failed = TRUE;
+	else if ((flags & MAILBOX_LIST_ITER_NO_AUTO_BOXES) == 0)
+		mailbox_list_iter_init_autocreate(ctx);
+	return ctx;
+}
+
+static bool
+ns_match_simple(struct ns_list_iterate_context *ctx, struct mail_namespace *ns)
+{
+	if ((ctx->type_mask & ns->type) == 0)
+		return FALSE;
+
+	if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SKIP_ALIASES) != 0) {
+		if (ns->alias_for != NULL)
+			return FALSE;
+	}
+	return TRUE;
+}
+
+static bool
+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)
+{
+	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
+		   wildcards */
+		if (strcmp(prefix_without_sep, pattern) == 0)
+			return TRUE;
+		break;
+	case IMAP_MATCH_CHILDREN: {
+		/* allow this only if there isn't another namespace
+		   with longer prefix that matches this pattern
+		   (namespaces are sorted by prefix length) */
+		struct mail_namespace *tmp;
+
+		T_BEGIN {
+			for (tmp = ns->next; tmp != NULL; tmp = tmp->next) {
+				if (ns_match_simple(ctx, tmp) &&
+				    ns_match_next(ctx, tmp, pattern))
+					break;
+			}
+		} T_END;
+		if (tmp == NULL)
+			return TRUE;
+		break;
+	}
+	case IMAP_MATCH_NO:
+	case IMAP_MATCH_PARENT:
+		break;
+	}
+	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);
+	}
+
+	return ns_is_match_within_ns(ctx, ns, prefix_without_sep,
+				     pattern, result);
+}
+
+static bool
+mailbox_list_ns_match_patterns(struct ns_list_iterate_context *ctx)
+{
+	struct mail_namespace *ns = ctx->cur_ns;
+	unsigned int i;
+
+	if (!ns_match_simple(ctx, ns))


More information about the dovecot-cvs mailing list