2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2001-2002
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.
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.
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.
26 /****************************************************************************
27 Hard/Symlink a file (UNIX extensions).
28 ****************************************************************************/
30 static BOOL
cli_link_internal(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
, BOOL hard_link
)
34 uint16 setup
= TRANSACT2_SETPATHINFO
;
35 char param
[sizeof(pstring
)+6];
37 char *rparam
=NULL
, *rdata
=NULL
;
40 memset(param
, 0, sizeof(param
));
41 SSVAL(param
,0,hard_link
? SMB_SET_FILE_UNIX_HLINK
: SMB_SET_FILE_UNIX_LINK
);
44 p
+= clistr_push(cli
, p
, fname_src
, -1, STR_TERMINATE
);
45 param_len
= PTR_DIFF(p
, param
);
48 p
+= clistr_push(cli
, p
, fname_dst
, -1, STR_TERMINATE
);
49 data_len
= PTR_DIFF(p
, data
);
51 if (!cli_send_trans(cli
, SMBtrans2
,
53 -1, 0, /* fid, flags */
54 &setup
, 1, 0, /* setup, length, max */
55 param
, param_len
, 2, /* param, length, max */
56 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
61 if (!cli_receive_trans(cli
, SMBtrans2
,
73 /****************************************************************************
74 Map standard UNIX permissions onto wire representations.
75 ****************************************************************************/
77 uint32
unix_perms_to_wire(mode_t perms
)
81 ret
|= ((perms
& S_IXOTH
) ? UNIX_X_OTH
: 0);
82 ret
|= ((perms
& S_IWOTH
) ? UNIX_W_OTH
: 0);
83 ret
|= ((perms
& S_IROTH
) ? UNIX_R_OTH
: 0);
84 ret
|= ((perms
& S_IXGRP
) ? UNIX_X_GRP
: 0);
85 ret
|= ((perms
& S_IWGRP
) ? UNIX_W_GRP
: 0);
86 ret
|= ((perms
& S_IRGRP
) ? UNIX_R_GRP
: 0);
87 ret
|= ((perms
& S_IXUSR
) ? UNIX_X_USR
: 0);
88 ret
|= ((perms
& S_IWUSR
) ? UNIX_W_USR
: 0);
89 ret
|= ((perms
& S_IRUSR
) ? UNIX_R_USR
: 0);
91 ret
|= ((perms
& S_ISVTX
) ? UNIX_STICKY
: 0);
94 ret
|= ((perms
& S_ISGID
) ? UNIX_SET_GID
: 0);
97 ret
|= ((perms
& S_ISUID
) ? UNIX_SET_UID
: 0);
102 /****************************************************************************
103 Symlink a file (UNIX extensions).
104 ****************************************************************************/
106 BOOL
cli_unix_symlink(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
108 return cli_link_internal(cli
, fname_src
, fname_dst
, False
);
111 /****************************************************************************
112 Hard a file (UNIX extensions).
113 ****************************************************************************/
115 BOOL
cli_unix_hardlink(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
117 return cli_link_internal(cli
, fname_src
, fname_dst
, True
);
120 /****************************************************************************
121 Chmod or chown a file internal (UNIX extensions).
122 ****************************************************************************/
124 static BOOL
cli_unix_chmod_chown_internal(struct cli_state
*cli
, const char *fname
, uint32 mode
, uint32 uid
, uint32 gid
)
128 uint16 setup
= TRANSACT2_SETPATHINFO
;
129 char param
[sizeof(pstring
)+6];
131 char *rparam
=NULL
, *rdata
=NULL
;
134 memset(param
, 0, sizeof(param
));
135 memset(data
, 0, sizeof(data
));
136 SSVAL(param
,0,SMB_SET_FILE_UNIX_BASIC
);
139 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
140 param_len
= PTR_DIFF(p
, param
);
148 if (!cli_send_trans(cli
, SMBtrans2
,
150 -1, 0, /* fid, flags */
151 &setup
, 1, 0, /* setup, length, max */
152 param
, param_len
, 2, /* param, length, max */
153 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
158 if (!cli_receive_trans(cli
, SMBtrans2
,
160 &rdata
, &data_len
)) {
170 /****************************************************************************
171 chmod a file (UNIX extensions).
172 ****************************************************************************/
174 BOOL
cli_unix_chmod(struct cli_state
*cli
, const char *fname
, mode_t mode
)
176 return cli_unix_chmod_chown_internal(cli
, fname
,
177 unix_perms_to_wire(mode
), SMB_UID_NO_CHANGE
, SMB_GID_NO_CHANGE
);
180 /****************************************************************************
181 chown a file (UNIX extensions).
182 ****************************************************************************/
184 BOOL
cli_unix_chown(struct cli_state
*cli
, const char *fname
, uid_t uid
, gid_t gid
)
186 return cli_unix_chmod_chown_internal(cli
, fname
, SMB_MODE_NO_CHANGE
, (uint32
)uid
, (uint32
)gid
);
189 /****************************************************************************
191 ****************************************************************************/
193 BOOL
cli_rename(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
197 memset(cli
->outbuf
,'\0',smb_size
);
198 memset(cli
->inbuf
,'\0',smb_size
);
200 set_message(cli
->outbuf
,1, 0, True
);
202 SCVAL(cli
->outbuf
,smb_com
,SMBmv
);
203 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
204 cli_setup_packet(cli
);
206 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
| aDIR
);
208 p
= smb_buf(cli
->outbuf
);
210 p
+= clistr_push(cli
, p
, fname_src
, -1, STR_TERMINATE
);
212 p
+= clistr_push(cli
, p
, fname_dst
, -1, STR_TERMINATE
);
214 cli_setup_bcc(cli
, p
);
217 if (!cli_receive_smb(cli
))
220 if (cli_is_error(cli
))
226 /****************************************************************************
228 ****************************************************************************/
230 BOOL
cli_unlink(struct cli_state
*cli
, const char *fname
)
234 memset(cli
->outbuf
,'\0',smb_size
);
235 memset(cli
->inbuf
,'\0',smb_size
);
237 set_message(cli
->outbuf
,1, 0,True
);
239 SCVAL(cli
->outbuf
,smb_com
,SMBunlink
);
240 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
241 cli_setup_packet(cli
);
243 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
);
245 p
= smb_buf(cli
->outbuf
);
247 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
249 cli_setup_bcc(cli
, p
);
251 if (!cli_receive_smb(cli
)) {
255 if (cli_is_error(cli
)) {
262 /****************************************************************************
264 ****************************************************************************/
266 BOOL
cli_mkdir(struct cli_state
*cli
, const char *dname
)
270 memset(cli
->outbuf
,'\0',smb_size
);
271 memset(cli
->inbuf
,'\0',smb_size
);
273 set_message(cli
->outbuf
,0, 0,True
);
275 SCVAL(cli
->outbuf
,smb_com
,SMBmkdir
);
276 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
277 cli_setup_packet(cli
);
279 p
= smb_buf(cli
->outbuf
);
281 p
+= clistr_push(cli
, p
, dname
, -1, STR_TERMINATE
);
283 cli_setup_bcc(cli
, p
);
286 if (!cli_receive_smb(cli
)) {
290 if (cli_is_error(cli
)) {
297 /****************************************************************************
299 ****************************************************************************/
301 BOOL
cli_rmdir(struct cli_state
*cli
, const char *dname
)
305 memset(cli
->outbuf
,'\0',smb_size
);
306 memset(cli
->inbuf
,'\0',smb_size
);
308 set_message(cli
->outbuf
,0, 0, True
);
310 SCVAL(cli
->outbuf
,smb_com
,SMBrmdir
);
311 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
312 cli_setup_packet(cli
);
314 p
= smb_buf(cli
->outbuf
);
316 p
+= clistr_push(cli
, p
, dname
, -1, STR_TERMINATE
);
318 cli_setup_bcc(cli
, p
);
321 if (!cli_receive_smb(cli
)) {
325 if (cli_is_error(cli
)) {
332 /****************************************************************************
333 Set or clear the delete on close flag.
334 ****************************************************************************/
336 int cli_nt_delete_on_close(struct cli_state
*cli
, int fnum
, BOOL flag
)
340 uint16 setup
= TRANSACT2_SETFILEINFO
;
343 char *rparam
=NULL
, *rdata
=NULL
;
345 memset(param
, 0, param_len
);
347 SSVAL(param
,2,SMB_SET_FILE_DISPOSITION_INFO
);
351 if (!cli_send_trans(cli
, SMBtrans2
,
353 -1, 0, /* fid, flags */
354 &setup
, 1, 0, /* setup, length, max */
355 param
, param_len
, 2, /* param, length, max */
356 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
361 if (!cli_receive_trans(cli
, SMBtrans2
,
363 &rdata
, &data_len
)) {
373 /****************************************************************************
374 Open a file - exposing the full horror of the NT API :-).
376 ****************************************************************************/
378 int cli_nt_create_full(struct cli_state
*cli
, const char *fname
, uint32 DesiredAccess
,
379 uint32 FileAttributes
, uint32 ShareAccess
,
380 uint32 CreateDisposition
, uint32 CreateOptions
)
385 memset(cli
->outbuf
,'\0',smb_size
);
386 memset(cli
->inbuf
,'\0',smb_size
);
388 set_message(cli
->outbuf
,24,0,True
);
390 SCVAL(cli
->outbuf
,smb_com
,SMBntcreateX
);
391 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
392 cli_setup_packet(cli
);
394 SSVAL(cli
->outbuf
,smb_vwv0
,0xFF);
395 if (cli
->use_oplocks
)
396 SIVAL(cli
->outbuf
,smb_ntcreate_Flags
, REQUEST_OPLOCK
|REQUEST_BATCH_OPLOCK
);
398 SIVAL(cli
->outbuf
,smb_ntcreate_Flags
, 0);
399 SIVAL(cli
->outbuf
,smb_ntcreate_RootDirectoryFid
, 0x0);
400 SIVAL(cli
->outbuf
,smb_ntcreate_DesiredAccess
, DesiredAccess
);
401 SIVAL(cli
->outbuf
,smb_ntcreate_FileAttributes
, FileAttributes
);
402 SIVAL(cli
->outbuf
,smb_ntcreate_ShareAccess
, ShareAccess
);
403 SIVAL(cli
->outbuf
,smb_ntcreate_CreateDisposition
, CreateDisposition
);
404 SIVAL(cli
->outbuf
,smb_ntcreate_CreateOptions
, CreateOptions
);
405 SIVAL(cli
->outbuf
,smb_ntcreate_ImpersonationLevel
, 0x02);
407 p
= smb_buf(cli
->outbuf
);
408 /* this alignment and termination is critical for netapp filers. Don't change */
409 p
+= clistr_align_out(cli
, p
, 0);
410 len
= clistr_push(cli
, p
, fname
, -1, 0);
412 SSVAL(cli
->outbuf
,smb_ntcreate_NameLength
, len
);
413 /* sigh. this copes with broken netapp filer behaviour */
414 p
+= clistr_push(cli
, p
, "", -1, STR_TERMINATE
);
416 cli_setup_bcc(cli
, p
);
419 if (!cli_receive_smb(cli
)) {
423 if (cli_is_error(cli
)) {
427 return SVAL(cli
->inbuf
,smb_vwv2
+ 1);
430 /****************************************************************************
432 ****************************************************************************/
434 int cli_nt_create(struct cli_state
*cli
, const char *fname
, uint32 DesiredAccess
)
436 return cli_nt_create_full(cli
, fname
, DesiredAccess
, 0,
437 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_EXISTS_OPEN
, 0x0);
440 /****************************************************************************
442 WARNING: if you open with O_WRONLY then getattrE won't work!
443 ****************************************************************************/
445 int cli_open(struct cli_state
*cli
, const char *fname
, int flags
, int share_mode
)
449 unsigned accessmode
=0;
453 if (!(flags
& O_EXCL
)) {
460 accessmode
= (share_mode
<<4);
462 if ((flags
& O_ACCMODE
) == O_RDWR
) {
464 } else if ((flags
& O_ACCMODE
) == O_WRONLY
) {
469 if ((flags
& O_SYNC
) == O_SYNC
) {
470 accessmode
|= (1<<14);
474 if (share_mode
== DENY_FCB
) {
478 memset(cli
->outbuf
,'\0',smb_size
);
479 memset(cli
->inbuf
,'\0',smb_size
);
481 set_message(cli
->outbuf
,15,0,True
);
483 SCVAL(cli
->outbuf
,smb_com
,SMBopenX
);
484 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
485 cli_setup_packet(cli
);
487 SSVAL(cli
->outbuf
,smb_vwv0
,0xFF);
488 SSVAL(cli
->outbuf
,smb_vwv2
,0); /* no additional info */
489 SSVAL(cli
->outbuf
,smb_vwv3
,accessmode
);
490 SSVAL(cli
->outbuf
,smb_vwv4
,aSYSTEM
| aHIDDEN
);
491 SSVAL(cli
->outbuf
,smb_vwv5
,0);
492 SSVAL(cli
->outbuf
,smb_vwv8
,openfn
);
494 if (cli
->use_oplocks
) {
495 /* if using oplocks then ask for a batch oplock via
496 core and extended methods */
497 SCVAL(cli
->outbuf
,smb_flg
, CVAL(cli
->outbuf
,smb_flg
)|
498 FLAG_REQUEST_OPLOCK
|FLAG_REQUEST_BATCH_OPLOCK
);
499 SSVAL(cli
->outbuf
,smb_vwv2
,SVAL(cli
->outbuf
,smb_vwv2
) | 6);
502 p
= smb_buf(cli
->outbuf
);
503 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
505 cli_setup_bcc(cli
, p
);
508 if (!cli_receive_smb(cli
)) {
512 if (cli_is_error(cli
)) {
516 return SVAL(cli
->inbuf
,smb_vwv2
);
519 /****************************************************************************
521 ****************************************************************************/
523 BOOL
cli_close(struct cli_state
*cli
, int fnum
)
525 memset(cli
->outbuf
,'\0',smb_size
);
526 memset(cli
->inbuf
,'\0',smb_size
);
528 set_message(cli
->outbuf
,3,0,True
);
530 SCVAL(cli
->outbuf
,smb_com
,SMBclose
);
531 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
532 cli_setup_packet(cli
);
534 SSVAL(cli
->outbuf
,smb_vwv0
,fnum
);
535 SIVALS(cli
->outbuf
,smb_vwv1
,-1);
538 if (!cli_receive_smb(cli
)) {
542 return !cli_is_error(cli
);
546 /****************************************************************************
547 send a lock with a specified locktype
548 this is used for testing LOCKING_ANDX_CANCEL_LOCK
549 ****************************************************************************/
550 NTSTATUS
cli_locktype(struct cli_state
*cli
, int fnum
,
551 uint32 offset
, uint32 len
, int timeout
, unsigned char locktype
)
554 int saved_timeout
= cli
->timeout
;
556 memset(cli
->outbuf
,'\0',smb_size
);
557 memset(cli
->inbuf
,'\0', smb_size
);
559 set_message(cli
->outbuf
,8,0,True
);
561 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
562 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
563 cli_setup_packet(cli
);
565 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
566 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
567 SCVAL(cli
->outbuf
,smb_vwv3
,locktype
);
568 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
569 SSVAL(cli
->outbuf
,smb_vwv6
,0);
570 SSVAL(cli
->outbuf
,smb_vwv7
,1);
572 p
= smb_buf(cli
->outbuf
);
573 SSVAL(p
, 0, cli
->pid
);
579 cli_setup_bcc(cli
, p
);
584 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 2*1000);
587 if (!cli_receive_smb(cli
)) {
588 cli
->timeout
= saved_timeout
;
589 return NT_STATUS_UNSUCCESSFUL
;
592 cli
->timeout
= saved_timeout
;
594 return cli_nt_error(cli
);
598 /****************************************************************************
600 ****************************************************************************/
602 BOOL
cli_lock(struct cli_state
*cli
, int fnum
,
603 uint32 offset
, uint32 len
, int timeout
, enum brl_type lock_type
)
606 int saved_timeout
= cli
->timeout
;
608 memset(cli
->outbuf
,'\0',smb_size
);
609 memset(cli
->inbuf
,'\0', smb_size
);
611 set_message(cli
->outbuf
,8,0,True
);
613 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
614 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
615 cli_setup_packet(cli
);
617 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
618 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
619 SCVAL(cli
->outbuf
,smb_vwv3
,(lock_type
== READ_LOCK
? 1 : 0));
620 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
621 SSVAL(cli
->outbuf
,smb_vwv6
,0);
622 SSVAL(cli
->outbuf
,smb_vwv7
,1);
624 p
= smb_buf(cli
->outbuf
);
625 SSVAL(p
, 0, cli
->pid
);
631 cli_setup_bcc(cli
, p
);
636 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 2*1000);
639 if (!cli_receive_smb(cli
)) {
640 cli
->timeout
= saved_timeout
;
644 cli
->timeout
= saved_timeout
;
646 if (cli_is_error(cli
)) {
653 /****************************************************************************
655 ****************************************************************************/
657 BOOL
cli_unlock(struct cli_state
*cli
, int fnum
, uint32 offset
, uint32 len
)
661 memset(cli
->outbuf
,'\0',smb_size
);
662 memset(cli
->inbuf
,'\0',smb_size
);
664 set_message(cli
->outbuf
,8,0,True
);
666 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
667 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
668 cli_setup_packet(cli
);
670 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
671 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
672 SCVAL(cli
->outbuf
,smb_vwv3
,0);
673 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
674 SSVAL(cli
->outbuf
,smb_vwv6
,1);
675 SSVAL(cli
->outbuf
,smb_vwv7
,0);
677 p
= smb_buf(cli
->outbuf
);
678 SSVAL(p
, 0, cli
->pid
);
682 cli_setup_bcc(cli
, p
);
684 if (!cli_receive_smb(cli
)) {
688 if (cli_is_error(cli
)) {
695 /****************************************************************************
696 Lock a file with 64 bit offsets.
697 ****************************************************************************/
699 BOOL
cli_lock64(struct cli_state
*cli
, int fnum
,
700 SMB_BIG_UINT offset
, SMB_BIG_UINT len
, int timeout
, enum brl_type lock_type
)
703 int saved_timeout
= cli
->timeout
;
706 if (! (cli
->capabilities
& CAP_LARGE_FILES
)) {
707 return cli_lock(cli
, fnum
, offset
, len
, timeout
, lock_type
);
710 ltype
= (lock_type
== READ_LOCK
? 1 : 0);
711 ltype
|= LOCKING_ANDX_LARGE_FILES
;
713 memset(cli
->outbuf
,'\0',smb_size
);
714 memset(cli
->inbuf
,'\0', smb_size
);
716 set_message(cli
->outbuf
,8,0,True
);
718 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
719 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
720 cli_setup_packet(cli
);
722 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
723 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
724 SCVAL(cli
->outbuf
,smb_vwv3
,ltype
);
725 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
726 SSVAL(cli
->outbuf
,smb_vwv6
,0);
727 SSVAL(cli
->outbuf
,smb_vwv7
,1);
729 p
= smb_buf(cli
->outbuf
);
730 SIVAL(p
, 0, cli
->pid
);
731 SOFF_T_R(p
, 4, offset
);
732 SOFF_T_R(p
, 12, len
);
735 cli_setup_bcc(cli
, p
);
739 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 5*1000);
742 if (!cli_receive_smb(cli
)) {
743 cli
->timeout
= saved_timeout
;
747 cli
->timeout
= saved_timeout
;
749 if (cli_is_error(cli
)) {
756 /****************************************************************************
757 Unlock a file with 64 bit offsets.
758 ****************************************************************************/
760 BOOL
cli_unlock64(struct cli_state
*cli
, int fnum
, SMB_BIG_UINT offset
, SMB_BIG_UINT len
)
764 if (! (cli
->capabilities
& CAP_LARGE_FILES
)) {
765 return cli_unlock(cli
, fnum
, offset
, len
);
768 memset(cli
->outbuf
,'\0',smb_size
);
769 memset(cli
->inbuf
,'\0',smb_size
);
771 set_message(cli
->outbuf
,8,0,True
);
773 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
774 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
775 cli_setup_packet(cli
);
777 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
778 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
779 SCVAL(cli
->outbuf
,smb_vwv3
,LOCKING_ANDX_LARGE_FILES
);
780 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
781 SSVAL(cli
->outbuf
,smb_vwv6
,1);
782 SSVAL(cli
->outbuf
,smb_vwv7
,0);
784 p
= smb_buf(cli
->outbuf
);
785 SIVAL(p
, 0, cli
->pid
);
786 SOFF_T_R(p
, 4, offset
);
787 SOFF_T_R(p
, 12, len
);
789 cli_setup_bcc(cli
, p
);
791 if (!cli_receive_smb(cli
)) {
795 if (cli_is_error(cli
)) {
803 /****************************************************************************
804 Do a SMBgetattrE call.
805 ****************************************************************************/
807 BOOL
cli_getattrE(struct cli_state
*cli
, int fd
,
808 uint16
*attr
, SMB_BIG_UINT
*size
,
809 time_t *c_time
, time_t *a_time
, time_t *m_time
)
811 memset(cli
->outbuf
,'\0',smb_size
);
812 memset(cli
->inbuf
,'\0',smb_size
);
814 set_message(cli
->outbuf
,1,0,True
);
816 SCVAL(cli
->outbuf
,smb_com
,SMBgetattrE
);
817 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
818 cli_setup_packet(cli
);
820 SSVAL(cli
->outbuf
,smb_vwv0
,fd
);
823 if (!cli_receive_smb(cli
)) {
827 if (cli_is_error(cli
)) {
832 *size
= IVAL(cli
->inbuf
, smb_vwv6
);
836 *attr
= SVAL(cli
->inbuf
,smb_vwv10
);
840 *c_time
= make_unix_date3(cli
->inbuf
+smb_vwv0
);
844 *a_time
= make_unix_date3(cli
->inbuf
+smb_vwv2
);
848 *m_time
= make_unix_date3(cli
->inbuf
+smb_vwv4
);
854 /****************************************************************************
856 ****************************************************************************/
858 BOOL
cli_getatr(struct cli_state
*cli
, const char *fname
,
859 uint16
*attr
, size_t *size
, time_t *t
)
863 memset(cli
->outbuf
,'\0',smb_size
);
864 memset(cli
->inbuf
,'\0',smb_size
);
866 set_message(cli
->outbuf
,0,0,True
);
868 SCVAL(cli
->outbuf
,smb_com
,SMBgetatr
);
869 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
870 cli_setup_packet(cli
);
872 p
= smb_buf(cli
->outbuf
);
874 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
876 cli_setup_bcc(cli
, p
);
879 if (!cli_receive_smb(cli
)) {
883 if (cli_is_error(cli
)) {
888 *size
= IVAL(cli
->inbuf
, smb_vwv3
);
892 *t
= make_unix_date3(cli
->inbuf
+smb_vwv1
);
896 *attr
= SVAL(cli
->inbuf
,smb_vwv0
);
903 /****************************************************************************
905 ****************************************************************************/
907 BOOL
cli_setatr(struct cli_state
*cli
, const char *fname
, uint16 attr
, time_t t
)
911 memset(cli
->outbuf
,'\0',smb_size
);
912 memset(cli
->inbuf
,'\0',smb_size
);
914 set_message(cli
->outbuf
,8,0,True
);
916 SCVAL(cli
->outbuf
,smb_com
,SMBsetatr
);
917 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
918 cli_setup_packet(cli
);
920 SSVAL(cli
->outbuf
,smb_vwv0
, attr
);
921 put_dos_date3(cli
->outbuf
,smb_vwv1
, t
);
923 p
= smb_buf(cli
->outbuf
);
925 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
928 cli_setup_bcc(cli
, p
);
931 if (!cli_receive_smb(cli
)) {
935 if (cli_is_error(cli
)) {
942 /****************************************************************************
943 Check for existance of a dir.
944 ****************************************************************************/
946 BOOL
cli_chkpath(struct cli_state
*cli
, const char *path
)
951 safe_strcpy(path2
,path
,sizeof(pstring
));
952 trim_string(path2
,NULL
,"\\");
953 if (!*path2
) *path2
= '\\';
955 memset(cli
->outbuf
,'\0',smb_size
);
956 set_message(cli
->outbuf
,0,0,True
);
957 SCVAL(cli
->outbuf
,smb_com
,SMBchkpth
);
958 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
959 cli_setup_packet(cli
);
960 p
= smb_buf(cli
->outbuf
);
962 p
+= clistr_push(cli
, p
, path2
, -1, STR_TERMINATE
);
964 cli_setup_bcc(cli
, p
);
967 if (!cli_receive_smb(cli
)) {
971 if (cli_is_error(cli
)) return False
;
976 /****************************************************************************
978 ****************************************************************************/
980 BOOL
cli_dskattr(struct cli_state
*cli
, int *bsize
, int *total
, int *avail
)
982 memset(cli
->outbuf
,'\0',smb_size
);
983 set_message(cli
->outbuf
,0,0,True
);
984 SCVAL(cli
->outbuf
,smb_com
,SMBdskattr
);
985 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
986 cli_setup_packet(cli
);
989 if (!cli_receive_smb(cli
)) {
993 *bsize
= SVAL(cli
->inbuf
,smb_vwv1
)*SVAL(cli
->inbuf
,smb_vwv2
);
994 *total
= SVAL(cli
->inbuf
,smb_vwv0
);
995 *avail
= SVAL(cli
->inbuf
,smb_vwv3
);
1000 /****************************************************************************
1001 Create and open a temporary file.
1002 ****************************************************************************/
1004 int cli_ctemp(struct cli_state
*cli
, const char *path
, char **tmp_path
)
1009 memset(cli
->outbuf
,'\0',smb_size
);
1010 memset(cli
->inbuf
,'\0',smb_size
);
1012 set_message(cli
->outbuf
,3,0,True
);
1014 SCVAL(cli
->outbuf
,smb_com
,SMBctemp
);
1015 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1016 cli_setup_packet(cli
);
1018 SSVAL(cli
->outbuf
,smb_vwv0
,0);
1019 SIVALS(cli
->outbuf
,smb_vwv1
,-1);
1021 p
= smb_buf(cli
->outbuf
);
1023 p
+= clistr_push(cli
, p
, path
, -1, STR_TERMINATE
);
1025 cli_setup_bcc(cli
, p
);
1028 if (!cli_receive_smb(cli
)) {
1032 if (cli_is_error(cli
)) {
1036 /* despite the spec, the result has a -1, followed by
1037 length, followed by name */
1038 p
= smb_buf(cli
->inbuf
);
1040 len
= smb_buflen(cli
->inbuf
) - 4;
1041 if (len
<= 0) return -1;
1045 clistr_pull(cli
, path2
, p
,
1046 sizeof(path2
), len
, STR_ASCII
);
1047 *tmp_path
= strdup(path2
);
1050 return SVAL(cli
->inbuf
,smb_vwv0
);