]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Try harder to rename a corrupted mailbox name to its old name.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 23 Nov 2016 20:42:03 +0000 (22:42 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 25 Nov 2016 13:28:17 +0000 (15:28 +0200)
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.

src/lib-storage/list/mailbox-list-index-backend.c

index f03e5beff8ccb473c0e0d19a98b0c82961894e44..e3ebcbb2dbdc8e2679337fead5613b7740e3fb89 100644 (file)
@@ -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;
 }