Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5560:3a3051d0e79b HEAD
Mailbox list index fixes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 17 Apr 2007 13:06:59 +0300 |
parents | 12b3d542146c |
children | ead3e882c9c9 |
files | src/lib-index/mailbox-list-index-sync.c src/lib-storage/list/index-mailbox-list.c src/lib-storage/list/index-mailbox-list.h |
diffstat | 3 files changed, 71 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mailbox-list-index-sync.c Tue Apr 17 12:43:14 2007 +0300 +++ b/src/lib-index/mailbox-list-index-sync.c Tue Apr 17 13:06:59 2007 +0300 @@ -214,12 +214,13 @@ const char *p, *hier_name; struct mailbox_list_sync_dir *dir; struct mailbox_list_sync_record *rec = NULL; - unsigned int idx; + unsigned int idx, child_flags; if (ctx->failed) return -1; dir = ctx->sync_root; + child_flags = MAILBOX_LIST_INDEX_FLAG_CHILDREN; t_push(); for (;;) { @@ -237,15 +238,20 @@ } if (rec != NULL) { + /* add CHILDREN flag to the parent and remove + NOCHILDREN flag. if we happened to create the + parent ourself, also add NONEXISTENT flag. */ mail_index_update_flags(ctx->trans, rec->seq, - MODIFY_REPLACE, - MAILBOX_LIST_INDEX_FLAG_NONEXISTENT | - MAILBOX_LIST_INDEX_FLAG_CHILDREN); + MODIFY_ADD, child_flags); + mail_index_update_flags(ctx->trans, rec->seq, + MODIFY_REMOVE, + MAILBOX_LIST_INDEX_FLAG_NOCHILDREN); } rec = mailbox_list_sync_dir_lookup(dir, hier_name, &idx); if (rec == NULL) { /* new record */ + child_flags |= MAILBOX_LIST_INDEX_FLAG_NONEXISTENT; rec = mailbox_list_alloc_add_record(ctx, dir, hier_name, idx); } else if (rec->seq == 0) {
--- a/src/lib-storage/list/index-mailbox-list.c Tue Apr 17 12:43:14 2007 +0300 +++ b/src/lib-storage/list/index-mailbox-list.c Tue Apr 17 13:06:59 2007 +0300 @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 Timo Sirainen */ +/* Copyright (C) 2006-2007 Timo Sirainen */ #include "lib.h" #include "ioloop.h" @@ -7,6 +7,7 @@ #include "imap-match.h" #include "mail-index.h" #include "mail-storage.h" +#include "mailbox-tree.h" #include "mailbox-list-index.h" #include "index-mailbox-list.h" @@ -146,6 +147,15 @@ /* FIXME: this works nicely with maildir++, but not others */ sync_flags = MAILBOX_LIST_SYNC_FLAG_RECURSIVE; + if (strchr(mask, '*') != NULL) + ctx->recurse_level = -1; + else { + ctx->mailbox_tree = + mailbox_tree_init(list->hierarchy_sep); + } + + ctx->info_pool = + pool_alloconly_create("mailbox name pool", 128); if (mailbox_list_index_sync_init(ilist->list_index, "", sync_flags, &ctx->sync_ctx) == 0) { @@ -259,6 +269,32 @@ } static struct mailbox_info * +mailbox_info_move_to_parent(struct index_mailbox_list_iterate_context *ctx, + const struct mailbox_info *info) +{ + const char *p, *name = info->name; + char sep = ctx->ctx.list->hierarchy_sep; + + p_clear(ctx->info_pool); + + t_push(); + while ((p = strrchr(name, sep)) != NULL) { + name = t_strdup_until(name, p); + if (imap_match(ctx->glob, name) == IMAP_MATCH_YES) { + ctx->info.name = p_strdup(ctx->info_pool, name); + break; + } + } + t_pop(); + + if (p == NULL) + i_unreached(); + + ctx->info.flags = MAILBOX_CHILDREN | MAILBOX_NONEXISTENT; + return &ctx->info; +} + +static struct mailbox_info * index_mailbox_list_iter_next(struct mailbox_list_iterate_context *_ctx) { struct index_mailbox_list_iterate_context *ctx = @@ -266,6 +302,7 @@ struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(_ctx->list); struct mailbox_info *info; uint32_t seq, flags; + enum imap_match_result match; if (ctx->iter_ctx != NULL) { if (iter_next_nonsync(ctx, &info) < 0) { @@ -281,7 +318,7 @@ return info; /* if the sync fails, just ignore it. we don't require synced - indexes to return valid output. */ + indexes to be able to return valid output. */ if (mailbox_list_index_sync_more(ctx->sync_ctx, info->name, &seq) == 0) { flags = index_mailbox_list_info_flags_translate( @@ -289,8 +326,23 @@ mail_index_update_flags(ctx->trans, seq, MODIFY_REPLACE, flags); } - } while (imap_match(ctx->glob, info->name) != IMAP_MATCH_YES || - !info_flags_match(ctx, info)); + match = imap_match(ctx->glob, info->name); + if (match == IMAP_MATCH_PARENT) { + info = mailbox_info_move_to_parent(ctx, info); + match = IMAP_MATCH_YES; + } + if (ctx->recurse_level >= 0) { + /* no "*" wildcards, keep track of what mailboxes we + have returned so we don't return same parents + multiple times. */ + bool created; + + (void)mailbox_tree_get(ctx->mailbox_tree, + info->name, &created); + if (!created) + match = IMAP_MATCH_NO; + } + } while (match != IMAP_MATCH_YES || !info_flags_match(ctx, info)); return info; } @@ -303,10 +355,12 @@ struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(_ctx->list); int ret = ctx->failed ? -1 : 0; - if (ctx->iter_ctx != NULL) { + if (ctx->iter_ctx != NULL) mailbox_list_index_iterate_deinit(&ctx->iter_ctx); + if (ctx->info_pool != NULL) pool_unref(ctx->info_pool); - } + if (ctx->mailbox_tree != NULL) + mailbox_tree_deinit(&ctx->mailbox_tree); if (ctx->mail_view != NULL) mail_index_view_close(&ctx->mail_view);
--- a/src/lib-storage/list/index-mailbox-list.h Tue Apr 17 12:43:14 2007 +0300 +++ b/src/lib-storage/list/index-mailbox-list.h Tue Apr 17 13:06:59 2007 +0300 @@ -37,6 +37,7 @@ char *prefix; int recurse_level; struct imap_match_glob *glob; + struct mailbox_tree_context *mailbox_tree; pool_t info_pool; struct mailbox_info info;