idxview.c revision 690bafa70767e3f6e98bbfd62ad4a26be2387ea9
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2007-2008 Dovecot authors, see the included COPYING file */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "lib.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "array.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "str.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "hex-binary.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "file-lock.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "mail-index-private.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "mail-cache-private.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "mail-cache-private.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "mail-index-modseq.h"
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include <stdio.h>
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include <stdlib.h>
1d738cce754bc64bbc66d3355ebdaf3f6eac55f1Timo Sirainen#include <time.h>
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstruct maildir_index_header {
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen uint32_t new_check_time, new_mtime, new_mtime_nsecs;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen uint32_t cur_check_time, cur_mtime, cur_mtime_nsecs;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen uint32_t uidlist_mtime, uidlist_mtime_nsecs, uidlist_size;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen};
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainenstruct mbox_index_header {
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen uint64_t sync_size;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen uint32_t sync_mtime;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen uint8_t dirty_flag;
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen uint8_t unused[3];
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen};
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainenstruct dbox_index_header {
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen uint32_t last_dirty_flush_stamp;
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen};
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainenstruct virtual_mail_index_record {
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen uint32_t mailbox_id;
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen uint32_t real_uid;
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen};
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainenstatic const char *unixdate2str(time_t timestamp)
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen{
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen static char buf[64];
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen struct tm *tm;
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen tm = localtime(&timestamp);
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", tm);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return buf;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic void dump_hdr(struct mail_index *index)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_index_header *hdr = &index->map->hdr;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen unsigned int i;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen printf("version .................. = %u.%u\n", hdr->major_version, hdr->minor_version);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("base header size ......... = %u\n", hdr->base_header_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("header size .............. = %u\n", hdr->header_size);
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen printf("record size .............. = %u\n", hdr->record_size);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen printf("compat flags ............. = %u\n", hdr->compat_flags);
b397665e90fa0fc7c6a9156fdd6cf28b571e8e39Timo Sirainen printf("index id ................. = %u (%s)\n", hdr->indexid, unixdate2str(hdr->indexid));
b397665e90fa0fc7c6a9156fdd6cf28b571e8e39Timo Sirainen printf("flags .................... = %u\n", hdr->flags);
b397665e90fa0fc7c6a9156fdd6cf28b571e8e39Timo Sirainen printf("uid validity ............. = %u (%s)\n", hdr->uid_validity, unixdate2str(hdr->uid_validity));
b397665e90fa0fc7c6a9156fdd6cf28b571e8e39Timo Sirainen printf("next uid ................. = %u\n", hdr->next_uid);
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen printf("messages count ........... = %u\n", hdr->messages_count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("seen messages count ...... = %u\n", hdr->seen_messages_count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("deleted messages count ... = %u\n", hdr->deleted_messages_count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("first recent uid ......... = %u\n", hdr->first_recent_uid);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("first unseen uid lowwater = %u\n", hdr->first_unseen_uid_lowwater);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("first deleted uid lowwater = %u\n", hdr->first_deleted_uid_lowwater);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("log file seq ............. = %u\n", hdr->log_file_seq);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (hdr->minor_version == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("log file int offset ...... = %u\n", hdr->log_file_tail_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("log file ext offset ...... = %u\n", hdr->log_file_head_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("log file tail offset ..... = %u\n", hdr->log_file_tail_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("log file head offset ..... = %u\n", hdr->log_file_head_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("sync size ................ = %llu\n", (unsigned long long)hdr->sync_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("sync stamp ............... = %u (%s)\n", hdr->sync_stamp, unixdate2str(hdr->sync_stamp));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("day stamp ................ = %u (%s)\n", hdr->day_stamp, unixdate2str(hdr->day_stamp));
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen for (i = 0; i < N_ELEMENTS(hdr->day_first_uid); i++)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("day first uid[%u] ......... = %u\n", i, hdr->day_first_uid[i]);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic void dump_extension_header(struct mail_index *index,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_index_ext *ext)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const void *data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (strcmp(ext->name, "keywords") == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data = CONST_PTR_OFFSET(index->map->hdr_base, ext->hdr_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (strcmp(ext->name, "maildir") == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct maildir_index_header *hdr = data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("header\n");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - new_check_time .... = %s\n", unixdate2str(hdr->new_check_time));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - new_mtime ......... = %s\n", unixdate2str(hdr->new_mtime));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - new_mtime_nsecs ... = %u\n", hdr->new_mtime_nsecs);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - cur_check_time .... = %s\n", unixdate2str(hdr->cur_check_time));
0f66f12eb4cdbf47670975044c88d8f388bf92dfTimo Sirainen printf(" - cur_mtime ......... = %s\n", unixdate2str(hdr->cur_mtime));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - cur_mtime_nsecs.... = %u\n", hdr->cur_mtime_nsecs);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - uidlist_mtime ..... = %s\n", unixdate2str(hdr->uidlist_mtime));
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen printf(" - uidlist_mtime_nsecs = %u\n", hdr->uidlist_mtime_nsecs);
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen printf(" - uidlist_size ...... = %u\n", hdr->uidlist_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else if (strcmp(ext->name, "mbox") == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mbox_index_header *hdr = data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen printf("header\n");
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen printf(" - sync_mtime = %s\n", unixdate2str(hdr->sync_mtime));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - sync_size = %llu\n",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen (unsigned long long)hdr->sync_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - dirty_flag = %d\n", hdr->dirty_flag);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else if (strcmp(ext->name, "dbox-hdr") == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct dbox_index_header *hdr = data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("header\n");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - last_dirty_flush_stamp = %s\n", unixdate2str(hdr->last_dirty_flush_stamp));
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen } else if (strcmp(ext->name, "modseq") == 0) {
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen const struct mail_index_modseq_header *hdr = data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("header\n");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen printf(" - highest_modseq = %llu\n",
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen (unsigned long long)hdr->highest_modseq);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf(" - log_seq ...... = %u\n", hdr->log_seq);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - log_offset ... = %u\n", hdr->log_offset);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen } else {
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("header ........ = %s\n",
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen binary_to_hex(data, ext->hdr_size));
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen }
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen}
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainenstatic void dump_extensions(struct mail_index *index)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen{
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen const struct mail_index_ext *extensions;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen unsigned int i, count;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (array_is_created(&index->map->extensions))
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen extensions = array_get(&index->map->extensions, &count);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen else
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen count = 0;
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen if (count == 0) {
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("no extensions\n");
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen return;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen }
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
0bf3eac1110a902e7ec7e695c64e8e46c114e623Timo Sirainen for (i = 0; i < count; i++) {
0bf3eac1110a902e7ec7e695c64e8e46c114e623Timo Sirainen const struct mail_index_ext *ext = &extensions[i];
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("-- Extension %u --\n", i);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("name ........ = %s\n", ext->name);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("hdr_size .... = %u\n", ext->hdr_size);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("reset_id .... = %u\n", ext->reset_id);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("record_offset = %u\n", ext->record_offset);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("record_size . = %u\n", ext->record_size);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("record_align = %u\n", ext->record_align);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (ext->hdr_size > 0)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen dump_extension_header(index, ext);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen }
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen}
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic void dump_keywords(struct mail_index *index)
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen{
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen const unsigned int *kw_indexes;
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen const char *const *keywords;
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen unsigned int i, count;
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen
dffa503fd4ce31334346e539496084c80a2d8d37Timo Sirainen printf("-- Keywords --\n");
dffa503fd4ce31334346e539496084c80a2d8d37Timo Sirainen if (!array_is_created(&index->map->keyword_idx_map))
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen return;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen kw_indexes = array_get(&index->map->keyword_idx_map, &count);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (count == 0)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen return;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen keywords = array_idx(&index->keywords, 0);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen for (i = 0; i < count; i++)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen printf("%3u = %s\n", i, keywords[kw_indexes[i]]);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic const char *cache_decision2str(enum mail_cache_decision_type type)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const char *str;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen switch (type & ~MAIL_CACHE_DECISION_FORCED) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_DECISION_NO:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str = "no";
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_DECISION_TEMP:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str = "tmp";
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_DECISION_YES:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str = "yes";
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen default:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return t_strdup_printf("0x%x", type);
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((type & MAIL_CACHE_DECISION_FORCED) != 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str = t_strconcat(str, "!", NULL);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return str;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#define CACHE_TYPE_IS_FIXED_SIZE(type) \
40ad2c4902e9d83557f2e8a4bff3d98fea2c8aa1Timo Sirainen ((type) == MAIL_CACHE_FIELD_FIXED_SIZE || \
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen (type) == MAIL_CACHE_FIELD_BITMASK)
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainenstatic const char *cache_type2str(enum mail_cache_field_type type)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen switch (type) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_FIELD_FIXED_SIZE:
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen return "fix";
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen case MAIL_CACHE_FIELD_VARIABLE_SIZE:
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen return "var";
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen case MAIL_CACHE_FIELD_STRING:
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen return "str";
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen case MAIL_CACHE_FIELD_BITMASK:
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen return "bit";
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen case MAIL_CACHE_FIELD_HEADER:
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen return "hdr";
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen default:
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen return t_strdup_printf("0x%x", type);
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen }
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen}
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainenstatic void dump_cache_hdr(struct mail_cache *cache)
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const struct mail_cache_header *hdr;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const struct mail_cache_field *fields, *field;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen unsigned int i, count, cache_idx;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen (void)mail_cache_open_and_verify(cache);
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen if (MAIL_CACHE_IS_UNUSABLE(cache)) {
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen printf("cache is unusable\n");
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen return;
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen }
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen hdr = cache->hdr;
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen printf("version .............. = %u\n", hdr->version);
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen printf("indexid .............. = %u (%s)\n", hdr->indexid, unixdate2str(hdr->indexid));
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen printf("file_seq ............. = %u (%s) (%d compressions)\n",
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen hdr->file_seq, unixdate2str(hdr->file_seq),
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen hdr->file_seq - hdr->indexid);
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen printf("continued_record_count = %u\n", hdr->continued_record_count);
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen printf("hole_offset .......... = %u\n", hdr->hole_offset);
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen printf("used_file_size ....... = %u\n", hdr->used_file_size);
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen printf("deleted_space ........ = %u\n", hdr->deleted_space);
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen printf("field_header_offset .. = %u (0x%08x nontranslated)\n",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_offset_to_uint32(hdr->field_header_offset),
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen hdr->field_header_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("-- Cache fields --\n");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen fields = mail_cache_register_get_list(cache, pool_datastack_create(),
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen &count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen" # Name Type Size Dec Last used\n");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (i = 0; i < cache->file_fields_count; i++) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen cache_idx = cache->file_field_map[i];
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen field = &fields[cache_idx];
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("%2u: %-44s %-4s ", i, field->name,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen cache_type2str(field->type));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (field->field_size != (uint32_t)-1 ||
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen CACHE_TYPE_IS_FIXED_SIZE(field->type))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("%4u ", field->field_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen else
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - ");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("%-4s %s\n",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen cache_decision2str(field->decision),
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen unixdate2str(cache->fields[cache_idx].last_used));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic void dump_cache(struct mail_cache_view *cache_view, unsigned int seq)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_cache_lookup_iterate_ctx iter;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_cache_record *prev_rec = NULL;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_cache_field *field;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_cache_iterate_field iter_field;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const void *data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen unsigned int size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen string_t *str;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen int ret;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str = t_str_new(512);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_cache_lookup_iter_init(cache_view, seq, &iter);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen while ((ret = mail_cache_lookup_iter_next(&iter, &iter_field)) > 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (iter.rec != prev_rec) {
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen printf(" - cache offset=%u size=%u, prev_offset = %u\n",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen iter.offset, iter.rec->size,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen iter.rec->prev_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen prev_rec = iter.rec;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
5707510e5d1c8aa79a0acf737ee1429caf3d59c2Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen field = &cache_view->cache->fields[iter_field.field_idx].field;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data = iter_field.data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen size = iter_field.size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_truncate(str, 0);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, " - %s: ", field->name);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen switch (field->type) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_FIELD_FIXED_SIZE:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (size == sizeof(uint32_t))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, "%u ", *((const uint32_t *)data));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen else if (size == sizeof(uint64_t))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, "%llu ", (unsigned long long)*((const uint64_t *)data));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_FIELD_VARIABLE_SIZE:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_FIELD_BITMASK:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, "(%s)", binary_to_hex(data, size));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen case MAIL_CACHE_FIELD_STRING:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (size > 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, "%.*s", (int)size, (const char *)data);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_FIELD_HEADER: {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const uint32_t *lines = data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen int i;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (i = 0;; i++) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (size < sizeof(uint32_t)) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (i == 0 && size == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* header doesn't exist */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen str_append(str, "\n - BROKEN: header field doesn't end with 0 line");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen size = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen size -= sizeof(uint32_t);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data = CONST_PTR_OFFSET(data, sizeof(uint32_t));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (lines[i] == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (i > 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_append(str, ", ");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, "%u", lines[i]);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen if (i == 1 && size > 0 &&
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen ((const char *)data)[size-1] == '\n')
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen size--;
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen if (size > 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, ": %.*s", (int)size, (const char *)data);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen case MAIL_CACHE_FIELD_COUNT:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_unreached();
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("%s\n", str_c(str));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (ret < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf(" - broken cache\n");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic const char *flags2str(enum mail_flags flags)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen string_t *str;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str = t_str_new(64);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_append_c(str, '(');
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((flags & MAIL_SEEN) != 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_append(str, "Seen ");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((flags & MAIL_ANSWERED) != 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_append(str, "Answered ");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((flags & MAIL_FLAGGED) != 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_append(str, "Flagged ");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((flags & MAIL_DELETED) != 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_append(str, "Deleted ");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((flags & MAIL_DRAFT) != 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_append(str, "Draft ");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (str_len(str) == 1)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return "";
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_truncate(str, str_len(str)-1);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_append_c(str, ')');
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen return str_c(str);
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen}
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen
6bc0f424bcdb9119d8159874cf98adfa53eefd9aTimo Sirainenstatic void dump_record(struct mail_index_view *view, unsigned int seq)
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen{
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen struct mail_index *index = mail_index_view_get_index(view);
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen const struct mail_index_record *rec;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen const struct mail_index_registered_ext *ext;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen const void *data;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen unsigned int i, ext_count;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen string_t *str;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen bool expunged;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen rec = mail_index_lookup(view, seq);
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen printf("RECORD: seq=%u, uid=%u, flags=0x%02x %s\n",
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen seq, rec->uid, rec->flags, flags2str(rec->flags));
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen str = t_str_new(256);
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen ext = array_get(&index->extensions, &ext_count);
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen for (i = 0; i < ext_count; i++) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_lookup_ext(view, seq, i, &data, &expunged);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (data == NULL || ext[i].record_size == 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen continue;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_truncate(str, 0);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, " - ext %d %-10s: ", i, ext[i].name);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (ext[i].record_size == sizeof(uint32_t) &&
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ext[i].record_align == sizeof(uint32_t))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, "%10u", *((const uint32_t *)data));
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen else if (ext[i].record_size == sizeof(uint64_t) &&
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen ext[i].record_align == sizeof(uint64_t)) {
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen uint64_t value = *((const uint64_t *)data);
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen str_printfa(str, "%10llu", (unsigned long long)value);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else {
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen str_append(str, " ");
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen str_printfa(str, " (%s)",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen binary_to_hex(data, ext[i].record_size));
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen printf("%s\n", str_c(str));
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen if (strcmp(ext[i].name, "virtual") == 0) {
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen const struct virtual_mail_index_record *vrec = data;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen printf(" : mailbox_id = %u\n", vrec->mailbox_id);
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen printf(" : real_uid = %u\n", vrec->real_uid);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint main(int argc, const char *argv[])
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen{
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen struct mail_index *index;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen struct mail_index_view *view;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen struct mail_cache_view *cache_view;
40ad2c4902e9d83557f2e8a4bff3d98fea2c8aa1Timo Sirainen unsigned int seq, uid = 0;
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen lib_init();
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen if (argc < 2)
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen i_fatal("Usage: idxview <index dir> [<uid>]");
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen index = mail_index_alloc(argv[1], "dovecot.index");
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen if (mail_index_open(index, MAIL_INDEX_OPEN_FLAG_READONLY,
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen FILE_LOCK_METHOD_FCNTL) <= 0)
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen i_fatal("Couldn't open index %s", argv[1]);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (argv[2] != NULL)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uid = atoi(argv[2]);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view = mail_index_view_open(index);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen cache_view = mail_cache_view_open(index->cache, view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (uid == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("-- INDEX: %s\n", index->filepath);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dump_hdr(index);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dump_extensions(index);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dump_keywords(index);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen printf("\n-- CACHE: %s\n", index->cache->filepath);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dump_cache_hdr(index->cache);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen printf("\n-- RECORDS: %u\n", index->map->hdr.messages_count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (seq = 1; seq <= index->map->hdr.messages_count; seq++) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (uid == 0 || mail_index_lookup(view, seq)->uid == uid) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen T_BEGIN {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dump_record(view, seq);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dump_cache(cache_view, seq);
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen printf("\n");
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen } T_END;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_cache_view_close(cache_view);
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen mail_index_view_close(&view);
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen mail_index_close(index);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_free(&index);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen