Mercurial > dovecot > core-2.2
changeset 13148:f42aac06a3df
lib-storage: renaming mailboxes under different parent was broken in fs layout
If alt storage was used with sdbox or if index or control dirs were used,
renaming "foo" to "bar/foo" would result "foo" not being renamed for those
directories.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 29 Jul 2011 12:25:52 +0300 |
parents | 94c6e1cd58f1 |
children | d7f76c266657 |
files | src/lib-storage/list/mailbox-list-fs.c |
diffstat | 1 files changed, 26 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-fs.c Fri Jul 29 00:04:20 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-fs.c Fri Jul 29 12:25:52 2011 +0300 @@ -466,7 +466,8 @@ struct mailbox_list *newlist, const char *newname, enum mailbox_list_path_type type, bool rmdir_parent) { - const char *oldpath, *newpath, *p; + struct stat st; + const char *oldpath, *newpath, *p, *oldparent, *newparent; oldpath = mailbox_list_get_path(oldlist, oldname, type); newpath = mailbox_list_get_path(newlist, newname, type); @@ -474,6 +475,30 @@ if (strcmp(oldpath, newpath) == 0) return 0; + p = strrchr(oldpath, '/'); + oldparent = p == NULL ? "/" : t_strdup_until(oldpath, p); + p = strrchr(newpath, '/'); + newparent = p == NULL ? "/" : t_strdup_until(newpath, p); + + if (strcmp(oldparent, newparent) != 0 && stat(oldpath, &st) == 0) { + /* make sure the newparent exists */ + mode_t mode; + gid_t gid; + const char *origin; + + mailbox_list_get_dir_permissions(newlist, NULL, &mode, + &gid, &origin); + if (mkdir_parents_chgrp(newparent, mode, gid, origin) < 0 && + errno != EEXIST) { + if (mailbox_list_set_error_from_errno(oldlist)) + return -1; + + mailbox_list_set_critical(oldlist, + "mkdir_parents(%s) failed: %m", newparent); + return -1; + } + } + if (rename(oldpath, newpath) < 0 && errno != ENOENT) { mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m", oldpath, newpath);