changeset 19903:35fc9498aa80

doveadm-kick: Rewrite to ver2 infra
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Sun, 28 Feb 2016 19:31:10 +0200
parents fb76c4085b27
children 4f2265d0dd10
files src/doveadm/doveadm-cmd.c src/doveadm/doveadm-cmd.h src/doveadm/doveadm-kick.c
diffstat 3 files changed, 49 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/doveadm-cmd.c	Sun Feb 28 19:25:46 2016 +0200
+++ b/src/doveadm/doveadm-cmd.c	Sun Feb 28 19:31:10 2016 +0200
@@ -13,7 +13,6 @@
 #include <getopt.h>
 
 static struct doveadm_cmd *doveadm_commands[] = {
-	&doveadm_cmd_kick,
 	&doveadm_cmd_mailbox_mutf7,
 	&doveadm_cmd_sis_deduplicate,
 	&doveadm_cmd_sis_find,
@@ -25,6 +24,7 @@
 	&doveadm_cmd_stats_dump_ver2,
 	&doveadm_cmd_stats_reset_ver2,
 	&doveadm_cmd_penalty_ver2,
+	&doveadm_cmd_kick_ver2,
 	&doveadm_cmd_who_ver2
 };
 
--- a/src/doveadm/doveadm-cmd.h	Sun Feb 28 19:25:46 2016 +0200
+++ b/src/doveadm/doveadm-cmd.h	Sun Feb 28 19:31:10 2016 +0200
@@ -88,7 +88,6 @@
 
 extern struct doveadm_cmd doveadm_cmd_dump;
 extern struct doveadm_cmd doveadm_cmd_pw;
-extern struct doveadm_cmd doveadm_cmd_kick;
 extern struct doveadm_cmd doveadm_cmd_mailbox_mutf7;
 extern struct doveadm_cmd doveadm_cmd_sis_deduplicate;
 extern struct doveadm_cmd doveadm_cmd_sis_find;
@@ -148,6 +147,7 @@
 extern struct doveadm_cmd_ver2 doveadm_cmd_stats_dump_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_stats_top_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_penalty_ver2;
+extern struct doveadm_cmd_ver2 doveadm_cmd_kick_ver2;
 extern struct doveadm_cmd_ver2 doveadm_cmd_who_ver2;
 
 #endif
--- a/src/doveadm/doveadm-kick.c	Sun Feb 28 19:25:46 2016 +0200
+++ b/src/doveadm/doveadm-kick.c	Sun Feb 28 19:31:10 2016 +0200
@@ -28,6 +28,7 @@
 struct kick_context {
 	struct who_context who;
 	HASH_TABLE(void *, struct kick_pid *) pids;
+	bool cli;
 	bool force_kick;
 	ARRAY(const char *) kicked_users;
 };
@@ -102,16 +103,20 @@
 	const char *const *users;
 
 	if (array_count(&ctx->kicked_users) == 0) {
-		printf("no users kicked\n");
+		if (ctx->cli)
+			printf("no users kicked\n");
 		doveadm_exit_code = DOVEADM_EX_NOTFOUND;
 		return;
 	}
 
-	if (show_warning) {
-		printf("warning: other connections would also be "
-		       "kicked from following users:\n");
-	} else
-		printf("kicked connections from the following users:\n");
+	if (ctx->cli) {
+		if (show_warning) {
+			printf("warning: other connections would also be "
+			       "kicked from following users:\n");
+		} else {
+			printf("kicked connections from the following users:\n");
+		}
+	}
 
 	array_sort(&ctx->kicked_users, i_strcmp_p);
 	users = array_get(&ctx->kicked_users, &count);
@@ -120,7 +125,8 @@
 		if (strcmp(users[i-1], users[i]) != 0)
 			doveadm_print(users[i]);
 	}
-	printf("\n");
+	if (ctx->cli)
+		printf("\n");
 
 	if (show_warning)
 		printf("Use the '-f' option to enforce the disconnect.\n");
