dovecot: Fixes to handling namespace prefixes and real!=virtual ...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Oct 28 01:53:36 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/e1fde9940f7e
changeset: 6639:e1fde9940f7e
user: Timo Sirainen <tss at iki.fi>
date: Sun Oct 28 01:53:32 2007 +0300
description:
Fixes to handling namespace prefixes and real!=virtual separator. Added a
new MAILBOX_LIST_ITER_VIRTUAL_NAMES which specifies if mailbox listing
should be using virtual or real mailbox names.
diffstat:
10 files changed, 220 insertions(+), 188 deletions(-)
src/imap/cmd-list.c | 5
src/lib-storage/list/mailbox-list-fs-iter.c | 52 +++++-----
src/lib-storage/list/mailbox-list-maildir-iter.c | 80 ++++++++-------
src/lib-storage/list/mailbox-list-subscriptions.c | 107 ++-------------------
src/lib-storage/mail-namespace.c | 18 +++
src/lib-storage/mail-namespace.h | 5
src/lib-storage/mailbox-list-private.h | 7 +
src/lib-storage/mailbox-list.c | 76 ++++++++++++++
src/lib-storage/mailbox-list.h | 3
src/plugins/acl/acl-mailbox-list.c | 55 +++++-----
diffs (truncated from 787 to 300 lines):
diff -r e2a4722f1b9b -r e1fde9940f7e src/imap/cmd-list.c
--- a/src/imap/cmd-list.c Sun Oct 28 01:52:00 2007 +0300
+++ b/src/imap/cmd-list.c Sun Oct 28 01:53:32 2007 +0300
@@ -819,14 +819,15 @@ bool cmd_list_full(struct client_command
args += 2;
}
+ ctx->list_flags = MAILBOX_LIST_ITER_VIRTUAL_NAMES;
if (lsub) {
/* LSUB - we don't care about flags */
- ctx->list_flags = MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
+ ctx->list_flags |= MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH |
MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
} else if (!ctx->used_listext) {
/* non-extended LIST - return children flags always */
- ctx->list_flags = MAILBOX_LIST_ITER_RETURN_CHILDREN;
+ ctx->list_flags |= MAILBOX_LIST_ITER_RETURN_CHILDREN;
}
if (args[0].type != IMAP_ARG_EOL) {
diff -r e2a4722f1b9b -r e1fde9940f7e src/lib-storage/list/mailbox-list-fs-iter.c
--- a/src/lib-storage/list/mailbox-list-fs-iter.c Sun Oct 28 01:52:00 2007 +0300
+++ b/src/lib-storage/list/mailbox-list-fs-iter.c Sun Oct 28 01:53:32 2007 +0300
@@ -30,6 +30,7 @@ struct fs_list_iterate_context {
struct imap_match_glob *glob;
struct mailbox_tree_context *subs_tree;
struct mailbox_tree_iterate_context *tree_iter;
+ char sep;
enum mailbox_info_flags inbox_flags;
@@ -50,19 +51,19 @@ fs_list_next(struct fs_list_iterate_cont
fs_list_next(struct fs_list_iterate_context *ctx);
static int
-pattern_get_path_pos(struct mail_namespace *ns, const char *pattern,
+pattern_get_path_pos(struct fs_list_iterate_context *ctx, const char *pattern,
const char *path, unsigned int *pos_r)
{
unsigned int i, j;
- if (strncasecmp(path, "INBOX", 5) == 0 && path[5] == ns->sep) {
+ if (strncasecmp(path, "INBOX", 5) == 0 && path[5] == ctx->sep) {
/* make sure INBOX prefix is matched case-insensitively */
char *tmp = t_strdup_noconst(pattern);
if (strncmp(path, "INBOX", 5) != 0)
- path = t_strdup_printf("INBOX%c%s", ns->sep, path + 6);
-
- for (i = 0; tmp[i] != ns->sep && tmp[i] != '\0'; i++)
+ path = t_strdup_printf("INBOX%c%s", ctx->sep, path + 6);
+
+ for (i = 0; tmp[i] != ctx->sep && tmp[i] != '\0'; i++)
tmp[i] = i_toupper(tmp[i]);
pattern = tmp;
}
@@ -73,13 +74,13 @@ pattern_get_path_pos(struct mail_namespa
if (pattern[j] == '%') {
/* skip until we're at the next hierarchy separator */
- if (path[i] == ns->sep) {
+ if (path[i] == ctx->sep) {
/* assume that pattern matches. we can't be
sure, but it'll be checked later. */
for (j++; pattern[j] != '\0'; j++) {
if (pattern[j] == '*')
return -1;
- if (pattern[j] == ns->sep) {
+ if (pattern[j] == ctx->sep) {
j++;
break;
}
@@ -98,18 +99,18 @@ pattern_get_path_pos(struct mail_namespa
}
static bool
-pattern_has_wildcard_at(struct mail_namespace *ns, const char *pattern,
- const char *path)
+pattern_has_wildcard_at(struct fs_list_iterate_context *ctx,
+ const char *pattern, const char *path)
{
unsigned int pos;
int ret;
- if ((ret = pattern_get_path_pos(ns, pattern, path, &pos)) < 0)
+ if ((ret = pattern_get_path_pos(ctx, pattern, path, &pos)) < 0)
return TRUE;
if (ret == 0)
return FALSE;
- for (; pattern[pos] != '\0' && pattern[pos] != ns->sep; pos++) {
+ for (; pattern[pos] != '\0' && pattern[pos] != ctx->sep; pos++) {
if (pattern[pos] == '%' || pattern[pos] == '*')
return TRUE;
}
@@ -128,8 +129,7 @@ static int list_opendir(struct fs_list_i
t_push();
patterns = array_idx(&ctx->valid_patterns, 0);
for (i = 0; patterns[i] != NULL; i++) {
- if (pattern_has_wildcard_at(ctx->ctx.list->ns,
- patterns[i], list_path))
+ if (pattern_has_wildcard_at(ctx, patterns[i], list_path))
break;
}
t_pop();
@@ -164,7 +164,7 @@ fs_list_iter_init(struct mailbox_list *_
enum mailbox_list_iter_flags flags)
{
struct fs_list_iterate_context *ctx;
- const char *path;
+ const char *path, *vpath;
char *pattern;
DIR *dirp;
int ret;
@@ -174,6 +174,8 @@ fs_list_iter_init(struct mailbox_list *_
ctx->ctx.flags = flags;
ctx->info_pool = pool_alloconly_create("fs list", 1024);
ctx->next = fs_list_next;
+ ctx->sep = (flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) != 0 ?
+ _list->ns->sep : _list->ns->real_sep;
i_array_init(&ctx->valid_patterns, 8);
for (; *patterns != NULL; patterns++) {
@@ -195,15 +197,14 @@ fs_list_iter_init(struct mailbox_list *_
}
patterns = (const void *)array_idx(&ctx->valid_patterns, 0);
ctx->glob = imap_match_init_multiple(default_pool, patterns, TRUE,
- _list->ns->sep);
+ ctx->sep);
if ((flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0) {
/* we want to return MAILBOX_SUBSCRIBED flags, possibly for all
mailboxes. Build a mailbox tree of all the subscriptions. */
- ctx->subs_tree = mailbox_tree_init(_list->ns->sep);
- if (mailbox_list_subscriptions_fill(&ctx->ctx,
- ctx->subs_tree,
+ ctx->subs_tree = mailbox_tree_init(ctx->sep);
+ if (mailbox_list_subscriptions_fill(&ctx->ctx, ctx->subs_tree,
ctx->glob, FALSE) < 0) {
ctx->ctx.failed = TRUE;
return &ctx->ctx;
@@ -217,15 +218,17 @@ fs_list_iter_init(struct mailbox_list *_
return &ctx->ctx;
}
+ vpath = (flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) != 0 ?
+ _list->ns->prefix : "";
path = mailbox_list_get_path(_list, NULL, MAILBOX_LIST_PATH_TYPE_DIR);
- if ((ret = list_opendir(ctx, path, _list->ns->prefix, &dirp)) < 0)
+ if ((ret = list_opendir(ctx, path, vpath, &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(_list->ns->prefix);
+ ctx->dir->virtual_path = i_strdup(vpath);
}
return &ctx->ctx;
}
@@ -411,7 +414,7 @@ list_file(struct fs_list_iterate_context
if ((ctx->info.flags & MAILBOX_NOINFERIORS) == 0) {
/* subdirectory. scan inside it. */
- vpath = t_strdup_printf("%s%c", list_path, ns->sep);
+ vpath = t_strdup_printf("%s%c", list_path, ctx->sep);
match2 = imap_match(ctx->glob, vpath);
if (match == IMAP_MATCH_YES)
@@ -428,7 +431,7 @@ list_file(struct fs_list_iterate_context
dir->dirp = dirp;
dir->real_path = i_strdup(real_path);
dir->virtual_path =
- i_strdup_printf("%s%c", list_path, ns->sep);
+ i_strdup_printf("%s%c", list_path, ctx->sep);
dir->prev = ctx->dir;
ctx->dir = dir;
@@ -480,7 +483,6 @@ static struct dirent *fs_list_dir_next(s
static struct dirent *fs_list_dir_next(struct fs_list_iterate_context *ctx)
{
struct list_dir_context *dir = ctx->dir;
- struct mail_namespace *ns = ctx->ctx.list->ns;
char *const *patterns;
const char *fname, *path, *p;
unsigned int pos;
@@ -501,14 +503,14 @@ static struct dirent *fs_list_dir_next(s
patterns += dir->pattern_pos;
dir->pattern_pos++;
- ret = pattern_get_path_pos(ns, *patterns, dir->virtual_path,
+ ret = pattern_get_path_pos(ctx, *patterns, dir->virtual_path,
&pos);
if (ret == 0)
continue;
i_assert(ret > 0);
/* get the filename from the pattern */
- p = strchr(*patterns + pos, ns->sep);
+ p = strchr(*patterns + pos, ctx->sep);
fname = p == NULL ? *patterns + pos :
t_strdup_until(*patterns + pos, p);
diff -r e2a4722f1b9b -r e1fde9940f7e src/lib-storage/list/mailbox-list-maildir-iter.c
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c Sun Oct 28 01:52:00 2007 +0300
+++ b/src/lib-storage/list/mailbox-list-maildir-iter.c Sun Oct 28 01:53:32 2007 +0300
@@ -36,30 +36,37 @@ static void node_fix_parents(struct mail
}
}
-static void maildir_fill_parents(struct maildir_list_iterate_context *ctx,
- struct imap_match_glob *glob, bool update_only,
- string_t *mailbox, const char *mailbox_c,
- enum mailbox_info_flags flags)
-{
+static void
+maildir_fill_parents(struct maildir_list_iterate_context *ctx,
+ struct imap_match_glob *glob, bool update_only,
+ string_t *mailbox, enum mailbox_info_flags flags)
+{
+ struct mail_namespace *ns = ctx->ctx.list->ns;
struct mailbox_node *node;
- const char *p;
+ const char *p, *mailbox_c;
char hierarchy_sep;
bool created;
- const char *ns_prefix = ctx->ctx.list->ns->prefix;
- unsigned int ns_prefix_len = strlen(ns_prefix);
-
- hierarchy_sep = ctx->ctx.list->ns->sep;
+ unsigned int prefix_len;
+
+ if ((ctx->ctx.flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) != 0) {
+ hierarchy_sep = ns->sep;
+ prefix_len = ns->prefix_len;
+ } else {
+ hierarchy_sep = ns->real_sep;
+ prefix_len = 0;
+ }
t_push();
+ mailbox_c = str_c(mailbox);
while ((p = strrchr(mailbox_c, hierarchy_sep)) != NULL) {
str_truncate(mailbox, (size_t) (p-mailbox_c));
mailbox_c = str_c(mailbox);
if (imap_match(glob, mailbox_c) != IMAP_MATCH_YES)
continue;
- if (*ns_prefix != '\0' && str_len(mailbox) == ns_prefix_len-1 &&
- strncmp(mailbox_c, ns_prefix, ns_prefix_len - 1) == 0 &&
- mailbox_c[ns_prefix_len-1] == hierarchy_sep) {
+ if (prefix_len > 0 && str_len(mailbox) == prefix_len-1 &&
+ strncmp(mailbox_c, ns->prefix, prefix_len - 1) == 0 &&
+ mailbox_c[prefix_len-1] == hierarchy_sep) {
/* don't return matches to namespace prefix itself */
continue;
}
@@ -92,14 +99,12 @@ maildir_fill_readdir(struct maildir_list
DIR *dirp;
struct dirent *d;
const char *mailbox_name;
- char *mailbox_c;
string_t *mailbox;
enum mailbox_info_flags flags;
enum imap_match_result match;
struct mailbox_node *node;
- bool created;
+ bool created, virtual_names;
char prefix_char;
- unsigned int pos;
int ret;
dirp = opendir(ctx->dir);
@@ -112,6 +117,7 @@ maildir_fill_readdir(struct maildir_list
return 0;
}
+ virtual_names = (ctx->ctx.flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) != 0;
prefix_char =
strcmp(ctx->ctx.list->name, MAILBOX_LIST_NAME_IMAPDIR) != 0 ?
ctx->ctx.list->hierarchy_sep : '\0';
@@ -134,22 +140,17 @@ maildir_fill_readdir(struct maildir_list
(fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0')))
continue;
+ if (!virtual_names) {
+ str_truncate(mailbox, 0);
+ str_append(mailbox, mailbox_name);
+ mailbox_name = str_c(mailbox);
+ } else {
+ mailbox_name = mail_namespace_get_vname(ns, mailbox,
+ mailbox_name);
+ }
+
/* make sure the pattern matches */
- str_truncate(mailbox, 0);
- if ((ns->flags & NAMESPACE_FLAG_INBOX) == 0 ||
More information about the dovecot-cvs
mailing list