dovecot-2.0: fs layout: Mailbox listing returned duplicates when...

dovecot at dovecot.org dovecot at dovecot.org
Tue Feb 28 05:11:08 EET 2012


details:   http://hg.dovecot.org/dovecot-2.0/rev/8f0c49f98e07
changeset: 13062:8f0c49f98e07
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Feb 28 05:10:41 2012 +0200
description:
fs layout: Mailbox listing returned duplicates when patterns contained a parent and its children.
This is an ugly patch to fix at least the most obvious cases. It's fixed
properly in v2.1 code.

diffstat:

 src/lib-storage/list/mailbox-list-fs-iter.c |  26 ++++++++++++++++++++++----
 1 files changed, 22 insertions(+), 4 deletions(-)

diffs (73 lines):

diff -r b7e5a83866a4 -r 8f0c49f98e07 src/lib-storage/list/mailbox-list-fs-iter.c
--- a/src/lib-storage/list/mailbox-list-fs-iter.c	Sat Feb 25 07:29:15 2012 +0200
+++ b/src/lib-storage/list/mailbox-list-fs-iter.c	Tue Feb 28 05:10:41 2012 +0200
@@ -36,6 +36,7 @@
 	struct mailbox_list_iterate_context ctx;
 
 	ARRAY_DEFINE(valid_patterns, char *);
+	bool *patterns_used;
 	struct imap_match_glob *glob;
 	struct mailbox_tree_context *subs_tree;
 	struct mailbox_tree_iterate_context *tree_iter;
@@ -250,6 +251,7 @@
 		}
 	}
 	(void)array_append_space(&ctx->valid_patterns); /* NULL-terminate */
+	ctx->patterns_used = i_new(bool, array_count(&ctx->valid_patterns));
 
 	if (array_count(&ctx->valid_patterns) == 1) {
 		/* we've only invalid patterns (or INBOX) */
@@ -337,6 +339,7 @@
 		pool_unref(&ctx->info_pool);
 	if (ctx->glob != NULL)
 		imap_match_deinit(&ctx->glob);
+	i_free(ctx->patterns_used);
 	i_free(ctx);
 
 	return ret;
@@ -560,7 +563,9 @@
 	struct mail_namespace *ns = ctx->ctx.list->ns;
 	const char *fname = entry->fname;
 	const char *list_path, *root_dir;
+	char *const *valid_patterns;
 	enum imap_match_result match;
+	unsigned int i;
 	struct stat st;
 	int ret;
 
@@ -598,6 +603,17 @@
 	if (ret <= 0)
 		return ret;
 
+	/* ugly workaround to avoid duplicates with: a list "" (foo foo/bar)
+	   this is fixed properly in v2.1 listing code */
+	valid_patterns = array_idx(&ctx->valid_patterns, 0);
+	for (i = 0; valid_patterns[i] != NULL; i++) {
+		if (!ctx->patterns_used[i] &&
+		    strcmp(valid_patterns[i], list_path) == 0) {
+			ctx->patterns_used[i] = TRUE;
+			break;
+		}
+	}
+
 	if (ctx->dir->delayed_send) {
 		/* send the parent directory first, then handle this
 		   file again if needed */
@@ -726,11 +742,13 @@
 
 	for (;;) {
 		patterns = array_idx(&ctx->valid_patterns, 0);
-		if (patterns[dir->pattern_pos] == NULL)
-			return NULL;
+		do {
+			if (patterns[dir->pattern_pos] == NULL)
+				return NULL;
 
-		patterns += dir->pattern_pos;
-		dir->pattern_pos++;
+			patterns += dir->pattern_pos;
+			dir->pattern_pos++;
+		} while (ctx->patterns_used[dir->pattern_pos-1]);
 
 		ret = pattern_get_path_pos(ctx, *patterns, dir->virtual_path,
 					   &pos);


More information about the dovecot-cvs mailing list