source: trunk/samba-3.0.25pre1/source/ndpsmb/smbwrp.c@ 6

Last change on this file since 6 was 6, checked in by Yuri Dario, 18 years ago

Client code changes for 3.0.25 upgrade.

  • Property svn:eol-style set to native
File size: 39.7 KB
Line 
1#include "includes.h"
2
3#include "smbwrp.h"
4
5/*
6 * Wrapper for cli_errno to return not connected error on negative fd
7 */
8int os2cli_errno(cli_state * cli)
9{
10 if (cli->fd == -1)
11 {
12 return ENOTCONN;
13 }
14 return cli_errno(cli);
15}
16
17int _System smbwrp_getclisize(void)
18{
19 return sizeof(struct cli_state);
20}
21
22/*****************************************************
23initialise structures
24*******************************************************/
25int _System smbwrp_init(void)
26{
27 static int initialised = 0;
28 char *p;
29 pstring line;
30
31 if (initialised)
32 {
33 return 0;
34 }
35 initialised = 1;
36
37 load_case_tables();
38
39 init_globals( True);
40
41 load_interfaces();
42
43 if (!init_names())
44 {
45 return 1;
46 }
47
48/*
49 if ((p=smbw_getshared("RESOLVE_ORDER"))) {
50 lp_set_name_resolve_order(p);
51 }
52*/
53 return 0;
54
55}
56
57#if 0
58/*****************************************************
59remove redundent stuff from a filename
60*******************************************************/
61void clean_fname(char *name)
62{
63 char *p, *p2;
64 int l;
65 int modified = 1;
66
67 if (!name) return;
68
69 while (modified) {
70 modified = 0;
71
72 if ((p=strstr(name,"/./"))) {
73 modified = 1;
74 while (*p) {
75 p[0] = p[2];
76 p++;
77 }
78 }
79
80 if ((p=strstr(name,"//"))) {
81 modified = 1;
82 while (*p) {
83 p[0] = p[1];
84 p++;
85 }
86 }
87
88 if (strcmp(name,"/../")==0) {
89 modified = 1;
90 name[1] = 0;
91 }
92
93 if ((p=strstr(name,"/../"))) {
94 modified = 1;
95 for (p2=(p>name?p-1:p);p2>name;p2--) {
96 if (p2[0] == '/') break;
97 }
98 while (*p2) {
99 p2[0] = p2[3];
100 p2++;
101 }
102 }
103
104 if (strcmp(name,"/..")==0) {
105 modified = 1;
106 name[1] = 0;
107 }
108
109 l = strlen(name);
110 p = l>=3?(name+l-3):name;
111 if (strcmp(p,"/..")==0) {
112 modified = 1;
113 for (p2=p-1;p2>name;p2--) {
114 if (p2[0] == '/') break;
115 }
116 if (p2==name) {
117 p[0] = '/';
118 p[1] = 0;
119 } else {
120 p2[0] = 0;
121 }
122 }
123
124 l = strlen(name);
125 p = l>=2?(name+l-2):name;
126 if (strcmp(p,"/.")==0) {
127 if (p == name) {
128 p[1] = 0;
129 } else {
130 p[0] = 0;
131 }
132 }
133
134 if (strncmp(p=name,"./",2) == 0) {
135 modified = 1;
136 do {
137 p[0] = p[2];
138 } while (*p++);
139 }
140
141 l = strlen(p=name);
142 if (l > 1 && p[l-1] == '/') {
143 modified = 1;
144 p[l-1] = 0;
145 }
146 }
147}
148#endif
149
150
151/****************************************************************************
152send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
153****************************************************************************/
154BOOL cli_qpathinfo3(struct cli_state *cli, const char *fname,
155 time_t *c_time, time_t *a_time, time_t *m_time,
156 time_t *w_time, off_t *size, uint16 *mode,
157 SMB_INO_T *ino)
158{
159 unsigned int data_len = 0;
160 unsigned int param_len = 0;
161 uint16 setup = TRANSACT2_QPATHINFO;
162 pstring param;
163 char *rparam=NULL, *rdata=NULL;
164 char *p;
165
166 p = param;
167 memset(p, 0, 6);
168 SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO);
169 p += 6;
170 p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
171
172 param_len = PTR_DIFF(p, param);
173
174 if (!cli_send_trans(cli, SMBtrans2,
175 NULL, /* name */
176 -1, 0, /* fid, flags */
177 &setup, 1, 0, /* setup, length, max */
178 param, param_len, 10, /* param, length, max */
179 NULL, data_len, cli->max_xmit /* data, length, max */
180 )) {
181 return False;
182 }
183
184 if (!cli_receive_trans(cli, SMBtrans2,
185 &rparam, &param_len,
186 &rdata, &data_len)) {
187 return False;
188 }
189
190 if (!rdata || data_len < 22) {
191 return False;
192 }
193
194 if (c_time) {
195 *c_time = convert_timespec_to_time_t(interpret_long_date(rdata+0)) - cli->serverzone;
196 }
197 if (a_time) {
198 *a_time = convert_timespec_to_time_t(interpret_long_date(rdata+8)) - cli->serverzone;
199 }
200 if (m_time) {
201 *m_time = convert_timespec_to_time_t(interpret_long_date(rdata+16)) - cli->serverzone;
202 }
203 if (w_time) {
204 *w_time = convert_timespec_to_time_t(interpret_long_date(rdata+24)) - cli->serverzone;
205 }
206 if (mode) {
207 *mode = SVAL(rdata, 32);
208 }
209 if (size) {
210 *size = IVAL2_TO_SMB_BIG_UINT(rdata, 48);
211 }
212 if (ino) {
213 *ino = IVAL(rdata, 64);
214 }
215
216 SAFE_FREE(rdata);
217 SAFE_FREE(rparam);
218 return True;
219}
220
221/****************************************************************************
222send a qfileinfo call
223****************************************************************************/
224BOOL cli_qfileinfo3(struct cli_state *cli, int fnum,
225 uint16 *mode, off_t *size,
226 time_t *c_time, time_t *a_time, time_t *m_time,
227 time_t *w_time, SMB_INO_T *ino)
228{
229 unsigned int data_len = 0;
230 unsigned int param_len = 0;
231 uint16 setup = TRANSACT2_QFILEINFO;
232 pstring param;
233 char *rparam=NULL, *rdata=NULL;
234
235 /* if its a win95 server then fail this - win95 totally screws it
236 up */
237 if (cli->win95) return False;
238
239 param_len = 4;
240
241 memset(param, 0, param_len);
242 SSVAL(param, 0, fnum);
243 SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);
244
245 if (!cli_send_trans(cli, SMBtrans2,
246 NULL, /* name */
247 -1, 0, /* fid, flags */
248 &setup, 1, 0, /* setup, length, max */
249 param, param_len, 2, /* param, length, max */
250 NULL, data_len, cli->max_xmit /* data, length, max */
251 )) {
252 return False;
253 }
254
255 if (!cli_receive_trans(cli, SMBtrans2,
256 &rparam, &param_len,
257 &rdata, &data_len)) {
258 return False;
259 }
260
261 if (!rdata || data_len < 68) {
262 return False;
263 }
264
265 if (c_time) {
266 *c_time = convert_timespec_to_time_t(interpret_long_date(rdata+0)) - cli->serverzone;
267 }
268 if (a_time) {
269 *a_time = convert_timespec_to_time_t(interpret_long_date(rdata+8)) - cli->serverzone;
270 }
271 if (m_time) {
272 *m_time = convert_timespec_to_time_t(interpret_long_date(rdata+16)) - cli->serverzone;
273 }
274 if (w_time) {
275 *w_time = convert_timespec_to_time_t(interpret_long_date(rdata+24)) - cli->serverzone;
276 }
277 if (mode) {
278 *mode = SVAL(rdata, 32);
279 }
280 if (size) {
281 *size = IVAL2_TO_SMB_BIG_UINT(rdata, 48);
282 }
283 if (ino) {
284 *ino = IVAL(rdata, 64);
285 }
286
287 SAFE_FREE(rdata);
288 SAFE_FREE(rparam);
289 return True;
290}
291
292/*****************************************************
293return a connection to a server
294*******************************************************/
295int _System smbwrp_connect(smbwrp_server * srv, struct cli_state * cli)
296{
297 char * server = srv->server_name;
298 char * share = *(srv->share_name) ? srv->share_name : "IPC$";
299 char * workgroup = srv->workgroup;
300 struct nmb_name called, calling;
301 char *p, *server_n = server;
302 fstring group;
303 struct in_addr ip;
304 NTSTATUS rc;
305 struct cli_state * c;
306
307 zero_ip(&ip);
308
309 DEBUG(1,("Connecting to \\\\%s:%s@%s:%s\\%s. Master %s:%d\n", srv->username, srv->password, workgroup, server, share, srv->master, srv->ifmastergroup));
310
311 if (!*server) {
312 struct in_addr sip;
313
314 if (*workgroup)
315 {
316 if (!find_master_ip(workgroup, &sip)) {
317 return 1;
318 }
319 fstrcpy(group, inet_ntoa(sip));
320 server_n = group;
321 } else
322 if (*srv->master)
323 {
324 if (srv->ifmastergroup)
325 {
326 if (!find_master_ip(srv->master, &sip)) {
327 return 11;
328 }
329 strncpy(srv->master, inet_ntoa(sip), sizeof(srv->master) - 1);
330 srv->ifmastergroup = 0;
331 }
332 server_n = srv->master;
333 } else
334 {
335 return 10;
336 }
337 }
338
339 make_nmb_name(&calling, global_myname(), 0x0);
340// make_nmb_name(&calling, "WORK", 0x0); // this machine name
341 make_nmb_name(&called , server_n, 0x20);
342
343 again:
344 zero_ip(&ip);
345
346 /* have to open a new connection */
347 if (!(c=cli_initialise()))
348 {
349 return 2;
350 }
351
352 if (!cli_connect(c, server_n, &ip))
353 {
354 return 3;
355 }
356 if (!cli_session_request(c, &calling, &called)) {
357 cli_shutdown(c);
358 if (strcmp(called.name, "*SMBSERVER")) {
359 make_nmb_name(&called , "*SMBSERVER", 0x20);
360 goto again;
361 }
362 return 4;
363 }
364
365 DEBUG(4,(" session request ok\n"));
366
367 if (!cli_negprot(c)) {
368 cli_shutdown(c);
369 return 5;
370 }
371
372 DEBUG(4,(" session setuping for <%s>/<%s> %d in <%s> %08x %08x %08x\n", srv->username, srv->password, strlen(srv->password), workgroup, c->protocol, c->sec_mode, c->capabilities));
373
374 if (!NT_STATUS_IS_OK(cli_session_setup(c, srv->username,
375 srv->password, strlen(srv->password),
376 srv->password, strlen(srv->password),
377 workgroup))) {
378 DEBUG(4,("%s/%s login failed\n", srv->username, srv->password));
379 /* try an anonymous login if it failed */
380 if (!NT_STATUS_IS_OK(cli_session_setup(c, "", "", 1,"", 0, workgroup))) {
381 DEBUG(4,("Anonymous login failed"));
382 cli_shutdown(c);
383 return 6;
384 }
385 }
386
387 DEBUG(4,(" session setup ok. Sending tconx <%s> <%s> %d\n", share, srv->password, strlen(srv->password)));
388
389 if (!cli_send_tconX(c, share, "?????",
390 srv->password, strlen(srv->password)+1)) {
391 cli_shutdown(c);
392 return 7;
393 }
394
395 DEBUG(4,(" tconx ok. cli caps %08x\n", c->capabilities));
396
397 // copy back cli_state
398 memcpy( cli, c, sizeof( struct cli_state));
399
400// srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
401
402 return 0;
403}
404
405/*****************************************************
406close a connection to a server
407*******************************************************/
408void _System smbwrp_disconnect(cli_state * cli)
409{
410 if (cli)
411 {
412 cli_shutdown(cli);
413 }
414}
415
416
417
418/*****************************************************
419a wrapper for open()
420*******************************************************/
421int _System smbwrp_open(cli_state * cli, smbwrp_file * file)
422{
423 int fd = -1;
424
425 if (!cli || !file || !*file->fname)
426 {
427 return EINVAL;
428 }
429 if (file->denymode < DENY_ALL || file->denymode > DENY_NONE)
430 {
431 file->denymode = DENY_NONE;
432 }
433
434 DEBUG(4,("cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode));
435 file->fd = cli_open(cli, file->fname, file->openmode, file->denymode);
436 if (file->fd == -1)
437 {
438 return os2cli_errno(cli);
439 }
440 if (file->openmode & (O_WRONLY | O_RDWR | O_TRUNC | O_CREAT))
441 {
442 time_t t;
443 file->mtime = time(NULL);
444 t = get_time_zone(file->mtime);
445 DEBUG(4,("cli_open mtime %lu %lu\n", file->mtime, t));
446 file->mtime -= t;
447 }
448 file->offset = 0;
449 return 0;
450}
451
452/*****************************************************
453a wrapper for read()
454*******************************************************/
455int _System smbwrp_read(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result)
456{
457 int ret;
458
459 if (!cli || !file || !buf || !result)
460 {
461 return EINVAL;
462 }
463
464 *result = 0;
465 ret = cli_read(cli, file->fd, buf, file->offset, count);
466 if (ret == -1)
467 {
468 return os2cli_errno(cli);
469 }
470
471 file->offset += ret;
472 *result = ret;
473 return 0;
474}
475
476
477
478/*****************************************************
479a wrapper for write()
480*******************************************************/
481int _System smbwrp_write(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result)
482{
483 int ret;
484
485 if (!cli || !file || !buf || !result)
486 {
487 return EINVAL;
488 }
489
490 *result = 0;
491//DEBUG(1,("Write %x %d %lld %d", cli, file->fd, file->offset, count));
492 ret = cli_write(cli, file->fd, 0, buf, file->offset, count);
493 if (ret == -1)
494 {
495 return os2cli_errno(cli);
496 }
497
498 file->offset += ret;
499 *result = ret;
500 return 0;
501}
502
503/*****************************************************
504a wrapper for close()
505*******************************************************/
506int _System smbwrp_close(cli_state * cli, smbwrp_file * file)
507{
508 int rc = 0;
509 if (!cli || !file)
510 {
511 return EINVAL;
512 }
513
514
515 if (!cli_close(cli, file->fd))
516 {
517 return os2cli_errno(cli);
518 }
519 file->fd = -1;
520 file->offset = 0;
521 if (file->openattr || file->mtime)
522 {
523 DEBUG(4,("Set attr on close %s %08x %d %d\n", file->fname, file->openattr, file->mtime, file->mtime + get_time_zone(file->mtime)));
524 if (!cli_setatr(cli, file->fname, file->openattr, file->mtime + get_time_zone(file->mtime)))
525 {
526 DEBUG(4,("Set attr on close failed %d\n", os2cli_errno(cli)));
527 //rc = os2cli_errno(cli);
528 }
529 file->openattr = 0;
530 file->mtime = 0;
531 }
532 *file->fname = 0;
533 return rc;
534}
535
536/*****************************************************
537a wrapper for setfilesize()
538*******************************************************/
539int cli_setfilenewsize(struct cli_state *cli, int fnum, off_t newsize)
540{
541 unsigned int data_len = 8;
542 unsigned int param_len = 6;
543 uint16 setup = TRANSACT2_SETFILEINFO;
544 pstring param;
545 char *rparam=NULL, *rdata=NULL;
546
547 memset(param, 0, param_len);
548 SSVAL(param,0,fnum);
549 SSVAL(param,2,SMB_SET_FILE_END_OF_FILE_INFO);
550
551 if (!cli_send_trans(cli, SMBtrans2,
552 NULL, /* name */
553 -1, 0, /* fid, flags */
554 &setup, 1, 0, /* setup, length, max */
555 param, param_len, 2, /* param, length, max */
556 (char *)&newsize, sizeof(newsize), cli->max_xmit /* data, length, max */
557 )) {
558 return False;
559 }
560
561 if (!cli_receive_trans(cli, SMBtrans2,
562 &rparam, &param_len,
563 &rdata, &data_len)) {
564 return False;
565 }
566
567 SAFE_FREE(rdata);
568 SAFE_FREE(rparam);
569
570 return True;
571}
572
573int _System smbwrp_setfilesize(cli_state * cli, smbwrp_file * file, long long newsize)
574{
575 int rc = 0;
576 if (!cli || !file)
577 {
578 return EINVAL;
579 }
580
581 DEBUG(4,("cli_setnewfileszie(%s) %lld\n", file->fname, newsize));
582 if (!cli_setfilenewsize(cli, file->fd, newsize))
583 {
584 if (newsize)
585 {
586 rc = os2cli_errno(cli);
587 }
588
589 if (!cli_close(cli, file->fd))
590 {
591 return os2cli_errno(cli);
592 }
593 file->fd = -1;
594 file->offset = 0;
595 file->openmode &= ~(O_CREAT | O_EXCL);
596 file->openmode |= O_TRUNC;
597 DEBUG(4,("cli_setnewfileszie : cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode));
598 file->fd = cli_open(cli, file->fname, file->openmode, file->denymode);
599 if (file->fd == -1)
600 {
601 return os2cli_errno(cli);
602 }
603 }
604 return 0;
605}
606
607/*****************************************************
608a wrapper for rename()
609*******************************************************/
610int _System smbwrp_rename(cli_state * cli, char *oldname, char *newname)
611{
612 if (!cli || !oldname || !newname)
613 {
614 return EINVAL;
615 }
616
617 DEBUG(1,("Rename <%s> -> <%s>\n", oldname, newname));
618 //cli_unlink(cli, newname);
619// if (!cli_rename(cli, oldname, newname) && !cli_ntrename(cli, oldname, newname))
620 if (!cli_rename(cli, oldname, newname))
621 {
622 return os2cli_errno(cli);
623 }
624 return 0;
625}
626
627
628/*****************************************************
629a wrapper for chmod()
630*******************************************************/
631int _System smbwrp_setattr(cli_state * cli, smbwrp_fileinfo *finfo)
632{
633 if (!cli || !finfo || !*finfo->fname)
634 {
635 return EINVAL;
636 }
637
638DEBUG(4,("Setting on <%s> attr %04x, time %lu/%lu\n", finfo->fname, finfo->attr, finfo->mtime, finfo->mtime + get_time_zone(finfo->mtime)));
639 if (!cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime + (finfo->mtime == 0 ? 0 : get_time_zone(finfo->mtime)))
640 && !cli_setatr(cli, finfo->fname, finfo->attr, 0))
641 {
642 return os2cli_errno(cli);
643 }
644 return 0;
645}
646
647/*****************************************************
648a wrapper for unlink()
649*******************************************************/
650int _System smbwrp_unlink(cli_state * cli, const char *fname)
651{
652 if (!cli || !fname)
653 {
654 return EINVAL;
655 }
656#if 0
657 if (strncmp(cli->dev, "LPT", 3) == 0)
658 {
659 int job = smbw_stat_printjob(cli, fname, NULL, NULL);
660 if (job == -1)
661 {
662 goto failed;
663 }
664 if (cli_printjob_del(cli, job) != 0)
665 {
666 goto failed;
667 }
668 } else
669#endif
670 if (!cli_unlink(cli, fname))
671 {
672 return os2cli_errno(cli);
673 }
674 return 0;
675}
676
677/*****************************************************
678a wrapper for lseek()
679*******************************************************/
680int _System smbwrp_lseek(cli_state * cli, smbwrp_file * file, int whence, long long offset)
681{
682 off_t size;
683 if (!cli || !file)
684 {
685 return EINVAL;
686 }
687
688 DEBUG(4,("lseek %d %lld %lld\n", whence, offset, file->offset));
689
690 switch (whence) {
691 case SEEK_SET:
692 if (offset < 0)
693 {
694 return EINVAL;
695 }
696 file->offset = offset;
697 break;
698 case SEEK_CUR:
699 file->offset += offset;
700 break;
701 case SEEK_END:
702 if (offset > 0)
703 {
704 return EINVAL;
705 }
706 if (!cli_qfileinfo3(cli, file->fd,
707 NULL, &size, NULL, NULL, NULL,
708 NULL, NULL) &&
709 !cli_getattrE(cli, file->fd,
710 NULL, (SMB_BIG_UINT *)&size, NULL, NULL, NULL))
711 {
712 return os2cli_errno(cli);
713 }
714 file->offset = size + offset;
715 break;
716 default: return EINVAL;
717 }
718
719 return 0;
720}
721
722/*****************************************************
723try to do a QPATHINFO and if that fails then do a getatr
724this is needed because win95 sometimes refuses the qpathinfo
725*******************************************************/
726int _System smbwrp_getattr(cli_state * cli, smbwrp_fileinfo *finfo)
727{
728 SMB_INO_T ino = 0;
729 if (!cli || !finfo || !*finfo->fname)
730 {
731 return EINVAL;
732 }
733 DEBUG(4,("getattr %d %d <%s>\n", cli->capabilities & CAP_NOPATHINFO2, cli->capabilities & CAP_NT_SMBS, finfo->fname));
734 if (!(cli->capabilities & CAP_NOPATHINFO2) &&
735 cli_qpathinfo3(cli, finfo->fname, (time_t *)&finfo->ctime, (time_t *)&finfo->atime, (time_t *)&finfo->mtime, NULL,
736 (off_t *)&finfo->size, (unsigned short *)&finfo->attr, &ino))
737 {
738 finfo->attr &= 0x7F;
739//DEBUG(2,("gotattr %08x <%s>\n", finfo->attr, finfo->fname));
740// finfo->ctime -= get_time_zone(finfo->ctime);
741// finfo->atime -= get_time_zone(finfo->atime);
742// finfo->mtime -= get_time_zone(finfo->mtime);
743 return 0;
744 }
745//DEBUG(2,("getattr rc1 %d\n", os2cli_errno(cli)));
746
747 /* if this is NT then don't bother with the getatr */
748 if (cli->capabilities & CAP_NT_SMBS && !(cli->capabilities & CAP_NOPATHINFO2))
749 {
750 int rc = os2cli_errno(cli);
751 // cli_qpathinfo* reports EINVAL when path of given file not exists
752 // thus there is no real situation when EINVAL should be returned to
753 // client at this point, we just replace it to ENOTDIR
754 if (rc == EINVAL)
755 {
756 rc = ENOTDIR;
757 }
758 return rc;
759 }
760
761 if (cli_getatr(cli, finfo->fname, (unsigned short *)&finfo->attr, (size_t *)&finfo->size, (time_t *)&finfo->mtime))
762 {
763//DEBUG(2,("gotattr1 %08x <%s>\n", finfo->attr, finfo->fname));
764 finfo->mtime -= get_time_zone(finfo->mtime);
765 finfo->atime = finfo->mtime;
766 finfo->ctime = finfo->mtime;
767 cli->capabilities &= CAP_NOPATHINFO2;
768 return 0;
769 }
770 return os2cli_errno(cli);
771}
772
773/*****************************************************
774try to do a QPATHINFO and if that fails then do a getatr
775this is needed because win95 sometimes refuses the qpathinfo
776*******************************************************/
777int _System smbwrp_fgetattr(cli_state * cli, smbwrp_file *file, smbwrp_fileinfo *finfo)
778{
779 SMB_INO_T ino = 0;
780 if (!cli || !file || !finfo)
781 {
782 return EINVAL;
783 }
784
785 strncpy(finfo->fname, file->fname, sizeof(finfo->fname) - 1);
786 if (!cli_qfileinfo3(cli, file->fd,
787 (unsigned short *)&finfo->attr, (off_t *)&finfo->size, (time_t *)&finfo->ctime, (time_t *)&finfo->atime, (time_t *)&finfo->mtime, NULL,
788 &ino))
789 {
790 if (!cli_getattrE(cli, file->fd,
791 (unsigned short *)&finfo->attr, (SMB_BIG_UINT *)(&finfo->size), (time_t *)&finfo->ctime, (time_t *)&finfo->atime, (time_t *)&finfo->mtime))
792 {
793 return os2cli_errno(cli);
794 }
795 else
796 {
797 finfo->ctime -= get_time_zone(finfo->ctime);
798 finfo->atime -= get_time_zone(finfo->atime);
799 finfo->mtime -= get_time_zone(finfo->mtime);
800 }
801 }
802 else
803 {
804// finfo->ctime -= get_time_zone(finfo->ctime);
805// finfo->atime -= get_time_zone(finfo->atime);
806// finfo->mtime -= get_time_zone(finfo->mtime);
807 }
808
809 return 0;
810}
811
812// =============================DIRECTORY ROUTINES============================
813
814/*****************************************************
815add a entry to a directory listing
816*******************************************************/
817static void smbwrp_dir_add(const char* mnt, smbwrp_fileinfo *finfo, const char *mask, void *state)
818{
819 if (state && finfo)
820 {
821 filelist_state * st = (filelist_state *)state;
822 if (st->add_dir_entry)
823 {
824DEBUG(8,("adding <%s> %d %d\n", finfo->fname, sizeof(st->finfo), st->datalen));
825 memcpy(&st->finfo, finfo, sizeof(st->finfo));
826 st->add_dir_entry(state);
827 }
828 }
829}
830#if 0
831static void smbwrp_dir_add_old(struct file_info *finfo, const char *mask, void *state)
832{
833 if (state && finfo)
834 {
835 filelist_state * st = (filelist_state *)state;
836 if (st->add_dir_entry)
837 {
838 strncpy(st->finfo.fname, finfo->name, sizeof(st->finfo.fname) - 1);
839 st->finfo.size = finfo->size;
840 st->finfo.easize = -1;
841 st->finfo.attr = finfo->mode;
842 st->finfo.ctime = finfo->ctime_ts.tv_sec - get_time_zone(finfo->ctime_ts.tv_sec);
843 st->finfo.mtime = finfo->mtime_ts.tv_sec - get_time_zone(finfo->mtime_ts.tv_sec);
844 st->finfo.atime = finfo->atime_ts.tv_sec - get_time_zone(finfo->atime_ts.tv_sec);
845 st->add_dir_entry(state);
846 }
847 }
848}
849#endif
850
851static void smbwrp_special_add(const char * name, void * state)
852{
853 smbwrp_fileinfo finfo = {0};
854
855 if (!name)
856 {
857 return;
858 }
859
860 ZERO_STRUCT(finfo);
861
862 strncpy(finfo.fname, name, sizeof(finfo.fname) - 1);
863 finfo.attr = aRONLY | aDIR;
864
865 smbwrp_dir_add("", &finfo, NULL, state);
866}
867
868static void smbwrp_printjob_add(struct print_job_info *job, void * state)
869{
870 smbwrp_fileinfo finfo = {0};
871
872 ZERO_STRUCT(finfo);
873
874//printf("Printjob <%s>\n", job->name);
875
876 strncpy(finfo.fname, job->name, sizeof(finfo.fname) - 1);
877 finfo.mtime = job->t - get_time_zone(job->t);
878 finfo.atime = finfo.mtime;
879 finfo.ctime = finfo.mtime;
880 finfo.attr = aRONLY;
881 finfo.size = job->size;
882
883 smbwrp_dir_add("", &finfo, NULL, state);
884}
885
886static void smbwrp_share_add(const char *share, uint32 type,
887 const char *comment, void *state)
888{
889 smbwrp_fileinfo finfo = {0};
890
891 if (strcmp(share,"IPC$") == 0) return;
892
893 ZERO_STRUCT(finfo);
894
895 strncpy(finfo.fname, share, sizeof(finfo.fname) - 1);
896 finfo.attr = aRONLY | aDIR;
897
898 smbwrp_dir_add("", &finfo, NULL, state);
899}
900
901/****************************************************************************
902 Interpret a long filename structure - this is mostly guesses at the moment.
903 The length of the structure is returned
904 The structure of a long filename depends on the info level. 260 is used
905 by NT and 2 is used by OS/2
906****************************************************************************/
907// YD from libsmb\clilist.c
908static size_t _os2_interpret_long_filename(struct cli_state *cli,
909 int level,char *p, smbwrp_fileinfo *finfo,
910 uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len)
911{
912 extern file_info def_finfo;
913 int len;
914 char *base = p;
915 smbwrp_fileinfo finfo1;
916
917 if (!finfo) finfo = &finfo1;
918
919// memcpy(finfo,&def_finfo,sizeof(*finfo));
920 finfo->attr = def_finfo.mode;
921 finfo->mtime = def_finfo.mtime_ts.tv_sec;
922 finfo->atime = def_finfo.atime_ts.tv_sec;
923 finfo->ctime = def_finfo.ctime_ts.tv_sec;
924 strncpy(finfo->fname, def_finfo.name, sizeof(finfo->fname) - 1);
925
926 switch (level) {
927 case 1: /* OS/2 understands this */
928 /* these dates are converted to GMT by
929 make_unix_date */
930 finfo->ctime = cli_make_unix_date2(cli, p+4);
931 finfo->atime = cli_make_unix_date2(cli, p+8);
932 finfo->mtime = cli_make_unix_date2(cli, p+12);
933 finfo->size = IVAL(p,16);
934 finfo->attr = CVAL(p,24);
935 len = CVAL(p, 26);
936 p += 27;
937 p += clistr_align_in(cli, p, 0);
938 /* the len+2 below looks strange but it is
939 important to cope with the differences
940 between win2000 and win9x for this call
941 (tridge) */
942 p += clistr_pull(cli, finfo->fname, p,
943 sizeof(finfo->fname),
944 len+2,
945 STR_TERMINATE);
946 finfo->easize = -1;
947 return PTR_DIFF(p, base);
948
949 case 2: /* this is what OS/2 uses mostly */
950 /* these dates are converted to GMT by
951 make_unix_date */
952 finfo->ctime = cli_make_unix_date2(cli, p+4);
953 finfo->atime = cli_make_unix_date2(cli, p+8);
954 finfo->mtime = cli_make_unix_date2(cli, p+12);
955 finfo->size = IVAL(p,16);
956 finfo->attr = CVAL(p,24);
957 finfo->easize = IVAL(p,26);
958 len = CVAL(p, 30);
959 p += 31;
960 /* check for unisys! */
961 p += clistr_pull(cli, finfo->fname, p,
962 sizeof(finfo->fname),
963 len,
964 STR_NOALIGN);
965 return PTR_DIFF(p, base) + 1;
966
967 case 260: /* NT uses this, but also accepts 2 */
968 {
969 size_t namelen, slen;
970 p += 4; /* next entry offset */
971#if 0
972 if (p_resume_key) {
973 *p_resume_key = IVAL(p,0);
974 }
975#endif
976 p += 4; /* fileindex */
977
978 /* Offset zero is "create time", not "change time". */
979 p += 8;
980 finfo->atime = interpret_long_date(p).tv_sec;
981 p += 8;
982 finfo->mtime = interpret_long_date(p).tv_sec;
983 p += 8;
984 finfo->ctime = interpret_long_date(p).tv_sec;
985 p += 8;
986 finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
987 p += 8;
988 p += 8; /* alloc size */
989 finfo->attr = CVAL(p,0);
990 p += 4;
991 namelen = IVAL(p,0);
992 p += 4;
993 p += 4; /* EA size */
994 slen = SVAL(p, 0);
995 p += 2;
996#if 0
997 {
998 /* stupid NT bugs. grr */
999 int flags = 0;
1000 if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE;
1001 clistr_pull(cli, finfo->short_name, p,
1002 sizeof(finfo->short_name),
1003 slen, flags);
1004 }
1005#endif
1006 p += 24; /* short name? */
1007 clistr_pull(cli, finfo->fname, p,
1008 sizeof(finfo->fname),
1009 namelen, 0);
1010
1011 /* To be robust in the face of unicode conversion failures
1012 we need to copy the raw bytes of the last name seen here.
1013 Namelen doesn't include the terminating unicode null, so
1014 copy it here. */
1015#if 0
1016 if (p_last_name_raw && p_last_name_raw_len) {
1017 if (namelen + 2 > p_last_name_raw->length) {
1018 memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length));
1019 *p_last_name_raw_len = 0;
1020 } else {
1021 memcpy(p_last_name_raw->data, p, namelen);
1022 SSVAL(p_last_name_raw->data, namelen, 0);
1023 *p_last_name_raw_len = namelen + 2;
1024 }
1025 }
1026#endif
1027 return (size_t)IVAL(base, 0);
1028 }
1029 }
1030
1031 DEBUG(1,("Unknown long filename format %d\n",level));
1032 return (size_t)IVAL(base,0);
1033}
1034
1035/****************************************************************************
1036 Do a directory listing, calling fn on each file found.
1037 Modified from cli_list_new
1038****************************************************************************/
1039
1040static int list_files(struct cli_state *cli, const char *Mask, uint16 attribute,
1041 void (*fn)(const char*, smbwrp_fileinfo *, const char *, void *), void *state)
1042{
1043#if 1
1044 int max_matches = 1366; /* Match W2k - was 512. */
1045#else
1046 int max_matches = 512;
1047#endif
1048 int info_level;
1049 char *p, *p2;
1050 pstring mask;
1051 smbwrp_fileinfo finfo;
1052 int i;
1053 char *tdl, *dirlist = NULL;
1054 int dirlist_len = 0;
1055 int total_received = -1;
1056 BOOL First = True;
1057 int ff_searchcount=0;
1058 int ff_eos=0;
1059 //int ff_lastname=0;
1060 int ff_dir_handle=0;
1061 int loop_count = 0;
1062 char *rparam=NULL, *rdata=NULL;
1063 unsigned int param_len, data_len;
1064 uint16 setup;
1065 pstring param;
1066 const char *mnt;
1067 uint32 resume_key = 0;
1068 uint32 last_name_raw_len = 0;
1069 DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring));
1070
1071 /* NT uses 260, OS/2 uses 2. Both accept 1. */
1072 info_level = (cli->capabilities&CAP_NT_SMBS)?260:2;
1073
1074 DEBUG(4,("list_files level %d. mask <%s>\n", info_level, mask));
1075
1076 /* when getting a directory listing from a 2k dfs root share,
1077 we have to include the full path (\server\share\mask) here */
1078
1079 if ( cli->dfsroot )
1080 pstr_sprintf( mask, "\\%s\\%s\\%s", cli->desthost, cli->share, Mask );
1081 else
1082 pstrcpy(mask,Mask);
1083
1084 while (ff_eos == 0) {
1085 loop_count++;
1086 if (loop_count > 200) {
1087 DEBUG(0,("Error: Looping in FIND_NEXT??\n"));
1088 break;
1089 }
1090
1091 if (First) {
1092 setup = TRANSACT2_FINDFIRST;
1093 SSVAL(param,0,attribute); /* attribute */
1094 SSVAL(param,2,max_matches); /* max count */
1095 //SSVAL(param,4,4+2); /* resume required + close on end */
1096 SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */
1097 SSVAL(param,6,info_level);
1098 SIVAL(param,8,0);
1099 p = param+12;
1100 p += clistr_push(cli, param+12, mask, sizeof(param)-12,
1101 STR_TERMINATE);
1102 } else {
1103 setup = TRANSACT2_FINDNEXT;
1104 SSVAL(param,0,ff_dir_handle);
1105 SSVAL(param,2,max_matches); /* max count */
1106 //SIVAL(param,6,0); /* ff_resume_key */
1107 SSVAL(param,4,info_level);
1108 /* For W2K servers serving out FAT filesystems we *must* set the
1109 resume key. If it's not FAT then it's returned as zero. */
1110 SIVAL(param,6,resume_key); /* ff_resume_key */
1111 /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren
1112 can miss filenames. Use last filename continue instead. JRA */
1113 SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */
1114 //SSVAL(param,10,8+4+2); /* continue + resume required + close on end */
1115 p = param+12;
1116 //p += clistr_push(cli, param+12, mask, sizeof(param)-12,
1117 // STR_TERMINATE);
1118 if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) {
1119 memcpy(p, last_name_raw.data, last_name_raw_len);
1120 p += last_name_raw_len;
1121 } else {
1122 p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE);
1123 }
1124 }
1125
1126 param_len = PTR_DIFF(p, param);
1127 if (!cli_send_trans(cli, SMBtrans2,
1128 NULL, /* Name */
1129 -1, 0, /* fid, flags */
1130 &setup, 1, 0, /* setup, length, max */
1131 param, param_len, 10, /* param, length, max */
1132 NULL, 0,
1133#if 0
1134 /* w2k value. */
1135 MIN(16384,cli->max_xmit) /* data, length, max. */
1136#else
1137 cli->max_xmit /* data, length, max. */
1138#endif
1139 )) {
1140 break;
1141 }
1142
1143 if (!cli_receive_trans(cli, SMBtrans2,
1144 &rparam, &param_len,
1145 &rdata, &data_len) &&
1146 cli_is_dos_error(cli)) {
1147 /* we need to work around a Win95 bug - sometimes
1148 it gives ERRSRV/ERRerror temprarily */
1149 uint8 eclass;
1150 uint32 ecode;
1151
1152 SAFE_FREE(rdata);
1153 SAFE_FREE(rparam);
1154
1155 cli_dos_error(cli, &eclass, &ecode);
1156 if (eclass != ERRSRV || ecode != ERRerror)
1157 break;
1158 smb_msleep(100);
1159 continue;
1160 }
1161
1162
1163 if (cli_is_error(cli) || !rdata || !rparam)
1164 {
1165 if (First && info_level == 2)
1166 {
1167 // we have tried query ea size, but now will try without ea size
1168 info_level = 1;
1169 DEBUG(4,("list_files fallback to level %d\n", info_level));
1170 continue;
1171 }
1172 SAFE_FREE(rdata);
1173 SAFE_FREE(rparam);
1174 break;
1175 }
1176
1177 if (total_received == -1)
1178 total_received = 0;
1179
1180 /* parse out some important return info */
1181 p = rparam;
1182 if (First) {
1183 ff_dir_handle = SVAL(p,0);
1184 ff_searchcount = SVAL(p,2);
1185 ff_eos = SVAL(p,4);
1186 //ff_lastname = SVAL(p,8);
1187 } else {
1188 ff_searchcount = SVAL(p,0);
1189 ff_eos = SVAL(p,2);
1190 //ff_lastname = SVAL(p,6);
1191 }
1192 DEBUG(4,("list_files %d %d %d %d\n", ff_searchcount, ff_eos, "(ff_lastname)", First));
1193
1194 if (ff_searchcount == 0) {
1195 SAFE_FREE(rdata);
1196 SAFE_FREE(rparam);
1197 break;
1198 }
1199
1200 /* point to the data bytes */
1201 p = rdata;
1202
1203 memset(&finfo, 0, sizeof(finfo));
1204 finfo.easize = -1;
1205 /* we might need the lastname for continuations */
1206 for (p2=p,i=0;i<ff_searchcount;i++) {
1207 if ((info_level == 260) && (i == ff_searchcount-1)) {
1208 /* Last entry - fixup the last offset length. */
1209 SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));
1210 }
1211 p2 += _os2_interpret_long_filename(cli,info_level,p2,&finfo,
1212 &resume_key,&last_name_raw,&last_name_raw_len);
1213
1214 if (!First && *mask && strcsequal(finfo.fname, mask)) {
1215 DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n",
1216 finfo.fname));
1217 ff_eos = 1;
1218 break;
1219 }
1220 }
1221
1222 if (ff_searchcount > 0) {
1223 pstrcpy(mask, finfo.fname);
1224 } else {
1225 pstrcpy(mask,"");
1226 }
1227
1228 /* grab the data for later use */
1229 /* and add them to the dirlist pool */
1230 dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len);
1231
1232 if (!dirlist) {
1233 DEBUG(0,("cli_list_new: Failed to expand dirlist\n"));
1234 SAFE_FREE(rdata);
1235 SAFE_FREE(rparam);
1236 break;
1237 }
1238
1239 memcpy(dirlist+dirlist_len,p,data_len);
1240 dirlist_len += data_len;
1241
1242 total_received += ff_searchcount;
1243
1244 SAFE_FREE(rdata);
1245 SAFE_FREE(rparam);
1246
1247 DEBUG(3,("received %d entries (eos=%d)\n",
1248 ff_searchcount,ff_eos));
1249
1250 if (ff_searchcount > 0)
1251 loop_count = 0;
1252
1253 First = False;
1254 }
1255
1256 mnt = cli_cm_get_mntpoint( cli );
1257
1258 /* see if the server disconnected or the connection otherwise failed */
1259 if (cli_is_error(cli)) {
1260 total_received = -1;
1261 } else {
1262 /* no connection problem. let user function add each entry */
1263 for (p=dirlist,i=0;i<total_received;i++) {
1264 p += _os2_interpret_long_filename(cli, info_level, p,
1265 &finfo,NULL,NULL,NULL);
1266 fn( mnt,&finfo, Mask, state );
1267 }
1268 }
1269
1270 /* free up the dirlist buffer and last name raw blob */
1271 SAFE_FREE(dirlist);
1272 data_blob_free(&last_name_raw);
1273 return(total_received);
1274}
1275
1276
1277/*****************************************************
1278open a directory on the server
1279*******************************************************/
1280int _System smbwrp_filelist(smbwrp_server *srv, cli_state * cli, filelist_state * state)
1281{
1282 if (!srv || !cli || !state || !*state->mask)
1283 {
1284 return EINVAL;
1285 }
1286 DEBUG(1,("Filelist <%s> on master <%s> wgrp <%s> server <%s> share <%s> clidev <%s>\n", state->mask, srv->master, srv->workgroup, srv->server_name, srv->share_name, cli->dev));
1287 if (*srv->workgroup == 0 && *srv->server_name == 0)
1288 {
1289 smbwrp_special_add(".", state);
1290 smbwrp_special_add("..", state);
1291 cli_NetServerEnum(cli, srv->master, SV_TYPE_DOMAIN_ENUM,
1292 smbwrp_share_add, state);
1293 } else
1294 if (*srv->server_name == 0)
1295 {
1296 smbwrp_special_add(".", state);
1297 smbwrp_special_add("..", state);
1298
1299 cli_NetServerEnum(cli, srv->workgroup, SV_TYPE_ALL,
1300 smbwrp_share_add, state);
1301 } else
1302 if ((strcmp(cli->dev,"IPC") == 0) || *srv->share_name == 0 || (stricmp(srv->share_name,"IPC$") == 0))
1303 {
1304 smbwrp_special_add(".", state);
1305 smbwrp_special_add("..", state);
1306 if (cli_RNetShareEnum(cli, smbwrp_share_add, state) < 0)
1307 {
1308 return os2cli_errno(cli);
1309 }
1310 } else
1311 if (strncmp(cli->dev,"LPT",3) == 0)
1312 {
1313 smbwrp_special_add(".", state);
1314 smbwrp_special_add("..", state);
1315 if (cli_print_queue_state(cli, smbwrp_printjob_add, state) < 0)
1316 {
1317 return os2cli_errno(cli);
1318 }
1319 }
1320 else
1321 {
1322#if 0
1323 if (strcmp(path,"\\") == 0) {
1324 smbwrp_special_add(".", state);
1325 smbwrp_special_add("..", state);
1326 }
1327#endif
1328#if 0
1329 if (cli_list(cli, state->mask, aHIDDEN|aSYSTEM|aDIR,
1330 smbwrp_dir_add_old, state) < 0)
1331#else
1332 if (list_files(cli, state->mask, aHIDDEN|aSYSTEM|aDIR,
1333 smbwrp_dir_add, state) < 0)
1334#endif
1335 {
1336 return os2cli_errno(cli);
1337 }
1338 }
1339
1340 return 0;
1341}
1342
1343/*****************************************************
1344a wrapper for chdir()
1345*******************************************************/
1346int _System smbwrp_chdir(cli_state * cli, char *fname)
1347{
1348 unsigned short mode = aDIR;
1349 smbwrp_fileinfo finfo = {0};
1350 if (!cli || !fname)
1351 {
1352 return EINVAL;
1353 }
1354
1355 strncpy(finfo.fname, fname, sizeof(finfo.fname) - 1);
1356 if (!smbwrp_getattr(cli, &finfo))
1357 {
1358 return os2cli_errno(cli);
1359 }
1360
1361 if (!(finfo.attr & aDIR)) {
1362 return ENOTDIR;
1363 }
1364
1365 return 0;
1366}
1367
1368
1369/*****************************************************
1370a wrapper for mkdir()
1371*******************************************************/
1372int _System smbwrp_mkdir(cli_state * cli, char *fname)
1373{
1374 if (!cli || !fname)
1375 {
1376 return EINVAL;
1377 }
1378
1379 if (!cli_mkdir(cli, fname))
1380 {
1381 return os2cli_errno(cli);
1382 }
1383 return 0;
1384}
1385
1386/*****************************************************
1387a wrapper for rmdir()
1388*******************************************************/
1389int _System smbwrp_rmdir(cli_state * cli, char *fname)
1390{
1391 if (!cli || !fname)
1392 {
1393 return EINVAL;
1394 }
1395
1396 if (!cli_rmdir(cli, fname))
1397 {
1398 return os2cli_errno(cli);
1399 }
1400 return 0;
1401}
1402
1403/*****************************************************
1404set EA for a path
1405*******************************************************/
1406int _System smbwrp_setea(cli_state * cli, char *fname, char * name, unsigned char * value, int size)
1407{
1408 if (!cli || !fname || !name)
1409 {
1410 return EINVAL;
1411 }
1412 if (!cli_set_ea_path(cli, fname, name, value, size))
1413 {
1414 return os2cli_errno(cli);
1415 }
1416 return 0;
1417}
1418
1419/*****************************************************
1420set EA for a file
1421*******************************************************/
1422int _System smbwrp_fsetea(cli_state * cli, smbwrp_file *file, char * name, unsigned char * value, int size)
1423{
1424 if (!cli || !file || !name)
1425 {
1426 return EINVAL;
1427 }
1428 if (!cli_set_ea_fnum(cli, file->fd, name, value, size))
1429 {
1430 return os2cli_errno(cli);
1431 }
1432 return 0;
1433}
1434
1435
1436#pragma pack(1)
1437typedef struct _FEA /* fea */
1438{
1439 unsigned char fEA; /* flags */
1440 unsigned char cbName; /* name length not including NULL */
1441 unsigned short cbValue; /* value length */
1442} FEA;
1443
1444typedef struct _FEALIST /* feal */
1445{
1446 unsigned long cbList; /* total bytes of structure including full list */
1447 FEA list[1]; /* variable length FEA structures */
1448} FEALIST;
1449#pragma pack()
1450
1451static int unilistea(cli_state * cli, char *fname, smbwrp_file *file, void * buffer, unsigned long size)
1452{
1453 int fnum, i;
1454 int gotsize = sizeof(unsigned long);
1455 size_t num_eas;
1456 struct ea_struct *ea_list = NULL;
1457 TALLOC_CTX *mem_ctx;
1458 FEA * p;
1459 FEALIST * pfealist;
1460 char * q;
1461
1462 mem_ctx = talloc_init("%d: ealist", _gettid());
1463 pfealist = (FEALIST *)buffer;
1464 pfealist->cbList = 0;
1465
1466 if (file)
1467 {
1468 if (!cli_get_ea_list_fnum(cli, file->fd, mem_ctx, &num_eas, &ea_list))
1469 {
1470 DEBUG(4,("ea_get_fnum list failed - %s\n", cli_errstr(cli)));
1471 talloc_destroy(mem_ctx);
1472 return os2cli_errno(cli);
1473 }
1474 }
1475 else
1476 {
1477 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list))
1478 {
1479 DEBUG(4,("ea_get_file list failed - %s\n", cli_errstr(cli)));
1480 talloc_destroy(mem_ctx);
1481 return os2cli_errno(cli);
1482 }
1483 }
1484
1485 DEBUG(4,("num_eas = %d\n", num_eas));
1486
1487 // we will count that os/2 max EA size for file is 64kb
1488 p = pfealist->list;
1489 for (i = 0; i < num_eas; i++)
1490 {
1491 int namelen = strlen(ea_list[i].name);
1492 DEBUG(4, ("%d Got EA <%s> with namelen %d, size %d. Gross %d. Buf %d\n", i, ea_list[i].name, namelen, ea_list[i].value.length, gotsize, size));
1493 if (namelen > 0xFF || ea_list[i].value.length > 0xFFFF)
1494 {
1495 DEBUG(4, ("Skip EA <%s> with namelen %d, size %d\n", ea_list[i].name, namelen, ea_list[i].value.length));
1496 continue;
1497 }
1498 gotsize += sizeof(FEA) + namelen + ea_list[i].value.length + 1;
1499 if (size >= gotsize)
1500 {
1501 p->fEA = 0;
1502 p->cbName = namelen;
1503 p->cbValue = ea_list[i].value.length;
1504 q = (char *)(p + 1);
1505 strncpy(q, ea_list[i].name, namelen + 1);
1506 q += namelen + 1;
1507 memcpy(q, ea_list[i].value.data, ea_list[i].value.length);
1508 p = (FEA *)(q + ea_list[i].value.length);
1509 }
1510 }
1511 pfealist->cbList = gotsize;
1512 DEBUG(4,("ret size = %d\n", gotsize));
1513
1514 talloc_destroy(mem_ctx);
1515 return 0;
1516}
1517
1518/*****************************************************
1519lists EA of a path
1520*******************************************************/
1521int _System smbwrp_listea(cli_state * cli, char *fname, void * buffer, unsigned long size)
1522{
1523 if (!cli || !fname || !buffer)
1524 {
1525 return EINVAL;
1526 }
1527
1528 DEBUG(4,("EALIst for <%s>\n", fname));
1529 return unilistea(cli, fname, NULL, buffer, size);
1530}
1531
1532/*****************************************************
1533lists EA of a file
1534*******************************************************/
1535int _System smbwrp_flistea(cli_state * cli, smbwrp_file *file, void * buffer, unsigned long size)
1536{
1537 if (!cli || !file || !buffer)
1538 {
1539 return EINVAL;
1540 }
1541
1542 DEBUG(4,("FEALIst for <%s>/%d\n", file->fname, file->fd));
1543 return unilistea(cli, NULL, file, buffer, size);
1544}
1545
1546/****************************************************************************
1547Check the space on a device.
1548****************************************************************************/
1549int _System smbwrp_dskattr(cli_state * cli, FSALLOCATE *pfsa)
1550{
1551 int total, bsize, avail;
1552
1553 if (!cli || !pfsa)
1554 {
1555 return EINVAL;
1556 }
1557
1558 if (!cli_dskattr(cli, &bsize, &total, &avail))
1559 {
1560 DEBUG(4,("Error in dskattr: %s\n",cli_errstr(cli)));
1561 return os2cli_errno(cli);
1562 }
1563
1564 DEBUG(4,("\n\t\t%d blocks of size %d. %d blocks available\n",
1565 total, bsize, avail));
1566
1567 // YD currently Samba return it in MB!
1568 pfsa->cSectorUnit = 1;
1569 if (bsize > 65536)
1570 {
1571 pfsa->cUnit = total*1024;
1572 pfsa->cUnitAvail = avail*1024;
1573 pfsa->cbSector = bsize/1024;
1574 }
1575 else
1576 {
1577 pfsa->cUnit = total;
1578 pfsa->cUnitAvail = avail;
1579 pfsa->cbSector = bsize;
1580 }
1581
1582 return 0;
1583}
Note: See TracBrowser for help on using the repository browser.