Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8742:37e118a32cd0 HEAD
Minor changes to mailbox list indexing code. Still disabled/non-working.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 10 Feb 2009 12:46:14 -0500 |
parents | d74fdb84ab8b |
children | c21c082aebb6 |
files | src/lib-index/mailbox-list-index-private.h src/lib-index/mailbox-list-index.c |
diffstat | 2 files changed, 49 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mailbox-list-index-private.h Tue Feb 10 12:19:05 2009 -0500 +++ b/src/lib-index/mailbox-list-index-private.h Tue Feb 10 12:46:14 2009 -0500 @@ -32,26 +32,30 @@ /* If non-zero, contains a pointer to updated directory list. Stored using mail_index_uint32_to_offset(). */ uint32_t next_offset; - /* Bytes used by this record, including mailbox names. */ + /* Bytes required to be able to fully read this directory's records. + This includes also bytes used by mailbox names that follow the + records (but doesn't include bytes for mailbox names that point + to earlier offsets in the file). */ uint32_t dir_size; uint32_t count; - /* The records are sorted by their name_hash */ + /* The records are sorted 1) by their name_hash, 2) the actual name */ /* struct mailbox_list_record records[count]; */ }; struct mailbox_list_record { /* CRC32 hash of the name */ uint32_t name_hash; - uint32_t uid:31; + unsigned int uid:31; /* Set when this record has been marked as deleted. It will be removed permanently the next time a new record is added to this directory or on the next index compression. */ - uint32_t deleted:1; + unsigned int deleted:1; /* Points to a NUL-terminated record name */ uint32_t name_offset; - /* the dir offset is stored using mail_index_uint32_to_offset() + /* Pointer to child mailboxes or 0 if there are no children. + The offset is stored using mail_index_uint32_to_offset() since it may change while we're reading */ uint32_t dir_offset; };
--- a/src/lib-index/mailbox-list-index.c Tue Feb 10 12:19:05 2009 -0500 +++ b/src/lib-index/mailbox-list-index.c Tue Feb 10 12:46:14 2009 -0500 @@ -388,8 +388,9 @@ const char *name; if (rec->name_offset >= index->mmap_size) { - mailbox_list_index_set_corrupted(index, - "record name_offset points outside file"); + mailbox_list_index_set_corrupted(index, t_strdup_printf( + "record name_offset (%u) points outside file (%u)", + rec->name_offset, index->mmap_size)); return -1; } max_len = index->mmap_size - rec->name_offset; @@ -398,32 +399,11 @@ because practically it always is even if the file is corrupted. just make sure we don't crash if it happens. */ *name_r = p_strndup(pool, name, max_len); - return 0; -} - -static int mailbox_list_record_cmp(const void *_key, const void *_rec) -{ - const struct mailbox_list_index_lookup_key *key = _key; - const struct mailbox_list_record *rec = _rec; - int ret; - - if (key->name_hash < rec->name_hash) + if (*name_r == '\0') { + mailbox_list_index_set_corrupted(index, "Empty mailbox name"); return -1; - if (key->name_hash > rec->name_hash) - return 1; - - T_BEGIN { - const char *name; - - if (mailbox_list_get_name(key->index, unsafe_data_stack_pool, - rec, &name) < 0) { - *key->failed = TRUE; - ret = -1; - } else { - ret = strcmp(key->name, name); - } - } T_END; - return ret; + } + return 0; } int mailbox_list_index_get_dir(struct mailbox_list_index_view *view, @@ -457,6 +437,12 @@ return mailbox_list_index_set_corrupted(index, "next_offset points backwards"); } + + if (dir->count > + index->mmap_size / sizeof(struct mailbox_list_record)) { + return mailbox_list_index_set_corrupted(index, + "dir count too large"); + } if (dir->dir_size < sizeof(*dir) + dir->count * sizeof(struct mailbox_list_record)) { return mailbox_list_index_set_corrupted(index, @@ -465,13 +451,7 @@ cur_offset = next_offset; } while (cur_offset != 0); - if (dir->count > INT_MAX/sizeof(struct mailbox_list_record)) { - mailbox_list_index_set_corrupted(index, "dir count too large"); - return -1; - } - cur_offset = (const char *)dir - (const char *)index->const_mmap_base; - ret = mailbox_list_index_map_area(index, cur_offset, dir->dir_size); if (ret <= 0) { if (ret < 0) @@ -485,6 +465,31 @@ return 0; } +static int mailbox_list_record_cmp(const void *_key, const void *_rec) +{ + const struct mailbox_list_index_lookup_key *key = _key; + const struct mailbox_list_record *rec = _rec; + int ret; + + if (key->name_hash < rec->name_hash) + return -1; + if (key->name_hash > rec->name_hash) + return 1; + + T_BEGIN { + const char *name; + + if (mailbox_list_get_name(key->index, unsafe_data_stack_pool, + rec, &name) < 0) { + *key->failed = TRUE; + ret = 0; + } else { + ret = strcmp(key->name, name); + } + } T_END; + return ret; +} + int mailbox_list_index_dir_lookup_rec(struct mailbox_list_index *index, const struct mailbox_list_dir_record *dir, const char *name, @@ -578,7 +583,8 @@ const struct mail_index_header *mail_hdr; mail_hdr = mail_view != NULL ? mail_index_get_header(mail_view) : NULL; - if (mail_hdr != NULL && index->hdr != NULL && + if (mail_hdr != NULL && mail_hdr->uid_validity != 0 && + index->hdr != NULL && mail_hdr->uid_validity != index->hdr->uid_validity) { mail_index_set_error(index->mail_index, "uid_validity mismatch in file %s: %u != %u",