From 55c88023635062105849a2cbab78232f483b2c02 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 23 Nov 2016 22:42:03 +0200 Subject: [PATCH] lib-storage: Try harder to rename a corrupted mailbox name to its old name. If the old name exists, use it as a prefix for the new name. This is especially useful when restoring autocreated mailboxes. A new mailbox could have already been autocreated, but it's still useful to have the broken one renamed with the same prefix, so it'll be clear that these mailboxes should be merged. --- .../list/mailbox-list-index-backend.c | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/lib-storage/list/mailbox-list-index-backend.c b/src/lib-storage/list/mailbox-list-index-backend.c index 798a0bdc2b..d37e304947 100644 --- a/src/lib-storage/list/mailbox-list-index-backend.c +++ b/src/lib-storage/list/mailbox-list-index-backend.c @@ -483,6 +483,29 @@ static bool mailbox_has_corrupted_name(struct mailbox *box) (node->flags & MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME) != 0; } +static void index_list_rename_corrupted(struct mailbox *box, const char *newname) +{ + if (index_list_rename_mailbox(box->list, box->name, + box->list, newname) == 0 || + box->list->error != MAIL_ERROR_EXISTS) + return; + + /* mailbox already exists. don't give up yet, just use the newname + as prefix and add the "lost-xx" as suffix. */ + char sep = mailbox_list_get_hierarchy_sep(box->list); + const char *oldname = box->name; + + /* oldname should be at the root level, but check for hierarchies + anyway to be safe. */ + const char *p = strrchr(oldname, sep); + if (p != NULL) + oldname = p+1; + + newname = t_strdup_printf("%s-%s", newname, oldname); + (void)index_list_rename_mailbox(box->list, box->name, + box->list, newname); +} + static int index_list_mailbox_open(struct mailbox *box) { struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box); @@ -537,8 +560,7 @@ static int index_list_mailbox_open(struct mailbox *box) newname[i] = sep; } - (void)index_list_rename_mailbox(box->list, box->name, - box->list, newname); + index_list_rename_corrupted(box, newname); } return 0; }