Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9588:4af00b22a466 HEAD
mbox: Renaming mailbox under newly created dir didn't move index directory.
This happened if .imap/ directory hadn't yet been created for destination dir.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 02 Jul 2010 16:06:30 +0100 |
parents | 659f72bf92ae |
children | 5c0265dba3d1 |
files | src/lib-storage/list/mailbox-list-fs.c |
diffstat | 1 files changed, 36 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-fs.c Wed Jun 23 14:59:49 2010 +0100 +++ b/src/lib-storage/list/mailbox-list-fs.c Fri Jul 02 16:06:30 2010 +0100 @@ -279,6 +279,31 @@ return mailbox_list_delete_index_control(list, name); } +static int +mailbox_list_mkdir_parent(struct mailbox_list *list, const char *path) +{ + const char *p, *parent, *origin; + mode_t mode; + gid_t gid; + + p = strrchr(path, '/'); + if (p == NULL) + return 0; + + mailbox_list_get_dir_permissions(list, NULL, &mode, &gid, &origin); + parent = t_strdup_until(path, p); + if (mkdir_parents_chgrp(parent, mode, gid, origin) < 0 && + errno != EEXIST) { + if (mailbox_list_set_error_from_errno(list)) + return -1; + + mailbox_list_set_critical(list, "mkdir_parents(%s) failed: %m", + parent); + return -1; + } + return 0; +} + static int rename_dir(struct mailbox_list *list, enum mailbox_list_path_type type, const char *oldname, const char *newname) @@ -291,7 +316,14 @@ if (strcmp(oldpath, newpath) == 0) return 0; - if (rename(oldpath, newpath) < 0 && errno != ENOENT) { + if (rename(oldpath, newpath) < 0) { + if (errno == ENOENT) { + /* maybe the parent directory doesn't exist. */ + if (mailbox_list_mkdir_parent(list, newpath) < 0) + return -1; + if (rename(oldpath, newpath) == 0 || errno == ENOENT) + return 0; + } mailbox_list_set_critical(list, "rename(%s, %s) failed: %m", oldpath, newpath); return -1; @@ -302,10 +334,8 @@ static int fs_list_rename_mailbox(struct mailbox_list *list, const char *oldname, const char *newname) { - const char *oldpath, *newpath, *p, *origin; + const char *oldpath, *newpath; struct stat st; - mode_t mode; - gid_t gid; oldpath = mailbox_list_get_path(list, oldname, MAILBOX_LIST_PATH_TYPE_DIR); @@ -313,21 +343,8 @@ MAILBOX_LIST_PATH_TYPE_DIR); /* create the hierarchy */ - p = strrchr(newpath, '/'); - if (p != NULL) { - mailbox_list_get_dir_permissions(list, NULL, &mode, - &gid, &origin); - p = t_strdup_until(newpath, p); - if (mkdir_parents_chgrp(p, mode, gid, origin) < 0 && - errno != EEXIST) { - if (mailbox_list_set_error_from_errno(list)) - return -1; - - mailbox_list_set_critical(list, - "mkdir_parents(%s) failed: %m", p); - return -1; - } - } + if (mailbox_list_mkdir_parent(list, newpath) < 0) + return -1; /* first check that the destination mailbox doesn't exist. this is racy, but we need to be atomic and there's hardly any