예제 #1
0
static int doveadm_cmd_handle(struct client_connection *conn,
			      const char *cmd_name,
			      const struct mail_storage_service_input *input,
			      int argc, char *argv[])
{
	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_cmd_find(cmd_name, &argc, &argv);
	if (cmd == NULL) {
		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;
	}

	/* 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;
}
예제 #2
0
static struct doveadm_mail_cmd_context *
doveadm_mail_cmd_server_parse(const char *cmd_name,
			      const struct doveadm_settings *set,
			      const struct mail_storage_service_input *input,
			      int argc, char *argv[])
{
	struct doveadm_mail_cmd_context *ctx;
	const struct doveadm_mail_cmd *cmd;
	const char *getopt_args;
	bool add_username_header = FALSE;
	int c;

	cmd = doveadm_mail_cmd_find(cmd_name);
	if (cmd == NULL) {
		i_error("doveadm: Client sent unknown command: %s", cmd_name);
		return NULL;
	}

	ctx = doveadm_mail_cmd_init(cmd, set);
	ctx->full_args = (const void *)(argv + 1);
	ctx->proxying = TRUE;

	ctx->service_flags |=
		MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
		MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
	if (doveadm_debug)
		ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;

	getopt_args = t_strconcat("AS:u:", ctx->getopt_args, NULL);
	while ((c = getopt(argc, argv, getopt_args)) > 0) {
		switch (c) {
		case 'A':
			add_username_header = TRUE;
			break;
		case 'S':
			/* ignore */
			break;
		case 'u':
			if (strchr(optarg, '*') != NULL ||
			    strchr(optarg, '?') != NULL)
				add_username_header = TRUE;
			break;
		default:
			if ((ctx->v.parse_arg == NULL ||
			     !ctx->v.parse_arg(ctx, c))) {
				i_error("doveadm %s: "
					"Client sent unknown parameter: %c",
					cmd->name, c);
				ctx->v.deinit(ctx);
				return NULL;
			}
		}
	}

	argv += optind;
	optind = 1;

	if (argv[0] != NULL && cmd->usage_args == NULL) {
		i_error("doveadm %s: Client sent unknown parameter: %s",
			cmd->name, argv[0]);
		ctx->v.deinit(ctx);
		return NULL;
	}
	ctx->args = (const void *)argv;

	if (doveadm_print_is_initialized() && add_username_header) {
		doveadm_print_header("username", "Username",
				     DOVEADM_PRINT_HEADER_FLAG_STICKY |
				     DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
		doveadm_print_sticky("username", input->username);
	}
	return ctx;
}