1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

ctdb-common: Change cmdline implementation to support multiple sections

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
Amitay Isaacs 2019-11-11 17:29:26 +11:00 committed by Martin Schwenke
parent 7a008c6b74
commit 977a6f7fad

View File

@ -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,6 +498,23 @@ static void cmdline_usage_command(struct cmdline_context *cmdline,
printf(" %s\n", cmd->msg_help);
}
static void cmdline_usage_section(struct cmdline_context *cmdline,
struct cmdline_section *section)
{
int i;
printf("\n");
if (section->name != NULL) {
printf("%s ", section->name);
}
printf("Commands:\n");
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;
@ -452,31 +522,29 @@ static void cmdline_usage_full(struct cmdline_context *cmdline)
poptSetOtherOptionHelp(cmdline->pc, "[<options>] <command> [<args>]");
poptPrintHelp(cmdline->pc, stdout, 0);
printf("\n");
if (cmdline->section != NULL) {
printf("%s ", cmdline->section);
}
printf("Commands:\n");
for (i=0; cmdline->commands[i].name != NULL; i++) {
cmdline_usage_command(cmdline, &cmdline->commands[i], true);
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;
}
}
}