From 3f398ec36d6b733c92682f5eb03eeacb047e582f Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 19 Mar 2010 22:04:08 -0700 Subject: smbtorture: Refactor interactive shell into independent commands. Refactor the smbtorture interactive shell into a set of independent command callbacks to make it easier to add more independent commands. --- source4/torture/shell.c | 180 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 154 insertions(+), 26 deletions(-) (limited to 'source4/torture') diff --git a/source4/torture/shell.c b/source4/torture/shell.c index 1da4c59081..31efb28447 100644 --- a/source4/torture/shell.c +++ b/source4/torture/shell.c @@ -3,6 +3,7 @@ SMB torture tester Copyright (C) Andrew Tridgell 1997-2003 Copyright (C) Jelmer Vernooij 2006-2008 + Copyright (C) James Peach 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,12 +24,68 @@ #include "lib/smbreadline/smbreadline.h" #include "torture/smbtorture.h" +struct shell_command; + +typedef void (*shell_function)(const struct shell_command *, + struct torture_context *, int, const char **); + +static void shell_quit(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_help(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_set(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_run(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_list(const struct shell_command *, + struct torture_context *, int, const char **); + +static void shell_usage(const struct shell_command *); +static bool match_command(const char *, const struct shell_command *); + +struct shell_command +{ + shell_function handler; + const char * name; + const char * usage; + const char * help; +} shell_command; + +static const struct shell_command commands[] = +{ + { + shell_help, "help", NULL, + "print this help message" + }, + + { + shell_quit, "quit", NULL, + "exit smbtorture" + }, + + { + shell_list, "list", NULL, + "list the available tests" + }, + + { + shell_set, "set", "[NAME VALUE]", + "print or set test configuration parameters" + }, + + { + shell_run, "run", "[TESTNAME]", + "run the specified test" + } +}; + void torture_shell(struct torture_context *tctx) { char *cline; int argc; const char **argv; int ret; + int i; while (1) { cline = smb_readline("torture> ", NULL, NULL); @@ -46,34 +103,105 @@ void torture_shell(struct torture_context *tctx) continue; } - if (!strcmp(argv[0], "quit")) { - return; - } else if (!strcmp(argv[0], "list")) { - torture_print_tests(true); - } else if (!strcmp(argv[0], "set")) { - if (argc < 3) { - lp_dump(tctx->lp_ctx, stdout, - false /* show_defaults */, - 0 /* skip services */); - } else { - char *name = talloc_asprintf(NULL, "torture:%s", argv[1]); - lp_set_cmdline(tctx->lp_ctx, name, argv[2]); - talloc_free(name); - } - } else if (!strcmp(argv[0], "help")) { - fprintf(stderr, "Available commands:\n" - " help - This help command\n" - " list - List the available\n" - " run - Run test\n" - " set - Change variables\n" - "\n"); - } else if (!strcmp(argv[0], "run")) { - if (argc < 2) { - fprintf(stderr, "Usage: run TEST-NAME [OPTIONS...]\n"); - } else { - torture_run_named_tests(tctx, argv[1]); + for (i = 0; i < ARRAY_SIZE(commands); i++) { + if (match_command(argv[0], &commands[i])) { + argc--; + argv++; + commands[i].handler(&commands[i], + tctx, argc, argv); + break; } } + free(cline); } } + +static void shell_quit(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + exit(0); +} + +static void shell_help(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + int i; + + fprintf(stdout, "Available commands:\n"); + for (i = 0; i < ARRAY_SIZE(commands); i++) { + fprintf(stdout, "\t%s - %s\n", + commands[i].name, commands[i].help); + } +} + +static void shell_set(const struct shell_command *command, + struct torture_context *tctx, int argc, const char **argv) +{ + char * name; + + switch (argc) { + case 0: + lp_dump(tctx->lp_ctx, stdout, + false /* show_defaults */, + 0 /* skip services */); + break; + + case 2: + name = talloc_asprintf(NULL, "torture:%s", argv[0]); + lp_set_cmdline(tctx->lp_ctx, name, argv[1]); + talloc_free(name); + break; + + default: + shell_usage(command); + } +} + +static void shell_run(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + if (argc != 1) { + shell_usage(command); + return; + } + + torture_run_named_tests(tctx, argv[0], NULL /* restricted */); +} + +static void shell_list(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + if (argc != 0) { + shell_usage(command); + return; + } + + torture_print_tests(true); +} + +static void shell_usage(const struct shell_command * command) +{ + if (command->usage) { + fprintf(stderr, "Usage: %s %s\n", + command->name, command->usage); + } else { + fprintf(stderr, "Usage: %s\n", + command->name); + } +} + +static bool match_command(const char * name, + const struct shell_command * command) +{ + if (!strcmp(name, command->name)) { + return true; + } + + if (name[0] == command->name[0] && name[1] == '\0') { + return true; + } + + return false; +} + -- cgit