smbw.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,563 行 · 第 1/3 页

C
1,563
字号
		return NULL;	}	if (!cli_session_setup(&c, username, 			       password, strlen(password),			       password, strlen(password),			       workgroup) &&	    /* try an anonymous login if it failed */	    !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {		cli_shutdown(&c);		errno = EPERM;		return NULL;	}	DEBUG(4,(" session setup ok\n"));	if (!cli_send_tconX(&c, share, "?????",			    password, strlen(password)+1)) {		errno = smbw_errno(&c);		cli_shutdown(&c);		return NULL;	}	smbw_setshared(ipenv,inet_ntoa(ip));		DEBUG(4,(" tconx ok\n"));	srv = SMB_MALLOC_P(struct smbw_server);	if (!srv) {		errno = ENOMEM;		goto failed;	}	ZERO_STRUCTP(srv);	srv->cli = c;	srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));	srv->server_name = SMB_STRDUP(server);	if (!srv->server_name) {		errno = ENOMEM;		goto failed;	}	srv->share_name = SMB_STRDUP(share);	if (!srv->share_name) {		errno = ENOMEM;		goto failed;	}	srv->workgroup = SMB_STRDUP(workgroup);	if (!srv->workgroup) {		errno = ENOMEM;		goto failed;	}	srv->username = SMB_STRDUP(username);	if (!srv->username) {		errno = ENOMEM;		goto failed;	}	/* some programs play with file descriptors fairly intimately. We	   try to get out of the way by duping to a high fd number */	if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) {		if (dup2(srv->cli.fd,SMBW_CLI_FD+srv->cli.fd) == 		    srv->cli.fd+SMBW_CLI_FD) {			close(srv->cli.fd);			srv->cli.fd += SMBW_CLI_FD;		}	}	DLIST_ADD(smbw_srvs, srv);	return srv; failed:	cli_shutdown(&c);	if (!srv) return NULL;	SAFE_FREE(srv->server_name);	SAFE_FREE(srv->share_name);	SAFE_FREE(srv);	return NULL;}/***************************************************** map a fd to a smbw_file structure*******************************************************/struct smbw_file *smbw_file(int fd){	struct smbw_file *file;	for (file=smbw_files;file;file=file->next) {		if (file->fd == fd) return file;	}	return NULL;}/***************************************************** a wrapper for open()*******************************************************/int smbw_open(const char *fname, int flags, mode_t mode){	fstring server, share;	pstring path;	struct smbw_server *srv=NULL;	int eno=0, fd = -1;	struct smbw_file *file=NULL;	smbw_init();	if (!fname) {		errno = EINVAL;		return -1;	}	smbw_busy++;		/* work out what server they are after */	smbw_parse_path(fname, server, share, path);	/* get a connection to the server */	srv = smbw_server(server, share);	if (!srv) {		/* smbw_server sets errno */		goto failed;	}	if (path[strlen(path)-1] == '\\') {		fd = -1;	} else {		fd = cli_open(&srv->cli, path, flags, DENY_NONE);	}	if (fd == -1) {		/* it might be a directory. Maybe we should use chkpath? */		eno = smbw_errno(&srv->cli);		fd = smbw_dir_open(fname);		if (fd == -1) errno = eno;		smbw_busy--;		return fd;	}	file = SMB_MALLOC_P(struct smbw_file);	if (!file) {		errno = ENOMEM;		goto failed;	}	ZERO_STRUCTP(file);	file->f = SMB_MALLOC_P(struct smbw_filedes);	if (!file->f) {		errno = ENOMEM;		goto failed;	}	ZERO_STRUCTP(file->f);	file->f->cli_fd = fd;	file->f->fname = SMB_STRDUP(path);	if (!file->f->fname) {		errno = ENOMEM;		goto failed;	}	file->srv = srv;	file->fd = open(SMBW_DUMMY, O_WRONLY);	if (file->fd == -1) {		errno = EMFILE;		goto failed;	}	if (bitmap_query(smbw_file_bmap, file->fd)) {		DEBUG(0,("ERROR: fd used in smbw_open\n"));		errno = EIO;		goto failed;	}	file->f->ref_count=1;	bitmap_set(smbw_file_bmap, file->fd);	DLIST_ADD(smbw_files, file);	DEBUG(4,("opened %s\n", fname));	smbw_busy--;	return file->fd; failed:	if (fd != -1) {		cli_close(&srv->cli, fd);	}	if (file) {		if (file->f) {			SAFE_FREE(file->f->fname);			SAFE_FREE(file->f);		}		SAFE_FREE(file);	}	smbw_busy--;	return -1;}/***************************************************** a wrapper for pread()*******************************************************/ssize_t smbw_pread(int fd, void *buf, size_t count, off_t ofs){	struct smbw_file *file;	int ret;	smbw_busy++;	file = smbw_file(fd);	if (!file) {		errno = EBADF;		smbw_busy--;		return -1;	}		ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, ofs, count);	if (ret == -1) {		errno = smbw_errno(&file->srv->cli);		smbw_busy--;		return -1;	}	smbw_busy--;	return ret;}/***************************************************** a wrapper for read()*******************************************************/ssize_t smbw_read(int fd, void *buf, size_t count){	struct smbw_file *file;	int ret;	DEBUG(4,("smbw_read(%d, %d)\n", fd, (int)count));	smbw_busy++;	file = smbw_file(fd);	if (!file) {		errno = EBADF;		smbw_busy--;		return -1;	}		ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, 		       file->f->offset, count);	if (ret == -1) {		errno = smbw_errno(&file->srv->cli);		smbw_busy--;		return -1;	}	file->f->offset += ret;		DEBUG(4,(" -> %d\n", ret));	smbw_busy--;	return ret;}	/***************************************************** a wrapper for write()*******************************************************/ssize_t smbw_write(int fd, void *buf, size_t count){	struct smbw_file *file;	int ret;	smbw_busy++;	file = smbw_file(fd);	if (!file) {		errno = EBADF;		smbw_busy--;		return -1;	}		ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, file->f->offset, count);	if (ret == -1) {		errno = smbw_errno(&file->srv->cli);		smbw_busy--;		return -1;	}	file->f->offset += ret;	smbw_busy--;	return ret;}/***************************************************** a wrapper for pwrite()*******************************************************/ssize_t smbw_pwrite(int fd, void *buf, size_t count, off_t ofs){	struct smbw_file *file;	int ret;	smbw_busy++;	file = smbw_file(fd);	if (!file) {		errno = EBADF;		smbw_busy--;		return -1;	}		ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, ofs, count);	if (ret == -1) {		errno = smbw_errno(&file->srv->cli);		smbw_busy--;		return -1;	}	smbw_busy--;	return ret;}/***************************************************** a wrapper for close()*******************************************************/int smbw_close(int fd){	struct smbw_file *file;	smbw_busy++;	file = smbw_file(fd);	if (!file) {		int ret = smbw_dir_close(fd);		smbw_busy--;		return ret;	}		if (file->f->ref_count == 1 &&	    !cli_close(&file->srv->cli, file->f->cli_fd)) {		errno = smbw_errno(&file->srv->cli);		smbw_busy--;		return -1;	}	bitmap_clear(smbw_file_bmap, file->fd);	close(file->fd);		DLIST_REMOVE(smbw_files, file);	file->f->ref_count--;	if (file->f->ref_count == 0) {		SAFE_FREE(file->f->fname);		SAFE_FREE(file->f);	}	ZERO_STRUCTP(file);	SAFE_FREE(file);		smbw_busy--;	return 0;}/***************************************************** a wrapper for fcntl()*******************************************************/int smbw_fcntl(int fd, int cmd, long arg){	return 0;}/***************************************************** a wrapper for access()*******************************************************/int smbw_access(const char *name, int mode){	struct stat st;	DEBUG(4,("smbw_access(%s, 0x%x)\n", name, mode));	if (smbw_stat(name, &st)) return -1;	if (((mode & R_OK) && !(st.st_mode & S_IRUSR)) ||	    ((mode & W_OK) && !(st.st_mode & S_IWUSR)) ||	    ((mode & X_OK) && !(st.st_mode & S_IXUSR))) {		errno = EACCES;		return -1;	}		return 0;}/***************************************************** a wrapper for realink() - needed for correct errno setting*******************************************************/int smbw_readlink(const char *path, char *buf, size_t bufsize){	struct stat st;	int ret;	ret = smbw_stat(path, &st);	if (ret != 0) {		DEBUG(4,("readlink(%s) failed\n", path));		return -1;	}		/* it exists - say it isn't a link */	DEBUG(4,("readlink(%s) not a link\n", path));	errno = EINVAL;	return -1;}/***************************************************** a wrapper for unlink()*******************************************************/int smbw_unlink(const char *fname){	struct smbw_server *srv;	fstring server, share;	pstring path;	if (!fname) {		errno = EINVAL;		return -1;	}	smbw_init();	smbw_busy++;	/* work out what server they are after */	smbw_parse_path(fname, server, share, path);	/* get a connection to the server */	srv = smbw_server(server, share);	if (!srv) {		/* smbw_server sets errno */		goto failed;	}	if (strncmp(srv->cli.dev, "LPT", 3) == 0) {		int job = smbw_stat_printjob(srv, path, NULL, NULL);		if (job == -1) {			goto failed;		}		if (cli_printjob_del(&srv->cli, job) != 0) {			goto failed;		}	} else if (!cli_unlink(&srv->cli, path)) {		errno = smbw_errno(&srv->cli);		goto failed;	}	smbw_busy--;	return 0; failed:	smbw_busy--;	return -1;}/***************************************************** a wrapper for rename()*******************************************************/int smbw_rename(const char *oldname, const char *newname){	struct smbw_server *srv;	fstring server1, share1;	pstring path1;	fstring server2, share2;	pstring path2;	if (!oldname || !newname) {		errno = EINVAL;		return -1;	}	smbw_init();	DEBUG(4,("smbw_rename(%s,%s)\n", oldname, newname));	smbw_busy++;	/* work out what server they are after */	smbw_parse_path(oldname, server1, share1, path1);	smbw_parse_path(newname, server2, share2, path2);	if (strcmp(server1, server2) || strcmp(share1, share2)) {		/* can't cross filesystems */		errno = EXDEV;		return -1;	}	/* get a connection to the server */	srv = smbw_server(server1, share1);	if (!srv) {		/* smbw_server sets errno */		goto failed;	}	if (!cli_rename(&srv->cli, path1, path2)) {		int eno = smbw_errno(&srv->cli);		if (eno != EEXIST ||

⌨️ 快捷键说明

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