added maxfid test
[Samba/gbeck.git] / source / utils / torture.c
blobdd5cf04cc58c20ca5ec04b63ddad847da3456c79
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB torture tester
5 Copyright (C) Andrew Tridgell 1997-1998
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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #define NO_SYSLOG
24 #include "includes.h"
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static char *sockops="";
31 static struct timeval tp1,tp2;
33 static void start_timer(void)
35 gettimeofday(&tp1,NULL);
38 static double end_timer(void)
40 gettimeofday(&tp2,NULL);
41 return((tp2.tv_sec - tp1.tv_sec) +
42 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
46 static BOOL open_connection(struct cli_state *c)
48 struct nmb_name called, calling;
50 if (!cli_initialise(c) || !cli_connect(c, host, NULL)) {
51 printf("Failed to connect with %s\n", host);
52 return False;
55 make_nmb_name(&calling, myname, 0x0, "");
56 make_nmb_name(&called , host, 0x20, "");
58 if (!cli_session_request(c, &calling, &called)) {
59 printf("%s rejected the session\n",host);
60 cli_shutdown(c);
61 return False;
64 c->protocol = max_protocol;
66 if (!cli_negprot(c)) {
67 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
68 cli_shutdown(c);
69 return False;
72 if (!cli_session_setup(c, username, password, strlen(password),
73 "", 0, workgroup)) {
74 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
75 cli_shutdown(c);
76 return False;
79 if (!cli_send_tconX(c, share,
80 strstr(share,"IPC$")?"IPC":"A:",
81 password, strlen(password)+1)) {
82 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
83 cli_shutdown(c);
84 return False;
87 return True;
92 static void close_connection(struct cli_state *c)
94 if (!cli_tdis(c)) {
95 printf("tdis failed (%s)\n", cli_errstr(c));
98 cli_shutdown(c);
102 /* check if the server produced the expected error code */
103 static BOOL check_error(struct cli_state *c,
104 uint8 eclass, uint32 ecode, uint32 nterr)
106 uint8 class;
107 uint32 num;
108 int eno;
109 eno = cli_error(c, &class, &num);
110 if ((eclass != class || ecode != num) &&
111 num != (nterr&0xFFFFFF)) {
112 printf("unexpected error code class=%d code=%d\n",
113 (int)class, (int)num);
114 printf(" expected %d/%d %d\n",
115 (int)eclass, (int)ecode, (int)nterr);
116 return False;
118 return True;
122 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
124 while (!cli_lock(c, fnum, offset, len, -1)) {
125 if (!check_error(c, ERRDOS, ERRlock, 0)) return False;
127 return True;
131 static BOOL rw_torture(struct cli_state *c, int numops)
133 char *lockfname = "\\torture.lck";
134 fstring fname;
135 int fnum;
136 int fnum2;
137 int pid2, pid = getpid();
138 int i, j;
139 char buf[1024];
141 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
142 DENY_NONE);
143 if (fnum2 == -1)
144 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
145 if (fnum2 == -1) {
146 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
147 return False;
151 for (i=0;i<numops;i++) {
152 unsigned n = (unsigned)sys_random()%10;
153 if (i % 10 == 0) {
154 printf("%d\r", i); fflush(stdout);
156 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
158 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
159 return False;
162 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
163 if (fnum == -1) {
164 printf("open failed (%s)\n", cli_errstr(c));
165 break;
168 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
169 printf("write failed (%s)\n", cli_errstr(c));
172 for (j=0;j<50;j++) {
173 if (cli_write(c, fnum, 0, (char *)buf,
174 sizeof(pid)+(j*sizeof(buf)),
175 sizeof(buf)) != sizeof(buf)) {
176 printf("write failed (%s)\n", cli_errstr(c));
180 pid2 = 0;
182 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
183 printf("read failed (%s)\n", cli_errstr(c));
186 if (pid2 != pid) {
187 printf("data corruption!\n");
190 if (!cli_close(c, fnum)) {
191 printf("close failed (%s)\n", cli_errstr(c));
194 if (!cli_unlink(c, fname)) {
195 printf("unlink failed (%s)\n", cli_errstr(c));
198 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int), -1)) {
199 printf("unlock failed (%s)\n", cli_errstr(c));
203 cli_close(c, fnum2);
204 cli_unlink(c, lockfname);
206 printf("%d\n", i);
208 return True;
211 static void usage(void)
213 printf("Usage: smbtorture //server/share <options>\n");
215 printf("\t-U user%%pass\n");
216 printf("\t-N numprocs\n");
217 printf("\t-n my_netbios_name\n");
218 printf("\t-W workgroup\n");
219 printf("\t-o num_operations\n");
220 printf("\t-O socket_options\n");
221 printf("\t-m maximum protocol\n");
222 printf("\n");
224 exit(1);
229 static void run_torture(int numops)
231 static struct cli_state cli;
233 if (open_connection(&cli)) {
234 cli_sockopt(&cli, sockops);
236 printf("pid %d OK\n", getpid());
238 rw_torture(&cli, numops);
240 close_connection(&cli);
245 This test checks for two things:
247 1) correct support for retaining locks over a close (ie. the server
248 must not use posix semantics)
249 2) support for lock timeouts
251 static void run_locktest1(void)
253 static struct cli_state cli1, cli2;
254 char *fname = "\\lockt1.lck";
255 int fnum1, fnum2, fnum3;
256 time_t t1, t2;
258 if (!open_connection(&cli1) || !open_connection(&cli2)) {
259 return;
261 cli_sockopt(&cli1, sockops);
262 cli_sockopt(&cli2, sockops);
264 printf("starting locktest1\n");
266 cli_unlink(&cli1, fname);
268 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
269 if (fnum1 == -1) {
270 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
271 return;
273 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
274 if (fnum2 == -1) {
275 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
276 return;
278 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
279 if (fnum3 == -1) {
280 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
281 return;
284 if (!cli_lock(&cli1, fnum1, 0, 4, 0)) {
285 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
286 return;
290 if (cli_lock(&cli2, fnum3, 0, 4, 0)) {
291 printf("lock2 succeeded! This is a locking bug\n");
292 return;
293 } else {
294 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
298 printf("Testing lock timeouts\n");
299 t1 = time(NULL);
300 if (cli_lock(&cli2, fnum3, 0, 4, 10*1000)) {
301 printf("lock3 succeeded! This is a locking bug\n");
302 return;
303 } else {
304 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
306 t2 = time(NULL);
308 if (t2 - t1 < 5) {
309 printf("error: This server appears not to support timed lock requests\n");
312 if (!cli_close(&cli1, fnum2)) {
313 printf("close1 failed (%s)\n", cli_errstr(&cli1));
314 return;
317 if (cli_lock(&cli2, fnum3, 0, 4, 0)) {
318 printf("lock4 succeeded! This is a locking bug\n");
319 return;
320 } else {
321 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
324 if (!cli_close(&cli1, fnum1)) {
325 printf("close2 failed (%s)\n", cli_errstr(&cli1));
326 return;
329 if (!cli_close(&cli2, fnum3)) {
330 printf("close3 failed (%s)\n", cli_errstr(&cli2));
331 return;
334 if (!cli_unlink(&cli1, fname)) {
335 printf("unlink failed (%s)\n", cli_errstr(&cli1));
336 return;
340 close_connection(&cli1);
341 close_connection(&cli2);
343 printf("Passed locktest1\n");
348 This test checks that
350 1) the server supports multiple locking contexts on the one SMB
351 connection, distinguished by PID.
353 2) the server correctly fails overlapping locks made by the same PID (this
354 goes against POSIX behaviour, which is why it is tricky to implement)
356 3) the server denies unlock requests by an incorrect client PID
358 static void run_locktest2(void)
360 static struct cli_state cli;
361 char *fname = "\\lockt2.lck";
362 int fnum1, fnum2, fnum3;
364 if (!open_connection(&cli)) {
365 return;
368 cli_sockopt(&cli, sockops);
370 printf("starting locktest2\n");
372 cli_unlink(&cli, fname);
374 cli_setpid(&cli, 1);
376 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
377 if (fnum1 == -1) {
378 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
379 return;
382 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
383 if (fnum2 == -1) {
384 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
385 return;
388 cli_setpid(&cli, 2);
390 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
391 if (fnum3 == -1) {
392 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
393 return;
396 cli_setpid(&cli, 1);
398 if (!cli_lock(&cli, fnum1, 0, 4, 0)) {
399 printf("lock1 failed (%s)\n", cli_errstr(&cli));
400 return;
403 if (cli_lock(&cli, fnum2, 0, 4, 0)) {
404 printf("lock2 succeeded! This is a locking bug\n");
405 } else {
406 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
409 cli_setpid(&cli, 2);
411 if (cli_unlock(&cli, fnum1, 0, 4, 0)) {
412 printf("unlock1 succeeded! This is a locking bug\n");
415 if (cli_lock(&cli, fnum3, 0, 4, 0)) {
416 printf("lock3 succeeded! This is a locking bug\n");
417 } else {
418 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
421 cli_setpid(&cli, 1);
423 if (!cli_close(&cli, fnum1)) {
424 printf("close1 failed (%s)\n", cli_errstr(&cli));
425 return;
428 if (!cli_close(&cli, fnum2)) {
429 printf("close2 failed (%s)\n", cli_errstr(&cli));
430 return;
433 if (!cli_close(&cli, fnum3)) {
434 printf("close3 failed (%s)\n", cli_errstr(&cli));
435 return;
438 close_connection(&cli);
440 printf("locktest2 finished\n");
445 This test checks that
447 1) the server supports the full offset range in lock requests
449 static void run_locktest3(int numops)
451 static struct cli_state cli1, cli2;
452 char *fname = "\\lockt3.lck";
453 int fnum1, fnum2, i;
454 uint32 offset;
456 #define NEXT_OFFSET offset += (~(uint32)0) / numops
458 if (!open_connection(&cli1) || !open_connection(&cli2)) {
459 return;
461 cli_sockopt(&cli1, sockops);
462 cli_sockopt(&cli2, sockops);
464 printf("starting locktest3\n");
466 cli_unlink(&cli1, fname);
468 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
469 if (fnum1 == -1) {
470 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
471 return;
473 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
474 if (fnum2 == -1) {
475 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
476 return;
479 for (offset=i=0;i<numops;i++) {
480 NEXT_OFFSET;
481 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0)) {
482 printf("lock1 %d failed (%s)\n",
484 cli_errstr(&cli1));
485 return;
488 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0)) {
489 printf("lock2 %d failed (%s)\n",
491 cli_errstr(&cli1));
492 return;
496 for (offset=i=0;i<numops;i++) {
497 NEXT_OFFSET;
499 if (cli_lock(&cli1, fnum1, offset-2, 1, 0)) {
500 printf("error: lock1 %d succeeded!\n", i);
501 return;
504 if (cli_lock(&cli2, fnum2, offset-1, 1, 0)) {
505 printf("error: lock2 %d succeeded!\n", i);
506 return;
509 if (cli_lock(&cli1, fnum1, offset-1, 1, 0)) {
510 printf("error: lock3 %d succeeded!\n", i);
511 return;
514 if (cli_lock(&cli2, fnum2, offset-2, 1, 0)) {
515 printf("error: lock4 %d succeeded!\n", i);
516 return;
520 for (offset=i=0;i<numops;i++) {
521 NEXT_OFFSET;
523 if (!cli_unlock(&cli1, fnum1, offset-1, 1, 0)) {
524 printf("unlock1 %d failed (%s)\n",
526 cli_errstr(&cli1));
527 return;
530 if (!cli_unlock(&cli2, fnum2, offset-2, 1, 0)) {
531 printf("unlock2 %d failed (%s)\n",
533 cli_errstr(&cli1));
534 return;
538 if (!cli_close(&cli1, fnum1)) {
539 printf("close1 failed (%s)\n", cli_errstr(&cli1));
542 if (!cli_close(&cli2, fnum2)) {
543 printf("close2 failed (%s)\n", cli_errstr(&cli2));
546 if (!cli_unlink(&cli1, fname)) {
547 printf("unlink failed (%s)\n", cli_errstr(&cli1));
548 return;
551 close_connection(&cli1);
552 close_connection(&cli2);
554 printf("finished locktest3\n");
559 This test checks that
561 1) the server does not allow an unlink on a file that is open
563 static void run_unlinktest(void)
565 static struct cli_state cli;
566 char *fname = "\\unlink.tst";
567 int fnum;
569 if (!open_connection(&cli)) {
570 return;
573 cli_sockopt(&cli, sockops);
575 printf("starting unlink test\n");
577 cli_unlink(&cli, fname);
579 cli_setpid(&cli, 1);
581 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
582 if (fnum == -1) {
583 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
584 return;
587 if (cli_unlink(&cli, fname)) {
588 printf("error: server allowed unlink on an open file\n");
591 cli_close(&cli, fnum);
592 cli_unlink(&cli, fname);
594 close_connection(&cli);
596 printf("unlink test finished\n");
601 test how many open files this server supports on the one socket
603 static void run_maxfidtest(int n)
605 static struct cli_state cli;
606 char *template = "\\maxfid.%d.%d";
607 fstring fname;
608 int fnum;
609 int retries=4;
611 srandom(getpid());
613 while (!open_connection(&cli) && retries--) msleep(random() % 2000);
615 if (retries <= 0) {
616 printf("failed to connect\n");
617 return;
620 cli_sockopt(&cli, sockops);
622 printf("starting maxfid test\n");
624 fnum = 0;
625 while (1) {
626 slprintf(fname,sizeof(fname)-1,template, fnum,getpid());
627 if (cli_open(&cli, fname,
628 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE) ==
629 -1) {
630 printf("open of %s failed (%s)\n",
631 fname, cli_errstr(&cli));
632 printf("maximum fnum is %d\n", fnum);
633 break;
635 fnum++;
638 printf("cleaning up\n");
639 while (fnum > n) {
640 fnum--;
641 slprintf(fname,sizeof(fname)-1,template, fnum,getpid());
642 if (cli_unlink(&cli, fname)) {
643 printf("unlink of %s failed (%s)\n",
644 fname, cli_errstr(&cli));
648 printf("maxfid test finished\n");
649 close_connection(&cli);
652 /* generate a random buffer */
653 static void rand_buf(char *buf, int len)
655 while (len--) {
656 *buf = sys_random();
657 buf++;
661 /* send random IPC commands */
662 static void run_randomipc(void)
664 char *rparam = NULL;
665 char *rdata = NULL;
666 int rdrcnt,rprcnt;
667 pstring param;
668 int api, param_len, i;
669 static struct cli_state cli;
671 printf("starting random ipc test\n");
673 if (!open_connection(&cli)) {
674 return;
677 for (i=0;i<50000;i++) {
678 api = sys_random() % 500;
679 param_len = (sys_random() % 64);
681 rand_buf(param, param_len);
683 SSVAL(param,0,api);
685 cli_api(&cli,
686 param, param_len, 8,
687 NULL, 0, BUFFER_SIZE,
688 &rparam, &rprcnt,
689 &rdata, &rdrcnt);
692 close_connection(&cli);
694 printf("finished random ipc test\n");
699 static void browse_callback(const char *sname, uint32 stype,
700 const char *comment)
702 printf("\t%20.20s %08x %s\n", sname, stype, comment);
708 This test checks the browse list code
711 static void run_browsetest(void)
713 static struct cli_state cli;
715 printf("starting browse test\n");
717 if (!open_connection(&cli)) {
718 return;
721 printf("domain list:\n");
722 cli_NetServerEnum(&cli, workgroup,
723 SV_TYPE_DOMAIN_ENUM,
724 browse_callback);
726 printf("machine list:\n");
727 cli_NetServerEnum(&cli, workgroup,
728 SV_TYPE_ALL,
729 browse_callback);
731 close_connection(&cli);
733 printf("browse test finished\n");
738 This checks how the getatr calls works
740 static void run_attrtest(void)
742 static struct cli_state cli;
743 int fnum;
744 time_t t, t2;
745 char *fname = "\\attrib.tst";
747 printf("starting attrib test\n");
749 if (!open_connection(&cli)) {
750 return;
753 cli_unlink(&cli, fname);
754 fnum = cli_open(&cli, fname,
755 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
756 cli_close(&cli, fnum);
757 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
758 printf("getatr failed (%s)\n", cli_errstr(&cli));
761 if (abs(t - time(NULL)) > 2) {
762 printf("ERROR: SMBgetatr bug. time is %s",
763 ctime(&t));
764 t = time(NULL);
767 t2 = t-60*60*24; /* 1 day ago */
769 if (!cli_setatr(&cli, fname, 0, t2)) {
770 printf("setatr failed (%s)\n", cli_errstr(&cli));
773 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
774 printf("getatr failed (%s)\n", cli_errstr(&cli));
777 if (t != t2) {
778 printf("ERROR: getatr/setatr bug. times are\n%s",
779 ctime(&t));
780 printf("%s", ctime(&t2));
783 cli_unlink(&cli, fname);
785 close_connection(&cli);
787 printf("attrib test finished\n");
792 This checks a couple of trans2 calls
794 static void run_trans2test(void)
796 static struct cli_state cli;
797 int fnum;
798 size_t size;
799 time_t c_time, a_time, m_time, w_time, m_time2;
800 char *fname = "\\trans2.tst";
801 char *dname = "\\trans2";
802 char *fname2 = "\\trans2\\trans2.tst";
804 printf("starting trans2 test\n");
806 if (!open_connection(&cli)) {
807 return;
810 cli_unlink(&cli, fname);
811 fnum = cli_open(&cli, fname,
812 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
813 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time)) {
814 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
816 cli_close(&cli, fnum);
818 sleep(2);
820 cli_unlink(&cli, fname);
821 fnum = cli_open(&cli, fname,
822 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
823 cli_close(&cli, fnum);
825 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
826 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
827 } else {
828 if (c_time != m_time) {
829 printf("create time=%s", ctime(&c_time));
830 printf("modify time=%s", ctime(&m_time));
831 printf("This system appears to have sticky create times\n");
833 if (a_time % (60*60) == 0) {
834 printf("access time=%s", ctime(&a_time));
835 printf("This system appears to set a midnight access time\n");
838 if (abs(m_time - time(NULL)) > 60*60*24*7) {
839 printf("ERROR: totally incorrect times - maybe word reversed?\n");
844 cli_unlink(&cli, fname);
845 fnum = cli_open(&cli, fname,
846 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
847 cli_close(&cli, fnum);
848 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
849 &w_time, &size, NULL)) {
850 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
851 } else {
852 if (w_time < 60*60*24*2) {
853 printf("write time=%s", ctime(&w_time));
854 printf("This system appears to set a initial 0 write time\n");
858 cli_unlink(&cli, fname);
861 /* check if the server updates the directory modification time
862 when creating a new file */
863 if (!cli_mkdir(&cli, dname)) {
864 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
866 sleep(3);
867 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
868 &w_time, &size, NULL)) {
869 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
872 fnum = cli_open(&cli, fname2,
873 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
874 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
875 cli_close(&cli, fnum);
876 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
877 &w_time, &size, NULL)) {
878 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
879 } else {
880 if (m_time2 == m_time)
881 printf("This system does not update directory modification times\n");
883 cli_unlink(&cli, fname2);
884 cli_rmdir(&cli, dname);
887 close_connection(&cli);
889 printf("trans2 test finished\n");
893 static void create_procs(int nprocs, int numops, void (*fn)(int ))
895 int i, status;
897 for (i=0;i<nprocs;i++) {
898 if (fork() == 0) {
899 int mypid = getpid();
900 sys_srandom(mypid ^ time(NULL));
901 fn(numops);
902 _exit(0);
906 for (i=0;i<nprocs;i++)
907 waitpid(0, &status, 0);
912 /****************************************************************************
913 main program
914 ****************************************************************************/
915 int main(int argc,char *argv[])
917 int nprocs=1, numops=100;
918 int opt;
919 char *p;
920 int gotpass = 0;
921 extern char *optarg;
922 extern int optind;
923 extern FILE *dbf;
925 dbf = stdout;
927 charset_initialise();
929 if (argc < 2) {
930 usage();
933 for(p = argv[1]; *p; p++)
934 if(*p == '\\')
935 *p = '/';
937 if (strncmp(argv[1], "//", 2)) {
938 usage();
941 fstrcpy(host, &argv[1][2]);
942 p = strchr(&host[2],'/');
943 if (!p) {
944 usage();
946 *p = 0;
947 fstrcpy(share, p+1);
949 get_myname(myname,NULL);
951 if (*username == 0 && getenv("LOGNAME")) {
952 pstrcpy(username,getenv("LOGNAME"));
955 argc--;
956 argv++;
959 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:")) != EOF) {
960 switch (opt) {
961 case 'W':
962 fstrcpy(workgroup,optarg);
963 break;
964 case 'm':
965 max_protocol = interpret_protocol(optarg, max_protocol);
966 break;
967 case 'N':
968 nprocs = atoi(optarg);
969 break;
970 case 'o':
971 numops = atoi(optarg);
972 break;
973 case 'O':
974 sockops = optarg;
975 break;
976 case 'n':
977 fstrcpy(myname, optarg);
978 break;
979 case 'U':
980 pstrcpy(username,optarg);
981 p = strchr(username,'%');
982 if (p) {
983 *p = 0;
984 pstrcpy(password, p+1);
985 gotpass = 1;
987 break;
988 default:
989 printf("Unknown option %c (%d)\n", (char)opt, opt);
990 usage();
995 while (!gotpass) {
996 p = getpass("Password:");
997 if (p) {
998 pstrcpy(password, p);
999 gotpass = 1;
1003 printf("host=%s share=%s user=%s myname=%s\n",
1004 host, share, username, myname);
1006 run_locktest1();
1007 run_locktest2();
1008 run_locktest3(numops);
1009 run_unlinktest();
1010 run_browsetest();
1011 run_attrtest();
1012 run_trans2test();
1014 create_procs(nprocs, numops, run_maxfidtest);
1016 start_timer();
1017 create_procs(nprocs, numops, run_torture);
1018 printf("rw_torture: %g secs\n", end_timer());
1020 run_randomipc();
1022 return(0);