summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2019-11-11 17:29:26 +1100
committerMartin Schwenke <martins@samba.org>2019-11-14 10:38:34 +0000
commit977a6f7fad8d2985e8e898bd8dc7d3d376164e9d (patch)
treee6516b41cfcd70e1bc407f412fbd5df567954264
parent7a008c6b74e559a3e677257be3ea57a5821e3e9c (diff)
downloadsamba-977a6f7fad8d2985e8e898bd8dc7d3d376164e9d.tar.gz
ctdb-common: Change cmdline implementation to support multiple sections
Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net>
-rw-r--r--ctdb/common/cmdline.c134
1 files changed, 101 insertions, 33 deletions
diff --git a/ctdb/common/cmdline.c b/ctdb/common/cmdline.c
index eb5361cf61a..0ce49b8311a 100644
--- a/ctdb/common/cmdline.c
+++ b/ctdb/common/cmdline.c
@@ -29,11 +29,16 @@
#define CMDLINE_MAX_LEN 80
+struct cmdline_section {
+ const char *name;
+ struct cmdline_command *commands;
+};
+
struct cmdline_context {
const char *prog;
struct poptOption *options;
- const char *section;
- struct cmdline_command *commands;
+ struct cmdline_section *section;
+ int num_sections;
int max_len;
poptContext pc;
int argc, arg0;
@@ -207,16 +212,51 @@ static bool cmdline_commands_check(struct cmdline_command *commands,
static int cmdline_context_destructor(struct cmdline_context *cmdline);
+static int cmdline_section_add(struct cmdline_context *cmdline,
+ const char *name,
+ struct cmdline_command *commands)
+{
+ struct cmdline_section *section;
+ size_t max_len = 0;
+ bool ok;
+
+ ok = cmdline_commands_check(commands, &max_len);
+ if (!ok) {
+ return EINVAL;
+ }
+
+ section = talloc_realloc(cmdline,
+ cmdline->section,
+ struct cmdline_section,
+ cmdline->num_sections + 1);
+ if (section == NULL) {
+ return ENOMEM;
+ }
+
+ section[cmdline->num_sections] = (struct cmdline_section) {
+ .name = name,
+ .commands = commands,
+ };
+
+ if (max_len > cmdline->max_len) {
+ cmdline->max_len = max_len;
+ }
+
+ cmdline->section = section;
+ cmdline->num_sections += 1;
+
+ return 0;
+}
+
int cmdline_init(TALLOC_CTX *mem_ctx,
const char *prog,
struct poptOption *options,
- const char *section,
+ const char *name,
struct cmdline_command *commands,
struct cmdline_context **result)
{
struct cmdline_context *cmdline;
int ret;
- size_t max_len = 0;
bool ok;
if (prog == NULL) {
@@ -228,11 +268,6 @@ int cmdline_init(TALLOC_CTX *mem_ctx,
return EINVAL;
}
- ok = cmdline_commands_check(commands, &max_len);
- if (!ok) {
- return EINVAL;
- }
-
cmdline = talloc_zero(mem_ctx, struct cmdline_context);
if (cmdline == NULL) {
return ENOMEM;
@@ -249,9 +284,12 @@ int cmdline_init(TALLOC_CTX *mem_ctx,
talloc_free(cmdline);
return ret;
}
- cmdline->section = section;
- cmdline->commands = commands;
- cmdline->max_len = max_len;
+
+ ret = cmdline_section_add(cmdline, name, commands);
+ if (ret != 0) {
+ talloc_free(cmdline);
+ return ret;
+ }
cmdline->argc = 1;
cmdline->argv = talloc_array(cmdline, const char *, 2);
@@ -326,16 +364,12 @@ static int cmdline_parse_options(struct cmdline_context *cmdline,
return 0;
}
-static int cmdline_match(struct cmdline_context *cmdline)
+static int cmdline_match_section(struct cmdline_context *cmdline,
+ struct cmdline_section *section)
{
int i;
- if (cmdline->argc == 0 || cmdline->argv == NULL) {
- cmdline->match_cmd = NULL;
- return EINVAL;
- }
-
- for (i=0; cmdline->commands[i].name != NULL; i++) {
+ for (i=0; section->commands[i].name != NULL; i++) {
struct cmdline_command *cmd;
char name[CMDLINE_MAX_LEN+1];
size_t len;
@@ -343,7 +377,7 @@ static int cmdline_match(struct cmdline_context *cmdline)
int n = 0;
bool match = false;
- cmd = &cmdline->commands[i];
+ cmd = &section->commands[i];
len = strlcpy(name, cmd->name, sizeof(name));
if (len >= sizeof(name)) {
D_ERR("Skipping long command '%s'\n", cmd->name);
@@ -382,6 +416,25 @@ static int cmdline_match(struct cmdline_context *cmdline)
return ENOENT;
}
+static int cmdline_match(struct cmdline_context *cmdline)
+{
+ int i, ret = ENOENT;
+
+ if (cmdline->argc == 0 || cmdline->argv == NULL) {
+ cmdline->match_cmd = NULL;
+ return EINVAL;
+ }
+
+ for (i=0; i<cmdline->num_sections; i++) {
+ ret = cmdline_match_section(cmdline, &cmdline->section[i]);
+ if (ret == 0) {
+ break;
+ }
+ }
+
+ return ret;
+}
+
int cmdline_parse(struct cmdline_context *cmdline,
int argc,
const char **argv,
@@ -445,38 +498,53 @@ static void cmdline_usage_command(struct cmdline_context *cmdline,
printf(" %s\n", cmd->msg_help);
}
-static void cmdline_usage_full(struct cmdline_context *cmdline)
+static void cmdline_usage_section(struct cmdline_context *cmdline,
+ struct cmdline_section *section)
{
int i;
- poptSetOtherOptionHelp(cmdline->pc, "[<options>] <command> [<args>]");
- poptPrintHelp(cmdline->pc, stdout, 0);
-
printf("\n");
- if (cmdline->section != NULL) {
- printf("%s ", cmdline->section);
+
+ if (section->name != NULL) {
+ printf("%s ", section->name);
}
printf("Commands:\n");
- for (i=0; cmdline->commands[i].name != NULL; i++) {
- cmdline_usage_command(cmdline, &cmdline->commands[i], true);
+ for (i=0; section->commands[i].name != NULL; i++) {
+ cmdline_usage_command(cmdline, &section->commands[i], true);
}
}
+static void cmdline_usage_full(struct cmdline_context *cmdline)
+{
+ int i;
+
+ poptSetOtherOptionHelp(cmdline->pc, "[<options>] <command> [<args>]");
+ poptPrintHelp(cmdline->pc, stdout, 0);
+
+ for (i=0; i<cmdline->num_sections; i++) {
+ cmdline_usage_section(cmdline, &cmdline->section[i]);
+ }
+}
+
void cmdline_usage(struct cmdline_context *cmdline, const char *cmd_name)
{
struct cmdline_command *cmd = NULL;
- int i;
+ int i, j;
if (cmd_name == NULL) {
cmdline_usage_full(cmdline);
return;
}
- for (i=0; cmdline->commands[i].name != NULL; i++) {
- if (strcmp(cmdline->commands[i].name, cmd_name) == 0) {
- cmd = &cmdline->commands[i];
- break;
+ for (j=0; j<cmdline->num_sections; j++) {
+ struct cmdline_section *section = &cmdline->section[j];
+
+ for (i=0; section->commands[i].name != NULL; i++) {
+ if (strcmp(section->commands[i].name, cmd_name) == 0) {
+ cmd = &section->commands[i];
+ break;
+ }
}
}