Mercurial > dovecot > core-2.2
changeset 21838:660b5830a05e
doveadm dump log: Use istream for reading the file.
Cleans up the code a bit and removes the 1MB record limit.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 27 Mar 2017 16:26:09 +0300 |
parents | 97e01a0ad4bc |
children | b4ed312463fd |
files | src/doveadm/doveadm-dump-log.c |
diffstat | 1 files changed, 43 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/src/doveadm/doveadm-dump-log.c Wed Mar 29 13:28:36 2017 +0300 +++ b/src/doveadm/doveadm-dump-log.c Mon Mar 27 16:26:09 2017 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "istream.h" #include "hex-binary.h" #include "mail-index-private.h" #include "mail-transaction-log.h" @@ -10,22 +11,26 @@ static struct mail_transaction_ext_intro prev_intro; -static void dump_hdr(int fd, uint64_t *modseq_r) +static void dump_hdr(struct istream *input, uint64_t *modseq_r) { struct mail_transaction_log_header hdr; - ssize_t ret; + const unsigned char *data; + size_t size; + int ret; - ret = read(fd, &hdr, sizeof(hdr)); - if (ret != sizeof(hdr)) { + ret = i_stream_read_bytes(input, &data, &size, sizeof(hdr)); + if (ret < 0 && input->stream_errno != 0) + i_fatal("read() failed: %s", i_stream_get_error(input)); + if (ret <= 0) { i_fatal("file hdr read() %"PRIuSIZE_T" != %"PRIuSIZE_T, - ret, sizeof(hdr)); + size, sizeof(hdr)); } + memcpy(&hdr, data, sizeof(hdr)); if (hdr.hdr_size < sizeof(hdr)) { memset(PTR_OFFSET(&hdr, hdr.hdr_size), 0, sizeof(hdr) - hdr.hdr_size); } - if (lseek(fd, hdr.hdr_size, SEEK_SET) < 0) - i_fatal("lseek() failed: %m"); + i_stream_skip(input, hdr.hdr_size); printf("version = %u.%u\n", hdr.major_version, hdr.minor_version); printf("hdr size = %u\n", hdr.hdr_size); @@ -480,77 +485,70 @@ } } -static int dump_record(int fd, uint64_t *modseq) +static int dump_record(struct istream *input, uint64_t *modseq) { - off_t offset; - ssize_t ret; struct mail_transaction_header hdr; unsigned int orig_size; - - offset = lseek(fd, 0, SEEK_CUR); - if (offset == -1) - i_fatal("lseek() failed: %m"); + const unsigned char *data; + size_t size; + int ret; - ret = read(fd, &hdr, sizeof(hdr)); - if (ret == 0) - return 0; - - if (ret != sizeof(hdr)) { + ret = i_stream_read_bytes(input, &data, &size, sizeof(hdr)); + if (ret < 0 && input->stream_errno != 0) + i_fatal("read() failed: %s", i_stream_get_error(input)); + if (ret <= 0) { + if (size == 0) + return 0; i_fatal("rec hdr read() %"PRIuSIZE_T" != %"PRIuSIZE_T, - ret, sizeof(hdr)); + size, sizeof(hdr)); } + memcpy(&hdr, data, sizeof(hdr)); orig_size = hdr.size; hdr.size = mail_index_offset_to_uint32(hdr.size); - if (hdr.size == 0) { + if (hdr.size < sizeof(hdr)) { printf("record: offset=%"PRIuUOFF_T", " "type=%s, size=broken (%x)\n", - offset, log_record_type(hdr.type), orig_size); + input->v_offset, log_record_type(hdr.type), orig_size); return 0; } printf("record: offset=%"PRIuUOFF_T", type=%s, size=%u", - offset, log_record_type(hdr.type), hdr.size); + input->v_offset, log_record_type(hdr.type), hdr.size); if (*modseq > 0 && mail_transaction_header_has_modseq(&hdr)) { *modseq += 1; printf(", modseq=%llu", (unsigned long long)*modseq); } printf("\n"); - if (hdr.size < sizeof(hdr)) { - i_fatal("Invalid header size %u", hdr.size); - } else if (hdr.size < 1024*1024) { - unsigned char *buf = t_malloc(hdr.size); - - ret = read(fd, buf, hdr.size - sizeof(hdr)); - if (ret != (ssize_t)(hdr.size - sizeof(hdr))) { - i_fatal("rec data read() %"PRIuSIZE_T" != %"PRIuSIZE_T, - ret, hdr.size - sizeof(hdr)); - } - log_record_print(&hdr, buf, (size_t)ret, modseq); - } else { - if (lseek(fd, hdr.size - sizeof(hdr), SEEK_CUR) < 0) - i_fatal("lseek() failed: %m"); + i_stream_skip(input, sizeof(hdr)); + size_t data_size = hdr.size - sizeof(hdr); + ret = i_stream_read_bytes(input, &data, &size, data_size); + if (ret < 0 && input->stream_errno != 0) + i_fatal("read() failed: %s", i_stream_get_error(input)); + if (ret <= 0) { + i_fatal("rec data read() %"PRIuSIZE_T" != %"PRIuSIZE_T, + size, data_size); } + log_record_print(&hdr, data, data_size, modseq); + i_stream_skip(input, data_size); return 1; } static void cmd_dump_log(int argc ATTR_UNUSED, char *argv[]) { + struct istream *input; uint64_t modseq; - int fd, ret; + int ret; - fd = open(argv[1], O_RDONLY); - if (fd < 0) - i_fatal("open(%s) failed: %m", argv[1]); - - dump_hdr(fd, &modseq); + input = i_stream_create_file(argv[1], (size_t)-1); + dump_hdr(input, &modseq); do { T_BEGIN { - ret = dump_record(fd, &modseq); + ret = dump_record(input, &modseq); } T_END; } while (ret > 0); - i_close_fd(&fd); + i_stream_unref(&input); } static bool test_dump_log(const char *path)