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
;
55 if (initialised
) return;
63 setup_logging("smbsh",True
);
67 if ((p
=smbw_getshared("LOGFILE"))) {
68 dbf
= sys_fopen(p
, "a");
71 smbw_file_bmap
= bitmap_allocate(SMBW_MAX_OPEN
);
72 if (!smbw_file_bmap
) {
82 if ((p
=smbw_getshared("SERVICESF"))) {
83 pstrcpy(servicesf
, p
);
86 lp_load(servicesf
,True
,False
,False
);
88 get_myname(global_myname
);
90 if ((p
=smbw_getshared("DEBUG"))) {
94 if ((p
=smbw_getshared("RESOLVE_ORDER"))) {
95 lp_set_name_resolve_order(p
);
98 if ((p
=smbw_getshared("PREFIX"))) {
99 slprintf(smbw_prefix
,sizeof(fstring
)-1, "/%s/", p
);
100 all_string_sub(smbw_prefix
,"//", "/", 0);
101 DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix
));
104 slprintf(line
,sizeof(line
)-1,"PWD_%d", (int)getpid());
106 p
= smbw_getshared(line
);
110 pstrcpy(smbw_cwd
, p
);
111 DEBUG(4,("Initial cwd is %s\n", smbw_cwd
));
115 set_maxfiles(SMBW_MAX_OPEN
);
117 BlockSignals(True
,SIGPIPE
);
122 /*****************************************************
123 determine if a file descriptor is a smb one
124 *******************************************************/
127 if (smbw_busy
) return 0;
128 return smbw_file_bmap
&& bitmap_query(smbw_file_bmap
, fd
);
131 /*****************************************************
132 determine if a file descriptor is an internal smbw fd
133 *******************************************************/
134 int smbw_local_fd(int fd
)
136 struct smbw_server
*srv
;
140 if (smbw_busy
) return 0;
141 if (smbw_shared_fd(fd
)) return 1;
143 for (srv
=smbw_srvs
;srv
;srv
=srv
->next
) {
144 if (srv
->cli
.fd
== fd
) return 1;
150 /*****************************************************
151 a crude inode number generator
152 *******************************************************/
153 ino_t
smbw_inode(const char *name
)
155 if (!*name
) return 2;
156 return (ino_t
)str_checksum(name
);
159 /*****************************************************
160 remove redundent stuff from a filename
161 *******************************************************/
162 void clean_fname(char *name
)
173 DEBUG(5,("cleaning %s\n", name
));
175 if ((p
=strstr(name
,"/./"))) {
183 if ((p
=strstr(name
,"//"))) {
191 if (strcmp(name
,"/../")==0) {
196 if ((p
=strstr(name
,"/../"))) {
198 for (p2
=(p
>name
?p
-1:p
);p2
>name
;p2
--) {
199 if (p2
[0] == '/') break;
207 if (strcmp(name
,"/..")==0) {
213 p
= l
>=3?(name
+l
-3):name
;
214 if (strcmp(p
,"/..")==0) {
216 for (p2
=p
-1;p2
>name
;p2
--) {
217 if (p2
[0] == '/') break;
228 p
= l
>=2?(name
+l
-2):name
;
229 if (strcmp(p
,"/.")==0) {
237 if (strncmp(p
=name
,"./",2) == 0) {
245 if (l
> 1 && p
[l
-1] == '/') {
254 /*****************************************************
255 find a workgroup (any workgroup!) that has a master
256 browser on the local network
257 *******************************************************/
258 static char *smbw_find_workgroup(void)
262 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!"));
279 free((char *)ip_list
);
281 DEBUG(0,("Need to do node status code"));
285 /*****************************************************
286 parse a smb path into its components.
288 1) the name of the SMB server
289 2) WORKGROUP#1D for share listing
290 3) WORKGROUP#__ for workgroup listing
291 share is the share on the server to query
292 path is the SMB path on the server
293 return the full path (ie. add cwd if needed)
294 *******************************************************/
295 char *smbw_parse_path(const char *fname
, char *server
, char *share
, char *path
)
302 /* add cwd if necessary */
303 if (fname
[0] != '/') {
304 slprintf(s
, sizeof(s
), "%s/%s", smbw_cwd
, fname
);
310 /* see if it has the right prefix */
311 len
= strlen(smbw_prefix
)-1;
312 if (strncmp(s
,smbw_prefix
,len
) ||
313 (s
[len
] != '/' && s
[len
] != 0)) return s
;
315 /* ok, its for us. Now parse out the workgroup, share etc. */
318 if (!next_token(&p
, workgroup
, "/", sizeof(fstring
))) {
319 /* we're in /smb - give a list of workgroups */
320 slprintf(server
,sizeof(fstring
), "%s#01", smbw_find_workgroup());
321 fstrcpy(share
,"IPC$");
326 if (!next_token(&p
, server
, "/", sizeof(fstring
))) {
327 /* we are in /smb/WORKGROUP */
328 slprintf(server
,sizeof(fstring
), "%s#1D", workgroup
);
329 fstrcpy(share
,"IPC$");
333 if (!next_token(&p
, share
, "/", sizeof(fstring
))) {
334 /* we are in /smb/WORKGROUP/SERVER */
335 fstrcpy(share
,"IPC$");
341 all_string_sub(path
, "/", "\\", 0);
346 /*****************************************************
347 determine if a path name (possibly relative) is in the
349 *******************************************************/
350 int smbw_path(const char *path
)
352 fstring server
, share
;
360 /* this is needed to prevent recursion with the BSD malloc which
361 opens /etc/malloc.conf on the first call */
362 if (strncmp(path
,"/etc/", 5) == 0) {
368 len
= strlen(smbw_prefix
)-1;
370 if (path
[0] == '/' && strncmp(path
,smbw_prefix
,len
)) {
374 if (smbw_busy
) return 0;
376 DEBUG(3,("smbw_path(%s)\n", path
));
378 cwd
= smbw_parse_path(path
, server
, share
, s
);
380 if (strncmp(cwd
,smbw_prefix
,len
) == 0 &&
381 (cwd
[len
] == '/' || cwd
[len
] == 0)) {
388 /*****************************************************
389 return a unix errno from a SMB error pair
390 *******************************************************/
391 int smbw_errno(struct cli_state
*c
)
397 ret
= cli_error(c
, &eclass
, &ecode
, NULL
);
400 DEBUG(3,("smbw_error %d %d (0x%x) -> %d\n",
401 (int)eclass
, (int)ecode
, (int)ecode
, ret
));
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(server_n
,'#')) &&
476 (strcmp(p
+1,"1D")==0 || strcmp(p
+1,"01")==0)) {
480 fstrcpy(group
, server_n
);
481 p
= strchr(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 if (srv
->server_name
) free(srv
->server_name
);
610 if (srv
->share_name
) 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 if (file
->f
->fname
) {
726 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 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 free(srv
->server_name
);
1388 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
;