dovecot-2.2: doveadm: Added "replicator status" command.

dovecot at dovecot.org dovecot at dovecot.org
Sun Mar 24 16:49:11 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/660d1fd6fc9c
changeset: 16096:660d1fd6fc9c
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Mar 24 16:48:53 2013 +0200
description:
doveadm: Added "replicator status" command.

diffstat:

 src/doveadm/Makefile.am          |    1 +
 src/doveadm/doveadm-replicator.c |  162 +++++++++++++++++++++++++++++++++++++++
 src/doveadm/doveadm.c            |    1 +
 src/doveadm/doveadm.h            |    1 +
 4 files changed, 165 insertions(+), 0 deletions(-)

diffs (198 lines):

diff -r 5271c894700c -r 660d1fd6fc9c src/doveadm/Makefile.am
--- a/src/doveadm/Makefile.am	Sun Mar 24 16:48:29 2013 +0200
+++ b/src/doveadm/Makefile.am	Sun Mar 24 16:48:53 2013 +0200
@@ -101,6 +101,7 @@
 	doveadm-print-table.c \
 	doveadm-proxy.c \
 	doveadm-pw.c \
+	doveadm-replicator.c \
 	doveadm-sis.c \
 	doveadm-stats.c \
 	doveadm-who.c \
diff -r 5271c894700c -r 660d1fd6fc9c src/doveadm/doveadm-replicator.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/doveadm/doveadm-replicator.c	Sun Mar 24 16:48:53 2013 +0200
@@ -0,0 +1,162 @@
+/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "net.h"
+#include "istream.h"
+#include "write-full.h"
+#include "master-service.h"
+#include "doveadm.h"
+#include "doveadm-print.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+struct replicator_context {
+	const char *socket_path;
+	struct istream *input;
+};
+
+extern struct doveadm_cmd doveadm_cmd_replicator[];
+
+static void replicator_cmd_help(doveadm_command_t *cmd) ATTR_NORETURN;
+
+static void
+replicator_send(struct replicator_context *ctx, const char *data)
+{
+	if (write_full(i_stream_get_fd(ctx->input), data, strlen(data)) < 0)
+		i_fatal("write(%s) failed: %m", ctx->socket_path);
+}
+
+static void replicator_connect(struct replicator_context *ctx)
+{
+#define REPLICATOR_HANDSHAKE "VERSION\treplicator-doveadm-client\t1\t0\n"
+	const char *line;
+	int fd;
+
+	fd = doveadm_connect(ctx->socket_path);
+	net_set_nonblock(fd, FALSE);
+
+	ctx->input = i_stream_create_fd(fd, (size_t)-1, TRUE);
+	replicator_send(ctx, REPLICATOR_HANDSHAKE);
+
+	alarm(5);
+	line = i_stream_read_next_line(ctx->input);
+	alarm(0);
+	if (line == NULL) {
+		if (ctx->input->stream_errno != 0)
+			i_fatal("read(%s) failed: %m", ctx->socket_path);
+		else if (ctx->input->eof)
+			i_fatal("%s disconnected", ctx->socket_path);
+		else
+			i_fatal("read(%s) timed out", ctx->socket_path);
+	}
+	if (!version_string_verify(line, "replicator-doveadm-server", 1)) {
+		i_fatal_status(EX_PROTOCOL,
+			       "%s not a compatible replicator-doveadm socket",
+			       ctx->socket_path);
+	}
+}
+
+static void replicator_disconnect(struct replicator_context *ctx)
+{
+	if (ctx->input->stream_errno != 0)
+		i_fatal("read(%s) failed: %m", ctx->socket_path);
+	i_stream_destroy(&ctx->input);
+}
+
+static struct replicator_context *
+cmd_replicator_init(int argc, char *argv[], doveadm_command_t *cmd)
+{
+	struct replicator_context *ctx;
+	int c;
+
+	ctx = t_new(struct replicator_context, 1);
+	ctx->socket_path = t_strconcat(doveadm_settings->base_dir,
+				       "/replicator-doveadm", NULL);
+
+	while ((c = getopt(argc, argv, "a:")) > 0) {
+		switch (c) {
+		case 'a':
+			ctx->socket_path = optarg;
+			break;
+		default:
+			replicator_cmd_help(cmd);
+		}
+	}
+	replicator_connect(ctx);
+	return ctx;
+}
+
+static const char *time_ago(time_t t)
+{
+	int diff = ioloop_time - t;
+
+	return t_strdup_printf("%02d:%02d:%02d", diff/3600, diff/60, diff%60);
+}
+
+static void cmd_replicator_status(int argc, char *argv[])
+{
+	struct replicator_context *ctx;
+	const char *line, *const *args;
+	time_t last_fast, last_full;
+
+	ctx = cmd_replicator_init(argc, argv, cmd_replicator_status);
+
+	doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
+	doveadm_print_header("username", "username",
+			     DOVEADM_PRINT_HEADER_FLAG_EXPAND);
+	doveadm_print_header_simple("priority");
+	doveadm_print_header_simple("fast sync");
+	doveadm_print_header_simple("full sync");
+	doveadm_print_header_simple("failed");
+
+	replicator_send(ctx, "STATUS\n");
+	while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
+		if (*line == '\0')
+			break;
+		T_BEGIN {
+			args = t_strsplit_tab(line);
+			if (str_array_length(args) >= 5 &&
+			    str_to_time(args[2], &last_fast) == 0 &&
+			    str_to_time(args[3], &last_full) == 0) {
+				doveadm_print(args[0]);
+				doveadm_print(args[1]);
+				doveadm_print(time_ago(last_fast));
+				doveadm_print(time_ago(last_full));
+				doveadm_print(args[4][0] == '0' ? "-" : "y");
+			}
+		} T_END;
+	}
+	if (line == NULL) {
+		i_error("Director disconnected unexpectedly");
+		doveadm_exit_code = EX_TEMPFAIL;
+	}
+	replicator_disconnect(ctx);
+}
+
+struct doveadm_cmd doveadm_cmd_replicator[] = {
+	{ cmd_replicator_status, "replicator status",
+	  "[-a <replicator socket path>] [<user mask>]" }
+};
+
+static void replicator_cmd_help(doveadm_command_t *cmd)
+{
+	unsigned int i;
+
+	for (i = 0; i < N_ELEMENTS(doveadm_cmd_replicator); i++) {
+		if (doveadm_cmd_replicator[i].cmd == cmd)
+			help(&doveadm_cmd_replicator[i]);
+	}
+	i_unreached();
+}
+
+void doveadm_register_replicator_commands(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < N_ELEMENTS(doveadm_cmd_replicator); i++)
+		doveadm_register_cmd(&doveadm_cmd_replicator[i]);
+}
diff -r 5271c894700c -r 660d1fd6fc9c src/doveadm/doveadm.c
--- a/src/doveadm/doveadm.c	Sun Mar 24 16:48:29 2013 +0200
+++ b/src/doveadm/doveadm.c	Sun Mar 24 16:48:53 2013 +0200
@@ -367,6 +367,7 @@
 		doveadm_register_mount_commands();
 		doveadm_register_proxy_commands();
 		doveadm_register_log_commands();
+		doveadm_register_replicator_commands();
 		doveadm_dump_init();
 		doveadm_mail_init();
 		doveadm_load_modules();
diff -r 5271c894700c -r 660d1fd6fc9c src/doveadm/doveadm.h
--- a/src/doveadm/doveadm.h	Sun Mar 24 16:48:29 2013 +0200
+++ b/src/doveadm/doveadm.h	Sun Mar 24 16:48:53 2013 +0200
@@ -46,5 +46,6 @@
 void doveadm_register_log_commands(void);
 void doveadm_register_instance_commands(void);
 void doveadm_register_mount_commands(void);
+void doveadm_register_replicator_commands(void);
 
 #endif


More information about the dovecot-cvs mailing list