Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8902:5ce33cfc568f HEAD
imap: Fixed LIST with namespace prefixes that have multiple hierarchies.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 02 Apr 2009 19:31:52 -0400 |
parents | 703214a10642 |
children | 20e6fa42d081 |
files | src/imap/cmd-list.c |
diffstat | 1 files changed, 44 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/cmd-list.c Thu Apr 02 19:09:32 2009 -0400 +++ b/src/imap/cmd-list.c Thu Apr 02 19:31:52 2009 -0400 @@ -214,6 +214,33 @@ return ret; } +static const char *ns_get_listed_prefix(struct cmd_list_context *ctx, + bool *have_children) +{ + struct imap_match_glob *glob; + enum imap_match_result match; + const char *ns_prefix, *p; + + glob = imap_match_init_multiple(pool_datastack_create(), + ctx->patterns, FALSE, ctx->ns->sep); + ns_prefix = ctx->ns->prefix; + match = imap_match(glob, ns_prefix); + if (match == IMAP_MATCH_YES) { + return !ctx->cur_ns_skip_trailing_sep ? ns_prefix : + t_strndup(ns_prefix, strlen(ns_prefix)-1); + } + + while ((match & IMAP_MATCH_PARENT) != 0) { + p = strrchr(ns_prefix, ctx->ns->sep); + i_assert(p != NULL); + ns_prefix = t_strdup_until(ns_prefix, p); + match = imap_match(glob, ns_prefix); + } + i_assert(match == IMAP_MATCH_YES); + *have_children = TRUE; + return ns_prefix; +} + static void list_namespace_send_prefix(struct cmd_list_context *ctx, bool have_children) { @@ -248,6 +275,8 @@ flags = MAILBOX_NONEXISTENT; } + name = ns_get_listed_prefix(ctx, &have_children); + if ((flags & MAILBOX_CHILDREN) == 0) { if (have_children || list_namespace_has_children(ctx)) { flags |= MAILBOX_CHILDREN; @@ -270,9 +299,6 @@ pattern. the prefix itself matches though, so show it. */ } - name = ctx->cur_ns_skip_trailing_sep ? - t_strndup(ctx->ns->prefix, len-1) : ctx->ns->prefix; - str = t_str_new(128); str_append(str, "* LIST ("); mailbox_flags2str(ctx, str, flags); @@ -584,6 +610,21 @@ if (*p == '*') return TRUE; } + } else { + while ((match & IMAP_MATCH_PARENT) != 0) { + p = strrchr(cur_ns_prefix, ns->sep); + if (p == NULL) + break; + cur_ns_prefix = t_strdup_until(cur_ns_prefix, p); + match = imap_match(pat_glob, cur_ns_prefix); + } + if (match == IMAP_MATCH_YES && + mail_namespace_find_prefix_nosep(ns->user->namespaces, + cur_ns_prefix) == NULL) { + /* ns prefix="foo/bar/" and we're listing e.g. % */ + if (list_want_send_prefix(ctx, orig_cur_pattern)) + ctx->cur_ns_send_prefix = TRUE; + } } return (match & IMAP_MATCH_CHILDREN) != 0;