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
, ctx
, &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
);
222 static void parse_dns(struct loadparm_context
*lp_ctx
, const char *dns
)
224 char *userdn
, *basedn
, *secret
;
227 /* retrieve the userdn */
228 p
= strchr_m(dns
, '#');
230 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_userdn", "");
231 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_basedn", "");
232 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", "");
235 userdn
= strndup(dns
, p
- dns
);
236 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_userdn", userdn
);
238 /* retrieve the basedn */
240 p
= strchr_m(d
, '#');
242 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_basedn", "");
243 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", "");
246 basedn
= strndup(d
, p
- d
);
247 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_basedn", basedn
);
249 /* retrieve the secret */
252 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", "");
256 lpcfg_set_cmdline(lp_ctx
, "torture:ldap_secret", secret
);
258 printf ("%s - %s - %s\n", userdn
, basedn
, secret
);
262 /* Print the full test list, formatted into separate labelled test
265 static void print_structured_testsuite_list(void)
267 struct torture_suite
*o
;
268 struct torture_suite
*s
;
269 struct torture_tcase
*t
;
272 if (torture_root
== NULL
) {
273 printf("NO TESTS LOADED\n");
277 for (o
= torture_root
->children
; o
; o
= o
->next
) {
278 printf("\n%s (%s):\n ", o
->description
, o
->name
);
281 for (s
= o
->children
; s
; s
= s
->next
) {
282 if (i
+ strlen(o
->name
) + strlen(s
->name
) >= (MAX_COLS
- 3)) {
286 i
+=printf("%s.%s ", o
->name
, s
->name
);
289 for (t
= o
->testcases
; t
; t
= t
->next
) {
290 if (i
+ strlen(o
->name
) + strlen(t
->name
) >= (MAX_COLS
- 3)) {
294 i
+=printf("%s.%s ", o
->name
, t
->name
);
300 printf("\nThe default test is ALL.\n");
303 static void print_testsuite_list(void)
305 struct torture_suite
*o
;
306 struct torture_suite
*s
;
307 struct torture_tcase
*t
;
309 if (torture_root
== NULL
)
312 for (o
= torture_root
->children
; o
; o
= o
->next
) {
313 for (s
= o
->children
; s
; s
= s
->next
) {
314 printf("%s.%s\n", o
->name
, s
->name
);
317 for (t
= o
->testcases
; t
; t
= t
->next
) {
318 printf("%s.%s\n", o
->name
, t
->name
);
323 void torture_print_testsuites(bool structured
)
326 print_structured_testsuite_list();
328 print_testsuite_list();
332 static void usage(poptContext pc
)
334 poptPrintUsage(pc
, stdout
, 0);
337 printf("The binding format is:\n\n");
339 printf(" TRANSPORT:host[flags]\n\n");
341 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
342 printf(" or ncalrpc for local connections.\n\n");
344 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
345 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
346 printf(" string.\n\n");
348 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
349 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
350 printf(" will be auto-determined.\n\n");
352 printf(" other recognised flags are:\n\n");
354 printf(" sign : enable ntlmssp signing\n");
355 printf(" seal : enable ntlmssp sealing\n");
356 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
357 printf(" validate: enable the NDR validator\n");
358 printf(" print: enable debugging of the packets\n");
359 printf(" bigendian: use bigendian RPC\n");
360 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
362 printf(" For example, these all connect to the samr pipe:\n\n");
364 printf(" ncacn_np:myserver\n");
365 printf(" ncacn_np:myserver[samr]\n");
366 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
367 printf(" ncacn_np:myserver[/pipe/samr]\n");
368 printf(" ncacn_np:myserver[samr,sign,print]\n");
369 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
370 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
371 printf(" ncacn_np:\n");
372 printf(" ncacn_np:[/pipe/samr]\n\n");
374 printf(" ncacn_ip_tcp:myserver\n");
375 printf(" ncacn_ip_tcp:myserver[1024]\n");
376 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
378 printf(" ncalrpc:\n\n");
380 printf("The UNC format is:\n\n");
382 printf(" //server/share\n\n");
384 printf("Tests are:");
386 print_structured_testsuite_list();
390 _NORETURN_
static void max_runtime_handler(int sig
)
392 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
396 /****************************************************************************
398 ****************************************************************************/
399 int main(int argc
, const char *argv
[])
405 struct torture_context
*torture
;
406 struct torture_results
*results
;
407 const struct torture_ui_ops
*ui_ops
;
410 static const char *target
= "other";
413 static const char *ui_ops_name
= "subunit";
414 const char *basedir
= NULL
;
416 const char *extra_module
= NULL
;
417 static int list_tests
= 0, list_testsuites
= 0;
418 int num_extra_users
= 0;
419 const char **restricted
= NULL
;
420 int num_restricted
= -1;
421 const char *load_list
= NULL
;
422 enum {OPT_LOADFILE
=1000,OPT_UNCLIST
,OPT_TIMELIMIT
,OPT_DNS
, OPT_LIST
,
423 OPT_DANGEROUS
,OPT_SMB_PORTS
,OPT_ASYNC
,OPT_NUMPROGS
,
425 TALLOC_CTX
*mem_ctx
= NULL
;
426 struct loadparm_context
*lp_ctx
= NULL
;
429 struct poptOption long_options
[] = {
431 {"fullname", 0, POPT_ARG_NONE
, &use_fullname
, 0,
432 "use full name for the test", NULL
},
433 {"format", 0, POPT_ARG_STRING
, &ui_ops_name
, 0, "Output format (one of: simple, subunit)", NULL
},
434 {"smb-ports", 'p', POPT_ARG_STRING
, NULL
, OPT_SMB_PORTS
, "SMB ports", NULL
},
435 {"basedir", 0, POPT_ARG_STRING
, &basedir
, 0, "base directory", "BASEDIR" },
436 {"seed", 0, POPT_ARG_INT
, &torture_seed
, 0, "Seed to use for randomizer", NULL
},
437 {"num-progs", 0, POPT_ARG_INT
, NULL
, OPT_NUMPROGS
, "num progs", NULL
},
438 {"num-ops", 0, POPT_ARG_INT
, &torture_numops
, 0, "num ops", NULL
},
439 {"entries", 0, POPT_ARG_INT
, &torture_entries
, 0, "entries", NULL
},
440 {"loadfile", 0, POPT_ARG_STRING
, NULL
, OPT_LOADFILE
, "NBench load file to use", NULL
},
441 {"list-suites", 0, POPT_ARG_NONE
, &list_testsuites
, 0, "List available testsuites and exit", NULL
},
442 {"list", 0, POPT_ARG_NONE
, &list_tests
, 0, "List available tests in specified suites and exit", NULL
},
443 {"unclist", 0, POPT_ARG_STRING
, NULL
, OPT_UNCLIST
, "unclist", NULL
},
444 {"timelimit", 't', POPT_ARG_INT
, NULL
, OPT_TIMELIMIT
, "Set time limit (in seconds)", NULL
},
445 {"failures", 'f', POPT_ARG_INT
, &torture_failures
, 0, "failures", NULL
},
446 {"parse-dns", 'D', POPT_ARG_STRING
, NULL
, OPT_DNS
, "parse-dns", NULL
},
447 {"dangerous", 'X', POPT_ARG_NONE
, NULL
, OPT_DANGEROUS
,
448 "run dangerous tests (eg. wiping out password database)", NULL
},
449 {"load-module", 0, POPT_ARG_STRING
, &extra_module
, 0, "load tests from DSO file", "SOFILE"},
450 {"shell", 0, POPT_ARG_NONE
, &shell
, true, "Run shell", NULL
},
451 {"target", 'T', POPT_ARG_STRING
, &target
, 0, "samba3|samba4|other", NULL
},
452 {"async", 'a', POPT_ARG_NONE
, NULL
, OPT_ASYNC
,
453 "run async tests", NULL
},
454 {"num-async", 0, POPT_ARG_INT
, &torture_numasync
, 0,
455 "number of simultaneous async requests", NULL
},
456 {"maximum-runtime", 0, POPT_ARG_INT
, &max_runtime
, 0,
457 "set maximum time for smbtorture to live", "seconds"},
458 {"extra-user", 0, POPT_ARG_STRING
, NULL
, OPT_EXTRA_USER
,
459 "extra user credentials", NULL
},
460 {"load-list", 0, POPT_ARG_STRING
, &load_list
, 0,
461 "load a test id list from a text file", NULL
},
463 POPT_COMMON_CONNECTION
464 POPT_COMMON_CREDENTIALS
472 mem_ctx
= talloc_named_const(NULL
, 0, "torture_ctx");
473 if (mem_ctx
== NULL
) {
474 printf("Unable to allocate torture_ctx\n");
478 printf("smbtorture %s\n", samba_version_string());
480 /* we are never interested in SIGPIPE */
481 BlockSignals(true, SIGPIPE
);
483 ok
= samba_cmdline_init(mem_ctx
,
484 SAMBA_CMDLINE_CONFIG_CLIENT
,
485 false /* require_smbconf */);
487 DBG_ERR("Unable to init cmdline parser\n");
488 TALLOC_FREE(mem_ctx
);
492 pc
= samba_popt_get_context(getprogname(),
496 POPT_CONTEXT_KEEP_FIRST
);
498 DBG_ERR("Failed cmdline parser\n");
499 TALLOC_FREE(mem_ctx
);
503 poptSetOtherOptionHelp(pc
, "<binding>|<unc> TEST1 TEST2 ...");
505 lp_ctx
= samba_cmdline_get_lp_ctx();
507 while((opt
= poptGetNextOpt(pc
)) != -1) {
510 lpcfg_set_cmdline(lp_ctx
, "torture:loadfile", poptGetOptArg(pc
));
513 lpcfg_set_cmdline(lp_ctx
, "torture:unclist", poptGetOptArg(pc
));
516 lpcfg_set_cmdline(lp_ctx
, "torture:timelimit", poptGetOptArg(pc
));
519 lpcfg_set_cmdline(lp_ctx
, "torture:nprocs", poptGetOptArg(pc
));
522 parse_dns(lp_ctx
, poptGetOptArg(pc
));
525 lpcfg_set_cmdline(lp_ctx
, "torture:dangerous", "Yes");
528 lpcfg_set_cmdline(lp_ctx
, "torture:async", "Yes");
531 lpcfg_set_cmdline(lp_ctx
, "smb ports", poptGetOptArg(pc
));
535 char *option
= talloc_asprintf(mem_ctx
,
536 "torture:extra_user%u",
538 const char *value
= poptGetOptArg(pc
);
539 if (option
== NULL
) {
540 printf("talloc fail\n");
541 talloc_free(mem_ctx
);
544 lpcfg_set_cmdline(lp_ctx
, option
, value
);
550 printf("Invalid command line option %s (%d)\n",
551 poptBadOption(pc
, 0),
553 talloc_free(mem_ctx
);
559 if (load_list
!= NULL
) {
561 r
= file_lines_load(load_list
, &num_restricted
, 0, mem_ctx
);
562 restricted
= discard_const_p(const char *, r
);
563 if (restricted
== NULL
) {
564 printf("Unable to read load list file '%s'\n", load_list
);
565 talloc_free(mem_ctx
);
570 if (strcmp(target
, "samba3") == 0) {
571 lpcfg_set_cmdline(lp_ctx
, "torture:samba3", "true");
572 lpcfg_set_cmdline(lp_ctx
, "torture:resume_key_support", "false");
573 } else if (strcmp(target
, "samba4") == 0) {
574 lpcfg_set_cmdline(lp_ctx
, "torture:samba4", "true");
575 } else if (strcmp(target
, "samba4-ntvfs") == 0) {
576 lpcfg_set_cmdline(lp_ctx
, "torture:samba4", "true");
577 lpcfg_set_cmdline(lp_ctx
, "torture:samba4-ntvfs", "true");
578 } else if (strcmp(target
, "winxp") == 0) {
579 lpcfg_set_cmdline(lp_ctx
, "torture:winxp", "true");
580 } else if (strcmp(target
, "w2k3") == 0) {
581 lpcfg_set_cmdline(lp_ctx
, "torture:w2k3", "true");
582 } else if (strcmp(target
, "w2k8") == 0) {
583 lpcfg_set_cmdline(lp_ctx
, "torture:w2k8", "true");
584 lpcfg_set_cmdline(lp_ctx
,
585 "torture:invalid_lock_range_support", "false");
586 } else if (strcmp(target
, "w2k12") == 0) {
587 lpcfg_set_cmdline(lp_ctx
, "torture:w2k12", "true");
588 } else if (strcmp(target
, "win7") == 0) {
589 lpcfg_set_cmdline(lp_ctx
, "torture:win7", "true");
590 lpcfg_set_cmdline(lp_ctx
, "torture:resume_key_support", "false");
591 lpcfg_set_cmdline(lp_ctx
, "torture:rewind_support", "false");
593 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
594 lpcfg_set_cmdline(lp_ctx
, "torture:search_ea_support", "false");
596 lpcfg_set_cmdline(lp_ctx
, "torture:hide_on_access_denied",
598 } else if (strcmp(target
, "onefs") == 0) {
599 lpcfg_set_cmdline(lp_ctx
, "torture:onefs", "true");
600 lpcfg_set_cmdline(lp_ctx
, "torture:openx_deny_dos_support",
602 lpcfg_set_cmdline(lp_ctx
, "torture:range_not_locked_on_file_close", "false");
603 lpcfg_set_cmdline(lp_ctx
, "torture:sacl_support", "false");
604 lpcfg_set_cmdline(lp_ctx
, "torture:ea_support", "false");
605 lpcfg_set_cmdline(lp_ctx
, "torture:smbexit_pdu_support",
607 lpcfg_set_cmdline(lp_ctx
, "torture:smblock_pdu_support",
609 lpcfg_set_cmdline(lp_ctx
, "torture:2_step_break_to_none",
611 lpcfg_set_cmdline(lp_ctx
, "torture:deny_dos_support", "false");
612 lpcfg_set_cmdline(lp_ctx
, "torture:deny_fcb_support", "false");
613 lpcfg_set_cmdline(lp_ctx
, "torture:read_support", "false");
614 lpcfg_set_cmdline(lp_ctx
, "torture:writeclose_support", "false");
615 lpcfg_set_cmdline(lp_ctx
, "torture:resume_key_support", "false");
616 lpcfg_set_cmdline(lp_ctx
, "torture:rewind_support", "false");
617 lpcfg_set_cmdline(lp_ctx
, "torture:raw_search_search", "false");
618 lpcfg_set_cmdline(lp_ctx
, "torture:search_ea_size", "false");
622 /* this will only work if nobody else uses alarm(),
623 which means it won't work for some tests, but we
624 can't use the event context method we use for smbd
625 as so many tests create their own event
626 context. This will at least catch most cases. */
627 signal(SIGALRM
, max_runtime_handler
);
631 if (extra_module
!= NULL
) {
632 init_module_fn fn
= load_module(poptGetOptArg(pc
), false, NULL
);
635 d_printf("Unable to load module from %s\n", poptGetOptArg(pc
));
637 status
= fn(mem_ctx
);
638 if (NT_STATUS_IS_ERR(status
)) {
639 d_printf("Error initializing module %s: %s\n",
640 poptGetOptArg(pc
), nt_errstr(status
));
644 torture_init(mem_ctx
);
647 if (list_testsuites
) {
648 print_testsuite_list();
650 talloc_free(mem_ctx
);
654 argv_new
= discard_const_p(char *, poptGetArgs(pc
));
657 for (i
=0; i
<argc
; i
++) {
658 if (argv_new
[i
] == NULL
) {
666 print_test_list(torture_root
, NULL
, "");
668 for (i
=1;i
<argc_new
;i
++) {
669 print_test_list(torture_root
, NULL
, argv_new
[i
]);
673 talloc_free(mem_ctx
);
677 if (torture_seed
== 0) {
678 torture_seed
= time(NULL
);
680 printf("Using seed %d\n", torture_seed
);
681 srandom(torture_seed
);
683 if (!strcmp(ui_ops_name
, "simple")) {
684 ui_ops
= &torture_simple_ui_ops
;
685 } else if (!strcmp(ui_ops_name
, "subunit")) {
686 ui_ops
= &torture_subunit_ui_ops
;
688 printf("Unknown output format '%s'\n", ui_ops_name
);
689 talloc_free(mem_ctx
);
693 results
= torture_results_init(mem_ctx
, ui_ops
);
695 torture
= torture_context_init(s4_event_context_init(mem_ctx
),
697 if (basedir
!= NULL
) {
698 if (basedir
[0] != '/') {
699 fprintf(stderr
, "Please specify an absolute path to --basedir\n");
701 talloc_free(mem_ctx
);
704 outputdir
= talloc_asprintf(torture
, "%s/smbtortureXXXXXX", basedir
);
706 char *pwd
= talloc_size(torture
, PATH_MAX
);
707 if (!getcwd(pwd
, PATH_MAX
)) {
708 fprintf(stderr
, "Unable to determine current working directory\n");
710 talloc_free(mem_ctx
);
713 outputdir
= talloc_asprintf(torture
, "%s/smbtortureXXXXXX", pwd
);
716 fprintf(stderr
, "Could not allocate per-run output dir\n");
718 talloc_free(mem_ctx
);
721 torture
->outputdir
= mkdtemp(outputdir
);
722 if (!torture
->outputdir
) {
723 perror("Failed to make temp output dir");
725 talloc_free(mem_ctx
);
729 torture
->lp_ctx
= lp_ctx
;
734 /* In shell mode, just ignore any remaining test names. */
735 torture_shell(torture
);
738 /* At this point, we should just have a target string,
739 * followed by a series of test names. Unless we are in
740 * shell mode, in which case we don't need anything more.
744 printf("You must specify a test to run, or 'ALL'\n");
746 torture
->results
->returncode
= 1;
747 } else if (!torture_parse_target(torture
,
748 lp_ctx
, argv_new
[1])) {
749 /* Take the target name or binding. */
751 torture
->results
->returncode
= 1;
753 for (i
=2;i
<argc_new
;i
++) {
754 if (!torture_run_named_tests(torture
, argv_new
[i
],
755 (const char **)restricted
)) {
762 /* Now delete the temp dir we created */
763 torture_deltree_outputdir(torture
);
765 if (torture
->results
->returncode
&& correct
) {
767 talloc_free(mem_ctx
);
771 talloc_free(mem_ctx
);