dovecot-2.2: doveadm: Added "replicator replicate" command to fo...

dovecot at dovecot.org dovecot at dovecot.org
Sun Mar 24 17:48:37 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/1b269672e33b
changeset: 16102:1b269672e33b
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Mar 24 17:48:17 2013 +0200
description:
doveadm: Added "replicator replicate" command to force replication of user(s).

diffstat:

 src/doveadm/doveadm-replicator.c                |  57 ++++++++++++++++++++++--
 src/replication/replicator/doveadm-connection.c |  41 +++++++++++++++++
 2 files changed, 93 insertions(+), 5 deletions(-)

diffs (171 lines):

diff -r 1fa248d2aef7 -r 1b269672e33b src/doveadm/doveadm-replicator.c
--- a/src/doveadm/doveadm-replicator.c	Sun Mar 24 17:23:33 2013 +0200
+++ b/src/doveadm/doveadm-replicator.c	Sun Mar 24 17:48:17 2013 +0200
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "ioloop.h"
+#include "str.h"
 #include "strescape.h"
 #include "istream.h"
 #include "write-full.h"
@@ -16,6 +17,7 @@
 
 struct replicator_context {
 	const char *socket_path;
+	const char *priority;
 	struct istream *input;
 };
 
@@ -68,7 +70,8 @@
 }
 
 static struct replicator_context *
-cmd_replicator_init(int argc, char *argv[], doveadm_command_t *cmd)
+cmd_replicator_init(int argc, char *argv[], const char *getopt_args,
+		    doveadm_command_t *cmd)
 {
 	struct replicator_context *ctx;
 	int c;
@@ -77,11 +80,14 @@
 	ctx->socket_path = t_strconcat(doveadm_settings->base_dir,
 				       "/replicator-doveadm", NULL);
 
-	while ((c = getopt(argc, argv, "a:")) > 0) {
+	while ((c = getopt(argc, argv, getopt_args)) > 0) {
 		switch (c) {
 		case 'a':
 			ctx->socket_path = optarg;
 			break;
+		case 'p':
+			ctx->priority = optarg;
+			break;
 		default:
 			replicator_cmd_help(cmd);
 		}
@@ -105,7 +111,7 @@
 	const char *line, *const *args;
 	time_t last_fast, last_full;
 
-	ctx = cmd_replicator_init(argc, argv, cmd_replicator_status);
+	ctx = cmd_replicator_init(argc, argv, "a:", cmd_replicator_status);
 
 	doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
 	doveadm_print_header("username", "username",
@@ -138,15 +144,56 @@
 		} T_END;
 	}
 	if (line == NULL) {
-		i_error("Director disconnected unexpectedly");
+		i_error("Replicator disconnected unexpectedly");
 		doveadm_exit_code = EX_TEMPFAIL;
 	}
 	replicator_disconnect(ctx);
 }
 
+static void cmd_replicator_replicate(int argc, char *argv[])
+{
+	struct replicator_context *ctx;
+	string_t *str;
+	const char *line;
+
+	if (argv[1] == NULL)
+		replicator_cmd_help(cmd_replicator_replicate);
+
+	ctx = cmd_replicator_init(argc, argv, "a:p:", cmd_replicator_replicate);
+
+	str = t_str_new(128);
+	str_append(str, "REPLICATE\t");
+	if (ctx->priority == NULL)
+		str_append_tabescaped(str, "low");
+	else
+		str_append_tabescaped(str, ctx->priority);
+	str_append_c(str, '\t');
+	str_append_tabescaped(str, argv[1]);
+	str_append_c(str, '\n');
+	replicator_send(ctx, str_c(str));
+
+	doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
+	doveadm_print_header("result", "result",
+			     DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
+
+	line = i_stream_read_next_line(ctx->input);
+	if (line == NULL) {
+		i_error("Replicator disconnected unexpectedly");
+		doveadm_exit_code = EX_TEMPFAIL;
+	} else if (line[0] != '+') {
+		i_error("Replicator failed: %s", line+1);
+		doveadm_exit_code = EX_USAGE;
+	} else {
+		doveadm_print(t_strdup_printf("%s users updated", line+1));
+	}
+	replicator_disconnect(ctx);
+}
+
 struct doveadm_cmd doveadm_cmd_replicator[] = {
 	{ cmd_replicator_status, "replicator status",
-	  "[-a <replicator socket path>] [<user mask>]" }
+	  "[-a <replicator socket path>] [<user mask>]" },
+	{ cmd_replicator_replicate, "replicator replicate",
+	  "[-a <replicator socket path>] [-p <priority>] <user mask>" },
 };
 
 static void replicator_cmd_help(doveadm_command_t *cmd)
diff -r 1fa248d2aef7 -r 1b269672e33b src/replication/replicator/doveadm-connection.c
--- a/src/replication/replicator/doveadm-connection.c	Sun Mar 24 17:23:33 2013 +0200
+++ b/src/replication/replicator/doveadm-connection.c	Sun Mar 24 17:48:17 2013 +0200
@@ -49,6 +49,45 @@
 	return 0;
 }
 
+static int
+client_input_replicate(struct doveadm_connection *client, const char *const *args)
+{
+	struct replicator_user *const *queue_users, **users_dup;
+	unsigned int i, count, match_count;
+	const char *usermask;
+	enum replication_priority priority;
+
+	/* <priority> <username>|<mask> */
+	if (str_array_length(args) != 2) {
+		i_error("%s: REPLICATE: Invalid parameters", client->conn.name);
+		return -1;
+	}
+	if (replication_priority_parse(args[0], &priority) < 0) {
+		o_stream_send_str(client->conn.output, "-Invalid priority\n");
+		return 0;
+	}
+	usermask = args[1];
+	if (strchr(usermask, '*') == NULL && strchr(usermask, '?') == NULL) {
+		replicator_queue_add(client->queue, usermask, priority);
+		o_stream_send_str(client->conn.output, "+1\n");
+		return 0;
+	}
+
+	queue_users = replicator_queue_get_users(client->queue, &count);
+	users_dup = i_new(struct replicator_user *, count+1);
+	for (i = match_count = 0; i < count; i++) {
+		if (wildcard_match(queue_users[i]->username, usermask))
+			users_dup[match_count++] = queue_users[i];
+	}
+	for (i = 0; i < match_count; i++) {
+		replicator_queue_add(client->queue, users_dup[i]->username,
+				     priority);
+	}
+	o_stream_send_str(client->conn.output,
+			  t_strdup_printf("+%u\n", match_count));
+	return 0;
+}
+
 static int client_input_args(struct connection *conn, const char *const *args)
 {
 	struct doveadm_connection *client = (struct doveadm_connection *)conn;
@@ -62,6 +101,8 @@
 
 	if (strcmp(cmd, "STATUS") == 0)
 		return client_input_status(client, args);
+	else if (strcmp(cmd, "REPLICATE") == 0)
+		return client_input_replicate(client, args);
 	i_error("%s: Unknown command: %s", conn->name, cmd);
 	return -1;
 }


More information about the dovecot-cvs mailing list