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