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