From: Timo Sirainen Date: Fri, 2 Jul 2010 14:52:06 +0000 (+0100) Subject: mbox: Support deleting a directory if it contains an empty .imap/ directory. X-Git-Tag: 2.0.rc1~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=095c07765b69592c1dd644361f05ee37b1d39bd4;p=thirdparty%2Fdovecot%2Fcore.git mbox: Support deleting a directory if it contains an empty .imap/ directory. --HG-- branch : HEAD --- diff --git a/src/lib-storage/list/mailbox-list-fs.c b/src/lib-storage/list/mailbox-list-fs.c index a30386f56d..8a1efa064a 100644 --- a/src/lib-storage/list/mailbox-list-fs.c +++ b/src/lib-storage/list/mailbox-list-fs.c @@ -410,23 +410,48 @@ static int fs_list_delete_mailbox(struct mailbox_list *list, const char *name) return 0; } -static int fs_list_delete_dir(struct mailbox_list *list, const char *name) +static int fs_list_rmdir(struct mailbox_list *list, const char *name, + const char *path) { - const char *path; uint8_t dir_sha128[MAIL_GUID_128_SIZE]; + if (rmdir(path) < 0) + return -1; + + mailbox_name_get_sha128(name, dir_sha128); + mailbox_list_add_change(list, MAILBOX_LOG_RECORD_DELETE_DIR, + dir_sha128); + return 0; +} + +static int fs_list_delete_dir(struct mailbox_list *list, const char *name) +{ + const char *path, *child_name, *child_path, *p; + path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR); - if (rmdir(path) == 0) { - mailbox_name_get_sha128(name, dir_sha128); - mailbox_list_add_change(list, MAILBOX_LOG_RECORD_DELETE_DIR, - dir_sha128); + if (fs_list_rmdir(list, name, path) == 0) return 0; - } if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); } else if (errno == ENOTEMPTY) { + /* mbox workaround: if only .imap/ directory is preventing the + deletion, remove it */ + child_name = t_strdup_printf("%s%cchild", name, + list->ns->real_sep); + child_path = mailbox_list_get_path(list, child_name, + MAILBOX_LIST_PATH_TYPE_INDEX); + if (strncmp(path, child_path, strlen(path)) == 0) { + /* drop the "/child" part out. */ + p = strrchr(child_path, '/'); + if (rmdir(t_strdup_until(child_path, p)) == 0) { + /* try again */ + if (fs_list_rmdir(list, name, path) == 0) + return 0; + } + } + mailbox_list_set_error(list, MAIL_ERROR_EXISTS, "Mailbox has children, delete them first"); } else {