Skip to content

Commit

Permalink
doveadm: Added struct doveadm_cmd_attributes, which is passed around …
Browse files Browse the repository at this point in the history
…instead of argc/argv
  • Loading branch information
sirainen committed Feb 26, 2016
1 parent 7616a15 commit 79bbb90
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 37 deletions.
47 changes: 28 additions & 19 deletions src/doveadm/client-connection.c
Expand Up @@ -69,30 +69,31 @@ doveadm_cmd_server_post(struct client_connection *conn, const char *cmd_name)
static void
doveadm_cmd_server_run_ver2(struct client_connection *conn,
const struct doveadm_cmd_ver2 *cmd,
int argc, const char *argv[])
const struct doveadm_cmd_attributes *attrs)
{
i_getopt_reset();
doveadm_exit_code = 0;
if (doveadm_cmd_run_ver2(cmd, argc, argv) < 0)
if (doveadm_cmd_run_ver2(cmd, attrs) < 0)
doveadm_exit_code = EX_USAGE;
doveadm_cmd_server_post(conn, cmd->name);
}

static void
doveadm_cmd_server_run(struct client_connection *conn,
const struct doveadm_cmd *cmd, int argc, char *argv[])
const struct doveadm_cmd *cmd,
const struct doveadm_cmd_attributes *attrs)
{
i_getopt_reset();
doveadm_exit_code = 0;
cmd->cmd(argc, argv);
cmd->cmd(attrs->argc, (char **)attrs->argv);
doveadm_cmd_server_post(conn, cmd->name);
}

static int
doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd,
const struct doveadm_settings *set,
const struct mail_storage_service_input *input,
int argc, char *argv[],
const struct doveadm_cmd_attributes *attrs,
struct doveadm_mail_cmd_context **ctx_r)
{
struct doveadm_mail_cmd_context *ctx;
Expand All @@ -101,7 +102,7 @@ doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd,
int c;

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

ctx->service_flags |=
Expand All @@ -112,7 +113,7 @@ doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd,

i_getopt_reset();
getopt_args = t_strconcat("AF:S:u:", ctx->getopt_args, NULL);
while ((c = getopt(argc, argv, getopt_args)) > 0) {
while ((c = getopt(attrs->argc, (char **)attrs->argv, getopt_args)) > 0) {
switch (c) {
case 'A':
case 'F':
Expand All @@ -138,16 +139,15 @@ doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd,
}
}
}
argv += optind;

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

if (doveadm_print_is_initialized() && add_username_header) {
doveadm_print_header("username", "Username",
Expand Down Expand Up @@ -219,25 +219,29 @@ bool doveadm_client_is_allowed_command(const struct doveadm_settings *set,
static int doveadm_cmd_handle(struct client_connection *conn,
const char *cmd_name,
const struct mail_storage_service_input *input,
int argc, char *argv[])
const struct doveadm_cmd_attributes *attrs)
{
struct ioloop *ioloop, *prev_ioloop = current_ioloop;
const struct doveadm_cmd *cmd = NULL;
const struct doveadm_mail_cmd *mail_cmd;
struct doveadm_mail_cmd_context *ctx;
const struct doveadm_cmd_ver2 *cmd_ver2;
struct doveadm_cmd_attributes cmd_attrs;

if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, argc, (const char**)argv)) == NULL) {
cmd = doveadm_cmd_find_with_args(cmd_name, &argc, &argv);
if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, attrs->argc, attrs->argv)) == NULL) {
cmd_attrs = *attrs;
cmd = doveadm_cmd_find_with_args(cmd_name, &cmd_attrs.argc, &cmd_attrs.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)
if (doveadm_mail_cmd_server_parse(mail_cmd, conn->set,
input, attrs, &ctx) < 0)
return -1;
} else {
attrs = &cmd_attrs;
}
}

