changeset 22721:cef6bd8535f0

doveadm dump: Add "multiplex" dump type This allows dumping all channels from istream-multiplex stream.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 22 Dec 2017 15:12:30 +0200
parents 2c86355ae261
children 2eba804a60a2
files src/doveadm/doveadm-dump.c
diffstat 1 files changed, 49 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/doveadm-dump.c	Fri Dec 22 15:11:45 2017 +0200
+++ b/src/doveadm/doveadm-dump.c	Fri Dec 22 15:12:30 2017 +0200
@@ -2,6 +2,8 @@
 
 #include "lib.h"
 #include "array.h"
+#include "istream.h"
+#include "istream-multiplex.h"
 #include "doveadm.h"
 #include "doveadm-dump.h"
 
@@ -81,6 +83,51 @@
 	cmd_dump, "dump", "[-t <type>] <path>"
 };
 
+static void cmd_dump_multiplex(int argc ATTR_UNUSED, char *argv[])
+{
+	const unsigned int channels_count = 256;
+	struct istream *file_input, *channels[channels_count];
+	const unsigned char *data;
+	size_t size;
+	unsigned int i;
+
+	file_input = i_stream_create_file(argv[1], IO_BLOCK_SIZE);
+	/* A bit kludgy: istream-multiplex returns 0 if a wrong channel is
+	   being read from. This causes a panic with blocking istreams.
+	   Work around this by assuming that the file istream isn't blocking. */
+	file_input->blocking = FALSE;
+	channels[0] = i_stream_create_multiplex(file_input, IO_BLOCK_SIZE);
+	i_stream_unref(&file_input);
+
+	for (i = 1; i < channels_count; i++)
+		channels[i] = i_stream_multiplex_add_channel(channels[0], i);
+
+	bool have_input;
+	do {
+		have_input = FALSE;
+		for (i = 0; i < channels_count; i++) {
+			if (i_stream_read_more(channels[i], &data, &size) > 0) {
+				printf("CHANNEL %u: %zu bytes:\n", i, size);
+				fwrite(data, 1, size, stdout);
+				printf("\n");
+				have_input = TRUE;
+				i_stream_skip(channels[i], size);
+			}
+		}
+	} while (have_input);
+
+	if (channels[0]->stream_errno != 0)
+		i_error("read() failed: %s", i_stream_get_error(channels[0]));
+	for (i = 0; i < channels_count; i++)
+		i_stream_unref(&channels[i]);
+}
+
+struct doveadm_cmd_dump doveadm_cmd_dump_multiplex = {
+	"multiplex",
+	NULL,
+	cmd_dump_multiplex
+};
+
 static const struct doveadm_cmd_dump *dumps_builtin[] = {
 	&doveadm_cmd_dump_dbox,
 	&doveadm_cmd_dump_index,
@@ -89,7 +136,8 @@
 	&doveadm_cmd_dump_thread,
 	&doveadm_cmd_dump_zlib,
 	&doveadm_cmd_dump_dcrypt_file,
-	&doveadm_cmd_dump_dcrypt_key
+	&doveadm_cmd_dump_dcrypt_key,
+	&doveadm_cmd_dump_multiplex,
 };
 
 void print_dump_types(void)