2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 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.
23 #include "realcalls.h"
27 static struct smbw_file *smbw_files;
28 static struct smbw_server *smbw_srvs;
30 struct bitmap *smbw_file_bmap;
31 extern pstring global_myname;
32 extern int DEBUGLEVEL;
34 fstring smbw_prefix = SMBW_PREFIX;
38 /* needs to be here because of dumb include files on some systems */
39 int creat_bits = O_WRONLY|O_CREAT|O_TRUNC;
42 /*****************************************************
44 *******************************************************/
47 extern BOOL in_client;
48 static int initialised;
49 static pstring servicesf = CONFIGFILE;
54 if (initialised) return;
62 setup_logging("smbsh",True);
66 if ((p=smbw_getshared("LOGFILE"))) {
67 dbf = sys_fopen(p, "a");
70 smbw_file_bmap = bitmap_allocate(SMBW_MAX_OPEN);
71 if (!smbw_file_bmap) {
79 if ((p=smbw_getshared("SERVICESF"))) {
80 pstrcpy(servicesf, p);
83 lp_load(servicesf,True,False,False);
87 get_myname(global_myname);
89 if ((p=smbw_getshared("DEBUG"))) {
93 if ((p=smbw_getshared("RESOLVE_ORDER"))) {
94 lp_set_name_resolve_order(p);
97 if ((p=smbw_getshared("PREFIX"))) {
98 slprintf(smbw_prefix,sizeof(fstring)-1, "/%s/", p);
99 all_string_sub(smbw_prefix,"//", "/", 0);
100 DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix));
103 slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
105 p = smbw_getshared(line);
109 pstrcpy(smbw_cwd, p);
110 DEBUG(4,("Initial cwd is %s\n", smbw_cwd));
114 set_maxfiles(SMBW_MAX_OPEN);
116 BlockSignals(True,SIGPIPE);
121 /*****************************************************
122 determine if a file descriptor is a smb one
123 *******************************************************/
126 if (smbw_busy) return 0;
127 return smbw_file_bmap && bitmap_query(smbw_file_bmap, fd);
130 /*****************************************************
131 determine if a file descriptor is an internal smbw fd
132 *******************************************************/
133 int smbw_local_fd(int fd)
135 struct smbw_server *srv;
139 if (smbw_busy) return 0;
140 if (smbw_shared_fd(fd)) return 1;
142 for (srv=smbw_srvs;srv;srv=srv->next) {
143 if (srv->cli.fd == fd) return 1;
149 /*****************************************************
150 a crude inode number generator
151 *******************************************************/
152 ino_t smbw_inode(const char *name)
154 if (!*name) return 2;
155 return (ino_t)str_checksum(name);
158 /*****************************************************
159 remove redundent stuff from a filename
160 *******************************************************/
161 void clean_fname(char *name)
172 DEBUG(5,("cleaning %s\n", name));
174 if ((p=strstr(name,"/./"))) {
182 if ((p=strstr(name,"//"))) {
190 if (strcmp(name,"/../")==0) {
195 if ((p=strstr(name,"/../"))) {
197 for (p2=(p>name?p-1:p);p2>name;p2--) {
198 if (p2[0] == '/') break;
206 if (strcmp(name,"/..")==0) {
212 p = l>=3?(name+l-3):name;
213 if (strcmp(p,"/..")==0) {
215 for (p2=p-1;p2>name;p2--) {
216 if (p2[0] == '/') break;
227 p = l>=2?(name+l-2):name;
228 if (strcmp(p,"/.")==0) {
236 if (strncmp(p=name,"./",2) == 0) {
244 if (l > 1 && p[l-1] == '/') {
253 /*****************************************************
254 find a workgroup (any workgroup!) that has a master
255 browser on the local network
256 *******************************************************/
257 static char *smbw_find_workgroup(void)
261 struct in_addr *ip_list = NULL;
265 /* first off see if an existing workgroup name exists */
266 p = smbw_getshared("WORKGROUP");
267 if (!p) p = lp_workgroup();
269 slprintf(server, sizeof(server), "%s#1D", p);
270 if (smbw_server(server, "IPC$")) return p;
272 /* go looking for workgroups */
273 if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
274 DEBUG(1,("No workgroups found!"));
278 for (i=0;i<count;i++) {
280 if (name_status_find(0x1d, ip_list[i], name)) {
281 slprintf(server, sizeof(server), "%s#1D", name);
282 if (smbw_server(server, "IPC$")) {
283 smbw_setshared("WORKGROUP", name);
295 /*****************************************************
296 parse a smb path into its components.
298 1) the name of the SMB server
299 2) WORKGROUP#1D for share listing
300 3) WORKGROUP#__ for workgroup listing
301 share is the share on the server to query
302 path is the SMB path on the server
303 return the full path (ie. add cwd if needed)
304 *******************************************************/
305 char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
312 /* add cwd if necessary */
313 if (fname[0] != '/') {
314 slprintf(s, sizeof(s), "%s/%s", smbw_cwd, fname);
320 /* see if it has the right prefix */
321 len = strlen(smbw_prefix)-1;
322 if (strncmp(s,smbw_prefix,len) ||
323 (s[len] != '/' && s[len] != 0)) return s;
325 /* ok, its for us. Now parse out the workgroup, share etc. */
328 if (!next_token(&p, workgroup, "/", sizeof(fstring))) {
329 /* we're in /smb - give a list of workgroups */
330 slprintf(server,sizeof(fstring), "%s#01", smbw_find_workgroup());
331 fstrcpy(share,"IPC$");
336 if (!next_token(&p, server, "/", sizeof(fstring))) {
337 /* we are in /smb/WORKGROUP */
338 slprintf(server,sizeof(fstring), "%s#1D", workgroup);
339 fstrcpy(share,"IPC$");
343 if (!next_token(&p, share, "/", sizeof(fstring))) {
344 /* we are in /smb/WORKGROUP/SERVER */
345 fstrcpy(share,"IPC$");
351 all_string_sub(path, "/", "\\", 0);
356 /*****************************************************
357 determine if a path name (possibly relative) is in the
359 *******************************************************/
360 int smbw_path(const char *path)
362 fstring server, share;
370 /* this is needed to prevent recursion with the BSD malloc which
371 opens /etc/malloc.conf on the first call */
372 if (strncmp(path,"/etc/", 5) == 0) {
378 len = strlen(smbw_prefix)-1;
380 if (path[0] == '/' && strncmp(path,smbw_prefix,len)) {
384 if (smbw_busy) return 0;
386 DEBUG(3,("smbw_path(%s)\n", path));
388 cwd = smbw_parse_path(path, server, share, s);
390 if (strncmp(cwd,smbw_prefix,len) == 0 &&
391 (cwd[len] == '/' || cwd[len] == 0)) {
398 /*****************************************************
399 return a unix errno from a SMB error pair
400 *******************************************************/
401 int smbw_errno(struct cli_state *c)
406 /* Return a username and password given a server and share name */
408 void get_envvar_auth_data(char *server, char *share, char **workgroup,
409 char **username, char **password)
411 /* Fall back to shared memory/environment variables */
413 *username = smbw_getshared("USER");
414 if (!*username) *username = getenv("USER");
415 if (!*username) *username = "guest";
417 *workgroup = smbw_getshared("WORKGROUP");
418 if (!*workgroup) *workgroup = lp_workgroup();
420 *password = smbw_getshared("PASSWORD");
421 if (!*password) *password = "";
424 static smbw_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data;
426 /*****************************************************
427 set the get auth data function
428 ******************************************************/
429 void smbw_set_auth_data_fn(smbw_get_auth_data_fn fn)
431 get_auth_data_fn = fn;
434 /*****************************************************
435 return a connection to a server (existing or new)
436 *******************************************************/
437 struct smbw_server *smbw_server(char *server, char *share)
439 struct smbw_server *srv=NULL;
444 struct nmb_name called, calling;
445 char *p, *server_n = server;
449 extern struct in_addr ipzero;
454 get_auth_data_fn(server, share, &workgroup, &username, &password);
456 /* try to use an existing connection */
457 for (srv=smbw_srvs;srv;srv=srv->next) {
458 if (strcmp(server,srv->server_name)==0 &&
459 strcmp(share,srv->share_name)==0 &&
460 strcmp(workgroup,srv->workgroup)==0 &&
461 strcmp(username, srv->username) == 0)
465 if (server[0] == 0) {
470 make_nmb_name(&calling, global_myname, 0x0);
471 make_nmb_name(&called , server, 0x20);
473 DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server));
475 if ((p=strchr_m(server_n,'#')) &&
476 (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) {
480 fstrcpy(group, server_n);
481 p = strchr_m(group,'#');
484 /* cache the workgroup master lookup */
485 slprintf(s,sizeof(s)-1,"MASTER_%s", group);
486 if (!(server_n = smbw_getshared(s))) {
487 if (!find_master_ip(group, &sip)) {
491 fstrcpy(group, inet_ntoa(sip));
493 smbw_setshared(s,server_n);
497 DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
500 slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
503 if ((p=smbw_getshared(ipenv))) {
504 ip = *(interpret_addr2(p));
507 /* have to open a new connection */
508 if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) {
513 if (!cli_session_request(&c, &calling, &called)) {
515 if (strcmp(called.name, "*SMBSERVER")) {
516 make_nmb_name(&called , "*SMBSERVER", 0x20);
523 DEBUG(4,(" session request ok\n"));
525 if (!cli_negprot(&c)) {
531 if (!cli_session_setup(&c, username,
532 password, strlen(password),
533 password, strlen(password),
535 /* try an anonymous login if it failed */
536 !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {
542 DEBUG(4,(" session setup ok\n"));
544 if (!cli_send_tconX(&c, share, "?????",
545 password, strlen(password)+1)) {
546 errno = smbw_errno(&c);
551 smbw_setshared(ipenv,inet_ntoa(ip));
553 DEBUG(4,(" tconx ok\n"));
555 srv = (struct smbw_server *)malloc(sizeof(*srv));
565 srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
567 srv->server_name = strdup(server);
568 if (!srv->server_name) {
573 srv->share_name = strdup(share);
574 if (!srv->share_name) {
579 srv->workgroup = strdup(workgroup);
580 if (!srv->workgroup) {
585 srv->username = strdup(username);
586 if (!srv->username) {
591 /* some programs play with file descriptors fairly intimately. We
592 try to get out of the way by duping to a high fd number */
593 if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) {
594 if (dup2(srv->cli.fd,SMBW_CLI_FD+srv->cli.fd) ==
595 srv->cli.fd+SMBW_CLI_FD) {
597 srv->cli.fd += SMBW_CLI_FD;
601 DLIST_ADD(smbw_srvs, srv);
607 if (!srv) return NULL;
609 SAFE_FREE(srv->server_name);
610 SAFE_FREE(srv->share_name);
616 /*****************************************************
617 map a fd to a smbw_file structure
618 *******************************************************/
619 struct smbw_file *smbw_file(int fd)
621 struct smbw_file *file;
623 for (file=smbw_files;file;file=file->next) {
624 if (file->fd == fd) return file;
629 /*****************************************************
631 *******************************************************/
632 int smbw_open(const char *fname, int flags, mode_t mode)
634 fstring server, share;
636 struct smbw_server *srv=NULL;
638 struct smbw_file *file=NULL;
649 /* work out what server they are after */
650 smbw_parse_path(fname, server, share, path);
652 /* get a connection to the server */
653 srv = smbw_server(server, share);
655 /* smbw_server sets errno */
659 if (path[strlen(path)-1] == '\\') {
662 fd = cli_open(&srv->cli, path, flags, DENY_NONE);
665 /* it might be a directory. Maybe we should use chkpath? */
666 eno = smbw_errno(&srv->cli);
667 fd = smbw_dir_open(fname);
668 if (fd == -1) errno = eno;
673 file = (struct smbw_file *)malloc(sizeof(*file));
681 file->f = (struct smbw_filedes *)malloc(sizeof(*(file->f)));
687 ZERO_STRUCTP(file->f);
689 file->f->cli_fd = fd;
690 file->f->fname = strdup(path);
691 if (!file->f->fname) {
696 file->fd = open(SMBW_DUMMY, O_WRONLY);
697 if (file->fd == -1) {
702 if (bitmap_query(smbw_file_bmap, file->fd)) {
703 DEBUG(0,("ERROR: fd used in smbw_open\n"));
708 file->f->ref_count=1;
710 bitmap_set(smbw_file_bmap, file->fd);
712 DLIST_ADD(smbw_files, file);
714 DEBUG(4,("opened %s\n", fname));
721 cli_close(&srv->cli, fd);
725 SAFE_FREE(file->f->fname);
735 /*****************************************************
736 a wrapper for pread()
737 *******************************************************/
738 ssize_t smbw_pread(int fd, void *buf, size_t count, off_t ofs)
740 struct smbw_file *file;
745 file = smbw_file(fd);
752 ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, ofs, count);
755 errno = smbw_errno(&file->srv->cli);
764 /*****************************************************
766 *******************************************************/
767 ssize_t smbw_read(int fd, void *buf, size_t count)
769 struct smbw_file *file;
772 DEBUG(4,("smbw_read(%d, %d)\n", fd, (int)count));
776 file = smbw_file(fd);
783 ret = cli_read(&file->srv->cli, file->f->cli_fd, buf,
784 file->f->offset, count);
787 errno = smbw_errno(&file->srv->cli);
792 file->f->offset += ret;
794 DEBUG(4,(" -> %d\n", ret));
802 /*****************************************************
803 a wrapper for write()
804 *******************************************************/
805 ssize_t smbw_write(int fd, void *buf, size_t count)
807 struct smbw_file *file;
812 file = smbw_file(fd);
819 ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, file->f->offset, count);
822 errno = smbw_errno(&file->srv->cli);
827 file->f->offset += ret;
833 /*****************************************************
834 a wrapper for pwrite()
835 *******************************************************/
836 ssize_t smbw_pwrite(int fd, void *buf, size_t count, off_t ofs)
838 struct smbw_file *file;
843 file = smbw_file(fd);
850 ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, ofs, count);
853 errno = smbw_errno(&file->srv->cli);
862 /*****************************************************
863 a wrapper for close()
864 *******************************************************/
865 int smbw_close(int fd)
867 struct smbw_file *file;
871 file = smbw_file(fd);
873 int ret = smbw_dir_close(fd);
878 if (file->f->ref_count == 1 &&
879 !cli_close(&file->srv->cli, file->f->cli_fd)) {
880 errno = smbw_errno(&file->srv->cli);
886 bitmap_clear(smbw_file_bmap, file->fd);
889 DLIST_REMOVE(smbw_files, file);
891 file->f->ref_count--;
892 if (file->f->ref_count == 0) {
893 SAFE_FREE(file->f->fname);
905 /*****************************************************
906 a wrapper for fcntl()
907 *******************************************************/
908 int smbw_fcntl(int fd, int cmd, long arg)
914 /*****************************************************
915 a wrapper for access()
916 *******************************************************/
917 int smbw_access(const char *name, int mode)
921 DEBUG(4,("smbw_access(%s, 0x%x)\n", name, mode));
923 if (smbw_stat(name, &st)) return -1;
925 if (((mode & R_OK) && !(st.st_mode & S_IRUSR)) ||
926 ((mode & W_OK) && !(st.st_mode & S_IWUSR)) ||
927 ((mode & X_OK) && !(st.st_mode & S_IXUSR))) {
935 /*****************************************************
936 a wrapper for realink() - needed for correct errno setting
937 *******************************************************/
938 int smbw_readlink(const char *path, char *buf, size_t bufsize)
943 ret = smbw_stat(path, &st);
945 DEBUG(4,("readlink(%s) failed\n", path));
949 /* it exists - say it isn't a link */
950 DEBUG(4,("readlink(%s) not a link\n", path));
957 /*****************************************************
958 a wrapper for unlink()
959 *******************************************************/
960 int smbw_unlink(const char *fname)
962 struct smbw_server *srv;
963 fstring server, share;
975 /* work out what server they are after */
976 smbw_parse_path(fname, server, share, path);
978 /* get a connection to the server */
979 srv = smbw_server(server, share);
981 /* smbw_server sets errno */
985 if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
986 int job = smbw_stat_printjob(srv, path, NULL, NULL);
990 if (cli_printjob_del(&srv->cli, job) != 0) {
993 } else if (!cli_unlink(&srv->cli, path)) {
994 errno = smbw_errno(&srv->cli);
1007 /*****************************************************
1008 a wrapper for rename()
1009 *******************************************************/
1010 int smbw_rename(const char *oldname, const char *newname)
1012 struct smbw_server *srv;
1013 fstring server1, share1;
1015 fstring server2, share2;
1018 if (!oldname || !newname) {
1025 DEBUG(4,("smbw_rename(%s,%s)\n", oldname, newname));
1029 /* work out what server they are after */
1030 smbw_parse_path(oldname, server1, share1, path1);
1031 smbw_parse_path(newname, server2, share2, path2);
1033 if (strcmp(server1, server2) || strcmp(share1, share2)) {
1034 /* can't cross filesystems */
1039 /* get a connection to the server */
1040 srv = smbw_server(server1, share1);
1042 /* smbw_server sets errno */
1046 if (!cli_rename(&srv->cli, path1, path2)) {
1047 int eno = smbw_errno(&srv->cli);
1048 if (eno != EEXIST ||
1049 !cli_unlink(&srv->cli, path2) ||
1050 !cli_rename(&srv->cli, path1, path2)) {
1065 /*****************************************************
1066 a wrapper for utime and utimes
1067 *******************************************************/
1068 static int smbw_settime(const char *fname, time_t t)
1070 struct smbw_server *srv;
1071 fstring server, share;
1084 /* work out what server they are after */
1085 smbw_parse_path(fname, server, share, path);
1087 /* get a connection to the server */
1088 srv = smbw_server(server, share);
1090 /* smbw_server sets errno */
1094 if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
1095 errno = smbw_errno(&srv->cli);
1099 if (!cli_setatr(&srv->cli, path, mode, t)) {
1100 /* some servers always refuse directory changes */
1101 if (!(mode & aDIR)) {
1102 errno = smbw_errno(&srv->cli);
1115 /*****************************************************
1117 *******************************************************/
1118 int smbw_utime(const char *fname, void *buf)
1120 struct utimbuf *tbuf = (struct utimbuf *)buf;
1121 return smbw_settime(fname, tbuf?tbuf->modtime:time(NULL));
1124 /*****************************************************
1126 *******************************************************/
1127 int smbw_utimes(const char *fname, void *buf)
1129 struct timeval *tbuf = (struct timeval *)buf;
1130 return smbw_settime(fname, tbuf?tbuf->tv_sec:time(NULL));
1134 /*****************************************************
1135 a wrapper for chown()
1136 *******************************************************/
1137 int smbw_chown(const char *fname, uid_t owner, gid_t group)
1139 struct smbw_server *srv;
1140 fstring server, share;
1153 /* work out what server they are after */
1154 smbw_parse_path(fname, server, share, path);
1156 /* get a connection to the server */
1157 srv = smbw_server(server, share);
1159 /* smbw_server sets errno */
1163 if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
1164 errno = smbw_errno(&srv->cli);
1168 /* assume success */
1178 /*****************************************************
1179 a wrapper for chmod()
1180 *******************************************************/
1181 int smbw_chmod(const char *fname, mode_t newmode)
1183 struct smbw_server *srv;
1184 fstring server, share;
1197 /* work out what server they are after */
1198 smbw_parse_path(fname, server, share, path);
1200 /* get a connection to the server */
1201 srv = smbw_server(server, share);
1203 /* smbw_server sets errno */
1209 if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;
1210 if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;
1211 if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
1212 if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
1214 if (!cli_setatr(&srv->cli, path, mode, 0)) {
1215 errno = smbw_errno(&srv->cli);
1227 /*****************************************************
1228 a wrapper for lseek()
1229 *******************************************************/
1230 off_t smbw_lseek(int fd, off_t offset, int whence)
1232 struct smbw_file *file;
1237 file = smbw_file(fd);
1239 off_t ret = smbw_dir_lseek(fd, offset, whence);
1246 file->f->offset = offset;
1249 file->f->offset += offset;
1252 if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
1253 NULL, &size, NULL, NULL, NULL,
1255 !cli_getattrE(&file->srv->cli, file->f->cli_fd,
1256 NULL, &size, NULL, NULL, NULL)) {
1261 file->f->offset = size + offset;
1266 return file->f->offset;
1270 /*****************************************************
1272 *******************************************************/
1273 int smbw_dup(int fd)
1276 struct smbw_file *file, *file2;
1280 file = smbw_file(fd);
1286 fd2 = dup(file->fd);
1291 if (bitmap_query(smbw_file_bmap, fd2)) {
1292 DEBUG(0,("ERROR: fd already open in dup!\n"));
1297 file2 = (struct smbw_file *)malloc(sizeof(*file2));
1304 ZERO_STRUCTP(file2);
1309 file->f->ref_count++;
1311 bitmap_set(smbw_file_bmap, fd2);
1313 DLIST_ADD(smbw_files, file2);
1324 /*****************************************************
1325 a wrapper for dup2()
1326 *******************************************************/
1327 int smbw_dup2(int fd, int fd2)
1329 struct smbw_file *file, *file2;
1333 file = smbw_file(fd);
1339 if (bitmap_query(smbw_file_bmap, fd2)) {
1340 DEBUG(0,("ERROR: fd already open in dup2!\n"));
1345 if (dup2(file->fd, fd2) != fd2) {
1349 file2 = (struct smbw_file *)malloc(sizeof(*file2));
1356 ZERO_STRUCTP(file2);
1361 file->f->ref_count++;
1363 bitmap_set(smbw_file_bmap, fd2);
1365 DLIST_ADD(smbw_files, file2);
1376 /*****************************************************
1377 close a connection to a server
1378 *******************************************************/
1379 static void smbw_srv_close(struct smbw_server *srv)
1383 cli_shutdown(&srv->cli);
1385 SAFE_FREE(srv->server_name);
1386 SAFE_FREE(srv->share_name);
1388 DLIST_REMOVE(smbw_srvs, srv);
1397 /*****************************************************
1398 when we fork we have to close all connections and files
1400 *******************************************************/
1408 struct smbw_file *file, *next_file;
1409 struct smbw_server *srv, *next_srv;
1411 if (pipe(p)) return real_fork();
1413 child = real_fork();
1416 /* block the parent for a moment until the sockets are
1426 /* close all files */
1427 for (file=smbw_files;file;file=next_file) {
1428 next_file = file->next;
1432 /* close all server connections */
1433 for (srv=smbw_srvs;srv;srv=next_srv) {
1434 next_srv = srv->next;
1435 smbw_srv_close(srv);
1438 slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
1439 smbw_setshared(line,smbw_cwd);
1441 /* unblock the parent */
1445 /* and continue in the child */
1449 #ifndef NO_ACL_WRAPPER
1450 /*****************************************************
1452 *******************************************************/
1453 int smbw_acl(const char *pathp, int cmd, int nentries, aclent_t *aclbufp)
1455 if (cmd == GETACL || cmd == GETACLCNT) return 0;
1461 #ifndef NO_FACL_WRAPPER
1462 /*****************************************************
1464 *******************************************************/
1465 int smbw_facl(int fd, int cmd, int nentries, aclent_t *aclbufp)
1467 if (cmd == GETACL || cmd == GETACLCNT) return 0;
1473 #ifdef HAVE_EXPLICIT_LARGEFILE_SUPPORT
1475 /* this can't be in wrapped.c because of include conflicts */
1476 void stat64_convert(struct stat *st, struct stat64 *st64)
1478 st64->st_size = st->st_size;
1479 st64->st_mode = st->st_mode;
1480 st64->st_ino = st->st_ino;
1481 st64->st_dev = st->st_dev;
1482 st64->st_rdev = st->st_rdev;
1483 st64->st_nlink = st->st_nlink;
1484 st64->st_uid = st->st_uid;
1485 st64->st_gid = st->st_gid;
1486 st64->st_atime = st->st_atime;
1487 st64->st_mtime = st->st_mtime;
1488 st64->st_ctime = st->st_ctime;
1489 st64->st_blksize = st->st_blksize;
1490 st64->st_blocks = st->st_blocks;
1494 #ifdef HAVE_READDIR64
1495 void dirent64_convert(struct dirent *d, struct dirent64 *d64)
1497 d64->d_ino = d->d_ino;
1498 d64->d_off = d->d_off;
1499 d64->d_reclen = d->d_reclen;
1500 pstrcpy(d64->d_name, d->d_name);
1507 /* Definition of `struct stat' used in the linux kernel.. */
1508 struct kernel_stat {
1509 unsigned short int st_dev;
1510 unsigned short int __pad1;
1511 unsigned long int st_ino;
1512 unsigned short int st_mode;
1513 unsigned short int st_nlink;
1514 unsigned short int st_uid;
1515 unsigned short int st_gid;
1516 unsigned short int st_rdev;
1517 unsigned short int __pad2;
1518 unsigned long int st_size;
1519 unsigned long int st_blksize;
1520 unsigned long int st_blocks;
1521 unsigned long int st_atime;
1522 unsigned long int __unused1;
1523 unsigned long int st_mtime;
1524 unsigned long int __unused2;
1525 unsigned long int st_ctime;
1526 unsigned long int __unused3;
1527 unsigned long int __unused4;
1528 unsigned long int __unused5;
1532 * Prototype for gcc in 'fussy' mode.
1534 void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf);
1535 void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf)
1537 #ifdef _STAT_VER_LINUX_OLD
1538 if (vers == _STAT_VER_LINUX_OLD) {
1539 memcpy(st, kbuf, sizeof(*st));
1546 st->st_dev = kbuf->st_dev;
1547 st->st_ino = kbuf->st_ino;
1548 st->st_mode = kbuf->st_mode;
1549 st->st_nlink = kbuf->st_nlink;
1550 st->st_uid = kbuf->st_uid;
1551 st->st_gid = kbuf->st_gid;
1552 st->st_rdev = kbuf->st_rdev;
1553 st->st_size = kbuf->st_size;
1554 st->st_blksize = kbuf->st_blksize;
1555 st->st_blocks = kbuf->st_blocks;
1556 st->st_atime = kbuf->st_atime;
1557 st->st_mtime = kbuf->st_mtime;
1558 st->st_ctime = kbuf->st_ctime;