changeset 22303:15823e373013

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.)
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 30 Jun 2017 13:46:22 +0300
parents 55d796ab90d8
children e181b398eac9
files src/lib-storage/list/mailbox-list-delete.c
diffstat 1 files changed, 24 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-delete.c	Mon Jun 26 19:06:26 2017 +0300
+++ b/src/lib-storage/list/mailbox-list-delete.c	Fri Jun 30 13:46:22 2017 +0300
@@ -286,7 +286,7 @@
 static int mailbox_list_try_delete(struct mailbox_list *list, const char *name,
 				   enum mailbox_list_path_type type)
 {
-	const char *mailbox_path, *path;
+	const char *mailbox_path, *index_path, *path;
 	int ret;
 
 	if (mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX,
@@ -295,6 +295,17 @@
 	    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 ||
@@ -325,9 +336,18 @@
 		}
 	}
 
-	/* 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;
 }