dovecot: Let lib-storage handle matching namespace prefixes as w...

dovecot at dovecot.org dovecot at dovecot.org
Sun Jul 15 09:25:16 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/92fabfda82f9
changeset: 6014:92fabfda82f9
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jul 15 09:21:55 2007 +0300
description:
Let lib-storage handle matching namespace prefixes as well.

diffstat:

4 files changed, 37 insertions(+), 131 deletions(-)
src/imap/cmd-list.c                               |  149 +++------------------
src/lib-storage/list/mailbox-list-fs-iter.c       |    4 
src/lib-storage/list/mailbox-list-maildir-iter.c  |    7 
src/lib-storage/list/mailbox-list-subscriptions.c |    8 +

diffs (truncated from 308 to 300 lines):

diff -r d094e8c0123a -r 92fabfda82f9 src/imap/cmd-list.c
--- a/src/imap/cmd-list.c	Sun Jul 15 09:20:55 2007 +0300
+++ b/src/imap/cmd-list.c	Sun Jul 15 09:21:55 2007 +0300
@@ -17,7 +17,6 @@ struct cmd_list_context {
 
 	struct mail_namespace *ns;
 	struct mailbox_list_iterate_context *list_iter;
-	struct imap_match_glob *glob;
 
 	ARRAY_DEFINE(ns_prefixes_listed, struct mail_namespace *);
 
@@ -255,34 +254,6 @@ list_namespace_send_prefix(struct cmd_li
 	client_send_line(ctx->cmd->client, str_c(str));
 }
 
-static bool
-list_insert_ns_prefix(string_t *name_str, struct cmd_list_context *ctx,
-		      const struct mailbox_info *info)
-{
-	if (strcasecmp(info->name, "INBOX") != 0) {
-		/* non-INBOX always has prefix */
-	} else if ((ctx->ns->flags & NAMESPACE_FLAG_INBOX) == 0) {
-		/* INBOX from non-INBOX namespace. */
-		if (*ctx->ns->prefix == '\0') {
-			/* no namespace prefix, we can't list this */
-			return FALSE;
-		}
-	} else if (!ctx->cur_ns_match_inbox) {
-		/* The pattern doesn't match INBOX (eg. prefix.%).
-		   We still want to list prefix.INBOX if it has
-		   children. Otherwise we don't want to list
-		   this INBOX at all. */
-		if ((info->flags & MAILBOX_CHILDREN) == 0)
-			return FALSE;
-	} else {
-		/* Listing INBOX from inbox=yes namespace.
-		   Don't insert the namespace prefix. */
-		return TRUE;
-	}
-	str_append(name_str, ctx->ns->prefix);
-	return TRUE;
-}
-
 static int
 list_namespace_mailboxes(struct cmd_list_context *ctx)
 {
@@ -297,29 +268,21 @@ list_namespace_mailboxes(struct cmd_list
 	str = t_str_new(256);
 	name_str = t_str_new(256);
 	while ((info = mailbox_list_iter_next(ctx->list_iter)) != NULL) {
-		str_truncate(name_str, 0);
-
-		if (!list_insert_ns_prefix(name_str, ctx, info))
-			continue;
-		str_append(name_str, info->name);
-
-		if (ctx->ns->sep != ctx->ns->real_sep) {
-                        char *p = str_c_modifiable(name_str);
-			for (; *p != '\0'; p++) {
+		if (ctx->ns->sep == ctx->ns->real_sep)
+			name = info->name;
+		else {
+			char *p;
+
+			str_truncate(name_str, 0);
+			str_append(name_str, info->name);
+			for (p = str_c_modifiable(name_str); *p != '\0'; p++) {
 				if (*p == ctx->ns->real_sep)
 					*p = ctx->ns->sep;
 			}
-		}
-		name = str_c(name_str);
+			name = str_c(name_str);
+		}
 		flags = info->flags;
 
-		if (*ctx->ns->prefix != '\0') {
-			/* With patterns containing '*' we do the checks here
-			   so prefix is included in matching */
-			if (ctx->glob != NULL &&
-			    imap_match(ctx->glob, name) != IMAP_MATCH_YES)
-				continue;
-		}
 		if (strcasecmp(name, "INBOX") == 0) {
 			i_assert((ctx->ns->flags & NAMESPACE_FLAG_INBOX) != 0);
 			if (ctx->inbox_found) {
@@ -503,59 +466,21 @@ list_use_inboxcase(struct cmd_list_conte
 	return ret;
 }
 
-static void
-skip_pattern_wildcard_prefix(const char *cur_ns_prefix, char sep,
-			     const char **cur_pattern_p)
-{
-	const char *cur_pattern = *cur_pattern_p;
-	unsigned int count;
-
-	for (count = 1; *cur_ns_prefix != '\0'; cur_ns_prefix++) {
-		if (*cur_ns_prefix == sep)
-			count++;
-	}
-
-	for (; count > 0; count--) {
-		/* skip over one hierarchy */
-		while (*cur_pattern != '\0' && *cur_pattern != '*' &&
-		       *cur_pattern != sep)
-			cur_pattern++;
-
-		if (*cur_pattern == '*') {
-			/* we'll just request "*" and filter it
-			   ourself. otherwise this gets too complex. */
-			cur_pattern = "*";
-			break;
-		}
-		if (*cur_pattern == '\0') {
-			/* pattern ended too early. we won't be listing
-			   any mailboxes. */
-			break;
-		}
-		cur_pattern++;
-	}
-
-	*cur_pattern_p = cur_pattern;
-}
-
 static bool
-list_namespace_init_pattern(struct cmd_list_context *ctx, bool inboxcase,
-			    const char *cur_ref, const char *cur_ns_prefix,
-			    const char **cur_pattern_p, bool *want_glob_r)
-{
+list_namespace_match_pattern(struct cmd_list_context *ctx, bool inboxcase,
+			     const char *cur_ref, const char *cur_ns_prefix,
+			     const char *cur_pattern)
+{
+	const char *orig_cur_pattern = cur_pattern;
 	struct mail_namespace *ns = ctx->ns;
 	struct imap_match_glob *pat_glob;
-	const char *cur_pattern = *cur_pattern_p;
 	enum imap_match_result match;
 	size_t len;
 
 	skip_namespace_prefix_pattern(ctx, &cur_ns_prefix,
 				      cur_ref, &cur_pattern);
-	if (*cur_ns_prefix == '\0') {
-		*want_glob_r = FALSE;
-		*cur_pattern_p = cur_pattern;
+	if (*cur_ns_prefix == '\0')
 		return TRUE;
-	}
 
 	/* namespace prefix still wasn't completely skipped over.
 	   for example cur_ns_prefix=INBOX/, pattern=%/% or pattern=IN%.
@@ -578,7 +503,7 @@ list_namespace_init_pattern(struct cmd_l
 		return FALSE;
 
 	/* check if this namespace prefix matches the current pattern */
-	pat_glob = imap_match_init(pool_datastack_create(), *cur_pattern_p,
+	pat_glob = imap_match_init(pool_datastack_create(), orig_cur_pattern,
 				   inboxcase, ns->sep);
 	match = imap_match(pat_glob, cur_ns_prefix);
 	if ((match & (IMAP_MATCH_YES | IMAP_MATCH_CHILDREN)) == 0)
@@ -589,29 +514,6 @@ list_namespace_init_pattern(struct cmd_l
 		/* the namespace prefix itself matches too. send it. */
 		ctx->cur_ns_send_prefix = TRUE;
 	}
-
-	/* We have now verified that the pattern matches the namespace prefix,
-	   so we'll just have to skip over as many hierarchies from pattern as
-	   there exists in namespace prefix. */
-	skip_pattern_wildcard_prefix(cur_ns_prefix, ns->sep, &cur_pattern);
-
-	if (*cur_pattern == '\0' && ctx->cur_ns_match_inbox) {
-		/* ns_prefix="INBOX/" and we wanted to list "%".
-		   This is an optimization to avoid doing an empty
-		   listing followed by another INBOX listing later. */
-		cur_pattern = "INBOX";
-		*want_glob_r = FALSE;
-	} else if (*cur_pattern != '*' || strcmp(*cur_pattern_p, "*") == 0) {
-		/* a) we don't have '*' in pattern
-		   b) we want to display everything
-
-		   we don't need to do separate filtering ourself */
-		*want_glob_r = FALSE;
-	} else {
-		*want_glob_r = TRUE;
-	}
-
-	*cur_pattern_p = cur_pattern;
 	return TRUE;
 }
 
@@ -621,7 +523,7 @@ static void list_namespace_init(struct c
 	const char *cur_ns_prefix, *cur_ref, *const *pat, *pattern;
 	enum imap_match_result inbox_match;
 	ARRAY_DEFINE(used_patterns, const char *);
-	bool inboxcase, want_glob = FALSE, want_any_glob = FALSE;
+	bool inboxcase;
 
 	cur_ns_prefix = ns->prefix;
 	cur_ref = ctx->ref;
@@ -650,13 +552,12 @@ static void list_namespace_init(struct c
 	t_array_init(&used_patterns, 16);
 	for (pat = ctx->patterns; *pat != NULL; pat++) {
 		pattern = *pat;
-		if (list_namespace_init_pattern(ctx, inboxcase, cur_ref,
-						cur_ns_prefix, &pattern,
-						&want_glob)) {
-			if (want_glob)
-				want_any_glob = TRUE;
+		/* see if pattern even has a chance of matching the
+		   namespace prefix */
+		if (list_namespace_match_pattern(ctx, inboxcase, cur_ref,
+						 cur_ns_prefix, pattern)) {
 			pattern = mailbox_list_join_refpattern(ns->list,
-				cur_ref, mail_namespace_fix_sep(ns, pattern));
+				ctx->ref, mail_namespace_fix_sep(ns, pattern));
 			array_append(&used_patterns, &pattern, 1);
 		}
 	}
@@ -665,10 +566,6 @@ static void list_namespace_init(struct c
 		return;
 	(void)array_append_space(&used_patterns); /* NULL-terminate */
 	pat = array_idx(&used_patterns, 0);
-
-	ctx->glob = !want_any_glob ? NULL :
-		imap_match_init_multiple(ctx->cmd->pool, pat,
-					 inboxcase, ns->sep);
 
 	cur_ref = mail_namespace_fix_sep(ns, cur_ref);
 	ctx->list_iter = mailbox_list_iter_init_multiple(ns->list, pat,
diff -r d094e8c0123a -r 92fabfda82f9 src/lib-storage/list/mailbox-list-fs-iter.c
--- a/src/lib-storage/list/mailbox-list-fs-iter.c	Sun Jul 15 09:20:55 2007 +0300
+++ b/src/lib-storage/list/mailbox-list-fs-iter.c	Sun Jul 15 09:21:55 2007 +0300
@@ -213,14 +213,14 @@ fs_list_iter_init(struct mailbox_list *_
 	}
 
 	path = mailbox_list_get_path(_list, NULL, MAILBOX_LIST_PATH_TYPE_DIR);
-	if ((ret = list_opendir(ctx, path, "", &dirp)) < 0)
+	if ((ret = list_opendir(ctx, path, _list->ns->prefix, &dirp)) < 0)
 		return &ctx->ctx;
 
 	if (ret > 0) {
 		ctx->dir = i_new(struct list_dir_context, 1);
 		ctx->dir->dirp = dirp;
 		ctx->dir->real_path = i_strdup(path);
-		ctx->dir->virtual_path = i_strdup("");
+		ctx->dir->virtual_path = i_strdup(_list->ns->prefix);
 	}
 	return &ctx->ctx;
 }
diff -r d094e8c0123a -r 92fabfda82f9 src/lib-storage/list/mailbox-list-maildir-iter.c
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c	Sun Jul 15 09:20:55 2007 +0300
+++ b/src/lib-storage/list/mailbox-list-maildir-iter.c	Sun Jul 15 09:21:55 2007 +0300
@@ -14,7 +14,7 @@ struct maildir_list_iterate_context {
 	struct mailbox_list_iterate_context ctx;
 	pool_t pool;
 
-	const char *dir, *prefix;
+	const char *dir;
 
         struct mailbox_tree_context *tree_ctx;
 	struct mailbox_tree_iterate_context *tree_iter;
@@ -117,7 +117,9 @@ maildir_fill_readdir(struct maildir_list
 
 		/* make sure the pattern matches */
 		str_truncate(mailbox, 0);
-		str_append(mailbox, ctx->prefix);
+		if ((ctx->ctx.list->ns->flags & NAMESPACE_FLAG_INBOX) != 0 &&
+		    strcasecmp(fname + 1, "INBOX") != 0)
+			str_append(mailbox, ctx->ctx.list->ns->prefix);
 		str_append(mailbox, fname + 1);
                 mailbox_c = str_c(mailbox);
 
@@ -221,7 +223,6 @@ maildir_list_iter_init(struct mailbox_li
 					_list->hierarchy_sep);
 
 	ctx->dir = _list->set.root_dir;
-	ctx->prefix = "";
 
 	if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) {
 		/* Listing only subscribed mailboxes.
diff -r d094e8c0123a -r 92fabfda82f9 src/lib-storage/list/mailbox-list-subscriptions.c
--- a/src/lib-storage/list/mailbox-list-subscriptions.c	Sun Jul 15 09:20:55 2007 +0300
+++ b/src/lib-storage/list/mailbox-list-subscriptions.c	Sun Jul 15 09:21:55 2007 +0300
@@ -29,6 +29,12 @@ mailbox_list_subscription_add(struct mai
 	enum imap_match_result match;
 	const char *p;
 	bool created;
+
+	if ((ctx->list->ns->flags & NAMESPACE_FLAG_INBOX) == 0 ||
+	    strcasecmp(name, "INBOX") != 0) {
+		/* add namespace prefix to all but INBOX */
+		name = t_strconcat(ctx->list->ns->prefix, name, NULL);
+	}
 
 	create_flags = (update_only ||
 			(ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0) ?
@@ -86,8 +92,10 @@ int mailbox_list_subscriptions_fill(stru
 	subsfile_ctx = subsfile_list_init(ctx->list, path);
 


More information about the dovecot-cvs mailing list