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