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.
26 extern int DEBUGLEVEL;
27 extern pstring debugf;
29 static fstring host, workgroup, share, password, username, myname;
30 static int max_protocol = PROTOCOL_NT1;
31 static char *sockops="";
34 static struct timeval tp1,tp2;
36 static void start_timer(void)
38 gettimeofday(&tp1,NULL);
41 static double end_timer(void)
43 gettimeofday(&tp2,NULL);
44 return((tp2.tv_sec - tp1.tv_sec) +
45 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
48 #define FAILED_NO_ERROR 0
49 #define FAILED_TCP_CONNECT 1
50 #define FAILED_SESSION_REQ 2
51 #define FAILED_SMB_SESS_SETUP 3
52 #define FAILED_SMB_TCON 4
53 #define FAILED_SMB_NEGPROT 5
54 #define FAILED_CLI_STATE_INIT 6
55 #define NUM_ERR_STATES 7
57 static char *smb_messages[] =
59 "No errors in connection",
61 "NetBIOS Session Request",
65 "Client initialisation "
68 static int open_connection(struct cli_state *c)
70 struct nmb_name called, calling;
74 make_nmb_name(&calling, myname, 0x0, "");
75 make_nmb_name(&called , host, 0x20, "");
77 if (!cli_initialise(c))
79 DEBUG(0,("Failed to connect with %s\n", host));
80 return FAILED_CLI_STATE_INIT;
83 if (!cli_connect(c, host, NULL)) {
84 DEBUG(0,("Failed to connect with %s\n", host));
85 return FAILED_TCP_CONNECT;
88 if (!cli_session_request(c, &calling, &called)) {
90 DEBUG(0,("%s rejected the session\n",host));
91 return FAILED_SESSION_REQ;
94 if (!cli_negprot(c)) {
95 DEBUG(0,("%s rejected the negprot (%s)\n",host, cli_errstr(c)));
97 return FAILED_SMB_NEGPROT;
100 if (!cli_session_setup(c, username,
101 password, strlen(password),
102 password, strlen(password),
104 DEBUG(0,("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c)));
106 return FAILED_SMB_SESS_SETUP;
109 if (!cli_send_tconX(c, share, "?????",
110 password, strlen(password)+1)) {
111 DEBUG(0,("%s refused tree connect (%s)\n", host, cli_errstr(c)));
113 return FAILED_SMB_TCON;
116 return FAILED_NO_ERROR;
120 static void close_connection(struct cli_state *c)
123 DEBUG(0,("tdis failed (%s)\n", cli_errstr(c)));
130 /* check if the server produced the expected error code */
131 static BOOL check_error(struct cli_state *c,
132 uint8 eclass, uint32 ecode, uint32 nterr)
137 eno = cli_error(c, &class, &num);
138 if ((eclass != class || ecode != num) &&
139 num != (nterr&0xFFFFFF)) {
140 DEBUG(0,("unexpected error code class=%d code=%d\n",
141 (int)class, (int)num));
142 DEBUG(0,(" expected %d/%d %d\n",
143 (int)eclass, (int)ecode, (int)nterr));
150 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
152 while (!cli_lock(c, fnum, offset, len, -1)) {
153 if (!check_error(c, ERRDOS, ERRlock, 0)) return False;
159 static BOOL rw_torture(struct cli_state *c, int numops)
161 char *lockfname = "\\torture.lck";
165 int pid2, pid = getpid();
169 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
172 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
174 DEBUG(0,("open of %s failed (%s)\n", lockfname, cli_errstr(c)));
179 for (i=0;i<numops;i++) {
180 unsigned n = (unsigned)sys_random()%10;
182 DEBUG(0,("%d\r", i));
184 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
186 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
190 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
192 DEBUG(0,("open failed (%s)\n", cli_errstr(c)));
196 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
197 DEBUG(0,("write failed (%s)\n", cli_errstr(c)));
201 if (cli_write(c, fnum, 0, (char *)buf,
202 sizeof(pid)+(j*sizeof(buf)),
203 sizeof(buf)) != sizeof(buf)) {
204 DEBUG(0,("write failed (%s)\n", cli_errstr(c)));
210 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
211 DEBUG(0,("read failed (%s)\n", cli_errstr(c)));
215 DEBUG(0,("data corruption!\n"));
218 if (!cli_close(c, fnum)) {
219 DEBUG(0,("close failed (%s)\n", cli_errstr(c)));
222 if (!cli_unlink(c, fname)) {
223 DEBUG(0,("unlink failed (%s)\n", cli_errstr(c)));
226 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int), -1)) {
227 DEBUG(0,("unlock failed (%s)\n", cli_errstr(c)));
232 cli_unlink(c, lockfname);
234 DEBUG(0,("%d\n", i));
239 static void usage(void)
241 printf("Usage: smbtorture //server/share <options>\n");
243 printf("\t-U user%%pass\n");
244 printf("\t-N numprocs\n");
245 printf("\t-n my_netbios_name\n");
246 printf("\t-W workgroup\n");
247 printf("\t-o num_operations\n");
248 printf("\t-O socket_options\n");
249 printf("\t-m maximum protocol\n");
257 static void run_torture(int numops)
259 static struct cli_state cli;
261 if (open_connection(&cli) == 0)
263 cli_sockopt(&cli, sockops);
265 DEBUG(0,("pid %d OK\n", getpid()));
267 rw_torture(&cli, numops);
269 close_connection(&cli);
273 DEBUG(0,("pid %d failed\n", getpid()));
279 This test checks for two things:
281 1) correct support for retaining locks over a close (ie. the server
282 must not use posix semantics)
283 2) support for lock timeouts
285 static void run_locktest1(void)
287 static struct cli_state cli1, cli2;
288 char *fname = "\\lockt1.lck";
289 int fnum1, fnum2, fnum3;
292 if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
295 cli_sockopt(&cli1, sockops);
296 cli_sockopt(&cli2, sockops);
298 DEBUG(0,("starting locktest1\n"));
300 cli_unlink(&cli1, fname);
302 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
304 DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
307 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
309 DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1)));
312 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
314 DEBUG(0,("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2)));
318 if (!cli_lock(&cli1, fnum1, 0, 4, 0)) {
319 DEBUG(0,("lock1 failed (%s)\n", cli_errstr(&cli1)));
324 if (cli_lock(&cli2, fnum3, 0, 4, 0)) {
325 DEBUG(0,("lock2 succeeded! This is a locking bug\n"));
328 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
332 DEBUG(0,("Testing lock timeouts\n"));
334 if (cli_lock(&cli2, fnum3, 0, 4, 10*1000)) {
335 DEBUG(0,("lock3 succeeded! This is a locking bug\n"));
338 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
343 DEBUG(0,("error: This server appears not to support timed lock requests\n"));
346 if (!cli_close(&cli1, fnum2)) {
347 DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli1)));
351 if (cli_lock(&cli2, fnum3, 0, 4, 0)) {
352 DEBUG(0,("lock4 succeeded! This is a locking bug\n"));
355 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
358 if (!cli_close(&cli1, fnum1)) {
359 DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli1)));
363 if (!cli_close(&cli2, fnum3)) {
364 DEBUG(0,("close3 failed (%s)\n", cli_errstr(&cli2)));
368 if (!cli_unlink(&cli1, fname)) {
369 DEBUG(0,("unlink failed (%s)\n", cli_errstr(&cli1)));
374 close_connection(&cli1);
375 close_connection(&cli2);
377 DEBUG(0,("Passed locktest1\n"));
382 This test checks that
384 1) the server supports multiple locking contexts on the one SMB
385 connection, distinguished by PID.
387 2) the server correctly fails overlapping locks made by the same PID (this
388 goes against POSIX behaviour, which is why it is tricky to implement)
390 3) the server denies unlock requests by an incorrect client PID
392 static void run_locktest2(void)
394 static struct cli_state cli;
395 char *fname = "\\lockt2.lck";
396 int fnum1, fnum2, fnum3;
398 if (open_connection(&cli) != 0) {
402 cli_sockopt(&cli, sockops);
404 DEBUG(0,("starting locktest2\n"));
406 cli_unlink(&cli, fname);
410 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
412 DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli)));
416 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
418 DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli)));
424 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
426 DEBUG(0,("open3 of %s failed (%s)\n", fname, cli_errstr(&cli)));
432 if (!cli_lock(&cli, fnum1, 0, 4, 0)) {
433 DEBUG(0,("lock1 failed (%s)\n", cli_errstr(&cli)));
437 if (cli_lock(&cli, fnum2, 0, 4, 0)) {
438 DEBUG(0,("lock2 succeeded! This is a locking bug\n"));
440 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
445 if (cli_unlock(&cli, fnum1, 0, 4, 0)) {
446 DEBUG(0,("unlock1 succeeded! This is a locking bug\n"));
449 if (cli_lock(&cli, fnum3, 0, 4, 0)) {
450 DEBUG(0,("lock3 succeeded! This is a locking bug\n"));
452 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
457 if (!cli_close(&cli, fnum1)) {
458 DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli)));
462 if (!cli_close(&cli, fnum2)) {
463 DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli)));
467 if (!cli_close(&cli, fnum3)) {
468 DEBUG(0,("close3 failed (%s)\n", cli_errstr(&cli)));
472 close_connection(&cli);
474 DEBUG(0,("locktest2 finished\n"));
479 This test checks that
481 1) the server supports the full offset range in lock requests
483 static void run_locktest3(int numops)
485 static struct cli_state cli1, cli2;
486 char *fname = "\\lockt3.lck";
490 #define NEXT_OFFSET offset += (~(uint32)0) / numops
492 if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
495 cli_sockopt(&cli1, sockops);
496 cli_sockopt(&cli2, sockops);
498 DEBUG(0,("starting locktest3\n"));
500 cli_unlink(&cli1, fname);
502 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
504 DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
507 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
509 DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2)));
513 for (offset=i=0;i<numops;i++) {
515 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0)) {
516 DEBUG(0,("lock1 %d failed (%s)\n",
522 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0)) {
523 DEBUG(0,("lock2 %d failed (%s)\n",
530 for (offset=i=0;i<numops;i++) {
533 if (cli_lock(&cli1, fnum1, offset-2, 1, 0)) {
534 DEBUG(0,("error: lock1 %d succeeded!\n", i));
538 if (cli_lock(&cli2, fnum2, offset-1, 1, 0)) {
539 DEBUG(0,("error: lock2 %d succeeded!\n", i));
543 if (cli_lock(&cli1, fnum1, offset-1, 1, 0)) {
544 DEBUG(0,("error: lock3 %d succeeded!\n", i));
548 if (cli_lock(&cli2, fnum2, offset-2, 1, 0)) {
549 DEBUG(0,("error: lock4 %d succeeded!\n", i));
554 for (offset=i=0;i<numops;i++) {
557 if (!cli_unlock(&cli1, fnum1, offset-1, 1, 0)) {
558 DEBUG(0,("unlock1 %d failed (%s)\n",
564 if (!cli_unlock(&cli2, fnum2, offset-2, 1, 0)) {
565 DEBUG(0,("unlock2 %d failed (%s)\n",
572 if (!cli_close(&cli1, fnum1)) {
573 DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli1)));
576 if (!cli_close(&cli2, fnum2)) {
577 DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli2)));
580 if (!cli_unlink(&cli1, fname)) {
581 DEBUG(0,("unlink failed (%s)\n", cli_errstr(&cli1)));
585 close_connection(&cli1);
586 close_connection(&cli2);
588 DEBUG(0,("finished locktest3\n"));
593 test whether fnums and tids open on one VC are available on another (a major
596 static void run_fdpasstest(void)
598 static struct cli_state cli1, cli2;
599 char *fname = "\\fdpass.tst";
603 if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
606 cli_sockopt(&cli1, sockops);
607 cli_sockopt(&cli2, sockops);
609 DEBUG(0,("starting fdpasstest\n"));
611 cli_unlink(&cli1, fname);
613 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
615 DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
619 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
620 DEBUG(0,("write failed (%s)\n", cli_errstr(&cli1)));
624 cli2.vuid = cli1.vuid;
625 cli2.cnum = cli1.cnum;
629 if (cli_read(&cli2, fnum1, buf, 0, 13) == 13) {
630 DEBUG(0,("read succeeded! nasty security hole [%s]\n",
635 cli_close(&cli1, fnum1);
636 cli_unlink(&cli1, fname);
638 close_connection(&cli1);
639 close_connection(&cli2);
641 DEBUG(0,("finished fdpasstest\n"));
646 This test checks that
648 1) the server does not allow an unlink on a file that is open
650 static void run_unlinktest(void)
652 static struct cli_state cli;
653 char *fname = "\\unlink.tst";
656 if (open_connection(&cli) != 0) {
660 cli_sockopt(&cli, sockops);
662 DEBUG(0,("starting unlink test\n"));
664 cli_unlink(&cli, fname);
668 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
670 DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli)));
674 if (cli_unlink(&cli, fname)) {
675 DEBUG(0,("error: server allowed unlink on an open file\n"));
678 cli_close(&cli, fnum);
679 cli_unlink(&cli, fname);
681 close_connection(&cli);
683 DEBUG(0,("unlink test finished\n"));
688 test how many open files this server supports on the one socket
690 static void run_maxfidtest(int n)
692 static struct cli_state cli;
693 char *template = "\\maxfid.%d.%d";
700 while (open_connection(&cli) != 0 && retries--) msleep(random() % 2000);
703 DEBUG(0,("failed to connect\n"));
707 cli_sockopt(&cli, sockops);
709 DEBUG(0,("starting maxfid test\n"));
713 slprintf(fname,sizeof(fname)-1,template, fnum,getpid());
714 if (cli_open(&cli, fname,
715 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE) ==
717 DEBUG(0,("open of %s failed (%s)\n",
718 fname, cli_errstr(&cli)));
719 DEBUG(0,("maximum fnum is %d\n", fnum));
725 DEBUG(0,("cleaning up\n"));
728 slprintf(fname,sizeof(fname)-1,template, fnum,getpid());
729 if (cli_unlink(&cli, fname)) {
730 DEBUG(0,("unlink of %s failed (%s)\n",
731 fname, cli_errstr(&cli)));
735 DEBUG(0,("maxfid test finished\n"));
736 close_connection(&cli);
739 /* generate a random buffer */
740 static void rand_buf(char *buf, int len)
748 /* send random IPC commands */
749 static void run_randomipc(int numops)
754 char param[BUFFER_SIZE];
755 int api, param_len, i;
756 int reconnect_count = 50;
757 static struct cli_state cli;
759 DEBUG(0,("starting random ipc test\n"));
761 while (reconnect_count > 0 && open_connection(&cli) != 0)
763 DEBUG(0,("connection failed: retrying %d\n", reconnect_count));
764 msleep(sys_random() % 1000);
768 if (reconnect_count == 0)
773 for (i=0;i<numops * 100;i++)
775 api = sys_random() % 500;
776 if ((sys_random() % 10) == 0)
778 param_len = (sys_random() % BUFFER_SIZE);
782 param_len = (sys_random() % 64);
785 rand_buf(param, param_len);
791 NULL, 0, BUFFER_SIZE,
796 close_connection(&cli);
798 DEBUG(0,("finished random ipc test\n"));
801 /* send random IPC commands */
802 static void run_randomipc_nowait(int numops)
804 char param[BUFFER_SIZE];
805 int api, param_len, i;
806 int reconnect_count = 50;
807 static struct cli_state cli;
809 DEBUG(0,("start random ipc test no waiting for SMBtrans response\n"));
811 while (reconnect_count > 0 && open_connection(&cli) != 0)
813 DEBUG(0,("connection failed: retrying %d\n", reconnect_count));
814 msleep(sys_random() % 1000);
818 if (reconnect_count == 0)
823 for (i=0;i<numops * 100;i++)
825 api = sys_random() % 500;
826 if ((sys_random() % 10) == 0)
828 param_len = (sys_random() % BUFFER_SIZE);
832 param_len = (sys_random() % 64);
835 rand_buf(param, param_len);
839 cli_send_trans(&cli,SMBtrans,
840 PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */
841 0,0, /* fid, flags */
842 NULL,0,0, /* Setup, length, max */
845 NULL, 0, BUFFER_SIZE);
848 close_connection(&cli);
850 DEBUG(0,("finished random ipc test\n"));
855 static void browse_callback(const char *sname, uint32 stype,
858 DEBUG(0,("\t%20.20s %08x %s\n", sname, stype, comment));
864 This test checks the browse list code
867 static void run_browsetest(void)
869 static struct cli_state cli;
871 DEBUG(0,("starting browse test\n"));
873 if (open_connection(&cli) != 0) {
877 DEBUG(0,("domain list:\n"));
878 cli_NetServerEnum(&cli, workgroup,
882 DEBUG(0,("machine list:\n"));
883 cli_NetServerEnum(&cli, workgroup,
887 close_connection(&cli);
889 DEBUG(0,("browse test finished\n"));
894 This checks how the getatr calls works
896 static void run_attrtest(void)
898 static struct cli_state cli;
901 char *fname = "\\attrib.tst";
903 DEBUG(0,("starting attrib test\n"));
905 if (open_connection(&cli) != 0) {
909 cli_unlink(&cli, fname);
910 fnum = cli_open(&cli, fname,
911 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
912 cli_close(&cli, fnum);
913 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
914 DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli)));
917 if (abs(t - time(NULL)) > 2) {
918 DEBUG(0,("ERROR: SMBgetatr bug. time is %s",
923 t2 = t-60*60*24; /* 1 day ago */
925 if (!cli_setatr(&cli, fname, 0, t2)) {
926 DEBUG(0,("setatr failed (%s)\n", cli_errstr(&cli)));
929 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
930 DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli)));
934 DEBUG(0,("ERROR: getatr/setatr bug. times are\n%s",
936 DEBUG(0,("%s", ctime(&t2)));
939 cli_unlink(&cli, fname);
941 close_connection(&cli);
943 DEBUG(0,("attrib test finished\n"));
948 This checks a couple of trans2 calls
950 static void run_trans2test(void)
952 static struct cli_state cli;
955 time_t c_time, a_time, m_time, w_time, m_time2;
956 char *fname = "\\trans2.tst";
957 char *dname = "\\trans2";
958 char *fname2 = "\\trans2\\trans2.tst";
960 DEBUG(0,("starting trans2 test\n"));
962 if (open_connection(&cli) != 0) {
966 cli_unlink(&cli, fname);
967 fnum = cli_open(&cli, fname,
968 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
969 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
971 DEBUG(0,("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli)));
973 cli_close(&cli, fnum);
977 cli_unlink(&cli, fname);
978 fnum = cli_open(&cli, fname,
979 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
980 cli_close(&cli, fnum);
982 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
983 DEBUG(0,("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli)));
985 if (c_time != m_time) {
986 DEBUG(0,("create time=%s", ctime(&c_time)));
987 DEBUG(0,("modify time=%s", ctime(&m_time)));
988 DEBUG(0,("This system appears to have sticky create times\n"));
990 if (a_time % (60*60) == 0) {
991 DEBUG(0,("access time=%s", ctime(&a_time)));
992 DEBUG(0,("This system appears to set a midnight access time\n"));
995 if (abs(m_time - time(NULL)) > 60*60*24*7) {
996 DEBUG(0,("ERROR: totally incorrect times - maybe word reversed?\n"));
1001 cli_unlink(&cli, fname);
1002 fnum = cli_open(&cli, fname,
1003 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1004 cli_close(&cli, fnum);
1005 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
1006 &w_time, &size, NULL, NULL)) {
1007 DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
1009 if (w_time < 60*60*24*2) {
1010 DEBUG(0,("write time=%s", ctime(&w_time)));
1011 DEBUG(0,("This system appears to set a initial 0 write time\n"));
1015 cli_unlink(&cli, fname);
1018 /* check if the server updates the directory modification time
1019 when creating a new file */
1020 if (!cli_mkdir(&cli, dname)) {
1021 DEBUG(0,("ERROR: mkdir failed (%s)\n", cli_errstr(&cli)));
1024 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
1025 &w_time, &size, NULL, NULL)) {
1026 DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
1029 fnum = cli_open(&cli, fname2,
1030 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1031 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
1032 cli_close(&cli, fnum);
1033 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
1034 &w_time, &size, NULL, NULL)) {
1035 DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
1037 if (m_time2 == m_time)
1038 DEBUG(0,("This system does not update directory modification times\n"));
1040 cli_unlink(&cli, fname2);
1041 cli_rmdir(&cli, dname);
1044 close_connection(&cli);
1046 DEBUG(0,("trans2 test finished\n"));
1050 static void run_connection(int numops)
1054 int failed[NUM_ERR_STATES];
1057 DEBUG(0,("Connection test starts:\n"));
1059 for (i = 0; i < NUM_ERR_STATES; i++)
1064 for (i = 0; i < numops; i++)
1067 DEBUG(0,("Connection test %d %d\n", i, numops));
1068 if ((err = open_connection(&c)))
1078 for (i = 0, failtotal = 0; i < NUM_ERR_STATES; i++)
1080 failtotal += failed[i];
1082 DEBUG(0,("Connection test results: count %d success %d\n", count, count-failtotal));
1084 for (i = 0; i < NUM_ERR_STATES; i++)
1086 DEBUG(0,("%s: failed: %d\n", smb_messages[i], failed[i]));
1090 static void create_procs(int nprocs, int numops, void (*fn)(int ))
1094 for (i=0;i<nprocs;i++)
1098 int mypid = getpid();
1099 sys_srandom(mypid ^ time(NULL));
1101 if (!dbg_interactive())
1103 slprintf(debugf, sizeof(debugf), "./log.torture.%d", mypid);
1113 for (i=0;i<nprocs;i++)
1115 waitpid(0, &status, 0);
1121 #define DEBUG_INTERACTIVE True
1123 /****************************************************************************
1125 ****************************************************************************/
1126 int main(int argc,char *argv[])
1128 int nprocs=1, numops=100;
1132 extern char *optarg;
1134 extern BOOL append_log;
1135 extern BOOL timestamp_log;
1138 pstrcpy(debugf,"./log.torture");
1139 setup_logging(argv[0], DEBUG_INTERACTIVE);
1141 timestamp_log = False;
1143 charset_initialise();
1149 for(p = argv[1]; *p; p++)
1153 if (strncmp(argv[1], "//", 2)) {
1157 fstrcpy(host, &argv[1][2]);
1158 p = strchr(&host[2],'/');
1163 fstrcpy(share, p+1);
1165 get_myname(myname,NULL);
1167 if (*username == 0 && getenv("LOGNAME")) {
1168 pstrcpy(username,getenv("LOGNAME"));
1175 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:")) != EOF) {
1178 fstrcpy(workgroup,optarg);
1181 max_protocol = interpret_protocol(optarg, max_protocol);
1184 nprocs = atoi(optarg);
1187 numops = atoi(optarg);
1193 fstrcpy(myname, optarg);
1196 pstrcpy(username,optarg);
1197 p = strchr(username,'%');
1200 pstrcpy(password, p+1);
1205 printf("Unknown option %c (%d)\n", (char)opt, opt);
1212 p = getpass("Password:");
1214 pstrcpy(password, p);
1219 printf("host=%s share=%s user=%s myname=%s procs=%d ops=%d\n",
1220 host, share, username, myname, nprocs, numops);
1222 create_procs(nprocs, numops, run_connection);
1225 create_procs(nprocs, numops, run_randomipc);
1226 create_procs(nprocs, numops, run_randomipc_nowait);
1231 run_locktest3(numops);
1237 create_procs(nprocs, numops, run_maxfidtest);
1242 create_procs(nprocs, numops, run_torture);
1243 printf("rw_torture: %g secs\n", end_timer());