⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wrapper.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    Unix SMB/Netbios implementation.   Version 2.0   SMB wrapper functions   Copyright (C) Andrew Tridgell 1998   Copyright (C) Derrell Lipman 2002-2005      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*//* * This is a rewrite of the original wrapped.c file, using libdl to obtain * pointers into the C library rather than attempting to find undocumented * functions in the C library to call for native file access.  The problem * with the original implementation's paradigm is that samba manipulates * defines such that it gets the sizes of structures that it wants * (e.g. mapping 32-bit functions to 64-bit functions with their associated * 64-bit structure fields), but programs run under smbsh or using * smbwrapper.so were not necessarily compiled with the same flags.  As an * example of the problem, a program calling stat() passes a pointer to a * "struct stat" but the fields in that structure are different in samba than * they are in the calling program if the calling program was not compiled to * force stat() to be mapped to stat64(). * * In this version, we provide an interface to each of the native functions, * not just the ones that samba is compiled to map to.  We obtain the function * pointers from the C library using dlsym(), and for native file operations, * directly call the same function that the calling application was * requesting.  Since the size of the calling application's structures vary * depending on what function was called, we use our own internal structures * for passing information to/from the SMB equivalent functions, and map them * back to the native structures before returning the result to the caller. * * This implementation was completed 25 December 2002. * Derrell Lipman *//* We do not want auto munging of 32->64 bit names in this file (only) */#undef _FILE_OFFSET_BITS#undef _GNU_SOURCE#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <utime.h>#include <stdio.h>#include <dirent.h>#include <signal.h>#include <stdarg.h>#ifdef __USE_GNU# define SMBW_USE_GNU#endif#define __USE_GNU             /* need this to have RTLD_NEXT defined */#include <dlfcn.h>#ifndef SMBW_USE_GNU# undef __USE_GNU#endif#include <errno.h>#include "libsmbclient.h"#include "bsd-strlfunc.h"#include "wrapper.h"/* * Debug bits: * 0x0 = none * 0x1 = display symbol definitions not found in C library * 0x2 = show wrapper functions being called * 0x4 = log to file SMBW_DEBUG_FILE instead of stderr */#define SMBW_DEBUG      0x0#define SMBW_DEBUG_FILE "/tmp/smbw.log"int      smbw_debug = 0;#if SMBW_DEBUG & 0x2static int      debugFd = 2;#endif#ifndef ENOTSUP#define ENOTSUP EOPNOTSUPP#endif/* * None of the methods of having the initialization function called * automatically upon shared library startup are effective in all situations. * We provide the "-init" parameter to the linker which is effective most of * the time, but fails for applications that provide their own shared * libraries with _init() functions (e.g. ps).  We can't use "-z initfirst" * because the environment isn't yet set up at that point, so we can't find * our shared memory identifier (see shared.c).  We therefore must resort to * this tried-and-true method of keeping an "initialized" flag.  We check it * prior to calling the initialize() function to save a function call (a slow * operation on x86). */#if SMBW_DEBUG & 0x2#  define check_init(buf)                                               \        do {                                                            \                int saved_errno = errno;                                \                if (! initialized) initialize();                        \                (* smbw_libc.write)(debugFd, "["buf"]", sizeof(buf)+1); \                errno = saved_errno;                                    \        } while (0)#else#  define check_init(buf)                               \        do {                                            \                if (! initialized) smbw_initialize();   \        } while (0)#endifstatic void initialize(void);static int initialized = 0;SMBW_libc_pointers smbw_libc;/* * A public entry point used by the "-init" option to the linker. */void smbw_initialize(void){        initialize();}static void initialize(void){        int saved_errno;#if SMBW_DEBUG & 0x1        char *error;#endif                saved_errno = errno;                if (initialized) {                return;        }        initialized = 1;        #if SMBW_DEBUG & 0x1# define GETSYM(symname, symstring)                                      \        if ((smbw_libc.symname = dlsym(RTLD_NEXT, symstring)) == NULL) { \                if (smbw_libc.write != NULL &&                           \                    (error = dlerror()) != NULL) {                       \                        (* smbw_libc.write)(1, error, strlen(error));    \                        (* smbw_libc.write)(1, "\n", 1);                 \                }                                                        \        }#else# define GETSYM(symname, symstring)                     \        smbw_libc.symname = dlsym(RTLD_NEXT, symstring);#endif                /*         * Get pointers to each of the symbols we'll need, from the C library         *         * Some of these symbols may not be found in the C library.  That's         * fine.  We declare all of them here, and if the C library supports         * them, they may be called so we have the wrappers for them.  If the         * C library doesn't support them, then the wrapper function will         * never be called, and the null pointer will never be dereferenced.         */        GETSYM(write, "write"); /* first, to allow debugging */        GETSYM(open, "open");        GETSYM(_open, "_open");        GETSYM(__open, "__open");        GETSYM(open64, "open64");        GETSYM(_open64, "_open64");        GETSYM(__open64, "__open64");        GETSYM(pread, "pread");        GETSYM(pread64, "pread64");        GETSYM(pwrite, "pwrite");        GETSYM(pwrite64, "pwrite64");        GETSYM(close, "close");        GETSYM(__close, "__close");        GETSYM(_close, "_close");        GETSYM(fcntl, "fcntl");        GETSYM(__fcntl, "__fcntl");        GETSYM(_fcntl, "_fcntl");        GETSYM(getdents, "getdents");        GETSYM(__getdents, "__getdents");        GETSYM(_getdents, "_getdents");        GETSYM(getdents64, "getdents64");        GETSYM(lseek, "lseek");        GETSYM(__lseek, "__lseek");        GETSYM(_lseek, "_lseek");        GETSYM(lseek64, "lseek64");        GETSYM(__lseek64, "__lseek64");        GETSYM(_lseek64, "_lseek64");        GETSYM(read, "read");        GETSYM(__read, "__read");        GETSYM(_read, "_read");        GETSYM(__write, "__write");        GETSYM(_write, "_write");        GETSYM(access, "access");        GETSYM(chmod, "chmod");        GETSYM(fchmod, "fchmod");        GETSYM(chown, "chown");        GETSYM(fchown, "fchown");        GETSYM(__xstat, "__xstat");        GETSYM(getcwd, "getcwd");        GETSYM(mkdir, "mkdir");        GETSYM(__fxstat, "__fxstat");        GETSYM(__lxstat, "__lxstat");        GETSYM(stat, "stat");        GETSYM(lstat, "lstat");        GETSYM(fstat, "fstat");        GETSYM(unlink, "unlink");        GETSYM(utime, "utime");        GETSYM(utimes, "utimes");        GETSYM(readlink, "readlink");        GETSYM(rename, "rename");        GETSYM(rmdir, "rmdir");        GETSYM(symlink, "symlink");        GETSYM(dup, "dup");        GETSYM(dup2, "dup2");        GETSYM(opendir, "opendir");        GETSYM(readdir, "readdir");        GETSYM(closedir, "closedir");        GETSYM(telldir, "telldir");        GETSYM(seekdir, "seekdir");        GETSYM(creat, "creat");        GETSYM(creat64, "creat64");        GETSYM(__xstat64, "__xstat64");        GETSYM(stat64, "stat64");        GETSYM(__fxstat64, "__fxstat64");        GETSYM(fstat64, "fstat64");        GETSYM(__lxstat64, "__lxstat64");        GETSYM(lstat64, "lstat64");        GETSYM(_llseek, "_llseek");        GETSYM(readdir64, "readdir64");        GETSYM(readdir_r, "readdir_r");        GETSYM(readdir64_r, "readdir64_r");        GETSYM(setxattr, "setxattr");        GETSYM(lsetxattr, "lsetxattr");        GETSYM(fsetxattr, "fsetxattr");        GETSYM(getxattr, "getxattr");        GETSYM(lgetxattr, "lgetxattr");        GETSYM(fgetxattr, "fgetxattr");        GETSYM(removexattr, "removexattr");        GETSYM(lremovexattr, "lremovexattr");        GETSYM(fremovexattr, "fremovexattr");        GETSYM(listxattr, "listxattr");        GETSYM(llistxattr, "llistxattr");        GETSYM(flistxattr, "flistxattr");        GETSYM(chdir, "chdir");        GETSYM(fchdir, "fchdir");        GETSYM(fork, "fork");        GETSYM(select, "select");        GETSYM(_select, "_select");        GETSYM(__select, "__select");        #if SMBW_DEBUG & 4        {                if ((debugFd =                     open(SMBW_DEBUG_FILE, O_WRONLY | O_CREAT | O_APPEND)) < 0)                {#               define SMBW_MESSAGE    "Could not create " SMBW_DEBUG_FILE "\n"                         (* smbw_libc.write)(1, SMBW_MESSAGE, sizeof(SMBW_MESSAGE));#               undef SMBW_MESSAGE                        exit(1);                }        }#endif                errno = saved_errno;}/** ** Static Functions **/static void stat_convert(struct SMBW_stat *src, struct stat *dest){        memset(dest, '\0', sizeof(*dest));	dest->st_size = src->s_size;	dest->st_mode = src->s_mode;	dest->st_ino = src->s_ino;	dest->st_dev = src->s_dev;	dest->st_rdev = src->s_rdev;	dest->st_nlink = src->s_nlink;	dest->st_uid = src->s_uid;	dest->st_gid = src->s_gid;	dest->st_atime = src->s_atime;	dest->st_mtime = src->s_mtime;	dest->st_ctime = src->s_ctime;	dest->st_blksize = src->s_blksize;	dest->st_blocks = src->s_blocks;}static void stat64_convert(struct SMBW_stat *src, struct stat64 *dest){        memset(dest, '\0', sizeof(*dest));	dest->st_size = src->s_size;	dest->st_mode = src->s_mode;	dest->st_ino = src->s_ino;	dest->st_dev = src->s_dev;	dest->st_rdev = src->s_rdev;	dest->st_nlink = src->s_nlink;	dest->st_uid = src->s_uid;	dest->st_gid = src->s_gid;	dest->st_atime = src->s_atime;	dest->st_mtime = src->s_mtime;	dest->st_ctime = src->s_ctime;	dest->st_blksize = src->s_blksize;	dest->st_blocks = src->s_blocks;}static void dirent_convert(struct SMBW_dirent *src, struct dirent *dest){        char *p;                memset(dest, '\0', sizeof(*dest));	dest->d_ino = src->d_ino;	dest->d_off = src->d_off;                switch(src->d_type)        {        case SMBC_WORKGROUP:        case SMBC_SERVER:        case SMBC_FILE_SHARE:        case SMBC_DIR:                dest->d_type = DT_DIR;                break;                        case SMBC_FILE:                dest->d_type = DT_REG;                break;                        case SMBC_PRINTER_SHARE:                dest->d_type = DT_CHR;                break;                        case SMBC_COMMS_SHARE:                dest->d_type = DT_SOCK;                break;                        case SMBC_IPC_SHARE:                dest->d_type = DT_FIFO;                break;                        case SMBC_LINK:                dest->d_type = DT_LNK;                break;        }        	dest->d_reclen = src->d_reclen;	smbw_strlcpy(dest->d_name, src->d_name, sizeof(dest->d_name));        p = dest->d_name + strlen(dest->d_name) + 1;        smbw_strlcpy(p,                     src->d_comment,                     sizeof(dest->d_name) - (p - dest->d_name));}static void dirent64_convert(struct SMBW_dirent *src, struct dirent64 *dest){        char *p;                memset(dest, '\0', sizeof(*dest));	dest->d_ino = src->d_ino;	dest->d_off = src->d_off;                switch(src->d_type)        {        case SMBC_WORKGROUP:        case SMBC_SERVER:        case SMBC_FILE_SHARE:        case SMBC_DIR:                dest->d_type = DT_DIR;                break;                        case SMBC_FILE:                dest->d_type = DT_REG;                break;                        case SMBC_PRINTER_SHARE:                dest->d_type = DT_CHR;                break;                        case SMBC_COMMS_SHARE:                dest->d_type = DT_SOCK;                break;                        case SMBC_IPC_SHARE:                dest->d_type = DT_FIFO;                break;                        case SMBC_LINK:                dest->d_type = DT_LNK;                break;        }        	dest->d_reclen = src->d_reclen;	smbw_strlcpy(dest->d_name, src->d_name, sizeof(dest->d_name));        p = dest->d_name + strlen(dest->d_name) + 1;        smbw_strlcpy(p,                     src->d_comment,                     sizeof(dest->d_name) - (p - dest->d_name));}static int openx(char *name, int flags, mode_t mode, int (* f)(char *, int, mode_t)){	if (smbw_path(name)) {		return smbw_open(name, flags, mode);	}                return (* f)(name, flags, mode);}static int closex(int fd, int (* f)(int fd)){	if (smbw_fd(fd)) {		return smbw_close(fd);	}                return (* f)(fd);}static int fcntlx(int fd, int cmd, long arg, int (* f)(int, int, long)){	if (smbw_fd(fd)) {		return smbw_fcntl(fd, cmd, arg);	}                return (* f)(fd, cmd, arg);}static int getdentsx(int fd, struct dirent *external, unsigned int count, int (* f)(int, struct dirent *, unsigned int)){	if (smbw_fd(fd)) {                int i;                int internal_count;                struct SMBW_dirent *internal;                int ret;                int n;                                /*                 * LIMITATION: If they pass a count which is not a multiple of                 * the size of struct dirent, they will not get a partial                 * structure; we ignore the excess count.                 */                n = (count / sizeof(struct dirent));                                internal_count = sizeof(struct SMBW_dirent) * n;                internal = malloc(internal_count);                if (internal == NULL) {                        errno = ENOMEM;                        return -1;                }		ret = smbw_getdents(fd, internal, internal_count);                if (ret <= 0)                        return ret;                                ret = sizeof(struct dirent) * n;                                for (i = 0; i < n; i++)                        dirent_convert(&internal[i], &external[i]);                                return ret;	}                return (* f)(fd, external, count);}static off_t lseekx(int fd,                    off_t offset,                    int whence,                    off_t (* f)(int, off_t, int)){        off_t           ret;                /*         * We have left the definitions of the smbw_ functions undefined,         * because types such as off_t can differ in meaning betweent his         * function and smbw.c et al.  Functions that return other than an         * integer value, however, MUST have their return value defined.         */        off64_t         smbw_lseek();                if (smbw_fd(fd)) {		return (off_t) smbw_lseek(fd, offset, whence);	}                ret = (* f)(fd, offset, whence);        if (smbw_debug)        {                printf("lseekx(%d, 0x%llx) returned 0x%llx\n",                       fd,                       (unsigned long long) offset,                       (unsigned long long) ret);        }        return ret;}static off64_t lseek64x(int fd,                        off64_t offset,                        int whence,                        off64_t (* f)(int, off64_t, int)){        off64_t         ret;                /*         * We have left the definitions of the smbw_ functions undefined,         * because types such as off_t can differ in meaning betweent his         * function and smbw.c et al.  Functions that return other than an         * integer value, however, MUST have their return value defined.         */        off64_t         smbw_lseek();        	if (smbw_fd(fd))		ret = smbw_lseek(fd, offset, whence);        else                ret = (* f)(fd, offset, whence);        if (smbw_debug)        {                printf("lseek64x(%d, 0x%llx) returned 0x%llx\n",                       fd,                       (unsigned long long) offset,                       (unsigned long long) ret);        }        return ret;}static ssize_t readx(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t)){	if (smbw_fd(fd)) {		return smbw_read(fd, buf, count);	}                return (* f)(fd, buf, count);}static ssize_t writex(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t)){	if (smbw_fd(fd)) {		return smbw_write(fd, buf, count);	}                return (* f)(fd, buf, count);}/** ** Wrapper Functions **/int open(__const char *name, int flags, ...){        va_list ap;        mode_t mode;                va_start(ap, flags);        mode = va_arg(ap, mode_t);        va_end(ap);                check_init("open");                return openx((char *) name, flags, mode, smbw_libc.open);}int _open(char *name, int flags, mode_t mode){        check_init("open");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -