use 32 bit locking if client doesn't do 64 bit
[tprouty/samba.git] / source3 / libsmb / clifile.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    client file operations
5    Copyright (C) Andrew Tridgell 1994-1998
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 #define NO_SYSLOG
23
24 #include "includes.h"
25
26 /****************************************************************************
27 rename a file
28 ****************************************************************************/
29 BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
30 {
31         char *p;
32
33         memset(cli->outbuf,'\0',smb_size);
34         memset(cli->inbuf,'\0',smb_size);
35
36         set_message(cli->outbuf,1, 0, True);
37
38         CVAL(cli->outbuf,smb_com) = SMBmv;
39         SSVAL(cli->outbuf,smb_tid,cli->cnum);
40         cli_setup_packet(cli);
41
42         SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
43
44         p = smb_buf(cli->outbuf);
45         *p++ = 4;
46         p += clistr_push(cli, p, fname_src, -1, 
47                          STR_TERMINATE);
48         *p++ = 4;
49         p += clistr_push(cli, p, fname_dst, -1, 
50                          STR_TERMINATE);
51
52         cli_setup_bcc(cli, p);
53
54         cli_send_smb(cli);
55         if (!cli_receive_smb(cli)) {
56                 return False;
57         }
58
59         if (CVAL(cli->inbuf,smb_rcls) != 0) {
60                 return False;
61         }
62
63         return True;
64 }
65
66 /****************************************************************************
67 delete a file
68 ****************************************************************************/
69 BOOL cli_unlink(struct cli_state *cli, char *fname)
70 {
71         char *p;
72
73         memset(cli->outbuf,'\0',smb_size);
74         memset(cli->inbuf,'\0',smb_size);
75
76         set_message(cli->outbuf,1, 0,True);
77
78         CVAL(cli->outbuf,smb_com) = SMBunlink;
79         SSVAL(cli->outbuf,smb_tid,cli->cnum);
80         cli_setup_packet(cli);
81
82         SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN);
83   
84         p = smb_buf(cli->outbuf);
85         *p++ = 4;      
86         p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
87
88         cli_setup_bcc(cli, p);
89         cli_send_smb(cli);
90         if (!cli_receive_smb(cli)) {
91                 return False;
92         }
93
94         if (CVAL(cli->inbuf,smb_rcls) != 0) {
95                 return False;
96         }
97
98         return True;
99 }
100
101 /****************************************************************************
102 create a directory
103 ****************************************************************************/
104 BOOL cli_mkdir(struct cli_state *cli, char *dname)
105 {
106         char *p;
107
108         memset(cli->outbuf,'\0',smb_size);
109         memset(cli->inbuf,'\0',smb_size);
110
111         set_message(cli->outbuf,0, 0,True);
112
113         CVAL(cli->outbuf,smb_com) = SMBmkdir;
114         SSVAL(cli->outbuf,smb_tid,cli->cnum);
115         cli_setup_packet(cli);
116
117         p = smb_buf(cli->outbuf);
118         *p++ = 4;      
119         p += clistr_push(cli, p, dname, -1, STR_TERMINATE);
120
121         cli_setup_bcc(cli, p);
122
123         cli_send_smb(cli);
124         if (!cli_receive_smb(cli)) {
125                 return False;
126         }
127
128         if (CVAL(cli->inbuf,smb_rcls) != 0) {
129                 return False;
130         }
131
132         return True;
133 }
134
135 /****************************************************************************
136 remove a directory
137 ****************************************************************************/
138 BOOL cli_rmdir(struct cli_state *cli, char *dname)
139 {
140         char *p;
141
142         memset(cli->outbuf,'\0',smb_size);
143         memset(cli->inbuf,'\0',smb_size);
144
145         set_message(cli->outbuf,0, 0, True);
146
147         CVAL(cli->outbuf,smb_com) = SMBrmdir;
148         SSVAL(cli->outbuf,smb_tid,cli->cnum);
149         cli_setup_packet(cli);
150
151         p = smb_buf(cli->outbuf);
152         *p++ = 4;      
153         p += clistr_push(cli, p, dname, -1, STR_TERMINATE);
154
155         cli_setup_bcc(cli, p);
156
157         cli_send_smb(cli);
158         if (!cli_receive_smb(cli)) {
159                 return False;
160         }
161
162         if (CVAL(cli->inbuf,smb_rcls) != 0) {
163                 return False;
164         }
165
166         return True;
167 }
168
169 /****************************************************************************
170  Set or clear the delete on close flag.
171 ****************************************************************************/
172
173 int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
174 {
175         int data_len = 1;
176         int param_len = 6;
177         uint16 setup = TRANSACT2_SETFILEINFO;
178         pstring param;
179         unsigned char data;
180         char *rparam=NULL, *rdata=NULL;
181
182         memset(param, 0, param_len);
183         SSVAL(param,0,fnum);
184         SSVAL(param,2,SMB_SET_FILE_DISPOSITION_INFO);
185
186         data = flag ? 1 : 0;
187
188         if (!cli_send_trans(cli, SMBtrans2,
189                                                 NULL,                        /* name */
190                                                 -1, 0,                          /* fid, flags */
191                                                 &setup, 1, 0,                   /* setup, length, max */
192                                                 param, param_len, 2,            /* param, length, max */
193                                                 (char *)&data,  data_len, cli->max_xmit /* data, length, max */
194                                                 )) {
195                 return False;
196         }
197
198         if (!cli_receive_trans(cli, SMBtrans2,
199                                                 &rparam, &param_len,
200                                                 &rdata, &data_len)) {
201                 return False;
202         }
203
204         if (rdata) free(rdata);
205         if (rparam) free(rparam);
206
207         return True;
208 }
209
210 /****************************************************************************
211  open a file - exposing the full horror of the NT API :-).
212  Used in smbtorture.
213 ****************************************************************************/
214
215 int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess,
216                  uint32 FileAttributes, uint32 ShareAccess,
217                  uint32 CreateDisposition, uint32 CreateOptions)
218 {
219         char *p;
220         int len;
221
222         memset(cli->outbuf,'\0',smb_size);
223         memset(cli->inbuf,'\0',smb_size);
224
225         set_message(cli->outbuf,24,0,True);
226
227         CVAL(cli->outbuf,smb_com) = SMBntcreateX;
228         SSVAL(cli->outbuf,smb_tid,cli->cnum);
229         cli_setup_packet(cli);
230
231         SSVAL(cli->outbuf,smb_vwv0,0xFF);
232         if (cli->use_oplocks)
233                 SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK);
234         else
235                 SIVAL(cli->outbuf,smb_ntcreate_Flags, 0);
236         SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0);
237         SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess);
238         SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, FileAttributes);
239         SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, ShareAccess);
240         SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition);
241         SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions);
242         SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02);
243
244         p = smb_buf(cli->outbuf);
245         /* this alignment and termination is critical for netapp filers. Don't change */
246         p += clistr_align_out(cli, p, 0);
247         len = clistr_push(cli, p, fname, -1, 0);
248         p += len;
249         SSVAL(cli->outbuf,smb_ntcreate_NameLength, len);
250         /* sigh. this copes with broken netapp filer behaviour */
251         p += clistr_push(cli, p, "", -1, STR_TERMINATE);
252
253         cli_setup_bcc(cli, p);
254
255         cli_send_smb(cli);
256         if (!cli_receive_smb(cli)) {
257                 return -1;
258         }
259
260         if (CVAL(cli->inbuf,smb_rcls) != 0) {
261                 return -1;
262         }
263
264         return SVAL(cli->inbuf,smb_vwv2 + 1);
265 }
266
267 /****************************************************************************
268 open a file
269 ****************************************************************************/
270
271 int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess)
272 {
273         return cli_nt_create_full(cli, fname, DesiredAccess, 0,
274                                 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0);
275 }
276
277 /****************************************************************************
278 open a file
279 WARNING: if you open with O_WRONLY then getattrE won't work!
280 ****************************************************************************/
281 int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
282 {
283         char *p;
284         unsigned openfn=0;
285         unsigned accessmode=0;
286
287         if (flags & O_CREAT)
288                 openfn |= (1<<4);
289         if (!(flags & O_EXCL)) {
290                 if (flags & O_TRUNC)
291                         openfn |= (1<<1);
292                 else
293                         openfn |= (1<<0);
294         }
295
296         accessmode = (share_mode<<4);
297
298         if ((flags & O_ACCMODE) == O_RDWR) {
299                 accessmode |= 2;
300         } else if ((flags & O_ACCMODE) == O_WRONLY) {
301                 accessmode |= 1;
302         } 
303
304 #if defined(O_SYNC)
305         if ((flags & O_SYNC) == O_SYNC) {
306                 accessmode |= (1<<14);
307         }
308 #endif /* O_SYNC */
309
310         if (share_mode == DENY_FCB) {
311                 accessmode = 0xFF;
312         }
313
314         memset(cli->outbuf,'\0',smb_size);
315         memset(cli->inbuf,'\0',smb_size);
316
317         set_message(cli->outbuf,15,0,True);
318
319         CVAL(cli->outbuf,smb_com) = SMBopenX;
320         SSVAL(cli->outbuf,smb_tid,cli->cnum);
321         cli_setup_packet(cli);
322
323         SSVAL(cli->outbuf,smb_vwv0,0xFF);
324         SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
325         SSVAL(cli->outbuf,smb_vwv3,accessmode);
326         SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
327         SSVAL(cli->outbuf,smb_vwv5,0);
328         SSVAL(cli->outbuf,smb_vwv8,openfn);
329
330         if (cli->use_oplocks) {
331                 /* if using oplocks then ask for a batch oplock via
332                    core and extended methods */
333                 CVAL(cli->outbuf,smb_flg) |= 
334                         FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
335                 SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
336         }
337   
338         p = smb_buf(cli->outbuf);
339         p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
340
341         cli_setup_bcc(cli, p);
342
343         cli_send_smb(cli);
344         if (!cli_receive_smb(cli)) {
345                 return -1;
346         }
347
348         if (CVAL(cli->inbuf,smb_rcls) != 0) {
349                 return -1;
350         }
351
352         return SVAL(cli->inbuf,smb_vwv2);
353 }
354
355
356
357
358 /****************************************************************************
359   close a file
360 ****************************************************************************/
361 BOOL cli_close(struct cli_state *cli, int fnum)
362 {
363         memset(cli->outbuf,'\0',smb_size);
364         memset(cli->inbuf,'\0',smb_size);
365
366         set_message(cli->outbuf,3,0,True);
367
368         CVAL(cli->outbuf,smb_com) = SMBclose;
369         SSVAL(cli->outbuf,smb_tid,cli->cnum);
370         cli_setup_packet(cli);
371
372         SSVAL(cli->outbuf,smb_vwv0,fnum);
373         SIVALS(cli->outbuf,smb_vwv1,-1);
374
375         cli_send_smb(cli);
376         if (!cli_receive_smb(cli)) {
377                 return False;
378         }
379
380         if (CVAL(cli->inbuf,smb_rcls) != 0) {
381                 return False;
382         }
383
384         return True;
385 }
386
387
388 /****************************************************************************
389   lock a file
390 ****************************************************************************/
391 BOOL cli_lock(struct cli_state *cli, int fnum, 
392               uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
393 {
394         char *p;
395         int saved_timeout = cli->timeout;
396
397         memset(cli->outbuf,'\0',smb_size);
398         memset(cli->inbuf,'\0', smb_size);
399
400         set_message(cli->outbuf,8,0,True);
401
402         CVAL(cli->outbuf,smb_com) = SMBlockingX;
403         SSVAL(cli->outbuf,smb_tid,cli->cnum);
404         cli_setup_packet(cli);
405
406         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
407         SSVAL(cli->outbuf,smb_vwv2,fnum);
408         CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0);
409         SIVALS(cli->outbuf, smb_vwv4, timeout);
410         SSVAL(cli->outbuf,smb_vwv6,0);
411         SSVAL(cli->outbuf,smb_vwv7,1);
412
413         p = smb_buf(cli->outbuf);
414         SSVAL(p, 0, cli->pid);
415         SIVAL(p, 2, offset);
416         SIVAL(p, 6, len);
417
418         p += 10;
419
420         cli_setup_bcc(cli, p);
421
422         cli_send_smb(cli);
423
424         cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
425
426         if (!cli_receive_smb(cli)) {
427                 cli->timeout = saved_timeout;
428                 return False;
429         }
430
431         cli->timeout = saved_timeout;
432
433         if (CVAL(cli->inbuf,smb_rcls) != 0) {
434                 return False;
435         }
436
437         return True;
438 }
439
440 /****************************************************************************
441   unlock a file
442 ****************************************************************************/
443 BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
444 {
445         char *p;
446
447         memset(cli->outbuf,'\0',smb_size);
448         memset(cli->inbuf,'\0',smb_size);
449
450         set_message(cli->outbuf,8,0,True);
451
452         CVAL(cli->outbuf,smb_com) = SMBlockingX;
453         SSVAL(cli->outbuf,smb_tid,cli->cnum);
454         cli_setup_packet(cli);
455
456         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
457         SSVAL(cli->outbuf,smb_vwv2,fnum);
458         CVAL(cli->outbuf,smb_vwv3) = 0;
459         SIVALS(cli->outbuf, smb_vwv4, 0);
460         SSVAL(cli->outbuf,smb_vwv6,1);
461         SSVAL(cli->outbuf,smb_vwv7,0);
462
463         p = smb_buf(cli->outbuf);
464         SSVAL(p, 0, cli->pid);
465         SIVAL(p, 2, offset);
466         SIVAL(p, 6, len);
467         p += 10;
468         cli_setup_bcc(cli, p);
469         cli_send_smb(cli);
470         if (!cli_receive_smb(cli)) {
471                 return False;
472         }
473
474         if (CVAL(cli->inbuf,smb_rcls) != 0) {
475                 return False;
476         }
477
478         return True;
479 }
480
481
482 /****************************************************************************
483   lock a file with 64 bit offsets
484 ****************************************************************************/
485 BOOL cli_lock64(struct cli_state *cli, int fnum, 
486                 SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type)
487 {
488         char *p;
489         int saved_timeout = cli->timeout;
490         int ltype;
491
492         if (! (cli->capabilities & CAP_LARGE_FILES)) {
493                 return cli_lock(cli, fnum, offset, len, timeout, lock_type);
494         }
495
496         ltype = (lock_type == READ_LOCK? 1 : 0);
497         ltype |= LOCKING_ANDX_LARGE_FILES;
498
499         memset(cli->outbuf,'\0',smb_size);
500         memset(cli->inbuf,'\0', smb_size);
501
502         set_message(cli->outbuf,8,0,True);
503
504         CVAL(cli->outbuf,smb_com) = SMBlockingX;
505         SSVAL(cli->outbuf,smb_tid,cli->cnum);
506         cli_setup_packet(cli);
507
508         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
509         SSVAL(cli->outbuf,smb_vwv2,fnum);
510         CVAL(cli->outbuf,smb_vwv3) = ltype;
511         SIVALS(cli->outbuf, smb_vwv4, timeout);
512         SSVAL(cli->outbuf,smb_vwv6,0);
513         SSVAL(cli->outbuf,smb_vwv7,1);
514
515         p = smb_buf(cli->outbuf);
516         SIVAL(p, 0, cli->pid);
517         SOFF_T_R(p, 4, offset);
518         SOFF_T_R(p, 12, len);
519         p += 20;
520
521         cli_setup_bcc(cli, p);
522         cli_send_smb(cli);
523
524         cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
525
526         if (!cli_receive_smb(cli)) {
527                 cli->timeout = saved_timeout;
528                 return False;
529         }
530
531         cli->timeout = saved_timeout;
532
533         if (CVAL(cli->inbuf,smb_rcls) != 0) {
534                 return False;
535         }
536
537         return True;
538 }
539
540 /****************************************************************************
541   unlock a file with 64 bit offsets
542 ****************************************************************************/
543 BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
544 {
545         char *p;
546
547         if (! (cli->capabilities & CAP_LARGE_FILES)) {
548                 return cli_unlock(cli, fnum, offset, len);
549         }
550
551         memset(cli->outbuf,'\0',smb_size);
552         memset(cli->inbuf,'\0',smb_size);
553
554         set_message(cli->outbuf,8,0,True);
555
556         CVAL(cli->outbuf,smb_com) = SMBlockingX;
557         SSVAL(cli->outbuf,smb_tid,cli->cnum);
558         cli_setup_packet(cli);
559
560         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
561         SSVAL(cli->outbuf,smb_vwv2,fnum);
562         CVAL(cli->outbuf,smb_vwv3) = LOCKING_ANDX_LARGE_FILES;
563         SIVALS(cli->outbuf, smb_vwv4, 0);
564         SSVAL(cli->outbuf,smb_vwv6,1);
565         SSVAL(cli->outbuf,smb_vwv7,0);
566
567         p = smb_buf(cli->outbuf);
568         SIVAL(p, 0, cli->pid);
569         SOFF_T_R(p, 4, offset);
570         SOFF_T_R(p, 12, len);
571         p += 20;
572         cli_setup_bcc(cli, p);
573         cli_send_smb(cli);
574         if (!cli_receive_smb(cli)) {
575                 return False;
576         }
577
578         if (CVAL(cli->inbuf,smb_rcls) != 0) {
579                 return False;
580         }
581
582         return True;
583 }
584
585
586
587
588
589 /****************************************************************************
590 do a SMBgetattrE call
591 ****************************************************************************/
592 BOOL cli_getattrE(struct cli_state *cli, int fd, 
593                   uint16 *attr, size_t *size, 
594                   time_t *c_time, time_t *a_time, time_t *m_time)
595 {
596         memset(cli->outbuf,'\0',smb_size);
597         memset(cli->inbuf,'\0',smb_size);
598
599         set_message(cli->outbuf,1,0,True);
600
601         CVAL(cli->outbuf,smb_com) = SMBgetattrE;
602         SSVAL(cli->outbuf,smb_tid,cli->cnum);
603         cli_setup_packet(cli);
604
605         SSVAL(cli->outbuf,smb_vwv0,fd);
606
607         cli_send_smb(cli);
608         if (!cli_receive_smb(cli)) {
609                 return False;
610         }
611         
612         if (CVAL(cli->inbuf,smb_rcls) != 0) {
613                 return False;
614         }
615
616         if (size) {
617                 *size = IVAL(cli->inbuf, smb_vwv6);
618         }
619
620         if (attr) {
621                 *attr = SVAL(cli->inbuf,smb_vwv10);
622         }
623
624         if (c_time) {
625                 *c_time = make_unix_date3(cli->inbuf+smb_vwv0);
626         }
627
628         if (a_time) {
629                 *a_time = make_unix_date3(cli->inbuf+smb_vwv2);
630         }
631
632         if (m_time) {
633                 *m_time = make_unix_date3(cli->inbuf+smb_vwv4);
634         }
635
636         return True;
637 }
638
639
640 /****************************************************************************
641 do a SMBgetatr call
642 ****************************************************************************/
643 BOOL cli_getatr(struct cli_state *cli, char *fname, 
644                 uint16 *attr, size_t *size, time_t *t)
645 {
646         char *p;
647
648         memset(cli->outbuf,'\0',smb_size);
649         memset(cli->inbuf,'\0',smb_size);
650
651         set_message(cli->outbuf,0,0,True);
652
653         CVAL(cli->outbuf,smb_com) = SMBgetatr;
654         SSVAL(cli->outbuf,smb_tid,cli->cnum);
655         cli_setup_packet(cli);
656
657         p = smb_buf(cli->outbuf);
658         *p++ = 4;
659         p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
660
661         cli_setup_bcc(cli, p);
662
663         cli_send_smb(cli);
664         if (!cli_receive_smb(cli)) {
665                 return False;
666         }
667         
668         if (CVAL(cli->inbuf,smb_rcls) != 0) {
669                 return False;
670         }
671
672         if (size) {
673                 *size = IVAL(cli->inbuf, smb_vwv3);
674         }
675
676         if (t) {
677                 *t = make_unix_date3(cli->inbuf+smb_vwv1);
678         }
679
680         if (attr) {
681                 *attr = SVAL(cli->inbuf,smb_vwv0);
682         }
683
684
685         return True;
686 }
687
688
689 /****************************************************************************
690 do a SMBsetatr call
691 ****************************************************************************/
692 BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
693 {
694         char *p;
695
696         memset(cli->outbuf,'\0',smb_size);
697         memset(cli->inbuf,'\0',smb_size);
698
699         set_message(cli->outbuf,8,0,True);
700
701         CVAL(cli->outbuf,smb_com) = SMBsetatr;
702         SSVAL(cli->outbuf,smb_tid,cli->cnum);
703         cli_setup_packet(cli);
704
705         SSVAL(cli->outbuf,smb_vwv0, attr);
706         put_dos_date3(cli->outbuf,smb_vwv1, t);
707
708         p = smb_buf(cli->outbuf);
709         *p++ = 4;
710         p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
711         *p++ = 4;
712
713         cli_setup_bcc(cli, p);
714
715         cli_send_smb(cli);
716         if (!cli_receive_smb(cli)) {
717                 return False;
718         }
719         
720         if (CVAL(cli->inbuf,smb_rcls) != 0) {
721                 return False;
722         }
723
724         return True;
725 }
726
727
728 /****************************************************************************
729 check for existance of a dir
730 ****************************************************************************/
731 BOOL cli_chkpath(struct cli_state *cli, char *path)
732 {
733         pstring path2;
734         char *p;
735         
736         safe_strcpy(path2,path,sizeof(pstring));
737         trim_string(path2,NULL,"\\");
738         if (!*path2) *path2 = '\\';
739         
740         memset(cli->outbuf,'\0',smb_size);
741         set_message(cli->outbuf,0,0,True);
742         SCVAL(cli->outbuf,smb_com,SMBchkpth);
743         SSVAL(cli->outbuf,smb_tid,cli->cnum);
744         cli_setup_packet(cli);
745         p = smb_buf(cli->outbuf);
746         *p++ = 4;
747         p += clistr_push(cli, p, path2, -1, STR_TERMINATE);
748
749         cli_setup_bcc(cli, p);
750
751         cli_send_smb(cli);
752         if (!cli_receive_smb(cli)) {
753                 return False;
754         }
755
756         if (cli_is_error(cli)) return False;
757
758         return True;
759 }
760
761
762
763 /****************************************************************************
764 query disk space
765 ****************************************************************************/
766 BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
767 {
768         memset(cli->outbuf,'\0',smb_size);
769         set_message(cli->outbuf,0,0,True);
770         CVAL(cli->outbuf,smb_com) = SMBdskattr;
771         SSVAL(cli->outbuf,smb_tid,cli->cnum);
772         cli_setup_packet(cli);
773
774         cli_send_smb(cli);
775         if (!cli_receive_smb(cli)) {
776                 return False;
777         }
778
779         *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2);
780         *total = SVAL(cli->inbuf,smb_vwv0);
781         *avail = SVAL(cli->inbuf,smb_vwv3);
782         
783         return True;
784 }
785
786
787 /****************************************************************************
788 create and open a temporary file
789 ****************************************************************************/
790 int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path)
791 {
792         char *p;
793
794         memset(cli->outbuf,'\0',smb_size);
795         memset(cli->inbuf,'\0',smb_size);
796
797         set_message(cli->outbuf,1,0,True);
798
799         CVAL(cli->outbuf,smb_com) = SMBctemp;
800         SSVAL(cli->outbuf,smb_tid,cli->cnum);
801         cli_setup_packet(cli);
802
803         SSVAL(cli->outbuf,smb_vwv0,0);
804
805         p = smb_buf(cli->outbuf);
806         *p++ = 4;
807         p += clistr_push(cli, p, path, -1, STR_TERMINATE);
808
809         cli_setup_bcc(cli, p);
810
811         cli_send_smb(cli);
812         if (!cli_receive_smb(cli)) {
813                 return -1;
814         }
815
816         if (CVAL(cli->inbuf,smb_rcls) != 0) {
817                 return -1;
818         }
819
820         if (tmp_path) {
821                 pstring path2;
822                 clistr_pull(cli, path2, smb_buf(cli->inbuf)+1, 
823                             sizeof(path2), -1, STR_TERMINATE);
824                 *tmp_path = strdup(path2);
825         }
826
827         return SVAL(cli->inbuf,smb_vwv0);
828 }