dovecot-2.1: doveadm: When AND-search includes mailbox names, do...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Apr 4 09:42:46 EEST 2012
details: http://hg.dovecot.org/dovecot-2.1/rev/1b6fb6363e7f
changeset: 14390:1b6fb6363e7f
user: Timo Sirainen <tss at iki.fi>
date: Wed Apr 04 09:42:34 2012 +0300
description:
doveadm: When AND-search includes mailbox names, don't bother going through them by list iteration.
diffstat:
src/doveadm/doveadm-mailbox-list-iter.c | 63 +++++++++++++++++++++++++-------
1 files changed, 48 insertions(+), 15 deletions(-)
diffs (141 lines):
diff -r 200af5e4c44f -r 1b6fb6363e7f src/doveadm/doveadm-mailbox-list-iter.c
--- a/src/doveadm/doveadm-mailbox-list-iter.c Wed Apr 04 09:41:15 2012 +0300
+++ b/src/doveadm/doveadm-mailbox-list-iter.c Wed Apr 04 09:42:34 2012 +0300
@@ -10,18 +10,24 @@
#include "doveadm-mailbox-list-iter.h"
struct doveadm_mailbox_list_iter {
+ struct mail_user *user;
struct doveadm_mail_cmd_context *ctx;
struct mail_search_args *search_args;
enum mailbox_list_iter_flags iter_flags;
struct mailbox_list_iterate_context *iter;
+
+ struct mailbox_info info;
+ ARRAY_TYPE(const_string) patterns;
+ unsigned int pattern_idx;
+
bool only_selectable;
};
static int
search_args_get_mailbox_patterns(const struct mail_search_arg *args,
ARRAY_TYPE(const_string) *patterns,
- bool *have_guid_r)
+ bool *have_guid, bool *have_wildcards)
{
const struct mail_search_arg *subargs;
@@ -35,12 +41,15 @@
subargs = args->value.subargs;
for (; subargs != NULL; subargs = subargs->next) {
if (!search_args_get_mailbox_patterns(subargs,
- patterns, have_guid_r))
+ patterns, have_guid,
+ have_wildcards))
return 0;
}
break;
+ case SEARCH_MAILBOX_GLOB:
+ *have_wildcards = TRUE;
+ /* fall through */
case SEARCH_MAILBOX:
- case SEARCH_MAILBOX_GLOB:
if (args->match_not) {
array_clear(patterns);
return 0;
@@ -48,7 +57,7 @@
array_append(patterns, &args->value.str, 1);
break;
case SEARCH_MAILBOX_GUID:
- *have_guid_r = TRUE;
+ *have_guid = TRUE;
break;
default:
break;
@@ -66,31 +75,36 @@
{
static const char *all_pattern = "*";
struct doveadm_mailbox_list_iter *iter;
- ARRAY_TYPE(const_string) patterns;
- bool have_guid = FALSE;
+ bool have_guid = FALSE, have_wildcards = FALSE;
iter = i_new(struct doveadm_mailbox_list_iter, 1);
iter->ctx = ctx;
iter->search_args = search_args;
+ iter->user = user;
+ i_array_init(&iter->patterns, 16);
+ search_args_get_mailbox_patterns(search_args->args, &iter->patterns,
+ &have_guid, &have_wildcards);
- t_array_init(&patterns, 16);
- search_args_get_mailbox_patterns(search_args->args, &patterns,
- &have_guid);
- if (array_count(&patterns) == 0) {
+ if (array_count(&iter->patterns) == 0) {
iter_flags |= MAILBOX_LIST_ITER_SKIP_ALIASES;
if (have_guid)
ns_mask |= NAMESPACE_SHARED | NAMESPACE_PUBLIC;
- array_append(&patterns, &all_pattern, 1);
- } else {
+ array_append(&iter->patterns, &all_pattern, 1);
+ } else if (have_wildcards) {
iter_flags |= MAILBOX_LIST_ITER_STAR_WITHIN_NS;
ns_mask |= NAMESPACE_SHARED | NAMESPACE_PUBLIC;
+ } else {
+ /* just return the listed mailboxes without actually
+ iterating through. this also allows accessing mailboxes
+ without lookup ACL right */
+ return iter;
}
- (void)array_append_space(&patterns);
+ (void)array_append_space(&iter->patterns);
iter->only_selectable = TRUE;
iter->iter_flags = iter_flags;
iter->iter = mailbox_list_iter_init_namespaces(user->namespaces,
- array_idx(&patterns, 0),
+ array_idx(&iter->patterns, 0),
ns_mask, iter_flags);
return iter;
}
@@ -130,10 +144,13 @@
*_iter = NULL;
- if ((ret = mailbox_list_iter_deinit(&iter->iter)) < 0) {
+ if (iter->iter == NULL)
+ ret = 0;
+ else if ((ret = mailbox_list_iter_deinit(&iter->iter)) < 0) {
i_error("Listing mailboxes failed");
doveadm_mail_failed_error(iter->ctx, MAIL_ERROR_TEMP);
}
+ array_free(&iter->patterns);
i_free(iter);
return ret;
}
@@ -142,6 +159,22 @@
doveadm_mailbox_list_iter_next(struct doveadm_mailbox_list_iter *iter)
{
const struct mailbox_info *info;
+ const char *const *patterns;
+ unsigned int count;
+
+ while (iter->iter == NULL) {
+ patterns = array_get(&iter->patterns, &count);
+ if (iter->pattern_idx == count)
+ return NULL;
+
+ iter->info.name = patterns[iter->pattern_idx++];
+ iter->info.ns = mail_namespace_find(iter->user->namespaces,
+ iter->info.name);
+ if (iter->info.ns != NULL)
+ return &iter->info;
+ /* FIXME: maybe fail?.. or just wait for v2.2 to get rid of
+ this error condition */
+ }
while ((info = mailbox_list_iter_next(iter->iter)) != NULL) {
char sep = mail_namespace_get_sep(info->ns);
More information about the dovecot-cvs
mailing list