doveadm-cmd.c revision b0d00847d0e1ab20662efce5b24f8fee6897c6fe
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny/* Copyright (c) 2009-2r016 Dovecot authors, see the included COPYING file */
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include "lib.h"
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include "array.h"
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include "istream.h"
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include "str.h"
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include "net.h"
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include "doveadm-cmd.h"
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include "doveadm.h"
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include <stdio.h>
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include <unistd.h>
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny#include <getopt.h>
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenystatic struct doveadm_cmd *doveadm_commands[] = {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_mailbox_mutf7,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_sis_deduplicate,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_sis_find,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny};
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenystatic struct doveadm_cmd_ver2 *doveadm_commands_ver2[] = {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_service_stop_ver2,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_service_status_ver2,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_process_status_ver2,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_stop_ver2,
3ee411625aee19afda7477bb10b52c3da378b6fbPetr Čech &doveadm_cmd_reload_ver2,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_stats_dump_ver2,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_stats_reset_ver2,
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher &doveadm_cmd_penalty_ver2,
fae99bfe4bfc8b4a12e9c2a0ad01b3684c22f934Simo Sorce &doveadm_cmd_kick_ver2,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny &doveadm_cmd_who_ver2
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny};
d81d8d3dc151ebc95cd0e3f3b14c1cdaa48980f1Sumit Bose
d81d8d3dc151ebc95cd0e3f3b14c1cdaa48980f1Sumit Bosestatic const struct exit_code_str {
d81d8d3dc151ebc95cd0e3f3b14c1cdaa48980f1Sumit Bose int code;
c03214d427ea43e7bf8255ccc79faa905c89f7f6Jakub Hrozek const char *str;
d81d8d3dc151ebc95cd0e3f3b14c1cdaa48980f1Sumit Bose} exit_code_strings[] = {
d81d8d3dc151ebc95cd0e3f3b14c1cdaa48980f1Sumit Bose { DOVEADM_EX_UNKNOWN, "UNKNOWN" },
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny { EX_TEMPFAIL, "TEMPFAIL" },
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny { EX_USAGE, "USAGE" },
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny { EX_NOUSER, "NOUSER" },
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny { EX_NOPERM, "NOPERM" },
bfd59d1a2d0d45125e5164ef12c425690d519f61Jakub Hrozek { EX_PROTOCOL, "PROTOCOL" },
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny { EX_DATAERR, "DATAERR" },
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek { DOVEADM_EX_NOTFOUND, "NOTFOUND" }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny};
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan ZelenyARRAY_TYPE(doveadm_cmd) doveadm_cmds;
21d485184df986e1a123f70c689517386e51a5ceMichal ZidekARRAY_TYPE(doveadm_cmd_ver2) doveadm_cmds_ver2;
f26c954658dfd7461f290f0b5d924951a6db219aJan ZelenyARRAY_DEFINE_TYPE(getopt_option_array, struct option);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
684d1b48b5582a1bf7812b8c3c663592dc6dfed9Pavel Březinaconst char *doveadm_exit_code_to_str(int code)
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose{
b56b06e199f15a8a840b36bc7cb8010e39ae761dSumit Bose for(size_t i = 0; i < N_ELEMENTS(exit_code_strings); i++) {
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik const struct exit_code_str *ptr = &exit_code_strings[i];
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (ptr->code == code)
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz return ptr->str;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return "UNKNOWN";
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenyint doveadm_str_to_exit_code(const char *reason)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny for(size_t i = 0; i < N_ELEMENTS(exit_code_strings); i++) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const struct exit_code_str *ptr = &exit_code_strings[i];
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek if (strcmp(ptr->str, reason) == 0)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return ptr->code;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return DOVEADM_EX_UNKNOWN;
c03214d427ea43e7bf8255ccc79faa905c89f7f6Jakub Hrozek}
c03214d427ea43e7bf8255ccc79faa905c89f7f6Jakub Hrozek
4c08db0fb0dda3d27b1184248ca5c800d7ce23f0Michal Zidekvoid doveadm_register_cmd(const struct doveadm_cmd *cmd)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append(&doveadm_cmds, cmd, 1);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
c03214d427ea43e7bf8255ccc79faa905c89f7f6Jakub Hrozek
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashovvoid doveadm_cmd_register_ver2(struct doveadm_cmd_ver2 *cmd)
15b5d885e28afcd6c3c19f900eea2a8e00c3e6d3Sumit Bose{
c03214d427ea43e7bf8255ccc79faa905c89f7f6Jakub Hrozek if (cmd->cmd == NULL) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (cmd->mail_cmd != NULL)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny cmd->cmd = doveadm_cmd_ver2_to_mail_cmd_wrapper;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny else if (cmd->old_cmd != NULL)
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov cmd->cmd = doveadm_cmd_ver2_to_cmd_wrapper;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov else i_unreached();
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append(&doveadm_cmds_ver2, cmd, 1);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenyconst struct doveadm_cmd_ver2 *doveadm_cmd_find_ver2(const char *cmd_name)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const struct doveadm_cmd_ver2 *cmd;
326f4fc3125e155ee2d484fe921aafddd6b5a49dPavel Březina
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_foreach(&doveadm_cmds_ver2, cmd) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (strcmp(cmd_name, cmd->name)==0)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return cmd;
b56b06e199f15a8a840b36bc7cb8010e39ae761dSumit Bose }
fdda4b659fa3be3027df91a2b053835186ec2c59Sumit Bose return NULL;
b56b06e199f15a8a840b36bc7cb8010e39ae761dSumit Bose}
b56b06e199f15a8a840b36bc7cb8010e39ae761dSumit Bose
21d485184df986e1a123f70c689517386e51a5ceMichal Zidekconst struct doveadm_cmd_ver2 *
21d485184df986e1a123f70c689517386e51a5ceMichal Zidekdoveadm_cmd_find_with_args_ver2(const char *cmd_name, int *argc,
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek const char *const *argv[])
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov{
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov int i, k;
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek const struct doveadm_cmd_ver2 *cmd;
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek const char *cptr;
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek for(i=0;i<*argc;i++) {
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek if (strcmp((*argv)[i],cmd_name)==0) break;
684d1b48b5582a1bf7812b8c3c663592dc6dfed9Pavel Březina }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny i_assert(i != *argc);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
bfd59d1a2d0d45125e5164ef12c425690d519f61Jakub Hrozek array_foreach(&doveadm_cmds_ver2, cmd) {
bfd59d1a2d0d45125e5164ef12c425690d519f61Jakub Hrozek cptr = cmd->name;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny /* cannot reuse i here because this needs be
bfd59d1a2d0d45125e5164ef12c425690d519f61Jakub Hrozek done more than once */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov for (k=0; *cptr != '\0' && i+k < *argc; k++) {
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek size_t alen = strlen((*argv)[i+k]);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny /* make sure we don't overstep */
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (strlen(cptr) < alen) break;
bfd59d1a2d0d45125e5164ef12c425690d519f61Jakub Hrozek /* did not match */
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (strncmp(cptr, (*argv)[i+k], alen) != 0) break;
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher /* do not accept abbreviations */
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose if (cptr[alen] != ' ' && cptr[alen] != '\0') break;
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose cptr += alen;
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose if (*cptr != '\0') cptr++; /* consume space */
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose }
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose /* name was fully consumed */
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose if (*cptr == '\0') {
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher if (k > 1) {
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose *argc -= k-1;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov *argv += k-1;
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose }
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov return cmd;
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose }
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose }
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose
75dd4b05e1dacc76dc9d5f16be31978f84a71dc5Sumit Bose return NULL;
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher}
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagherstatic bool
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagherdoveadm_cmd_find_multi_word(const char *cmdname, int *_argc,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov const char *const *_argv[])
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov{
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher int argc = *_argc;
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher const char *const *argv = *_argv;
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher size_t len;
8be5e4497e5008f7807178acdfcbf97365ec4e73Stephen Gallagher
c20a339d54b39120b4051f690ca759e6d079f177Stephen Gallagher if (argc < 2)
c20a339d54b39120b4051f690ca759e6d079f177Stephen Gallagher return FALSE;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov len = strlen(argv[1]);
c20a339d54b39120b4051f690ca759e6d079f177Stephen Gallagher if (strncmp(cmdname, argv[1], len) != 0)
c20a339d54b39120b4051f690ca759e6d079f177Stephen Gallagher return FALSE;
c20a339d54b39120b4051f690ca759e6d079f177Stephen Gallagher
c20a339d54b39120b4051f690ca759e6d079f177Stephen Gallagher argc--; argv++;
c20a339d54b39120b4051f690ca759e6d079f177Stephen Gallagher if (cmdname[len] == ' ') {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov /* more args */
c20a339d54b39120b4051f690ca759e6d079f177Stephen Gallagher if (!doveadm_cmd_find_multi_word(cmdname + len + 1,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov &argc, &argv))
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher return FALSE;
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher } else {
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher if (cmdname[len] != '\0')
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher return FALSE;
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher }
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher *_argc = argc;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov *_argv = argv;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov return TRUE;
bfd59d1a2d0d45125e5164ef12c425690d519f61Jakub Hrozek}
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashovconst struct doveadm_cmd *
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagherdoveadm_cmd_find_with_args(const char *cmd_name, int *argc,
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher const char *const *argv[])
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher{
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov const struct doveadm_cmd *cmd;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov size_t cmd_name_len;
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek
58d02e0d3d6d48c97fccdb2ad7212e065671ad6dStephen Gallagher i_assert(*argc > 0);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny cmd_name_len = strlen(cmd_name);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_foreach(&doveadm_cmds, cmd) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (strcmp(cmd->name, cmd_name) == 0)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return cmd;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov /* see if it matches a multi-word command */
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek if (strncmp(cmd->name, cmd_name, cmd_name_len) == 0 &&
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny cmd->name[cmd_name_len] == ' ') {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const char *subcmd_name = cmd->name + cmd_name_len + 1;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
1d93029624d708119bbf803e6647a2cbb271f001Sumit Bose if (doveadm_cmd_find_multi_word(subcmd_name,
1d93029624d708119bbf803e6647a2cbb271f001Sumit Bose argc, argv))
1d93029624d708119bbf803e6647a2cbb271f001Sumit Bose return cmd;
1d93029624d708119bbf803e6647a2cbb271f001Sumit Bose }
1d93029624d708119bbf803e6647a2cbb271f001Sumit Bose }
56e88cd5f3501566778b138e4934ee8e7f3fa674Lukas Slebodnik return NULL;
56e88cd5f3501566778b138e4934ee8e7f3fa674Lukas Slebodnik}
56e88cd5f3501566778b138e4934ee8e7f3fa674Lukas Slebodnik
56e88cd5f3501566778b138e4934ee8e7f3fa674Lukas Slebodnikvoid doveadm_cmds_init(void)
56e88cd5f3501566778b138e4934ee8e7f3fa674Lukas Slebodnik{
56e88cd5f3501566778b138e4934ee8e7f3fa674Lukas Slebodnik unsigned int i;
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek
1d93029624d708119bbf803e6647a2cbb271f001Sumit Bose i_array_init(&doveadm_cmds, 32);
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek i_array_init(&doveadm_cmds_ver2, 2);
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek for (i = 0; i < N_ELEMENTS(doveadm_commands); i++)
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek doveadm_register_cmd(doveadm_commands[i]);
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek for (i = 0; i < N_ELEMENTS(doveadm_commands_ver2); i++)
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek doveadm_cmd_register_ver2(doveadm_commands_ver2[i]);
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik doveadm_register_director_commands();
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik doveadm_register_instance_commands();
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik doveadm_register_proxy_commands();
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik doveadm_register_log_commands();
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik doveadm_register_replicator_commands();
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik doveadm_register_dict_commands();
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik doveadm_register_fs_commands();
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik}
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnik
b9fbeb75e7a4f50f98d979a70a710f9221892483Lukas Slebodnikvoid doveadm_cmds_deinit(void)
bfd59d1a2d0d45125e5164ef12c425690d519f61Jakub Hrozek{
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov array_free(&doveadm_cmds);
d115f40c7a3999e3cbe705a2ff9cf0fd493f80fbMichal Zidek array_free(&doveadm_cmds_ver2);
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek}
108db0e3b9e06e530364ef8228634f5e3f6bd3b5Jakub Hrozek
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenystatic const struct doveadm_cmd_param*
21d485184df986e1a123f70c689517386e51a5ceMichal Zidekdoveadm_cmd_param_get(const struct doveadm_cmd_context *cctx,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const char *name)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny i_assert(cctx != NULL);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny i_assert(cctx->argv != NULL);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny for(int i = 0; i < cctx->argc; i++) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (strcmp(cctx->argv[i].name, name) == 0 && cctx->argv[i].value_set)
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov return &(cctx->argv[i]);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return NULL;
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek}
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenybool doveadm_cmd_param_bool(const struct doveadm_cmd_context *cctx,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const char *name, bool *value_r)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const struct doveadm_cmd_param *param;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if ((param = doveadm_cmd_param_get(cctx, name))==NULL) return FALSE;
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (param->type == CMD_PARAM_BOOL) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny *value_r = param->value.v_bool;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return TRUE;
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek }
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek return FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek
21d485184df986e1a123f70c689517386e51a5ceMichal Zidekbool doveadm_cmd_param_int64(const struct doveadm_cmd_context *cctx,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov const char *name, int64_t *value_r)
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const struct doveadm_cmd_param *param;
e30d02c04efad31f97c35165a92105852c805d34Jakub Hrozek if ((param = doveadm_cmd_param_get(cctx, name))==NULL) return FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (param->type == CMD_PARAM_INT64) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny *value_r = param->value.v_int64;
6199bd6b41e8b280e65db4b4bb17a1c5c0444aa9Stephen Gallagher return TRUE;
b23539e420b9962ad3bfd8f305b9d5acf47e7efbSimo Sorce }
6199bd6b41e8b280e65db4b4bb17a1c5c0444aa9Stephen Gallagher return FALSE;
6199bd6b41e8b280e65db4b4bb17a1c5c0444aa9Stephen Gallagher}
6199bd6b41e8b280e65db4b4bb17a1c5c0444aa9Stephen Gallagher
6199bd6b41e8b280e65db4b4bb17a1c5c0444aa9Stephen Gallagherbool doveadm_cmd_param_str(const struct doveadm_cmd_context *cctx,
6199bd6b41e8b280e65db4b4bb17a1c5c0444aa9Stephen Gallagher const char *name, const char **value_r)
6199bd6b41e8b280e65db4b4bb17a1c5c0444aa9Stephen Gallagher{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const struct doveadm_cmd_param *param;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if ((param = doveadm_cmd_param_get(cctx, name))==NULL) return FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek if (param->type == CMD_PARAM_STR) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny *value_r = param->value.v_string;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return TRUE;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek }
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek return FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenybool doveadm_cmd_param_ip(const struct doveadm_cmd_context *cctx,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const char *name, struct ip_addr *value_r)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const struct doveadm_cmd_param *param;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if ((param = doveadm_cmd_param_get(cctx, name))==NULL) return FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (param->type == CMD_PARAM_IP) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny memcpy(value_r, &param->value.v_ip, sizeof(struct ip_addr));
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return TRUE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
3931c6612fae5ad32ad81a59f77d77c2d896ebe1Jakub Hrozek return FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenybool doveadm_cmd_param_array(const struct doveadm_cmd_context *cctx,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const char *name, const char *const **value_r)
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov{
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov const struct doveadm_cmd_param *param;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov unsigned int count;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if ((param = doveadm_cmd_param_get(cctx, name))==NULL) return FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (param->type == CMD_PARAM_ARRAY) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny *value_r = array_get(&param->value.v_array, &count);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny /* doveadm_cmd_params_null_terminate_arrays() should have been
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny called, which guarantees that we're NULL-terminated */
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny i_assert((*value_r)[count] == NULL);
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozek return TRUE;
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozek }
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozek return FALSE;
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozek}
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozek
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozekbool doveadm_cmd_param_istream(const struct doveadm_cmd_context *cctx,
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozek const char *name, struct istream **value_r)
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozek{
64175969779e51c00a78397746d4fec7ce7033a4Jakub Hrozek const struct doveadm_cmd_param *param;
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek if ((param = doveadm_cmd_param_get(cctx, name))==NULL) return FALSE;
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek if (param->type == CMD_PARAM_ISTREAM) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny *value_r = param->value.v_istream;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return TRUE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek return FALSE;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek}
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozekvoid doveadm_cmd_params_clean(ARRAY_TYPE(doveadm_cmd_param_arr_t) *pargv)
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek{
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek struct doveadm_cmd_param *param;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_foreach_modifiable(pargv, param) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (param->type == CMD_PARAM_ISTREAM &&
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny param->value.v_istream != NULL)
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek i_stream_destroy(&(param->value.v_istream));
b23539e420b9962ad3bfd8f305b9d5acf47e7efbSimo Sorce }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_clear(pargv);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashovvoid doveadm_cmd_params_null_terminate_arrays(ARRAY_TYPE(doveadm_cmd_param_arr_t) *pargv)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny{
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny struct doveadm_cmd_param *param;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_foreach_modifiable(pargv, param) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov if (param->type == CMD_PARAM_ARRAY &&
d115f40c7a3999e3cbe705a2ff9cf0fd493f80fbMichal Zidek array_is_created(&param->value.v_array)) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append_zero(&param->value.v_array);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_delete(&param->value.v_array, array_count(&param->value.v_array)-1, 1);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov }
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov}
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenystatic void
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenydoveadm_cmd_params_to_argv(const char *name, int pargc, const struct doveadm_cmd_param* params,
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek ARRAY_TYPE(const_string) *argv)
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek{
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov bool array_add_opt;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek int i;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek const char * const * cptr;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek i_assert(array_count(argv) == 0);
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek array_append(argv, &name, 1);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny ARRAY_TYPE(const_string) pargv;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek t_array_init(&pargv, 8);
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek for(i=0;i<pargc;i++) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov const char *optarg = NULL;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek ARRAY_TYPE(const_string) *target = argv;
88ab259f993956b6cd0b1a07d3d88d105e368a8cJakub Hrozek if ((params[i].flags & CMD_PARAM_FLAG_POSITIONAL) != 0)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny target = &pargv;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny /* istreams are special */
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny i_assert(params[i].type != CMD_PARAM_ISTREAM);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (params[i].value_set) {
9091fdea936f7d21584682b7f3d58f49b1e7b013Jan Zeleny array_add_opt = FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (params[i].short_opt != '\0') {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (params[i].type == CMD_PARAM_ARRAY) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_add_opt = TRUE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny } else {
2ce00e0d3896bb42db169d1e79553a81ca837a22Simo Sorce optarg = t_strdup_printf("-%c", params[i].short_opt);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append(argv, &optarg, 1);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny /* CMD_PARAM_BOOL is implicitly handled above */
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek if (params[i].type == CMD_PARAM_STR) {
9fcfe80902655f495b7258218fc8114aa5d2c023Stephen Gallagher array_append(target, &params[i].value.v_string,1);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher } else if (params[i].type == CMD_PARAM_INT64) {
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher const char *tmp = t_strdup_printf("%lld",
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny (long long)params[i].value.v_int64);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append(target, &tmp, 1);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny } else if (params[i].type == CMD_PARAM_IP) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const char *tmp = net_ip2addr(&params[i].value.v_ip);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append(target, &tmp, 1);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher } else if (params[i].type == CMD_PARAM_ARRAY) {
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher array_foreach(&params[i].value.v_array, cptr) {
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher if (array_add_opt)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append(argv, &optarg, 1);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append(target, cptr, 1);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (array_count(&pargv) > 0) {
2ce00e0d3896bb42db169d1e79553a81ca837a22Simo Sorce const char *dashdash = "--";
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append(argv, &dashdash, 1);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_append_array(argv, &pargv);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher array_append_zero(argv);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenyvoid
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozekdoveadm_cmd_ver2_to_cmd_wrapper(struct doveadm_cmd_context *cctx)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny{
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek unsigned int pargc;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny const char **pargv;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny i_assert(cctx->cmd->old_cmd != NULL);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny ARRAY_TYPE(const_string) nargv;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny t_array_init(&nargv, 8);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny doveadm_cmd_params_to_argv(cctx->cmd->name, cctx->argc, cctx->argv, &nargv);
2ce00e0d3896bb42db169d1e79553a81ca837a22Simo Sorce pargv = array_get_modifiable(&nargv, &pargc);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny i_getopt_reset();
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny cctx->cmd->old_cmd(pargc-1, (char**)pargv);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher}
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagherstatic void
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagherdoveadm_build_options(const struct doveadm_cmd_param par[],
749cfb5d3270b5daf389d51a0dbd3fd2aec6e05dJakub Hrozek string_t *shortopts,
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher ARRAY_TYPE(getopt_option_array) *longopts)
169fa5bd3edd34aa0db35681832bd7406e423c1bStephen Gallagher{
169fa5bd3edd34aa0db35681832bd7406e423c1bStephen Gallagher for(size_t i=0; par[i].name != NULL; i++) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov struct option longopt;
169fa5bd3edd34aa0db35681832bd7406e423c1bStephen Gallagher
169fa5bd3edd34aa0db35681832bd7406e423c1bStephen Gallagher i_zero(&longopt);
169fa5bd3edd34aa0db35681832bd7406e423c1bStephen Gallagher longopt.name = par[i].name;
169fa5bd3edd34aa0db35681832bd7406e423c1bStephen Gallagher if (par[i].short_opt != '\0') {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny longopt.val = par[i].short_opt;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny str_append_c(shortopts, par[i].short_opt);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (par[i].type != CMD_PARAM_BOOL)
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny str_append_c(shortopts, ':');
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (par[i].type != CMD_PARAM_BOOL)
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny longopt.has_arg = 1;
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny array_append(longopts, &longopt, 1);
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny }
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny array_append_zero(longopts);
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny}
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zelenystatic void doveadm_fill_param(struct doveadm_cmd_param *param,
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny const char *value, pool_t pool)
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny{
64ddff90c7fcc02ccb06824ac93af7d5f361a88fJan Zeleny param->value_set = TRUE;
6b81b6ada1010e65b447fc74453e236fb8791813Jan Zeleny switch(param->type) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny case CMD_PARAM_BOOL:
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny param->value.v_bool = TRUE; break;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny case CMD_PARAM_INT64:
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (str_to_int64(value, &param->value.v_int64) != 0) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny param->value_set = FALSE;
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek }
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek break;
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek case CMD_PARAM_IP:
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek if (net_addr2ip(value, &param->value.v_ip) != 0) {
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek param->value_set = FALSE;
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek }
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek break;
c4eb21582937362e09aa34e6a18b7f33815d4940Jakub Hrozek case CMD_PARAM_STR:
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny param->value.v_string = p_strdup(pool, value);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny break;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny case CMD_PARAM_ARRAY:
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (!array_is_created(&param->value.v_array))
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny p_array_init(&param->value.v_array, pool, 8);
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek const char *val = p_strdup(pool, value);
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek array_append(&param->value.v_array, &val, 1);
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek break;
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek case CMD_PARAM_ISTREAM: {
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek struct istream *is;
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek if (strcmp(value,"-") == 0) {
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek is = i_stream_create_fd(STDIN_FILENO, IO_BLOCK_SIZE);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher } else {
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek is = i_stream_create_file(value, IO_BLOCK_SIZE);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
7ba70236daccb48432350147d0560b3302518ceeMichal Zidek param->value.v_istream = is;
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek }
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny}
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zelenybool doveadm_cmd_try_run_ver2(const char *cmd_name,
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny int argc, const char *const argv[],
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny struct doveadm_cmd_context *cctx)
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek{
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek const struct doveadm_cmd_ver2 *cmd;
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek cmd = doveadm_cmd_find_with_args_ver2(cmd_name, &argc, &argv);
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek if (cmd == NULL)
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek return FALSE;
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek cctx->cmd = cmd;
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek if (doveadm_cmd_run_ver2(argc, argv, cctx) < 0)
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek doveadm_exit_code = EX_USAGE;
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek return TRUE;
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek}
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozekint doveadm_cmd_run_ver2(int argc, const char *const argv[],
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek struct doveadm_cmd_context *cctx)
3e39806177e1cd383743ff596cb96df44a6ce8c9Jakub Hrozek{
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher struct doveadm_cmd_param *param;
169fa5bd3edd34aa0db35681832bd7406e423c1bStephen Gallagher ARRAY_TYPE(doveadm_cmd_param_arr_t) pargv;
169fa5bd3edd34aa0db35681832bd7406e423c1bStephen Gallagher ARRAY_TYPE(getopt_option_array) opts;
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher unsigned int pargc;
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher int c,li;
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher pool_t pool = pool_datastack_create();
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher string_t *optbuf = str_new(pool, 64);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher p_array_init(&opts, pool, 4);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher // build parameters
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher doveadm_build_options(cctx->cmd->parameters, optbuf, &opts);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher p_array_init(&pargv, pool, 20);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher for(pargc=0;cctx->cmd->parameters[pargc].name != NULL;pargc++) {
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher param = array_append_space(&pargv);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher memcpy(param, &(cctx->cmd->parameters[pargc]), sizeof(struct doveadm_cmd_param));
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher param->value_set = FALSE;
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher }
92ec40e6aa25f75903ffdb166a8ec56b67bfd77dPavel Březina i_assert(pargc == array_count(&opts)-1); /* opts is NULL-terminated */
92ec40e6aa25f75903ffdb166a8ec56b67bfd77dPavel Březina
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher while((c = getopt_long(argc, (char*const*)argv, str_c(optbuf), array_idx(&opts, 0), &li)) > -1) {
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher switch(c) {
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher case 0:
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher for(unsigned int i = 0; i < array_count(&pargv); i++) {
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher const struct option *opt = array_idx(&opts,li);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov param = array_idx_modifiable(&pargv,i);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if (opt->name == param->name)
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher doveadm_fill_param(param, optarg, pool);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher }
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher break;
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher case '?':
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher case ':':
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher doveadm_cmd_params_clean(&pargv);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher return -1;
2f3ee3f49019f5b60adbe073070f31e6e2d7c7abStephen Gallagher default:
2f3ee3f49019f5b60adbe073070f31e6e2d7c7abStephen Gallagher // hunt the option
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny for(unsigned int i = 0; i < pargc; i++) {
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher const struct option *longopt = array_idx(&opts,i);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (longopt->val == c)
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher doveadm_fill_param(array_idx_modifiable(&pargv,i), optarg, pool);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny /* process positional arguments */
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny for(;optind<argc;optind++) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny struct doveadm_cmd_param *ptr;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny bool found = FALSE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny array_foreach_modifiable(&pargv, ptr) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if ((ptr->flags & CMD_PARAM_FLAG_POSITIONAL) != 0 &&
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny (ptr->value_set == FALSE || ptr->type == CMD_PARAM_ARRAY)) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny doveadm_fill_param(ptr, argv[optind], pool);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny found = TRUE;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny break;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny if (!found) {
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny i_error("Extraneous arguments found: %s",
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny t_strarray_join(argv+optind, " "));
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny doveadm_cmd_params_clean(&pargv);
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny return -1;
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny }
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny
f26c954658dfd7461f290f0b5d924951a6db219aJan Zeleny doveadm_cmd_params_null_terminate_arrays(&pargv);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher cctx->argv = array_get_modifiable(&pargv, &pargc);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher cctx->argc = pargc;
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher cctx->cmd->cmd(cctx);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher doveadm_cmd_params_clean(&pargv);
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher return 0;
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher}
38e1ee5d65ade946f1322efa96f69c05e041c57fStephen Gallagher