2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1994-1998
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_ISVTX
) ? 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
), UID_NO_CHANGE
, 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
, 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
);
545 /****************************************************************************
547 ****************************************************************************/
549 BOOL
cli_lock(struct cli_state
*cli
, int fnum
,
550 uint32 offset
, uint32 len
, int timeout
, enum brl_type lock_type
)
553 int saved_timeout
= cli
->timeout
;
555 memset(cli
->outbuf
,'\0',smb_size
);
556 memset(cli
->inbuf
,'\0', smb_size
);
558 set_message(cli
->outbuf
,8,0,True
);
560 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
561 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
562 cli_setup_packet(cli
);
564 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
565 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
566 SCVAL(cli
->outbuf
,smb_vwv3
,(lock_type
== READ_LOCK
? 1 : 0));
567 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
568 SSVAL(cli
->outbuf
,smb_vwv6
,0);
569 SSVAL(cli
->outbuf
,smb_vwv7
,1);
571 p
= smb_buf(cli
->outbuf
);
572 SSVAL(p
, 0, cli
->pid
);
578 cli_setup_bcc(cli
, p
);
582 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 2*1000);
584 if (!cli_receive_smb(cli
)) {
585 cli
->timeout
= saved_timeout
;
589 cli
->timeout
= saved_timeout
;
591 if (cli_is_error(cli
)) {
598 /****************************************************************************
600 ****************************************************************************/
602 BOOL
cli_unlock(struct cli_state
*cli
, int fnum
, uint32 offset
, uint32 len
)
606 memset(cli
->outbuf
,'\0',smb_size
);
607 memset(cli
->inbuf
,'\0',smb_size
);
609 set_message(cli
->outbuf
,8,0,True
);
611 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
612 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
613 cli_setup_packet(cli
);
615 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
616 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
617 SCVAL(cli
->outbuf
,smb_vwv3
,0);
618 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
619 SSVAL(cli
->outbuf
,smb_vwv6
,1);
620 SSVAL(cli
->outbuf
,smb_vwv7
,0);
622 p
= smb_buf(cli
->outbuf
);
623 SSVAL(p
, 0, cli
->pid
);
627 cli_setup_bcc(cli
, p
);
629 if (!cli_receive_smb(cli
)) {
633 if (cli_is_error(cli
)) {
640 /****************************************************************************
641 Lock a file with 64 bit offsets.
642 ****************************************************************************/
644 BOOL
cli_lock64(struct cli_state
*cli
, int fnum
,
645 SMB_BIG_UINT offset
, SMB_BIG_UINT len
, int timeout
, enum brl_type lock_type
)
648 int saved_timeout
= cli
->timeout
;
651 if (! (cli
->capabilities
& CAP_LARGE_FILES
)) {
652 return cli_lock(cli
, fnum
, offset
, len
, timeout
, lock_type
);
655 ltype
= (lock_type
== READ_LOCK
? 1 : 0);
656 ltype
|= LOCKING_ANDX_LARGE_FILES
;
658 memset(cli
->outbuf
,'\0',smb_size
);
659 memset(cli
->inbuf
,'\0', smb_size
);
661 set_message(cli
->outbuf
,8,0,True
);
663 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
664 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
665 cli_setup_packet(cli
);
667 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
668 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
669 SCVAL(cli
->outbuf
,smb_vwv3
,ltype
);
670 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
671 SSVAL(cli
->outbuf
,smb_vwv6
,0);
672 SSVAL(cli
->outbuf
,smb_vwv7
,1);
674 p
= smb_buf(cli
->outbuf
);
675 SIVAL(p
, 0, cli
->pid
);
676 SOFF_T_R(p
, 4, offset
);
677 SOFF_T_R(p
, 12, len
);
680 cli_setup_bcc(cli
, p
);
683 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 2*1000);
685 if (!cli_receive_smb(cli
)) {
686 cli
->timeout
= saved_timeout
;
690 cli
->timeout
= saved_timeout
;
692 if (cli_is_error(cli
)) {
699 /****************************************************************************
700 Unlock a file with 64 bit offsets.
701 ****************************************************************************/
703 BOOL
cli_unlock64(struct cli_state
*cli
, int fnum
, SMB_BIG_UINT offset
, SMB_BIG_UINT len
)
707 if (! (cli
->capabilities
& CAP_LARGE_FILES
)) {
708 return cli_unlock(cli
, fnum
, offset
, len
);
711 memset(cli
->outbuf
,'\0',smb_size
);
712 memset(cli
->inbuf
,'\0',smb_size
);
714 set_message(cli
->outbuf
,8,0,True
);
716 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
717 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
718 cli_setup_packet(cli
);
720 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
721 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
722 SCVAL(cli
->outbuf
,smb_vwv3
,LOCKING_ANDX_LARGE_FILES
);
723 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
724 SSVAL(cli
->outbuf
,smb_vwv6
,1);
725 SSVAL(cli
->outbuf
,smb_vwv7
,0);
727 p
= smb_buf(cli
->outbuf
);
728 SIVAL(p
, 0, cli
->pid
);
729 SOFF_T_R(p
, 4, offset
);
730 SOFF_T_R(p
, 12, len
);
732 cli_setup_bcc(cli
, p
);
734 if (!cli_receive_smb(cli
)) {
738 if (cli_is_error(cli
)) {
745 /****************************************************************************
746 Do a SMBgetattrE call.
747 ****************************************************************************/
749 BOOL
cli_getattrE(struct cli_state
*cli
, int fd
,
750 uint16
*attr
, size_t *size
,
751 time_t *c_time
, time_t *a_time
, time_t *m_time
)
753 memset(cli
->outbuf
,'\0',smb_size
);
754 memset(cli
->inbuf
,'\0',smb_size
);
756 set_message(cli
->outbuf
,1,0,True
);
758 SCVAL(cli
->outbuf
,smb_com
,SMBgetattrE
);
759 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
760 cli_setup_packet(cli
);
762 SSVAL(cli
->outbuf
,smb_vwv0
,fd
);
765 if (!cli_receive_smb(cli
)) {
769 if (cli_is_error(cli
)) {
774 *size
= IVAL(cli
->inbuf
, smb_vwv6
);
778 *attr
= SVAL(cli
->inbuf
,smb_vwv10
);
782 *c_time
= make_unix_date3(cli
->inbuf
+smb_vwv0
);
786 *a_time
= make_unix_date3(cli
->inbuf
+smb_vwv2
);
790 *m_time
= make_unix_date3(cli
->inbuf
+smb_vwv4
);
796 /****************************************************************************
798 ****************************************************************************/
800 BOOL
cli_getatr(struct cli_state
*cli
, const char *fname
,
801 uint16
*attr
, size_t *size
, time_t *t
)
805 memset(cli
->outbuf
,'\0',smb_size
);
806 memset(cli
->inbuf
,'\0',smb_size
);
808 set_message(cli
->outbuf
,0,0,True
);
810 SCVAL(cli
->outbuf
,smb_com
,SMBgetatr
);
811 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
812 cli_setup_packet(cli
);
814 p
= smb_buf(cli
->outbuf
);
816 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
818 cli_setup_bcc(cli
, p
);
821 if (!cli_receive_smb(cli
)) {
825 if (cli_is_error(cli
)) {
830 *size
= IVAL(cli
->inbuf
, smb_vwv3
);
834 *t
= make_unix_date3(cli
->inbuf
+smb_vwv1
);
838 *attr
= SVAL(cli
->inbuf
,smb_vwv0
);
845 /****************************************************************************
847 ****************************************************************************/
849 BOOL
cli_setatr(struct cli_state
*cli
, const char *fname
, uint16 attr
, time_t t
)
853 memset(cli
->outbuf
,'\0',smb_size
);
854 memset(cli
->inbuf
,'\0',smb_size
);
856 set_message(cli
->outbuf
,8,0,True
);
858 SCVAL(cli
->outbuf
,smb_com
,SMBsetatr
);
859 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
860 cli_setup_packet(cli
);
862 SSVAL(cli
->outbuf
,smb_vwv0
, attr
);
863 put_dos_date3(cli
->outbuf
,smb_vwv1
, t
);
865 p
= smb_buf(cli
->outbuf
);
867 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
870 cli_setup_bcc(cli
, p
);
873 if (!cli_receive_smb(cli
)) {
877 if (cli_is_error(cli
)) {
884 /****************************************************************************
885 Check for existance of a dir.
886 ****************************************************************************/
888 BOOL
cli_chkpath(struct cli_state
*cli
, const char *path
)
893 safe_strcpy(path2
,path
,sizeof(pstring
));
894 trim_string(path2
,NULL
,"\\");
895 if (!*path2
) *path2
= '\\';
897 memset(cli
->outbuf
,'\0',smb_size
);
898 set_message(cli
->outbuf
,0,0,True
);
899 SCVAL(cli
->outbuf
,smb_com
,SMBchkpth
);
900 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
901 cli_setup_packet(cli
);
902 p
= smb_buf(cli
->outbuf
);
904 p
+= clistr_push(cli
, p
, path2
, -1, STR_TERMINATE
);
906 cli_setup_bcc(cli
, p
);
909 if (!cli_receive_smb(cli
)) {
913 if (cli_is_error(cli
)) return False
;
918 /****************************************************************************
920 ****************************************************************************/
922 BOOL
cli_dskattr(struct cli_state
*cli
, int *bsize
, int *total
, int *avail
)
924 memset(cli
->outbuf
,'\0',smb_size
);
925 set_message(cli
->outbuf
,0,0,True
);
926 SCVAL(cli
->outbuf
,smb_com
,SMBdskattr
);
927 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
928 cli_setup_packet(cli
);
931 if (!cli_receive_smb(cli
)) {
935 *bsize
= SVAL(cli
->inbuf
,smb_vwv1
)*SVAL(cli
->inbuf
,smb_vwv2
);
936 *total
= SVAL(cli
->inbuf
,smb_vwv0
);
937 *avail
= SVAL(cli
->inbuf
,smb_vwv3
);
942 /****************************************************************************
943 Create and open a temporary file.
944 ****************************************************************************/
946 int cli_ctemp(struct cli_state
*cli
, const char *path
, char **tmp_path
)
951 memset(cli
->outbuf
,'\0',smb_size
);
952 memset(cli
->inbuf
,'\0',smb_size
);
954 set_message(cli
->outbuf
,3,0,True
);
956 SCVAL(cli
->outbuf
,smb_com
,SMBctemp
);
957 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
958 cli_setup_packet(cli
);
960 SSVAL(cli
->outbuf
,smb_vwv0
,0);
961 SIVALS(cli
->outbuf
,smb_vwv1
,-1);
963 p
= smb_buf(cli
->outbuf
);
965 p
+= clistr_push(cli
, p
, path
, -1, STR_TERMINATE
);
967 cli_setup_bcc(cli
, p
);
970 if (!cli_receive_smb(cli
)) {
974 if (cli_is_error(cli
)) {
978 /* despite the spec, the result has a -1, followed by
979 length, followed by name */
980 p
= smb_buf(cli
->inbuf
);
982 len
= smb_buflen(cli
->inbuf
) - 4;
983 if (len
<= 0) return -1;
987 clistr_pull(cli
, path2
, p
,
988 sizeof(path2
), len
, STR_ASCII
);
989 *tmp_path
= strdup(path2
);
992 return SVAL(cli
->inbuf
,smb_vwv0
);