sync with SAMBA_2_2
[Samba/gbeck.git] / source / libsmb / clifile.c
blob4002a43c1b2cf89a3d287696ead69b21d1dbeee6
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 client file operations
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.
22 #define NO_SYSLOG
24 #include "includes.h"
26 /****************************************************************************
27 rename a file
28 ****************************************************************************/
29 BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
31 char *p;
33 memset(cli->outbuf,'\0',smb_size);
34 memset(cli->inbuf,'\0',smb_size);
36 set_message(cli->outbuf,1, 0, True);
38 CVAL(cli->outbuf,smb_com) = SMBmv;
39 SSVAL(cli->outbuf,smb_tid,cli->cnum);
40 cli_setup_packet(cli);
42 SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
44 p = smb_buf(cli->outbuf);
45 *p++ = 4;
46 p += clistr_push(cli, p, fname_src, -1,
47 STR_TERMINATE | STR_CONVERT);
48 *p++ = 4;
49 p += clistr_push(cli, p, fname_dst, -1,
50 STR_TERMINATE | STR_CONVERT);
52 cli_setup_bcc(cli, p);
54 cli_send_smb(cli);
55 if (!cli_receive_smb(cli)) {
56 return False;
59 if (CVAL(cli->inbuf,smb_rcls) != 0) {
60 return False;
63 return True;
66 /****************************************************************************
67 delete a file
68 ****************************************************************************/
69 BOOL cli_unlink(struct cli_state *cli, char *fname)
71 char *p;
73 memset(cli->outbuf,'\0',smb_size);
74 memset(cli->inbuf,'\0',smb_size);
76 set_message(cli->outbuf,1, 0,True);
78 CVAL(cli->outbuf,smb_com) = SMBunlink;
79 SSVAL(cli->outbuf,smb_tid,cli->cnum);
80 cli_setup_packet(cli);
82 SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN);
84 p = smb_buf(cli->outbuf);
85 *p++ = 4;
86 p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT);
88 cli_setup_bcc(cli, p);
89 cli_send_smb(cli);
90 if (!cli_receive_smb(cli)) {
91 return False;
94 if (CVAL(cli->inbuf,smb_rcls) != 0) {
95 return False;
98 return True;
101 /****************************************************************************
102 create a directory
103 ****************************************************************************/
104 BOOL cli_mkdir(struct cli_state *cli, char *dname)
106 char *p;
108 memset(cli->outbuf,'\0',smb_size);
109 memset(cli->inbuf,'\0',smb_size);
111 set_message(cli->outbuf,0, 0,True);
113 CVAL(cli->outbuf,smb_com) = SMBmkdir;
114 SSVAL(cli->outbuf,smb_tid,cli->cnum);
115 cli_setup_packet(cli);
117 p = smb_buf(cli->outbuf);
118 *p++ = 4;
119 p += clistr_push(cli, p, dname, -1, STR_CONVERT|STR_TERMINATE);
121 cli_setup_bcc(cli, p);
123 cli_send_smb(cli);
124 if (!cli_receive_smb(cli)) {
125 return False;
128 if (CVAL(cli->inbuf,smb_rcls) != 0) {
129 return False;
132 return True;
135 /****************************************************************************
136 remove a directory
137 ****************************************************************************/
138 BOOL cli_rmdir(struct cli_state *cli, char *dname)
140 char *p;
142 memset(cli->outbuf,'\0',smb_size);
143 memset(cli->inbuf,'\0',smb_size);
145 set_message(cli->outbuf,0, 0, True);
147 CVAL(cli->outbuf,smb_com) = SMBrmdir;
148 SSVAL(cli->outbuf,smb_tid,cli->cnum);
149 cli_setup_packet(cli);
151 p = smb_buf(cli->outbuf);
152 *p++ = 4;
153 p += clistr_push(cli, p, dname, -1, STR_TERMINATE|STR_CONVERT);
155 cli_setup_bcc(cli, p);
157 cli_send_smb(cli);
158 if (!cli_receive_smb(cli)) {
159 return False;
162 if (CVAL(cli->inbuf,smb_rcls) != 0) {
163 return False;
166 return True;
169 /****************************************************************************
170 Set or clear the delete on close flag.
171 ****************************************************************************/
173 int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
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;
182 memset(param, 0, param_len);
183 SSVAL(param,0,fnum);
184 SSVAL(param,2,SMB_SET_FILE_DISPOSITION_INFO);
186 data = flag ? 1 : 0;
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;
198 if (!cli_receive_trans(cli, SMBtrans2,
199 &rparam, &param_len,
200 &rdata, &data_len)) {
201 return False;
204 if (rdata) free(rdata);
205 if (rparam) free(rparam);
207 return True;
210 /****************************************************************************
211 open a file - exposing the full horror of the NT API :-).
212 Used in smbtorture.
213 ****************************************************************************/
215 int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess,
216 uint32 FileAttributes, uint32 ShareAccess,
217 uint32 CreateDisposition, uint32 CreateOptions)
219 char *p;
220 int len;
222 memset(cli->outbuf,'\0',smb_size);
223 memset(cli->inbuf,'\0',smb_size);
225 set_message(cli->outbuf,24,0,True);
227 CVAL(cli->outbuf,smb_com) = SMBntcreateX;
228 SSVAL(cli->outbuf,smb_tid,cli->cnum);
229 cli_setup_packet(cli);
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);
244 p = smb_buf(cli->outbuf);
245 /* this alignment and termination is critical for netapp filers. Don't change */
246 p += clistr_align(cli->outbuf, p);
247 len = clistr_push(cli, p, fname, -1, STR_CONVERT);
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);
253 cli_setup_bcc(cli, p);
255 cli_send_smb(cli);
256 if (!cli_receive_smb(cli)) {
257 return -1;
260 if (CVAL(cli->inbuf,smb_rcls) != 0) {
261 return -1;
264 return SVAL(cli->inbuf,smb_vwv2 + 1);
267 /****************************************************************************
268 open a file
269 ****************************************************************************/
271 int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess)
273 return cli_nt_create_full(cli, fname, DesiredAccess, 0,
274 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0);
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)
283 char *p;
284 unsigned openfn=0;
285 unsigned accessmode=0;
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);
296 accessmode = (share_mode<<4);
298 if ((flags & O_ACCMODE) == O_RDWR) {
299 accessmode |= 2;
300 } else if ((flags & O_ACCMODE) == O_WRONLY) {
301 accessmode |= 1;
304 #if defined(O_SYNC)
305 if ((flags & O_SYNC) == O_SYNC) {
306 accessmode |= (1<<14);
308 #endif /* O_SYNC */
310 if (share_mode == DENY_FCB) {
311 accessmode = 0xFF;
314 memset(cli->outbuf,'\0',smb_size);
315 memset(cli->inbuf,'\0',smb_size);
317 set_message(cli->outbuf,15,0,True);
319 CVAL(cli->outbuf,smb_com) = SMBopenX;
320 SSVAL(cli->outbuf,smb_tid,cli->cnum);
321 cli_setup_packet(cli);
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);
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);
338 p = smb_buf(cli->outbuf);
339 p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT);
341 cli_setup_bcc(cli, p);
343 cli_send_smb(cli);
344 if (!cli_receive_smb(cli)) {
345 return -1;
348 if (CVAL(cli->inbuf,smb_rcls) != 0) {
349 return -1;
352 return SVAL(cli->inbuf,smb_vwv2);
358 /****************************************************************************
359 close a file
360 ****************************************************************************/
361 BOOL cli_close(struct cli_state *cli, int fnum)
363 memset(cli->outbuf,'\0',smb_size);
364 memset(cli->inbuf,'\0',smb_size);
366 set_message(cli->outbuf,3,0,True);
368 CVAL(cli->outbuf,smb_com) = SMBclose;
369 SSVAL(cli->outbuf,smb_tid,cli->cnum);
370 cli_setup_packet(cli);
372 SSVAL(cli->outbuf,smb_vwv0,fnum);
373 SIVALS(cli->outbuf,smb_vwv1,-1);
375 cli_send_smb(cli);
376 if (!cli_receive_smb(cli)) {
377 return False;
380 if (CVAL(cli->inbuf,smb_rcls) != 0) {
381 return False;
384 return True;
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)
394 char *p;
395 int saved_timeout = cli->timeout;
397 memset(cli->outbuf,'\0',smb_size);
398 memset(cli->inbuf,'\0', smb_size);
400 set_message(cli->outbuf,8,0,True);
402 CVAL(cli->outbuf,smb_com) = SMBlockingX;
403 SSVAL(cli->outbuf,smb_tid,cli->cnum);
404 cli_setup_packet(cli);
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);
413 p = smb_buf(cli->outbuf);
414 SSVAL(p, 0, cli->pid);
415 SIVAL(p, 2, offset);
416 SIVAL(p, 6, len);
418 p += 10;
420 cli_setup_bcc(cli, p);
422 cli_send_smb(cli);
424 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
426 if (!cli_receive_smb(cli)) {
427 cli->timeout = saved_timeout;
428 return False;
431 cli->timeout = saved_timeout;
433 if (CVAL(cli->inbuf,smb_rcls) != 0) {
434 return False;
437 return True;
440 /****************************************************************************
441 unlock a file
442 ****************************************************************************/
443 BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
445 char *p;
447 memset(cli->outbuf,'\0',smb_size);
448 memset(cli->inbuf,'\0',smb_size);
450 set_message(cli->outbuf,8,0,True);
452 CVAL(cli->outbuf,smb_com) = SMBlockingX;
453 SSVAL(cli->outbuf,smb_tid,cli->cnum);
454 cli_setup_packet(cli);
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);
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;
474 if (CVAL(cli->inbuf,smb_rcls) != 0) {
475 return False;
478 return True;
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)
488 char *p;
489 int saved_timeout = cli->timeout;
490 int ltype;
492 ltype = (lock_type == READ_LOCK? 1 : 0);
493 ltype |= LOCKING_ANDX_LARGE_FILES;
495 memset(cli->outbuf,'\0',smb_size);
496 memset(cli->inbuf,'\0', smb_size);
498 set_message(cli->outbuf,8,0,True);
500 CVAL(cli->outbuf,smb_com) = SMBlockingX;
501 SSVAL(cli->outbuf,smb_tid,cli->cnum);
502 cli_setup_packet(cli);
504 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
505 SSVAL(cli->outbuf,smb_vwv2,fnum);
506 CVAL(cli->outbuf,smb_vwv3) = ltype;
507 SIVALS(cli->outbuf, smb_vwv4, timeout);
508 SSVAL(cli->outbuf,smb_vwv6,0);
509 SSVAL(cli->outbuf,smb_vwv7,1);
511 p = smb_buf(cli->outbuf);
512 SIVAL(p, 0, cli->pid);
513 SOFF_T_R(p, 4, offset);
514 SOFF_T_R(p, 12, len);
515 p += 20;
517 cli_setup_bcc(cli, p);
518 cli_send_smb(cli);
520 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
522 if (!cli_receive_smb(cli)) {
523 cli->timeout = saved_timeout;
524 return False;
527 cli->timeout = saved_timeout;
529 if (CVAL(cli->inbuf,smb_rcls) != 0) {
530 return False;
533 return True;
536 /****************************************************************************
537 unlock a file with 64 bit offsets
538 ****************************************************************************/
539 BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
541 char *p;
543 memset(cli->outbuf,'\0',smb_size);
544 memset(cli->inbuf,'\0',smb_size);
546 set_message(cli->outbuf,8,0,True);
548 CVAL(cli->outbuf,smb_com) = SMBlockingX;
549 SSVAL(cli->outbuf,smb_tid,cli->cnum);
550 cli_setup_packet(cli);
552 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
553 SSVAL(cli->outbuf,smb_vwv2,fnum);
554 CVAL(cli->outbuf,smb_vwv3) = LOCKING_ANDX_LARGE_FILES;
555 SIVALS(cli->outbuf, smb_vwv4, 0);
556 SSVAL(cli->outbuf,smb_vwv6,1);
557 SSVAL(cli->outbuf,smb_vwv7,0);
559 p = smb_buf(cli->outbuf);
560 SIVAL(p, 0, cli->pid);
561 SOFF_T_R(p, 4, offset);
562 SOFF_T_R(p, 12, len);
563 p += 20;
564 cli_setup_bcc(cli, p);
565 cli_send_smb(cli);
566 if (!cli_receive_smb(cli)) {
567 return False;
570 if (CVAL(cli->inbuf,smb_rcls) != 0) {
571 return False;
574 return True;
581 /****************************************************************************
582 do a SMBgetattrE call
583 ****************************************************************************/
584 BOOL cli_getattrE(struct cli_state *cli, int fd,
585 uint16 *attr, size_t *size,
586 time_t *c_time, time_t *a_time, time_t *m_time)
588 memset(cli->outbuf,'\0',smb_size);
589 memset(cli->inbuf,'\0',smb_size);
591 set_message(cli->outbuf,1,0,True);
593 CVAL(cli->outbuf,smb_com) = SMBgetattrE;
594 SSVAL(cli->outbuf,smb_tid,cli->cnum);
595 cli_setup_packet(cli);
597 SSVAL(cli->outbuf,smb_vwv0,fd);
599 cli_send_smb(cli);
600 if (!cli_receive_smb(cli)) {
601 return False;
604 if (CVAL(cli->inbuf,smb_rcls) != 0) {
605 return False;
608 if (size) {
609 *size = IVAL(cli->inbuf, smb_vwv6);
612 if (attr) {
613 *attr = SVAL(cli->inbuf,smb_vwv10);
616 if (c_time) {
617 *c_time = make_unix_date3(cli->inbuf+smb_vwv0);
620 if (a_time) {
621 *a_time = make_unix_date3(cli->inbuf+smb_vwv2);
624 if (m_time) {
625 *m_time = make_unix_date3(cli->inbuf+smb_vwv4);
628 return True;
632 /****************************************************************************
633 do a SMBgetatr call
634 ****************************************************************************/
635 BOOL cli_getatr(struct cli_state *cli, char *fname,
636 uint16 *attr, size_t *size, time_t *t)
638 char *p;
640 memset(cli->outbuf,'\0',smb_size);
641 memset(cli->inbuf,'\0',smb_size);
643 set_message(cli->outbuf,0,0,True);
645 CVAL(cli->outbuf,smb_com) = SMBgetatr;
646 SSVAL(cli->outbuf,smb_tid,cli->cnum);
647 cli_setup_packet(cli);
649 p = smb_buf(cli->outbuf);
650 *p++ = 4;
651 p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT);
653 cli_setup_bcc(cli, p);
655 cli_send_smb(cli);
656 if (!cli_receive_smb(cli)) {
657 return False;
660 if (CVAL(cli->inbuf,smb_rcls) != 0) {
661 return False;
664 if (size) {
665 *size = IVAL(cli->inbuf, smb_vwv3);
668 if (t) {
669 *t = make_unix_date3(cli->inbuf+smb_vwv1);
672 if (attr) {
673 *attr = SVAL(cli->inbuf,smb_vwv0);
677 return True;
681 /****************************************************************************
682 do a SMBsetatr call
683 ****************************************************************************/
684 BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
686 char *p;
688 memset(cli->outbuf,'\0',smb_size);
689 memset(cli->inbuf,'\0',smb_size);
691 set_message(cli->outbuf,8,0,True);
693 CVAL(cli->outbuf,smb_com) = SMBsetatr;
694 SSVAL(cli->outbuf,smb_tid,cli->cnum);
695 cli_setup_packet(cli);
697 SSVAL(cli->outbuf,smb_vwv0, attr);
698 put_dos_date3(cli->outbuf,smb_vwv1, t);
700 p = smb_buf(cli->outbuf);
701 *p++ = 4;
702 p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT);
703 *p++ = 4;
705 cli_setup_bcc(cli, p);
707 cli_send_smb(cli);
708 if (!cli_receive_smb(cli)) {
709 return False;
712 if (CVAL(cli->inbuf,smb_rcls) != 0) {
713 return False;
716 return True;
720 /****************************************************************************
721 check for existance of a dir
722 ****************************************************************************/
723 BOOL cli_chkpath(struct cli_state *cli, char *path)
725 pstring path2;
726 char *p;
728 safe_strcpy(path2,path,sizeof(pstring));
729 trim_string(path2,NULL,"\\");
730 if (!*path2) *path2 = '\\';
732 memset(cli->outbuf,'\0',smb_size);
733 set_message(cli->outbuf,0,0,True);
734 SCVAL(cli->outbuf,smb_com,SMBchkpth);
735 SSVAL(cli->outbuf,smb_tid,cli->cnum);
736 cli_setup_packet(cli);
737 p = smb_buf(cli->outbuf);
738 *p++ = 4;
739 p += clistr_push(cli, p, path2, -1, STR_TERMINATE | STR_CONVERT);
741 cli_setup_bcc(cli, p);
743 cli_send_smb(cli);
744 if (!cli_receive_smb(cli)) {
745 return False;
748 if (cli_error(cli, NULL, NULL, NULL)) return False;
750 return True;
755 /****************************************************************************
756 query disk space
757 ****************************************************************************/
758 BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
760 memset(cli->outbuf,'\0',smb_size);
761 set_message(cli->outbuf,0,0,True);
762 CVAL(cli->outbuf,smb_com) = SMBdskattr;
763 SSVAL(cli->outbuf,smb_tid,cli->cnum);
764 cli_setup_packet(cli);
766 cli_send_smb(cli);
767 if (!cli_receive_smb(cli)) {
768 return False;
771 *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2);
772 *total = SVAL(cli->inbuf,smb_vwv0);
773 *avail = SVAL(cli->inbuf,smb_vwv3);
775 return True;
779 /****************************************************************************
780 create and open a temporary file
781 ****************************************************************************/
782 int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path)
784 char *p;
786 memset(cli->outbuf,'\0',smb_size);
787 memset(cli->inbuf,'\0',smb_size);
789 set_message(cli->outbuf,1,strlen(path)+2,True);
791 CVAL(cli->outbuf,smb_com) = SMBctemp;
792 SSVAL(cli->outbuf,smb_tid,cli->cnum);
793 cli_setup_packet(cli);
795 SSVAL(cli->outbuf,smb_vwv0,0);
797 p = smb_buf(cli->outbuf);
798 *p++ = 4;
799 p += clistr_push(cli, p, path, -1, STR_TERMINATE | STR_CONVERT);
801 cli_send_smb(cli);
802 if (!cli_receive_smb(cli)) {
803 return -1;
806 if (CVAL(cli->inbuf,smb_rcls) != 0) {
807 return -1;
810 if (tmp_path) {
811 pstring path2;
812 clistr_pull(cli, path2, smb_buf(cli->inbuf)+1,
813 sizeof(path2), -1, STR_TERMINATE | STR_CONVERT);
814 *tmp_path = strdup(path2);
817 return SVAL(cli->inbuf,smb_vwv0);