Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8802:f93d9e08f89c HEAD
lazy_expunge: When deleting mailboxes, if the destination parent dir didn't exist, delete failed.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 04 Mar 2009 18:30:42 -0500 |
parents | 60e778555558 |
children | fe4782341037 |
files | src/plugins/lazy-expunge/lazy-expunge-plugin.c |
diffstat | 1 files changed, 30 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- 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,