listview.c revision 19e8adccba16ff419f5675b1575358c2956dce83
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov/* Copyright (c) 2007-2008 Dovecot authors, see the included COPYING file */
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov#include "lib.h"
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov#include "crc32.h"
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov#include "mail-index.h"
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov#include "mailbox-list-index-private.h"
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov#include <stdio.h>
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov#include <stdlib.h>
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashovstatic struct mailbox_list_index_header hdr;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashovstatic uint32_t mail_index_offset_to_uint32(uint32_t offset)
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov{
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov const unsigned char *buf = (const unsigned char *) &offset;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if ((offset & 0x80808080) != 0x80808080)
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov return 0;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov return (((uint32_t)buf[3] & 0x7f) << 2) |
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov (((uint32_t)buf[2] & 0x7f) << 9) |
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov (((uint32_t)buf[1] & 0x7f) << 16) |
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov (((uint32_t)buf[0] & 0x7f) << 23);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov}
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashovstatic void dump_hdr(int fd)
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov{
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov int ret;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov ret = read(fd, &hdr, sizeof(hdr));
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (ret != sizeof(hdr))
c46dec3dfad9e83321cc9d3185d93f0e8c38f57eLukas Slebodnik i_fatal("file hdr read() %d != %ld\n", ret, sizeof(hdr));
c46dec3dfad9e83321cc9d3185d93f0e8c38f57eLukas Slebodnik
c46dec3dfad9e83321cc9d3185d93f0e8c38f57eLukas Slebodnik printf("version = %u.%u\n", hdr.major_version, hdr.minor_version);
c46dec3dfad9e83321cc9d3185d93f0e8c38f57eLukas Slebodnik printf("header size = %u\n", hdr.header_size);
c46dec3dfad9e83321cc9d3185d93f0e8c38f57eLukas Slebodnik printf("uid validity = %u\n", hdr.uid_validity);
60713f738cedb6e4239604baf6619a0ca986fa49Michal Židek printf("file seq = %u\n", hdr.file_seq);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("next uid = %u\n", hdr.next_uid);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("used space = %u\n", hdr.used_space);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("deleted space = %u\n", hdr.deleted_space);
e1711a2b2cb904f7edc26cc68566e064896d4f8aLukas Slebodnik}
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
e1711a2b2cb904f7edc26cc68566e064896d4f8aLukas Slebodnikstatic void dump_dir(int fd, unsigned int show_offset, const char *path)
e1711a2b2cb904f7edc26cc68566e064896d4f8aLukas Slebodnik{
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov struct mailbox_list_dir_record dir;
60713f738cedb6e4239604baf6619a0ca986fa49Michal Židek struct mailbox_list_record rec;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov off_t offset;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov char name[1024];
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov unsigned int i;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov int ret;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov offset = lseek(fd, 0, SEEK_CUR);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov ret = read(fd, &dir, sizeof(dir));
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (ret == 0) {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (*path != '\0')
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov i_fatal("unexpected EOF when reading dir");
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov return;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov }
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (ret != sizeof(dir))
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov i_fatal("dir read() %d != %ld", ret, sizeof(dir));
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov dir.next_offset = mail_index_offset_to_uint32(dir.next_offset);
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov printf("%s: DIR: offset=%"PRIuUOFF_T" next_offset=%u count=%u dir_size=%u\n",
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov path, offset, dir.next_offset, dir.count, dir.dir_size);
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov if (dir.next_offset != 0 && dir.next_offset != show_offset) {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov lseek(fd, dir.next_offset, SEEK_SET);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov dump_dir(fd, show_offset, path);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov return;
bf472d2422599d14345e7cd9999289c26455c622Lukas Slebodnik }
bf472d2422599d14345e7cd9999289c26455c622Lukas Slebodnik
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov offset += sizeof(dir);
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov for (i = 0; i < dir.count; i++) {
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov lseek(fd, offset, SEEK_SET);
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov ret = read(fd, &rec, sizeof(rec));
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov if (ret == 0)
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov i_fatal("unexpected EOF, %d/%d records", i, dir.count);
efdcf49660505e13607b99ba82eb504cf37b8794Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (ret != sizeof(rec))
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov i_fatal("rec read() %d != %ld", ret, sizeof(rec));
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov rec.dir_offset = mail_index_offset_to_uint32(rec.dir_offset);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov ret = pread(fd, name, sizeof(name)-1, rec.name_offset);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov name[ret < 0 ? 0 : ret] = '\0';
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("%s%s: offset=%"PRIuUOFF_T" uid=%u "
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov "name_offset=%u name_hash=%u", path, name, offset,
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov rec.uid, rec.name_offset, rec.name_hash);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (rec.deleted != 0)
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf(" deleted=%u", rec.deleted);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (rec.dir_offset != 0)
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf(" dir_offset=%u", rec.dir_offset);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("\n");
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (ret <= 0)
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("%s%s: - invalid name_offset", path, name);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov else if (strlen(name) == (size_t)ret) {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("%s%s: - name missing NUL terminator",
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov path, name);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov }
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (crc32_str(name) != rec.name_hash) {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("%s%s: - invalid name hash %u vs %u\n",
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov path, name, crc32_str(name), rec.name_hash);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov }
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (rec.dir_offset != 0) T_BEGIN {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov const char *new_path;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov lseek(fd, rec.dir_offset, SEEK_SET);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (*path == '\0')
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov new_path = t_strdup_printf("%s/", name);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov else
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov new_path = t_strdup_printf("%s%s/", path, name);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov dump_dir(fd, show_offset, new_path);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov } T_END;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov offset += sizeof(rec);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov }
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov}
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashovint main(int argc ATTR_UNUSED, const char *argv[])
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov{
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov int fd;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov lib_init();
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov fd = open(argv[1], O_RDONLY);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (fd < 0) {
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov i_error("open(): %m");
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov return 1;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov }
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("-- LIST INDEX: %s\n", argv[1]);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov dump_hdr(fd);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov lseek(fd, hdr.header_size, SEEK_SET);
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov printf("---------------\n");
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov dump_dir(fd, argv[2] == NULL ? 0 : atoi(argv[2]), "");
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov return 0;
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov}
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov