r4591: - converted the other _p talloc functions to not need _p
[jelmer/samba4-debian.git] / source / torture / raw / read.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for various read operations
4    Copyright (C) Andrew Tridgell 2003
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "system/time.h"
24
25 #define CHECK_STATUS(status, correct) do { \
26         if (!NT_STATUS_EQUAL(status, correct)) { \
27                 printf("(%s) Incorrect status %s - should be %s\n", \
28                        __location__, nt_errstr(status), nt_errstr(correct)); \
29                 ret = False; \
30                 goto done; \
31         }} while (0)
32
33 #define CHECK_VALUE(v, correct) do { \
34         if ((v) != (correct)) { \
35                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
36                        __location__, #v, v, correct); \
37                 ret = False; \
38                 goto done; \
39         }} while (0)
40
41 #define CHECK_BUFFER(buf, seed, len) do { \
42         if (!check_buffer(buf, seed, len, __LINE__)) { \
43                 ret = False; \
44                 goto done; \
45         }} while (0)
46
47 #define BASEDIR "\\testread"
48
49
50 /*
51   setup a random buffer based on a seed
52 */
53 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
54 {
55         int i;
56         srandom(seed);
57         for (i=0;i<len;i++) buf[i] = random();
58 }
59
60 /*
61   check a random buffer based on a seed
62 */
63 static BOOL check_buffer(uint8_t *buf, uint_t seed, int len, int line)
64 {
65         int i;
66         srandom(seed);
67         for (i=0;i<len;i++) {
68                 uint8_t v = random();
69                 if (buf[i] != v) {
70                         printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n", 
71                                line, i, buf[i], v);
72                         return False;
73                 }
74         }
75         return True;
76 }
77
78 /*
79   test read ops
80 */
81 static BOOL test_read(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
82 {
83         union smb_read io;
84         NTSTATUS status;
85         BOOL ret = True;
86         int fnum;
87         uint8_t *buf;
88         const int maxsize = 90000;
89         const char *fname = BASEDIR "\\test.txt";
90         const char *test_data = "TEST DATA";
91         uint_t seed = time(NULL);
92
93         buf = talloc_zero_size(mem_ctx, maxsize);
94
95         if (!torture_setup_dir(cli, BASEDIR)) {
96                 return False;
97         }
98
99         printf("Testing RAW_READ_READ\n");
100         io.generic.level = RAW_READ_READ;
101         
102         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
103         if (fnum == -1) {
104                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
105                 ret = False;
106                 goto done;
107         }
108
109         printf("Trying empty file read\n");
110         io.read.in.fnum = fnum;
111         io.read.in.count = 1;
112         io.read.in.offset = 0;
113         io.read.in.remaining = 0;
114         io.read.out.data = buf;
115         status = smb_raw_read(cli->tree, &io);
116
117         CHECK_STATUS(status, NT_STATUS_OK);
118         CHECK_VALUE(io.read.out.nread, 0);
119
120         printf("Trying zero file read\n");
121         io.read.in.count = 0;
122         status = smb_raw_read(cli->tree, &io);
123         CHECK_STATUS(status, NT_STATUS_OK);
124         CHECK_VALUE(io.read.out.nread, 0);
125
126         printf("Trying bad fnum\n");
127         io.read.in.fnum = fnum+1;
128         status = smb_raw_read(cli->tree, &io);
129         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
130         io.read.in.fnum = fnum;
131
132         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
133
134         printf("Trying small read\n");
135         io.read.in.fnum = fnum;
136         io.read.in.offset = 0;
137         io.read.in.remaining = 0;
138         io.read.in.count = strlen(test_data);
139         status = smb_raw_read(cli->tree, &io);
140         CHECK_STATUS(status, NT_STATUS_OK);
141         CHECK_VALUE(io.read.out.nread, strlen(test_data));
142         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
143                 ret = False;
144                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
145                 goto done;
146         }
147
148         printf("Trying short read\n");
149         io.read.in.offset = 1;
150         io.read.in.count = strlen(test_data);
151         status = smb_raw_read(cli->tree, &io);
152         CHECK_STATUS(status, NT_STATUS_OK);
153         CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
154         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
155                 ret = False;
156                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
157                 goto done;
158         }
159
160         printf("Trying max offset\n");
161         io.read.in.offset = ~0;
162         io.read.in.count = strlen(test_data);
163         status = smb_raw_read(cli->tree, &io);
164         CHECK_STATUS(status, NT_STATUS_OK);
165         CHECK_VALUE(io.read.out.nread, 0);
166
167         setup_buffer(buf, seed, maxsize);
168         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
169         memset(buf, 0, maxsize);
170
171         printf("Trying large read\n");
172         io.read.in.offset = 0;
173         io.read.in.count = ~0;
174         status = smb_raw_read(cli->tree, &io);
175         CHECK_STATUS(status, NT_STATUS_OK);
176         CHECK_BUFFER(buf, seed, io.read.out.nread);
177
178
179         printf("Trying locked region\n");
180         cli->session->pid++;
181         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
182                 printf("Failed to lock file at %d\n", __LINE__);
183                 ret = False;
184                 goto done;
185         }
186         cli->session->pid--;
187         memset(buf, 0, maxsize);
188         io.read.in.offset = 0;
189         io.read.in.count = ~0;
190         status = smb_raw_read(cli->tree, &io);
191         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
192         
193
194 done:
195         smbcli_close(cli->tree, fnum);
196         smb_raw_exit(cli->session);
197         smbcli_deltree(cli->tree, BASEDIR);
198         return ret;
199 }
200
201
202 /*
203   test lockread ops
204 */
205 static BOOL test_lockread(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
206 {
207         union smb_read io;
208         NTSTATUS status;
209         BOOL ret = True;
210         int fnum;
211         uint8_t *buf;
212         const int maxsize = 90000;
213         const char *fname = BASEDIR "\\test.txt";
214         const char *test_data = "TEST DATA";
215         uint_t seed = time(NULL);
216
217         buf = talloc_zero_size(mem_ctx, maxsize);
218
219         if (!torture_setup_dir(cli, BASEDIR)) {
220                 return False;
221         }
222
223         printf("Testing RAW_READ_LOCKREAD\n");
224         io.generic.level = RAW_READ_LOCKREAD;
225         
226         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
227         if (fnum == -1) {
228                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
229                 ret = False;
230                 goto done;
231         }
232
233         printf("Trying empty file read\n");
234         io.lockread.in.fnum = fnum;
235         io.lockread.in.count = 1;
236         io.lockread.in.offset = 1;
237         io.lockread.in.remaining = 0;
238         io.lockread.out.data = buf;
239         status = smb_raw_read(cli->tree, &io);
240
241         CHECK_STATUS(status, NT_STATUS_OK);
242         CHECK_VALUE(io.lockread.out.nread, 0);
243
244         status = smb_raw_read(cli->tree, &io);
245         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
246
247         status = smb_raw_read(cli->tree, &io);
248         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
249
250         printf("Trying zero file read\n");
251         io.lockread.in.count = 0;
252         status = smb_raw_read(cli->tree, &io);
253         CHECK_STATUS(status, NT_STATUS_OK);
254
255         smbcli_unlock(cli->tree, fnum, 1, 1);
256
257         printf("Trying bad fnum\n");
258         io.lockread.in.fnum = fnum+1;
259         status = smb_raw_read(cli->tree, &io);
260         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
261         io.lockread.in.fnum = fnum;
262
263         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
264
265         printf("Trying small read\n");
266         io.lockread.in.fnum = fnum;
267         io.lockread.in.offset = 0;
268         io.lockread.in.remaining = 0;
269         io.lockread.in.count = strlen(test_data);
270         status = smb_raw_read(cli->tree, &io);
271         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
272
273         smbcli_unlock(cli->tree, fnum, 1, 0);
274
275         status = smb_raw_read(cli->tree, &io);
276         CHECK_STATUS(status, NT_STATUS_OK);
277         CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
278         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
279                 ret = False;
280                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
281                 goto done;
282         }
283
284         printf("Trying short read\n");
285         io.lockread.in.offset = 1;
286         io.lockread.in.count = strlen(test_data);
287         status = smb_raw_read(cli->tree, &io);
288         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
289         smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
290         status = smb_raw_read(cli->tree, &io);
291         CHECK_STATUS(status, NT_STATUS_OK);
292
293         CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
294         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
295                 ret = False;
296                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
297                 goto done;
298         }
299
300         printf("Trying max offset\n");
301         io.lockread.in.offset = ~0;
302         io.lockread.in.count = strlen(test_data);
303         status = smb_raw_read(cli->tree, &io);
304         CHECK_STATUS(status, NT_STATUS_OK);
305         CHECK_VALUE(io.lockread.out.nread, 0);
306
307         setup_buffer(buf, seed, maxsize);
308         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
309         memset(buf, 0, maxsize);
310
311         printf("Trying large read\n");
312         io.lockread.in.offset = 0;
313         io.lockread.in.count = ~0;
314         status = smb_raw_read(cli->tree, &io);
315         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
316         smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
317         status = smb_raw_read(cli->tree, &io);
318         CHECK_STATUS(status, NT_STATUS_OK);
319         CHECK_BUFFER(buf, seed, io.lockread.out.nread);
320         smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
321
322
323         printf("Trying locked region\n");
324         cli->session->pid++;
325         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
326                 printf("Failed to lock file at %d\n", __LINE__);
327                 ret = False;
328                 goto done;
329         }
330         cli->session->pid--;
331         memset(buf, 0, maxsize);
332         io.lockread.in.offset = 0;
333         io.lockread.in.count = ~0;
334         status = smb_raw_read(cli->tree, &io);
335         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
336         
337
338 done:
339         smbcli_close(cli->tree, fnum);
340         smbcli_deltree(cli->tree, BASEDIR);
341         return ret;
342 }
343
344
345 /*
346   test readx ops
347 */
348 static BOOL test_readx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
349 {
350         union smb_read io;
351         NTSTATUS status;
352         BOOL ret = True;
353         int fnum;
354         uint8_t *buf;
355         const int maxsize = 90000;
356         const char *fname = BASEDIR "\\test.txt";
357         const char *test_data = "TEST DATA";
358         uint_t seed = time(NULL);
359
360         buf = talloc_zero_size(mem_ctx, maxsize);
361
362         if (!torture_setup_dir(cli, BASEDIR)) {
363                 return False;
364         }
365
366         printf("Testing RAW_READ_READX\n");
367         
368         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
369         if (fnum == -1) {
370                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
371                 ret = False;
372                 goto done;
373         }
374
375         printf("Trying empty file read\n");
376         io.generic.level = RAW_READ_READX;
377         io.readx.in.fnum = fnum;
378         io.readx.in.mincnt = 1;
379         io.readx.in.maxcnt = 1;
380         io.readx.in.offset = 0;
381         io.readx.in.remaining = 0;
382         io.readx.out.data = buf;
383         status = smb_raw_read(cli->tree, &io);
384
385         CHECK_STATUS(status, NT_STATUS_OK);
386         CHECK_VALUE(io.readx.out.nread, 0);
387         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
388         CHECK_VALUE(io.readx.out.compaction_mode, 0);
389
390         printf("Trying zero file read\n");
391         io.readx.in.mincnt = 0;
392         io.readx.in.maxcnt = 0;
393         status = smb_raw_read(cli->tree, &io);
394         CHECK_STATUS(status, NT_STATUS_OK);
395         CHECK_VALUE(io.readx.out.nread, 0);
396         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
397         CHECK_VALUE(io.readx.out.compaction_mode, 0);
398
399         printf("Trying bad fnum\n");
400         io.readx.in.fnum = fnum+1;
401         status = smb_raw_read(cli->tree, &io);
402         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
403         io.readx.in.fnum = fnum;
404
405         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
406
407         printf("Trying small read\n");
408         io.readx.in.fnum = fnum;
409         io.readx.in.offset = 0;
410         io.readx.in.remaining = 0;
411         io.readx.in.mincnt = strlen(test_data);
412         io.readx.in.maxcnt = strlen(test_data);
413         status = smb_raw_read(cli->tree, &io);
414         CHECK_STATUS(status, NT_STATUS_OK);
415         CHECK_VALUE(io.readx.out.nread, strlen(test_data));
416         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
417         CHECK_VALUE(io.readx.out.compaction_mode, 0);
418         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
419                 ret = False;
420                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
421                 goto done;
422         }
423
424         printf("Trying short read\n");
425         io.readx.in.offset = 1;
426         io.readx.in.mincnt = strlen(test_data);
427         io.readx.in.maxcnt = strlen(test_data);
428         status = smb_raw_read(cli->tree, &io);
429         CHECK_STATUS(status, NT_STATUS_OK);
430         CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
431         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
432         CHECK_VALUE(io.readx.out.compaction_mode, 0);
433         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
434                 ret = False;
435                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
436                 goto done;
437         }
438
439         printf("Trying max offset\n");
440         io.readx.in.offset = 0xffffffff;
441         io.readx.in.mincnt = strlen(test_data);
442         io.readx.in.maxcnt = strlen(test_data);
443         status = smb_raw_read(cli->tree, &io);
444         CHECK_STATUS(status, NT_STATUS_OK);
445         CHECK_VALUE(io.readx.out.nread, 0);
446         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
447         CHECK_VALUE(io.readx.out.compaction_mode, 0);
448
449         setup_buffer(buf, seed, maxsize);
450         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
451         memset(buf, 0, maxsize);
452
453         printf("Trying large read\n");
454         io.readx.in.offset = 0;
455         io.readx.in.mincnt = 0xFFFF;
456         io.readx.in.maxcnt = 0xFFFF;
457         status = smb_raw_read(cli->tree, &io);
458         CHECK_STATUS(status, NT_STATUS_OK);
459         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
460         CHECK_VALUE(io.readx.out.compaction_mode, 0);
461         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
462         CHECK_BUFFER(buf, seed, io.readx.out.nread);
463
464         printf("Trying extra large read\n");
465         io.readx.in.offset = 0;
466         io.readx.in.mincnt = 100;
467         io.readx.in.maxcnt = 80000;
468         status = smb_raw_read(cli->tree, &io);
469         CHECK_STATUS(status, NT_STATUS_OK);
470         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
471         CHECK_VALUE(io.readx.out.compaction_mode, 0);
472         CHECK_VALUE(io.readx.out.nread, 0);
473         CHECK_BUFFER(buf, seed, io.readx.out.nread);
474
475         printf("Trying mincnt > maxcnt\n");
476         memset(buf, 0, maxsize);
477         io.readx.in.offset = 0;
478         io.readx.in.mincnt = 30000;
479         io.readx.in.maxcnt = 20000;
480         status = smb_raw_read(cli->tree, &io);
481         CHECK_STATUS(status, NT_STATUS_OK);
482         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
483         CHECK_VALUE(io.readx.out.compaction_mode, 0);
484         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
485         CHECK_BUFFER(buf, seed, io.readx.out.nread);
486
487         printf("Trying mincnt < maxcnt\n");
488         memset(buf, 0, maxsize);
489         io.readx.in.offset = 0;
490         io.readx.in.mincnt = 20000;
491         io.readx.in.maxcnt = 30000;
492         status = smb_raw_read(cli->tree, &io);
493         CHECK_STATUS(status, NT_STATUS_OK);
494         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
495         CHECK_VALUE(io.readx.out.compaction_mode, 0);
496         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
497         CHECK_BUFFER(buf, seed, io.readx.out.nread);
498
499         printf("Trying locked region\n");
500         cli->session->pid++;
501         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
502                 printf("Failed to lock file at %d\n", __LINE__);
503                 ret = False;
504                 goto done;
505         }
506         cli->session->pid--;
507         memset(buf, 0, maxsize);
508         io.readx.in.offset = 0;
509         io.readx.in.mincnt = 100;
510         io.readx.in.maxcnt = 200;
511         status = smb_raw_read(cli->tree, &io);
512         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);     
513
514         printf("Trying large offset read\n");
515         io.readx.in.offset = ((uint64_t)0x2) << 32;
516         io.readx.in.mincnt = 10;
517         io.readx.in.maxcnt = 10;
518         status = smb_raw_read(cli->tree, &io);
519         CHECK_STATUS(status, NT_STATUS_OK);
520         CHECK_VALUE(io.readx.out.nread, 0);
521
522         if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
523                 printf("Failed to lock file at %d\n", __LINE__);
524                 ret = False;
525                 goto done;
526         }
527
528         status = smb_raw_read(cli->tree, &io);
529         CHECK_STATUS(status, NT_STATUS_OK);
530         CHECK_VALUE(io.readx.out.nread, 0);
531
532 done:
533         smbcli_close(cli->tree, fnum);
534         smbcli_deltree(cli->tree, BASEDIR);
535         return ret;
536 }
537
538
539 /*
540   test readbraw ops
541 */
542 static BOOL test_readbraw(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
543 {
544         union smb_read io;
545         NTSTATUS status;
546         BOOL ret = True;
547         int fnum;
548         uint8_t *buf;
549         const int maxsize = 90000;
550         const char *fname = BASEDIR "\\test.txt";
551         const char *test_data = "TEST DATA";
552         uint_t seed = time(NULL);
553
554         buf = talloc_zero_size(mem_ctx, maxsize);
555
556         if (!torture_setup_dir(cli, BASEDIR)) {
557                 return False;
558         }
559
560         printf("Testing RAW_READ_READBRAW\n");
561         
562         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
563         if (fnum == -1) {
564                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
565                 ret = False;
566                 goto done;
567         }
568
569         printf("Trying empty file read\n");
570         io.generic.level = RAW_READ_READBRAW;
571         io.readbraw.in.fnum = fnum;
572         io.readbraw.in.mincnt = 1;
573         io.readbraw.in.maxcnt = 1;
574         io.readbraw.in.offset = 0;
575         io.readbraw.in.timeout = 0;
576         io.readbraw.out.data = buf;
577         status = smb_raw_read(cli->tree, &io);
578
579         CHECK_STATUS(status, NT_STATUS_OK);
580         CHECK_VALUE(io.readbraw.out.nread, 0);
581
582         printf("Trying zero file read\n");
583         io.readbraw.in.mincnt = 0;
584         io.readbraw.in.maxcnt = 0;
585         status = smb_raw_read(cli->tree, &io);
586         CHECK_STATUS(status, NT_STATUS_OK);
587         CHECK_VALUE(io.readbraw.out.nread, 0);
588
589         printf("Trying bad fnum\n");
590         io.readbraw.in.fnum = fnum+1;
591         status = smb_raw_read(cli->tree, &io);
592         CHECK_STATUS(status, NT_STATUS_OK);
593         CHECK_VALUE(io.readbraw.out.nread, 0);
594         io.readbraw.in.fnum = fnum;
595
596         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
597
598         printf("Trying small read\n");
599         io.readbraw.in.fnum = fnum;
600         io.readbraw.in.offset = 0;
601         io.readbraw.in.mincnt = strlen(test_data);
602         io.readbraw.in.maxcnt = strlen(test_data);
603         status = smb_raw_read(cli->tree, &io);
604         CHECK_STATUS(status, NT_STATUS_OK);
605         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
606         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
607                 ret = False;
608                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
609                 goto done;
610         }
611
612         printf("Trying short read\n");
613         io.readbraw.in.offset = 1;
614         io.readbraw.in.mincnt = strlen(test_data);
615         io.readbraw.in.maxcnt = strlen(test_data);
616         status = smb_raw_read(cli->tree, &io);
617         CHECK_STATUS(status, NT_STATUS_OK);
618         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
619         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
620                 ret = False;
621                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
622                 goto done;
623         }
624
625         printf("Trying max offset\n");
626         io.readbraw.in.offset = ~0;
627         io.readbraw.in.mincnt = strlen(test_data);
628         io.readbraw.in.maxcnt = strlen(test_data);
629         status = smb_raw_read(cli->tree, &io);
630         CHECK_STATUS(status, NT_STATUS_OK);
631         CHECK_VALUE(io.readbraw.out.nread, 0);
632
633         setup_buffer(buf, seed, maxsize);
634         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
635         memset(buf, 0, maxsize);
636
637         printf("Trying large read\n");
638         io.readbraw.in.offset = 0;
639         io.readbraw.in.mincnt = ~0;
640         io.readbraw.in.maxcnt = ~0;
641         status = smb_raw_read(cli->tree, &io);
642         CHECK_STATUS(status, NT_STATUS_OK);
643         CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
644         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
645
646         printf("Trying mincnt > maxcnt\n");
647         memset(buf, 0, maxsize);
648         io.readbraw.in.offset = 0;
649         io.readbraw.in.mincnt = 30000;
650         io.readbraw.in.maxcnt = 20000;
651         status = smb_raw_read(cli->tree, &io);
652         CHECK_STATUS(status, NT_STATUS_OK);
653         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
654         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
655
656         printf("Trying mincnt < maxcnt\n");
657         memset(buf, 0, maxsize);
658         io.readbraw.in.offset = 0;
659         io.readbraw.in.mincnt = 20000;
660         io.readbraw.in.maxcnt = 30000;
661         status = smb_raw_read(cli->tree, &io);
662         CHECK_STATUS(status, NT_STATUS_OK);
663         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
664         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
665
666         printf("Trying locked region\n");
667         cli->session->pid++;
668         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
669                 printf("Failed to lock file at %d\n", __LINE__);
670                 ret = False;
671                 goto done;
672         }
673         cli->session->pid--;
674         memset(buf, 0, maxsize);
675         io.readbraw.in.offset = 0;
676         io.readbraw.in.mincnt = 100;
677         io.readbraw.in.maxcnt = 200;
678         status = smb_raw_read(cli->tree, &io);
679         CHECK_STATUS(status, NT_STATUS_OK);
680         CHECK_VALUE(io.readbraw.out.nread, 0);
681
682         printf("Trying locked region with timeout\n");
683         memset(buf, 0, maxsize);
684         io.readbraw.in.offset = 0;
685         io.readbraw.in.mincnt = 100;
686         io.readbraw.in.maxcnt = 200;
687         io.readbraw.in.timeout = 10000;
688         status = smb_raw_read(cli->tree, &io);
689         CHECK_STATUS(status, NT_STATUS_OK);
690         CHECK_VALUE(io.readbraw.out.nread, 0);
691
692         printf("Trying large offset read\n");
693         io.readbraw.in.offset = ((uint64_t)0x2) << 32;
694         io.readbraw.in.mincnt = 10;
695         io.readbraw.in.maxcnt = 10;
696         io.readbraw.in.timeout = 0;
697         status = smb_raw_read(cli->tree, &io);
698         CHECK_STATUS(status, NT_STATUS_OK);
699         CHECK_VALUE(io.readbraw.out.nread, 0);
700
701 done:
702         smbcli_close(cli->tree, fnum);
703         smbcli_deltree(cli->tree, BASEDIR);
704         return ret;
705 }
706
707
708 /* 
709    basic testing of read calls
710 */
711 BOOL torture_raw_read(void)
712 {
713         struct smbcli_state *cli;
714         BOOL ret = True;
715         TALLOC_CTX *mem_ctx;
716
717         if (!torture_open_connection(&cli)) {
718                 return False;
719         }
720
721         mem_ctx = talloc_init("torture_raw_read");
722
723         if (!test_read(cli, mem_ctx)) {
724                 ret = False;
725         }
726
727         if (!test_readx(cli, mem_ctx)) {
728                 ret = False;
729         }
730
731         if (!test_lockread(cli, mem_ctx)) {
732                 ret = False;
733         }
734
735         if (!test_readbraw(cli, mem_ctx)) {
736                 ret = False;
737         }
738
739         torture_close_connection(cli);
740         talloc_destroy(mem_ctx);
741         return ret;
742 }