# HG changeset patch # User Timo Sirainen # Date 1304165540 -10800 # Node ID 9949b7987409f49f9cc09877e366fd45dd284bd6 # Parent a8fe529ea72b6d947eda80ef4125ed8c482e9fd9 lib-storage: mailbox_delete() for a symlink now removes the symlink instead of expunging mails. diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/index/imapc/imapc-list.c --- a/src/lib-storage/index/imapc/imapc-list.c Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-list.c Sat Apr 30 15:12:20 2011 +0300 @@ -497,6 +497,14 @@ } static int +imapc_list_delete_symlink(struct mailbox_list *list, + const char *name ATTR_UNUSED) +{ + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Not supported"); + return -1; +} + +static int imapc_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname, struct mailbox_list *newlist, const char *newname, bool rename_children) @@ -560,6 +568,7 @@ imapc_list_create_mailbox_dir, imapc_list_delete_mailbox, imapc_list_delete_dir, + imapc_list_delete_symlink, imapc_list_rename_mailbox } }; diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/index/index-storage.c Sat Apr 30 15:12:20 2011 +0300 @@ -522,6 +522,11 @@ return index_storage_mailbox_delete_dir(box, FALSE); } + /* specifically support symlinked shared mailboxes. a deletion will + simply remove the symlink, not actually expunge any mails */ + if (mailbox_list_delete_symlink(box->list, box->name) == 0) + return 0; + /* we can't easily atomically delete all mails and the mailbox. so: 1) expunge all mails 2) mark the mailbox deleted (modifications after this will fail) diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/index/shared/shared-list.c --- a/src/lib-storage/index/shared/shared-list.c Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/index/shared/shared-list.c Sat Apr 30 15:12:20 2011 +0300 @@ -275,6 +275,20 @@ return ret; } +static int +shared_list_delete_symlink(struct mailbox_list *list, const char *name) +{ + struct mail_namespace *ns = list->ns; + int ret; + + if (shared_storage_get_namespace(&ns, &name) < 0) + return -1; + ret = mailbox_list_delete_symlink(ns->list, name); + if (ret < 0) + shared_list_copy_error(list, ns); + return ret; +} + static int shared_list_rename_get_ns(struct mailbox_list *oldlist, const char **oldname, struct mailbox_list *newlist, @@ -342,6 +356,7 @@ shared_list_create_mailbox_dir, shared_list_delete_mailbox, shared_list_delete_dir, + shared_list_delete_symlink, shared_list_rename_mailbox } }; diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/list/mailbox-list-delete.c --- a/src/lib-storage/list/mailbox-list-delete.c Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-delete.c Sat Apr 30 15:12:20 2011 +0300 @@ -328,3 +328,25 @@ } return 0; } + +int mailbox_list_delete_symlink_default(struct mailbox_list *list, + const char *name) +{ + const char *path; + + path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR); + if (unlink(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 == EISDIR) { + mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, + "Mailbox isn't a symlink"); + } else { + mailbox_list_set_critical(list, "stat(%s) failed: %m", path); + } + return -1; +} + diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/list/mailbox-list-delete.h --- a/src/lib-storage/list/mailbox-list-delete.h Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-delete.h Sat Apr 30 15:12:20 2011 +0300 @@ -17,4 +17,7 @@ enum mailbox_list_path_type type); int mailbox_list_delete_trash(const char *path); +int mailbox_list_delete_symlink_default(struct mailbox_list *list, + const char *name); + #endif diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/list/mailbox-list-fs.c --- a/src/lib-storage/list/mailbox-list-fs.c Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-fs.c Sat Apr 30 15:12:20 2011 +0300 @@ -613,6 +613,7 @@ fs_list_create_mailbox_dir, fs_list_delete_mailbox, fs_list_delete_dir, + mailbox_list_delete_symlink_default, fs_list_rename_mailbox } }; diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/list/mailbox-list-maildir.c --- a/src/lib-storage/list/mailbox-list-maildir.c Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-maildir.c Sat Apr 30 15:12:20 2011 +0300 @@ -660,6 +660,7 @@ maildir_list_create_mailbox_dir, maildir_list_delete_mailbox, maildir_list_delete_dir, + mailbox_list_delete_symlink_default, maildir_list_rename_mailbox } }; @@ -694,6 +695,7 @@ maildir_list_create_mailbox_dir, maildir_list_delete_mailbox, maildir_list_delete_dir, + mailbox_list_delete_symlink_default, maildir_list_rename_mailbox } }; diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/list/mailbox-list-none.c --- a/src/lib-storage/list/mailbox-list-none.c Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/list/mailbox-list-none.c Sat Apr 30 15:12:20 2011 +0300 @@ -210,6 +210,7 @@ none_list_create_mailbox_dir, none_list_delete_mailbox, none_list_delete_dir, + none_list_delete_dir, none_list_rename_mailbox } }; diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/mailbox-list-private.h --- a/src/lib-storage/mailbox-list-private.h Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/mailbox-list-private.h Sat Apr 30 15:12:20 2011 +0300 @@ -82,6 +82,7 @@ enum mailbox_dir_create_type type); int (*delete_mailbox)(struct mailbox_list *list, const char *name); int (*delete_dir)(struct mailbox_list *list, const char *name); + int (*delete_symlink)(struct mailbox_list *list, const char *name); int (*rename_mailbox)(struct mailbox_list *oldlist, const char *oldname, struct mailbox_list *newlist, const char *newname, bool rename_children); diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/mailbox-list.c --- a/src/lib-storage/mailbox-list.c Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/mailbox-list.c Sat Apr 30 15:12:20 2011 +0300 @@ -1404,6 +1404,16 @@ return list->v.delete_dir(list, name); } +int mailbox_list_delete_symlink(struct mailbox_list *list, const char *name) +{ + if (!mailbox_list_is_valid_existing_name(list, name) || *name == '\0') { + mailbox_list_set_error(list, MAIL_ERROR_PARAMS, + "Invalid mailbox name"); + return -1; + } + return list->v.delete_symlink(list, name); +} + void mailbox_name_get_sha128(const char *name, uint8_t guid[MAIL_GUID_128_SIZE]) { unsigned char sha[SHA1_RESULTLEN]; diff -r a8fe529ea72b -r 9949b7987409 src/lib-storage/mailbox-list.h --- a/src/lib-storage/mailbox-list.h Sat Apr 30 15:00:42 2011 +0300 +++ b/src/lib-storage/mailbox-list.h Sat Apr 30 15:12:20 2011 +0300 @@ -265,6 +265,8 @@ int mailbox_list_create_dir(struct mailbox_list *list, const char *name); /* Delete a non-selectable mailbox. Fail if the mailbox is selectable. */ int mailbox_list_delete_dir(struct mailbox_list *list, const char *name); +/* Delete a symlinked mailbox. Fail if the mailbox isn't a symlink. */ +int mailbox_list_delete_symlink(struct mailbox_list *list, const char *name); /* Returns the error message of last occurred error. */ const char *mailbox_list_get_last_error(struct mailbox_list *list,