Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6687:294af3a8d974 HEAD
idxview rewrite. It now uses lib-index functions to read the files.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 04 Nov 2007 14:48:16 +0200 |
parents | 610f3d9813b5 |
children | 3cd4b722baab |
files | src/util/Makefile.am src/util/idxview.c |
diffstat | 2 files changed, 215 insertions(+), 330 deletions(-) [+] |
line wrap: on
line diff
--- a/src/util/Makefile.am Sun Nov 04 14:47:01 2007 +0200 +++ b/src/util/Makefile.am Sun Nov 04 14:48:16 2007 +0200 @@ -22,6 +22,7 @@ gdbhelper.c idxview_LDADD = \ + ../lib-index/libindex.a \ ../lib/liblib.a idxview_SOURCES = \
--- a/src/util/idxview.c Sun Nov 04 14:47:01 2007 +0200 +++ b/src/util/idxview.c Sun Nov 04 14:48:16 2007 +0200 @@ -4,128 +4,98 @@ #include "array.h" #include "str.h" #include "hex-binary.h" +#include "file-lock.h" #include "mail-index-private.h" #include "mail-cache-private.h" -#include "mail-transaction-log.h" #include <stdio.h> #include <stdlib.h> #include <time.h> -static struct mail_index_header hdr; -static ARRAY_DEFINE(extensions, struct mail_index_ext); -static struct mail_cache_header cache_hdr; -static ARRAY_DEFINE(cache_fields, struct mail_cache_field); -static unsigned int cache_ext = (unsigned int)-1; -static unsigned int cache_search_offset = 0; -static int cache_fd = -1; - -uint32_t mail_index_offset_to_uint32(uint32_t offset) +static const char *unixdate2str(time_t time) { - const unsigned char *buf = (const unsigned char *) &offset; + static char buf[64]; + struct tm *tm; - if ((offset & 0x80808080) != 0x80808080) - return 0; - - return (((uint32_t)buf[3] & 0x7f) << 2) | - (((uint32_t)buf[2] & 0x7f) << 9) | - (((uint32_t)buf[1] & 0x7f) << 16) | - (((uint32_t)buf[0] & 0x7f) << 23); -} - -static size_t get_align(size_t name_len) -{ - size_t size = sizeof(struct mail_index_ext_header) + name_len; - return MAIL_INDEX_HEADER_SIZE_ALIGN(size) - size; + tm = localtime(&time); + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", tm); + return buf; } -static void dump_hdr(int fd) +static void dump_hdr(struct mail_index *index) { - const struct mail_index_ext_header *ext_hdr; - struct mail_index_ext ext; - char *base; - ssize_t ret; - unsigned int i, offset, name_offset; - - ret = read(fd, &hdr, sizeof(hdr)); - if (ret != sizeof(hdr)) { - i_fatal("file hdr read() %"PRIuSIZE_T" != %"PRIuSIZE_T, - ret, sizeof(hdr)); - } + const struct mail_index_header *hdr = &index->map->hdr; + unsigned int i; - printf("version = %u.%u\n", hdr.major_version, hdr.minor_version); - printf("base header size = %u\n", hdr.base_header_size); - printf("header size = %u\n", hdr.header_size); - printf("record size = %u\n", hdr.record_size); - printf("compat flags = %u\n", hdr.compat_flags); - printf("index id = %u\n", hdr.indexid); - printf("flags = %u\n", hdr.flags); - printf("uid validity = %u\n", hdr.uid_validity); - printf("next uid = %u\n", hdr.next_uid); - printf("messages count = %u\n", hdr.messages_count); - printf("seen messages count = %u\n", hdr.seen_messages_count); - printf("deleted messages count = %u\n", hdr.deleted_messages_count); - printf("first recent uid = %u\n", hdr.first_recent_uid); - printf("first unseen uid lowwater = %u\n", hdr.first_unseen_uid_lowwater); - printf("first deleted uid lowwater = %u\n", hdr.first_deleted_uid_lowwater); - printf("log file seq = %u\n", hdr.log_file_seq); - if (hdr.minor_version == 0) { - printf("log file int offset = %u\n", hdr.log_file_tail_offset); - printf("log file ext offset = %u\n", hdr.log_file_head_offset); + printf("version .................. = %u.%u\n", hdr->major_version, hdr->minor_version); + printf("base header size ......... = %u\n", hdr->base_header_size); + printf("header size .............. = %u\n", hdr->header_size); + printf("record size .............. = %u\n", hdr->record_size); + printf("compat flags ............. = %u\n", hdr->compat_flags); + printf("index id ................. = %u (%s)\n", hdr->indexid, unixdate2str(hdr->indexid)); + printf("flags .................... = %u\n", hdr->flags); + printf("uid validity ............. = %u (%s)\n", hdr->uid_validity, unixdate2str(hdr->uid_validity)); + printf("next uid ................. = %u\n", hdr->next_uid); + printf("messages count ........... = %u\n", hdr->messages_count); + printf("seen messages count ...... = %u\n", hdr->seen_messages_count); + printf("deleted messages count ... = %u\n", hdr->deleted_messages_count); + printf("first recent uid ......... = %u\n", hdr->first_recent_uid); + printf("first unseen uid lowwater = %u\n", hdr->first_unseen_uid_lowwater); + printf("first deleted uid lowwater = %u\n", hdr->first_deleted_uid_lowwater); + printf("log file seq ............. = %u\n", hdr->log_file_seq); + if (hdr->minor_version == 0) { + printf("log file int offset ...... = %u\n", hdr->log_file_tail_offset); + printf("log file ext offset ...... = %u\n", hdr->log_file_head_offset); } else { - printf("log file tail offset = %u\n", hdr.log_file_tail_offset); - printf("log file head offset = %u\n", hdr.log_file_head_offset); + printf("log file tail offset ..... = %u\n", hdr->log_file_tail_offset); + printf("log file head offset ..... = %u\n", hdr->log_file_head_offset); } - printf("sync size = %llu\n", (unsigned long long)hdr.sync_size); - printf("sync stamp = %u\n", hdr.sync_stamp); - printf("day stamp = %u\n", hdr.day_stamp); - for (i = 0; i < 8; i++) - printf("day first uid[%u] = %u\n", i, hdr.day_first_uid[i]); + printf("sync size ................ = %llu\n", (unsigned long long)hdr->sync_size); + printf("sync stamp ............... = %u (%s)\n", hdr->sync_stamp, unixdate2str(hdr->sync_stamp)); + printf("day stamp ................ = %u (%s)\n", hdr->day_stamp, unixdate2str(hdr->day_stamp)); + for (i = 0; i < N_ELEMENTS(hdr->day_first_uid); i++) + printf("day first uid[%u] ......... = %u\n", i, hdr->day_first_uid[i]); +} - i_array_init(&extensions, 16); - offset = MAIL_INDEX_HEADER_SIZE_ALIGN(hdr.base_header_size); - if (offset >= hdr.header_size) { +static void dump_extensions(struct mail_index *index) +{ + const struct mail_index_ext *extensions; + unsigned int i, count; + + extensions = array_get(&index->map->extensions, &count); + if (count == 0) { printf("no extensions\n"); return; } - base = i_malloc(hdr.header_size); - ret = pread(fd, base, hdr.header_size, 0); - if (ret != (ssize_t)hdr.header_size) { - i_fatal("file hdr read() %"PRIuSIZE_T" != %u", - ret, hdr.header_size); - } - - memset(&ext, 0, sizeof(ext)); i = 0; - while (offset < hdr.header_size) { - ext_hdr = CONST_PTR_OFFSET(base, offset); - - offset += sizeof(*ext_hdr); - name_offset = offset; - offset += ext_hdr->name_size + get_align(ext_hdr->name_size); - - ext.name = i_strndup(CONST_PTR_OFFSET(base, name_offset), - ext_hdr->name_size); - ext.record_offset = ext_hdr->record_offset; - ext.record_size = ext_hdr->record_size; - ext.record_align = ext_hdr->record_align; - - if (strcmp(ext.name, "cache") == 0) - cache_ext = i; + for (i = 0; i < count; i++) { + const struct mail_index_ext *ext = &extensions[i]; printf("-- Extension %u --\n", i); - printf("name: %s\n", ext.name); - printf("hdr_size: %u\n", ext_hdr->hdr_size); - printf("reset_id: %u\n", ext_hdr->reset_id); - printf("record_offset: %u\n", ext_hdr->record_offset); - printf("record_size: %u\n", ext_hdr->record_size); - printf("record_align: %u\n", ext_hdr->record_align); - printf("name_size: %u\n", ext_hdr->name_size); + printf("name ........ = %s\n", ext->name); + printf("hdr_size .... = %u\n", ext->hdr_size); + printf("reset_id .... = %u\n", ext->reset_id); + printf("record_offset = %u\n", ext->record_offset); + printf("record_size . = %u\n", ext->record_size); + printf("record_align = %u\n", ext->record_align); + } +} - offset += MAIL_INDEX_HEADER_SIZE_ALIGN(ext_hdr->hdr_size); - array_append(&extensions, &ext, 1); - i++; - } +static void dump_keywords(struct mail_index *index) +{ + const unsigned int *kw_indexes; + const char *const *keywords; + unsigned int i, count; + + printf("-- Keywords --\n"); + + kw_indexes = array_get(&index->map->keyword_idx_map, &count); + if (count == 0) + return; + + keywords = array_idx(&index->keywords, 0); + for (i = 0; i < count; i++) + printf("%3u = %s\n", i, keywords[kw_indexes[i]]); } static const char *cache_decision2str(enum mail_cache_decision_type type) @@ -137,7 +107,7 @@ str = "no"; break; case MAIL_CACHE_DECISION_TEMP: - str = "temp"; + str = "tmp"; break; case MAIL_CACHE_DECISION_YES: str = "yes"; @@ -147,7 +117,7 @@ } if ((type & MAIL_CACHE_DECISION_FORCED) != 0) - str = t_strconcat(str, " (forced)", NULL); + str = t_strconcat(str, "!", NULL); return str; } @@ -158,199 +128,107 @@ { switch (type) { case MAIL_CACHE_FIELD_FIXED_SIZE: - return "fixed"; + return "fix"; case MAIL_CACHE_FIELD_VARIABLE_SIZE: - return "variable"; + return "var"; case MAIL_CACHE_FIELD_STRING: - return "string"; + return "str"; case MAIL_CACHE_FIELD_BITMASK: - return "bitmask"; + return "bit"; case MAIL_CACHE_FIELD_HEADER: - return "header"; + return "hdr"; default: return t_strdup_printf("0x%x", type); } } -static const char *unixdate2str(time_t time) -{ - static char buf[64]; - struct tm *tm; - - tm = localtime(&time); - strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", tm); - return buf; -} - -static void dump_cache_hdr(int fd) +static void dump_cache_hdr(struct mail_cache *cache) { - struct mail_cache_header_fields fields; - struct mail_cache_field field; - uint32_t field_offset, next_offset; - char *buf; - ssize_t ret; - const uint32_t *last_used, *size; - const uint8_t *type, *decision; - const char *names; - unsigned int i; + const struct mail_cache_header *hdr; + const struct mail_cache_field *fields, *field; + unsigned int i, count, cache_idx; - ret = read(fd, &cache_hdr, sizeof(cache_hdr)); - if (ret != sizeof(cache_hdr)) { - i_fatal("cache file hdr read() %"PRIuSIZE_T" != %"PRIuSIZE_T, - ret, sizeof(cache_hdr)); + (void)mail_cache_open_and_verify(cache); + if (MAIL_CACHE_IS_UNUSABLE(cache)) { + printf("cache is unusable\n"); + return; } - field_offset = - mail_index_offset_to_uint32(cache_hdr.field_header_offset); - - printf("Cache header:\n"); - printf("version: %u\n", cache_hdr.version); - printf("indexid: %u\n", cache_hdr.indexid); - printf("file_seq: %u\n", cache_hdr.file_seq); - printf("continued_record_count: %u\n", cache_hdr.continued_record_count); - printf("hole_offset: %u\n", cache_hdr.hole_offset); - printf("used_file_size: %u\n", cache_hdr.used_file_size); - printf("deleted_space: %u\n", cache_hdr.deleted_space); - printf("field_header_offset: %u / %u\n", - cache_hdr.field_header_offset, field_offset); - - for (;;) { - ret = pread(fd, &fields, sizeof(fields), field_offset); - if (ret != sizeof(fields)) { - i_fatal("cache file fields read() %" - PRIuSIZE_T" != %"PRIuSIZE_T, - ret, sizeof(fields)); - } - - next_offset = - mail_index_offset_to_uint32(fields.next_offset); - if (next_offset == 0) - break; - - field_offset = next_offset; - } - - printf("-- Cache fields: --\n"); - printf("actual used header offset: %u\n", field_offset); + hdr = cache->hdr; + printf("version .............. = %u\n", hdr->version); + printf("indexid .............. = %u (%s)\n", hdr->indexid, unixdate2str(hdr->indexid)); + printf("file_seq ............. = %u (%s)\n", hdr->file_seq, unixdate2str(hdr->file_seq)); + printf("continued_record_count = %u\n", hdr->continued_record_count); + printf("hole_offset .......... = %u\n", hdr->hole_offset); + printf("used_file_size ....... = %u\n", hdr->used_file_size); + printf("deleted_space ........ = %u\n", hdr->deleted_space); + printf("field_header_offset .. = %u (0x%08x nontranslated)\n", + mail_index_offset_to_uint32(hdr->field_header_offset), + hdr->field_header_offset); - buf = i_malloc(fields.size); - ret = pread(fd, buf, fields.size, field_offset); - if (ret != (ssize_t)fields.size) { - i_fatal("cache file fields read() %"PRIuSIZE_T" != %u", - ret, fields.size); - } - printf("fields_count: %u\n", fields.fields_count); - - if (fields.fields_count > 10000) - i_fatal("Broken fields_count"); - - last_used = CONST_PTR_OFFSET(buf, MAIL_CACHE_FIELD_LAST_USED()); - size = CONST_PTR_OFFSET(buf, MAIL_CACHE_FIELD_SIZE(fields.fields_count)); - type = CONST_PTR_OFFSET(buf, MAIL_CACHE_FIELD_TYPE(fields.fields_count)); - decision = CONST_PTR_OFFSET(buf, MAIL_CACHE_FIELD_DECISION(fields.fields_count)); - names = CONST_PTR_OFFSET(buf, MAIL_CACHE_FIELD_NAMES(fields.fields_count)); + printf("-- Cache fields --\n"); + fields = mail_cache_register_get_list(cache, pool_datastack_create(), + &count); + printf( +" # Name Type Size Dec Last used\n"); + for (i = 0; i < cache->file_fields_count; i++) { + cache_idx = cache->file_field_map[i]; + field = &fields[cache_idx]; - if ((unsigned int)(names - (const char *)buf) >= fields.size) - i_fatal("Fields go outside allocated size"); - - i_array_init(&cache_fields, 64); - memset(&field, 0, sizeof(field)); - for (i = 0; i < fields.fields_count; i++) { - field.name = names; - - field.field_size = size[i]; - field.type = type[i]; - field.decision = decision[i]; - array_append(&cache_fields, &field, 1); - - printf("#%u %s: type=%s ", i, names, cache_type2str(type[i])); - if (size[i] != (uint32_t)-1 || - CACHE_TYPE_IS_FIXED_SIZE(type[i])) - printf("size=%u ", size[i]); - printf("decision=%s last_used=%s\n", - cache_decision2str(decision[i]), - unixdate2str(last_used[i])); - names += strlen(names) + 1; + printf("%2u: %-44s %-4s ", i, field->name, + cache_type2str(field->type)); + if (field->field_size != (uint32_t)-1 || + CACHE_TYPE_IS_FIXED_SIZE(field->type)) + printf("%4u ", field->field_size); + else + printf(" - "); + printf("%-4s %s\n", + cache_decision2str(field->decision), + unixdate2str(cache->fields[cache_idx].last_used)); } } -static void dump_cache(uint32_t offset) +static void dump_cache(struct mail_cache_view *cache_view, unsigned int seq) { - const struct mail_cache_field *fields; - struct mail_cache_record rec; - ssize_t ret; - char *buf; - unsigned int idx, size, pos, next_pos, cache_fields_count; + struct mail_cache_lookup_iterate_ctx iter; + const struct mail_cache_record *prev_rec = NULL; + const struct mail_cache_field *field; + struct mail_cache_iterate_field iter_field; + const void *data; + unsigned int size; string_t *str; - - if (offset == 0 || cache_fd == -1) - return; - - ret = pread(cache_fd, &rec, sizeof(rec), offset); - if (ret != sizeof(rec)) { - printf(" - cache at %u BROKEN: points outside file\n", offset); - return; - } + int ret; - if (rec.size == 0 || rec.size > 1000000) { - printf(" - cache at %u BROKEN: rec.size = %u\n", - offset, rec.size); - return; - } - - if (offset <= cache_search_offset && - offset + rec.size > cache_search_offset) - printf(" - SEARCH MATCH\n"); - - buf = t_malloc(rec.size); - ret = pread(cache_fd, buf, rec.size, offset); - if (ret != (ssize_t)rec.size) - i_fatal("cache rec read() %"PRIuSIZE_T" != %u", ret, rec.size); - printf(" - cache at %u + %u (prev_offset = %u)\n", - offset, rec.size, rec.prev_offset); - - fields = array_get(&cache_fields, &cache_fields_count); str = t_str_new(512); - for (pos = sizeof(rec); pos < rec.size; ) { - idx = *((const uint32_t *)(buf+pos)); - pos += sizeof(uint32_t); - - if (idx >= cache_fields_count) { - printf("BROKEN: file_field = %u > %u\n", - idx, cache_fields_count); - return; + mail_cache_lookup_iter_init(cache_view, seq, &iter); + while ((ret = mail_cache_lookup_iter_next(&iter, &iter_field)) > 0) { + if (iter.rec != prev_rec) { + printf(" - cache offset=%u size=%u, prev_offset = %u\n", + iter.offset, iter.rec->size, + iter.rec->prev_offset); + prev_rec = iter.rec; } - size = fields[idx].field_size; - if (size == (unsigned int)-1) { - size = *((const uint32_t *)(buf+pos)); - pos += sizeof(uint32_t); - } - - next_pos = pos + ((size + 3) & ~3); - if (size > rec.size || next_pos > rec.size) { - printf("BROKEN: record continues outside its allocated size\n"); - return; - } + field = &cache_view->cache->fields[iter_field.field_idx].field; + data = iter_field.data; + size = iter_field.size; str_truncate(str, 0); - str_printfa(str, " - %s: ", fields[idx].name); - switch (fields[idx].type) { + str_printfa(str, " - %s: ", field->name); + switch (field->type) { case MAIL_CACHE_FIELD_FIXED_SIZE: - if (size == sizeof(uint32_t)) { - str_printfa(str, "%u", *((const uint32_t *)(buf+pos))); - break; - } + if (size == sizeof(uint32_t)) + str_printfa(str, "%u ", *((const uint32_t *)data)); case MAIL_CACHE_FIELD_VARIABLE_SIZE: case MAIL_CACHE_FIELD_BITMASK: - str_printfa(str, " (%s)", binary_to_hex((const unsigned char *)buf+pos, size)); + str_printfa(str, "(%s)", binary_to_hex(data, size)); break; case MAIL_CACHE_FIELD_STRING: if (size > 0) - str_printfa(str, "%.*s", (int)size, buf+pos); + str_printfa(str, "%.*s", (int)size, (const char *)data); break; case MAIL_CACHE_FIELD_HEADER: { - const uint32_t *lines = (void *)(buf + pos); + const uint32_t *lines = data; int i; for (i = 0;; i++) { @@ -366,7 +244,7 @@ } size -= sizeof(uint32_t); - pos += sizeof(uint32_t); + data = CONST_PTR_OFFSET(data, sizeof(uint32_t)); if (lines[i] == 0) break; @@ -375,9 +253,11 @@ str_printfa(str, "%u", lines[i]); } - if (i == 1 && size > 0 && buf[pos+size-1] == '\n') size--; + if (i == 1 && size > 0 && + ((const char *)data)[size-1] == '\n') + size--; if (size > 0) - str_printfa(str, ": %.*s", (int)size, buf+pos); + str_printfa(str, ": %.*s", (int)size, (const char *)data); break; } case MAIL_CACHE_FIELD_COUNT: @@ -386,107 +266,111 @@ } printf("%s\n", str_c(str)); - pos = next_pos; } - - dump_cache(rec.prev_offset); + if (ret < 0) + printf(" - broken cache\n"); } -static int dump_record(int fd, void *buf, unsigned int seq) +static const char *flags2str(enum mail_flags flags) { - off_t offset; - ssize_t ret; - const struct mail_index_record *rec = buf; - const struct mail_index_ext *ext; - const void *ptr; - unsigned int i, ext_count; string_t *str; - ret = read(fd, buf, hdr.record_size); - if (ret == 0) - return 0; + str = t_str_new(64); + str_append_c(str, '('); + if ((flags & MAIL_SEEN) != 0) + str_append(str, "Seen "); + if ((flags & MAIL_ANSWERED) != 0) + str_append(str, "Answered "); + if ((flags & MAIL_FLAGGED) != 0) + str_append(str, "Flagged "); + if ((flags & MAIL_DELETED) != 0) + str_append(str, "Deleted "); + if ((flags & MAIL_DRAFT) != 0) + str_append(str, "Draft "); + if (str_len(str) == 1) + return ""; - if (ret != (ssize_t)hdr.record_size) { - i_fatal("rec hdr read() %"PRIuSIZE_T" != %u", - ret, hdr.record_size); - } - - offset = lseek(fd, 0, SEEK_CUR); + str_truncate(str, str_len(str)-1); + str_append_c(str, ')'); + return str_c(str); +} - printf("RECORD: offset=%"PRIuUOFF_T", seq=%u, uid=%u, flags=%x\n", - offset, seq, rec->uid, rec->flags); +static void dump_record(struct mail_index_view *view, unsigned int seq) +{ + struct mail_index *index = mail_index_view_get_index(view); + const struct mail_index_record *rec; + const struct mail_index_ext *ext; + const void *data; + unsigned int i, ext_count; + string_t *str; + bool expunged; + + rec = MAIL_INDEX_MAP_IDX(index->map, seq-1); + printf("RECORD: seq=%u, uid=%u, flags=0x%02x %s\n", + seq, rec->uid, rec->flags, flags2str(rec->flags)); + str = t_str_new(256); - ext = array_get(&extensions, &ext_count); + ext = array_get(&index->map->extensions, &ext_count); for (i = 0; i < ext_count; i++) { - if (ext[i].record_size == 0) + mail_index_lookup_ext(view, seq, i, &data, &expunged); + if (data == NULL || ext[i].record_size == 0) continue; + str_truncate(str, 0); - str_printfa(str, " - ext %s(%u): ", ext[i].name, i); - - ptr = CONST_PTR_OFFSET(buf, ext[i].record_offset); + str_printfa(str, " - ext %d %s: ", i, ext[i].name); if (ext[i].record_size == sizeof(uint32_t) && ext[i].record_align == sizeof(uint32_t)) - str_printfa(str, "%u", *((const uint32_t *)ptr)); + str_printfa(str, "%u", *((const uint32_t *)data)); else if (ext[i].record_size == sizeof(uint64_t) && ext[i].record_align == sizeof(uint64_t)) { - uint64_t value = *((const uint64_t *)ptr); + uint64_t value = *((const uint64_t *)data); str_printfa(str, "%llu", (unsigned long long)value); } - str_printfa(str, " (%s)", binary_to_hex(ptr, ext[i].record_size)); + str_printfa(str, " (%s)", + binary_to_hex(data, ext[i].record_size)); printf("%s\n", str_c(str)); - - if (i == cache_ext) - dump_cache(*((const uint32_t *)ptr)); } - return 1; } int main(int argc, const char *argv[]) { + struct mail_index *index; + struct mail_index_view *view; + struct mail_cache_view *cache_view; unsigned int seq; - void *buf; - int fd, ret; lib_init(); if (argc < 2) - i_fatal("Usage: idxview dovecot.index [dovecot.index.cache]"); + i_fatal("Usage: idxview <index dir>"); - fd = open(argv[1], O_RDONLY); - if (fd < 0) { - i_error("open(): %m"); - return 1; + index = mail_index_alloc(argv[1], "dovecot.index"); + if (mail_index_open(index, MAIL_INDEX_OPEN_FLAG_READONLY, + FILE_LOCK_METHOD_FCNTL) <= 0) { + i_fatal("Couldn't open index %s: %s", argv[1], + mail_index_get_error_message(index)); } - - printf("-- INDEX: %s\n", argv[1]); - - dump_hdr(fd); - lseek(fd, hdr.header_size, SEEK_SET); - - printf("---------------\n"); + view = mail_index_view_open(index); + cache_view = mail_cache_view_open(index->cache, view); - if (argv[2] != NULL) { - cache_fd = open(argv[2], O_RDONLY); - if (cache_fd < 0) { - i_error("open(): %m"); - return 1; - } + printf("-- INDEX: %s\n", index->filepath); + dump_hdr(index); + dump_extensions(index); + dump_keywords(index); - dump_cache_hdr(cache_fd); - - printf("---------------\n"); + printf("\n-- CACHE: %s\n", index->cache->filepath); + dump_cache_hdr(index->cache); - if (argv[3] != NULL) - cache_search_offset = atoi(argv[3]); + printf("\n-- RECORDS: %u\n", index->map->hdr.messages_count); + for (seq = 1; seq <= index->map->hdr.messages_count; seq++) { + t_push(); + dump_record(view, seq); + dump_cache(cache_view, seq); + t_pop(); } - - buf = i_malloc(hdr.record_size); - seq = 1; - do { - t_push(); - ret = dump_record(fd, buf, seq); - t_pop(); - seq++; - } while (ret); + mail_cache_view_close(cache_view); + mail_index_view_close(&view); + mail_index_close(index); + mail_index_free(&index); return 0; }