Expand All @@ -248,9 +252,9 @@ static int doveadm_cmd_handle(struct client_connection *conn,
lib_signals_reset_ioloop();

if (cmd_ver2 != NULL)
doveadm_cmd_server_run_ver2(conn, cmd_ver2, argc, (const char**)argv);
doveadm_cmd_server_run_ver2(conn, cmd_ver2, attrs);
else if (cmd != NULL)
doveadm_cmd_server_run(conn, cmd, argc, argv);
doveadm_cmd_server_run(conn, cmd, attrs);
else
doveadm_mail_cmd_server_run(conn, ctx, input);

Expand All @@ -268,6 +272,7 @@ static int doveadm_cmd_handle(struct client_connection *conn,

static bool client_handle_command(struct client_connection *conn, char **args)
{
struct doveadm_cmd_attributes attrs;
struct mail_storage_service_input input;
const char *flags, *cmd_name;
unsigned int argc;
Expand All @@ -286,6 +291,10 @@ static bool client_handle_command(struct client_connection *conn, char **args)
i_error("doveadm client: No command given");
return FALSE;
}
memset(&attrs, 0, sizeof(attrs));
attrs.argv = (const char **)args;
attrs.argc = argc;

flags = args[0];
input.username = args[1];
cmd_name = args[2];
Expand Down Expand Up @@ -318,7 +327,7 @@ static bool client_handle_command(struct client_connection *conn, char **args)
}

o_stream_cork(conn->output);
if (doveadm_cmd_handle(conn, cmd_name, &input, argc, args) < 0)
if (doveadm_cmd_handle(conn, cmd_name, &input, &attrs) < 0)
o_stream_nsend(conn->output, "\n-\n", 3);
o_stream_uncork(conn->output);

Expand Down
22 changes: 12 additions & 10 deletions src/doveadm/doveadm-cmd.c
Expand Up @@ -97,10 +97,10 @@ doveadm_cmd_find_with_args_ver2(const char *cmd_name, int argc, const char *argv

static const struct doveadm_cmd *
doveadm_cmd_find_multi_word(const struct doveadm_cmd *cmd,
const char *cmdname, int *_argc, char **_argv[])
const char *cmdname, int *_argc, const char **_argv[])
{
int argc = *_argc;
char **argv = *_argv;
const char **argv = *_argv;
const struct doveadm_cmd *subcmd;
unsigned int len;

Expand Down Expand Up @@ -129,7 +129,7 @@ doveadm_cmd_find_multi_word(const struct doveadm_cmd *cmd,
}

const struct doveadm_cmd *
doveadm_cmd_find_with_args(const char *cmd_name, int *argc, char **argv[])
doveadm_cmd_find_with_args(const char *cmd_name, int *argc, const char **argv[])
{
const struct doveadm_cmd *cmd, *subcmd;
unsigned int cmd_name_len;
Expand Down Expand Up @@ -396,20 +396,22 @@ static void doveadm_fill_param(struct doveadm_cmd_param *param,
}
}

bool doveadm_cmd_try_run_ver2(const char *cmd_name, int argc, const char *argv[])
bool doveadm_cmd_try_run_ver2(const char *cmd_name,
const struct doveadm_cmd_attributes *attrs)
{
const struct doveadm_cmd_ver2 *cmd;

cmd = doveadm_cmd_find_with_args_ver2(cmd_name, argc, argv);
cmd = doveadm_cmd_find_with_args_ver2(cmd_name, attrs->argc, attrs->argv);
if (cmd == NULL)
return FALSE;

if (doveadm_cmd_run_ver2(cmd, argc, argv) < 0)
if (doveadm_cmd_run_ver2(cmd, attrs) < 0)
doveadm_exit_code = EX_USAGE;
return TRUE;
}

int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const char *argv[])
int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd,
const struct doveadm_cmd_attributes *attrs)
{
struct doveadm_cmd_param *param;
ARRAY_TYPE(doveadm_cmd_param_arr_t) pargv;
Expand All @@ -434,7 +436,7 @@ int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const cha
}
i_assert(pargc == array_count(&opts)-1); /* opts is NULL-terminated */

