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

📄 smbw.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/Netbios implementation.   Version 2.0   SMB wrapper functions   Copyright (C) Andrew Tridgell 1998   Copyright (C) Derrell Lipman 2003-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.*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <stdarg.h>#include <assert.h>#include "smbw.h"#include "bsd-strlfunc.h"typedef enum StartupType{        StartupType_Fake,        StartupType_Real} StartupType;int smbw_fd_map[__FD_SETSIZE];int smbw_ref_count[__FD_SETSIZE];char smbw_cwd[PATH_MAX];char smbw_prefix[] = SMBW_PREFIX;/* needs to be here because of dumb include files on some systems */int creat_bits = O_WRONLY|O_CREAT|O_TRUNC;int smbw_initialized = 0;static int debug_level = 0;static SMBCCTX *smbw_ctx;extern int smbw_debug;/*****************************************************smbw_ref -- manipulate reference counts******************************************************/int smbw_ref(int client_fd, Ref_Count_Type type, ...){        va_list ap;        /* client id values begin at SMBC_BASE_FC. */        client_fd -= SMBC_BASE_FD;        va_start(ap, type);        switch(type)        {        case SMBW_RCT_Increment:                return ++smbw_ref_count[client_fd];        case SMBW_RCT_Decrement:                return --smbw_ref_count[client_fd];        case SMBW_RCT_Get:                return smbw_ref_count[client_fd];        case SMBW_RCT_Set:                return (smbw_ref_count[client_fd] = va_arg(ap, int));        }        va_end(ap);        /* never gets here */        return -1;}/* * Return a username and password given a server and share name * * Returns 0 upon success; * non-zero otherwise, and errno is set to indicate the error. */static void get_envvar_auth_data(const char *srv,                                  const char *shr,                                 char *wg, int wglen,                                  char *un, int unlen,                                 char *pw, int pwlen){        char *u;        char *p;        char *w;	/* Fall back to environment variables */	w = getenv("WORKGROUP");	if (w == NULL) w = "";	u = getenv("USER");	if (u == NULL) u = "";	p = getenv("PASSWORD");	if (p == NULL) p = "";        smbw_strlcpy(wg, w, wglen);        smbw_strlcpy(un, u, unlen);        smbw_strlcpy(pw, p, pwlen);}static smbc_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data;/*****************************************************set the get auth data function******************************************************/void smbw_set_auth_data_fn(smbc_get_auth_data_fn fn){	get_auth_data_fn = fn;}/*****************************************************ensure that all connections are terminated upon exit******************************************************/static void do_shutdown(void){        if (smbw_ctx != NULL) {                smbc_free_context(smbw_ctx, 1);        }}/***************************************************** initialise structures*******************************************************/static void do_init(StartupType startupType){        int i;        char *p;	smbw_initialized = 1;   /* this must be first to avoid recursion! */        smbw_ctx = NULL;        /* don't free context until it's established */        /* initially, no file descriptors are mapped */        for (i = 0; i < __FD_SETSIZE; i++) {                smbw_fd_map[i] = -1;                smbw_ref_count[i] = 0;        }        /* See if we've been told to start in a particular directory */        if ((p=getenv("SMBW_DIR")) != NULL) {                smbw_strlcpy(smbw_cwd, p, PATH_MAX);                /* we don't want the old directory to be busy */                (* smbw_libc.chdir)("/");                        } else {                *smbw_cwd = '\0';        }	if ((p=getenv("DEBUG"))) {		debug_level = atoi(p);	}        if ((smbw_ctx = smbc_new_context()) == NULL) {                fprintf(stderr, "Could not create a context.\n");                exit(1);        }                smbw_ctx->debug = debug_level;        smbw_ctx->callbacks.auth_fn = get_auth_data_fn;        smbw_ctx->options.browse_max_lmb_count = 0;        smbw_ctx->options.urlencode_readdir_entries = 1;        smbw_ctx->options.one_share_per_server = 1;                if (smbc_init_context(smbw_ctx) == NULL) {                fprintf(stderr, "Could not initialize context.\n");                exit(1);        }                        smbc_set_context(smbw_ctx);        /* if not real startup, exit handler has already been established */        if (startupType == StartupType_Real) {            atexit(do_shutdown);        }}/***************************************************** initialise structures, real start up vs a fork()*******************************************************/void smbw_init(void){    do_init(StartupType_Real);}/***************************************************** determine if a file descriptor is a smb one*******************************************************/int smbw_fd(int smbw_fd){        SMBW_INIT();        return (smbw_fd >= 0 &&                smbw_fd < __FD_SETSIZE &&                smbw_fd_map[smbw_fd] >= SMBC_BASE_FD); /* minimum smbc_ fd */}/***************************************************** determine if a path is a smb one*******************************************************/int smbw_path(const char *name){        int len;        int ret;        int saved_errno;        saved_errno = errno;        SMBW_INIT();        len = strlen(smbw_prefix);        ret = ((strncmp(name, smbw_prefix, len) == 0 &&                (name[len] == '\0' || name[len] == '/')) ||               (*name != '/' && *smbw_cwd != '\0'));        errno = saved_errno;        return ret;}/***************************************************** remove redundent stuff from a filename*******************************************************/void smbw_clean_fname(char *name){	char *p, *p2;	int l;	int modified = 1;	if (!name) return;        DEBUG(10, ("Clean [%s]...\n", name));	while (modified) {		modified = 0;		if ((p=strstr(name,"/./"))) {			modified = 1;			while (*p) {				p[0] = p[2];				p++;			}                        DEBUG(10, ("\tclean 1 (/./) produced [%s]\n", name));		}		if ((p=strstr(name,"//"))) {			modified = 1;			while (*p) {				p[0] = p[1];				p++;			}                        DEBUG(10, ("\tclean 2 (//) produced [%s]\n", name));		}		if (strcmp(name,"/../")==0) {			modified = 1;			name[1] = 0;                        DEBUG(10,("\tclean 3 (^/../$) produced [%s]\n", name));		}		if ((p=strstr(name,"/../"))) {			modified = 1;			for (p2 = (p > name ? p-1 : p); p2 > name; p2--) {				if (p2[0] == '/') break;			}                        if (p2 > name) p2++;			while (*p2) {				p2[0] = p[3];				p2++;                                p++;			}                        DEBUG(10, ("\tclean 4 (/../) produced [%s]\n", name));		}		if (strcmp(name,"/..")==0) {			modified = 1;			name[1] = 0;                        DEBUG(10, ("\tclean 5 (^/..$) produced [%s]\n", name));		}		l = strlen(name);		p = l>=3?(name+l-3):name;		if (strcmp(p,"/..")==0) {			modified = 1;			for (p2=p-1;p2>name;p2--) {				if (p2[0] == '/') break;			}			if (p2==name) {				p[0] = '/';				p[1] = 0;			} else {				p2[0] = 0;			}                        DEBUG(10, ("\tclean 6 (/..) produced [%s]\n", name));		}		l = strlen(name);		p = l>=2?(name+l-2):name;		if (strcmp(p,"/.")==0) {                        modified = 1;			if (p == name) {				p[1] = 0;			} else {				p[0] = 0;			}                        DEBUG(10, ("\tclean 7 (/.) produced [%s]\n", name));		}		if (strncmp(p=name,"./",2) == 0) {      			modified = 1;			do {				p[0] = p[2];			} while (*p++);                        DEBUG(10, ("\tclean 8 (^./) produced [%s]\n", name));		}		l = strlen(p=name);		if (l > 1 && p[l-1] == '/') {			modified = 1;			p[l-1] = 0;                        DEBUG(10, ("\tclean 9 (/) produced [%s]\n", name));		}	}}void smbw_fix_path(const char *src, char *dest){        const char *p;        int len = strlen(smbw_prefix);        if (*src == '/') {                for (p = src + len; *p == '/'; p++)                        ;                snprintf(dest, PATH_MAX, "smb://%s", p);        } else {                snprintf(dest, PATH_MAX, "%s/%s", smbw_cwd, src);        }        smbw_clean_fname(dest + 5);        DEBUG(10, ("smbw_fix_path(%s) returning [%s]\n", src, dest));}/***************************************************** a wrapper for open()*******************************************************/int smbw_open(const char *fname, int flags, mode_t mode){        int client_fd;        int smbw_fd;	char path[PATH_MAX];	SMBW_INIT();	if (!fname) {		errno = EINVAL;		return -1;	}	smbw_fd = (smbw_libc.open)(SMBW_DUMMY, O_WRONLY, 0200);	if (smbw_fd == -1) {		errno = EMFILE;                return -1;	}        smbw_fix_path(fname, path);        if (flags == creat_bits) {                client_fd =  smbc_creat(path, mode);        } else {                client_fd = smbc_open(path, flags, mode);        }        if (client_fd < 0) {                (* smbw_libc.close)(smbw_fd);                return -1;        }        smbw_fd_map[smbw_fd] = client_fd;        smbw_ref(client_fd, SMBW_RCT_Increment);        return smbw_fd;}/***************************************************** a wrapper for pread()there should really be an smbc_pread() to avoid the twolseek()s required in this kludge.*******************************************************/ssize_t smbw_pread(int smbw_fd, void *buf, size_t count, SMBW_OFF_T ofs){        int client_fd;	ssize_t ret;        int saved_errno;        SMBW_OFF_T old_ofs;                if (count == 0) {                return 0;        }        client_fd = smbw_fd_map[smbw_fd];        if ((old_ofs = smbc_lseek(client_fd, 0, SEEK_CUR)) < 0 ||            smbc_lseek(client_fd, ofs, SEEK_SET) < 0) {                return -1;        }        if ((ret = smbc_read(client_fd, buf, count)) < 0) {                saved_errno = errno;                (void) smbc_lseek(client_fd, old_ofs, SEEK_SET);                errno = saved_errno;                return -1;        }        return ret;}/***************************************************** a wrapper for read()*******************************************************/ssize_t smbw_read(int smbw_fd, void *buf, size_t count){        int client_fd;                client_fd = smbw_fd_map[smbw_fd];        return smbc_read(client_fd, buf, count);}	/***************************************************** a wrapper for write()*******************************************************/ssize_t smbw_write(int smbw_fd, void *buf, size_t count){        int client_fd;        client_fd = smbw_fd_map[smbw_fd];        return smbc_write(client_fd, buf, count);

⌨️ 快捷键说明

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