From: Timo Sirainen Date: Tue, 25 Jul 2017 12:54:37 +0000 (+0300) Subject: lib-storage: Mailbox rename shouldn't auto-rmdir parent index dirs with ITERINDEX X-Git-Tag: 2.2.32.rc1~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=224566864db67ab4033b83ef5f98aab5be267481;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Mailbox rename shouldn't auto-rmdir parent index dirs with ITERINDEX For example: - create a/b - rename a/b c This resulted in "a" existing in mail root directory, but not in index directory. With ITERINDEX this meant that the "a" was lost. --- diff --git a/src/lib-storage/list/mailbox-list-delete.c b/src/lib-storage/list/mailbox-list-delete.c index 37f7a19bff..5112c9e672 100644 --- a/src/lib-storage/list/mailbox-list-delete.c +++ b/src/lib-storage/list/mailbox-list-delete.c @@ -256,12 +256,35 @@ int mailbox_list_delete_mailbox_nonrecursive(struct mailbox_list *list, return 0; } +static bool mailbox_list_path_is_index(struct mailbox_list *list, + enum mailbox_list_path_type type) +{ + const char *index_root, *type_root; + + if (type == MAILBOX_LIST_PATH_TYPE_INDEX) + return TRUE; + + /* e.g. CONTROL dir could point to the same INDEX dir. */ + type_root = mailbox_list_get_root_forced(list, type); + index_root = mailbox_list_get_root_forced(list, MAILBOX_LIST_PATH_TYPE_INDEX); + return strcmp(type_root, index_root) == 0; +} + void mailbox_list_delete_until_root(struct mailbox_list *list, const char *path, enum mailbox_list_path_type type) { const char *root_dir, *p; size_t len; + if (list->set.iter_from_index_dir && + mailbox_list_path_is_index(list, type)) { + /* Don't auto-rmdir parent index directories with ITERINDEX. + Otherwise it'll get us into inconsistent state with a + \NoSelect mailbox in the mail directory but not in index + directory. */ + return; + } + root_dir = mailbox_list_get_root_forced(list, type); if (strncmp(path, root_dir, strlen(root_dir)) != 0) { /* mbox workaround: name=child/box, root_dir=mail/.imap/, @@ -350,18 +373,10 @@ static int mailbox_list_try_delete(struct mailbox_list *list, const char *name, } } - if (!list->set.iter_from_index_dir || - type != MAILBOX_LIST_PATH_TYPE_INDEX) { - /* Avoid leaving empty parent directories lying around. - We don't want to do it though when we're iterating mailboxes - from index directory, since it'll get us into inconsistent - state with a \NoSelect mailbox in the mail directory but not - in index directory. - - These parent directories' existence or removal doesn't - affect our return value. */ - mailbox_list_delete_until_root(list, path, type); - } + /* Avoid leaving empty parent directories lying around. + These parent directories' existence or removal doesn't + affect our return value. */ + mailbox_list_delete_until_root(list, path, type); return ret; }