This commit was generated by cvs2svn to compensate for changes in r30,
[samba.git] / source4 / libcli / raw / rawfile.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client file operations
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Jeremy Allison 2001-2002
6    Copyright (C) James Myers 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 #define SETUP_REQUEST(cmd, wct, buflen) do { \
26         req = cli_request_setup(tree, cmd, wct, buflen); \
27         if (!req) return NULL; \
28 } while (0)
29
30
31 /****************************************************************************
32  Rename a file - async interface
33 ****************************************************************************/
34 struct cli_request *smb_raw_rename_send(struct cli_tree *tree,
35                                         struct smb_rename *parms)
36 {
37         struct cli_request *req; 
38
39         SETUP_REQUEST(SMBmv, 1, 0);
40         
41         SSVAL(req->out.vwv, VWV(0), parms->in.attrib);
42         
43         cli_req_append_ascii4(req, parms->in.pattern1, STR_TERMINATE);
44         cli_req_append_ascii4(req, parms->in.pattern2, STR_TERMINATE);
45
46         if (!cli_request_send(req)) {
47                 cli_request_destroy(req);
48                 return NULL;
49         }
50
51         return req;
52 }
53
54 /****************************************************************************
55  Rename a file - sync interface
56 ****************************************************************************/
57 NTSTATUS smb_raw_rename(struct cli_tree *tree,
58                         struct smb_rename *parms)
59 {
60         struct cli_request *req = smb_raw_rename_send(tree, parms);
61         return cli_request_simple_recv(req);
62 }
63
64
65 /****************************************************************************
66  Delete a file - async interface
67 ****************************************************************************/
68 struct cli_request *smb_raw_unlink_send(struct cli_tree *tree,
69                                         struct smb_unlink *parms)
70 {
71         struct cli_request *req; 
72
73         SETUP_REQUEST(SMBunlink, 1, 0);
74
75         SSVAL(req->out.vwv, VWV(0), parms->in.attrib);
76         cli_req_append_ascii4(req, parms->in.pattern, STR_TERMINATE);
77
78         if (!cli_request_send(req)) {
79                 cli_request_destroy(req);
80                 return NULL;
81         }
82         return req;
83 }
84
85 /*
86   delete a file - sync interface
87 */
88 NTSTATUS smb_raw_unlink(struct cli_tree *tree,
89                         struct smb_unlink *parms)
90 {
91         struct cli_request *req = smb_raw_unlink_send(tree, parms);
92         return cli_request_simple_recv(req);
93 }
94
95
96 /****************************************************************************
97  create a directory  using TRANSACT2_MKDIR - async interface
98 ****************************************************************************/
99 static struct cli_request *smb_raw_t2mkdir_send(struct cli_tree *tree, 
100                                                 union smb_mkdir *parms)
101 {
102         struct smb_trans2 t2;
103         uint16 setup = TRANSACT2_MKDIR;
104         TALLOC_CTX *mem_ctx;
105         struct cli_request *req;
106         uint16 data_total;
107
108         mem_ctx = talloc_init("t2mkdir");
109
110         data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
111
112         t2.in.max_param = 0;
113         t2.in.max_data = 0;
114         t2.in.max_setup = 0;
115         t2.in.flags = 0;
116         t2.in.timeout = 0;
117         t2.in.setup_count = 1;
118         t2.in.setup = &setup;
119         t2.in.params = data_blob_talloc(mem_ctx, NULL, 4);
120         t2.in.data = data_blob_talloc(mem_ctx, NULL, data_total);
121
122         SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */
123
124         cli_blob_append_string(tree->session, mem_ctx, 
125                                &t2.in.params, parms->t2mkdir.in.path, 0);
126
127         ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
128
129         req = smb_raw_trans2_send(tree, &t2);
130
131         talloc_destroy(mem_ctx);
132
133         return req;
134 }
135
136 /****************************************************************************
137  Create a directory - async interface
138 ****************************************************************************/
139 struct cli_request *smb_raw_mkdir_send(struct cli_tree *tree,
140                                        union smb_mkdir *parms)
141 {
142         struct cli_request *req; 
143
144         if (parms->generic.level == RAW_MKDIR_T2MKDIR) {
145                 return smb_raw_t2mkdir_send(tree, parms);
146         }
147
148         if (parms->generic.level != RAW_MKDIR_MKDIR) {
149                 return NULL;
150         }
151
152         SETUP_REQUEST(SMBmkdir, 0, 0);
153         
154         cli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE);
155
156         if (!cli_request_send(req)) {
157                 return NULL;
158         }
159
160         return req;
161 }
162
163 /****************************************************************************
164  Create a directory - sync interface
165 ****************************************************************************/
166 NTSTATUS smb_raw_mkdir(struct cli_tree *tree,
167                        union smb_mkdir *parms)
168 {
169         struct cli_request *req = smb_raw_mkdir_send(tree, parms);
170         return cli_request_simple_recv(req);
171 }
172
173 /****************************************************************************
174  Remove a directory - async interface
175 ****************************************************************************/
176 struct cli_request *smb_raw_rmdir_send(struct cli_tree *tree,
177                                        struct smb_rmdir *parms)
178 {
179         struct cli_request *req; 
180
181         SETUP_REQUEST(SMBrmdir, 0, 0);
182         
183         cli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
184
185         if (!cli_request_send(req)) {
186                 cli_request_destroy(req);
187                 return NULL;
188         }
189
190         return req;
191 }
192
193 /****************************************************************************
194  Remove a directory - sync interface
195 ****************************************************************************/
196 NTSTATUS smb_raw_rmdir(struct cli_tree *tree,
197                        struct smb_rmdir *parms)
198 {
199         struct cli_request *req = smb_raw_rmdir_send(tree, parms);
200         return cli_request_simple_recv(req);
201 }
202
203
204 /****************************************************************************
205  Open a file using TRANSACT2_OPEN - async send 
206 ****************************************************************************/
207 static struct cli_request *smb_raw_t2open_send(struct cli_tree *tree, 
208                                                union smb_open *parms)
209 {
210         struct smb_trans2 t2;
211         uint16 setup = TRANSACT2_OPEN;
212         TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open");
213         struct cli_request *req;
214         uint16 list_size;
215
216         list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas);
217
218         t2.in.max_param = 30;
219         t2.in.max_data = 0;
220         t2.in.max_setup = 0;
221         t2.in.flags = 0;
222         t2.in.timeout = 0;
223         t2.in.setup_count = 1;
224         t2.in.setup = &setup;
225         t2.in.params = data_blob_talloc(mem_ctx, NULL, 28);
226         t2.in.data = data_blob_talloc(mem_ctx, NULL, list_size);
227
228         SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags);
229         SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode);
230         SSVAL(t2.in.params.data, VWV(2), 0); /* reserved */
231         SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs);
232         put_dos_date(t2.in.params.data, VWV(4), parms->t2open.in.write_time);
233         SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func);
234         SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size);
235         SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout);
236         SIVAL(t2.in.params.data, VWV(11), 0);
237         SSVAL(t2.in.params.data, VWV(13), 0);
238
239         cli_blob_append_string(tree->session, mem_ctx, 
240                                &t2.in.params, parms->t2open.in.fname, 
241                                STR_TERMINATE);
242
243         ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas);
244
245         req = smb_raw_trans2_send(tree, &t2);
246
247         talloc_destroy(mem_ctx);
248
249         return req;
250 }
251
252
253 /****************************************************************************
254  Open a file using TRANSACT2_OPEN - async recv
255 ****************************************************************************/
256 static NTSTATUS smb_raw_t2open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
257 {
258         struct smb_trans2 t2;
259         NTSTATUS status;
260
261         status = smb_raw_trans2_recv(req, mem_ctx, &t2);
262         if (!NT_STATUS_IS_OK(status)) return status;
263
264         if (t2.out.params.length < 30) {
265                 return NT_STATUS_INFO_LENGTH_MISMATCH;
266         }
267
268         parms->t2open.out.fnum =        SVAL(t2.out.params.data, VWV(0));
269         parms->t2open.out.attrib =      SVAL(t2.out.params.data, VWV(1));
270         parms->t2open.out.write_time = make_unix_date3(t2.out.params.data + VWV(2));
271         parms->t2open.out.size =        IVAL(t2.out.params.data, VWV(4));
272         parms->t2open.out.access =      SVAL(t2.out.params.data, VWV(6));
273         parms->t2open.out.ftype =       SVAL(t2.out.params.data, VWV(7));
274         parms->t2open.out.devstate =    SVAL(t2.out.params.data, VWV(8));
275         parms->t2open.out.action =      SVAL(t2.out.params.data, VWV(9));
276         parms->t2open.out.unknown =     SVAL(t2.out.params.data, VWV(10));
277
278         return NT_STATUS_OK;
279 }
280
281 /****************************************************************************
282  Open a file - async send
283 ****************************************************************************/
284 struct cli_request *smb_raw_open_send(struct cli_tree *tree, union smb_open *parms)
285 {
286         int len;
287         struct cli_request *req = NULL; 
288
289         switch (parms->open.level) {
290         case RAW_OPEN_T2OPEN:
291                 return smb_raw_t2open_send(tree, parms);
292
293         case RAW_OPEN_OPEN:
294                 SETUP_REQUEST(SMBopen, 2, 0);
295                 SSVAL(req->out.vwv, VWV(0), parms->open.in.flags);
296                 SSVAL(req->out.vwv, VWV(1), parms->open.in.search_attrs);
297                 cli_req_append_ascii4(req, parms->open.in.fname, STR_TERMINATE);
298                 break;
299                 
300         case RAW_OPEN_OPENX:
301                 SETUP_REQUEST(SMBopenX, 15, 0);
302                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
303                 SSVAL(req->out.vwv, VWV(1), 0);
304                 SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
305                 SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
306                 SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
307                 SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
308                 put_dos_date3(req->out.vwv, VWV(6), parms->openx.in.write_time);
309                 SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
310                 SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
311                 SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
312                 SIVAL(req->out.vwv, VWV(13),0); /* reserved */
313                 cli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE);
314                 break;
315                 
316         case RAW_OPEN_MKNEW:
317                 SETUP_REQUEST(SMBmknew, 3, 0);
318                 SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib);
319                 put_dos_date3(req->out.vwv, VWV(1), parms->mknew.in.write_time);
320                 cli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE);
321                 break;
322                 
323         case RAW_OPEN_CTEMP:
324                 SETUP_REQUEST(SMBctemp, 3, 0);
325                 SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib);
326                 put_dos_date3(req->out.vwv, VWV(1), parms->ctemp.in.write_time);
327                 cli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE);
328                 break;
329                 
330         case RAW_OPEN_SPLOPEN:
331                 SETUP_REQUEST(SMBsplopen, 2, 0);
332                 SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length);
333                 SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode);
334                 break;
335                 
336         case RAW_OPEN_NTCREATEX:
337                 SETUP_REQUEST(SMBntcreateX, 24, 0);
338                 SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
339                 SSVAL(req->out.vwv, VWV(1),0);
340                 SCVAL(req->out.vwv, VWV(2),0); /* padding */
341                 SIVAL(req->out.vwv,  7, parms->ntcreatex.in.flags);
342                 SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid);
343                 SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask);
344                 SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size);
345                 SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr);
346                 SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access);
347                 SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition);
348                 SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options);
349                 SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation);
350                 SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags);
351                 
352                 cli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len);
353                 SSVAL(req->out.vwv, 5, len);
354                 break;
355         }
356
357         if (!cli_request_send(req)) {
358                 cli_request_destroy(req);
359                 return NULL;
360         }
361
362         return req;
363 }
364
365 /****************************************************************************
366  Open a file - async recv
367 ****************************************************************************/
368 NTSTATUS smb_raw_open_recv(struct cli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
369 {
370         if (!cli_request_receive(req) ||
371             cli_request_is_error(req)) {
372                 goto failed;
373         }
374
375         switch (parms->open.level) {
376         case RAW_OPEN_T2OPEN:
377                 return smb_raw_t2open_recv(req, mem_ctx, parms);
378
379         case RAW_OPEN_OPEN:
380                 CLI_CHECK_WCT(req, 7);
381                 parms->open.out.fnum = SVAL(req->in.vwv, VWV(0));
382                 parms->open.out.attrib = SVAL(req->in.vwv, VWV(1));
383                 parms->open.out.write_time = make_unix_date3(req->in.vwv + VWV(2));
384                 parms->open.out.size = IVAL(req->in.vwv, VWV(4));
385                 parms->open.out.rmode = SVAL(req->in.vwv, VWV(6));
386                 break;
387
388         case RAW_OPEN_OPENX:
389                 CLI_CHECK_MIN_WCT(req, 15);
390                 parms->openx.out.fnum = SVAL(req->in.vwv, VWV(2));
391                 parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3));
392                 parms->openx.out.write_time = make_unix_date3(req->in.vwv + VWV(4));
393                 parms->openx.out.size = IVAL(req->in.vwv, VWV(6));
394                 parms->openx.out.access = SVAL(req->in.vwv, VWV(8));
395                 parms->openx.out.ftype = SVAL(req->in.vwv, VWV(9));
396                 parms->openx.out.devstate = SVAL(req->in.vwv, VWV(10));
397                 parms->openx.out.action = SVAL(req->in.vwv, VWV(11));
398                 parms->openx.out.unique_fid = IVAL(req->in.vwv, VWV(12));
399                 if (req->in.wct >= 19) {
400                         parms->openx.out.access_mask = IVAL(req->in.vwv, VWV(15));
401                         parms->openx.out.unknown =     IVAL(req->in.vwv, VWV(17));
402                 } else {
403                         parms->openx.out.access_mask = 0;
404                         parms->openx.out.unknown = 0;
405                 }
406                 break;
407
408         case RAW_OPEN_MKNEW:
409                 CLI_CHECK_WCT(req, 1);
410                 parms->mknew.out.fnum = SVAL(req->in.vwv, VWV(0));
411                 break;
412
413         case RAW_OPEN_CTEMP:
414                 CLI_CHECK_WCT(req, 1);
415                 parms->ctemp.out.fnum = SVAL(req->in.vwv, VWV(0));
416                 cli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
417                 break;
418
419         case RAW_OPEN_SPLOPEN:
420                 CLI_CHECK_WCT(req, 1);
421                 parms->splopen.out.fnum = SVAL(req->in.vwv, VWV(0));
422                 break;
423
424         case RAW_OPEN_NTCREATEX:
425                 CLI_CHECK_MIN_WCT(req, 34);
426                 parms->ntcreatex.out.oplock_level =              CVAL(req->in.vwv, 4);
427                 parms->ntcreatex.out.fnum =                      SVAL(req->in.vwv, 5);
428                 parms->ntcreatex.out.create_action =             IVAL(req->in.vwv, 7);
429                 parms->ntcreatex.out.create_time =   cli_pull_nttime(req->in.vwv, 11);
430                 parms->ntcreatex.out.access_time =   cli_pull_nttime(req->in.vwv, 19);
431                 parms->ntcreatex.out.write_time =    cli_pull_nttime(req->in.vwv, 27);
432                 parms->ntcreatex.out.change_time =   cli_pull_nttime(req->in.vwv, 35);
433                 parms->ntcreatex.out.attrib =                   IVAL(req->in.vwv, 43);
434                 parms->ntcreatex.out.alloc_size =               BVAL(req->in.vwv, 47);
435                 parms->ntcreatex.out.size =                     BVAL(req->in.vwv, 55);
436                 parms->ntcreatex.out.file_type =                SVAL(req->in.vwv, 63);
437                 parms->ntcreatex.out.ipc_state =                SVAL(req->in.vwv, 65);
438                 parms->ntcreatex.out.is_directory =             CVAL(req->in.vwv, 67);
439                 break;
440         }
441
442 failed:
443         return cli_request_destroy(req);
444 }
445
446
447 /****************************************************************************
448  Open a file - sync interface
449 ****************************************************************************/
450 NTSTATUS smb_raw_open(struct cli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms)
451 {
452         struct cli_request *req = smb_raw_open_send(tree, parms);
453         return smb_raw_open_recv(req, mem_ctx, parms);
454 }
455
456
457 /****************************************************************************
458  Close a file - async send
459 ****************************************************************************/
460 struct cli_request *smb_raw_close_send(struct cli_tree *tree, union smb_close *parms)
461 {
462         struct cli_request *req; 
463
464         switch (parms->generic.level) {
465         case RAW_CLOSE_GENERIC:
466                 return NULL;
467
468         case RAW_CLOSE_CLOSE:
469                 SETUP_REQUEST(SMBclose, 3, 0);
470                 SSVAL(req->out.vwv, VWV(0), parms->close.in.fnum);
471                 put_dos_date3(req->out.vwv, VWV(1), parms->close.in.write_time);
472                 break;
473
474         case RAW_CLOSE_SPLCLOSE:
475                 SETUP_REQUEST(SMBsplclose, 3, 0);
476                 SSVAL(req->out.vwv, VWV(0), parms->splclose.in.fnum);
477                 SIVAL(req->out.vwv, VWV(1), 0); /* reserved */
478                 break;
479         }
480
481         if (!req) return NULL;
482
483         if (!cli_request_send(req)) {
484                 cli_request_destroy(req);
485                 return NULL;
486         }
487
488         return req;
489 }
490
491
492 /****************************************************************************
493  Close a file - sync interface
494 ****************************************************************************/
495 NTSTATUS smb_raw_close(struct cli_tree *tree, union smb_close *parms)
496 {
497         struct cli_request *req = smb_raw_close_send(tree, parms);
498         return cli_request_simple_recv(req);
499 }
500
501
502 /****************************************************************************
503  Locking calls - async interface
504 ****************************************************************************/
505 struct cli_request *smb_raw_lock_send(struct cli_tree *tree, union smb_lock *parms)
506 {
507         struct cli_request *req; 
508
509         switch (parms->generic.level) {
510         case RAW_LOCK_GENERIC:
511                 return NULL;
512
513         case RAW_LOCK_LOCK:
514                 SETUP_REQUEST(SMBlock, 5, 0);
515                 SSVAL(req->out.vwv, VWV(0), parms->lock.in.fnum);
516                 SIVAL(req->out.vwv, VWV(1), parms->lock.in.count);
517                 SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset);
518                 break;
519                 
520         case RAW_LOCK_UNLOCK:
521                 SETUP_REQUEST(SMBunlock, 5, 0);
522                 SSVAL(req->out.vwv, VWV(0), parms->unlock.in.fnum);
523                 SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count);
524                 SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset);
525                 break;
526                 
527         case RAW_LOCK_LOCKX: {
528                 struct smb_lock_entry *lockp;
529                 uint_t lck_size = (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES)? 20 : 10;
530                 uint_t lock_count = parms->lockx.in.ulock_cnt + parms->lockx.in.lock_cnt;
531                 int i;
532
533                 SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count);
534                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
535                 SSVAL(req->out.vwv, VWV(1), 0);
536                 SSVAL(req->out.vwv, VWV(2), parms->lockx.in.fnum);
537                 SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode);
538                 SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout);
539                 SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt);
540                 SSVAL(req->out.vwv, VWV(7), parms->lockx.in.lock_cnt);
541                 
542                 /* copy in all the locks */
543                 lockp = &parms->lockx.in.locks[0];
544                 for (i = 0; i < lock_count; i++) {
545                         char *p = req->out.data + lck_size * i;
546                         SSVAL(p, 0, lockp[i].pid);
547                         if (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) {
548                                 SSVAL(p,  2, 0); /* reserved */
549                                 SIVAL(p,  4, lockp[i].offset>>32);
550                                 SIVAL(p,  8, lockp[i].offset);
551                                 SIVAL(p, 12, lockp[i].count>>32);
552                                 SIVAL(p, 16, lockp[i].count);
553                         } else {
554                                 SIVAL(p, 2, lockp[i].offset);
555                                 SIVAL(p, 6, lockp[i].count);
556                         }
557                 }       
558         }
559         }
560
561         if (!cli_request_send(req)) {
562                 cli_request_destroy(req);
563                 return NULL;
564         }
565
566         return req;
567 }
568
569 /****************************************************************************
570  Locking calls - sync interface
571 ****************************************************************************/
572 NTSTATUS smb_raw_lock(struct cli_tree *tree, union smb_lock *parms)
573 {
574         struct cli_request *req = smb_raw_lock_send(tree, parms);
575         return cli_request_simple_recv(req);
576 }
577         
578
579 /****************************************************************************
580  Check for existence of a dir - async send
581 ****************************************************************************/
582 struct cli_request *smb_raw_chkpath_send(struct cli_tree *tree, struct smb_chkpath *parms)
583 {
584         struct cli_request *req; 
585
586         SETUP_REQUEST(SMBchkpth, 0, 0);
587
588         cli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
589
590         if (!cli_request_send(req)) {
591                 cli_request_destroy(req);
592                 return NULL;
593         }
594
595         return req;
596 }
597
598 /****************************************************************************
599  Check for existence of a dir - sync interface
600 ****************************************************************************/
601 NTSTATUS smb_raw_chkpath(struct cli_tree *tree, struct smb_chkpath *parms)
602 {
603         struct cli_request *req = smb_raw_chkpath_send(tree, parms);
604         return cli_request_simple_recv(req);
605 }
606
607
608
609
610 /****************************************************************************
611  flush a file - async send
612  a flush to fnum 0xFFFF will flush all files
613 ****************************************************************************/
614 struct cli_request *smb_raw_flush_send(struct cli_tree *tree, struct smb_flush *parms)
615 {
616         struct cli_request *req; 
617
618         SETUP_REQUEST(SMBflush, 1, 0);
619         SSVAL(req->out.vwv, VWV(0), parms->in.fnum);
620
621         if (!cli_request_send(req)) {
622                 cli_request_destroy(req);
623                 return NULL;
624         }
625
626         return req;
627 }
628
629
630 /****************************************************************************
631  flush a file - sync interface
632 ****************************************************************************/
633 NTSTATUS smb_raw_flush(struct cli_tree *tree, struct smb_flush *parms)
634 {
635         struct cli_request *req = smb_raw_flush_send(tree, parms);
636         return cli_request_simple_recv(req);
637 }
638
639
640 /****************************************************************************
641  seek a file - async send
642 ****************************************************************************/
643 struct cli_request *smb_raw_seek_send(struct cli_tree *tree,
644                                       struct smb_seek *parms)
645 {
646         struct cli_request *req; 
647
648         SETUP_REQUEST(SMBlseek, 4, 0);
649
650         SSVAL(req->out.vwv, VWV(0), parms->in.fnum);
651         SSVAL(req->out.vwv, VWV(1), parms->in.mode);
652         SIVALS(req->out.vwv, VWV(2), parms->in.offset);
653
654         if (!cli_request_send(req)) {
655                 cli_request_destroy(req);
656                 return NULL;
657         }
658         return req;
659 }
660
661 /****************************************************************************
662  seek a file - async receive
663 ****************************************************************************/
664 NTSTATUS smb_raw_seek_recv(struct cli_request *req,
665                                       struct smb_seek *parms)
666 {
667         if (!cli_request_receive(req) ||
668             cli_request_is_error(req)) {
669                 return cli_request_destroy(req);
670         }
671
672         CLI_CHECK_WCT(req, 2);  
673         parms->out.offset = IVAL(req->in.vwv, VWV(0));
674
675 failed: 
676         return cli_request_destroy(req);
677 }
678
679 /*
680   seek a file - sync interface
681 */
682 NTSTATUS smb_raw_seek(struct cli_tree *tree,
683                       struct smb_seek *parms)
684 {
685         struct cli_request *req = smb_raw_seek_send(tree, parms);
686         return smb_raw_seek_recv(req, parms);
687 }