fixed unitialized struct bug in enum_users (whatever it is called)
[Samba/gbeck.git] / source / libsmb / clifile.c
blob214c30d930af9997d04a94a4e5a503024f0eff83
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, 4 + strlen(fname_src) + strlen(fname_dst), 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 pstrcpy(p,fname_src);
47 unix_to_dos(p,True);
48 p = skip_string(p,1);
49 *p++ = 4;
50 pstrcpy(p,fname_dst);
51 unix_to_dos(p,True);
53 cli_send_smb(cli);
54 if (!cli_receive_smb(cli)) {
55 return False;
58 if (CVAL(cli->inbuf,smb_rcls) != 0) {
59 return False;
62 return True;
65 /****************************************************************************
66 delete a file
67 ****************************************************************************/
68 BOOL cli_unlink(struct cli_state *cli, char *fname)
70 char *p;
72 memset(cli->outbuf,'\0',smb_size);
73 memset(cli->inbuf,'\0',smb_size);
75 set_message(cli->outbuf,1, 2 + strlen(fname),True);
77 CVAL(cli->outbuf,smb_com) = SMBunlink;
78 SSVAL(cli->outbuf,smb_tid,cli->cnum);
79 cli_setup_packet(cli);
81 SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN);
83 p = smb_buf(cli->outbuf);
84 *p++ = 4;
85 pstrcpy(p,fname);
86 unix_to_dos(p,True);
88 cli_send_smb(cli);
89 if (!cli_receive_smb(cli)) {
90 return False;
93 if (CVAL(cli->inbuf,smb_rcls) != 0) {
94 return False;
97 return True;
100 /****************************************************************************
101 create a directory
102 ****************************************************************************/
103 BOOL cli_mkdir(struct cli_state *cli, char *dname)
105 char *p;
107 memset(cli->outbuf,'\0',smb_size);
108 memset(cli->inbuf,'\0',smb_size);
110 set_message(cli->outbuf,0, 2 + strlen(dname),True);
112 CVAL(cli->outbuf,smb_com) = SMBmkdir;
113 SSVAL(cli->outbuf,smb_tid,cli->cnum);
114 cli_setup_packet(cli);
116 p = smb_buf(cli->outbuf);
117 *p++ = 4;
118 pstrcpy(p,dname);
119 unix_to_dos(p,True);
121 cli_send_smb(cli);
122 if (!cli_receive_smb(cli)) {
123 return False;
126 if (CVAL(cli->inbuf,smb_rcls) != 0) {
127 return False;
130 return True;
133 /****************************************************************************
134 remove a directory
135 ****************************************************************************/
136 BOOL cli_rmdir(struct cli_state *cli, char *dname)
138 char *p;
140 memset(cli->outbuf,'\0',smb_size);
141 memset(cli->inbuf,'\0',smb_size);
143 set_message(cli->outbuf,0, 2 + strlen(dname),True);
145 CVAL(cli->outbuf,smb_com) = SMBrmdir;
146 SSVAL(cli->outbuf,smb_tid,cli->cnum);
147 cli_setup_packet(cli);
149 p = smb_buf(cli->outbuf);
150 *p++ = 4;
151 pstrcpy(p,dname);
152 unix_to_dos(p,True);
154 cli_send_smb(cli);
155 if (!cli_receive_smb(cli)) {
156 return False;
159 if (CVAL(cli->inbuf,smb_rcls) != 0) {
160 return False;
163 return True;
168 /****************************************************************************
169 open a file
170 ****************************************************************************/
171 int cli_nt_create(struct cli_state *cli, char *fname)
173 char *p;
175 memset(cli->outbuf,'\0',smb_size);
176 memset(cli->inbuf,'\0',smb_size);
178 set_message(cli->outbuf,24,1 + strlen(fname),True);
180 CVAL(cli->outbuf,smb_com) = SMBntcreateX;
181 SSVAL(cli->outbuf,smb_tid,cli->cnum);
182 cli_setup_packet(cli);
184 SSVAL(cli->outbuf,smb_vwv0,0xFF);
185 SIVAL(cli->outbuf,smb_ntcreate_Flags, 0x06);
186 SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0);
187 SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f);
188 SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0);
189 SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03);
190 SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01);
191 SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0);
192 SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02);
193 SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname));
195 p = smb_buf(cli->outbuf);
196 pstrcpy(p,fname);
197 unix_to_dos(p,True);
198 p = skip_string(p,1);
200 cli_send_smb(cli);
201 if (!cli_receive_smb(cli)) {
202 return -1;
205 if (CVAL(cli->inbuf,smb_rcls) != 0) {
206 return -1;
209 return SVAL(cli->inbuf,smb_vwv2 + 1);
213 /****************************************************************************
214 open a file
215 WARNING: if you open with O_WRONLY then getattrE won't work!
216 ****************************************************************************/
217 int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
219 char *p;
220 unsigned openfn=0;
221 unsigned accessmode=0;
223 if (flags & O_CREAT)
224 openfn |= (1<<4);
225 if (!(flags & O_EXCL)) {
226 if (flags & O_TRUNC)
227 openfn |= (1<<1);
228 else
229 openfn |= (1<<0);
232 accessmode = (share_mode<<4);
234 if ((flags & O_ACCMODE) == O_RDWR) {
235 accessmode |= 2;
236 } else if ((flags & O_ACCMODE) == O_WRONLY) {
237 accessmode |= 1;
240 #if defined(O_SYNC)
241 if ((flags & O_SYNC) == O_SYNC) {
242 accessmode |= (1<<14);
244 #endif /* O_SYNC */
246 if (share_mode == DENY_FCB) {
247 accessmode = 0xFF;
250 memset(cli->outbuf,'\0',smb_size);
251 memset(cli->inbuf,'\0',smb_size);
253 set_message(cli->outbuf,15,1 + strlen(fname),True);
255 CVAL(cli->outbuf,smb_com) = SMBopenX;
256 SSVAL(cli->outbuf,smb_tid,cli->cnum);
257 cli_setup_packet(cli);
259 SSVAL(cli->outbuf,smb_vwv0,0xFF);
260 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
261 SSVAL(cli->outbuf,smb_vwv3,accessmode);
262 SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
263 SSVAL(cli->outbuf,smb_vwv5,0);
264 SSVAL(cli->outbuf,smb_vwv8,openfn);
266 if (cli->use_oplocks) {
267 /* if using oplocks then ask for a batch oplock via
268 core and extended methods */
269 CVAL(cli->outbuf,smb_flg) |=
270 FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
271 SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
274 p = smb_buf(cli->outbuf);
275 pstrcpy(p,fname);
276 unix_to_dos(p,True);
277 p = skip_string(p,1);
279 cli_send_smb(cli);
280 if (!cli_receive_smb(cli)) {
281 return -1;
284 if (CVAL(cli->inbuf,smb_rcls) != 0) {
285 return -1;
288 return SVAL(cli->inbuf,smb_vwv2);
294 /****************************************************************************
295 close a file
296 ****************************************************************************/
297 BOOL cli_close(struct cli_state *cli, int fnum)
299 memset(cli->outbuf,'\0',smb_size);
300 memset(cli->inbuf,'\0',smb_size);
302 set_message(cli->outbuf,3,0,True);
304 CVAL(cli->outbuf,smb_com) = SMBclose;
305 SSVAL(cli->outbuf,smb_tid,cli->cnum);
306 cli_setup_packet(cli);
308 SSVAL(cli->outbuf,smb_vwv0,fnum);
309 SIVALS(cli->outbuf,smb_vwv1,-1);
311 cli_send_smb(cli);
312 if (!cli_receive_smb(cli)) {
313 return False;
316 if (CVAL(cli->inbuf,smb_rcls) != 0) {
317 return False;
320 return True;
324 /****************************************************************************
325 lock a file
326 ****************************************************************************/
327 BOOL cli_lock(struct cli_state *cli, int fnum,
328 uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
330 char *p;
331 int saved_timeout = cli->timeout;
333 memset(cli->outbuf,'\0',smb_size);
334 memset(cli->inbuf,'\0', smb_size);
336 set_message(cli->outbuf,8,10,True);
338 CVAL(cli->outbuf,smb_com) = SMBlockingX;
339 SSVAL(cli->outbuf,smb_tid,cli->cnum);
340 cli_setup_packet(cli);
342 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
343 SSVAL(cli->outbuf,smb_vwv2,fnum);
344 CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0);
345 SIVALS(cli->outbuf, smb_vwv4, timeout);
346 SSVAL(cli->outbuf,smb_vwv6,0);
347 SSVAL(cli->outbuf,smb_vwv7,1);
349 p = smb_buf(cli->outbuf);
350 SSVAL(p, 0, cli->pid);
351 SIVAL(p, 2, offset);
352 SIVAL(p, 6, len);
353 cli_send_smb(cli);
355 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
357 if (!cli_receive_smb(cli)) {
358 cli->timeout = saved_timeout;
359 return False;
362 cli->timeout = saved_timeout;
364 if (CVAL(cli->inbuf,smb_rcls) != 0) {
365 return False;
368 return True;
371 /****************************************************************************
372 unlock a file
373 ****************************************************************************/
374 BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
376 char *p;
378 memset(cli->outbuf,'\0',smb_size);
379 memset(cli->inbuf,'\0',smb_size);
381 set_message(cli->outbuf,8,10,True);
383 CVAL(cli->outbuf,smb_com) = SMBlockingX;
384 SSVAL(cli->outbuf,smb_tid,cli->cnum);
385 cli_setup_packet(cli);
387 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
388 SSVAL(cli->outbuf,smb_vwv2,fnum);
389 CVAL(cli->outbuf,smb_vwv3) = 0;
390 SIVALS(cli->outbuf, smb_vwv4, 0);
391 SSVAL(cli->outbuf,smb_vwv6,1);
392 SSVAL(cli->outbuf,smb_vwv7,0);
394 p = smb_buf(cli->outbuf);
395 SSVAL(p, 0, cli->pid);
396 SIVAL(p, 2, offset);
397 SIVAL(p, 6, len);
399 cli_send_smb(cli);
400 if (!cli_receive_smb(cli)) {
401 return False;
404 if (CVAL(cli->inbuf,smb_rcls) != 0) {
405 return False;
408 return True;
415 /****************************************************************************
416 do a SMBgetattrE call
417 ****************************************************************************/
418 BOOL cli_getattrE(struct cli_state *cli, int fd,
419 uint16 *attr, size_t *size,
420 time_t *c_time, time_t *a_time, time_t *m_time)
422 memset(cli->outbuf,'\0',smb_size);
423 memset(cli->inbuf,'\0',smb_size);
425 set_message(cli->outbuf,1,0,True);
427 CVAL(cli->outbuf,smb_com) = SMBgetattrE;
428 SSVAL(cli->outbuf,smb_tid,cli->cnum);
429 cli_setup_packet(cli);
431 SSVAL(cli->outbuf,smb_vwv0,fd);
433 cli_send_smb(cli);
434 if (!cli_receive_smb(cli)) {
435 return False;
438 if (CVAL(cli->inbuf,smb_rcls) != 0) {
439 return False;
442 if (size) {
443 *size = IVAL(cli->inbuf, smb_vwv6);
446 if (attr) {
447 *attr = SVAL(cli->inbuf,smb_vwv10);
450 if (c_time) {
451 *c_time = make_unix_date3(cli->inbuf+smb_vwv0);
454 if (a_time) {
455 *a_time = make_unix_date3(cli->inbuf+smb_vwv2);
458 if (m_time) {
459 *m_time = make_unix_date3(cli->inbuf+smb_vwv4);
462 return True;
466 /****************************************************************************
467 do a SMBgetatr call
468 ****************************************************************************/
469 BOOL cli_getatr(struct cli_state *cli, char *fname,
470 uint16 *attr, size_t *size, time_t *t)
472 char *p;
474 memset(cli->outbuf,'\0',smb_size);
475 memset(cli->inbuf,'\0',smb_size);
477 set_message(cli->outbuf,0,strlen(fname)+2,True);
479 CVAL(cli->outbuf,smb_com) = SMBgetatr;
480 SSVAL(cli->outbuf,smb_tid,cli->cnum);
481 cli_setup_packet(cli);
483 p = smb_buf(cli->outbuf);
484 *p = 4;
485 pstrcpy(p+1, fname);
486 unix_to_dos(p+1,True);
488 cli_send_smb(cli);
489 if (!cli_receive_smb(cli)) {
490 return False;
493 if (CVAL(cli->inbuf,smb_rcls) != 0) {
494 return False;
497 if (size) {
498 *size = IVAL(cli->inbuf, smb_vwv3);
501 if (t) {
502 *t = make_unix_date3(cli->inbuf+smb_vwv1);
505 if (attr) {
506 *attr = SVAL(cli->inbuf,smb_vwv0);
510 return True;
514 /****************************************************************************
515 do a SMBsetatr call
516 ****************************************************************************/
517 BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
519 char *p;
521 memset(cli->outbuf,'\0',smb_size);
522 memset(cli->inbuf,'\0',smb_size);
524 set_message(cli->outbuf,8,strlen(fname)+4,True);
526 CVAL(cli->outbuf,smb_com) = SMBsetatr;
527 SSVAL(cli->outbuf,smb_tid,cli->cnum);
528 cli_setup_packet(cli);
530 SSVAL(cli->outbuf,smb_vwv0, attr);
531 put_dos_date3(cli->outbuf,smb_vwv1, t);
533 p = smb_buf(cli->outbuf);
534 *p = 4;
535 pstrcpy(p+1, fname);
536 unix_to_dos(p+1,True);
537 p = skip_string(p,1);
538 *p = 4;
540 cli_send_smb(cli);
541 if (!cli_receive_smb(cli)) {
542 return False;
545 if (CVAL(cli->inbuf,smb_rcls) != 0) {
546 return False;
549 return True;
553 /****************************************************************************
554 check for existance of a dir
555 ****************************************************************************/
556 BOOL cli_chkpath(struct cli_state *cli, char *path)
558 pstring path2;
559 char *p;
561 safe_strcpy(path2,path,sizeof(pstring));
562 trim_string(path2,NULL,"\\");
563 if (!*path2) *path2 = '\\';
565 memset(cli->outbuf,'\0',smb_size);
566 set_message(cli->outbuf,0,4 + strlen(path2),True);
567 SCVAL(cli->outbuf,smb_com,SMBchkpth);
568 SSVAL(cli->outbuf,smb_tid,cli->cnum);
569 cli_setup_packet(cli);
570 p = smb_buf(cli->outbuf);
571 *p++ = 4;
572 safe_strcpy(p,path2,strlen(path2));
573 unix_to_dos(p,True);
575 cli_send_smb(cli);
576 if (!cli_receive_smb(cli)) {
577 return False;
580 if (cli_error(cli, NULL, NULL, NULL)) return False;
582 return True;
587 /****************************************************************************
588 query disk space
589 ****************************************************************************/
590 BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
592 memset(cli->outbuf,'\0',smb_size);
593 set_message(cli->outbuf,0,0,True);
594 CVAL(cli->outbuf,smb_com) = SMBdskattr;
595 SSVAL(cli->outbuf,smb_tid,cli->cnum);
596 cli_setup_packet(cli);
598 cli_send_smb(cli);
599 if (!cli_receive_smb(cli)) {
600 return False;
603 *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2);
604 *total = SVAL(cli->inbuf,smb_vwv0);
605 *avail = SVAL(cli->inbuf,smb_vwv3);
607 return True;