From: Timo Sirainen Date: Fri, 30 Jun 2017 10:46:22 +0000 (+0300) Subject: lib-storage: Fix ITERINDEX to leave \NoSelect parents after deleting child mailbox X-Git-Tag: 2.3.0.rc1~1329 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3aa1816a6b10a137c8f6242d02e31d479123c8b5;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Fix ITERINDEX to leave \NoSelect parents after deleting child mailbox For example if "a/b" was created and deleted, "a" should be left behind. (Or at least it shouldn't have left "a" to mail root directory and kept it invisible since it didn't exist in index dir.) --- diff --git a/src/lib-storage/list/mailbox-list-delete.c b/src/lib-storage/list/mailbox-list-delete.c index 9c3b26ad41..49ef84bb49 100644 --- a/src/lib-storage/list/mailbox-list-delete.c +++ b/src/lib-storage/list/mailbox-list-delete.c @@ -287,7 +287,7 @@ void mailbox_list_delete_until_root(struct mailbox_list *list, const char *path, static int mailbox_list_try_delete(struct mailbox_list *list, const char *name, enum mailbox_list_path_type type) { - const char *mailbox_path, *path, *error; + const char *mailbox_path, *index_path, *path, *error; int ret; if (mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX, @@ -296,6 +296,17 @@ static int mailbox_list_try_delete(struct mailbox_list *list, const char *name, strcmp(path, mailbox_path) == 0) return 0; + if (type == MAILBOX_LIST_PATH_TYPE_CONTROL && + mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_INDEX, + &index_path) > 0 && + strcmp(index_path, path) == 0) { + /* CONTROL dir is the same as INDEX dir, which we already + deleted. We don't want to continue especially with + iter_from_index_dir=yes, because it could be deleting the + index directory. */ + return 0; + } + /* Note that only ALT currently uses maildir_name in paths. INDEX and CONTROL don't. */ if (type != MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX || @@ -326,9 +337,18 @@ static int mailbox_list_try_delete(struct mailbox_list *list, const char *name, } } - /* Avoid leaving empty parent directories lying around. - They don't affect our return value. */ - mailbox_list_delete_until_root(list, path, type); + 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); + } return ret; }