@@ -168,38 +174,40 @@
 	kick_print_kicked(ctx, show_enforce_warning);
 }
 
-static void cmd_kick(int argc, char *argv[])
+static void cmd_kick(struct doveadm_cmd_context *cctx)
 {
+	const char *const *masks;
 	struct kick_context ctx;
-	int c;
 
 	memset(&ctx, 0, sizeof(ctx));
-	ctx.who.anvil_path = t_strconcat(doveadm_settings->base_dir, "/anvil", NULL);
-	ctx.force_kick = FALSE;
+	if (!doveadm_cmd_param_str(cctx, "socket-path", &(ctx.who.anvil_path)))
+		ctx.who.anvil_path = t_strconcat(doveadm_settings->base_dir, "/anvil", NULL);
+	(void)doveadm_cmd_param_bool(cctx, "force", &(ctx.force_kick));
+	if (!doveadm_cmd_param_array(cctx, "mask", &masks)) {
+		doveadm_exit_code = EX_USAGE;
+		i_error("user and/or ip[/bits] must be specified.");
+		return;
+	}
+	ctx.cli = cctx->cli;
+	if (!ctx.cli) {
+		/* force-kick is a pretty ugly option. its output can't be
+		   nicely translated to an API reply. it also wouldn't be very
+		   useful in scripts, only for preventing a new admin from
+		   accidentally kicking too many users. it's also useful only
+		   in a non-recommended setup where processes are handling
+		   multiple connections. so for now we'll preserve the option
+		   for CLI, but always do a force-kick with non-CLI. */
+		ctx.force_kick = TRUE;
+	}
 	ctx.who.pool = pool_alloconly_create("kick pids", 10240);
 	hash_table_create_direct(&ctx.pids, ctx.who.pool, 0);
 
-	while ((c = getopt(argc, argv, "a:f")) > 0) {
-		switch (c) {
-		case 'a':
-			ctx.who.anvil_path = optarg;
-			break;
-		case 'f':
-			ctx.force_kick = TRUE;
-			break;
-		default:
-			help(&doveadm_cmd_kick);
-		}
+	if (who_parse_args(&ctx.who, masks)!=0) {
+		hash_table_destroy(&ctx.pids);
+		pool_unref(&ctx.who.pool);
+		return;
 	}
 
-	argv += optind - 1;
-	if (argv[1] == NULL) {
-		i_fatal_status(EX_USAGE,
-			       "user and/or ip[/bits] must be specified.");
-	}
-	if (who_parse_args(&ctx.who, (const char *const *)argv + 1) < 0)
-		help(&doveadm_cmd_kick);
-
 	doveadm_print_init(DOVEADM_PRINT_TYPE_FORMATTED);
 	doveadm_print_formatted_set_format("%{result} ");
 	doveadm_print_header_simple("result");
@@ -211,7 +219,13 @@
 	pool_unref(&ctx.who.pool);
 }
 
-struct doveadm_cmd doveadm_cmd_kick = {
-	cmd_kick, "kick",
-	"[-a <anvil socket path>] [-f] <user mask>[|]<ip/bits>"
+struct doveadm_cmd_ver2 doveadm_cmd_kick_ver2 = {
+	.name = "kick",
+	.cmd = cmd_kick,
+	.usage = "[-a <anvil socket path>] <user mask>[|]<ip/bits>",
+DOVEADM_CMD_PARAMS_START
+DOVEADM_CMD_PARAM('a',"socket-path",CMD_PARAM_STR,0)
+DOVEADM_CMD_PARAM('f',"force",CMD_PARAM_BOOL,0)
+DOVEADM_CMD_PARAM('\0',"mask",CMD_PARAM_ARRAY,CMD_PARAM_FLAG_POSITIONAL)
+DOVEADM_CMD_PARAMS_END
 };