From: Timo Sirainen Date: Thu, 30 Dec 2010 11:45:11 +0000 (+0200) Subject: lib-storage: Fixed deleting symlinked mailbox. X-Git-Tag: 2.0.9~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4cdfd6cc490503ed4176a6796140470916d06e01;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Fixed deleting symlinked mailbox. --- diff --git a/src/lib-storage/list/mailbox-list-delete.c b/src/lib-storage/list/mailbox-list-delete.c index 2cc4c9774e..5b7036d54d 100644 --- a/src/lib-storage/list/mailbox-list-delete.c +++ b/src/lib-storage/list/mailbox-list-delete.c @@ -97,7 +97,7 @@ int mailbox_list_delete_maildir_via_trash(struct mailbox_list *list, if (trash_dir == trash_dest) { trash_dest = t_strconcat(trash_dir, "/", unique_fname(), NULL); - } else if (unlink_directory(trash_dest, TRUE) < 0 && + } else if (mailbox_list_delete_trash(trash_dest) < 0 && (errno != ENOTEMPTY || count >= 5)) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", trash_dest); @@ -105,7 +105,7 @@ int mailbox_list_delete_maildir_via_trash(struct mailbox_list *list, } } - if (unlink_directory(trash_dir, TRUE) < 0 && + if (mailbox_list_delete_trash(trash_dir) < 0 && errno != ENOTEMPTY && errno != EBUSY) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", trash_dir); @@ -189,7 +189,7 @@ int mailbox_list_delete_mailbox_nonrecursive(struct mailbox_list *list, str_append(full_path, d->d_name); if (mailbox_dir) { - if (unlink_directory(str_c(full_path), TRUE) < 0) { + if (mailbox_list_delete_trash(str_c(full_path)) < 0) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", str_c(full_path)); @@ -297,7 +297,7 @@ static void mailbox_list_try_delete(struct mailbox_list *list, const char *name, rmdir_path) < 0) return; } else { - if (unlink_directory(path, TRUE) < 0 && + if (mailbox_list_delete_trash(path) < 0 && errno != ENOENT && errno != ENOTEMPTY) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", path); @@ -314,3 +314,17 @@ void mailbox_list_delete_finish(struct mailbox_list *list, const char *name) mailbox_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_CONTROL); mailbox_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX); } + +int mailbox_list_delete_trash(const char *path) +{ + if (unlink_directory(path, TRUE) < 0) { + if (errno == ELOOP) { + /* it's a symlink? try just deleting it */ + if (unlink(path) == 0) + return 0; + errno = ELOOP; + return -1; + } + } + return 0; +} diff --git a/src/lib-storage/list/mailbox-list-delete.h b/src/lib-storage/list/mailbox-list-delete.h index 38d5a59a8c..71a4ca834f 100644 --- a/src/lib-storage/list/mailbox-list-delete.h +++ b/src/lib-storage/list/mailbox-list-delete.h @@ -15,5 +15,6 @@ void mailbox_list_delete_finish(struct mailbox_list *list, const char *name); void mailbox_list_delete_until_root(struct mailbox_list *list, const char *path, enum mailbox_list_path_type type); +int mailbox_list_delete_trash(const char *path); #endif diff --git a/src/lib-storage/list/mailbox-list-maildir-iter.c b/src/lib-storage/list/mailbox-list-maildir-iter.c index b1b45d3e40..a90113d866 100644 --- a/src/lib-storage/list/mailbox-list-maildir-iter.c +++ b/src/lib-storage/list/mailbox-list-maildir-iter.c @@ -6,6 +6,7 @@ #include "unlink-directory.h" #include "imap-match.h" #include "mailbox-tree.h" +#include "mailbox-list-delete.h" #include "mailbox-list-subscriptions.h" #include "mailbox-list-maildir.h" @@ -256,7 +257,7 @@ static bool maildir_delete_trash_dir(struct maildir_list_iterate_context *ctx, path = t_strdup_printf("%s/%s", ctx->dir, fname); if (stat(path, &st) == 0 && st.st_mtime < ioloop_time - 3600) - (void)unlink_directory(path, TRUE); + (void)mailbox_list_delete_trash(path); return TRUE; }