while((c = getopt_long(argc, (char*const*)argv, str_c(optbuf), array_idx(&opts, 0), &li)) > -1) {
while((c = getopt_long(attrs->argc, (char*const*)attrs->argv, str_c(optbuf), array_idx(&opts, 0), &li)) > -1) {
switch(c) {
case 0:
doveadm_fill_param(array_idx_modifiable(&pargv,li), optarg, pool);
Expand All @@ -457,13 +459,13 @@ int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const cha
while((cptr = strchr(cptr+1, ' ')) != NULL) optind++;

/* process positional arguments */
for(;optind<argc;optind++) {
for(;optind<attrs->argc;optind++) {
struct doveadm_cmd_param *ptr;
bool found = FALSE;
array_foreach_modifiable(&pargv, ptr) {
if ((ptr->flags & CMD_PARAM_FLAG_POSITIONAL) != 0 &&
(ptr->value_set == FALSE || ptr->type == CMD_PARAM_ARRAY)) {
doveadm_fill_param(ptr, argv[optind], pool);
doveadm_fill_param(ptr, attrs->argv[optind], pool);
found = TRUE;
break;
}
Expand Down
13 changes: 9 additions & 4 deletions src/doveadm/doveadm-cmd.h
Expand Up @@ -66,6 +66,11 @@ struct doveadm_cmd_ver2 {
const struct doveadm_cmd_param *parameters;
};

struct doveadm_cmd_attributes {
int argc;
const char **argv;
};

ARRAY_DEFINE_TYPE(doveadm_cmd, struct doveadm_cmd);
extern ARRAY_TYPE(doveadm_cmd) doveadm_cmds;

Expand All @@ -84,7 +89,7 @@ extern struct doveadm_cmd doveadm_cmd_zlibconnect;
void doveadm_register_cmd(const struct doveadm_cmd *cmd);

const struct doveadm_cmd *
doveadm_cmd_find_with_args(const char *cmd_name, int *argc, char **argv[]);
doveadm_cmd_find_with_args(const char *cmd_name, int *argc, const char **argv[]);

void doveadm_register_auth_commands(void);
void doveadm_register_director_commands(void);
Expand All @@ -109,11 +114,11 @@ const struct doveadm_cmd_ver2 *
doveadm_cmd_find_with_args_ver2(const char *cmd_name, int argc, const char *argv[]);
const struct doveadm_cmd_ver2 *doveadm_cmd_find_ver2(const char *cmd_name);
/* Returns FALSE if cmd_name doesn't exist, TRUE if it exists. */
bool doveadm_cmd_try_run_ver2(const char *cmd_name, int argc,
const char *argv[]);
bool doveadm_cmd_try_run_ver2(const char *cmd_name,
const struct doveadm_cmd_attributes *attrs);
/* Returns 0 if success, -1 if parameters were invalid. */
int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd,
int argc, const char *argv[]);
const struct doveadm_cmd_attributes *attrs);

bool doveadm_cmd_param_bool(int argc, const struct doveadm_cmd_param *params,
const char *name, bool *value_r);
Expand Down
13 changes: 9 additions & 4 deletions src/doveadm/doveadm.c
Expand Up @@ -210,14 +210,14 @@ static void cmd_exec(int argc ATTR_UNUSED, char *argv[])
i_fatal("execv(%s) failed: %m", argv[0]);
}

static bool doveadm_try_run(const char *cmd_name, int argc, char *argv[])
static bool doveadm_try_run(const char *cmd_name, int argc, const char *argv[])
{
const struct doveadm_cmd *cmd;

cmd = doveadm_cmd_find_with_args(cmd_name, &argc, &argv);
if (cmd == NULL)
return FALSE;
cmd->cmd(argc, argv);
cmd->cmd(argc, (char **)argv);
return TRUE;
}

Expand Down Expand Up @@ -283,6 +283,7 @@ int main(int argc, char *argv[])
enum master_service_flags service_flags =
MASTER_SERVICE_FLAG_STANDALONE |
MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN;
struct doveadm_cmd_attributes attrs;
const char *cmd_name;
unsigned int i;
bool quick_init = FALSE;
Expand Down Expand Up @@ -364,8 +365,12 @@ int main(int argc, char *argv[])
i_set_debug_file("/dev/null");
}

if (!doveadm_cmd_try_run_ver2(cmd_name, argc, (const char**)argv) &&
!doveadm_try_run(cmd_name, argc, argv) &&
memset(&attrs, 0, sizeof(attrs));
attrs.argc = argc;
attrs.argv = (const char **)argv;

if (!doveadm_cmd_try_run_ver2(cmd_name, &attrs) &&
!doveadm_try_run(cmd_name, argc, (const char **)argv) &&
!doveadm_mail_try_run(cmd_name, argc, argv)) {
if (doveadm_has_subcommands(cmd_name))
usage_to(stdout, cmd_name);
Expand Down

0 comments on commit 79bbb90

Please sign in to comment.