changeset 22385:ae8fe0ac1f34

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.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 25 Jul 2017 15:54:37 +0300
parents 9a117c44073e
children 1534de106851
files src/lib-storage/list/mailbox-list-delete.c
diffstat 1 files changed, 27 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-delete.c	Mon Jul 24 16:37:42 2017 +0300
+++ b/src/lib-storage/list/mailbox-list-delete.c	Tue Jul 25 15:54:37 2017 +0300
@@ -256,12 +256,35 @@
 	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 @@
 		}
 	}
 
-	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;
 }