dovecot-1.2: lazy_expunge: When deleting mailboxes, if the desti...

dovecot at dovecot.org dovecot at dovecot.org
Thu Mar 5 01:31:28 EET 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/f93d9e08f89c
changeset: 8802:f93d9e08f89c
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Mar 04 18:30:42 2009 -0500
description:
lazy_expunge: When deleting mailboxes, if the destination parent dir didn't exist, delete failed.

diffstat:

1 file changed, 30 insertions(+), 3 deletions(-)
src/plugins/lazy-expunge/lazy-expunge-plugin.c |   33 +++++++++++++++++++++---

diffs (56 lines):

diff -r 60e778555558 -r f93d9e08f89c src/plugins/lazy-expunge/lazy-expunge-plugin.c
--- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c	Wed Mar 04 18:03:23 2009 -0500
+++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c	Wed Mar 04 18:30:42 2009 -0500
@@ -5,6 +5,7 @@
 #include "array.h"
 #include "str.h"
 #include "seq-range-array.h"
+#include "mkdir-parents.h"
 #include "maildir-storage.h"
 #include "mail-namespace.h"
 #include "lazy-expunge-plugin.h"
@@ -379,15 +380,41 @@ mailbox_move(struct mailbox_list *src_li
 	     struct mailbox_list *dest_list, const char **_dest_name)
 {
 	const char *dest_name = *_dest_name;
-	const char *srcdir, *src2dir, *src3dir, *destdir;
+	const char *srcdir, *src2dir, *src3dir, *destdir, *p, *destparent;
+	struct stat st;
+	mode_t mode;
+	gid_t gid;
 
 	srcdir = mailbox_list_get_path(src_list, src_name,
 				       MAILBOX_LIST_PATH_TYPE_MAILBOX);
 	destdir = mailbox_list_get_path(dest_list, dest_name,
 					MAILBOX_LIST_PATH_TYPE_MAILBOX);
 	while (rename(srcdir, destdir) < 0) {
-		if (errno == ENOENT)
-			return 0;
+		if (errno == ENOENT) {
+			/* if this is because the destination parent directory
+			   didn't exist, create it. */
+			p = strrchr(destdir, '/');
+			if (p == NULL)
+				return 0;
+			destparent = t_strdup_until(destdir, p);
+			if (stat(destparent, &st) == 0)
+				return 0;
+
+			mailbox_list_get_dir_permissions(dest_list, NULL,
+							 &mode, &gid);
+			if (mkdir_parents_chown(destparent, mode,
+						(uid_t)-1, gid) < 0) {
+				if (errno == EEXIST) {
+					/* race condition */
+					continue;
+				}
+				mailbox_list_set_critical(src_list,
+					"mkdir(%s) failed: %m", destparent);
+				return -1;
+			}
+			/* created, try again. */
+			continue;
+		}
 
 		if (!EDESTDIREXISTS(errno)) {
 			mailbox_list_set_critical(src_list,


More information about the dovecot-cvs mailing list