# HG changeset patch # User Timo Sirainen # Date 1236209442 18000 # Node ID f93d9e08f89cac3e370ae35362f999aeaf22a7e4 # Parent 60e7785555584c642b4c959484542c88ed18a0bb lazy_expunge: When deleting mailboxes, if the destination parent dir didn't exist, delete failed. 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 @@ 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,