0eb9a256fcc09c1b64b1a08f29af5eb20eed5816
[ira/wip.git] / source3 / utils / torture.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    SMB torture tester
5    Copyright (C) Andrew Tridgell 1997
6    
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.
11    
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.
16    
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.
20 */
21
22 #ifdef SYSLOG
23 #undef SYSLOG
24 #endif
25
26 #include "includes.h"
27
28 static struct cli_state cli;
29 static fstring host, workgroup, share, password, username, myname;
30 static char *sockops="";
31
32
33 static struct timeval tp1,tp2;
34
35 static void start_timer()
36 {
37         gettimeofday(&tp1,NULL);
38 }
39
40 static double end_timer()
41 {
42         gettimeofday(&tp2,NULL);
43         return((tp2.tv_sec - tp1.tv_sec) + 
44                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
45 }
46
47
48 static int open_connection(void)
49 {
50         if (!cli_initialise(&cli) || !cli_connect(&cli, host, NULL)) {
51                 printf("Failed to connect with %s\n", host);
52         }
53
54         if (!cli_session_request(&cli, host, 0x20, myname)) {
55                 printf("%s rejected the session\n",host);
56                 cli_shutdown(&cli);
57                 return -1;
58         }
59
60         if (!cli_negprot(&cli)) {
61                 printf("%s rejected the negprot (%s)\n",host, cli_errstr(&cli));
62                 cli_shutdown(&cli);
63                 return -1;
64         }
65
66         if (!cli_session_setup(&cli, username, password, strlen(password),
67                                "", 0, workgroup)) {
68                 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(&cli));
69                 cli_shutdown(&cli);
70                 return -1;
71         }
72
73         if (!cli_send_tconX(&cli, share, "A:", password, strlen(password)+1)) {
74                 printf("%s refused tree connect (%s)\n", host, cli_errstr(&cli));
75                 cli_shutdown(&cli);
76                 return -1;
77         }
78
79         return 0;
80 }
81
82
83
84 static void close_connection(void)
85 {
86         if (!cli_tdis(&cli)) {
87                 printf("tdis failed (%s)\n", cli_errstr(&cli));
88         }
89
90         cli_shutdown(&cli);
91 }
92
93
94
95
96 static BOOL wait_lock(int fnum, uint32 offset, uint32 len)
97 {
98         while (!cli_lock(&cli, fnum, offset, len, -1)) {
99                 int eclass, num;
100                 cli_error(&cli, &eclass, &num);
101                 if (eclass != ERRDOS || num != ERRlock) {
102                         printf("lock failed (%s)\n", 
103                                cli_errstr(&cli));
104                         return False;
105                 }
106         }
107         return True;
108 }
109
110
111 static int rw_torture(int numops)
112 {
113         char *lockfname = "\\torture.lck";
114         fstring fname;
115         int fnum;
116         int fnum2;
117         int pid2, pid = getpid();
118         int i;
119
120         fnum2 = cli_open(&cli, lockfname, O_RDWR | O_CREAT | O_EXCL, 
121                          DENY_NONE);
122         if (fnum2 == -1)
123                 fnum2 = cli_open(&cli, lockfname, O_RDWR, DENY_NONE);
124         if (fnum2 == -1) {
125                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(&cli));
126                 return -1;
127         }
128
129
130         for (i=0;i<numops;i++) {
131                 unsigned n = (unsigned)random()%10;
132                 if (i % 10 == 0) {
133                         printf("%d\r", i); fflush(stdout);
134                 }
135                 sprintf(fname,"\\torture.%u", n);
136
137                 if (!wait_lock(fnum2, n*sizeof(int), sizeof(int))) {
138                         return -1;
139                 }
140
141                 fnum = cli_open(&cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
142                 if (fnum == -1) {
143                         printf("open failed (%s)\n", cli_errstr(&cli));
144                         break;
145                 }
146
147                 if (cli_write(&cli, fnum, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
148                         printf("write failed (%s)\n", cli_errstr(&cli));
149                 }
150
151                 pid2 = 0;
152
153                 if (cli_read(&cli, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
154                         printf("read failed (%s)\n", cli_errstr(&cli));
155                 }
156
157                 if (pid2 != pid) {
158                         printf("data corruption!\n");
159                 }
160
161                 if (!cli_close(&cli, fnum)) {
162                         printf("close failed (%s)\n", cli_errstr(&cli));
163                 }
164
165                 if (!cli_unlink(&cli, fname)) {
166                         printf("unlink failed (%s)\n", cli_errstr(&cli));
167                 }
168
169                 if (!cli_unlock(&cli, fnum2, n*sizeof(int), sizeof(int), -1)) {
170                         printf("unlock failed (%s)\n", cli_errstr(&cli));
171                 }
172         }
173
174         printf("%d\n", i);
175
176         return 0;
177 }
178
179 static void usage(void)
180 {
181         printf("Usage: smbtorture \\\\server\\share <options>\n");
182
183         printf("\t-U user%%pass\n");
184         printf("\t-N numprocs\n");
185         printf("\t-n my_netbios_name\n");
186         printf("\t-W workgroup\n");
187         printf("\t-o num_operations\n");
188         printf("\t-O socket_options\n");
189         printf("\n");
190
191         exit(1);
192 }
193
194
195
196 static void run_torture(int numops)
197 {
198         if (open_connection() == 0) {
199                 cli_sockopt(&cli, sockops);
200
201                 printf("pid %d OK\n", getpid());
202
203                 rw_torture(numops);
204
205                 close_connection();
206         }
207 }
208
209
210 static void create_procs(int nprocs, int numops)
211 {
212         int i, status;
213
214         for (i=0;i<nprocs;i++) {
215                 if (fork() == 0) {
216                         int mypid = getpid();
217                         srandom(mypid ^ time(NULL));
218                         run_torture(numops);
219                         _exit(0);
220                 }
221         }
222
223         for (i=0;i<nprocs;i++)
224                 waitpid(0, &status, 0);
225 }
226
227
228
229 /****************************************************************************
230   main program
231 ****************************************************************************/
232  int main(int argc,char *argv[])
233 {
234         int nprocs=1, numops=100;
235         int opt;
236         char *p;
237         int gotpass = 0;
238         extern char *optarg;
239         extern int optind;
240         extern FILE *dbf;
241
242         dbf = stdout;
243
244         charset_initialise();
245
246         if (argc < 2) {
247                 usage();
248         }
249
250         if (strncmp(argv[1], "\\\\", 2)) {
251                 usage();
252         }
253
254         fstrcpy(host, &argv[1][2]);
255         p = strchr(&host[2],'\\');
256         if (!p) {
257                 usage();
258         }
259         *p = 0;
260         fstrcpy(share, p+1);
261
262         get_myname(myname,NULL);
263
264         argc--;
265         argv++;
266
267
268         while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:")) != EOF) {
269                 switch (opt) {
270                 case 'W':
271                         fstrcpy(workgroup,optarg);
272                         break;
273                 case 'N':
274                         nprocs = atoi(optarg);
275                         break;
276                 case 'o':
277                         numops = atoi(optarg);
278                         break;
279                 case 'O':
280                         sockops = optarg;
281                         break;
282                 case 'n':
283                         fstrcpy(myname, optarg);
284                         break;
285                 case 'U':
286                         strcpy(username,optarg);
287                         p = strchr(username,'%');
288                         if (p) {
289                                 *p = 0;
290                                 strcpy(password, p+1);
291                                 gotpass = 1;
292                         }
293                         break;
294                 default:
295                         printf("Unknown option %c (%d)\n", (char)opt, opt);
296                         usage();
297                 }
298         }
299
300
301         while (!gotpass) {
302                 p = getpass("Password:");
303                 if (p) {
304                         strcpy(password, p);
305                         gotpass = 1;
306                 }
307         }
308
309         printf("host=%s share=%s user=%s myname=%s\n", 
310                host, share, username, myname);
311
312         start_timer();
313         create_procs(nprocs, numops);
314         printf("rw_torture: %g secs\n", end_timer());
315
316         return(0);
317 }
318
319