dovecot-2.2: lib-storage: Mailbox list index now detects duplica...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Nov 11 01:12:50 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/e5cf0209bc9e
changeset: 18054:e5cf0209bc9e
user: Timo Sirainen <tss at iki.fi>
date: Fri Oct 31 04:27:27 2014 +0200
description:
lib-storage: Mailbox list index now detects duplicate mailbox names.
With LAYOUT=index the duplicates are renamed.
diffstat:
src/lib-storage/list/mailbox-list-index.c | 48 +++++++++++++++++++++++++++++-
1 files changed, 45 insertions(+), 3 deletions(-)
diffs (103 lines):
diff -r 8fe127697587 -r e5cf0209bc9e src/lib-storage/list/mailbox-list-index.c
--- a/src/lib-storage/list/mailbox-list-index.c Wed Nov 05 13:00:14 2014 +0200
+++ b/src/lib-storage/list/mailbox-list-index.c Fri Oct 31 04:27:27 2014 +0200
@@ -238,11 +238,27 @@
ilist->highest_name_id = node->name_id;
}
+static int mailbox_list_index_node_cmp(const struct mailbox_list_index_node *n1,
+ const struct mailbox_list_index_node *n2)
+{
+ return n1->parent == n2->parent &&
+ strcmp(n1->name, n2->name) == 0 ? 0 : -1;
+}
+
+static unsigned int
+mailbox_list_index_node_hash(const struct mailbox_list_index_node *node)
+{
+ return str_hash(node->name) ^
+ POINTER_CAST_TO(node->parent, unsigned int);
+}
+
static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist,
struct mail_index_view *view,
const char **error_r)
{
struct mailbox_list_index_node *node;
+ HASH_TABLE(struct mailbox_list_index_node *,
+ struct mailbox_list_index_node *) duplicate_hash;
const struct mail_index_record *rec;
const struct mailbox_list_index_record *irec;
const void *data;
@@ -251,6 +267,9 @@
*error_r = NULL;
+ hash_table_create(&duplicate_hash, default_pool, 0,
+ mailbox_list_index_node_hash,
+ mailbox_list_index_node_cmp);
count = mail_index_view_get_messages_count(view);
for (seq = 1; seq <= count; seq++) {
node = p_new(ilist->mailbox_pool,
@@ -263,7 +282,7 @@
&data, &expunged);
if (data == NULL) {
*error_r = "Missing list extension data";
- return -1;
+ break;
}
irec = data;
@@ -273,7 +292,7 @@
if (node->name == NULL) {
*error_r = "name_id not in index header";
if (ilist->has_backing_store)
- return -1;
+ break;
/* generate a new name and use it */
mailbox_list_index_generate_name(ilist, node);
}
@@ -284,6 +303,8 @@
/* do a second scan to create the actual mailbox tree hierarchy.
this is needed because the parent_uid may be smaller or higher than
the current node's uid */
+ if (*error_r != NULL)
+ count = 0;
for (seq = 1; seq <= count; seq++) {
mail_index_lookup_uid(view, seq, &uid);
mail_index_lookup_ext(view, seq, ilist->ext_id,
@@ -304,12 +325,33 @@
}
*error_r = "parent_uid points to nonexistent record";
if (ilist->has_backing_store)
- return -1;
+ break;
/* just place it under the root */
}
+ if (hash_table_lookup(duplicate_hash, node) == NULL)
+ hash_table_insert(duplicate_hash, node, node);
+ else {
+ guid_128_t guid;
+
+ if (ilist->has_backing_store) {
+ *error_r = "Duplicate mailbox in index";
+ break;
+ }
+
+ /* we have only the mailbox list index and this node
+ may have a different GUID, so rename it. */
+ guid_128_generate(guid);
+ node->name = p_strdup_printf(ilist->mailbox_pool,
+ "%s-duplicate-%s", node->name,
+ guid_128_to_string(guid));
+ *error_r = t_strdup_printf(
+ "Duplicate mailbox in index, renaming to %s",
+ node->name);
+ }
node->next = ilist->mailbox_tree;
ilist->mailbox_tree = node;
}
+ hash_table_destroy(&duplicate_hash);
return *error_r == NULL ? 0 : -1;
}
More information about the dovecot-cvs
mailing list