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 #define TORT_BUFFER_SIZE 1024
750 /* send random IPC commands */
751 static void run_randomipc(int numops)
756 char param[TORT_BUFFER_SIZE];
757 int api, param_len, i;
758 int reconnect_count = 500;
759 static struct cli_state cli;
761 DEBUG(0,("starting random ipc test\n"));
763 while (reconnect_count > 0 && open_connection(&cli) != 0)
765 DEBUG(0,("connection failed: retrying %d\n", reconnect_count));
766 msleep(sys_random() % 5000);
770 if (reconnect_count == 0)
775 for (i=0;i<numops * 100;i++)
777 api = sys_random() % 500;
778 if ((sys_random() % 10) == 0)
780 param_len = (sys_random() % TORT_BUFFER_SIZE);
784 param_len = (sys_random() % 64);
787 rand_buf(param, param_len);
793 NULL, 0, BUFFER_SIZE,
798 close_connection(&cli);
800 DEBUG(0,("finished random ipc test\n"));
803 /* send random IPC commands */
804 static void run_randomipc_nowait(int numops)
806 char param[TORT_BUFFER_SIZE];
807 int api, param_len, i;
808 int reconnect_count = 500;
809 static struct cli_state cli;
811 DEBUG(0,("start random ipc test no waiting for SMBtrans response\n"));
813 while (reconnect_count > 0 && open_connection(&cli) != 0)
815 DEBUG(0,("connection failed: retrying %d\n", reconnect_count));
816 msleep(sys_random() % 5000);
820 if (reconnect_count == 0)
825 for (i=0;i<numops * 100;i++)
827 api = sys_random() % 500;
828 if ((sys_random() % 10) == 0)
830 param_len = (sys_random() % TORT_BUFFER_SIZE);
834 param_len = (sys_random() % 64);
837 rand_buf(param, param_len);
841 cli_send_trans(&cli,SMBtrans,
842 PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */
843 0,0, /* fid, flags */
844 NULL,0,0, /* Setup, length, max */
847 NULL, 0, BUFFER_SIZE);
850 close_connection(&cli);
852 DEBUG(0,("finished random ipc test\n"));
857 static void browse_callback(const char *sname, uint32 stype,
860 DEBUG(0,("\t%20.20s %08x %s\n", sname, stype, comment));
866 This test checks the browse list code
869 static void run_browsetest(void)
871 static struct cli_state cli;
873 DEBUG(0,("starting browse test\n"));
875 if (open_connection(&cli) != 0) {
879 DEBUG(0,("domain list:\n"));
880 cli_NetServerEnum(&cli, workgroup,
884 DEBUG(0,("machine list:\n"));
885 cli_NetServerEnum(&cli, workgroup,
889 close_connection(&cli);
891 DEBUG(0,("browse test finished\n"));
896 This checks how the getatr calls works
898 static void run_attrtest(void)
900 static struct cli_state cli;
903 char *fname = "\\attrib.tst";
905 DEBUG(0,("starting attrib test\n"));
907 if (open_connection(&cli) != 0) {
911 cli_unlink(&cli, fname);
912 fnum = cli_open(&cli, fname,
913 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
914 cli_close(&cli, fnum);
915 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
916 DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli)));
919 if (abs(t - time(NULL)) > 2) {
920 DEBUG(0,("ERROR: SMBgetatr bug. time is %s",
925 t2 = t-60*60*24; /* 1 day ago */
927 if (!cli_setatr(&cli, fname, 0, t2)) {
928 DEBUG(0,("setatr failed (%s)\n", cli_errstr(&cli)));
931 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
932 DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli)));
936 DEBUG(0,("ERROR: getatr/setatr bug. times are\n%s",
938 DEBUG(0,("%s", ctime(&t2)));
941 cli_unlink(&cli, fname);
943 close_connection(&cli);
945 DEBUG(0,("attrib test finished\n"));
950 This checks a couple of trans2 calls
952 static void run_trans2test(void)
954 static struct cli_state cli;
957 time_t c_time, a_time, m_time, w_time, m_time2;
958 char *fname = "\\trans2.tst";
959 char *dname = "\\trans2";
960 char *fname2 = "\\trans2\\trans2.tst";
962 DEBUG(0,("starting trans2 test\n"));
964 if (open_connection(&cli) != 0) {
968 cli_unlink(&cli, fname);
969 fnum = cli_open(&cli, fname,
970 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
971 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
973 DEBUG(0,("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli)));
975 cli_close(&cli, fnum);
979 cli_unlink(&cli, fname);
980 fnum = cli_open(&cli, fname,
981 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
982 cli_close(&cli, fnum);
984 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
985 DEBUG(0,("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli)));
987 if (c_time != m_time) {
988 DEBUG(0,("create time=%s", ctime(&c_time)));
989 DEBUG(0,("modify time=%s", ctime(&m_time)));
990 DEBUG(0,("This system appears to have sticky create times\n"));
992 if (a_time % (60*60) == 0) {
993 DEBUG(0,("access time=%s", ctime(&a_time)));
994 DEBUG(0,("This system appears to set a midnight access time\n"));
997 if (abs(m_time - time(NULL)) > 60*60*24*7) {
998 DEBUG(0,("ERROR: totally incorrect times - maybe word reversed?\n"));
1003 cli_unlink(&cli, fname);
1004 fnum = cli_open(&cli, fname,
1005 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1006 cli_close(&cli, fnum);
1007 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
1008 &w_time, &size, NULL, NULL)) {
1009 DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
1011 if (w_time < 60*60*24*2) {
1012 DEBUG(0,("write time=%s", ctime(&w_time)));
1013 DEBUG(0,("This system appears to set a initial 0 write time\n"));
1017 cli_unlink(&cli, fname);
1020 /* check if the server updates the directory modification time
1021 when creating a new file */
1022 if (!cli_mkdir(&cli, dname)) {
1023 DEBUG(0,("ERROR: mkdir failed (%s)\n", cli_errstr(&cli)));
1026 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
1027 &w_time, &size, NULL, NULL)) {
1028 DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
1031 fnum = cli_open(&cli, fname2,
1032 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1033 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
1034 cli_close(&cli, fnum);
1035 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
1036 &w_time, &size, NULL, NULL)) {
1037 DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
1039 if (m_time2 == m_time)
1040 DEBUG(0,("This system does not update directory modification times\n"));
1042 cli_unlink(&cli, fname2);
1043 cli_rmdir(&cli, dname);
1046 close_connection(&cli);
1048 DEBUG(0,("trans2 test finished\n"));
1052 static void run_connection(int numops)
1056 int failed[NUM_ERR_STATES];
1059 DEBUG(0,("Connection test starts:\n"));
1061 for (i = 0; i < NUM_ERR_STATES; i++)
1066 for (i = 0; i < numops; i++)
1069 DEBUG(0,("Connection test %d %d\n", i, numops));
1070 if ((err = open_connection(&c)))
1080 for (i = 0, failtotal = 0; i < NUM_ERR_STATES; i++)
1082 failtotal += failed[i];
1084 DEBUG(0,("Connection test results: count %d success %d\n", count, count-failtotal));
1086 for (i = 0; i < NUM_ERR_STATES; i++)
1088 DEBUG(0,("%s: failed: %d\n", smb_messages[i], failed[i]));
1092 static void create_procs(int nprocs, int numops, void (*fn)(int ))
1096 for (i=0;i<nprocs;i++)
1100 int mypid = getpid();
1101 sys_srandom(mypid ^ time(NULL));
1103 if (!dbg_interactive())
1105 slprintf(debugf, sizeof(debugf), "./log.torture.%d", mypid);
1115 for (i=0;i<nprocs;i++)
1117 waitpid(0, &status, 0);
1123 #define DEBUG_INTERACTIVE True
1125 /****************************************************************************
1127 ****************************************************************************/
1128 int main(int argc,char *argv[])
1130 int nprocs=1, numops=100;
1134 extern char *optarg;
1136 extern BOOL append_log;
1137 extern BOOL timestamp_log;
1140 pstrcpy(debugf,"./log.torture");
1141 setup_logging(argv[0], DEBUG_INTERACTIVE);
1143 timestamp_log = False;
1145 charset_initialise();
1151 for(p = argv[1]; *p; p++)
1155 if (strncmp(argv[1], "//", 2)) {
1159 fstrcpy(host, &argv[1][2]);
1160 p = strchr(&host[2],'/');
1165 fstrcpy(share, p+1);
1167 get_myname(myname,NULL);
1169 if (*username == 0 && getenv("LOGNAME")) {
1170 pstrcpy(username,getenv("LOGNAME"));
1177 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:")) != EOF) {
1180 fstrcpy(workgroup,optarg);
1183 max_protocol = interpret_protocol(optarg, max_protocol);
1186 nprocs = atoi(optarg);
1189 numops = atoi(optarg);
1195 fstrcpy(myname, optarg);
1198 pstrcpy(username,optarg);
1199 p = strchr(username,'%');
1202 pstrcpy(password, p+1);
1207 printf("Unknown option %c (%d)\n", (char)opt, opt);
1214 p = getpass("Password:");
1216 pstrcpy(password, p);
1221 printf("host=%s share=%s user=%s myname=%s procs=%d ops=%d\n",
1222 host, share, username, myname, nprocs, numops);
1224 create_procs(nprocs, numops, run_randomipc_nowait);
1226 create_procs(nprocs, numops, run_randomipc);
1228 create_procs(nprocs, numops, run_connection);
1233 run_locktest3(numops);
1239 create_procs(nprocs, numops, run_maxfidtest);
1244 create_procs(nprocs, numops, run_torture);
1245 printf("rw_torture: %g secs\n", end_timer());