s4:selftest: correctly copy a python list into a temporary variable
[Samba.git] / source4 / torture / smbtorture.c
blobfc50436933f8d20bc6ebb7a2a100a489ba776e8a
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-2003
5 Copyright (C) Jelmer Vernooij 2006-2008
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "lib/cmdline/popt_common.h"
23 #include "system/time.h"
24 #include "system/wait.h"
25 #include "system/filesys.h"
26 #include "system/readline.h"
27 #include "../libcli/smbreadline/smbreadline.h"
28 #include "libcli/libcli.h"
29 #include "lib/events/events.h"
31 #include "torture/smbtorture.h"
32 #include "librpc/rpc/dcerpc.h"
33 #include "auth/gensec/gensec.h"
34 #include "param/param.h"
35 #include "lib/util/samba_modules.h"
37 #if HAVE_READLINE_HISTORY_H
38 #include <readline/history.h>
39 #endif
41 static char *prefix_name(TALLOC_CTX *mem_ctx, const char *prefix, const char *name)
43 if (prefix == NULL)
44 return talloc_strdup(mem_ctx, name);
45 else
46 return talloc_asprintf(mem_ctx, "%s.%s", prefix, name);
49 static void print_test_list(const struct torture_suite *suite, const char *prefix, const char *expr)
51 struct torture_suite *o;
52 struct torture_tcase *t;
53 struct torture_test *p;
55 for (o = suite->children; o; o = o->next) {
56 char *name = prefix_name(NULL, prefix, o->name);
57 print_test_list(o, name, expr);
58 talloc_free(name);
61 for (t = suite->testcases; t; t = t->next) {
62 for (p = t->tests; p; p = p->next) {
63 char *name = talloc_asprintf(NULL, "%s.%s.%s", prefix, t->name, p->name);
64 if (strncmp(name, expr, strlen(expr)) == 0) {
65 printf("%s\n", name);
67 talloc_free(name);
72 static bool run_matching(struct torture_context *torture,
73 const char *prefix,
74 const char *expr,
75 const char **restricted,
76 struct torture_suite *suite,
77 bool *matched)
79 bool ret = true;
80 struct torture_suite *o;
81 struct torture_tcase *t;
82 struct torture_test *p;
84 for (o = suite->children; o; o = o->next) {
85 char *name = NULL;
86 name = prefix_name(torture, prefix, o->name);
87 if (gen_fnmatch(expr, name) == 0) {
88 *matched = true;
89 reload_charcnv(torture->lp_ctx);
90 if (restricted != NULL)
91 ret &= torture_run_suite_restricted(torture, o, restricted);
92 else
93 ret &= torture_run_suite(torture, o);
95 ret &= run_matching(torture, name, expr, restricted, o, matched);
98 for (t = suite->testcases; t; t = t->next) {
99 char *name = talloc_asprintf(torture, "%s.%s", prefix, t->name);
100 if (gen_fnmatch(expr, name) == 0) {
101 *matched = true;
102 reload_charcnv(torture->lp_ctx);
103 ret &= torture_run_tcase_restricted(torture, t, restricted);
105 for (p = t->tests; p; p = p->next) {
106 name = talloc_asprintf(torture, "%s.%s.%s", prefix, t->name, p->name);
107 if (gen_fnmatch(expr, name) == 0) {
108 *matched = true;
109 reload_charcnv(torture->lp_ctx);
110 ret &= torture_run_test_restricted(torture, t, p, restricted);
115 return ret;
118 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
120 /****************************************************************************
121 run a specified test or "ALL"
122 ****************************************************************************/
123 bool torture_run_named_tests(struct torture_context *torture, const char *name,
124 const char **restricted)
126 bool ret = true;
127 bool matched = false;
128 struct torture_suite *o;
130 torture_ui_report_time(torture);
132 if (strequal(name, "ALL")) {
133 if (restricted != NULL) {
134 printf("--load-list and ALL are incompatible\n");
135 return false;
137 for (o = torture_root->children; o; o = o->next) {
138 ret &= torture_run_suite(torture, o);
140 return ret;
143 ret = run_matching(torture, NULL, name, restricted, torture_root, &matched);
145 if (!matched) {
146 printf("Unknown torture operation '%s'\n", name);
147 return false;
150 return ret;
153 bool torture_parse_target(struct loadparm_context *lp_ctx, const char *target)
155 char *host = NULL, *share = NULL;
156 struct dcerpc_binding *binding_struct;
157 NTSTATUS status;
159 /* see if its a RPC transport specifier */
160 if (!smbcli_parse_unc(target, NULL, &host, &share)) {
161 const char *h;
163 status = dcerpc_parse_binding(talloc_autofree_context(), target, &binding_struct);
164 if (NT_STATUS_IS_ERR(status)) {
165 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target);
166 return false;
169 h = dcerpc_binding_get_string_option(binding_struct, "host");
170 host = discard_const_p(char, h);
171 if (host != NULL) {
172 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
175 if (lpcfg_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
176 lpcfg_set_cmdline(lp_ctx, "torture:share", "IPC$");
177 lpcfg_set_cmdline(lp_ctx, "torture:binding", target);
178 } else {
179 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
180 lpcfg_set_cmdline(lp_ctx, "torture:share", share);
181 lpcfg_set_cmdline(lp_ctx, "torture:binding", host);
184 return true;
187 static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
189 char *userdn, *basedn, *secret;
190 char *p, *d;
192 /* retrievieng the userdn */
193 p = strchr_m(dns, '#');
194 if (!p) {
195 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", "");
196 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
197 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
198 return;
200 userdn = strndup(dns, p - dns);
201 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn);
203 /* retrieve the basedn */
204 d = p + 1;
205 p = strchr_m(d, '#');
206 if (!p) {
207 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
208 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
209 return;
211 basedn = strndup(d, p - d);
212 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn);
214 /* retrieve the secret */
215 p = p + 1;
216 if (!p) {
217 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
218 return;
220 secret = strdup(p);
221 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", secret);
223 printf ("%s - %s - %s\n", userdn, basedn, secret);
227 /* Print the full test list, formatted into separate labelled test
228 * groups.
230 static void print_structured_testsuite_list(void)
232 struct torture_suite *o;
233 struct torture_suite *s;
234 struct torture_tcase *t;
235 int i;
237 if (torture_root == NULL) {
238 printf("NO TESTS LOADED\n");
239 return;
242 for (o = torture_root->children; o; o = o->next) {
243 printf("\n%s (%s):\n ", o->description, o->name);
245 i = 0;
246 for (s = o->children; s; s = s->next) {
247 if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) {
248 printf("\n ");
249 i = 0;
251 i+=printf("%s.%s ", o->name, s->name);
254 for (t = o->testcases; t; t = t->next) {
255 if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) {
256 printf("\n ");
257 i = 0;
259 i+=printf("%s.%s ", o->name, t->name);
262 if (i) printf("\n");
265 printf("\nThe default test is ALL.\n");
268 static void print_testsuite_list(void)
270 struct torture_suite *o;
271 struct torture_suite *s;
272 struct torture_tcase *t;
274 if (torture_root == NULL)
275 return;
277 for (o = torture_root->children; o; o = o->next) {
278 for (s = o->children; s; s = s->next) {
279 printf("%s.%s\n", o->name, s->name);
282 for (t = o->testcases; t; t = t->next) {
283 printf("%s.%s\n", o->name, t->name);
288 void torture_print_testsuites(bool structured)
290 if (structured) {
291 print_structured_testsuite_list();
292 } else {
293 print_testsuite_list();
297 static void usage(poptContext pc)
299 poptPrintUsage(pc, stdout, 0);
300 printf("\n");
302 printf("The binding format is:\n\n");
304 printf(" TRANSPORT:host[flags]\n\n");
306 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
307 printf(" or ncalrpc for local connections.\n\n");
309 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
310 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
311 printf(" string.\n\n");
313 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
314 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
315 printf(" will be auto-determined.\n\n");
317 printf(" other recognised flags are:\n\n");
319 printf(" sign : enable ntlmssp signing\n");
320 printf(" seal : enable ntlmssp sealing\n");
321 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
322 printf(" validate: enable the NDR validator\n");
323 printf(" print: enable debugging of the packets\n");
324 printf(" bigendian: use bigendian RPC\n");
325 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
327 printf(" For example, these all connect to the samr pipe:\n\n");
329 printf(" ncacn_np:myserver\n");
330 printf(" ncacn_np:myserver[samr]\n");
331 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
332 printf(" ncacn_np:myserver[/pipe/samr]\n");
333 printf(" ncacn_np:myserver[samr,sign,print]\n");
334 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
335 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
336 printf(" ncacn_np:\n");
337 printf(" ncacn_np:[/pipe/samr]\n\n");
339 printf(" ncacn_ip_tcp:myserver\n");
340 printf(" ncacn_ip_tcp:myserver[1024]\n");
341 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
343 printf(" ncalrpc:\n\n");
345 printf("The UNC format is:\n\n");
347 printf(" //server/share\n\n");
349 printf("Tests are:");
351 print_structured_testsuite_list();
355 _NORETURN_ static void max_runtime_handler(int sig)
357 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
358 exit(1);
361 /****************************************************************************
362 main program
363 ****************************************************************************/
364 int main(int argc, const char *argv[])
366 int opt, i;
367 bool correct = true;
368 int max_runtime=0;
369 int argc_new;
370 struct torture_context *torture;
371 struct torture_results *results;
372 const struct torture_ui_ops *ui_ops;
373 char **argv_new;
374 poptContext pc;
375 static const char *target = "other";
376 NTSTATUS status;
377 int shell = false;
378 static const char *ui_ops_name = "subunit";
379 const char *basedir = NULL;
380 char *outputdir;
381 const char *extra_module = NULL;
382 static int list_tests = 0, list_testsuites = 0;
383 int num_extra_users = 0;
384 const char **restricted = NULL;
385 int num_restricted = -1;
386 const char *load_list = NULL;
387 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
388 OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,
389 OPT_EXTRA_USER,};
391 struct poptOption long_options[] = {
392 POPT_AUTOHELP
393 {"format", 0, POPT_ARG_STRING, &ui_ops_name, 0, "Output format (one of: simple, subunit)", NULL },
394 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
395 {"basedir", 0, POPT_ARG_STRING, &basedir, 0, "base directory", "BASEDIR" },
396 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "Seed to use for randomizer", NULL},
397 {"num-progs", 0, POPT_ARG_INT, NULL, OPT_NUMPROGS, "num progs", NULL},
398 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
399 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
400 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "NBench load file to use", NULL},
401 {"list-suites", 0, POPT_ARG_NONE, &list_testsuites, 0, "List available testsuites and exit", NULL },
402 {"list", 0, POPT_ARG_NONE, &list_tests, 0, "List available tests in specified suites and exit", NULL },
403 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
404 {"timelimit", 't', POPT_ARG_INT, NULL, OPT_TIMELIMIT, "Set time limit (in seconds)", NULL},
405 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
406 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
407 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS,
408 "run dangerous tests (eg. wiping out password database)", NULL},
409 {"load-module", 0, POPT_ARG_STRING, &extra_module, 0, "load tests from DSO file", "SOFILE"},
410 {"shell", 0, POPT_ARG_NONE, &shell, true, "Run shell", NULL},
411 {"target", 'T', POPT_ARG_STRING, &target, 0, "samba3|samba4|other", NULL},
412 {"async", 'a', POPT_ARG_NONE, NULL, OPT_ASYNC,
413 "run async tests", NULL},
414 {"num-async", 0, POPT_ARG_INT, &torture_numasync, 0,
415 "number of simultaneous async requests", NULL},
416 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
417 "set maximum time for smbtorture to live", "seconds"},
418 {"extra-user", 0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
419 "extra user credentials", NULL},
420 {"load-list", 0, POPT_ARG_STRING, &load_list, 0,
421 "load a test id list from a text file", NULL},
422 POPT_COMMON_SAMBA
423 POPT_COMMON_CONNECTION
424 POPT_COMMON_CREDENTIALS
425 POPT_COMMON_VERSION
426 { NULL }
429 setlinebuf(stdout);
431 printf("smbtorture %s\n", samba_version_string());
433 /* we are never interested in SIGPIPE */
434 BlockSignals(true, SIGPIPE);
436 pc = poptGetContext("smbtorture", argc, argv, long_options,
437 POPT_CONTEXT_KEEP_FIRST);
439 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
441 while((opt = poptGetNextOpt(pc)) != -1) {
442 switch (opt) {
443 case OPT_LOADFILE:
444 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:loadfile", poptGetOptArg(pc));
445 break;
446 case OPT_UNCLIST:
447 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:unclist", poptGetOptArg(pc));
448 break;
449 case OPT_TIMELIMIT:
450 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:timelimit", poptGetOptArg(pc));
451 break;
452 case OPT_NUMPROGS:
453 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:nprocs", poptGetOptArg(pc));
454 break;
455 case OPT_DNS:
456 parse_dns(cmdline_lp_ctx, poptGetOptArg(pc));
457 break;
458 case OPT_DANGEROUS:
459 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:dangerous", "Yes");
460 break;
461 case OPT_ASYNC:
462 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:async", "Yes");
463 break;
464 case OPT_SMB_PORTS:
465 lpcfg_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
466 break;
467 case OPT_EXTRA_USER:
469 char *option = talloc_asprintf(NULL, "torture:extra_user%u",
470 ++num_extra_users);
471 const char *value = poptGetOptArg(pc);
472 lpcfg_set_cmdline(cmdline_lp_ctx, option, value);
473 talloc_free(option);
475 break;
476 default:
477 if (opt < 0) {
478 printf("bad command line option %d\n", opt);
479 exit(1);
484 if (load_list != NULL) {
485 char **r;
486 r = file_lines_load(load_list, &num_restricted, 0, talloc_autofree_context());
487 restricted = discard_const_p(const char *, r);
488 if (restricted == NULL) {
489 printf("Unable to read load list file '%s'\n", load_list);
490 exit(1);
494 if (strcmp(target, "samba3") == 0) {
495 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba3", "true");
496 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
497 } else if (strcmp(target, "samba4") == 0) {
498 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
499 } else if (strcmp(target, "samba4-ntvfs") == 0) {
500 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
501 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4-ntvfs", "true");
502 } else if (strcmp(target, "winxp") == 0) {
503 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:winxp", "true");
504 } else if (strcmp(target, "w2k3") == 0) {
505 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k3", "true");
506 } else if (strcmp(target, "w2k8") == 0) {
507 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k8", "true");
508 lpcfg_set_cmdline(cmdline_lp_ctx,
509 "torture:invalid_lock_range_support", "false");
510 } else if (strcmp(target, "w2k12") == 0) {
511 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k12", "true");
512 } else if (strcmp(target, "win7") == 0) {
513 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:win7", "true");
514 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:cn_max_buffer_size",
515 "0x00010000");
516 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
517 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
519 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
520 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_support", "false");
522 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:hide_on_access_denied",
523 "true");
524 } else if (strcmp(target, "onefs") == 0) {
525 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:onefs", "true");
526 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:openx_deny_dos_support",
527 "false");
528 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:range_not_locked_on_file_close", "false");
529 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:sacl_support", "false");
530 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:ea_support", "false");
531 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smbexit_pdu_support",
532 "false");
533 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smblock_pdu_support",
534 "false");
535 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:2_step_break_to_none",
536 "true");
537 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_dos_support", "false");
538 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_fcb_support", "false");
539 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:read_support", "false");
540 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:writeclose_support", "false");
541 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
542 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
543 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:raw_search_search", "false");
544 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_size", "false");
547 if (max_runtime) {
548 /* this will only work if nobody else uses alarm(),
549 which means it won't work for some tests, but we
550 can't use the event context method we use for smbd
551 as so many tests create their own event
552 context. This will at least catch most cases. */
553 signal(SIGALRM, max_runtime_handler);
554 alarm(max_runtime);
557 if (extra_module != NULL) {
558 init_module_fn fn = load_module(poptGetOptArg(pc), false, NULL);
560 if (fn == NULL)
561 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
562 else {
563 status = fn();
564 if (NT_STATUS_IS_ERR(status)) {
565 d_printf("Error initializing module %s: %s\n",
566 poptGetOptArg(pc), nt_errstr(status));
569 } else {
570 torture_init();
573 if (list_testsuites) {
574 print_testsuite_list();
575 return 0;
578 argv_new = discard_const_p(char *, poptGetArgs(pc));
580 argc_new = argc;
581 for (i=0; i<argc; i++) {
582 if (argv_new[i] == NULL) {
583 argc_new = i;
584 break;
588 if (list_tests) {
589 if (argc_new == 1) {
590 print_test_list(torture_root, NULL, "");
591 } else {
592 for (i=1;i<argc_new;i++) {
593 print_test_list(torture_root, NULL, argv_new[i]);
596 return 0;
599 if (torture_seed == 0) {
600 torture_seed = time(NULL);
602 printf("Using seed %d\n", torture_seed);
603 srandom(torture_seed);
605 if (!strcmp(ui_ops_name, "simple")) {
606 ui_ops = &torture_simple_ui_ops;
607 } else if (!strcmp(ui_ops_name, "subunit")) {
608 ui_ops = &torture_subunit_ui_ops;
609 } else {
610 printf("Unknown output format '%s'\n", ui_ops_name);
611 exit(1);
614 results = torture_results_init(talloc_autofree_context(), ui_ops);
616 torture = torture_context_init(s4_event_context_init(talloc_autofree_context()),
617 results);
618 if (basedir != NULL) {
619 if (basedir[0] != '/') {
620 fprintf(stderr, "Please specify an absolute path to --basedir\n");
621 return 1;
623 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
624 } else {
625 char *pwd = talloc_size(torture, PATH_MAX);
626 if (!getcwd(pwd, PATH_MAX)) {
627 fprintf(stderr, "Unable to determine current working directory\n");
628 return 1;
630 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
632 if (!outputdir) {
633 fprintf(stderr, "Could not allocate per-run output dir\n");
634 return 1;
636 torture->outputdir = mkdtemp(outputdir);
637 if (!torture->outputdir) {
638 perror("Failed to make temp output dir");
641 torture->lp_ctx = cmdline_lp_ctx;
643 gensec_init();
645 if (shell) {
646 /* In shell mode, just ignore any remaining test names. */
647 torture_shell(torture);
648 } else {
650 /* At this point, we should just have a target string,
651 * followed by a series of test names. Unless we are in
652 * shell mode, in which case we don't need anythig more.
655 if (argc_new < 3) {
656 printf("You must specify a test to run, or 'ALL'\n");
657 usage(pc);
658 torture->results->returncode = 1;
659 } else if (!torture_parse_target(cmdline_lp_ctx, argv_new[1])) {
660 /* Take the target name or binding. */
661 usage(pc);
662 torture->results->returncode = 1;
663 } else {
664 for (i=2;i<argc_new;i++) {
665 if (!torture_run_named_tests(torture, argv_new[i],
666 (const char **)restricted)) {
667 correct = false;
673 /* Now delete the temp dir we created */
674 torture_deltree_outputdir(torture);
676 if (torture->results->returncode && correct) {
677 return(0);
678 } else {
679 return(1);