dovecot-2.2: doveadm: Support running non-mail commands via dove...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Nov 11 23:08:55 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/a4fbe94952ea
changeset: 18060:a4fbe94952ea
user: Timo Sirainen <tss at iki.fi>
date: Wed Nov 12 01:06:02 2014 +0200
description:
doveadm: Support running non-mail commands via doveadm server.
There are still some commands that print their output via printf though, so
they need to be fixed separately.
diffstat:
src/doveadm/Makefile.am | 44 ++++++++++-------
src/doveadm/client-connection.c | 100 ++++++++++++++++++++++++++++++---------
src/doveadm/main.c | 8 +++
3 files changed, 109 insertions(+), 43 deletions(-)
diffs (260 lines):
diff -r c54b6bbf215a -r a4fbe94952ea src/doveadm/Makefile.am
--- a/src/doveadm/Makefile.am Wed Nov 12 01:04:27 2014 +0200
+++ b/src/doveadm/Makefile.am Wed Nov 12 01:06:02 2014 +0200
@@ -58,7 +58,25 @@
$(LIBDOVECOT_STORAGE_DEPS) \
$(LIBDOVECOT_DEPS)
-common = \
+doveadm_common_cmds = \
+ doveadm-auth.c \
+ doveadm-dict.c \
+ doveadm-director.c \
+ doveadm-fs.c \
+ doveadm-instance.c \
+ doveadm-kick.c \
+ doveadm-log.c \
+ doveadm-master.c \
+ doveadm-mount.c \
+ doveadm-mutf7.c \
+ doveadm-penalty.c \
+ doveadm-proxy.c \
+ doveadm-replicator.c \
+ doveadm-sis.c \
+ doveadm-stats.c \
+ doveadm-who.c
+
+doveadm_common_mail_cmds = \
doveadm-dsync.c \
doveadm-mail.c \
doveadm-mail-altmove.c \
@@ -76,7 +94,12 @@
doveadm-mail-copymove.c \
doveadm-mailbox-list-iter.c \
doveadm-mail-search.c \
- doveadm-mail-server.c \
+ doveadm-mail-server.c
+
+common = \
+ $(doveadm_common_cmds) \
+ $(doveadm_common_mail_cmds) \
+ doveadm-cmd.c \
doveadm-print.c \
doveadm-settings.c \
doveadm-util.c \
@@ -85,34 +108,17 @@
doveadm_SOURCES = \
$(common) \
doveadm.c \
- doveadm-auth.c \
- doveadm-cmd.c \
- doveadm-dict.c \
- doveadm-director.c \
doveadm-dump.c \
doveadm-dump-dbox.c \
doveadm-dump-index.c \
doveadm-dump-log.c \
doveadm-dump-mailboxlog.c \
doveadm-dump-thread.c \
- doveadm-fs.c \
- doveadm-instance.c \
- doveadm-kick.c \
- doveadm-log.c \
- doveadm-master.c \
- doveadm-mount.c \
- doveadm-mutf7.c \
- doveadm-penalty.c \
doveadm-print-flow.c \
doveadm-print-pager.c \
doveadm-print-tab.c \
doveadm-print-table.c \
- doveadm-proxy.c \
doveadm-pw.c \
- doveadm-replicator.c \
- doveadm-sis.c \
- doveadm-stats.c \
- doveadm-who.c \
doveadm-zlib.c
doveadm_server_SOURCES = \
diff -r c54b6bbf215a -r a4fbe94952ea src/doveadm/client-connection.c
--- a/src/doveadm/client-connection.c Wed Nov 12 01:04:27 2014 +0200
+++ b/src/doveadm/client-connection.c Wed Nov 12 01:06:02 2014 +0200
@@ -24,8 +24,52 @@
#define MAX_INBUF_SIZE (1024*1024)
+static struct {
+ int code;
+ const char *str;
+} exit_code_strings[] = {
+ { EX_TEMPFAIL, "TEMPFAIL" },
+ { EX_USAGE, "USAGE" },
+ { EX_NOUSER, "NOUSER" },
+ { EX_NOPERM, "NOPERM" },
+ { EX_PROTOCOL, "PROTOCOL" },
+ { EX_DATAERR, "DATAERR" },
+ { DOVEADM_EX_NOTFOUND, "NOTFOUND" }
+};
+
static void client_connection_input(struct client_connection *conn);
+static void
+doveadm_cmd_server_run(struct client_connection *conn,
+ const struct doveadm_cmd *cmd, int argc, char *argv[])
+{
+ const char *str = NULL;
+ unsigned int i;
+
+ doveadm_exit_code = 0;
+ cmd->cmd(argc, argv);
+
+ if (doveadm_exit_code == 0) {
+ o_stream_nsend(conn->output, "\n+\n", 3);
+ return;
+ }
+
+ for (i = 0; i < N_ELEMENTS(exit_code_strings); i++) {
+ if (exit_code_strings[i].code == doveadm_exit_code) {
+ str = exit_code_strings[i].str;
+ break;
+ }
+ }
+ if (str != NULL) {
+ o_stream_nsend_str(conn->output,
+ t_strdup_printf("\n-%s\n", str));
+ } else {
+ o_stream_nsend_str(conn->output, "\n-\n");
+ i_error("BUG: Command '%s' returned unknown error code %d",
+ cmd->name, doveadm_exit_code);
+ }
+}
+
static int
doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd,
const struct doveadm_settings *set,
@@ -102,16 +146,10 @@
const struct mail_storage_service_input *input)
{
const char *error;
- struct ioloop *ioloop, *prev_ioloop = current_ioloop;
int ret;
ctx->conn = conn;
- /* some commands will want to call io_loop_run(), but we're already
- running one and we can't call the original one recursively, so
- create a new ioloop. */
- ioloop = io_loop_create();
- lib_signals_reset_ioloop();
if (ctx->v.preinit != NULL)
ctx->v.preinit(ctx);
@@ -121,12 +159,6 @@
doveadm_print_flush();
mail_storage_service_deinit(&ctx->storage_service);
- io_loop_set_current(prev_ioloop);
- lib_signals_reset_ioloop();
- o_stream_switch_ioloop(conn->output);
- io_loop_set_current(ioloop);
- io_loop_destroy(&ioloop);
-
if (ret < 0) {
i_error("%s: %s", ctx->cmd->name, error);
o_stream_nsend(conn->output, "\n-\n", 3);
@@ -140,10 +172,6 @@
o_stream_nsend(conn->output, "\n+\n", 3);
}
pool_unref(&ctx->pool);
-
- /* clear all headers */
- doveadm_print_deinit();
- doveadm_print_init(DOVEADM_PRINT_TYPE_SERVER);
}
static bool client_is_allowed_command(const struct doveadm_settings *set,
@@ -172,19 +200,43 @@
const struct mail_storage_service_input *input,
int argc, char *argv[])
{
- const struct doveadm_mail_cmd *cmd;
+ struct ioloop *ioloop, *prev_ioloop = current_ioloop;
+ const struct doveadm_cmd *cmd;
+ const struct doveadm_mail_cmd *mail_cmd;
struct doveadm_mail_cmd_context *ctx;
- cmd = doveadm_mail_cmd_find(cmd_name);
+ cmd = doveadm_cmd_find(cmd_name, &argc, &argv);
if (cmd == NULL) {
- i_error("doveadm: Client sent unknown command: %s", cmd_name);
- return -1;
+ mail_cmd = doveadm_mail_cmd_find(cmd_name);
+ if (mail_cmd == NULL) {
+ i_error("doveadm: Client sent unknown command: %s", cmd_name);
+ return -1;
+ }
+ if (doveadm_mail_cmd_server_parse(mail_cmd, conn->set, input,
+ argc, argv, &ctx) < 0)
+ return -1;
}
- if (doveadm_mail_cmd_server_parse(cmd, conn->set, input,
- argc, argv, &ctx) < 0)
- return -1;
- doveadm_mail_cmd_server_run(conn, ctx, input);
+ /* some commands will want to call io_loop_run(), but we're already
+ running one and we can't call the original one recursively, so
+ create a new ioloop. */
+ ioloop = io_loop_create();
+ lib_signals_reset_ioloop();
+
+ if (cmd != NULL)
+ doveadm_cmd_server_run(conn, cmd, argc, argv);
+ else
+ doveadm_mail_cmd_server_run(conn, ctx, input);
+
+ io_loop_set_current(prev_ioloop);
+ lib_signals_reset_ioloop();
+ o_stream_switch_ioloop(conn->output);
+ io_loop_set_current(ioloop);
+ io_loop_destroy(&ioloop);
+
+ /* clear all headers */
+ doveadm_print_deinit();
+ doveadm_print_init(DOVEADM_PRINT_TYPE_SERVER);
return 0;
}
diff -r c54b6bbf215a -r a4fbe94952ea src/doveadm/main.c
--- a/src/doveadm/main.c Wed Nov 12 01:04:27 2014 +0200
+++ b/src/doveadm/main.c Wed Nov 12 01:06:02 2014 +0200
@@ -36,6 +36,12 @@
conn->ssl);
}
+void help(const struct doveadm_cmd *cmd)
+{
+ i_fatal("Client sent invalid command. Usage: %s %s",
+ cmd->name, cmd->short_usage);
+}
+
static void main_preinit(void)
{
restrict_access_by_env(NULL, FALSE);
@@ -50,6 +56,7 @@
doveadm_settings,
pool_datastack_create());
+ doveadm_cmds_init();
doveadm_mail_init();
doveadm_load_modules();
doveadm_print_init(DOVEADM_PRINT_TYPE_SERVER);
@@ -62,6 +69,7 @@
doveadm_mail_deinit();
doveadm_unload_modules();
doveadm_print_deinit();
+ doveadm_cmds_deinit();
}
int main(int argc, char *argv[])
More information about the dovecot-cvs
mailing list