]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm dump: Add "multiplex" dump type
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 22 Dec 2017 13:12:30 +0000 (15:12 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Wed, 3 Jan 2018 10:40:29 +0000 (12:40 +0200)
This allows dumping all channels from istream-multiplex stream.

src/doveadm/doveadm-dump.c

index 1312b8bf6088be45cafc1eac4990fefdb8fc6d84..3976e4f9432ea26b2530fc2db94199cdff4bafd4 100644 (file)
@@ -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 @@ struct doveadm_cmd doveadm_cmd_dump = {
        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 @@ static const struct doveadm_cmd_dump *dumps_builtin[] = {
        &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)