2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1998
6 Copyright (C) Derrell Lipman 2002-2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * This is a rewrite of the original wrapped.c file, using libdl to obtain
24 * pointers into the C library rather than attempting to find undocumented
25 * functions in the C library to call for native file access. The problem
26 * with the original implementation's paradigm is that samba manipulates
27 * defines such that it gets the sizes of structures that it wants
28 * (e.g. mapping 32-bit functions to 64-bit functions with their associated
29 * 64-bit structure fields), but programs run under smbsh or using
30 * smbwrapper.so were not necessarily compiled with the same flags. As an
31 * example of the problem, a program calling stat() passes a pointer to a
32 * "struct stat" but the fields in that structure are different in samba than
33 * they are in the calling program if the calling program was not compiled to
34 * force stat() to be mapped to stat64().
36 * In this version, we provide an interface to each of the native functions,
37 * not just the ones that samba is compiled to map to. We obtain the function
38 * pointers from the C library using dlsym(), and for native file operations,
39 * directly call the same function that the calling application was
40 * requesting. Since the size of the calling application's structures vary
41 * depending on what function was called, we use our own internal structures
42 * for passing information to/from the SMB equivalent functions, and map them
43 * back to the native structures before returning the result to the caller.
45 * This implementation was completed 25 December 2002.
49 /* We do not want auto munging of 32->64 bit names in this file (only) */
50 #undef _FILE_OFFSET_BITS
53 #include <sys/types.h>
68 #define __USE_GNU /* need this to have RTLD_NEXT defined */
74 #include "libsmbclient.h"
75 #include "bsd-strlfunc.h"
81 * 0x1 = display symbol definitions not found in C library
82 * 0x2 = show wrapper functions being called
83 * 0x4 = log to file SMBW_DEBUG_FILE instead of stderr
85 #define SMBW_DEBUG 0x0
86 #define SMBW_DEBUG_FILE "/tmp/smbw.log"
91 static int debugFd
= 2;
95 #define ENOTSUP EOPNOTSUPP
99 * None of the methods of having the initialization function called
100 * automatically upon shared library startup are effective in all situations.
101 * We provide the "-init" parameter to the linker which is effective most of
102 * the time, but fails for applications that provide their own shared
103 * libraries with _init() functions (e.g. ps). We can't use "-z initfirst"
104 * because the environment isn't yet set up at that point, so we can't find
105 * our shared memory identifier (see shared.c). We therefore must resort to
106 * this tried-and-true method of keeping an "initialized" flag. We check it
107 * prior to calling the initialize() function to save a function call (a slow
111 # define check_init(buf) \
113 int saved_errno = errno; \
114 if (! initialized) initialize(); \
115 (* smbw_libc.write)(debugFd, "["buf"]", sizeof(buf)+1); \
116 errno = saved_errno; \
119 # define check_init(buf) \
121 if (! initialized) smbw_initialize(); \
125 static void initialize(void);
127 static int initialized
= 0;
129 SMBW_libc_pointers smbw_libc
;
132 * A public entry point used by the "-init" option to the linker.
134 void smbw_initialize(void)
139 static void initialize(void)
154 # define GETSYM(symname, symstring) \
155 if ((smbw_libc.symname = dlsym(RTLD_NEXT, symstring)) == NULL) { \
156 if (smbw_libc.write != NULL && \
157 (error = dlerror()) != NULL) { \
158 (* smbw_libc.write)(1, error, strlen(error)); \
159 (* smbw_libc.write)(1, "\n", 1); \
163 # define GETSYM(symname, symstring) \
164 smbw_libc.symname = dlsym(RTLD_NEXT, symstring);
168 * Get pointers to each of the symbols we'll need, from the C library
170 * Some of these symbols may not be found in the C library. That's
171 * fine. We declare all of them here, and if the C library supports
172 * them, they may be called so we have the wrappers for them. If the
173 * C library doesn't support them, then the wrapper function will
174 * never be called, and the null pointer will never be dereferenced.
176 GETSYM(write
, "write"); /* first, to allow debugging */
177 GETSYM(open
, "open");
178 GETSYM(_open
, "_open");
179 GETSYM(__open
, "__open");
180 GETSYM(open64
, "open64");
181 GETSYM(_open64
, "_open64");
182 GETSYM(__open64
, "__open64");
183 GETSYM(pread
, "pread");
184 GETSYM(pread64
, "pread64");
185 GETSYM(pwrite
, "pwrite");
186 GETSYM(pwrite64
, "pwrite64");
187 GETSYM(close
, "close");
188 GETSYM(__close
, "__close");
189 GETSYM(_close
, "_close");
190 GETSYM(fcntl
, "fcntl");
191 GETSYM(__fcntl
, "__fcntl");
192 GETSYM(_fcntl
, "_fcntl");
193 GETSYM(getdents
, "getdents");
194 GETSYM(__getdents
, "__getdents");
195 GETSYM(_getdents
, "_getdents");
196 GETSYM(getdents64
, "getdents64");
197 GETSYM(lseek
, "lseek");
198 GETSYM(__lseek
, "__lseek");
199 GETSYM(_lseek
, "_lseek");
200 GETSYM(lseek64
, "lseek64");
201 GETSYM(__lseek64
, "__lseek64");
202 GETSYM(_lseek64
, "_lseek64");
203 GETSYM(read
, "read");
204 GETSYM(__read
, "__read");
205 GETSYM(_read
, "_read");
206 GETSYM(__write
, "__write");
207 GETSYM(_write
, "_write");
208 GETSYM(access
, "access");
209 GETSYM(chmod
, "chmod");
210 GETSYM(fchmod
, "fchmod");
211 GETSYM(chown
, "chown");
212 GETSYM(fchown
, "fchown");
213 GETSYM(__xstat
, "__xstat");
214 GETSYM(getcwd
, "getcwd");
215 GETSYM(mkdir
, "mkdir");
216 GETSYM(__fxstat
, "__fxstat");
217 GETSYM(__lxstat
, "__lxstat");
218 GETSYM(stat
, "stat");
219 GETSYM(lstat
, "lstat");
220 GETSYM(fstat
, "fstat");
221 GETSYM(unlink
, "unlink");
222 GETSYM(utime
, "utime");
223 GETSYM(utimes
, "utimes");
224 GETSYM(readlink
, "readlink");
225 GETSYM(rename
, "rename");
226 GETSYM(rmdir
, "rmdir");
227 GETSYM(symlink
, "symlink");
229 GETSYM(dup2
, "dup2");
230 GETSYM(opendir
, "opendir");
231 GETSYM(readdir
, "readdir");
232 GETSYM(closedir
, "closedir");
233 GETSYM(telldir
, "telldir");
234 GETSYM(seekdir
, "seekdir");
235 GETSYM(creat
, "creat");
236 GETSYM(creat64
, "creat64");
237 GETSYM(__xstat64
, "__xstat64");
238 GETSYM(stat64
, "stat64");
239 GETSYM(__fxstat64
, "__fxstat64");
240 GETSYM(fstat64
, "fstat64");
241 GETSYM(__lxstat64
, "__lxstat64");
242 GETSYM(lstat64
, "lstat64");
243 GETSYM(_llseek
, "_llseek");
244 GETSYM(readdir64
, "readdir64");
245 GETSYM(readdir_r
, "readdir_r");
246 GETSYM(readdir64_r
, "readdir64_r");
247 GETSYM(setxattr
, "setxattr");
248 GETSYM(lsetxattr
, "lsetxattr");
249 GETSYM(fsetxattr
, "fsetxattr");
250 GETSYM(getxattr
, "getxattr");
251 GETSYM(lgetxattr
, "lgetxattr");
252 GETSYM(fgetxattr
, "fgetxattr");
253 GETSYM(removexattr
, "removexattr");
254 GETSYM(lremovexattr
, "lremovexattr");
255 GETSYM(fremovexattr
, "fremovexattr");
256 GETSYM(listxattr
, "listxattr");
257 GETSYM(llistxattr
, "llistxattr");
258 GETSYM(flistxattr
, "flistxattr");
259 GETSYM(chdir
, "chdir");
260 GETSYM(fchdir
, "fchdir");
261 GETSYM(fork
, "fork");
262 GETSYM(select
, "select");
263 GETSYM(_select
, "_select");
264 GETSYM(__select
, "__select");
269 open(SMBW_DEBUG_FILE
, O_WRONLY
| O_CREAT
| O_APPEND
)) < 0)
271 # define SMBW_MESSAGE "Could not create " SMBW_DEBUG_FILE "\n"
272 (* smbw_libc
.write
)(1, SMBW_MESSAGE
, sizeof(SMBW_MESSAGE
));
286 static void stat_convert(struct SMBW_stat
*src
, struct stat
*dest
)
288 memset(dest
, '\0', sizeof(*dest
));
289 dest
->st_size
= src
->s_size
;
290 dest
->st_mode
= src
->s_mode
;
291 dest
->st_ino
= src
->s_ino
;
292 dest
->st_dev
= src
->s_dev
;
293 dest
->st_rdev
= src
->s_rdev
;
294 dest
->st_nlink
= src
->s_nlink
;
295 dest
->st_uid
= src
->s_uid
;
296 dest
->st_gid
= src
->s_gid
;
297 dest
->st_atime
= src
->s_atime
;
298 dest
->st_mtime
= src
->s_mtime
;
299 dest
->st_ctime
= src
->s_ctime
;
300 dest
->st_blksize
= src
->s_blksize
;
301 dest
->st_blocks
= src
->s_blocks
;
304 static void stat64_convert(struct SMBW_stat
*src
, struct stat64
*dest
)
306 memset(dest
, '\0', sizeof(*dest
));
307 dest
->st_size
= src
->s_size
;
308 dest
->st_mode
= src
->s_mode
;
309 dest
->st_ino
= src
->s_ino
;
310 dest
->st_dev
= src
->s_dev
;
311 dest
->st_rdev
= src
->s_rdev
;
312 dest
->st_nlink
= src
->s_nlink
;
313 dest
->st_uid
= src
->s_uid
;
314 dest
->st_gid
= src
->s_gid
;
315 dest
->st_atime
= src
->s_atime
;
316 dest
->st_mtime
= src
->s_mtime
;
317 dest
->st_ctime
= src
->s_ctime
;
318 dest
->st_blksize
= src
->s_blksize
;
319 dest
->st_blocks
= src
->s_blocks
;
322 static void dirent_convert(struct SMBW_dirent
*src
, struct dirent
*dest
)
326 memset(dest
, '\0', sizeof(*dest
));
327 dest
->d_ino
= src
->d_ino
;
328 dest
->d_off
= src
->d_off
;
334 case SMBC_FILE_SHARE
:
336 dest
->d_type
= DT_DIR
;
340 dest
->d_type
= DT_REG
;
343 case SMBC_PRINTER_SHARE
:
344 dest
->d_type
= DT_CHR
;
347 case SMBC_COMMS_SHARE
:
348 dest
->d_type
= DT_SOCK
;
352 dest
->d_type
= DT_FIFO
;
356 dest
->d_type
= DT_LNK
;
360 dest
->d_reclen
= src
->d_reclen
;
361 smbw_strlcpy(dest
->d_name
, src
->d_name
, sizeof(dest
->d_name
));
362 p
= dest
->d_name
+ strlen(dest
->d_name
) + 1;
365 sizeof(dest
->d_name
) - (p
- dest
->d_name
));
368 static void dirent64_convert(struct SMBW_dirent
*src
, struct dirent64
*dest
)
372 memset(dest
, '\0', sizeof(*dest
));
373 dest
->d_ino
= src
->d_ino
;
374 dest
->d_off
= src
->d_off
;
380 case SMBC_FILE_SHARE
:
382 dest
->d_type
= DT_DIR
;
386 dest
->d_type
= DT_REG
;
389 case SMBC_PRINTER_SHARE
:
390 dest
->d_type
= DT_CHR
;
393 case SMBC_COMMS_SHARE
:
394 dest
->d_type
= DT_SOCK
;
398 dest
->d_type
= DT_FIFO
;
402 dest
->d_type
= DT_LNK
;
406 dest
->d_reclen
= src
->d_reclen
;
407 smbw_strlcpy(dest
->d_name
, src
->d_name
, sizeof(dest
->d_name
));
408 p
= dest
->d_name
+ strlen(dest
->d_name
) + 1;
411 sizeof(dest
->d_name
) - (p
- dest
->d_name
));
414 static int openx(char *name
, int flags
, mode_t mode
, int (* f
)(char *, int, mode_t
))
416 if (smbw_path(name
)) {
417 return smbw_open(name
, flags
, mode
);
420 return (* f
)(name
, flags
, mode
);
423 static int closex(int fd
, int (* f
)(int fd
))
426 return smbw_close(fd
);
432 static int fcntlx(int fd
, int cmd
, long arg
, int (* f
)(int, int, long))
435 return smbw_fcntl(fd
, cmd
, arg
);
438 return (* f
)(fd
, cmd
, arg
);
441 static int getdentsx(int fd
, struct dirent
*external
, unsigned int count
, int (* f
)(int, struct dirent
*, unsigned int))
446 struct SMBW_dirent
*internal
;
451 * LIMITATION: If they pass a count which is not a multiple of
452 * the size of struct dirent, they will not get a partial
453 * structure; we ignore the excess count.
455 n
= (count
/ sizeof(struct dirent
));
457 internal_count
= sizeof(struct SMBW_dirent
) * n
;
458 internal
= malloc(internal_count
);
459 if (internal
== NULL
) {
463 ret
= smbw_getdents(fd
, internal
, internal_count
);
467 ret
= sizeof(struct dirent
) * n
;
469 for (i
= 0; i
< n
; i
++)
470 dirent_convert(&internal
[i
], &external
[i
]);
475 return (* f
)(fd
, external
, count
);
478 static off_t
lseekx(int fd
,
481 off_t (* f
)(int, off_t
, int))
486 * We have left the definitions of the smbw_ functions undefined,
487 * because types such as off_t can differ in meaning betweent his
488 * function and smbw.c et al. Functions that return other than an
489 * integer value, however, MUST have their return value defined.
491 off64_t
smbw_lseek();
494 return (off_t
) smbw_lseek(fd
, offset
, whence
);
497 ret
= (* f
)(fd
, offset
, whence
);
500 printf("lseekx(%d, 0x%llx) returned 0x%llx\n",
502 (unsigned long long) offset
,
503 (unsigned long long) ret
);
508 static off64_t
lseek64x(int fd
,
511 off64_t (* f
)(int, off64_t
, int))
516 * We have left the definitions of the smbw_ functions undefined,
517 * because types such as off_t can differ in meaning betweent his
518 * function and smbw.c et al. Functions that return other than an
519 * integer value, however, MUST have their return value defined.
521 off64_t
smbw_lseek();
524 ret
= smbw_lseek(fd
, offset
, whence
);
526 ret
= (* f
)(fd
, offset
, whence
);
529 printf("lseek64x(%d, 0x%llx) returned 0x%llx\n",
531 (unsigned long long) offset
,
532 (unsigned long long) ret
);
537 static ssize_t
readx(int fd
, void *buf
, size_t count
, ssize_t (* f
)(int, void *, size_t))
540 return smbw_read(fd
, buf
, count
);
543 return (* f
)(fd
, buf
, count
);
546 static ssize_t
writex(int fd
, void *buf
, size_t count
, ssize_t (* f
)(int, void *, size_t))
549 return smbw_write(fd
, buf
, count
);
552 return (* f
)(fd
, buf
, count
);
560 int open(__const
char *name
, int flags
, ...)
566 mode
= va_arg(ap
, mode_t
);
571 return openx((char *) name
, flags
, mode
, smbw_libc
.open
);
574 int _open(char *name
, int flags
, mode_t mode
)
578 return openx(name
, flags
, mode
, smbw_libc
._open
);
581 int __open(char *name
, int flags
, mode_t mode
)
585 return openx(name
, flags
, mode
, smbw_libc
.__open
);
588 int open64 (__const
char *name
, int flags
, ...)
594 mode
= va_arg(ap
, mode_t
);
597 check_init("open64");
598 return openx((char *) name
, flags
, mode
, smbw_libc
.open64
);
601 int _open64(char *name
, int flags
, mode_t mode
)
603 check_init("_open64");
604 return openx(name
, flags
, mode
, smbw_libc
._open64
);
607 int __open64(char *name
, int flags
, mode_t mode
)
609 check_init("__open64");
610 return openx(name
, flags
, mode
, smbw_libc
.__open64
);
613 ssize_t
pread(int fd
, void *buf
, size_t size
, off_t ofs
)
618 return smbw_pread(fd
, buf
, size
, ofs
);
621 return (* smbw_libc
.pread
)(fd
, buf
, size
, ofs
);
624 ssize_t
pread64(int fd
, void *buf
, size_t size
, off64_t ofs
)
626 check_init("pread64");
629 return smbw_pread(fd
, buf
, size
, (off_t
) ofs
);
632 return (* smbw_libc
.pread64
)(fd
, buf
, size
, ofs
);
635 ssize_t
pwrite(int fd
, const void *buf
, size_t size
, off_t ofs
)
637 check_init("pwrite");
640 return smbw_pwrite(fd
, (void *) buf
, size
, ofs
);
643 return (* smbw_libc
.pwrite
)(fd
, (void *) buf
, size
, ofs
);
646 ssize_t
pwrite64(int fd
, const void *buf
, size_t size
, off64_t ofs
)
648 check_init("pwrite64");
651 return smbw_pwrite(fd
, (void *) buf
, size
, (off_t
) ofs
);
654 return (* smbw_libc
.pwrite64
)(fd
, (void *) buf
, size
, ofs
);
657 int chdir(const char *name
)
660 return smbw_chdir((char *) name
);;
663 int __chdir(char *name
)
665 check_init("__chdir");
666 return smbw_chdir(name
);
669 int _chdir(char *name
)
671 check_init("_chdir");
672 return smbw_chdir(name
);
678 return closex(fd
, smbw_libc
.close
);
683 check_init("__close");
684 return closex(fd
, smbw_libc
.__close
);
689 check_init("_close");
690 return closex(fd
, smbw_libc
._close
);
695 check_init("fchdir");
696 return smbw_fchdir(fd
);
701 check_init("__fchdir");
707 check_init("_fchdir");
711 int fcntl (int fd
, int cmd
, ...)
717 arg
= va_arg(ap
, long);
721 return fcntlx(fd
, cmd
, arg
, smbw_libc
.fcntl
);
724 int __fcntl(int fd
, int cmd
, ...)
730 arg
= va_arg(ap
, long);
733 check_init("__fcntl");
734 return fcntlx(fd
, cmd
, arg
, smbw_libc
.__fcntl
);
737 int _fcntl(int fd
, int cmd
, ...)
743 arg
= va_arg(ap
, long);
746 check_init("_fcntl");
747 return fcntlx(fd
, cmd
, arg
, smbw_libc
._fcntl
);
750 int getdents(int fd
, struct dirent
*dirp
, unsigned int count
)
752 check_init("getdents");
753 return getdentsx(fd
, dirp
, count
, smbw_libc
.getdents
);
756 int __getdents(int fd
, struct dirent
*dirp
, unsigned int count
)
758 check_init("__getdents");
759 return getdentsx(fd
, dirp
, count
, smbw_libc
.__getdents
);
762 int _getdents(int fd
, struct dirent
*dirp
, unsigned int count
)
764 check_init("_getdents");
765 return getdentsx(fd
, dirp
, count
, smbw_libc
._getdents
);
768 int getdents64(int fd
, struct dirent64
*external
, unsigned int count
)
770 check_init("getdents64");
773 struct SMBW_dirent
*internal
;
778 * LIMITATION: If they pass a count which is not a multiple of
779 * the size of struct dirent, they will not get a partial
780 * structure; we ignore the excess count.
782 n
= (count
/ sizeof(struct dirent64
));
784 internal
= malloc(sizeof(struct SMBW_dirent
) * n
);
785 if (internal
== NULL
) {
789 ret
= smbw_getdents(fd
, internal
, count
);
793 ret
= sizeof(struct dirent
) * count
;
795 for (i
= 0; count
; i
++, count
--)
796 dirent64_convert(&internal
[i
], &external
[i
]);
801 return (* smbw_libc
.getdents64
)(fd
, external
, count
);
804 off_t
lseek(int fd
, off_t offset
, int whence
)
808 ret
= lseekx(fd
, offset
, whence
, smbw_libc
.lseek
);
811 printf("lseek(%d, 0x%llx) returned 0x%llx\n",
813 (unsigned long long) offset
,
814 (unsigned long long) ret
);
819 off_t
__lseek(int fd
, off_t offset
, int whence
)
822 check_init("__lseek");
823 ret
= lseekx(fd
, offset
, whence
, smbw_libc
.__lseek
);
826 printf("__lseek(%d, 0x%llx) returned 0x%llx\n",
828 (unsigned long long) offset
,
829 (unsigned long long) ret
);
834 off_t
_lseek(int fd
, off_t offset
, int whence
)
837 check_init("_lseek");
838 ret
= lseekx(fd
, offset
, whence
, smbw_libc
._lseek
);
841 printf("_lseek(%d, 0x%llx) returned 0x%llx\n",
843 (unsigned long long) offset
,
844 (unsigned long long) ret
);
849 off64_t
lseek64(int fd
, off64_t offset
, int whence
)
852 check_init("lseek64");
853 ret
= lseek64x(fd
, offset
, whence
, smbw_libc
.lseek64
);
856 printf("lseek64(%d, 0x%llx) returned 0x%llx\n",
858 (unsigned long long) offset
,
859 (unsigned long long) ret
);
864 off64_t
__lseek64(int fd
, off64_t offset
, int whence
)
866 check_init("__lseek64");
867 return lseek64x(fd
, offset
, whence
, smbw_libc
.__lseek64
);
870 off64_t
_lseek64(int fd
, off64_t offset
, int whence
)
873 check_init("_lseek64");
874 ret
= lseek64x(fd
, offset
, whence
, smbw_libc
._lseek64
);
877 printf("_lseek64(%d, 0x%llx) returned 0x%llx\n",
879 (unsigned long long) offset
,
880 (unsigned long long) ret
);
885 ssize_t
read(int fd
, void *buf
, size_t count
)
888 return readx(fd
, buf
, count
, smbw_libc
.read
);
891 ssize_t
__read(int fd
, void *buf
, size_t count
)
893 check_init("__read");
894 return readx(fd
, buf
, count
, smbw_libc
.__read
);
897 ssize_t
_read(int fd
, void *buf
, size_t count
)
900 return readx(fd
, buf
, count
, smbw_libc
._read
);
903 ssize_t
write(int fd
, const void *buf
, size_t count
)
906 return writex(fd
, (void *) buf
, count
, smbw_libc
.write
);
909 ssize_t
__write(int fd
, const void *buf
, size_t count
)
911 check_init("__write");
912 return writex(fd
, (void *) buf
, count
, smbw_libc
.__write
);
915 ssize_t
_write(int fd
, const void *buf
, size_t count
)
917 check_init("_write");
918 return writex(fd
, (void *) buf
, count
, smbw_libc
._write
);
921 int access(const char *name
, int mode
)
923 check_init("access");
925 if (smbw_path((char *) name
)) {
926 return smbw_access((char *) name
, mode
);
929 return (* smbw_libc
.access
)((char *) name
, mode
);
932 int chmod(const char *name
, mode_t mode
)
936 if (smbw_path((char *) name
)) {
937 return smbw_chmod((char *) name
, mode
);
940 return (* smbw_libc
.chmod
)((char *) name
, mode
);
943 int fchmod(int fd
, mode_t mode
)
945 check_init("fchmod");
948 /* Not yet implemented in libsmbclient */
952 return (* smbw_libc
.fchmod
)(fd
, mode
);
955 int chown(const char *name
, uid_t owner
, gid_t group
)
959 if (smbw_path((char *) name
)) {
960 return smbw_chown((char *) name
, owner
, group
);
963 return (* smbw_libc
.chown
)((char *) name
, owner
, group
);
966 int fchown(int fd
, uid_t owner
, gid_t group
)
968 check_init("fchown");
971 /* Not yet implemented in libsmbclient */
975 return (* smbw_libc
.fchown
)(fd
, owner
, group
);
978 char *getcwd(char *buf
, size_t size
)
980 check_init("getcwd");
981 return (char *)smbw_getcwd(buf
, size
);
984 int mkdir(const char *name
, mode_t mode
)
988 if (smbw_path((char *) name
)) {
989 return smbw_mkdir((char *) name
, mode
);
992 return (* smbw_libc
.mkdir
)((char *) name
, mode
);
995 int __fxstat(int vers
, int fd
, struct stat
*st
)
997 check_init("__fxstat");
1000 struct SMBW_stat statbuf
;
1001 int ret
= smbw_fstat(fd
, &statbuf
);
1002 stat_convert(&statbuf
, st
);
1006 return (* smbw_libc
.__fxstat
)(vers
, fd
, st
);
1009 int __xstat(int vers
, const char *name
, struct stat
*st
)
1011 check_init("__xstat");
1013 if (smbw_path((char *) name
)) {
1014 struct SMBW_stat statbuf
;
1015 int ret
= smbw_stat((char *) name
, &statbuf
);
1016 stat_convert(&statbuf
, st
);
1020 return (* smbw_libc
.__xstat
)(vers
, (char *) name
, st
);
1023 int __lxstat(int vers
, const char *name
, struct stat
*st
)
1025 check_init("__lxstat");
1027 if (smbw_path((char *) name
)) {
1028 struct SMBW_stat statbuf
;
1029 int ret
= smbw_stat((char *) name
, &statbuf
);
1030 stat_convert(&statbuf
, st
);
1034 return (* smbw_libc
.__lxstat
)(vers
, (char *) name
, st
);
1037 int stat(const char *name
, struct stat
*st
)
1041 if (smbw_path((char *) name
)) {
1042 struct SMBW_stat statbuf
;
1043 int ret
= smbw_stat((char *) name
, &statbuf
);
1044 stat_convert(&statbuf
, st
);
1048 return (* smbw_libc
.stat
)((char *) name
, st
);
1051 int lstat(const char *name
, struct stat
*st
)
1053 check_init("lstat");
1055 if (smbw_path((char *) name
)) {
1056 struct SMBW_stat statbuf
;
1057 int ret
= smbw_stat((char *) name
, &statbuf
);
1058 stat_convert(&statbuf
, st
);
1062 return (* smbw_libc
.lstat
)((char *) name
, st
);
1065 int fstat(int fd
, struct stat
*st
)
1067 check_init("fstat");
1070 struct SMBW_stat statbuf
;
1071 int ret
= smbw_fstat(fd
, &statbuf
);
1072 stat_convert(&statbuf
, st
);
1076 return (* smbw_libc
.fstat
)(fd
, st
);
1079 int unlink(const char *name
)
1081 check_init("unlink");
1083 if (smbw_path((char *) name
)) {
1084 return smbw_unlink((char *) name
);
1087 return (* smbw_libc
.unlink
)((char *) name
);
1090 int utime(const char *name
, const struct utimbuf
*tvp
)
1092 check_init("utime");
1094 if (smbw_path(name
)) {
1095 return smbw_utime(name
, (struct utimbuf
*) tvp
);
1098 return (* smbw_libc
.utime
)((char *) name
, (struct utimbuf
*) tvp
);
1101 int utimes(const char *name
, const struct timeval
*tvp
)
1103 check_init("utimes");
1105 if (smbw_path(name
)) {
1106 return smbw_utimes(name
, (struct timeval
*) tvp
);
1109 return (* smbw_libc
.utimes
)((char *) name
, (struct timeval
*) tvp
);
1112 ssize_t
readlink(const char *path
, char *buf
, size_t bufsize
)
1114 check_init("readlink");
1116 if (smbw_path((char *) path
)) {
1117 return smbw_readlink(path
, (char *) buf
, bufsize
);
1120 return (* smbw_libc
.readlink
)((char *) path
, buf
, bufsize
);
1123 int rename(const char *oldname
, const char *newname
)
1127 check_init("rename");
1129 p1
= smbw_path((char *) oldname
);
1130 p2
= smbw_path((char *) newname
);
1132 /* can't cross filesystem boundaries */
1137 return smbw_rename((char *) oldname
, (char *) newname
);
1140 return (* smbw_libc
.rename
)((char *) oldname
, (char *) newname
);
1143 int rmdir(const char *name
)
1145 check_init("rmdir");
1147 if (smbw_path((char *) name
)) {
1148 return smbw_rmdir((char *) name
);
1151 return (* smbw_libc
.rmdir
)((char *) name
);
1154 int symlink(const char *topath
, const char *frompath
)
1158 check_init("symlink");
1160 p1
= smbw_path((char *) topath
);
1161 p2
= smbw_path((char *) frompath
);
1163 /* can't handle symlinks */
1168 return (* smbw_libc
.symlink
)((char *) topath
, (char *) frompath
);
1176 return smbw_dup(fd
);
1179 return (* smbw_libc
.dup
)(fd
);
1182 int dup2(int oldfd
, int newfd
)
1186 if (smbw_fd(newfd
)) {
1187 (* smbw_libc
.close
)(newfd
);
1190 if (smbw_fd(oldfd
)) {
1191 return smbw_dup2(oldfd
, newfd
);
1194 return (* smbw_libc
.dup2
)(oldfd
, newfd
);
1198 DIR *opendir(const char *name
)
1200 check_init("opendir");
1202 if (smbw_path((char *) name
)) {
1203 return (void *)smbw_opendir((char *) name
);
1206 return (* smbw_libc
.opendir
)((char *) name
);
1209 struct dirent
*readdir(DIR *dir
)
1211 check_init("readdir");
1213 if (smbw_dirp(dir
)) {
1214 static struct dirent external
;
1215 struct SMBW_dirent
* internal
= (void *)smbw_readdir(dir
);
1216 if (internal
!= NULL
) {
1217 dirent_convert(internal
, &external
);
1222 return (* smbw_libc
.readdir
)(dir
);
1225 int closedir(DIR *dir
)
1227 check_init("closedir");
1229 if (smbw_dirp(dir
)) {
1230 return smbw_closedir(dir
);
1233 return (* smbw_libc
.closedir
)(dir
);
1236 long telldir(DIR *dir
)
1238 check_init("telldir");
1240 if (smbw_dirp(dir
)) {
1241 return (long) smbw_telldir(dir
);
1244 return (* smbw_libc
.telldir
)(dir
);
1247 void seekdir(DIR *dir
, long offset
)
1249 check_init("seekdir");
1251 if (smbw_dirp(dir
)) {
1252 smbw_seekdir(dir
, (long long) offset
);
1256 (* smbw_libc
.seekdir
)(dir
, offset
);
1259 int creat(const char *path
, mode_t mode
)
1261 extern int creat_bits
;
1263 check_init("creat");
1264 return openx((char *) path
, creat_bits
, mode
, smbw_libc
.open
);
1267 int creat64(const char *path
, mode_t mode
)
1269 extern int creat_bits
;
1271 check_init("creat64");
1272 return openx((char *) path
, creat_bits
, mode
, smbw_libc
.open64
);
1275 int __xstat64 (int ver
, const char *name
, struct stat64
*st64
)
1277 check_init("__xstat64");
1279 if (smbw_path((char *) name
)) {
1280 struct SMBW_stat statbuf
;
1281 int ret
= smbw_stat((char *) name
, &statbuf
);
1282 stat64_convert(&statbuf
, st64
);
1286 return (* smbw_libc
.__xstat64
)(ver
, (char *) name
, st64
);
1289 int stat64(const char *name
, struct stat64
*st64
)
1291 check_init("stat64");
1293 if (smbw_path((char *) name
)) {
1294 struct SMBW_stat statbuf
;
1295 int ret
= smbw_stat((char *) name
, &statbuf
);
1296 stat64_convert(&statbuf
, st64
);
1300 return (* smbw_libc
.stat64
)((char *) name
, st64
);
1303 int __fxstat64(int ver
, int fd
, struct stat64
*st64
)
1305 check_init("__fxstat64");
1308 struct SMBW_stat statbuf
;
1309 int ret
= smbw_fstat(fd
, &statbuf
);
1310 stat64_convert(&statbuf
, st64
);
1314 return (* smbw_libc
.__fxstat64
)(ver
, fd
, st64
);
1317 int fstat64(int fd
, struct stat64
*st64
)
1319 check_init("fstat64");
1322 struct SMBW_stat statbuf
;
1323 int ret
= smbw_fstat(fd
, &statbuf
);
1324 stat64_convert(&statbuf
, st64
);
1328 return (* smbw_libc
.fstat64
)(fd
, st64
);
1331 int __lxstat64(int ver
, const char *name
, struct stat64
*st64
)
1333 check_init("__lxstat64");
1335 if (smbw_path((char *) name
)) {
1336 struct SMBW_stat statbuf
;
1337 int ret
= smbw_stat(name
, &statbuf
);
1338 stat64_convert(&statbuf
, st64
);
1342 return (* smbw_libc
.__lxstat64
)(ver
, (char *) name
, st64
);
1345 int lstat64(const char *name
, struct stat64
*st64
)
1347 check_init("lstat64");
1349 if (smbw_path((char *) name
)) {
1350 struct SMBW_stat statbuf
;
1351 int ret
= smbw_stat((char *) name
, &statbuf
);
1352 stat64_convert(&statbuf
, st64
);
1356 return (* smbw_libc
.lstat64
)((char *) name
, st64
);
1359 int _llseek(unsigned int fd
, unsigned long offset_high
, unsigned long offset_low
, loff_t
*result
, unsigned int whence
)
1361 check_init("_llseek");
1364 *result
= lseek(fd
, offset_low
, whence
);
1365 return (*result
< 0 ? -1 : 0);
1368 return (* smbw_libc
._llseek
)(fd
, offset_high
, offset_low
, result
, whence
);
1371 struct dirent64
*readdir64(DIR *dir
)
1373 check_init("readdir64");
1375 if (smbw_dirp(dir
)) {
1376 static struct dirent64 external
;
1377 struct SMBW_dirent
* internal
= (void *)smbw_readdir(dir
);
1378 if (internal
!= NULL
) {
1379 dirent64_convert(internal
, &external
);
1385 return (* smbw_libc
.readdir64
)(dir
);
1388 int readdir_r(DIR *dir
, struct dirent
*external
, struct dirent
**result
)
1390 check_init("readdir_r");
1392 if (smbw_dirp(dir
)) {
1393 struct SMBW_dirent internal
;
1394 int ret
= smbw_readdir_r(dir
, &internal
, NULL
);
1396 dirent_convert(&internal
, external
);
1402 return (* smbw_libc
.readdir_r
)(dir
, external
, result
);
1405 int readdir64_r(DIR *dir
, struct dirent64
*external
, struct dirent64
**result
)
1407 check_init("readdir64_r");
1409 if (smbw_dirp(dir
)) {
1410 struct SMBW_dirent internal
;
1411 int ret
= smbw_readdir_r(dir
, &internal
, NULL
);
1413 dirent64_convert(&internal
, external
);
1419 return (* smbw_libc
.readdir64_r
)(dir
, external
, result
);
1428 int setxattr(const char *fname
,
1434 if (smbw_path(fname
)) {
1435 return smbw_setxattr(fname
, name
, value
, size
, flags
);
1438 return (* smbw_libc
.setxattr
)(fname
, name
, value
, size
, flags
);
1441 int lsetxattr(const char *fname
,
1447 if (smbw_path(fname
)) {
1448 return smbw_lsetxattr(fname
, name
, value
, size
, flags
);
1451 return (* smbw_libc
.lsetxattr
)(fname
, name
, value
, size
, flags
);
1454 int fsetxattr(int fd
,
1461 return smbw_fsetxattr(fd
, name
, value
, size
, flags
);
1464 return (* smbw_libc
.fsetxattr
)(fd
, name
, value
, size
, flags
);
1467 int getxattr(const char *fname
,
1472 if (smbw_path(fname
)) {
1473 return smbw_getxattr(fname
, name
, value
, size
);
1476 return (* smbw_libc
.getxattr
)(fname
, name
, value
, size
);
1479 int lgetxattr(const char *fname
,
1484 if (smbw_path(fname
)) {
1485 return smbw_lgetxattr(fname
, name
, value
, size
);
1488 return (* smbw_libc
.lgetxattr
)(fname
, name
, value
, size
);
1491 int fgetxattr(int fd
,
1497 return smbw_fgetxattr(fd
, name
, value
, size
);
1500 return (* smbw_libc
.fgetxattr
)(fd
, name
, value
, size
);
1503 int removexattr(const char *fname
,
1506 if (smbw_path(fname
)) {
1507 return smbw_removexattr(fname
, name
);
1510 return (* smbw_libc
.removexattr
)(fname
, name
);
1513 int lremovexattr(const char *fname
,
1516 if (smbw_path(fname
)) {
1517 return smbw_lremovexattr(fname
, name
);
1520 return (* smbw_libc
.lremovexattr
)(fname
, name
);
1523 int fremovexattr(int fd
,
1527 return smbw_fremovexattr(fd
, name
);
1530 return (* smbw_libc
.fremovexattr
)(fd
, name
);
1533 int listxattr(const char *fname
,
1537 if (smbw_path(fname
)) {
1538 return smbw_listxattr(fname
, list
, size
);
1541 return (* smbw_libc
.listxattr
)(fname
, list
, size
);
1544 int llistxattr(const char *fname
,
1548 if (smbw_path(fname
)) {
1549 return smbw_llistxattr(fname
, list
, size
);
1552 return (* smbw_libc
.llistxattr
)(fname
, list
, size
);
1555 int flistxattr(int fd
,
1560 return smbw_flistxattr(fd
, list
, size
);
1563 return (* smbw_libc
.flistxattr
)(fd
, list
, size
);
1568 * We're ending up with a different implementation of malloc() with smbwrapper
1569 * than without it. The one with it does not support returning a non-NULL
1570 * pointer from a call to malloc(0), and many apps depend on getting a valid
1571 * pointer when requesting zero length (e.g. df, emacs).
1573 * Unfortunately, initializing the smbw_libc[] array via the dynamic link
1574 * library (libdl) requires malloc so we can't just do the same type of
1575 * mapping to the C library as we do with everything else. We need to
1576 * implement a different way of allocating memory that ensures that the C
1577 * library version of malloc() gets used. This is the only place where we
1578 * kludge the code to use an undocumented interface to the C library.
1580 * If anyone can come up with a way to dynamically link to the C library
1581 * rather than using this undocumented interface, I'd sure love to hear about
1582 * it. Better yet, if you can figure out where the alternate malloc()
1583 * functions are coming from and arrange for them not to be called, that would
1584 * be even better. We should try to avoid wrapping functions that don't
1585 * really require it.
1588 void *malloc(size_t size
)
1590 void *__libc_malloc(size_t size
);
1591 return __libc_malloc(size
);
1594 void *calloc(size_t nmemb
, size_t size
)
1596 void *__libc_calloc(size_t nmemb
, size_t size
);
1597 return __libc_calloc(nmemb
, size
);
1600 void *realloc(void *ptr
, size_t size
)
1602 void *__libc_realloc(void *ptr
, size_t size
);
1603 return __libc_realloc(ptr
, size
);
1606 void free(void *ptr
)
1608 static int in_progress
= 0;
1609 void __libc_free(void *ptr
);
1611 if (in_progress
) return;
1620 static struct sigaction user_action
[_NSIG
];
1623 smbw_sigaction_handler(int signum
,
1627 /* Our entire purpose for trapping signals is to call this! */
1628 sys_select_signal();
1630 /* Call the user's handler */
1631 if (user_action
[signum
].sa_handler
!= SIG_IGN
&&
1632 user_action
[signum
].sa_handler
!= SIG_DFL
&&
1633 user_action
[signum
].sa_handler
!= SIG_ERR
) {
1634 (* user_action
[signum
].sa_sigaction
)(signum
, info
, context
);
1640 * Every Samba signal handler must call sys_select_signal() to avoid a race
1641 * condition, so we'll take whatever signal handler is currently assigned,
1642 * call call sys_select_signal() in addition to their call.
1649 struct timeval
*timeout
,
1650 int (* select_fn
)(int n
,
1654 struct timeval
*timeout
))
1660 struct sigaction new_action
;
1662 saved_errno
= errno
;
1663 for (i
=1; i
<_NSIG
; i
++) {
1664 sigemptyset(&sigset
);
1665 new_action
.sa_mask
= sigset
;
1666 new_action
.sa_flags
= SA_SIGINFO
;
1667 new_action
.sa_sigaction
= smbw_sigaction_handler
;
1669 if (sigaction(i
, &new_action
, &user_action
[i
]) < 0) {
1670 if (errno
!= EINVAL
) {
1675 errno
= saved_errno
;
1677 ret
= (* select_fn
)(n
, readfds
, writefds
, exceptfds
, timeout
);
1678 saved_errno
= errno
;
1680 for (i
=0; i
<_NSIG
; i
++) {
1681 (void) sigaction(i
, &user_action
[i
], NULL
);
1684 errno
= saved_errno
;
1693 struct timeval
*timeout
)
1695 check_init("select");
1697 return do_select(n
, readfds
, writefds
, exceptfds
,
1698 timeout
, smbw_libc
.select
);
1706 struct timeval
*timeout
)
1708 check_init("_select");
1710 return do_select(n
, readfds
, writefds
, exceptfds
,
1711 timeout
, smbw_libc
._select
);
1719 struct timeval
*timeout
)
1721 check_init("__select");
1723 return do_select(n
, readfds
, writefds
, exceptfds
,
1724 timeout
, smbw_libc
.__select
);