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;
33 fstring smbw_prefix = SMBW_PREFIX;
37 /* needs to be here because of dumb include files on some systems */
38 int creat_bits = O_WRONLY|O_CREAT|O_TRUNC;
41 /*****************************************************
43 *******************************************************/
46 extern BOOL in_client;
47 static int initialised;
52 if (initialised) return;
60 setup_logging("smbsh",True);
64 if ((p=smbw_getshared("LOGFILE"))) {
65 dbf = sys_fopen(p, "a");
68 smbw_file_bmap = bitmap_allocate(SMBW_MAX_OPEN);
69 if (!smbw_file_bmap) {
77 if ((p=smbw_getshared("SERVICESF"))) {
78 pstrcpy(dyn_CONFIGFILE, p);
81 lp_load(dyn_CONFIGFILE,True,False,False);
83 get_myname(global_myname);
85 if ((p=smbw_getshared("DEBUG"))) {
89 if ((p=smbw_getshared("RESOLVE_ORDER"))) {
90 lp_set_name_resolve_order(p);
93 if ((p=smbw_getshared("PREFIX"))) {
94 slprintf(smbw_prefix,sizeof(fstring)-1, "/%s/", p);
95 all_string_sub(smbw_prefix,"//", "/", 0);
96 DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix));
99 slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
101 p = smbw_getshared(line);
105 pstrcpy(smbw_cwd, p);
106 DEBUG(4,("Initial cwd is %s\n", smbw_cwd));
110 set_maxfiles(SMBW_MAX_OPEN);
112 BlockSignals(True,SIGPIPE);
117 /*****************************************************
118 determine if a file descriptor is a smb one
119 *******************************************************/
122 if (smbw_busy) return 0;
123 return smbw_file_bmap && bitmap_query(smbw_file_bmap, fd);
126 /*****************************************************
127 determine if a file descriptor is an internal smbw fd
128 *******************************************************/
129 int smbw_local_fd(int fd)
131 struct smbw_server *srv;
135 if (smbw_busy) return 0;
136 if (smbw_shared_fd(fd)) return 1;
138 for (srv=smbw_srvs;srv;srv=srv->next) {
139 if (srv->cli.fd == fd) return 1;
145 /*****************************************************
146 a crude inode number generator
147 *******************************************************/
148 ino_t smbw_inode(const char *name)
150 if (!*name) return 2;
151 return (ino_t)str_checksum(name);
154 /*****************************************************
155 remove redundent stuff from a filename
156 *******************************************************/
157 void clean_fname(char *name)
168 DEBUG(5,("cleaning %s\n", name));
170 if ((p=strstr(name,"/./"))) {
178 if ((p=strstr(name,"//"))) {
186 if (strcmp(name,"/../")==0) {
191 if ((p=strstr(name,"/../"))) {
193 for (p2=(p>name?p-1:p);p2>name;p2--) {
194 if (p2[0] == '/') break;
202 if (strcmp(name,"/..")==0) {
208 p = l>=3?(name+l-3):name;
209 if (strcmp(p,"/..")==0) {
211 for (p2=p-1;p2>name;p2--) {
212 if (p2[0] == '/') break;
223 p = l>=2?(name+l-2):name;
224 if (strcmp(p,"/.")==0) {
232 if (strncmp(p=name,"./",2) == 0) {
240 if (l > 1 && p[l-1] == '/') {
249 /*****************************************************
250 find a workgroup (any workgroup!) that has a master
251 browser on the local network
252 *******************************************************/
253 static char *smbw_find_workgroup(void)
257 struct in_addr *ip_list = NULL;
261 /* first off see if an existing workgroup name exists */
262 p = smbw_getshared("WORKGROUP");
263 if (!p) p = lp_workgroup();
265 slprintf(server, sizeof(server), "%s#1D", p);
266 if (smbw_server(server, "IPC$")) return p;
268 /* go looking for workgroups */
269 if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
270 DEBUG(1,("No workgroups found!"));
274 for (i=0;i<count;i++) {
276 if (name_status_find("*", 0, 0x1d, ip_list[i], name)) {
277 slprintf(server, sizeof(server), "%s#1D", name);
278 if (smbw_server(server, "IPC$")) {
279 smbw_setshared("WORKGROUP", name);
291 /*****************************************************
292 parse a smb path into its components.
294 1) the name of the SMB server
295 2) WORKGROUP#1D for share listing
296 3) WORKGROUP#__ for workgroup listing
297 share is the share on the server to query
298 path is the SMB path on the server
299 return the full path (ie. add cwd if needed)
300 *******************************************************/
301 char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
308 /* add cwd if necessary */
309 if (fname[0] != '/') {
310 slprintf(s, sizeof(s), "%s/%s", smbw_cwd, fname);
316 /* see if it has the right prefix */
317 len = strlen(smbw_prefix)-1;
318 if (strncmp(s,smbw_prefix,len) ||
319 (s[len] != '/' && s[len] != 0)) return s;
321 /* ok, its for us. Now parse out the workgroup, share etc. */
324 if (!next_token(&p, workgroup, "/", sizeof(fstring))) {
325 /* we're in /smb - give a list of workgroups */
326 slprintf(server,sizeof(fstring), "%s#01", smbw_find_workgroup());
327 fstrcpy(share,"IPC$");
332 if (!next_token(&p, server, "/", sizeof(fstring))) {
333 /* we are in /smb/WORKGROUP */
334 slprintf(server,sizeof(fstring), "%s#1D", workgroup);
335 fstrcpy(share,"IPC$");
339 if (!next_token(&p, share, "/", sizeof(fstring))) {
340 /* we are in /smb/WORKGROUP/SERVER */
341 fstrcpy(share,"IPC$");
347 all_string_sub(path, "/", "\\", 0);
352 /*****************************************************
353 determine if a path name (possibly relative) is in the
355 *******************************************************/
356 int smbw_path(const char *path)
358 fstring server, share;
366 /* this is needed to prevent recursion with the BSD malloc which
367 opens /etc/malloc.conf on the first call */
368 if (strncmp(path,"/etc/", 5) == 0) {
374 len = strlen(smbw_prefix)-1;
376 if (path[0] == '/' && strncmp(path,smbw_prefix,len)) {
380 if (smbw_busy) return 0;
382 DEBUG(3,("smbw_path(%s)\n", path));
384 cwd = smbw_parse_path(path, server, share, s);
386 if (strncmp(cwd,smbw_prefix,len) == 0 &&
387 (cwd[len] == '/' || cwd[len] == 0)) {
394 /*****************************************************
395 return a unix errno from a SMB error pair
396 *******************************************************/
397 int smbw_errno(struct cli_state *c)
402 /* Return a username and password given a server and share name */
404 void get_envvar_auth_data(char *server, char *share, char **workgroup,
405 char **username, char **password)
407 /* Fall back to shared memory/environment variables */
409 *username = smbw_getshared("USER");
410 if (!*username) *username = getenv("USER");
411 if (!*username) *username = "guest";
413 *workgroup = smbw_getshared("WORKGROUP");
414 if (!*workgroup) *workgroup = lp_workgroup();
416 *password = smbw_getshared("PASSWORD");
417 if (!*password) *password = "";
420 static smbw_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data;
422 /*****************************************************
423 set the get auth data function
424 ******************************************************/
425 void smbw_set_auth_data_fn(smbw_get_auth_data_fn fn)
427 get_auth_data_fn = fn;
430 /*****************************************************
431 return a connection to a server (existing or new)
432 *******************************************************/
433 struct smbw_server *smbw_server(char *server, char *share)
435 struct smbw_server *srv=NULL;
440 struct nmb_name called, calling;
441 char *p, *server_n = server;
449 get_auth_data_fn(server, share, &workgroup, &username, &password);
451 /* try to use an existing connection */
452 for (srv=smbw_srvs;srv;srv=srv->next) {
453 if (strcmp(server,srv->server_name)==0 &&
454 strcmp(share,srv->share_name)==0 &&
455 strcmp(workgroup,srv->workgroup)==0 &&
456 strcmp(username, srv->username) == 0)
460 if (server[0] == 0) {
465 make_nmb_name(&calling, global_myname, 0x0);
466 make_nmb_name(&called , server, 0x20);
468 DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server));
470 if ((p=strchr_m(server_n,'#')) &&
471 (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) {
475 fstrcpy(group, server_n);
476 p = strchr_m(group,'#');
479 /* cache the workgroup master lookup */
480 slprintf(s,sizeof(s)-1,"MASTER_%s", group);
481 if (!(server_n = smbw_getshared(s))) {
482 if (!find_master_ip(group, &sip)) {
486 fstrcpy(group, inet_ntoa(sip));
488 smbw_setshared(s,server_n);
492 DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
495 slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
498 if ((p=smbw_getshared(ipenv))) {
499 ip = *(interpret_addr2(p));
502 /* have to open a new connection */
503 if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) {
508 if (!cli_session_request(&c, &calling, &called)) {
510 if (strcmp(called.name, "*SMBSERVER")) {
511 make_nmb_name(&called , "*SMBSERVER", 0x20);
518 DEBUG(4,(" session request ok\n"));
520 if (!cli_negprot(&c)) {
526 if (!cli_session_setup(&c, username,
527 password, strlen(password),
528 password, strlen(password),
530 /* try an anonymous login if it failed */
531 !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {
537 DEBUG(4,(" session setup ok\n"));
539 if (!cli_send_tconX(&c, share, "?????",
540 password, strlen(password)+1)) {
541 errno = smbw_errno(&c);
546 smbw_setshared(ipenv,inet_ntoa(ip));
548 DEBUG(4,(" tconx ok\n"));
550 srv = (struct smbw_server *)malloc(sizeof(*srv));
560 srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
562 srv->server_name = strdup(server);
563 if (!srv->server_name) {
568 srv->share_name = strdup(share);
569 if (!srv->share_name) {
574 srv->workgroup = strdup(workgroup);
575 if (!srv->workgroup) {
580 srv->username = strdup(username);
581 if (!srv->username) {
586 /* some programs play with file descriptors fairly intimately. We
587 try to get out of the way by duping to a high fd number */
588 if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) {
589 if (dup2(srv->cli.fd,SMBW_CLI_FD+srv->cli.fd) ==
590 srv->cli.fd+SMBW_CLI_FD) {
592 srv->cli.fd += SMBW_CLI_FD;
596 DLIST_ADD(smbw_srvs, srv);
602 if (!srv) return NULL;
604 SAFE_FREE(srv->server_name);
605 SAFE_FREE(srv->share_name);
611 /*****************************************************
612 map a fd to a smbw_file structure
613 *******************************************************/
614 struct smbw_file *smbw_file(int fd)
616 struct smbw_file *file;
618 for (file=smbw_files;file;file=file->next) {
619 if (file->fd == fd) return file;
624 /*****************************************************
626 *******************************************************/
627 int smbw_open(const char *fname, int flags, mode_t mode)
629 fstring server, share;
631 struct smbw_server *srv=NULL;
633 struct smbw_file *file=NULL;
644 /* work out what server they are after */
645 smbw_parse_path(fname, server, share, path);
647 /* get a connection to the server */
648 srv = smbw_server(server, share);
650 /* smbw_server sets errno */
654 if (path[strlen(path)-1] == '\\') {
657 fd = cli_open(&srv->cli, path, flags, DENY_NONE);
660 /* it might be a directory. Maybe we should use chkpath? */
661 eno = smbw_errno(&srv->cli);
662 fd = smbw_dir_open(fname);
663 if (fd == -1) errno = eno;
668 file = (struct smbw_file *)malloc(sizeof(*file));
676 file->f = (struct smbw_filedes *)malloc(sizeof(*(file->f)));
682 ZERO_STRUCTP(file->f);
684 file->f->cli_fd = fd;
685 file->f->fname = strdup(path);
686 if (!file->f->fname) {
691 file->fd = open(SMBW_DUMMY, O_WRONLY);
692 if (file->fd == -1) {
697 if (bitmap_query(smbw_file_bmap, file->fd)) {
698 DEBUG(0,("ERROR: fd used in smbw_open\n"));
703 file->f->ref_count=1;
705 bitmap_set(smbw_file_bmap, file->fd);
707 DLIST_ADD(smbw_files, file);
709 DEBUG(4,("opened %s\n", fname));
716 cli_close(&srv->cli, fd);
720 SAFE_FREE(file->f->fname);
730 /*****************************************************
731 a wrapper for pread()
732 *******************************************************/
733 ssize_t smbw_pread(int fd, void *buf, size_t count, off_t ofs)
735 struct smbw_file *file;
740 file = smbw_file(fd);
747 ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, ofs, count);
750 errno = smbw_errno(&file->srv->cli);
759 /*****************************************************
761 *******************************************************/
762 ssize_t smbw_read(int fd, void *buf, size_t count)
764 struct smbw_file *file;
767 DEBUG(4,("smbw_read(%d, %d)\n", fd, (int)count));
771 file = smbw_file(fd);
778 ret = cli_read(&file->srv->cli, file->f->cli_fd, buf,
779 file->f->offset, count);
782 errno = smbw_errno(&file->srv->cli);
787 file->f->offset += ret;
789 DEBUG(4,(" -> %d\n", ret));
797 /*****************************************************
798 a wrapper for write()
799 *******************************************************/
800 ssize_t smbw_write(int fd, void *buf, size_t count)
802 struct smbw_file *file;
807 file = smbw_file(fd);
814 ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, file->f->offset, count);
817 errno = smbw_errno(&file->srv->cli);
822 file->f->offset += ret;
828 /*****************************************************
829 a wrapper for pwrite()
830 *******************************************************/
831 ssize_t smbw_pwrite(int fd, void *buf, size_t count, off_t ofs)
833 struct smbw_file *file;
838 file = smbw_file(fd);
845 ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, ofs, count);
848 errno = smbw_errno(&file->srv->cli);
857 /*****************************************************
858 a wrapper for close()
859 *******************************************************/
860 int smbw_close(int fd)
862 struct smbw_file *file;
866 file = smbw_file(fd);
868 int ret = smbw_dir_close(fd);
873 if (file->f->ref_count == 1 &&
874 !cli_close(&file->srv->cli, file->f->cli_fd)) {
875 errno = smbw_errno(&file->srv->cli);
881 bitmap_clear(smbw_file_bmap, file->fd);
884 DLIST_REMOVE(smbw_files, file);
886 file->f->ref_count--;
887 if (file->f->ref_count == 0) {
888 SAFE_FREE(file->f->fname);
900 /*****************************************************
901 a wrapper for fcntl()
902 *******************************************************/
903 int smbw_fcntl(int fd, int cmd, long arg)
909 /*****************************************************
910 a wrapper for access()
911 *******************************************************/
912 int smbw_access(const char *name, int mode)
916 DEBUG(4,("smbw_access(%s, 0x%x)\n", name, mode));
918 if (smbw_stat(name, &st)) return -1;
920 if (((mode & R_OK) && !(st.st_mode & S_IRUSR)) ||
921 ((mode & W_OK) && !(st.st_mode & S_IWUSR)) ||
922 ((mode & X_OK) && !(st.st_mode & S_IXUSR))) {
930 /*****************************************************
931 a wrapper for realink() - needed for correct errno setting
932 *******************************************************/
933 int smbw_readlink(const char *path, char *buf, size_t bufsize)
938 ret = smbw_stat(path, &st);
940 DEBUG(4,("readlink(%s) failed\n", path));
944 /* it exists - say it isn't a link */
945 DEBUG(4,("readlink(%s) not a link\n", path));
952 /*****************************************************
953 a wrapper for unlink()
954 *******************************************************/
955 int smbw_unlink(const char *fname)
957 struct smbw_server *srv;
958 fstring server, share;
970 /* work out what server they are after */
971 smbw_parse_path(fname, server, share, path);
973 /* get a connection to the server */
974 srv = smbw_server(server, share);
976 /* smbw_server sets errno */
980 if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
981 int job = smbw_stat_printjob(srv, path, NULL, NULL);
985 if (cli_printjob_del(&srv->cli, job) != 0) {
988 } else if (!cli_unlink(&srv->cli, path)) {
989 errno = smbw_errno(&srv->cli);
1002 /*****************************************************
1003 a wrapper for rename()
1004 *******************************************************/
1005 int smbw_rename(const char *oldname, const char *newname)
1007 struct smbw_server *srv;
1008 fstring server1, share1;
1010 fstring server2, share2;
1013 if (!oldname || !newname) {
1020 DEBUG(4,("smbw_rename(%s,%s)\n", oldname, newname));
1024 /* work out what server they are after */
1025 smbw_parse_path(oldname, server1, share1, path1);
1026 smbw_parse_path(newname, server2, share2, path2);
1028 if (strcmp(server1, server2) || strcmp(share1, share2)) {
1029 /* can't cross filesystems */
1034 /* get a connection to the server */
1035 srv = smbw_server(server1, share1);
1037 /* smbw_server sets errno */
1041 if (!cli_rename(&srv->cli, path1, path2)) {
1042 int eno = smbw_errno(&srv->cli);
1043 if (eno != EEXIST ||
1044 !cli_unlink(&srv->cli, path2) ||
1045 !cli_rename(&srv->cli, path1, path2)) {
1060 /*****************************************************
1061 a wrapper for utime and utimes
1062 *******************************************************/
1063 static int smbw_settime(const char *fname, time_t t)
1065 struct smbw_server *srv;
1066 fstring server, share;
1079 /* work out what server they are after */
1080 smbw_parse_path(fname, server, share, path);
1082 /* get a connection to the server */
1083 srv = smbw_server(server, share);
1085 /* smbw_server sets errno */
1089 if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
1090 errno = smbw_errno(&srv->cli);
1094 if (!cli_setatr(&srv->cli, path, mode, t)) {
1095 /* some servers always refuse directory changes */
1096 if (!(mode & aDIR)) {
1097 errno = smbw_errno(&srv->cli);
1110 /*****************************************************
1112 *******************************************************/
1113 int smbw_utime(const char *fname, void *buf)
1115 struct utimbuf *tbuf = (struct utimbuf *)buf;
1116 return smbw_settime(fname, tbuf?tbuf->modtime:time(NULL));
1119 /*****************************************************
1121 *******************************************************/
1122 int smbw_utimes(const char *fname, void *buf)
1124 struct timeval *tbuf = (struct timeval *)buf;
1125 return smbw_settime(fname, tbuf?tbuf->tv_sec:time(NULL));
1129 /*****************************************************
1130 a wrapper for chown()
1131 *******************************************************/
1132 int smbw_chown(const char *fname, uid_t owner, gid_t group)
1134 struct smbw_server *srv;
1135 fstring server, share;
1148 /* work out what server they are after */
1149 smbw_parse_path(fname, server, share, path);
1151 /* get a connection to the server */
1152 srv = smbw_server(server, share);
1154 /* smbw_server sets errno */
1158 if (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {
1159 errno = smbw_errno(&srv->cli);
1163 /* assume success */
1173 /*****************************************************
1174 a wrapper for chmod()
1175 *******************************************************/
1176 int smbw_chmod(const char *fname, mode_t newmode)
1178 struct smbw_server *srv;
1179 fstring server, share;
1192 /* work out what server they are after */
1193 smbw_parse_path(fname, server, share, path);
1195 /* get a connection to the server */
1196 srv = smbw_server(server, share);
1198 /* smbw_server sets errno */
1204 if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;
1205 if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;
1206 if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
1207 if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
1209 if (!cli_setatr(&srv->cli, path, mode, 0)) {
1210 errno = smbw_errno(&srv->cli);
1222 /*****************************************************
1223 a wrapper for lseek()
1224 *******************************************************/
1225 off_t smbw_lseek(int fd, off_t offset, int whence)
1227 struct smbw_file *file;
1232 file = smbw_file(fd);
1234 off_t ret = smbw_dir_lseek(fd, offset, whence);
1241 file->f->offset = offset;
1244 file->f->offset += offset;
1247 if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd,
1248 NULL, &size, NULL, NULL, NULL,
1250 !cli_getattrE(&file->srv->cli, file->f->cli_fd,
1251 NULL, &size, NULL, NULL, NULL)) {
1256 file->f->offset = size + offset;
1261 return file->f->offset;
1265 /*****************************************************
1267 *******************************************************/
1268 int smbw_dup(int fd)
1271 struct smbw_file *file, *file2;
1275 file = smbw_file(fd);
1281 fd2 = dup(file->fd);
1286 if (bitmap_query(smbw_file_bmap, fd2)) {
1287 DEBUG(0,("ERROR: fd already open in dup!\n"));
1292 file2 = (struct smbw_file *)malloc(sizeof(*file2));
1299 ZERO_STRUCTP(file2);
1304 file->f->ref_count++;
1306 bitmap_set(smbw_file_bmap, fd2);
1308 DLIST_ADD(smbw_files, file2);
1319 /*****************************************************
1320 a wrapper for dup2()
1321 *******************************************************/
1322 int smbw_dup2(int fd, int fd2)
1324 struct smbw_file *file, *file2;
1328 file = smbw_file(fd);
1334 if (bitmap_query(smbw_file_bmap, fd2)) {
1335 DEBUG(0,("ERROR: fd already open in dup2!\n"));
1340 if (dup2(file->fd, fd2) != fd2) {
1344 file2 = (struct smbw_file *)malloc(sizeof(*file2));
1351 ZERO_STRUCTP(file2);
1356 file->f->ref_count++;
1358 bitmap_set(smbw_file_bmap, fd2);
1360 DLIST_ADD(smbw_files, file2);
1371 /*****************************************************
1372 close a connection to a server
1373 *******************************************************/
1374 static void smbw_srv_close(struct smbw_server *srv)
1378 cli_shutdown(&srv->cli);
1380 SAFE_FREE(srv->server_name);
1381 SAFE_FREE(srv->share_name);
1383 DLIST_REMOVE(smbw_srvs, srv);
1392 /*****************************************************
1393 when we fork we have to close all connections and files
1395 *******************************************************/
1403 struct smbw_file *file, *next_file;
1404 struct smbw_server *srv, *next_srv;
1406 if (pipe(p)) return real_fork();
1408 child = real_fork();
1411 /* block the parent for a moment until the sockets are
1421 /* close all files */
1422 for (file=smbw_files;file;file=next_file) {
1423 next_file = file->next;
1427 /* close all server connections */
1428 for (srv=smbw_srvs;srv;srv=next_srv) {
1429 next_srv = srv->next;
1430 smbw_srv_close(srv);
1433 slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
1434 smbw_setshared(line,smbw_cwd);
1436 /* unblock the parent */
1440 /* and continue in the child */
1444 #ifndef NO_ACL_WRAPPER
1445 /*****************************************************
1447 *******************************************************/
1448 int smbw_acl(const char *pathp, int cmd, int nentries, aclent_t *aclbufp)
1450 if (cmd == GETACL || cmd == GETACLCNT) return 0;
1456 #ifndef NO_FACL_WRAPPER
1457 /*****************************************************
1459 *******************************************************/
1460 int smbw_facl(int fd, int cmd, int nentries, aclent_t *aclbufp)
1462 if (cmd == GETACL || cmd == GETACLCNT) return 0;
1468 #ifdef HAVE_EXPLICIT_LARGEFILE_SUPPORT
1470 /* this can't be in wrapped.c because of include conflicts */
1471 void stat64_convert(struct stat *st, struct stat64 *st64)
1473 st64->st_size = st->st_size;
1474 st64->st_mode = st->st_mode;
1475 st64->st_ino = st->st_ino;
1476 st64->st_dev = st->st_dev;
1477 st64->st_rdev = st->st_rdev;
1478 st64->st_nlink = st->st_nlink;
1479 st64->st_uid = st->st_uid;
1480 st64->st_gid = st->st_gid;
1481 st64->st_atime = st->st_atime;
1482 st64->st_mtime = st->st_mtime;
1483 st64->st_ctime = st->st_ctime;
1484 st64->st_blksize = st->st_blksize;
1485 st64->st_blocks = st->st_blocks;
1489 #ifdef HAVE_READDIR64
1490 void dirent64_convert(struct dirent *d, struct dirent64 *d64)
1492 d64->d_ino = d->d_ino;
1493 d64->d_off = d->d_off;
1494 d64->d_reclen = d->d_reclen;
1495 pstrcpy(d64->d_name, d->d_name);
1502 /* Definition of `struct stat' used in the linux kernel.. */
1503 struct kernel_stat {
1504 unsigned short int st_dev;
1505 unsigned short int __pad1;
1506 unsigned long int st_ino;
1507 unsigned short int st_mode;
1508 unsigned short int st_nlink;
1509 unsigned short int st_uid;
1510 unsigned short int st_gid;
1511 unsigned short int st_rdev;
1512 unsigned short int __pad2;
1513 unsigned long int st_size;
1514 unsigned long int st_blksize;
1515 unsigned long int st_blocks;
1516 unsigned long int st_atime;
1517 unsigned long int __unused1;
1518 unsigned long int st_mtime;
1519 unsigned long int __unused2;
1520 unsigned long int st_ctime;
1521 unsigned long int __unused3;
1522 unsigned long int __unused4;
1523 unsigned long int __unused5;
1527 * Prototype for gcc in 'fussy' mode.
1529 void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf);
1530 void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf)
1532 #ifdef _STAT_VER_LINUX_OLD
1533 if (vers == _STAT_VER_LINUX_OLD) {
1534 memcpy(st, kbuf, sizeof(*st));
1541 st->st_dev = kbuf->st_dev;
1542 st->st_ino = kbuf->st_ino;
1543 st->st_mode = kbuf->st_mode;
1544 st->st_nlink = kbuf->st_nlink;
1545 st->st_uid = kbuf->st_uid;
1546 st->st_gid = kbuf->st_gid;
1547 st->st_rdev = kbuf->st_rdev;
1548 st->st_size = kbuf->st_size;
1549 st->st_blksize = kbuf->st_blksize;
1550 st->st_blocks = kbuf->st_blocks;
1551 st->st_atime = kbuf->st_atime;
1552 st->st_mtime = kbuf->st_mtime;
1553 st->st_ctime = kbuf->st_ctime;