2 Unix SMB/CIFS implementation.
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/>.
22 #include "lib/util/util_file.h"
23 #include "lib/cmdline/cmdline.h"
24 #include "system/time.h"
25 #include "system/wait.h"
26 #include "system/filesys.h"
27 #include "system/readline.h"
28 #include "../libcli/smbreadline/smbreadline.h"
29 #include "libcli/libcli.h"
30 #include "lib/events/events.h"
32 #include "torture/smbtorture.h"
33 #include "librpc/rpc/dcerpc.h"
34 #include "auth/gensec/gensec.h"
35 #include "param/param.h"
36 #include "lib/util/samba_modules.h"
38 #ifdef HAVE_READLINE_HISTORY_H
39 #include <readline/history.h>
42 static int use_fullname
;
44 static char *prefix_name(TALLOC_CTX
*mem_ctx
, const char *prefix
, const char *name
)
47 return talloc_strdup(mem_ctx
, name
);
49 return talloc_asprintf(mem_ctx
, "%s.%s", prefix
, name
);
52 static void print_test_list(const struct torture_suite
*suite
, const char *prefix
, const char *expr
)
54 struct torture_suite
*o
;
55 struct torture_tcase
*t
;
56 struct torture_test
*p
;
58 for (o
= suite
->children
; o
; o
= o
->next
) {
59 char *name
= prefix_name(NULL
, prefix
, o
->name
);
60 print_test_list(o
, name
, expr
);
64 for (t
= suite
->testcases
; t
; t
= t
->next
) {
65 for (p
= t
->tests
; p
; p
= p
->next
) {
66 char *name
= talloc_asprintf(NULL
, "%s.%s.%s", prefix
, t
->name
, p
->name
);
67 if (strncmp(name
, expr
, strlen(expr
)) == 0) {
75 static bool run_matching(struct torture_context
*torture
,
78 const char **restricted
,
79 struct torture_suite
*suite
,
83 struct torture_suite
*o
;
84 struct torture_tcase
*t
;
85 struct torture_test
*p
;
87 for (o
= suite
->children
; o
; o
= o
->next
) {
89 name
= prefix_name(torture
, prefix
, o
->name
);
90 if (gen_fnmatch(expr
, name
) == 0) {
92 reload_charcnv(torture
->lp_ctx
);
93 if (use_fullname
== 1) {
94 torture_subunit_prefix_reset(torture
, prefix
);
96 ret
&= torture_run_suite_restricted(torture
, o
, restricted
);
97 if (use_fullname
== 1) {
98 torture_subunit_prefix_reset(torture
, NULL
);
101 * torture_run_suite_restricted() already implements
102 * recursion, so we're done with this child suite.
106 ret
&= run_matching(torture
, name
, expr
, restricted
, o
, matched
);
109 for (t
= suite
->testcases
; t
; t
= t
->next
) {
110 char *tname
= prefix_name(torture
, prefix
, t
->name
);
111 if (gen_fnmatch(expr
, tname
) == 0) {
113 reload_charcnv(torture
->lp_ctx
);
114 if (use_fullname
== 1) {
115 torture_subunit_prefix_reset(torture
, prefix
);
117 ret
&= torture_run_tcase_restricted(torture
, t
, restricted
);
118 if (use_fullname
== 1) {
119 torture_subunit_prefix_reset(torture
, NULL
);
122 * torture_run_tcase_restricted() already implements
123 * recursion, so we're done for this tcase.
127 for (p
= t
->tests
; p
; p
= p
->next
) {
128 char *pname
= prefix_name(torture
, tname
, p
->name
);
129 if (gen_fnmatch(expr
, pname
) == 0) {
131 reload_charcnv(torture
->lp_ctx
);
132 if (use_fullname
== 1) {
133 torture_subunit_prefix_reset(torture
,
136 ret
&= torture_run_test_restricted(torture
, t
, p
, restricted
);
137 if (use_fullname
== 1) {
138 torture_subunit_prefix_reset(torture
,
148 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
150 /****************************************************************************
151 run a specified test or "ALL"
152 ****************************************************************************/
153 bool torture_run_named_tests(struct torture_context
*torture
, const char *name
,
154 const char **restricted
)
157 bool matched
= false;
158 struct torture_suite
*o
;
160 torture_ui_report_time(torture
);
162 if (strequal(name
, "ALL")) {
163 if (restricted
!= NULL
) {
164 printf("--load-list and ALL are incompatible\n");
167 for (o
= torture_root
->children
; o
; o
= o
->next
) {
168 ret
&= torture_run_suite(torture
, o
);
173 ret
= run_matching(torture
, NULL
, name
, restricted
, torture_root
, &matched
);
176 printf("Unknown torture operation '%s'\n", name
);
183 bool torture_parse_target(TALLOC_CTX
*ctx
,
184 struct loadparm_context
*lp_ctx
,
187 char *host
= NULL
, *share
= NULL
;
188 struct dcerpc_binding
*binding_struct
;
191 /* see if its a RPC transport specifier */
192 if (!smbcli_parse_unc(target
, NULL
, &host
, &share
)) {
195 status
= dcerpc_parse_binding(ctx
, target
, &binding_struct
);
196 if (NT_STATUS_IS_ERR(status
)) {
197 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target
);
201 h
= dcerpc_binding_get_string_option(binding_struct
, "host");
202 host
= discard_const_p(char, h
);
204 lpcfg_set_cmdline(lp_ctx
, "torture:host", host
);
207 if (lpcfg_parm_string(lp_ctx
, NULL
, "torture", "share") == NULL
)
208 lpcfg_set_cmdline(lp_ctx
, "torture:share", "IPC$");
209 lpcfg_set_cmdline(lp_ctx
, "torture:binding", target
);
211 lpcfg_set_cmdline(lp_ctx
, "torture:host", host
);
212 lpcfg_set_cmdline(lp_ctx
, "torture:share", share
);
213 lpcfg_set_cmdline(lp_ctx
, "torture:binding", host
);
219 static void parse_dns(struct loadparm_context
*lp_ctx
, const char *dns
)
221 char *userdn
, *basedn
, *secret
;
224 /* retrieve the userdn */
225 p
= strchr_m(dns
, '#');
227 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_userdn", "");
228 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_basedn", "");
229 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", "");
232 userdn
= strndup(dns
, p
- dns
);
233 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_userdn", userdn
);
235 /* retrieve the basedn */
237 p
= strchr_m(d
, '#');
239 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_basedn", "");
240 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", "");
243 basedn
= strndup(d
, p
- d
);
244 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_basedn", basedn
);
246 /* retrieve the secret */
249 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", "");
253 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", secret
);
255 printf ("%s - %s - %s\n", userdn
, basedn
, secret
);
259 /* Print the full test list, formatted into separate labelled test
262 static void print_structured_testsuite_list(void)
264 struct torture_suite
*o
;
265 struct torture_suite
*s
;
266 struct torture_tcase
*t
;
269 if (torture_root
== NULL
) {
270 printf("NO TESTS LOADED\n");
274 for (o
= torture_root
->children
; o
; o
= o
->next
) {
275 printf("\n%s (%s):\n ", o
->description
, o
->name
);
278 for (s
= o
->children
; s
; s
= s
->next
) {
279 if (i
+ strlen(o
->name
) + strlen(s
->name
) >= (MAX_COLS
- 3)) {
283 i
+=printf("%s.%s ", o
->name
, s
->name
);
286 for (t
= o
->testcases
; t
; t
= t
->next
) {
287 if (i
+ strlen(o
->name
) + strlen(t
->name
) >= (MAX_COLS
- 3)) {
291 i
+=printf("%s.%s ", o
->name
, t
->name
);
297 printf("\nThe default test is ALL.\n");
300 static void print_testsuite_list(void)
302 struct torture_suite
*o
;
303 struct torture_suite
*s
;
304 struct torture_tcase
*t
;
306 if (torture_root
== NULL
)
309 for (o
= torture_root
->children
; o
; o
= o
->next
) {
310 for (s
= o
->children
; s
; s
= s
->next
) {
311 printf("%s.%s\n", o
->name
, s
->name
);
314 for (t
= o
->testcases
; t
; t
= t
->next
) {
315 printf("%s.%s\n", o
->name
, t
->name
);
320 void torture_print_testsuites(bool structured
)
323 print_structured_testsuite_list();
325 print_testsuite_list();
329 static void usage(poptContext pc
)
331 poptPrintUsage(pc
, stdout
, 0);
334 printf("The binding format is:\n\n");
336 printf(" TRANSPORT:host[flags]\n\n");
338 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
339 printf(" or ncalrpc for local connections.\n\n");
341 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
342 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
343 printf(" string.\n\n");
345 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
346 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
347 printf(" will be auto-determined.\n\n");
349 printf(" other recognised flags are:\n\n");
351 printf(" sign : enable ntlmssp signing\n");
352 printf(" seal : enable ntlmssp sealing\n");
353 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
354 printf(" validate: enable the NDR validator\n");
355 printf(" print: enable debugging of the packets\n");
356 printf(" bigendian: use bigendian RPC\n");
357 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
359 printf(" For example, these all connect to the samr pipe:\n\n");
361 printf(" ncacn_np:myserver\n");
362 printf(" ncacn_np:myserver[samr]\n");
363 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
364 printf(" ncacn_np:myserver[/pipe/samr]\n");
365 printf(" ncacn_np:myserver[samr,sign,print]\n");
366 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
367 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
368 printf(" ncacn_np:\n");
369 printf(" ncacn_np:[/pipe/samr]\n\n");
371 printf(" ncacn_ip_tcp:myserver\n");
372 printf(" ncacn_ip_tcp:myserver[1024]\n");
373 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
375 printf(" ncalrpc:\n\n");
377 printf("The UNC format is:\n\n");
379 printf(" //server/share\n\n");
381 printf("Tests are:");
383 print_structured_testsuite_list();
387 _NORETURN_
static void max_runtime_handler(int sig
)
389 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
393 /****************************************************************************
395 ****************************************************************************/
396 int main(int argc
, const char *argv
[])
402 struct torture_context
*torture
;
403 struct torture_results
*results
;
404 const struct torture_ui_ops
*ui_ops
;
407 static const char *target
= "other";
410 static const char *ui_ops_name
= "subunit";
411 const char *basedir
= NULL
;
413 const char *extra_module
= NULL
;
414 static int list_tests
= 0, list_testsuites
= 0;
415 int num_extra_users
= 0;
416 const char **restricted
= NULL
;
417 int num_restricted
= -1;
418 const char *load_list
= NULL
;
419 enum {OPT_LOADFILE
=1000,OPT_UNCLIST
,OPT_TIMELIMIT
,OPT_DNS
, OPT_LIST
,
420 OPT_DANGEROUS
,OPT_SMB_PORTS
,OPT_ASYNC
,OPT_NUMPROGS
,
422 TALLOC_CTX
*mem_ctx
= NULL
;
423 struct loadparm_context
*lp_ctx
= NULL
;
426 struct poptOption long_options
[] = {
428 {"fullname", 0, POPT_ARG_NONE
, &use_fullname
, 0,
429 "use full name for the test", NULL
},
430 {"format", 0, POPT_ARG_STRING
, &ui_ops_name
, 0, "Output format (one of: simple, subunit)", NULL
},
431 {"smb-ports", 'p', POPT_ARG_STRING
, NULL
, OPT_SMB_PORTS
, "SMB ports", NULL
},
432 {"basedir", 0, POPT_ARG_STRING
, &basedir
, 0, "base directory", "BASEDIR" },
433 {"seed", 0, POPT_ARG_INT
, &torture_seed
, 0, "Seed to use for randomizer", NULL
},
434 {"num-progs", 0, POPT_ARG_INT
, NULL
, OPT_NUMPROGS
, "num progs", NULL
},
435 {"num-ops", 0, POPT_ARG_INT
, &torture_numops
, 0, "num ops", NULL
},
436 {"entries", 0, POPT_ARG_INT
, &torture_entries
, 0, "entries", NULL
},
437 {"loadfile", 0, POPT_ARG_STRING
, NULL
, OPT_LOADFILE
, "NBench load file to use", NULL
},
438 {"list-suites", 0, POPT_ARG_NONE
, &list_testsuites
, 0, "List available testsuites and exit", NULL
},
439 {"list", 0, POPT_ARG_NONE
, &list_tests
, 0, "List available tests in specified suites and exit", NULL
},
440 {"unclist", 0, POPT_ARG_STRING
, NULL
, OPT_UNCLIST
, "unclist", NULL
},
441 {"timelimit", 't', POPT_ARG_INT
, NULL
, OPT_TIMELIMIT
, "Set time limit (in seconds)", NULL
},
442 {"failures", 'f', POPT_ARG_INT
, &torture_failures
, 0, "failures", NULL
},
443 {"parse-dns", 'D', POPT_ARG_STRING
, NULL
, OPT_DNS
, "parse-dns", NULL
},
444 {"dangerous", 'X', POPT_ARG_NONE
, NULL
, OPT_DANGEROUS
,
445 "run dangerous tests (eg. wiping out password database)", NULL
},
446 {"load-module", 0, POPT_ARG_STRING
, &extra_module
, 0, "load tests from DSO file", "SOFILE"},
447 {"shell", 0, POPT_ARG_NONE
, &shell
, true, "Run shell", NULL
},
448 {"target", 'T', POPT_ARG_STRING
, &target
, 0, "samba3|samba4|other", NULL
},
449 {"async", 'a', POPT_ARG_NONE
, NULL
, OPT_ASYNC
,
450 "run async tests", NULL
},
451 {"num-async", 0, POPT_ARG_INT
, &torture_numasync
, 0,
452 "number of simultaneous async requests", NULL
},
453 {"maximum-runtime", 0, POPT_ARG_INT
, &max_runtime
, 0,
454 "set maximum time for smbtorture to live", "seconds"},
455 {"extra-user", 0, POPT_ARG_STRING
, NULL
, OPT_EXTRA_USER
,
456 "extra user credentials", NULL
},
457 {"load-list", 0, POPT_ARG_STRING
, &load_list
, 0,
458 "load a test id list from a text file", NULL
},
460 POPT_COMMON_CONNECTION
461 POPT_COMMON_CREDENTIALS
469 mem_ctx
= talloc_named_const(NULL
, 0, "torture_ctx");
470 if (mem_ctx
== NULL
) {
471 printf("Unable to allocate torture_ctx\n");
475 printf("smbtorture %s\n", samba_version_string());
477 /* we are never interested in SIGPIPE */
478 BlockSignals(true, SIGPIPE
);
480 ok
= samba_cmdline_init(mem_ctx
,
481 SAMBA_CMDLINE_CONFIG_CLIENT
,
482 false /* require_smbconf */);
484 DBG_ERR("Unable to init cmdline parser\n");
485 TALLOC_FREE(mem_ctx
);
489 pc
= samba_popt_get_context(getprogname(),
493 POPT_CONTEXT_KEEP_FIRST
);
495 DBG_ERR("Failed cmdline parser\n");
496 TALLOC_FREE(mem_ctx
);
500 poptSetOtherOptionHelp(pc
, "<binding>|<unc> TEST1 TEST2 ...");
502 lp_ctx
= samba_cmdline_get_lp_ctx();
504 while((opt
= poptGetNextOpt(pc
)) != -1) {
507 lpcfg_set_cmdline(lp_ctx
, "torture:loadfile", poptGetOptArg(pc
));
510 lpcfg_set_cmdline(lp_ctx
, "torture:unclist", poptGetOptArg(pc
));
513 lpcfg_set_cmdline(lp_ctx
, "torture:timelimit", poptGetOptArg(pc
));
516 lpcfg_set_cmdline(lp_ctx
, "torture:nprocs", poptGetOptArg(pc
));
519 parse_dns(lp_ctx
, poptGetOptArg(pc
));
522 lpcfg_set_cmdline(lp_ctx
, "torture:dangerous", "Yes");
525 lpcfg_set_cmdline(lp_ctx
, "torture:async", "Yes");
528 lpcfg_set_cmdline(lp_ctx
, "smb ports", poptGetOptArg(pc
));
532 char *option
= talloc_asprintf(mem_ctx
,
533 "torture:extra_user%u",
535 const char *value
= poptGetOptArg(pc
);
536 if (option
== NULL
) {
537 printf("talloc fail\n");
538 talloc_free(mem_ctx
);
541 lpcfg_set_cmdline(lp_ctx
, option
, value
);
547 printf("Invalid command line option %s (%d)\n",
548 poptBadOption(pc
, 0),
550 talloc_free(mem_ctx
);
556 if (load_list
!= NULL
) {
558 r
= file_lines_load(load_list
, &num_restricted
, 0, mem_ctx
);
559 restricted
= discard_const_p(const char *, r
);
560 if (restricted
== NULL
) {
561 printf("Unable to read load list file '%s'\n", load_list
);
562 talloc_free(mem_ctx
);
567 if (strcmp(target
, "samba3") == 0) {
568 lpcfg_set_cmdline(lp_ctx
, "torture:samba3", "true");
569 lpcfg_set_cmdline(lp_ctx
, "torture:resume_key_support", "false");
570 } else if (strcmp(target
, "samba4") == 0) {
571 lpcfg_set_cmdline(lp_ctx
, "torture:samba4", "true");
572 } else if (strcmp(target
, "samba4-ntvfs") == 0) {
573 lpcfg_set_cmdline(lp_ctx
, "torture:samba4", "true");
574 lpcfg_set_cmdline(lp_ctx
, "torture:samba4-ntvfs", "true");
575 } else if (strcmp(target
, "winxp") == 0) {
576 lpcfg_set_cmdline(lp_ctx
, "torture:winxp", "true");
577 } else if (strcmp(target
, "w2k3") == 0) {
578 lpcfg_set_cmdline(lp_ctx
, "torture:w2k3", "true");
579 } else if (strcmp(target
, "w2k8") == 0) {
580 lpcfg_set_cmdline(lp_ctx
, "torture:w2k8", "true");
581 lpcfg_set_cmdline(lp_ctx
,
582 "torture:invalid_lock_range_support", "false");
583 } else if (strcmp(target
, "w2k12") == 0) {
584 lpcfg_set_cmdline(lp_ctx
, "torture:w2k12", "true");
585 } else if (strcmp(target
, "win7") == 0) {
586 lpcfg_set_cmdline(lp_ctx
, "torture:win7", "true");
587 lpcfg_set_cmdline(lp_ctx
, "torture:resume_key_support", "false");
588 lpcfg_set_cmdline(lp_ctx
, "torture:rewind_support", "false");
590 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
591 lpcfg_set_cmdline(lp_ctx
, "torture:search_ea_support", "false");
593 lpcfg_set_cmdline(lp_ctx
, "torture:hide_on_access_denied",
595 } else if (strcmp(target
, "onefs") == 0) {
596 lpcfg_set_cmdline(lp_ctx
, "torture:onefs", "true");
597 lpcfg_set_cmdline(lp_ctx
, "torture:openx_deny_dos_support",
599 lpcfg_set_cmdline(lp_ctx
, "torture:range_not_locked_on_file_close", "false");
600 lpcfg_set_cmdline(lp_ctx
, "torture:sacl_support", "false");
601 lpcfg_set_cmdline(lp_ctx
, "torture:ea_support", "false");
602 lpcfg_set_cmdline(lp_ctx
, "torture:smbexit_pdu_support",
604 lpcfg_set_cmdline(lp_ctx
, "torture:smblock_pdu_support",
606 lpcfg_set_cmdline(lp_ctx
, "torture:2_step_break_to_none",
608 lpcfg_set_cmdline(lp_ctx
, "torture:deny_dos_support", "false");
609 lpcfg_set_cmdline(lp_ctx
, "torture:deny_fcb_support", "false");
610 lpcfg_set_cmdline(lp_ctx
, "torture:read_support", "false");
611 lpcfg_set_cmdline(lp_ctx
, "torture:writeclose_support", "false");
612 lpcfg_set_cmdline(lp_ctx
, "torture:resume_key_support", "false");
613 lpcfg_set_cmdline(lp_ctx
, "torture:rewind_support", "false");
614 lpcfg_set_cmdline(lp_ctx
, "torture:raw_search_search", "false");
615 lpcfg_set_cmdline(lp_ctx
, "torture:search_ea_size", "false");
619 /* this will only work if nobody else uses alarm(),
620 which means it won't work for some tests, but we
621 can't use the event context method we use for smbd
622 as so many tests create their own event
623 context. This will at least catch most cases. */
624 signal(SIGALRM
, max_runtime_handler
);
628 if (extra_module
!= NULL
) {
629 init_module_fn fn
= load_module(poptGetOptArg(pc
), false, NULL
);
632 d_printf("Unable to load module from %s\n", poptGetOptArg(pc
));
634 status
= fn(mem_ctx
);
635 if (NT_STATUS_IS_ERR(status
)) {
636 d_printf("Error initializing module %s: %s\n",
637 poptGetOptArg(pc
), nt_errstr(status
));
641 torture_init(mem_ctx
);
644 if (list_testsuites
) {
645 print_testsuite_list();
647 talloc_free(mem_ctx
);
651 argv_new
= discard_const_p(char *, poptGetArgs(pc
));
654 for (i
=0; i
<argc
; i
++) {
655 if (argv_new
[i
] == NULL
) {
663 print_test_list(torture_root
, NULL
, "");
665 for (i
=1;i
<argc_new
;i
++) {
666 print_test_list(torture_root
, NULL
, argv_new
[i
]);
670 talloc_free(mem_ctx
);
674 if (torture_seed
== 0) {
675 torture_seed
= time(NULL
);
677 printf("Using seed %d\n", torture_seed
);
678 srandom(torture_seed
);
680 if (!strcmp(ui_ops_name
, "simple")) {
681 ui_ops
= &torture_simple_ui_ops
;
682 } else if (!strcmp(ui_ops_name
, "subunit")) {
683 ui_ops
= &torture_subunit_ui_ops
;
685 printf("Unknown output format '%s'\n", ui_ops_name
);
686 talloc_free(mem_ctx
);
690 results
= torture_results_init(mem_ctx
, ui_ops
);
692 torture
= torture_context_init(s4_event_context_init(mem_ctx
),
694 if (basedir
!= NULL
) {
695 if (basedir
[0] != '/') {
696 fprintf(stderr
, "Please specify an absolute path to --basedir\n");
698 talloc_free(mem_ctx
);
701 outputdir
= talloc_asprintf(torture
, "%s/smbtortureXXXXXX", basedir
);
703 char *pwd
= talloc_size(torture
, PATH_MAX
);
704 if (!getcwd(pwd
, PATH_MAX
)) {
705 fprintf(stderr
, "Unable to determine current working directory\n");
707 talloc_free(mem_ctx
);
710 outputdir
= talloc_asprintf(torture
, "%s/smbtortureXXXXXX", pwd
);
713 fprintf(stderr
, "Could not allocate per-run output dir\n");
715 talloc_free(mem_ctx
);
718 torture
->outputdir
= mkdtemp(outputdir
);
719 if (!torture
->outputdir
) {
720 perror("Failed to make temp output dir");
722 talloc_free(mem_ctx
);
726 torture
->lp_ctx
= lp_ctx
;
731 /* In shell mode, just ignore any remaining test names. */
732 torture_shell(torture
);
735 /* At this point, we should just have a target string,
736 * followed by a series of test names. Unless we are in
737 * shell mode, in which case we don't need anything more.
741 printf("You must specify a test to run, or 'ALL'\n");
743 torture
->results
->returncode
= 1;
744 } else if (!torture_parse_target(torture
,
745 lp_ctx
, argv_new
[1])) {
746 /* Take the target name or binding. */
748 torture
->results
->returncode
= 1;
750 for (i
=2;i
<argc_new
;i
++) {
751 if (!torture_run_named_tests(torture
, argv_new
[i
],
752 (const char **)restricted
)) {
759 /* Now delete the temp dir we created */
760 torture_deltree_outputdir(torture
);
762 if (torture
->results
->returncode
&& correct
) {
764 talloc_free(mem_ctx
);
768 talloc_free(mem_ctx
);