The branch, master has been updated via 6227eac... smbtorture: Fixx off-by-one command line parsing. via 0fc18ea... smbtorture: Add "target" command to interactive shell. via 7a25e2e... smbtorture: Enhance shell "help" command. via bf35aa8... smbtorture: Add "auth" command to the shell. via 3f398ec... smbtorture: Refactor interactive shell into independent commands. via 9f69790... smbtorture: Move interactive shell into a separate file. via a5e14bd... smbtorture: Print global options for interactive "list" command. via 12e15b0... smbtorture: Add history support to shell mode. via 6f96293... smbtorture: Add list command to smbtorture shell. from acf54c3... s3-winbind: Make KRB5_EVENT_REFRESH_TIME a function
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 6227eac607131ed1042af1de83af7f70d0b05375 Author: James Peach <jpe...@samba.org> Date: Mon Jun 21 11:09:45 2010 -0700 smbtorture: Fixx off-by-one command line parsing. If we are not in shell mode we require both the target and test name arguments. Make sure we process these from the correct index. commit 0fc18ead76a79286365646eeb7607b39b01a1c9f Author: James Peach <jpe...@samba.org> Date: Mon Mar 22 21:55:49 2010 -0700 smbtorture: Add "target" command to interactive shell. Add a "target" command to set the target server to test. Refactor the command line argument processing a little so that you can run --shell without any additional arguments. commit 7a25e2efe9360b333fedc3fb938774437703700e Author: James Peach <jpe...@samba.org> Date: Sun Mar 21 22:04:37 2010 -0700 smbtorture: Enhance shell "help" command. Sort the command list alphabetically. Let the help command print usage info for other commands. commit bf35aa86038aa5bbf06bf73eb58cfa6fa1eae904 Author: James Peach <jpe...@samba.org> Date: Sun Mar 21 21:56:05 2010 -0700 smbtorture: Add "auth" command to the shell. Add a new "auth" command to set the cmdline credentials from withing the smbtorture shell. commit 3f398ec36d6b733c92682f5eb03eeacb047e582f Author: James Peach <jpe...@samba.org> Date: Fri Mar 19 22:04:08 2010 -0700 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. commit 9f697903556529bb4fedd73d027c317e56f6bf21 Author: James Peach <jpe...@samba.org> Date: Fri Mar 19 21:24:15 2010 -0700 smbtorture: Move interactive shell into a separate file. commit a5e14bded48ac53e21307eda1c9767be64b39a17 Author: James Peach <jpe...@samba.org> Date: Thu Mar 18 21:59:35 2010 -0700 smbtorture: Print global options for interactive "list" command. commit 12e15b0ac800a84d553ff82c4c61ccc8da9fd5fd Author: James Peach <jpe...@samba.org> Date: Thu Mar 18 21:25:17 2010 -0700 smbtorture: Add history support to shell mode. commit 6f96293406bfaff35e7588d0624842de145ff249 Author: James Peach <jpe...@samba.org> Date: Thu Mar 18 21:14:47 2010 -0700 smbtorture: Add list command to smbtorture shell. ----------------------------------------------------------------------- Summary of changes: lib/torture/torture.c | 2 +- lib/torture/torture.h | 2 +- source4/lib/smbreadline/readline.m4 | 5 + source4/torture/config.mk | 5 +- source4/torture/shell.c | 318 +++++++++++++++++++++++++++++++++++ source4/torture/smbtorture.c | 141 ++++++++++------ source4/torture/smbtorture.h | 5 + source4/torture/wscript_build | 2 +- 8 files changed, 422 insertions(+), 58 deletions(-) create mode 100644 source4/torture/shell.c Changeset truncated at 500 lines: diff --git a/lib/torture/torture.c b/lib/torture/torture.c index dcb28ee..4333f98 100644 --- a/lib/torture/torture.c +++ b/lib/torture/torture.c @@ -305,7 +305,7 @@ bool torture_run_suite(struct torture_context *context, } bool torture_run_suite_restricted(struct torture_context *context, - struct torture_suite *suite, char **restricted) + struct torture_suite *suite, const char **restricted) { /* FIXME */ return false; diff --git a/lib/torture/torture.h b/lib/torture/torture.h index 931937c..6482e89 100644 --- a/lib/torture/torture.h +++ b/lib/torture/torture.h @@ -221,7 +221,7 @@ bool torture_run_suite(struct torture_context *context, /* Run the specified testsuite recursively, but only the specified * tests */ bool torture_run_suite_restricted(struct torture_context *context, - struct torture_suite *suite, char **restricted); + struct torture_suite *suite, const char **restricted); /* Run the specified testcase */ bool torture_run_tcase(struct torture_context *context, diff --git a/source4/lib/smbreadline/readline.m4 b/source4/lib/smbreadline/readline.m4 index df15440..06d60ca 100644 --- a/source4/lib/smbreadline/readline.m4 +++ b/source4/lib/smbreadline/readline.m4 @@ -78,6 +78,11 @@ AC_CHECK_LIB(readline, history_list, [], [$TERMLIBS]) +AC_CHECK_LIB(readline, add_history, + [AC_DEFINE(HAVE_ADD_HISTORY, 1, [Do we have add_history?])], + [], + [$TERMLIBS]) + AC_MSG_CHECKING(whether to use extern readline) if test x"$EXTERNAL_READLINE" = x"yes"; then AC_MSG_RESULT(yes) diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 25e9b53..09af078 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -280,7 +280,10 @@ PRIVATE_DEPENDENCIES = \ # End BINARY smbtorture ################################# -smbtorture_OBJ_FILES = $(torturesrcdir)/smbtorture.o $(torturesrcdir)/torture.o +smbtorture_OBJ_FILES = \ + $(torturesrcdir)/smbtorture.o \ + $(torturesrcdir)/torture.o \ + $(torturesrcdir)/shell.o PUBLIC_HEADERS += $(torturesrcdir)/smbtorture.h MANPAGES += $(torturesrcdir)/man/smbtorture.1 diff --git a/source4/torture/shell.c b/source4/torture/shell.c new file mode 100644 index 0000000..2f58eb9 --- /dev/null +++ b/source4/torture/shell.c @@ -0,0 +1,318 @@ +/* + Unix SMB/CIFS implementation. + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/readline.h" +#include "lib/smbreadline/smbreadline.h" +#include "lib/cmdline/popt_common.h" +#include "auth/credentials/credentials.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_auth(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_target(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_auth, "auth", + "[[username | principal | domain | realm | password] STRING]", + "set authentication parameters" + }, + + { + shell_help, "help", NULL, + "print this help message" + }, + + { + shell_list, "list", NULL, + "list the available tests" + }, + + { + shell_quit, "quit", NULL, + "exit smbtorture" + }, + + { + shell_run, "run", "[TESTNAME]", + "run the specified test" + }, + + { + shell_set, "set", "[NAME VALUE]", + "print or set test configuration parameters" + }, + + { + shell_target, "target", "[TARGET]", + "print or set the test target" + } + +}; + +void torture_shell(struct torture_context *tctx) +{ + char *cline; + int argc; + const char **argv; + int ret; + int i; + + /* If we don't have a specified password, specify it as empty. This + * stops the credentials system prompting when we use the "auth" + * command to display the current auth parameters. + */ + if (cmdline_credentials->password_obtained != CRED_SPECIFIED) { + cli_credentials_set_password(cmdline_credentials, "", + CRED_SPECIFIED); + } + + while (1) { + cline = smb_readline("torture> ", NULL, NULL); + + if (cline == NULL) + return; + +#if HAVE_ADD_HISTORY + add_history(cline); +#endif + + ret = poptParseArgvString(cline, &argc, &argv); + if (ret != 0) { + fprintf(stderr, "Error parsing line\n"); + continue; + } + + 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; + + if (argc == 1) { + for (i = 0; i < ARRAY_SIZE(commands); i++) { + if (match_command(argv[0], &commands[i])) { + shell_usage(&commands[i]); + return; + } + } + } else { + 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_auth(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + + if (argc == 0) { + const char * username; + const char * domain; + const char * realm; + const char * password; + const char * principal; + + username = cli_credentials_get_username(cmdline_credentials); + principal = cli_credentials_get_principal(cmdline_credentials, tctx); + domain = cli_credentials_get_domain(cmdline_credentials); + realm = cli_credentials_get_realm(cmdline_credentials); + password = cli_credentials_get_password(cmdline_credentials); + + printf("Username: %s\n", username ? username : ""); + printf("User Principal: %s\n", principal ? principal : ""); + printf("Domain: %s\n", domain ? domain : ""); + printf("Realm: %s\n", realm ? realm : ""); + printf("Password: %s\n", password ? password : ""); + } else if (argc == 2) { + bool result; + + if (!strcmp(argv[0], "username")) { + result = cli_credentials_set_username( + cmdline_credentials, argv[1], CRED_SPECIFIED); + } else if (!strcmp(argv[0], "principal")) { + result = cli_credentials_set_principal( + cmdline_credentials, argv[1], CRED_SPECIFIED); + } else if (!strcmp(argv[0], "domain")) { + result = cli_credentials_set_domain( + cmdline_credentials, argv[1], CRED_SPECIFIED); + } else if (!strcmp(argv[0], "realm")) { + result = cli_credentials_set_realm( + cmdline_credentials, argv[1], CRED_SPECIFIED); + } else if (!strcmp(argv[0], "password")) { + result = cli_credentials_set_password( + cmdline_credentials, argv[1], CRED_SPECIFIED); + } else { + shell_usage(command); + return; + } + + if (!result) { + printf("failed to set %s\n", argv[0]); + } + } else { + shell_usage(command); + } + +} + +static void shell_target(const struct shell_command *command, + struct torture_context *tctx, int argc, const char **argv) +{ + if (argc == 0) { + const char * host; + const char * share; + const char * binding; + + host = torture_setting_string(tctx, "host", NULL); + share = torture_setting_string(tctx, "share", NULL); + binding = torture_setting_string(tctx, "binding", NULL); + + printf("Target host: %s\n", host ? host : ""); + printf("Target share: %s\n", share ? share : ""); + printf("Target binding: %s\n", binding ? binding : ""); + } else if (argc == 1) { + torture_parse_target(tctx->lp_ctx, argv[0]); + } else { + shell_usage(command); + } +} + +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; +} diff --git a/source4/torture/smbtorture.c b/source4/torture/smbtorture.c index 4b5eef6..14eeff9 100644 --- a/source4/torture/smbtorture.c +++ b/source4/torture/smbtorture.c @@ -33,11 +33,14 @@ #include "auth/gensec/gensec.h" #include "param/param.h" +#if HAVE_READLINE_HISTORY_H +#include <readline/history.h> +#endif static bool run_matching(struct torture_context *torture, const char *prefix, const char *expr, - char **restricted, + const char **restricted, struct torture_suite *suite, bool *matched) { @@ -91,8 +94,8 @@ static bool run_matching(struct torture_context *torture, /**************************************************************************** run a specified test or "ALL" ****************************************************************************/ -static bool run_test(struct torture_context *torture, const char *name, - char **restricted) +bool torture_run_named_tests(struct torture_context *torture, const char *name, + const char **restricted) { bool ret = true; bool matched = false; @@ -119,7 +122,7 @@ static bool run_test(struct torture_context *torture, const char *name, return ret; } -static bool parse_target(struct loadparm_context *lp_ctx, const char *target) +bool torture_parse_target(struct loadparm_context *lp_ctx, const char *target) { char *host = NULL, *share = NULL; struct dcerpc_binding *binding_struct; @@ -185,6 +188,47 @@ static void parse_dns(struct loadparm_context *lp_ctx, const char *dns) } +/* Print the full test list, formatted into separate labelled test + * groups. + */ +static void print_structured_test_list(void) +{ + struct torture_suite *o; + struct torture_suite *s; + struct torture_tcase *t; + int i; + + if (torture_root == NULL) { + printf("NO TESTS LOADED\n"); + return; + } + + for (o = torture_root->children; o; o = o->next) { + printf("\n%s (%s):\n ", o->description, o->name); + + i = 0; + for (s = o->children; s; s = s->next) { + if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) { + printf("\n "); + i = 0; + } + i+=printf("%s-%s ", o->name, s->name); + } + + for (t = o->testcases; t; t = t->next) { + if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) { + printf("\n "); + i = 0; + } + i+=printf("%s-%s ", o->name, t->name); + } + + if (i) printf("\n"); + } + + printf("\nThe default test is ALL.\n"); +} + static void print_test_list(void) { struct torture_suite *o; @@ -205,13 +249,17 @@ static void print_test_list(void) } } -_NORETURN_ static void usage(poptContext pc) +void torture_print_tests(bool structured) { - struct torture_suite *o; - struct torture_suite *s; - struct torture_tcase *t; - int i; + if (structured) { + print_structured_test_list(); + } else { + print_test_list(); + } +} +_NORETURN_ static void usage(poptContext pc) +{ poptPrintUsage(pc, stdout, 0); printf("\n"); @@ -264,35 +312,7 @@ _NORETURN_ static void usage(poptContext pc) printf("Tests are:"); - if (torture_root == NULL) { - printf("NO TESTS LOADED\n"); - exit(1); -- Samba Shared Repository