From: Timo Sirainen Date: Wed, 23 Nov 2016 20:42:03 +0000 (+0200) Subject: lib-storage: Try harder to rename a corrupted mailbox name to its old name. X-Git-Tag: 2.2.27~64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e6a3d022b64defe98480587ee24e23180c46344a;p=thirdparty%2Fdovecot%2Fcore.git 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. --- diff --git a/src/lib-storage/list/mailbox-list-index-backend.c b/src/lib-storage/list/mailbox-list-index-backend.c index f03e5beff8..e3ebcbb2db 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; }