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