dovecot-2.0: lazy-expunge plugin implements mailbox deletions no...

dovecot at dovecot.org dovecot at dovecot.org
Sat May 23 02:16:51 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/8cf39c0b88d9
changeset: 9354:8cf39c0b88d9
user:      Timo Sirainen <tss at iki.fi>
date:      Fri May 22 19:16:45 2009 -0400
description:
lazy-expunge plugin implements mailbox deletions now using mailbox_list_rename_mailbox().

diffstat:

1 file changed, 23 insertions(+), 127 deletions(-)
src/plugins/lazy-expunge/lazy-expunge-plugin.c |  150 +++---------------------

diffs (181 lines):

diff -r c86b65e4a510 -r 8cf39c0b88d9 src/plugins/lazy-expunge/lazy-expunge-plugin.c
--- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c	Fri May 22 19:16:03 2009 -0400
+++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c	Fri May 22 19:16:45 2009 -0400
@@ -271,146 +271,42 @@ lazy_expunge_mailbox_open(struct mail_st
 	return box;
 }
 
-static int dir_move_or_merge(struct mailbox_list *list,
-			     const char *srcdir, const char *destdir)
-{
-	DIR *dir;
-	struct dirent *dp;
-	string_t *src_path, *dest_path;
-	unsigned int src_dirlen, dest_dirlen;
-	int ret = 0;
-
-	if (rename(srcdir, destdir) == 0 || errno == ENOENT)
-		return 0;
-
-	if (!EDESTDIREXISTS(errno)) {
-		mailbox_list_set_critical(list,
-			"rename(%s, %s) failed: %m", srcdir, destdir);
-	}
-
-	/* rename all the files separately */
-	dir = opendir(srcdir);
-	if (dir == NULL) {
-		mailbox_list_set_critical(list,
-			"opendir(%s) failed: %m", srcdir);
-		return -1;
-	}
-
-	src_path = t_str_new(512);
-	dest_path = t_str_new(512);
-
-	str_append(src_path, srcdir);
-	str_append(dest_path, destdir);
-	str_append_c(src_path, '/');
-	str_append_c(dest_path, '/');
-	src_dirlen = str_len(src_path);
-	dest_dirlen = str_len(dest_path);
-
-	while ((dp = readdir(dir)) != NULL) {
-		if (dp->d_name[0] == '.' &&
-		    (dp->d_name[1] == '\0' ||
-		     (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
-			continue;
-
-		str_truncate(src_path, src_dirlen);
-		str_append(src_path, dp->d_name);
-		str_truncate(dest_path, dest_dirlen);
-		str_append(dest_path, dp->d_name);
-
-		if (rename(str_c(src_path), str_c(dest_path)) < 0 &&
-		    errno != ENOENT) {
-			mailbox_list_set_critical(list,
-				"rename(%s, %s) failed: %m",
-				str_c(src_path), str_c(dest_path));
-			ret = -1;
-		}
-	}
-	if (closedir(dir) < 0) {
-		mailbox_list_set_critical(list,
-			"closedir(%s) failed: %m", srcdir);
-		ret = -1;
-	}
-	if (ret == 0) {
-		if (rmdir(srcdir) < 0) {
-			mailbox_list_set_critical(list,
-				"rmdir(%s) failed: %m", srcdir);
-			ret = -1;
-		}
-	}
-	return ret;
-}
-
 static int
 mailbox_move(struct mailbox_list *src_list, const char *src_name,
 	     struct mailbox_list *dest_list, const char **_dest_name)
 {
-	const char *dest_name = *_dest_name;
-	const char *srcdir, *src2dir, *src3dir, *destdir, *p, *destparent;
-	struct stat st;
+	const char *dir, *dest_name = *_dest_name;
+	enum mail_error error;
 	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) {
-			/* 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,
-				"rename(%s, %s) failed: %m", srcdir, destdir);
+	/* make sure the destination root directory exists */
+	mailbox_list_get_dir_permissions(dest_list, NULL, &mode, &gid);
+	dir = mailbox_list_get_path(dest_list, NULL, MAILBOX_LIST_PATH_TYPE_DIR);
+	if (mkdir_parents_chown(dir, mode, (uid_t)-1, gid) < 0 &&
+	    errno != EEXIST) {
+		mailbox_list_set_critical(src_list,
+			"mkdir_parents_chown(%s) failed: %m", dir);
+		return -1;
+	}
+
+	while (mailbox_list_rename_mailbox(src_list, src_name,
+					   dest_list, dest_name, FALSE) < 0) {
+		mailbox_list_get_last_error(src_list, &error);
+		switch (error) {
+		case MAIL_ERROR_EXISTS:
 			return -1;
+		case MAIL_ERROR_NOTFOUND:
+			return 0;
+		default:
+			break;
 		}
 
 		/* mailbox is being deleted multiple times per second.
 		   update the filename. */
 		dest_name = t_strdup_printf("%s-%04u", *_dest_name,
 					    (uint32_t)random());
-		destdir = mailbox_list_get_path(dest_list, dest_name,
-						MAILBOX_LIST_PATH_TYPE_MAILBOX);
-	}
-
-	src2dir = mailbox_list_get_path(src_list, src_name,
-					MAILBOX_LIST_PATH_TYPE_CONTROL);
-	if (strcmp(src2dir, srcdir) != 0) {
-		destdir = mailbox_list_get_path(dest_list, dest_name,
-						MAILBOX_LIST_PATH_TYPE_CONTROL);
-		(void)dir_move_or_merge(src_list, src2dir, destdir);
-	}
-	src3dir = mailbox_list_get_path(src_list, src_name,
-					MAILBOX_LIST_PATH_TYPE_INDEX);
-	if (strcmp(src3dir, srcdir) != 0 && strcmp(src3dir, src2dir) != 0) {
-		destdir = mailbox_list_get_path(dest_list, dest_name,
-						MAILBOX_LIST_PATH_TYPE_INDEX);
-		(void)dir_move_or_merge(src_list, src3dir, destdir);
-	}
-
-	*_dest_name = dest_name;
+	}
 	return 1;
 }
 
@@ -517,7 +413,7 @@ static void lazy_expunge_mailbox_list_cr
 		LAZY_EXPUNGE_USER_CONTEXT(list->ns->user);
 	struct lazy_expunge_mailbox_list *llist;
 
-	if (luser != NULL) {
+	if (luser != NULL && list->ns->type == NAMESPACE_PRIVATE) {
 		llist = p_new(list->pool, struct lazy_expunge_mailbox_list, 1);
 		llist->module_ctx.super = list->v;
 		list->v.delete_mailbox = lazy_expunge_mailbox_list_delete;


More information about the dovecot-cvs mailing list