return 0;
}
+static bool mailbox_has_corrupted_name(struct mailbox *box)
+{
+ struct mailbox_list_index_node *node;
+
+ node = mailbox_list_index_lookup(box->list, box->name);
+ return node != NULL &&
+ (node->flags & MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME) != 0;
+}
+
static int index_list_mailbox_open(struct mailbox *box)
{
struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
if (name_hdr_size == box_name_len &&
memcmp(box_zerosep_name, name_hdr, box_name_len) == 0) {
/* Same mailbox name */
- } else {
+ } else if (!mailbox_has_corrupted_name(box)) {
/* Mailbox name changed - update */
struct mail_index_transaction *trans =
mail_index_transaction_begin(box->view, 0);
oldrec.name_id = newrec.name_id;
oldrec.parent_uid = newrec.parent_uid;
+ if ((newnode->flags & MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME) != 0) {
+ /* mailbox is renamed - clear away the corruption flag so the
+ new name will be written to the mailbox index header. */
+ newnode->flags &= ~MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME;
+ mail_index_update_flags(sync_ctx->trans, oldseq, MODIFY_REMOVE,
+ MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME);
+ }
mail_index_update_ext(sync_ctx->trans, oldseq,
sync_ctx->ilist->ext_id, &oldrec, NULL);
mail_index_expunge(sync_ctx->trans, newseq);
sync_ctx->ilist->ext_id, &irec, NULL);
node->corrupted_parent = FALSE;
}
+ if ((node->flags & MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME) != 0) {
+ /* rely on lib-index to drop unnecessary updates */
+ mail_index_update_flags(sync_ctx->trans, seq, MODIFY_ADD,
+ MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME);
+ }
}
static void
name = p_strdup_printf(ilist->mailbox_pool, "unknown-%s",
guid_128_to_string(guid));
node->name = name;
+ node->flags |= MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME;
hash_table_insert(ilist->mailbox_names,
POINTER_CAST(node->name_id), name);
/* we have only the mailbox list index and this node
may have a different GUID, so rename it. */
guid_128_generate(guid);
+ node->flags |= MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME;
node->name = p_strdup_printf(ilist->mailbox_pool,
"%s-duplicate-%s", node->name,
guid_128_to_string(guid));
MAILBOX_LIST_INDEX_FLAG_NONEXISTENT = MAIL_DELETED,
MAILBOX_LIST_INDEX_FLAG_NOSELECT = MAIL_DRAFT,
MAILBOX_LIST_INDEX_FLAG_NOINFERIORS = MAIL_ANSWERED,
+ MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME = MAIL_SEEN,
/* set during syncing for mailboxes that still exist */
MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS = MAIL_FLAGGED