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 BOOL AllowDebugChange
;
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
;
55 if (initialised
) return;
63 AllowDebugChange
= False
;
64 setup_logging("smbsh",True
);
68 if ((p
=smbw_getshared("LOGFILE"))) {
69 dbf
= sys_fopen(p
, "a");
72 smbw_file_bmap
= bitmap_allocate(SMBW_MAX_OPEN
);
73 if (!smbw_file_bmap
) {
83 if ((p
=smbw_getshared("SERVICESF"))) {
84 pstrcpy(servicesf
, p
);
87 lp_load(servicesf
,True
,False
,False
);
88 codepage_initialise(lp_client_code_page());
90 get_myname(global_myname
);
92 if ((p
=smbw_getshared("DEBUG"))) {
96 if ((p
=smbw_getshared("RESOLVE_ORDER"))) {
97 lp_set_name_resolve_order(p
);
100 if ((p
=smbw_getshared("PREFIX"))) {
101 slprintf(smbw_prefix
,sizeof(fstring
)-1, "/%s/", p
);
102 all_string_sub(smbw_prefix
,"//", "/", 0);
103 DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix
));
106 slprintf(line
,sizeof(line
)-1,"PWD_%d", (int)getpid());
108 p
= smbw_getshared(line
);
112 pstrcpy(smbw_cwd
, p
);
113 DEBUG(4,("Initial cwd is %s\n", smbw_cwd
));
117 set_maxfiles(SMBW_MAX_OPEN
);
119 BlockSignals(True
,SIGPIPE
);
124 /*****************************************************
125 determine if a file descriptor is a smb one
126 *******************************************************/
129 if (smbw_busy
) return 0;
130 return smbw_file_bmap
&& bitmap_query(smbw_file_bmap
, fd
);
133 /*****************************************************
134 determine if a file descriptor is an internal smbw fd
135 *******************************************************/
136 int smbw_local_fd(int fd
)
138 struct smbw_server
*srv
;
142 if (smbw_busy
) return 0;
143 if (smbw_shared_fd(fd
)) return 1;
145 for (srv
=smbw_srvs
;srv
;srv
=srv
->next
) {
146 if (srv
->cli
.fd
== fd
) return 1;
152 /*****************************************************
153 a crude inode number generator
154 *******************************************************/
155 ino_t
smbw_inode(const char *name
)
157 if (!*name
) return 2;
158 return (ino_t
)str_checksum(name
);
161 /*****************************************************
162 remove redundent stuff from a filename
163 *******************************************************/
164 void clean_fname(char *name
)
175 DEBUG(5,("cleaning %s\n", name
));
177 if ((p
=strstr(name
,"/./"))) {
185 if ((p
=strstr(name
,"//"))) {
193 if (strcmp(name
,"/../")==0) {
198 if ((p
=strstr(name
,"/../"))) {
200 for (p2
=(p
>name
?p
-1:p
);p2
>name
;p2
--) {
201 if (p2
[0] == '/') break;
209 if (strcmp(name
,"/..")==0) {
215 p
= l
>=3?(name
+l
-3):name
;
216 if (strcmp(p
,"/..")==0) {
218 for (p2
=p
-1;p2
>name
;p2
--) {
219 if (p2
[0] == '/') break;
230 p
= l
>=2?(name
+l
-2):name
;
231 if (strcmp(p
,"/.")==0) {
239 if (strncmp(p
=name
,"./",2) == 0) {
247 if (l
> 1 && p
[l
-1] == '/') {
256 /*****************************************************
257 find a workgroup (any workgroup!) that has a master
258 browser on the local network
259 *******************************************************/
260 static char *smbw_find_workgroup(void)
264 struct in_addr
*ip_list
= NULL
;
268 /* first off see if an existing workgroup name exists */
269 p
= smbw_getshared("WORKGROUP");
270 if (!p
) p
= lp_workgroup();
272 slprintf(server
, sizeof(server
), "%s#1D", p
);
273 if (smbw_server(server
, "IPC$")) return p
;
275 /* go looking for workgroups */
276 if (!name_resolve_bcast(MSBROWSE
, 1, &ip_list
, &count
)) {
277 DEBUG(1,("No workgroups found!"));
281 for (i
=0;i
<count
;i
++) {
283 if (name_status_find("*", 0, 0x1d, ip_list
[i
], name
)) {
284 slprintf(server
, sizeof(server
), "%s#1D", name
);
285 if (smbw_server(server
, "IPC$")) {
286 smbw_setshared("WORKGROUP", name
);
298 /*****************************************************
299 parse a smb path into its components.
301 1) the name of the SMB server
302 2) WORKGROUP#1D for share listing
303 3) WORKGROUP#__ for workgroup listing
304 share is the share on the server to query
305 path is the SMB path on the server
306 return the full path (ie. add cwd if needed)
307 *******************************************************/
308 char *smbw_parse_path(const char *fname
, char *server
, char *share
, char *path
)
315 /* add cwd if necessary */
316 if (fname
[0] != '/') {
317 slprintf(s
, sizeof(s
), "%s/%s", smbw_cwd
, fname
);
323 /* see if it has the right prefix */
324 len
= strlen(smbw_prefix
)-1;
325 if (strncmp(s
,smbw_prefix
,len
) ||
326 (s
[len
] != '/' && s
[len
] != 0)) return s
;
328 /* ok, its for us. Now parse out the workgroup, share etc. */
331 if (!next_token(&p
, workgroup
, "/", sizeof(fstring
))) {
332 /* we're in /smb - give a list of workgroups */
333 slprintf(server
,sizeof(fstring
), "%s#01", smbw_find_workgroup());
334 fstrcpy(share
,"IPC$");
339 if (!next_token(&p
, server
, "/", sizeof(fstring
))) {
340 /* we are in /smb/WORKGROUP */
341 slprintf(server
,sizeof(fstring
), "%s#1D", workgroup
);
342 fstrcpy(share
,"IPC$");
346 if (!next_token(&p
, share
, "/", sizeof(fstring
))) {
347 /* we are in /smb/WORKGROUP/SERVER */
348 fstrcpy(share
,"IPC$");
354 all_string_sub(path
, "/", "\\", 0);
359 /*****************************************************
360 determine if a path name (possibly relative) is in the
362 *******************************************************/
363 int smbw_path(const char *path
)
365 fstring server
, share
;
373 /* this is needed to prevent recursion with the BSD malloc which
374 opens /etc/malloc.conf on the first call */
375 if (strncmp(path
,"/etc/", 5) == 0) {
381 len
= strlen(smbw_prefix
)-1;
383 if (path
[0] == '/' && strncmp(path
,smbw_prefix
,len
)) {
387 if (smbw_busy
) return 0;
389 DEBUG(3,("smbw_path(%s)\n", path
));
391 cwd
= smbw_parse_path(path
, server
, share
, s
);
393 if (strncmp(cwd
,smbw_prefix
,len
) == 0 &&
394 (cwd
[len
] == '/' || cwd
[len
] == 0)) {
401 /*****************************************************
402 return a unix errno from a SMB error pair
403 *******************************************************/
404 int smbw_errno(struct cli_state
*c
)
409 /* Return a username and password given a server and share name */
411 void get_envvar_auth_data(char *server
, char *share
, char **workgroup
,
412 char **username
, char **password
)
414 /* Fall back to shared memory/environment variables */
416 *username
= smbw_getshared("USER");
417 if (!*username
) *username
= getenv("USER");
418 if (!*username
) *username
= "guest";
420 *workgroup
= smbw_getshared("WORKGROUP");
421 if (!*workgroup
) *workgroup
= lp_workgroup();
423 *password
= smbw_getshared("PASSWORD");
424 if (!*password
) *password
= "";
427 static smbw_get_auth_data_fn get_auth_data_fn
= get_envvar_auth_data
;
429 /*****************************************************
430 set the get auth data function
431 ******************************************************/
432 void smbw_set_auth_data_fn(smbw_get_auth_data_fn fn
)
434 get_auth_data_fn
= fn
;
437 /*****************************************************
438 return a connection to a server (existing or new)
439 *******************************************************/
440 struct smbw_server
*smbw_server(char *server
, char *share
)
442 struct smbw_server
*srv
=NULL
;
447 struct nmb_name called
, calling
;
448 char *p
, *server_n
= server
;
456 get_auth_data_fn(server
, share
, &workgroup
, &username
, &password
);
458 /* try to use an existing connection */
459 for (srv
=smbw_srvs
;srv
;srv
=srv
->next
) {
460 if (strcmp(server
,srv
->server_name
)==0 &&
461 strcmp(share
,srv
->share_name
)==0 &&
462 strcmp(workgroup
,srv
->workgroup
)==0 &&
463 strcmp(username
, srv
->username
) == 0)
467 if (server
[0] == 0) {
472 make_nmb_name(&calling
, global_myname
, 0x0);
473 make_nmb_name(&called
, server
, 0x20);
475 DEBUG(4,("server_n=[%s] server=[%s]\n", server_n
, server
));
477 if ((p
=strchr(server_n
,'#')) &&
478 (strcmp(p
+1,"1D")==0 || strcmp(p
+1,"01")==0)) {
482 fstrcpy(group
, server_n
);
483 p
= strchr(group
,'#');
486 /* cache the workgroup master lookup */
487 slprintf(s
,sizeof(s
)-1,"MASTER_%s", group
);
488 if (!(server_n
= smbw_getshared(s
))) {
489 if (!find_master_ip(group
, &sip
)) {
493 fstrcpy(group
, inet_ntoa(sip
));
495 smbw_setshared(s
,server_n
);
499 DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n
, server
));
502 slprintf(ipenv
,sizeof(ipenv
)-1,"HOST_%s", server_n
);
505 if ((p
=smbw_getshared(ipenv
))) {
506 ip
= *(interpret_addr2(p
));
509 /* have to open a new connection */
510 if (!cli_initialise(&c
) || !cli_connect(&c
, server_n
, &ip
)) {
515 if (!cli_session_request(&c
, &calling
, &called
)) {
517 if (strcmp(called
.name
, "*SMBSERVER")) {
518 make_nmb_name(&called
, "*SMBSERVER", 0x20);
525 DEBUG(4,(" session request ok\n"));
527 if (!cli_negprot(&c
)) {
533 if (!cli_session_setup(&c
, username
,
534 password
, strlen(password
),
535 password
, strlen(password
),
537 /* try an anonymous login if it failed */
538 !cli_session_setup(&c
, "", "", 1,"", 0, workgroup
)) {
544 DEBUG(4,(" session setup ok\n"));
546 if (!cli_send_tconX(&c
, share
, "?????",
547 password
, strlen(password
)+1)) {
548 errno
= smbw_errno(&c
);
553 smbw_setshared(ipenv
,inet_ntoa(ip
));
555 DEBUG(4,(" tconx ok\n"));
557 srv
= (struct smbw_server
*)malloc(sizeof(*srv
));
567 srv
->dev
= (dev_t
)(str_checksum(server
) ^ str_checksum(share
));
569 srv
->server_name
= strdup(server
);
570 if (!srv
->server_name
) {
575 srv
->share_name
= strdup(share
);
576 if (!srv
->share_name
) {
581 srv
->workgroup
= strdup(workgroup
);
582 if (!srv
->workgroup
) {
587 srv
->username
= strdup(username
);
588 if (!srv
->username
) {
593 /* some programs play with file descriptors fairly intimately. We
594 try to get out of the way by duping to a high fd number */
595 if (fcntl(SMBW_CLI_FD
+ srv
->cli
.fd
, F_GETFD
) && errno
== EBADF
) {
596 if (dup2(srv
->cli
.fd
,SMBW_CLI_FD
+srv
->cli
.fd
) ==
597 srv
->cli
.fd
+SMBW_CLI_FD
) {
599 srv
->cli
.fd
+= SMBW_CLI_FD
;
603 DLIST_ADD(smbw_srvs
, srv
);
609 if (!srv
) return NULL
;
611 SAFE_FREE(srv
->server_name
);
612 SAFE_FREE(srv
->share_name
);
618 /*****************************************************
619 map a fd to a smbw_file structure
620 *******************************************************/
621 struct smbw_file
*smbw_file(int fd
)
623 struct smbw_file
*file
;
625 for (file
=smbw_files
;file
;file
=file
->next
) {
626 if (file
->fd
== fd
) return file
;
631 /*****************************************************
633 *******************************************************/
634 int smbw_open(const char *fname
, int flags
, mode_t mode
)
636 fstring server
, share
;
638 struct smbw_server
*srv
=NULL
;
640 struct smbw_file
*file
=NULL
;
651 /* work out what server they are after */
652 smbw_parse_path(fname
, server
, share
, path
);
654 /* get a connection to the server */
655 srv
= smbw_server(server
, share
);
657 /* smbw_server sets errno */
661 if (path
[strlen(path
)-1] == '\\') {
664 fd
= cli_open(&srv
->cli
, path
, flags
, DENY_NONE
);
667 /* it might be a directory. Maybe we should use chkpath? */
668 eno
= smbw_errno(&srv
->cli
);
669 fd
= smbw_dir_open(fname
);
670 if (fd
== -1) errno
= eno
;
675 file
= (struct smbw_file
*)malloc(sizeof(*file
));
683 file
->f
= (struct smbw_filedes
*)malloc(sizeof(*(file
->f
)));
689 ZERO_STRUCTP(file
->f
);
691 file
->f
->cli_fd
= fd
;
692 file
->f
->fname
= strdup(path
);
693 if (!file
->f
->fname
) {
698 file
->fd
= open(SMBW_DUMMY
, O_WRONLY
);
699 if (file
->fd
== -1) {
704 if (bitmap_query(smbw_file_bmap
, file
->fd
)) {
705 DEBUG(0,("ERROR: fd used in smbw_open\n"));
710 file
->f
->ref_count
=1;
712 bitmap_set(smbw_file_bmap
, file
->fd
);
714 DLIST_ADD(smbw_files
, file
);
716 DEBUG(4,("opened %s\n", fname
));
723 cli_close(&srv
->cli
, fd
);
727 SAFE_FREE(file
->f
->fname
);
737 /*****************************************************
738 a wrapper for pread()
739 *******************************************************/
740 ssize_t
smbw_pread(int fd
, void *buf
, size_t count
, off_t ofs
)
742 struct smbw_file
*file
;
747 file
= smbw_file(fd
);
754 ret
= cli_read(&file
->srv
->cli
, file
->f
->cli_fd
, buf
, ofs
, count
);
757 errno
= smbw_errno(&file
->srv
->cli
);
766 /*****************************************************
768 *******************************************************/
769 ssize_t
smbw_read(int fd
, void *buf
, size_t count
)
771 struct smbw_file
*file
;
774 DEBUG(4,("smbw_read(%d, %d)\n", fd
, (int)count
));
778 file
= smbw_file(fd
);
785 ret
= cli_read(&file
->srv
->cli
, file
->f
->cli_fd
, buf
,
786 file
->f
->offset
, count
);
789 errno
= smbw_errno(&file
->srv
->cli
);
794 file
->f
->offset
+= ret
;
796 DEBUG(4,(" -> %d\n", ret
));
804 /*****************************************************
805 a wrapper for write()
806 *******************************************************/
807 ssize_t
smbw_write(int fd
, void *buf
, size_t count
)
809 struct smbw_file
*file
;
814 file
= smbw_file(fd
);
821 ret
= cli_write(&file
->srv
->cli
, file
->f
->cli_fd
, 0, buf
, file
->f
->offset
, count
);
824 errno
= smbw_errno(&file
->srv
->cli
);
829 file
->f
->offset
+= ret
;
835 /*****************************************************
836 a wrapper for pwrite()
837 *******************************************************/
838 ssize_t
smbw_pwrite(int fd
, void *buf
, size_t count
, off_t ofs
)
840 struct smbw_file
*file
;
845 file
= smbw_file(fd
);
852 ret
= cli_write(&file
->srv
->cli
, file
->f
->cli_fd
, 0, buf
, ofs
, count
);
855 errno
= smbw_errno(&file
->srv
->cli
);
864 /*****************************************************
865 a wrapper for close()
866 *******************************************************/
867 int smbw_close(int fd
)
869 struct smbw_file
*file
;
873 file
= smbw_file(fd
);
875 int ret
= smbw_dir_close(fd
);
880 if (file
->f
->ref_count
== 1 &&
881 !cli_close(&file
->srv
->cli
, file
->f
->cli_fd
)) {
882 errno
= smbw_errno(&file
->srv
->cli
);
888 bitmap_clear(smbw_file_bmap
, file
->fd
);
891 DLIST_REMOVE(smbw_files
, file
);
893 file
->f
->ref_count
--;
894 if (file
->f
->ref_count
== 0) {
895 SAFE_FREE(file
->f
->fname
);
907 /*****************************************************
908 a wrapper for fcntl()
909 *******************************************************/
910 int smbw_fcntl(int fd
, int cmd
, long arg
)
916 /*****************************************************
917 a wrapper for access()
918 *******************************************************/
919 int smbw_access(const char *name
, int mode
)
923 DEBUG(4,("smbw_access(%s, 0x%x)\n", name
, mode
));
925 if (smbw_stat(name
, &st
)) return -1;
927 if (((mode
& R_OK
) && !(st
.st_mode
& S_IRUSR
)) ||
928 ((mode
& W_OK
) && !(st
.st_mode
& S_IWUSR
)) ||
929 ((mode
& X_OK
) && !(st
.st_mode
& S_IXUSR
))) {
937 /*****************************************************
938 a wrapper for realink() - needed for correct errno setting
939 *******************************************************/
940 int smbw_readlink(const char *path
, char *buf
, size_t bufsize
)
945 ret
= smbw_stat(path
, &st
);
947 DEBUG(4,("readlink(%s) failed\n", path
));
951 /* it exists - say it isn't a link */
952 DEBUG(4,("readlink(%s) not a link\n", path
));
959 /*****************************************************
960 a wrapper for unlink()
961 *******************************************************/
962 int smbw_unlink(const char *fname
)
964 struct smbw_server
*srv
;
965 fstring server
, share
;
977 /* work out what server they are after */
978 smbw_parse_path(fname
, server
, share
, path
);
980 /* get a connection to the server */
981 srv
= smbw_server(server
, share
);
983 /* smbw_server sets errno */
987 if (strncmp(srv
->cli
.dev
, "LPT", 3) == 0) {
988 int job
= smbw_stat_printjob(srv
, path
, NULL
, NULL
);
992 if (cli_printjob_del(&srv
->cli
, job
) != 0) {
995 } else if (!cli_unlink(&srv
->cli
, path
)) {
996 errno
= smbw_errno(&srv
->cli
);
1009 /*****************************************************
1010 a wrapper for rename()
1011 *******************************************************/
1012 int smbw_rename(const char *oldname
, const char *newname
)
1014 struct smbw_server
*srv
;
1015 fstring server1
, share1
;
1017 fstring server2
, share2
;
1020 if (!oldname
|| !newname
) {
1027 DEBUG(4,("smbw_rename(%s,%s)\n", oldname
, newname
));
1031 /* work out what server they are after */
1032 smbw_parse_path(oldname
, server1
, share1
, path1
);
1033 smbw_parse_path(newname
, server2
, share2
, path2
);
1035 if (strcmp(server1
, server2
) || strcmp(share1
, share2
)) {
1036 /* can't cross filesystems */
1041 /* get a connection to the server */
1042 srv
= smbw_server(server1
, share1
);
1044 /* smbw_server sets errno */
1048 if (!cli_rename(&srv
->cli
, path1
, path2
)) {
1049 int eno
= smbw_errno(&srv
->cli
);
1050 if (eno
!= EEXIST
||
1051 !cli_unlink(&srv
->cli
, path2
) ||
1052 !cli_rename(&srv
->cli
, path1
, path2
)) {
1067 /*****************************************************
1068 a wrapper for utime and utimes
1069 *******************************************************/
1070 static int smbw_settime(const char *fname
, time_t t
)
1072 struct smbw_server
*srv
;
1073 fstring server
, share
;
1086 /* work out what server they are after */
1087 smbw_parse_path(fname
, server
, share
, path
);
1089 /* get a connection to the server */
1090 srv
= smbw_server(server
, share
);
1092 /* smbw_server sets errno */
1096 if (!cli_getatr(&srv
->cli
, path
, &mode
, NULL
, NULL
)) {
1097 errno
= smbw_errno(&srv
->cli
);
1101 if (!cli_setatr(&srv
->cli
, path
, mode
, t
)) {
1102 /* some servers always refuse directory changes */
1103 if (!(mode
& aDIR
)) {
1104 errno
= smbw_errno(&srv
->cli
);
1117 /*****************************************************
1119 *******************************************************/
1120 int smbw_utime(const char *fname
, void *buf
)
1122 struct utimbuf
*tbuf
= (struct utimbuf
*)buf
;
1123 return smbw_settime(fname
, tbuf
?tbuf
->modtime
:time(NULL
));
1126 /*****************************************************
1128 *******************************************************/
1129 int smbw_utimes(const char *fname
, void *buf
)
1131 struct timeval
*tbuf
= (struct timeval
*)buf
;
1132 return smbw_settime(fname
, tbuf
?tbuf
->tv_sec
:time(NULL
));
1136 /*****************************************************
1137 a wrapper for chown()
1138 *******************************************************/
1139 int smbw_chown(const char *fname
, uid_t owner
, gid_t group
)
1141 struct smbw_server
*srv
;
1142 fstring server
, share
;
1155 /* work out what server they are after */
1156 smbw_parse_path(fname
, server
, share
, path
);
1158 /* get a connection to the server */
1159 srv
= smbw_server(server
, share
);
1161 /* smbw_server sets errno */
1165 if (!cli_getatr(&srv
->cli
, path
, &mode
, NULL
, NULL
)) {
1166 errno
= smbw_errno(&srv
->cli
);
1170 /* assume success */
1180 /*****************************************************
1181 a wrapper for chmod()
1182 *******************************************************/
1183 int smbw_chmod(const char *fname
, mode_t newmode
)
1185 struct smbw_server
*srv
;
1186 fstring server
, share
;
1199 /* work out what server they are after */
1200 smbw_parse_path(fname
, server
, share
, path
);
1202 /* get a connection to the server */
1203 srv
= smbw_server(server
, share
);
1205 /* smbw_server sets errno */
1211 if (!(newmode
& (S_IWUSR
| S_IWGRP
| S_IWOTH
))) mode
|= aRONLY
;
1212 if ((newmode
& S_IXUSR
) && lp_map_archive(-1)) mode
|= aARCH
;
1213 if ((newmode
& S_IXGRP
) && lp_map_system(-1)) mode
|= aSYSTEM
;
1214 if ((newmode
& S_IXOTH
) && lp_map_hidden(-1)) mode
|= aHIDDEN
;
1216 if (!cli_setatr(&srv
->cli
, path
, mode
, 0)) {
1217 errno
= smbw_errno(&srv
->cli
);
1229 /*****************************************************
1230 a wrapper for lseek()
1231 *******************************************************/
1232 off_t
smbw_lseek(int fd
, off_t offset
, int whence
)
1234 struct smbw_file
*file
;
1239 file
= smbw_file(fd
);
1241 off_t ret
= smbw_dir_lseek(fd
, offset
, whence
);
1248 file
->f
->offset
= offset
;
1251 file
->f
->offset
+= offset
;
1254 if (!cli_qfileinfo(&file
->srv
->cli
, file
->f
->cli_fd
,
1255 NULL
, &size
, NULL
, NULL
, NULL
,
1257 !cli_getattrE(&file
->srv
->cli
, file
->f
->cli_fd
,
1258 NULL
, &size
, NULL
, NULL
, NULL
)) {
1263 file
->f
->offset
= size
+ offset
;
1268 return file
->f
->offset
;
1272 /*****************************************************
1274 *******************************************************/
1275 int smbw_dup(int fd
)
1278 struct smbw_file
*file
, *file2
;
1282 file
= smbw_file(fd
);
1288 fd2
= dup(file
->fd
);
1293 if (bitmap_query(smbw_file_bmap
, fd2
)) {
1294 DEBUG(0,("ERROR: fd already open in dup!\n"));
1299 file2
= (struct smbw_file
*)malloc(sizeof(*file2
));
1306 ZERO_STRUCTP(file2
);
1311 file
->f
->ref_count
++;
1313 bitmap_set(smbw_file_bmap
, fd2
);
1315 DLIST_ADD(smbw_files
, file2
);
1326 /*****************************************************
1327 a wrapper for dup2()
1328 *******************************************************/
1329 int smbw_dup2(int fd
, int fd2
)
1331 struct smbw_file
*file
, *file2
;
1335 file
= smbw_file(fd
);
1341 if (bitmap_query(smbw_file_bmap
, fd2
)) {
1342 DEBUG(0,("ERROR: fd already open in dup2!\n"));
1347 if (dup2(file
->fd
, fd2
) != fd2
) {
1351 file2
= (struct smbw_file
*)malloc(sizeof(*file2
));
1358 ZERO_STRUCTP(file2
);
1363 file
->f
->ref_count
++;
1365 bitmap_set(smbw_file_bmap
, fd2
);
1367 DLIST_ADD(smbw_files
, file2
);
1378 /*****************************************************
1379 close a connection to a server
1380 *******************************************************/
1381 static void smbw_srv_close(struct smbw_server
*srv
)
1385 cli_shutdown(&srv
->cli
);
1387 SAFE_FREE(srv
->server_name
);
1388 SAFE_FREE(srv
->share_name
);
1390 DLIST_REMOVE(smbw_srvs
, srv
);
1399 /*****************************************************
1400 when we fork we have to close all connections and files
1402 *******************************************************/
1410 struct smbw_file
*file
, *next_file
;
1411 struct smbw_server
*srv
, *next_srv
;
1413 if (pipe(p
)) return real_fork();
1415 child
= real_fork();
1418 /* block the parent for a moment until the sockets are
1428 /* close all files */
1429 for (file
=smbw_files
;file
;file
=next_file
) {
1430 next_file
= file
->next
;
1434 /* close all server connections */
1435 for (srv
=smbw_srvs
;srv
;srv
=next_srv
) {
1436 next_srv
= srv
->next
;
1437 smbw_srv_close(srv
);
1440 slprintf(line
,sizeof(line
)-1,"PWD_%d", (int)getpid());
1441 smbw_setshared(line
,smbw_cwd
);
1443 /* unblock the parent */
1447 /* and continue in the child */
1451 #ifndef NO_ACL_WRAPPER
1452 /*****************************************************
1454 *******************************************************/
1455 int smbw_acl(const char *pathp
, int cmd
, int nentries
, aclent_t
*aclbufp
)
1457 if (cmd
== GETACL
|| cmd
== GETACLCNT
) return 0;
1463 #ifndef NO_FACL_WRAPPER
1464 /*****************************************************
1466 *******************************************************/
1467 int smbw_facl(int fd
, int cmd
, int nentries
, aclent_t
*aclbufp
)
1469 if (cmd
== GETACL
|| cmd
== GETACLCNT
) return 0;
1475 #ifdef HAVE_EXPLICIT_LARGEFILE_SUPPORT
1477 /* this can't be in wrapped.c because of include conflicts */
1478 void stat64_convert(struct stat
*st
, struct stat64
*st64
)
1480 st64
->st_size
= st
->st_size
;
1481 st64
->st_mode
= st
->st_mode
;
1482 st64
->st_ino
= st
->st_ino
;
1483 st64
->st_dev
= st
->st_dev
;
1484 st64
->st_rdev
= st
->st_rdev
;
1485 st64
->st_nlink
= st
->st_nlink
;
1486 st64
->st_uid
= st
->st_uid
;
1487 st64
->st_gid
= st
->st_gid
;
1488 st64
->st_atime
= st
->st_atime
;
1489 st64
->st_mtime
= st
->st_mtime
;
1490 st64
->st_ctime
= st
->st_ctime
;
1491 st64
->st_blksize
= st
->st_blksize
;
1492 st64
->st_blocks
= st
->st_blocks
;
1496 #ifdef HAVE_READDIR64
1497 void dirent64_convert(struct dirent
*d
, struct dirent64
*d64
)
1499 d64
->d_ino
= d
->d_ino
;
1500 d64
->d_off
= d
->d_off
;
1501 d64
->d_reclen
= d
->d_reclen
;
1502 pstrcpy(d64
->d_name
, d
->d_name
);
1509 /* Definition of `struct stat' used in the linux kernel.. */
1510 struct kernel_stat
{
1511 unsigned short int st_dev
;
1512 unsigned short int __pad1
;
1513 unsigned long int st_ino
;
1514 unsigned short int st_mode
;
1515 unsigned short int st_nlink
;
1516 unsigned short int st_uid
;
1517 unsigned short int st_gid
;
1518 unsigned short int st_rdev
;
1519 unsigned short int __pad2
;
1520 unsigned long int st_size
;
1521 unsigned long int st_blksize
;
1522 unsigned long int st_blocks
;
1523 unsigned long int st_atime
;
1524 unsigned long int __unused1
;
1525 unsigned long int st_mtime
;
1526 unsigned long int __unused2
;
1527 unsigned long int st_ctime
;
1528 unsigned long int __unused3
;
1529 unsigned long int __unused4
;
1530 unsigned long int __unused5
;
1534 * Prototype for gcc in 'fussy' mode.
1536 void xstat_convert(int vers
, struct stat
*st
, struct kernel_stat
*kbuf
);
1537 void xstat_convert(int vers
, struct stat
*st
, struct kernel_stat
*kbuf
)
1539 #ifdef _STAT_VER_LINUX_OLD
1540 if (vers
== _STAT_VER_LINUX_OLD
) {
1541 memcpy(st
, kbuf
, sizeof(*st
));
1548 st
->st_dev
= kbuf
->st_dev
;
1549 st
->st_ino
= kbuf
->st_ino
;
1550 st
->st_mode
= kbuf
->st_mode
;
1551 st
->st_nlink
= kbuf
->st_nlink
;
1552 st
->st_uid
= kbuf
->st_uid
;
1553 st
->st_gid
= kbuf
->st_gid
;
1554 st
->st_rdev
= kbuf
->st_rdev
;
1555 st
->st_size
= kbuf
->st_size
;
1556 st
->st_blksize
= kbuf
->st_blksize
;
1557 st
->st_blocks
= kbuf
->st_blocks
;
1558 st
->st_atime
= kbuf
->st_atime
;
1559 st
->st_mtime
= kbuf
->st_mtime
;
1560 st
->st_ctime
= kbuf
->st_ctime
;