From c664d0da658c8d3200d88ea3c4cd580afd33fa73 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 8 Oct 2009 20:43:25 -0400 Subject: [PATCH] util/*view binaries are now accessed via "doveadm dump". listview binary stays for now, since mailbox list indexes won't work anyway and they might get a complete redesign. --HG-- branch : HEAD --- .hgignore | 4 - src/doveadm/Makefile.am | 6 ++ .../doveadm-dump-index.c} | 35 ++++++-- .../logview.c => doveadm/doveadm-dump-log.c} | 61 ++++++++------ .../doveadm-dump-mailboxlog.c} | 53 +++++++++--- .../doveadm-dump-thread.c} | 82 +++++-------------- src/doveadm/doveadm-dump.c | 79 ++++++++++++++++++ src/doveadm/doveadm-dump.h | 17 ++++ src/doveadm/doveadm.c | 1 + src/doveadm/doveadm.h | 1 + src/util/Makefile.am | 26 +----- 11 files changed, 232 insertions(+), 133 deletions(-) rename src/{util/idxview.c => doveadm/doveadm-dump-index.c} (95%) rename src/{util/logview.c => doveadm/doveadm-dump-log.c} (93%) rename src/{util/mailboxlogview.c => doveadm/doveadm-dump-mailboxlog.c} (61%) rename src/{util/threadview.c => doveadm/doveadm-dump-thread.c} (70%) create mode 100644 src/doveadm/doveadm-dump.c create mode 100644 src/doveadm/doveadm-dump.h diff --git a/.hgignore b/.hgignore index 68f75cf9f0..2d6a138da4 100644 --- a/.hgignore +++ b/.hgignore @@ -79,14 +79,10 @@ src/plugins/fts-squat/squat-test src/pop3-login/pop3-login src/pop3/pop3 src/util/gdbhelper -src/util/idxview src/util/imap-utf7 src/util/listview -src/util/logview -src/util/mailboxlogview src/util/maildirlock src/util/rawlog -src/util/threadview src/plugins/quota/rquota_xdr.c src/plugins/quota/rquota.h diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am index f371e7b7c7..ad18090310 100644 --- a/src/doveadm/Makefile.am +++ b/src/doveadm/Makefile.am @@ -30,8 +30,14 @@ doveadm_DEPENDENCIES = \ doveadm_SOURCES = \ doveadm.c \ doveadm-auth.c \ + doveadm-dump.c \ + doveadm-dump-index.c \ + doveadm-dump-log.c \ + doveadm-dump-mailboxlog.c \ + doveadm-dump-thread.c \ doveadm-mail.c \ doveadm-pw.c noinst_HEADERS = \ + doveadm-dump.h \ doveadm-mail.h diff --git a/src/util/idxview.c b/src/doveadm/doveadm-dump-index.c similarity index 95% rename from src/util/idxview.c rename to src/doveadm/doveadm-dump-index.c index 4ddedcb41b..be70cd56b4 100644 --- a/src/util/idxview.c +++ b/src/doveadm/doveadm-dump-index.c @@ -9,6 +9,7 @@ #include "mail-cache-private.h" #include "mail-cache-private.h" #include "mail-index-modseq.h" +#include "doveadm-dump.h" #include #include @@ -453,7 +454,7 @@ static void dump_record(struct mail_index_view *view, unsigned int seq) } } -int main(int argc, const char *argv[]) +static void cmd_dump_index(int argc ATTR_UNUSED, char *argv[]) { struct mail_index *index; struct mail_index_view *view; @@ -462,11 +463,6 @@ int main(int argc, const char *argv[]) const char *p; unsigned int seq, uid = 0; - lib_init(); - - if (argc < 2) - i_fatal("Usage: idxview []"); - if (stat(argv[1], &st) == 0 && S_ISDIR(st.st_mode)) index = mail_index_alloc(argv[1], "dovecot.index"); else if ((p = strrchr(argv[1], '/')) != NULL) @@ -506,5 +502,30 @@ int main(int argc, const char *argv[]) mail_index_view_close(&view); mail_index_close(index); mail_index_free(&index); - return 0; } + +static bool test_dump_index(const char *path) +{ + struct mail_index *index; + struct stat st; + const char *p; + bool ret; + + if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) + index = mail_index_alloc(path, "dovecot.index"); + else if ((p = strrchr(path, '/')) != NULL) + index = mail_index_alloc(t_strdup_until(path, p), p + 1); + else + index = mail_index_alloc(".", path); + + ret = mail_index_open(index, MAIL_INDEX_OPEN_FLAG_READONLY, + FILE_LOCK_METHOD_FCNTL) > 0; + mail_index_free(&index); + return ret; +} + +struct doveadm_cmd_dump doveadm_cmd_dump_index = { + "index", + test_dump_index, + cmd_dump_index +}; diff --git a/src/util/logview.c b/src/doveadm/doveadm-dump-log.c similarity index 93% rename from src/util/logview.c rename to src/doveadm/doveadm-dump-log.c index 1fea88e897..a0a1135ccb 100644 --- a/src/util/logview.c +++ b/src/doveadm/doveadm-dump-log.c @@ -4,24 +4,12 @@ #include "hex-binary.h" #include "mail-index-private.h" #include "mail-transaction-log.h" +#include "doveadm-dump.h" #include static struct mail_transaction_ext_intro prev_intro; -uint32_t mail_index_offset_to_uint32(uint32_t offset) -{ - const unsigned char *buf = (const unsigned char *) &offset; - - 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 void dump_hdr(int fd, uint64_t *modseq_r) { struct mail_transaction_log_header hdr; @@ -70,6 +58,7 @@ mail_transaction_header_has_modseq(const struct mail_transaction_header *hdr) } return FALSE; } + static const char *log_record_type(unsigned int type) { const char *name; @@ -466,21 +455,14 @@ static int dump_record(int fd, uint64_t *modseq) return 1; } -int main(int argc, const char *argv[]) +static void cmd_dump_log(int argc ATTR_UNUSED, char *argv[]) { uint64_t modseq; int fd, ret; - lib_init(); - - if (argc < 2) - i_fatal("Usage: logview dovecot.index.log"); - fd = open(argv[1], O_RDONLY); - if (fd < 0) { - i_error("open(): %m"); - return 1; - } + if (fd < 0) + i_fatal("open(%s) failed: %m", argv[1]); dump_hdr(fd, &modseq); do { @@ -488,5 +470,36 @@ int main(int argc, const char *argv[]) ret = dump_record(fd, &modseq); } T_END; } while (ret > 0); - return 0; } + +static bool test_dump_log(const char *path) +{ + struct mail_transaction_log_header hdr; + const char *p; + bool ret = FALSE; + int fd; + + p = strrchr(path, '/'); + if (p == NULL) + return FALSE; + p = strstr(p, ".log"); + if (p == NULL || !(p[4] == '\0' || p[4] == '.')) + return FALSE; + + fd = open(path, O_RDONLY); + if (fd == -1) + return FALSE; + + if (read(fd, &hdr, sizeof(hdr)) >= MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE && + hdr.major_version == MAIL_TRANSACTION_LOG_MAJOR_VERSION && + hdr.hdr_size >= MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE) + ret = TRUE; + (void)close(fd); + return ret; +} + +struct doveadm_cmd_dump doveadm_cmd_dump_log = { + "log", + test_dump_log, + cmd_dump_log +}; diff --git a/src/util/mailboxlogview.c b/src/doveadm/doveadm-dump-mailboxlog.c similarity index 61% rename from src/util/mailboxlogview.c rename to src/doveadm/doveadm-dump-mailboxlog.c index 367424ec09..65fce2fc02 100644 --- a/src/util/mailboxlogview.c +++ b/src/doveadm/doveadm-dump-mailboxlog.c @@ -3,6 +3,7 @@ #include "lib.h" #include "hex-binary.h" #include "mailbox-log.h" +#include "doveadm-dump.h" #include #include @@ -66,25 +67,55 @@ static int dump_record(int fd) return 1; } -int main(int argc, const char *argv[]) +static void cmd_dump_mailboxlog(int argc ATTR_UNUSED, char *argv[]) { int fd, ret; - lib_init(); - - if (argc < 2) - i_fatal("Usage: logview dovecot.mailbox.log"); - fd = open(argv[1], O_RDONLY); - if (fd < 0) { - i_error("open(): %m"); - return 1; - } + if (fd < 0) + i_fatal("open(%s) failed: %m", argv[1]); do { T_BEGIN { ret = dump_record(fd); } T_END; } while (ret > 0); - return 0; } + +static bool test_dump_mailboxlog(const char *path) +{ + const char *p; + int fd; + struct mailbox_log_record rec; + bool ret = FALSE; + + p = strrchr(path, '.'); + if (p == NULL || strcmp(p, ".log") != 0) + return FALSE; + + fd = open(path, O_RDONLY); + if (fd == -1) + return FALSE; + + if (read(fd, &rec, sizeof(rec)) == sizeof(rec) && + rec.padding[0] == 0 && rec.padding[1] == 0 && rec.padding[2] == 0) { + enum mailbox_log_record_type type = rec.type; + switch (type) { + case MAILBOX_LOG_RECORD_DELETE_MAILBOX: + case MAILBOX_LOG_RECORD_DELETE_DIR: + case MAILBOX_LOG_RECORD_RENAME: + case MAILBOX_LOG_RECORD_SUBSCRIBE: + case MAILBOX_LOG_RECORD_UNSUBSCRIBE: + ret = TRUE; + break; + } + } + (void)close(fd); + return ret; +} + +struct doveadm_cmd_dump doveadm_cmd_dump_mailboxlog = { + "mailboxlog", + test_dump_mailboxlog, + cmd_dump_mailboxlog +}; diff --git a/src/util/threadview.c b/src/doveadm/doveadm-dump-thread.c similarity index 70% rename from src/util/threadview.c rename to src/doveadm/doveadm-dump-thread.c index 2548b15b86..4bda82c85f 100644 --- a/src/util/threadview.c +++ b/src/doveadm/doveadm-dump-thread.c @@ -4,6 +4,7 @@ #include "mmap-util.h" #include "mail-index-private.h" #include "mail-index-strmap.h" +#include "doveadm-dump.h" #include #include @@ -12,53 +13,6 @@ static uint32_t max_likely_index; -uint32_t mail_index_offset_to_uint32(uint32_t offset) -{ - const unsigned char *buf = (const unsigned char *) &offset; - - 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); -} - -int mail_index_unpack_num(const uint8_t **p, const uint8_t *end, - uint32_t *num_r) -{ - const uint8_t *c = *p; - uint32_t value = 0; - unsigned int bits = 0; - - for (;;) { - if (unlikely(c == end)) { - /* we should never see EOF */ - *num_r = 0; - return -1; - } - - value |= (*c & 0x7f) << bits; - if (*c < 0x80) - break; - - bits += 7; - c++; - } - - if (unlikely(bits >= 32)) { - /* broken input */ - *p = end; - *num_r = 0; - return -1; - } - - *p = c + 1; - *num_r = value; - return 0; -} - static size_t dump_hdr(const struct mail_index_strmap_header *hdr) { printf("version = %u\n", hdr->version); @@ -137,7 +91,7 @@ static int dump_block(const uint8_t *data, const uint8_t *end, uint32_t *uid) return p - data; } -int main(int argc, const char *argv[]) +static void cmd_dump_thread(int argc ATTR_UNUSED, char *argv[]) { unsigned int pos; const void *map, *end; @@ -145,21 +99,12 @@ int main(int argc, const char *argv[]) uint32_t uid; int fd, ret; - lib_init(); - - if (argc < 2) - i_fatal("Usage: threadview dovecot.index.thread"); - fd = open(argv[1], O_RDONLY); - if (fd < 0) { - i_error("open(%s) failed: %m", argv[1]); - return 1; - } + if (fd < 0) + i_fatal("open(%s) failed: %m", argv[1]); - if (fstat(fd, &st) < 0) { - i_error("fstat(%s) failed: %m", argv[1]); - return 1; - } + if (fstat(fd, &st) < 0) + i_fatal("fstat(%s) failed: %m", argv[1]); max_likely_index = (st.st_size / 8) * 2; map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); @@ -175,5 +120,18 @@ int main(int argc, const char *argv[]) pos += ret; } T_END; } while (ret > 0); - return 0; } + +static bool test_dump_thread(const char *path) +{ + const char *p; + + p = strrchr(path, '.'); + return p != NULL && strcmp(p, ".thread") == 0; +} + +struct doveadm_cmd_dump doveadm_cmd_dump_thread = { + "thread", + test_dump_thread, + cmd_dump_thread +}; diff --git a/src/doveadm/doveadm-dump.c b/src/doveadm/doveadm-dump.c new file mode 100644 index 0000000000..19c1011c24 --- /dev/null +++ b/src/doveadm/doveadm-dump.c @@ -0,0 +1,79 @@ +/* Copyright (C) 2004 Joshua Goodall */ + +#include "lib.h" +#include "doveadm.h" +#include "doveadm-dump.h" + +#include +#include + +static const struct doveadm_cmd_dump *dumps[] = { + &doveadm_cmd_dump_index, + &doveadm_cmd_dump_log, + &doveadm_cmd_dump_mailboxlog, + &doveadm_cmd_dump_thread +}; + +static const struct doveadm_cmd_dump * +dump_find_name(const char *name) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(dumps); i++) { + if (strcmp(dumps[i]->name, name) == 0) + return dumps[i]; + } + return NULL; +} + +static const struct doveadm_cmd_dump * +dump_find_test(const char *path) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(dumps); i++) { + if (dumps[i]->test(path)) + return dumps[i]; + } + return NULL; +} + +static void cmd_dump(int argc, char *argv[]) +{ + const struct doveadm_cmd_dump *dump; + const char *type = NULL; + int c; + + while ((c = getopt(argc, argv, "t:")) > 0) { + switch (c) { + case 't': + type = optarg; + break; + default: + help(&doveadm_cmd_dump); + } + } + if (optind == argc) + help(&doveadm_cmd_dump); + + optind--; + argc -= optind; + argv += optind; + + dump = type != NULL ? dump_find_name(type) : dump_find_test(argv[1]); + if (dump == NULL) { + if (type != NULL) + i_fatal("Unknown type: %s", type); + else + i_fatal("Can't autodetect file type: %s", argv[1]); + } else { + if (type == NULL) + printf("Detected file type: %s\n", dump->name); + } + dump->cmd(argc, argv); +} + +struct doveadm_cmd doveadm_cmd_dump = { + cmd_dump, "dump", "[-t ] ", +" can be: index log mailboxlog thread\n" +}; diff --git a/src/doveadm/doveadm-dump.h b/src/doveadm/doveadm-dump.h new file mode 100644 index 0000000000..c344fb0d3f --- /dev/null +++ b/src/doveadm/doveadm-dump.h @@ -0,0 +1,17 @@ +#ifndef DOVEADM_DUMP_H +#define DOVEADM_DUMP_H + +#include "doveadm.h" + +struct doveadm_cmd_dump { + const char *name; + bool (*test)(const char *path); + doveadm_command_t *cmd; +}; + +extern struct doveadm_cmd_dump doveadm_cmd_dump_index; +extern struct doveadm_cmd_dump doveadm_cmd_dump_log; +extern struct doveadm_cmd_dump doveadm_cmd_dump_mailboxlog; +extern struct doveadm_cmd_dump doveadm_cmd_dump_thread; + +#endif diff --git a/src/doveadm/doveadm.c b/src/doveadm/doveadm.c index 15d790463e..a36be21a1c 100644 --- a/src/doveadm/doveadm.c +++ b/src/doveadm/doveadm.c @@ -81,6 +81,7 @@ int main(int argc, char *argv[]) doveadm_register_cmd(&doveadm_cmd_help); doveadm_register_cmd(&doveadm_cmd_auth); doveadm_register_cmd(&doveadm_cmd_user); + doveadm_register_cmd(&doveadm_cmd_dump); doveadm_register_cmd(&doveadm_cmd_pw); /* "+" is GNU extension to stop at the first non-option. diff --git a/src/doveadm/doveadm.h b/src/doveadm/doveadm.h index d75ecef954..e142232b2d 100644 --- a/src/doveadm/doveadm.h +++ b/src/doveadm/doveadm.h @@ -14,6 +14,7 @@ struct doveadm_cmd { extern struct doveadm_cmd doveadm_cmd_auth; extern struct doveadm_cmd doveadm_cmd_user; +extern struct doveadm_cmd doveadm_cmd_dump; extern struct doveadm_cmd doveadm_cmd_pw; void doveadm_register_cmd(const struct doveadm_cmd *cmd); diff --git a/src/util/Makefile.am b/src/util/Makefile.am index d1a02509c7..dbf8d7a94d 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -3,13 +3,9 @@ pkglibexecdir = $(libexecdir)/dovecot pkglibexec_PROGRAMS = \ rawlog \ gdbhelper \ - idxview \ imap-utf7 \ listview \ - logview \ - mailboxlogview \ - maildirlock \ - threadview + maildirlock AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ @@ -33,11 +29,6 @@ gdbhelper_DEPENDENCIES = $(LIBDOVECOT) gdbhelper_SOURCES = \ gdbhelper.c -idxview_LDADD = $(LIBDOVECOT_STORAGE) $(LIBDOVECOT) -idxview_DEPENDENCIES = $(LIBDOVECOT_STORAGE) $(LIBDOVECOT) -idxview_SOURCES = \ - idxview.c - imap_utf7_LDADD = $(LIBDOVECOT) imap_utf7_DEPENDENCIES = $(LIBDOVECOT) imap_utf7_SOURCES = \ @@ -48,22 +39,7 @@ listview_DEPENDENCIES = $(LIBDOVECOT) listview_SOURCES = \ listview.c -logview_LDADD = $(LIBDOVECOT) -logview_DEPENDENCIES = $(LIBDOVECOT) -logview_SOURCES = \ - logview.c - -mailboxlogview_LDADD = $(LIBDOVECOT) -mailboxlogview_DEPENDENCIES = $(LIBDOVECOT) -mailboxlogview_SOURCES = \ - mailboxlogview.c - maildirlock_LDADD = $(LIBDOVECOT) maildirlock_DEPENDENCIES = $(LIBDOVECOT) maildirlock_SOURCES = \ maildirlock.c - -threadview_LDADD = $(LIBDOVECOT) -threadview_DEPENDENCIES = $(LIBDOVECOT) -threadview_SOURCES = \ - threadview.c -- 2.47.3