r14173: change smb interface structures to always use
[jelmer/samba4-debian.git] / source / torture / raw / seek.c
1 /* 
2    Unix SMB/CIFS implementation.
3    seek test suite
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 "torture/torture.h"
23 #include "system/filesys.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "libcli/libcli.h"
26
27 #define CHECK_STATUS(status, correct) do { \
28         if (!NT_STATUS_EQUAL(status, correct)) { \
29                 printf("(%d) Incorrect status %s - should be %s\n", \
30                        __LINE__, nt_errstr(status), nt_errstr(correct)); \
31                 ret = False; \
32                 goto done; \
33         }} while (0)
34
35 #define CHECK_VALUE(v, correct) do { \
36         if ((v) != (correct)) { \
37                 printf("(%d) Incorrect value %s=%d - should be %d\n", \
38                        __LINE__, #v, (int)v, (int)correct); \
39                 ret = False; \
40                 goto done; \
41         }} while (0)
42
43 #define BASEDIR "\\testseek"
44
45 /*
46   test seek ops
47 */
48 static BOOL test_seek(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
49 {
50         union smb_seek io;
51         union smb_fileinfo finfo;
52         union smb_setfileinfo sfinfo;
53         NTSTATUS status;
54         BOOL ret = True;
55         int fnum, fnum2;
56         const char *fname = BASEDIR "\\test.txt";
57         uint8_t c[2];
58
59         if (!torture_setup_dir(cli, BASEDIR)) {
60                 return False;
61         }
62
63         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
64         if (fnum == -1) {
65                 printf("Failed to open test.txt - %s\n", smbcli_errstr(cli->tree));
66                 ret = False;
67                 goto done;
68         }
69
70         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
71         finfo.position_information.file.fnum = fnum;
72         
73         printf("Trying bad handle\n");
74         io.lseek.file.fnum = fnum+1;
75         io.lseek.in.mode = SEEK_MODE_START;
76         io.lseek.in.offset = 0;
77         status = smb_raw_seek(cli->tree, &io);
78         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
79
80         printf("Trying simple seek\n");
81         io.lseek.file.fnum = fnum;
82         io.lseek.in.mode = SEEK_MODE_START;
83         io.lseek.in.offset = 17;
84         status = smb_raw_seek(cli->tree, &io);
85         CHECK_STATUS(status, NT_STATUS_OK);
86         CHECK_VALUE(io.lseek.out.offset, 17);
87         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
88         CHECK_STATUS(status, NT_STATUS_OK);
89         CHECK_VALUE(finfo.position_information.out.position, 0);
90         
91         printf("Trying relative seek\n");
92         io.lseek.file.fnum = fnum;
93         io.lseek.in.mode = SEEK_MODE_CURRENT;
94         io.lseek.in.offset = -3;
95         status = smb_raw_seek(cli->tree, &io);
96         CHECK_STATUS(status, NT_STATUS_OK);
97         CHECK_VALUE(io.lseek.out.offset, 14);
98
99         printf("Trying end seek\n");
100         io.lseek.file.fnum = fnum;
101         io.lseek.in.mode = SEEK_MODE_END;
102         io.lseek.in.offset = 0;
103         status = smb_raw_seek(cli->tree, &io);
104         CHECK_STATUS(status, NT_STATUS_OK);
105         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
106         finfo.all_info.file.fnum = fnum;
107         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
108         CHECK_STATUS(status, NT_STATUS_OK);
109         CHECK_VALUE(io.lseek.out.offset, finfo.all_info.out.size);
110
111         printf("Trying max seek\n");
112         io.lseek.file.fnum = fnum;
113         io.lseek.in.mode = SEEK_MODE_START;
114         io.lseek.in.offset = -1;
115         status = smb_raw_seek(cli->tree, &io);
116         CHECK_STATUS(status, NT_STATUS_OK);
117         CHECK_VALUE(io.lseek.out.offset, 0xffffffff);
118
119         printf("Testing position information change\n");
120         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
121         finfo.position_information.file.fnum = fnum;
122         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
123         CHECK_STATUS(status, NT_STATUS_OK);
124         CHECK_VALUE(finfo.position_information.out.position, 0);
125
126         printf("Trying max overflow\n");
127         io.lseek.file.fnum = fnum;
128         io.lseek.in.mode = SEEK_MODE_CURRENT;
129         io.lseek.in.offset = 1000;
130         status = smb_raw_seek(cli->tree, &io);
131         CHECK_STATUS(status, NT_STATUS_OK);
132         CHECK_VALUE(io.lseek.out.offset, 999);
133
134         printf("Testing position information change\n");
135         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
136         finfo.position_information.file.fnum = fnum;
137         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
138         CHECK_STATUS(status, NT_STATUS_OK);
139         CHECK_VALUE(finfo.position_information.out.position, 0);
140
141         printf("trying write to update offset\n");
142         ZERO_STRUCT(c);
143         if (smbcli_write(cli->tree, fnum, 0, c, 0, 2) != 2) {
144                 printf("Write failed - %s\n", smbcli_errstr(cli->tree));
145                 ret = False;
146                 goto done;              
147         }
148
149         printf("Testing position information change\n");
150         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
151         finfo.position_information.file.fnum = fnum;
152         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
153         CHECK_STATUS(status, NT_STATUS_OK);
154         CHECK_VALUE(finfo.position_information.out.position, 0);
155
156         io.lseek.file.fnum = fnum;
157         io.lseek.in.mode = SEEK_MODE_CURRENT;
158         io.lseek.in.offset = 0;
159         status = smb_raw_seek(cli->tree, &io);
160         CHECK_STATUS(status, NT_STATUS_OK);
161         CHECK_VALUE(io.lseek.out.offset, 2);
162         
163         if (smbcli_read(cli->tree, fnum, c, 0, 1) != 1) {
164                 printf("Read failed - %s\n", smbcli_errstr(cli->tree));
165                 ret = False;
166                 goto done;              
167         }
168
169         printf("Testing position information change\n");
170         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
171         finfo.position_information.file.fnum = fnum;
172         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
173         CHECK_STATUS(status, NT_STATUS_OK);
174         CHECK_VALUE(finfo.position_information.out.position, 1);
175
176         status = smb_raw_seek(cli->tree, &io);
177         CHECK_STATUS(status, NT_STATUS_OK);
178         CHECK_VALUE(io.lseek.out.offset, 1);
179
180         printf("Testing position information\n");
181         fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
182         if (fnum2 == -1) {
183                 printf("2nd open failed - %s\n", smbcli_errstr(cli->tree));
184                 ret = False;
185                 goto done;
186         }
187         sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
188         sfinfo.position_information.file.fnum = fnum2;
189         sfinfo.position_information.in.position = 25;
190         status = smb_raw_setfileinfo(cli->tree, &sfinfo);
191         CHECK_STATUS(status, NT_STATUS_OK);
192
193         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
194         finfo.position_information.file.fnum = fnum2;
195         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
196         CHECK_STATUS(status, NT_STATUS_OK);
197         CHECK_VALUE(finfo.position_information.out.position, 25);
198
199         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
200         finfo.position_information.file.fnum = fnum;
201         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
202         CHECK_STATUS(status, NT_STATUS_OK);
203         CHECK_VALUE(finfo.position_information.out.position, 1);
204
205         printf("position_information via paths\n");
206
207         sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
208         sfinfo.position_information.file.path = fname;
209         sfinfo.position_information.in.position = 32;
210         status = smb_raw_setpathinfo(cli->tree, &sfinfo);
211         CHECK_STATUS(status, NT_STATUS_OK);
212
213         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
214         finfo.position_information.file.fnum = fnum2;
215         status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
216         CHECK_STATUS(status, NT_STATUS_OK);
217         CHECK_VALUE(finfo.position_information.out.position, 25);
218
219         finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
220         finfo.position_information.file.path = fname;
221         status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
222         CHECK_STATUS(status, NT_STATUS_OK);
223         CHECK_VALUE(finfo.position_information.out.position, 0);
224         
225
226 done:
227         smb_raw_exit(cli->session);
228         smbcli_deltree(cli->tree, BASEDIR);
229         return ret;
230 }
231
232
233 /* 
234    basic testing of seek calls
235 */
236 BOOL torture_raw_seek(void)
237 {
238         struct smbcli_state *cli;
239         BOOL ret = True;
240         TALLOC_CTX *mem_ctx;
241
242         if (!torture_open_connection(&cli)) {
243                 return False;
244         }
245
246         mem_ctx = talloc_init("torture_raw_seek");
247
248         if (!test_seek(cli, mem_ctx)) {
249                 ret = False;
250         }
251
252         torture_close_connection(cli);
253         talloc_free(mem_ctx);
254         return ret;
255 }