2 Unix SMB/Netbios implementation.
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.
28 static fstring host, workgroup, share, password, username, myname;
29 static int max_protocol = PROTOCOL_NT1;
30 static char *sockops="TCP_NODELAY";
31 static int nprocs=1, numops=100;
32 static struct cli_state current_cli;
34 static double create_procs(void (*fn)(int));
37 static struct timeval tp1,tp2;
39 static void start_timer(void)
41 gettimeofday(&tp1,NULL);
44 static double end_timer(void)
46 gettimeofday(&tp2,NULL);
47 return((tp2.tv_sec - tp1.tv_sec) +
48 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
52 /* return a pointer to a anonymous shared memory segment of size "size"
53 which will persist across fork() but will disappear when all processes
56 The memory is not zeroed
58 This function uses system5 shared memory. It takes advantage of a property
59 that the memory is not destroyed if it is attached when the id is removed
61 static void *shm_setup(int size)
66 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
68 printf("can't get shared memory\n");
71 ret = (void *)shmat(shmid, 0, 0);
72 if (!ret || ret == (void *)-1) {
73 printf("can't attach to shared memory\n");
76 /* the following releases the ipc, but note that this process
77 and all its children will still have access to the memory, its
78 just that the shmid is no longer valid for other shm calls. This
79 means we don't leave behind lots of shm segments after we exit
81 See Stevens "advanced programming in unix env" for details
83 shmctl(shmid, IPC_RMID, 0);
89 static BOOL open_connection(struct cli_state *c)
91 struct nmb_name called, calling;
93 extern struct in_addr ipzero;
97 make_nmb_name(&calling, myname, 0x0);
98 make_nmb_name(&called , host, 0x20);
102 if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
103 printf("Failed to connect with %s\n", host);
107 c->timeout = 120000; /* set a really long timeout (2 minutes) */
109 if (!cli_session_request(c, &calling, &called)) {
110 printf("%s rejected the session\n",host);
115 if (!cli_negprot(c)) {
116 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
121 if (!cli_session_setup(c, username,
122 password, strlen(password),
123 password, strlen(password),
125 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
130 if (!cli_send_tconX(c, share, "?????",
131 password, strlen(password)+1)) {
132 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
142 static void close_connection(struct cli_state *c)
145 printf("tdis failed (%s)\n", cli_errstr(c));
152 /* check if the server produced the expected error code */
153 static BOOL check_error(struct cli_state *c,
154 uint8 eclass, uint32 ecode, uint32 nterr)
158 (void)cli_error(c, &class, &num, NULL);
159 if ((eclass != class || ecode != num) &&
160 num != (nterr&0xFFFFFF)) {
161 printf("unexpected error code class=%d code=%d\n",
162 (int)class, (int)num);
163 printf(" expected %d/%d %d\n",
164 (int)eclass, (int)ecode, (int)nterr);
171 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
173 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
174 if (!check_error(c, ERRDOS, ERRlock, 0)) return False;
180 static BOOL rw_torture(struct cli_state *c)
182 char *lockfname = "\\torture.lck";
186 pid_t pid2, pid = getpid();
190 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
193 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
195 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
200 for (i=0;i<numops;i++) {
201 unsigned n = (unsigned)sys_random()%10;
203 printf("%d\r", i); fflush(stdout);
205 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
207 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
211 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
213 printf("open failed (%s)\n", cli_errstr(c));
217 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
218 printf("write failed (%s)\n", cli_errstr(c));
222 if (cli_write(c, fnum, 0, (char *)buf,
223 sizeof(pid)+(j*sizeof(buf)),
224 sizeof(buf)) != sizeof(buf)) {
225 printf("write failed (%s)\n", cli_errstr(c));
231 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
232 printf("read failed (%s)\n", cli_errstr(c));
236 printf("data corruption!\n");
239 if (!cli_close(c, fnum)) {
240 printf("close failed (%s)\n", cli_errstr(c));
243 if (!cli_unlink(c, fname)) {
244 printf("unlink failed (%s)\n", cli_errstr(c));
247 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
248 printf("unlock failed (%s)\n", cli_errstr(c));
253 cli_unlink(c, lockfname);
260 static void run_torture(int dummy)
262 struct cli_state cli;
266 cli_sockopt(&cli, sockops);
270 close_connection(&cli);
275 /* run a test that simulates an approximate netbench client load */
276 static void run_netbench(int client)
278 struct cli_state cli;
288 cli_sockopt(&cli, sockops);
292 slprintf(cname,sizeof(fname), "CLIENT%d", client);
294 f = fopen("client.txt", "r");
297 perror("client.txt");
301 while (fgets(line, sizeof(line)-1, f)) {
304 line[strlen(line)-1] = 0;
306 /* printf("[%d] %s\n", line_count, line); */
308 all_string_sub(line,"CLIENT1", cname, sizeof(line));
310 for (i=0;i<20;i++) params[i] = "";
312 /* parse the command parameters */
313 params[0] = strtok(line," ");
315 while (params[i]) params[++i] = strtok(NULL," ");
321 if (strcmp(params[1],"REQUEST") == 0) {
322 if (!strcmp(params[0],"SMBopenX")) {
323 fstrcpy(fname, params[5]);
324 } else if (!strcmp(params[0],"SMBclose")) {
325 nb_close(atoi(params[3]));
326 } else if (!strcmp(params[0],"SMBmkdir")) {
328 } else if (!strcmp(params[0],"CREATE")) {
329 nb_create(params[3], atoi(params[5]));
330 } else if (!strcmp(params[0],"SMBrmdir")) {
332 } else if (!strcmp(params[0],"SMBunlink")) {
333 fstrcpy(fname, params[3]);
334 } else if (!strcmp(params[0],"SMBmv")) {
335 nb_rename(params[3], params[5]);
336 } else if (!strcmp(params[0],"SMBgetatr")) {
337 fstrcpy(fname, params[3]);
338 } else if (!strcmp(params[0],"SMBwrite")) {
339 nb_write(atoi(params[3]),
340 atoi(params[5]), atoi(params[7]));
341 } else if (!strcmp(params[0],"SMBwritebraw")) {
342 nb_write(atoi(params[3]),
343 atoi(params[7]), atoi(params[5]));
344 } else if (!strcmp(params[0],"SMBreadbraw")) {
345 nb_read(atoi(params[3]),
346 atoi(params[7]), atoi(params[5]));
347 } else if (!strcmp(params[0],"SMBread")) {
348 nb_read(atoi(params[3]),
349 atoi(params[5]), atoi(params[7]));
352 if (!strcmp(params[0],"SMBopenX")) {
353 if (!strncmp(params[2], "ERR", 3)) continue;
354 nb_open(fname, atoi(params[3]), atoi(params[5]));
355 } else if (!strcmp(params[0],"SMBgetatr")) {
356 if (!strncmp(params[2], "ERR", 3)) continue;
357 nb_stat(fname, atoi(params[3]));
358 } else if (!strcmp(params[0],"SMBunlink")) {
359 if (!strncmp(params[2], "ERR", 3)) continue;
366 slprintf(fname,sizeof(fname), "CLIENTS/CLIENT%d", client);
372 close_connection(&cli);
376 /* run a test that simulates an approximate netbench w9X client load */
377 static void run_nbw95(int dummy)
380 t = create_procs(run_netbench);
381 /* to produce a netbench result we scale accoding to the
382 netbench measured throughput for the run that produced the
383 sniff that was used to produce client.txt. That run used 2
384 clients and ran for 660 seconds to produce a result of
386 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
387 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
390 /* run a test that simulates an approximate netbench wNT client load */
391 static void run_nbwnt(int dummy)
394 t = create_procs(run_netbench);
395 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
396 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
402 This test checks for two things:
404 1) correct support for retaining locks over a close (ie. the server
405 must not use posix semantics)
406 2) support for lock timeouts
408 static void run_locktest1(int dummy)
410 static struct cli_state cli1, cli2;
411 char *fname = "\\lockt1.lck";
412 int fnum1, fnum2, fnum3;
415 if (!open_connection(&cli1) || !open_connection(&cli2)) {
418 cli_sockopt(&cli1, sockops);
419 cli_sockopt(&cli2, sockops);
421 printf("starting locktest1\n");
423 cli_unlink(&cli1, fname);
425 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
427 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
430 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
432 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
435 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
437 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
441 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
442 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
447 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
448 printf("lock2 succeeded! This is a locking bug\n");
451 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
455 printf("Testing lock timeouts\n");
457 if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
458 printf("lock3 succeeded! This is a locking bug\n");
461 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
466 printf("error: This server appears not to support timed lock requests\n");
469 if (!cli_close(&cli1, fnum2)) {
470 printf("close1 failed (%s)\n", cli_errstr(&cli1));
474 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
475 printf("lock4 succeeded! This is a locking bug\n");
478 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
481 if (!cli_close(&cli1, fnum1)) {
482 printf("close2 failed (%s)\n", cli_errstr(&cli1));
486 if (!cli_close(&cli2, fnum3)) {
487 printf("close3 failed (%s)\n", cli_errstr(&cli2));
491 if (!cli_unlink(&cli1, fname)) {
492 printf("unlink failed (%s)\n", cli_errstr(&cli1));
497 close_connection(&cli1);
498 close_connection(&cli2);
500 printf("Passed locktest1\n");
504 checks for correct tconX support
506 static void run_tcon_test(int dummy)
508 static struct cli_state cli1;
509 char *fname = "\\tcontest.tmp";
514 if (!open_connection(&cli1)) {
517 cli_sockopt(&cli1, sockops);
519 printf("starting tcontest\n");
521 cli_unlink(&cli1, fname);
523 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
526 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
532 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
534 printf("write failed (%s)", cli_errstr(&cli1));
538 if (!cli_send_tconX(&cli1, share, "?????",
539 password, strlen(password)+1)) {
540 printf("%s refused 2nd tree connect (%s)\n", host,
546 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
548 printf("write succeeded (%s)", cli_errstr(&cli1));
552 if (cli_close(&cli1, fnum1)) {
553 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
557 if (!cli_tdis(&cli1)) {
558 printf("tdis failed (%s)\n", cli_errstr(&cli1));
564 if (!cli_close(&cli1, fnum1)) {
565 printf("close2 failed (%s)\n", cli_errstr(&cli1));
569 close_connection(&cli1);
571 printf("Passed tcontest\n");
576 This test checks that
578 1) the server supports multiple locking contexts on the one SMB
579 connection, distinguished by PID.
581 2) the server correctly fails overlapping locks made by the same PID (this
582 goes against POSIX behaviour, which is why it is tricky to implement)
584 3) the server denies unlock requests by an incorrect client PID
586 static void run_locktest2(int dummy)
588 static struct cli_state cli;
589 char *fname = "\\lockt2.lck";
590 int fnum1, fnum2, fnum3;
592 if (!open_connection(&cli)) {
596 cli_sockopt(&cli, sockops);
598 printf("starting locktest2\n");
600 cli_unlink(&cli, fname);
604 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
606 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
610 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
612 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
618 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
620 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
626 if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
627 printf("lock1 failed (%s)\n", cli_errstr(&cli));
631 if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
632 printf("WRITE lock1 succeeded! This is a locking bug\n");
634 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
637 if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
638 printf("WRITE lock2 succeeded! This is a locking bug\n");
640 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
643 if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
644 printf("READ lock2 succeeded! This is a locking bug\n");
646 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
651 if (cli_unlock(&cli, fnum1, 0, 8)) {
652 printf("unlock1 succeeded! This is a locking bug\n");
655 if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
656 printf("lock3 succeeded! This is a locking bug\n");
658 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
663 if (!cli_close(&cli, fnum1)) {
664 printf("close1 failed (%s)\n", cli_errstr(&cli));
668 if (!cli_close(&cli, fnum2)) {
669 printf("close2 failed (%s)\n", cli_errstr(&cli));
673 if (!cli_close(&cli, fnum3)) {
674 printf("close3 failed (%s)\n", cli_errstr(&cli));
678 close_connection(&cli);
680 printf("locktest2 finished\n");
685 This test checks that
687 1) the server supports the full offset range in lock requests
689 static void run_locktest3(int dummy)
691 static struct cli_state cli1, cli2;
692 char *fname = "\\lockt3.lck";
696 #define NEXT_OFFSET offset += (~(uint32)0) / numops
698 if (!open_connection(&cli1) || !open_connection(&cli2)) {
701 cli_sockopt(&cli1, sockops);
702 cli_sockopt(&cli2, sockops);
704 printf("starting locktest3\n");
706 cli_unlink(&cli1, fname);
708 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
710 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
713 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
715 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
719 for (offset=i=0;i<numops;i++) {
721 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
722 printf("lock1 %d failed (%s)\n",
728 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
729 printf("lock2 %d failed (%s)\n",
736 for (offset=i=0;i<numops;i++) {
739 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
740 printf("error: lock1 %d succeeded!\n", i);
744 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
745 printf("error: lock2 %d succeeded!\n", i);
749 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
750 printf("error: lock3 %d succeeded!\n", i);
754 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
755 printf("error: lock4 %d succeeded!\n", i);
760 for (offset=i=0;i<numops;i++) {
763 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
764 printf("unlock1 %d failed (%s)\n",
770 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
771 printf("unlock2 %d failed (%s)\n",
778 if (!cli_close(&cli1, fnum1)) {
779 printf("close1 failed (%s)\n", cli_errstr(&cli1));
782 if (!cli_close(&cli2, fnum2)) {
783 printf("close2 failed (%s)\n", cli_errstr(&cli2));
786 if (!cli_unlink(&cli1, fname)) {
787 printf("unlink failed (%s)\n", cli_errstr(&cli1));
791 close_connection(&cli1);
792 close_connection(&cli2);
794 printf("finished locktest3\n");
797 #define EXPECTED(ret, v) if ((ret) != (v)) printf("** ")
800 looks at overlapping locks
802 static void run_locktest4(int dummy)
804 static struct cli_state cli1, cli2;
805 char *fname = "\\lockt4.lck";
810 if (!open_connection(&cli1) || !open_connection(&cli2)) {
814 cli_sockopt(&cli1, sockops);
815 cli_sockopt(&cli2, sockops);
817 printf("starting locktest4\n");
819 cli_unlink(&cli1, fname);
821 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
822 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
824 memset(buf, 0, sizeof(buf));
826 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
827 printf("Failed to create file\n");
831 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
832 cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
833 EXPECTED(ret, False);
834 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
836 ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
837 cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
839 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
841 ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
842 cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
843 EXPECTED(ret, False);
844 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
846 ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
847 cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
849 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
851 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
852 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
853 EXPECTED(ret, False);
854 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
856 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
857 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
859 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
861 ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
862 cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
864 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
866 ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
867 cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
868 EXPECTED(ret, False);
869 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
871 ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
872 cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
873 EXPECTED(ret, False);
874 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
876 ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
877 cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
879 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
881 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
882 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
883 EXPECTED(ret, False);
884 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
886 ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
887 cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
888 cli_unlock(&cli1, fnum1, 110, 6);
889 EXPECTED(ret, False);
890 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
893 ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
894 (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
895 EXPECTED(ret, False);
896 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
898 ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
899 (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
900 EXPECTED(ret, False);
901 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
904 ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
905 cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
906 cli_unlock(&cli1, fnum1, 140, 4) &&
907 cli_unlock(&cli1, fnum1, 140, 4);
909 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
912 ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
913 cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
914 cli_unlock(&cli1, fnum1, 150, 4) &&
915 (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
916 !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
917 cli_unlock(&cli1, fnum1, 150, 4);
919 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
921 ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
922 cli_unlock(&cli1, fnum1, 160, 4) &&
923 (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
924 (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
926 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
928 ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
929 cli_unlock(&cli1, fnum1, 170, 4) &&
930 (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
931 (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
933 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
935 ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
936 cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
937 cli_unlock(&cli1, fnum1, 190, 4) &&
938 !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
939 (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
941 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
943 cli_close(&cli1, fnum1);
944 cli_close(&cli2, fnum2);
945 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
946 f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
947 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
948 cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
949 cli_close(&cli1, fnum1) &&
950 ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
951 cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
954 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
959 cli_close(&cli1, fnum1);
960 cli_close(&cli2, fnum2);
961 cli_unlink(&cli1, fname);
962 close_connection(&cli1);
963 close_connection(&cli2);
965 printf("finished locktest4\n");
969 looks at lock upgrade/downgrade.
971 static void run_locktest5(int dummy)
973 static struct cli_state cli1, cli2;
974 char *fname = "\\lockt5.lck";
975 int fnum1, fnum2, fnum3;
979 if (!open_connection(&cli1) || !open_connection(&cli2)) {
983 cli_sockopt(&cli1, sockops);
984 cli_sockopt(&cli2, sockops);
986 printf("starting locktest5\n");
988 cli_unlink(&cli1, fname);
990 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
991 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
992 fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
994 memset(buf, 0, sizeof(buf));
996 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
997 printf("Failed to create file\n");
1001 /* Check for NT bug... */
1002 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1003 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1004 cli_close(&cli1, fnum1);
1005 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1006 ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1007 EXPECTED(ret, True);
1008 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1009 cli_close(&cli1, fnum1);
1010 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1011 cli_unlock(&cli1, fnum3, 0, 1);
1013 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1014 cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1015 EXPECTED(ret, True);
1016 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1018 ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1019 EXPECTED(ret, False);
1021 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1023 /* Unlock the process 2 lock. */
1024 cli_unlock(&cli2, fnum2, 0, 4);
1026 ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1027 EXPECTED(ret, False);
1029 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1031 /* Unlock the process 1 fnum3 lock. */
1032 cli_unlock(&cli1, fnum3, 0, 4);
1034 /* Stack 2 more locks here. */
1035 ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1036 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1038 EXPECTED(ret, True);
1039 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1041 /* Unlock the first process lock, then check this was the WRITE lock that was
1044 ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1045 cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1047 EXPECTED(ret, True);
1048 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1050 /* Unlock the process 2 lock. */
1051 cli_unlock(&cli2, fnum2, 0, 4);
1053 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1055 ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1056 cli_unlock(&cli1, fnum1, 0, 4) &&
1057 cli_unlock(&cli1, fnum1, 0, 4);
1059 EXPECTED(ret, True);
1060 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1062 /* Ensure the next unlock fails. */
1063 ret = cli_unlock(&cli1, fnum1, 0, 4);
1064 EXPECTED(ret, False);
1065 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1067 /* Ensure connection 2 can get a write lock. */
1068 ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1069 EXPECTED(ret, True);
1071 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1074 cli_close(&cli1, fnum1);
1075 cli_close(&cli2, fnum2);
1076 cli_unlink(&cli1, fname);
1077 close_connection(&cli1);
1078 close_connection(&cli2);
1080 printf("finished locktest5\n");
1085 this produces a matrix of deny mode behaviour
1087 static void run_denytest1(int dummy)
1089 static struct cli_state cli1, cli2;
1091 int f, d1, d2, o1, o2, x=0;
1092 char *fnames[] = {"denytest1.exe", "denytest1.dat", NULL};
1097 {DENY_DOS, "DENY_DOS"},
1098 {DENY_ALL, "DENY_ALL"},
1099 {DENY_WRITE, "DENY_WRITE"},
1100 {DENY_READ, "DENY_READ"},
1101 {DENY_NONE, "DENY_NONE"},
1102 {DENY_FCB, "DENY_FCB"},
1109 {O_RDONLY, "O_RDONLY"},
1110 {O_WRONLY, "O_WRONLY"},
1113 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1116 cli_sockopt(&cli1, sockops);
1117 cli_sockopt(&cli2, sockops);
1119 printf("starting denytest1\n");
1121 for (f=0;fnames[f];f++) {
1122 cli_unlink(&cli1, fnames[f]);
1124 fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
1125 cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
1126 cli_close(&cli1, fnum1);
1128 for (d1=0;deny_modes[d1].name;d1++)
1129 for (o1=0;open_modes[o1].name;o1++)
1130 for (d2=0;deny_modes[d2].name;d2++)
1131 for (o2=0;open_modes[o2].name;o2++) {
1132 fnum1 = cli_open(&cli1, fnames[f],
1135 fnum2 = cli_open(&cli2, fnames[f],
1139 printf("%s %8s %10s %8s %10s ",
1141 open_modes[o1].name,
1142 deny_modes[d1].name,
1143 open_modes[o2].name,
1144 deny_modes[d2].name);
1148 } else if (fnum2 == -1) {
1151 if (cli_read(&cli2, fnum2, (void *)&x, 0, 1) == 1) {
1154 if (cli_write(&cli2, fnum2, 0, (void *)&x, 0, 1) == 1) {
1160 cli_close(&cli1, fnum1);
1161 cli_close(&cli2, fnum2);
1164 cli_unlink(&cli1, fnames[f]);
1167 close_connection(&cli1);
1168 close_connection(&cli2);
1170 printf("finshed denytest1\n");
1175 this produces a matrix of deny mode behaviour for two opens on the
1178 static void run_denytest2(int dummy)
1180 static struct cli_state cli1;
1182 int f, d1, d2, o1, o2, x=0;
1183 char *fnames[] = {"denytest2.exe", "denytest2.dat", NULL};
1188 {DENY_DOS, "DENY_DOS"},
1189 {DENY_ALL, "DENY_ALL"},
1190 {DENY_WRITE, "DENY_WRITE"},
1191 {DENY_READ, "DENY_READ"},
1192 {DENY_NONE, "DENY_NONE"},
1193 {DENY_FCB, "DENY_FCB"},
1200 {O_RDONLY, "O_RDONLY"},
1201 {O_WRONLY, "O_WRONLY"},
1204 if (!open_connection(&cli1)) {
1207 cli_sockopt(&cli1, sockops);
1209 printf("starting denytest2\n");
1211 for (f=0;fnames[f];f++) {
1212 cli_unlink(&cli1, fnames[f]);
1214 fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
1215 cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
1216 cli_close(&cli1, fnum1);
1218 for (d1=0;deny_modes[d1].name;d1++)
1219 for (o1=0;open_modes[o1].name;o1++)
1220 for (d2=0;deny_modes[d2].name;d2++)
1221 for (o2=0;open_modes[o2].name;o2++) {
1222 fnum1 = cli_open(&cli1, fnames[f],
1225 fnum2 = cli_open(&cli1, fnames[f],
1229 printf("%s %8s %10s %8s %10s ",
1231 open_modes[o1].name,
1232 deny_modes[d1].name,
1233 open_modes[o2].name,
1234 deny_modes[d2].name);
1238 } else if (fnum2 == -1) {
1241 if (cli_read(&cli1, fnum2, (void *)&x, 0, 1) == 1) {
1244 if (cli_write(&cli1, fnum2, 0, (void *)&x, 0, 1) == 1) {
1250 cli_close(&cli1, fnum1);
1251 cli_close(&cli1, fnum2);
1254 cli_unlink(&cli1, fnames[f]);
1257 close_connection(&cli1);
1259 printf("finshed denytest2\n");
1263 test whether fnums and tids open on one VC are available on another (a major
1266 static void run_fdpasstest(int dummy)
1268 static struct cli_state cli1, cli2;
1269 char *fname = "\\fdpass.tst";
1273 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1276 cli_sockopt(&cli1, sockops);
1277 cli_sockopt(&cli2, sockops);
1279 printf("starting fdpasstest\n");
1281 cli_unlink(&cli1, fname);
1283 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1285 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1289 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1290 printf("write failed (%s)\n", cli_errstr(&cli1));
1294 cli2.vuid = cli1.vuid;
1295 cli2.cnum = cli1.cnum;
1296 cli2.pid = cli1.pid;
1299 if (cli_read(&cli2, fnum1, buf, 0, 13) == 13) {
1300 printf("read succeeded! nasty security hole [%s]\n",
1305 cli_close(&cli1, fnum1);
1306 cli_unlink(&cli1, fname);
1308 close_connection(&cli1);
1309 close_connection(&cli2);
1311 printf("finished fdpasstest\n");
1316 This test checks that
1318 1) the server does not allow an unlink on a file that is open
1320 static void run_unlinktest(int dummy)
1322 static struct cli_state cli;
1323 char *fname = "\\unlink.tst";
1326 if (!open_connection(&cli)) {
1330 cli_sockopt(&cli, sockops);
1332 printf("starting unlink test\n");
1334 cli_unlink(&cli, fname);
1336 cli_setpid(&cli, 1);
1338 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1340 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1344 if (cli_unlink(&cli, fname)) {
1345 printf("error: server allowed unlink on an open file\n");
1348 cli_close(&cli, fnum);
1349 cli_unlink(&cli, fname);
1351 close_connection(&cli);
1353 printf("unlink test finished\n");
1358 test how many open files this server supports on the one socket
1360 static void run_maxfidtest(int dummy)
1362 static struct cli_state cli;
1363 char *template = "\\maxfid.%d.%d";
1372 printf("failed to connect\n");
1376 cli_sockopt(&cli, sockops);
1380 slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
1381 if (cli_open(&cli, fname,
1382 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE) ==
1384 printf("open of %s failed (%s)\n",
1385 fname, cli_errstr(&cli));
1386 printf("maximum fnum is %d\n", fnum);
1392 printf("cleaning up\n");
1395 slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
1396 if (cli_unlink(&cli, fname)) {
1397 printf("unlink of %s failed (%s)\n",
1398 fname, cli_errstr(&cli));
1402 printf("maxfid test finished\n");
1403 close_connection(&cli);
1406 /* generate a random buffer */
1407 static void rand_buf(char *buf, int len)
1410 *buf = (char)sys_random();
1415 /* send random IPC commands */
1416 static void run_randomipc(int dummy)
1418 char *rparam = NULL;
1422 int api, param_len, i;
1423 static struct cli_state cli;
1425 printf("starting random ipc test\n");
1427 if (!open_connection(&cli)) {
1431 for (i=0;i<50000;i++) {
1432 api = sys_random() % 500;
1433 param_len = (sys_random() % 64);
1435 rand_buf(param, param_len);
1440 param, param_len, 8,
1441 NULL, 0, BUFFER_SIZE,
1446 close_connection(&cli);
1448 printf("finished random ipc test\n");
1453 static void browse_callback(const char *sname, uint32 stype,
1454 const char *comment)
1456 printf("\t%20.20s %08x %s\n", sname, stype, comment);
1462 This test checks the browse list code
1465 static void run_browsetest(int dummy)
1467 static struct cli_state cli;
1469 printf("starting browse test\n");
1471 if (!open_connection(&cli)) {
1475 printf("domain list:\n");
1476 cli_NetServerEnum(&cli, cli.server_domain,
1477 SV_TYPE_DOMAIN_ENUM,
1480 printf("machine list:\n");
1481 cli_NetServerEnum(&cli, cli.server_domain,
1485 close_connection(&cli);
1487 printf("browse test finished\n");
1492 This checks how the getatr calls works
1494 static void run_attrtest(int dummy)
1496 static struct cli_state cli;
1499 char *fname = "\\attrib.tst";
1501 printf("starting attrib test\n");
1503 if (!open_connection(&cli)) {
1507 cli_unlink(&cli, fname);
1508 fnum = cli_open(&cli, fname,
1509 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1510 cli_close(&cli, fnum);
1511 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1512 printf("getatr failed (%s)\n", cli_errstr(&cli));
1515 if (abs(t - time(NULL)) > 2) {
1516 printf("ERROR: SMBgetatr bug. time is %s",
1521 t2 = t-60*60*24; /* 1 day ago */
1523 if (!cli_setatr(&cli, fname, 0, t2)) {
1524 printf("setatr failed (%s)\n", cli_errstr(&cli));
1527 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1528 printf("getatr failed (%s)\n", cli_errstr(&cli));
1532 printf("ERROR: getatr/setatr bug. times are\n%s",
1534 printf("%s", ctime(&t2));
1537 cli_unlink(&cli, fname);
1539 close_connection(&cli);
1541 printf("attrib test finished\n");
1546 This checks a couple of trans2 calls
1548 static void run_trans2test(int dummy)
1550 static struct cli_state cli;
1553 time_t c_time, a_time, m_time, w_time, m_time2;
1554 char *fname = "\\trans2.tst";
1555 char *dname = "\\trans2";
1556 char *fname2 = "\\trans2\\trans2.tst";
1558 printf("starting trans2 test\n");
1560 if (!open_connection(&cli)) {
1564 cli_unlink(&cli, fname);
1565 fnum = cli_open(&cli, fname,
1566 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1567 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
1569 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
1571 cli_close(&cli, fnum);
1575 cli_unlink(&cli, fname);
1576 fnum = cli_open(&cli, fname,
1577 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1578 cli_close(&cli, fnum);
1580 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
1581 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
1583 if (c_time != m_time) {
1584 printf("create time=%s", ctime(&c_time));
1585 printf("modify time=%s", ctime(&m_time));
1586 printf("This system appears to have sticky create times\n");
1588 if (a_time % (60*60) == 0) {
1589 printf("access time=%s", ctime(&a_time));
1590 printf("This system appears to set a midnight access time\n");
1593 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1594 printf("ERROR: totally incorrect times - maybe word reversed?\n");
1599 cli_unlink(&cli, fname);
1600 fnum = cli_open(&cli, fname,
1601 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1602 cli_close(&cli, fnum);
1603 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
1604 &w_time, &size, NULL, NULL)) {
1605 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1607 if (w_time < 60*60*24*2) {
1608 printf("write time=%s", ctime(&w_time));
1609 printf("This system appears to set a initial 0 write time\n");
1613 cli_unlink(&cli, fname);
1616 /* check if the server updates the directory modification time
1617 when creating a new file */
1618 if (!cli_mkdir(&cli, dname)) {
1619 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
1622 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
1623 &w_time, &size, NULL, NULL)) {
1624 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1627 fnum = cli_open(&cli, fname2,
1628 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1629 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
1630 cli_close(&cli, fnum);
1631 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
1632 &w_time, &size, NULL, NULL)) {
1633 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1635 if (m_time2 == m_time)
1636 printf("This system does not update directory modification times\n");
1638 cli_unlink(&cli, fname2);
1639 cli_rmdir(&cli, dname);
1642 close_connection(&cli);
1644 printf("trans2 test finished\n");
1649 this is a harness for some oplock tests
1651 static void run_oplock(int dummy)
1653 static struct cli_state cli1;
1654 char *fname = "\\lockt1.lck";
1657 printf("starting oplock test\n");
1659 if (!open_connection(&cli1)) {
1663 cli_unlink(&cli1, fname);
1665 cli_sockopt(&cli1, sockops);
1667 cli1.use_oplocks = True;
1669 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1671 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1675 cli1.use_oplocks = False;
1677 cli_unlink(&cli1, fname);
1678 cli_unlink(&cli1, fname);
1680 if (!cli_close(&cli1, fnum1)) {
1681 printf("close2 failed (%s)\n", cli_errstr(&cli1));
1685 if (!cli_unlink(&cli1, fname)) {
1686 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1691 close_connection(&cli1);
1693 printf("finished oplock test\n");
1697 static void list_fn(file_info *finfo, const char *name)
1703 test directory listing speed
1705 static void run_dirtest(int dummy)
1708 static struct cli_state cli;
1712 printf("starting directory test\n");
1714 if (!open_connection(&cli)) {
1718 cli_sockopt(&cli, sockops);
1721 for (i=0;i<numops;i++) {
1723 slprintf(fname, sizeof(fname), "%x", (int)random());
1724 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
1726 fprintf(stderr,"Failed to open %s\n", fname);
1729 cli_close(&cli, fnum);
1734 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn));
1735 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn));
1736 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn));
1738 printf("dirtest core %g seconds\n", end_timer() - t1);
1741 for (i=0;i<numops;i++) {
1743 slprintf(fname, sizeof(fname), "%x", (int)random());
1744 cli_unlink(&cli, fname);
1747 close_connection(&cli);
1749 printf("finished dirtest\n");
1754 static double create_procs(void (*fn)(int))
1757 volatile int *child_status;
1765 child_status = (volatile int *)shm_setup(sizeof(int)*nprocs);
1766 if (!child_status) {
1767 printf("Failed to setup shared memory\n");
1771 memset((char *)child_status, 0, sizeof(int)*nprocs);
1773 for (i=0;i<nprocs;i++) {
1775 pid_t mypid = getpid();
1776 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
1778 slprintf(myname,sizeof(myname),"CLIENT%d", i);
1781 memset(¤t_cli, 0, sizeof(current_cli));
1782 if (open_connection(¤t_cli)) break;
1784 printf("pid %d failed to start\n", (int)getpid());
1790 child_status[i] = getpid();
1792 while (child_status[i]) msleep(2);
1801 for (i=0;i<nprocs;i++) {
1802 if (child_status[i]) synccount++;
1804 if (synccount == nprocs) break;
1806 } while (end_timer() < 30);
1808 if (synccount != nprocs) {
1809 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
1813 /* start the client load */
1816 for (i=0;i<nprocs;i++) {
1817 child_status[i] = 0;
1820 printf("%d clients started\n", nprocs);
1822 for (i=0;i<nprocs;i++) {
1823 waitpid(0, &status, 0);
1831 #define FLAG_MULTIPROC 1
1838 {"FDPASS", run_fdpasstest, 0},
1839 {"LOCK1", run_locktest1, 0},
1840 {"LOCK2", run_locktest2, 0},
1841 {"LOCK3", run_locktest3, 0},
1842 {"LOCK4", run_locktest4, 0},
1843 {"LOCK5", run_locktest5, 0},
1844 {"UNLINK", run_unlinktest, 0},
1845 {"BROWSE", run_browsetest, 0},
1846 {"ATTR", run_attrtest, 0},
1847 {"TRANS2", run_trans2test, 0},
1848 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
1849 {"TORTURE",run_torture, FLAG_MULTIPROC},
1850 {"RANDOMIPC", run_randomipc, 0},
1851 {"NBW95", run_nbw95, 0},
1852 {"NBWNT", run_nbwnt, 0},
1853 {"OPLOCK", run_oplock, 0},
1854 {"DIR", run_dirtest, 0},
1855 {"DENY1", run_denytest1, 0},
1856 {"DENY2", run_denytest2, 0},
1857 {"TCON", run_tcon_test, 0},
1861 /****************************************************************************
1862 run a specified test or "ALL"
1863 ****************************************************************************/
1864 static void run_test(char *name)
1867 if (strequal(name,"ALL")) {
1868 for (i=0;torture_ops[i].name;i++) {
1869 run_test(torture_ops[i].name);
1873 for (i=0;torture_ops[i].name;i++) {
1874 if (strequal(name, torture_ops[i].name)) {
1876 printf("Running %s\n", name);
1877 if (torture_ops[i].flags & FLAG_MULTIPROC) {
1878 create_procs(torture_ops[i].fn);
1880 torture_ops[i].fn(0);
1882 printf("%s took %g secs\n\n", name, end_timer());
1888 static void usage(void)
1892 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
1894 printf("\t-U user%%pass\n");
1895 printf("\t-N numprocs\n");
1896 printf("\t-n my_netbios_name\n");
1897 printf("\t-W workgroup\n");
1898 printf("\t-o num_operations\n");
1899 printf("\t-O socket_options\n");
1900 printf("\t-m maximum protocol\n");
1903 printf("tests are:");
1904 for (i=0;torture_ops[i].name;i++) {
1905 printf(" %s", torture_ops[i].name);
1909 printf("default test is ALL\n");
1918 /****************************************************************************
1920 ****************************************************************************/
1921 int main(int argc,char *argv[])
1926 extern char *optarg;
1929 static pstring servicesf = CONFIGFILE;
1933 setbuffer(stdout, NULL, 0);
1935 charset_initialise();
1937 lp_load(servicesf,True,False,False);
1944 for(p = argv[1]; *p; p++)
1948 if (strncmp(argv[1], "//", 2)) {
1952 fstrcpy(host, &argv[1][2]);
1953 p = strchr(&host[2],'/');
1958 fstrcpy(share, p+1);
1962 if (*username == 0 && getenv("LOGNAME")) {
1963 pstrcpy(username,getenv("LOGNAME"));
1970 fstrcpy(workgroup, lp_workgroup());
1972 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:")) != EOF) {
1975 fstrcpy(workgroup,optarg);
1978 max_protocol = interpret_protocol(optarg, max_protocol);
1981 nprocs = atoi(optarg);
1984 numops = atoi(optarg);
1990 fstrcpy(myname, optarg);
1993 pstrcpy(username,optarg);
1994 p = strchr(username,'%');
1997 pstrcpy(password, p+1);
2002 printf("Unknown option %c (%d)\n", (char)opt, opt);
2009 p = getpass("Password:");
2011 pstrcpy(password, p);
2016 printf("host=%s share=%s user=%s myname=%s\n",
2017 host, share, username, myname);
2022 for (i=1;i<argc;i++) {