]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Fixed deleting symlinked mailbox.
authorTimo Sirainen <tss@iki.fi>
Thu, 30 Dec 2010 11:45:11 +0000 (13:45 +0200)
committerTimo Sirainen <tss@iki.fi>
Thu, 30 Dec 2010 11:45:11 +0000 (13:45 +0200)
src/lib-storage/list/mailbox-list-delete.c
src/lib-storage/list/mailbox-list-delete.h
src/lib-storage/list/mailbox-list-maildir-iter.c

index 2cc4c9774e3a291207093ab745af6a66eb4e1ab0..5b7036d54d175d2ccef991961e58955ba861c203 100644 (file)
@@ -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;
+}
index 38d5a59a8c49672cca59158b499fe1a4f240550c..71a4ca834ff968f3a82a8139b1aa70930343f0c9 100644 (file)
@@ -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
index b1b45d3e40750d981a5c88e03096e6934e3f5428..a90113d866836f3d15a44784ddf8d468b725ecd4 100644 (file)
@@ -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;
 }