dovecot-1.2: mbox: Renaming mailbox under newly created dir didn...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jul 2 18:06:35 EEST 2010


details:   http://hg.dovecot.org/dovecot-1.2/rev/4af00b22a466
changeset: 9588:4af00b22a466
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jul 02 16:06:30 2010 +0100
description:
mbox: Renaming mailbox under newly created dir didn't move index directory.
This happened if .imap/ directory hadn't yet been created for destination dir.

diffstat:

 src/lib-storage/list/mailbox-list-fs.c |  55 ++++++++++++++++++---------
 1 files changed, 36 insertions(+), 19 deletions(-)

diffs (87 lines):

diff -r 659f72bf92ae -r 4af00b22a466 src/lib-storage/list/mailbox-list-fs.c
--- a/src/lib-storage/list/mailbox-list-fs.c	Wed Jun 23 14:59:49 2010 +0100
+++ b/src/lib-storage/list/mailbox-list-fs.c	Fri Jul 02 16:06:30 2010 +0100
@@ -279,6 +279,31 @@
 	return mailbox_list_delete_index_control(list, name);
 }
 
+static int
+mailbox_list_mkdir_parent(struct mailbox_list *list, const char *path)
+{
+	const char *p, *parent, *origin;
+	mode_t mode;
+	gid_t gid;
+
+	p = strrchr(path, '/');
+	if (p == NULL)
+		return 0;
+
+	mailbox_list_get_dir_permissions(list, NULL, &mode, &gid, &origin);
+	parent = t_strdup_until(path, p);
+	if (mkdir_parents_chgrp(parent, mode, gid, origin) < 0 &&
+	    errno != EEXIST) {
+		if (mailbox_list_set_error_from_errno(list))
+			return -1;
+
+		mailbox_list_set_critical(list, "mkdir_parents(%s) failed: %m",
+					  parent);
+		return -1;
+	}
+	return 0;
+}
+
 static int rename_dir(struct mailbox_list *list,
 		      enum mailbox_list_path_type type,
 		      const char *oldname, const char *newname)
@@ -291,7 +316,14 @@
 	if (strcmp(oldpath, newpath) == 0)
 		return 0;
 
-	if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
+	if (rename(oldpath, newpath) < 0) {
+		if (errno == ENOENT) {
+			/* maybe the parent directory doesn't exist. */
+			if (mailbox_list_mkdir_parent(list, newpath) < 0)
+				return -1;
+			if (rename(oldpath, newpath) == 0 || errno == ENOENT)
+				return 0;
+		}
 		mailbox_list_set_critical(list, "rename(%s, %s) failed: %m",
 					  oldpath, newpath);
 		return -1;
@@ -302,10 +334,8 @@
 static int fs_list_rename_mailbox(struct mailbox_list *list,
 				  const char *oldname, const char *newname)
 {
-	const char *oldpath, *newpath, *p, *origin;
+	const char *oldpath, *newpath;
 	struct stat st;
-	mode_t mode;
-	gid_t gid;
 
 	oldpath = mailbox_list_get_path(list, oldname,
 					MAILBOX_LIST_PATH_TYPE_DIR);
@@ -313,21 +343,8 @@
 					MAILBOX_LIST_PATH_TYPE_DIR);
 
 	/* create the hierarchy */
-	p = strrchr(newpath, '/');
-	if (p != NULL) {
-		mailbox_list_get_dir_permissions(list, NULL, &mode,
-						 &gid, &origin);
-		p = t_strdup_until(newpath, p);
-		if (mkdir_parents_chgrp(p, mode, gid, origin) < 0 &&
-		    errno != EEXIST) {
-			if (mailbox_list_set_error_from_errno(list))
-				return -1;
-
-			mailbox_list_set_critical(list,
-				"mkdir_parents(%s) failed: %m", p);
-			return -1;
-		}
-	}
+	if (mailbox_list_mkdir_parent(list, newpath) < 0)
+		return -1;
 
 	/* first check that the destination mailbox doesn't exist.
 	   this is racy, but we need to be atomic and there's hardly any


More information about the dovecot-cvs mailing list