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; }
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; }