smbw.c

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

C
1,563
字号
		    !cli_unlink(&srv->cli, path2) ||		    !cli_rename(&srv->cli, path1, path2)) {			errno = eno;			goto failed;		}	}	smbw_busy--;	return 0; failed:	smbw_busy--;	return -1;}/***************************************************** a wrapper for utime and utimes*******************************************************/static int smbw_settime(const char *fname, time_t t){	struct smbw_server *srv;	fstring server, share;	pstring path;	uint16 mode;	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 (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {		errno = smbw_errno(&srv->cli);		goto failed;	}	if (!cli_setatr(&srv->cli, path, mode, t)) {		/* some servers always refuse directory changes */		if (!(mode & aDIR)) {			errno = smbw_errno(&srv->cli);			goto failed;		}	}	smbw_busy--;	return 0; failed:	smbw_busy--;	return -1;}/***************************************************** a wrapper for utime *******************************************************/int smbw_utime(const char *fname, void *buf){	struct utimbuf *tbuf = (struct utimbuf *)buf;	return smbw_settime(fname, tbuf?tbuf->modtime:time(NULL));}/***************************************************** a wrapper for utime *******************************************************/int smbw_utimes(const char *fname, void *buf){	struct timeval *tbuf = (struct timeval *)buf;	return smbw_settime(fname, tbuf?tbuf->tv_sec:time(NULL));}/***************************************************** a wrapper for chown()*******************************************************/int smbw_chown(const char *fname, uid_t owner, gid_t group){	struct smbw_server *srv;	fstring server, share;	pstring path;	uint16 mode;	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 (!cli_getatr(&srv->cli, path, &mode, NULL, NULL)) {		errno = smbw_errno(&srv->cli);		goto failed;	}		/* assume success */	smbw_busy--;	return 0; failed:	smbw_busy--;	return -1;}/***************************************************** a wrapper for chmod()*******************************************************/int smbw_chmod(const char *fname, mode_t newmode){	struct smbw_server *srv;	fstring server, share;	pstring path;	uint32 mode;	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;	}	mode = 0;	if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;	if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;	if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;	if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;	if (!cli_setatr(&srv->cli, path, mode, 0)) {		errno = smbw_errno(&srv->cli);		goto failed;	}		smbw_busy--;	return 0; failed:	smbw_busy--;	return -1;}/***************************************************** a wrapper for lseek()*******************************************************/off_t smbw_lseek(int fd, off_t offset, int whence){	struct smbw_file *file;	SMB_OFF_T size;	smbw_busy++;	file = smbw_file(fd);	if (!file) {		off_t ret = smbw_dir_lseek(fd, offset, whence);		smbw_busy--;		return ret;	}	switch (whence) {	case SEEK_SET:		file->f->offset = offset;		break;	case SEEK_CUR:		file->f->offset += offset;		break;	case SEEK_END:		if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd, 				   NULL, &size, NULL, NULL, NULL, 				   NULL, NULL) &&		    !cli_getattrE(&file->srv->cli, file->f->cli_fd, 				  NULL, &size, NULL, NULL, NULL)) {			errno = EINVAL;			smbw_busy--;			return -1;		}		file->f->offset = size + offset;		break;	}	smbw_busy--;	return file->f->offset;}/***************************************************** a wrapper for dup()*******************************************************/int smbw_dup(int fd){	int fd2;	struct smbw_file *file, *file2;	smbw_busy++;	file = smbw_file(fd);	if (!file) {		errno = EBADF;		goto failed;	}	fd2 = dup(file->fd);	if (fd2 == -1) {		goto failed;	}	if (bitmap_query(smbw_file_bmap, fd2)) {		DEBUG(0,("ERROR: fd already open in dup!\n"));		errno = EIO;		goto failed;	}	file2 = SMB_MALLOC_P(struct smbw_file);	if (!file2) {		close(fd2);		errno = ENOMEM;		goto failed;	}	ZERO_STRUCTP(file2);	*file2 = *file;	file2->fd = fd2;	file->f->ref_count++;	bitmap_set(smbw_file_bmap, fd2);		DLIST_ADD(smbw_files, file2);		smbw_busy--;	return fd2; failed:	smbw_busy--;	return -1;}/***************************************************** a wrapper for dup2()*******************************************************/int smbw_dup2(int fd, int fd2){	struct smbw_file *file, *file2;	smbw_busy++;	file = smbw_file(fd);	if (!file) {		errno = EBADF;		goto failed;	}	if (bitmap_query(smbw_file_bmap, fd2)) {		DEBUG(0,("ERROR: fd already open in dup2!\n"));		errno = EIO;		goto failed;	}	if (dup2(file->fd, fd2) != fd2) {		goto failed;	}	file2 = SMB_MALLOC_P(struct smbw_file);	if (!file2) {		close(fd2);		errno = ENOMEM;		goto failed;	}	ZERO_STRUCTP(file2);	*file2 = *file;	file2->fd = fd2;	file->f->ref_count++;	bitmap_set(smbw_file_bmap, fd2);		DLIST_ADD(smbw_files, file2);		smbw_busy--;	return fd2; failed:	smbw_busy--;	return -1;}/***************************************************** close a connection to a server*******************************************************/static void smbw_srv_close(struct smbw_server *srv){	smbw_busy++;	cli_shutdown(&srv->cli);	SAFE_FREE(srv->server_name);	SAFE_FREE(srv->share_name);	DLIST_REMOVE(smbw_srvs, srv);	ZERO_STRUCTP(srv);	SAFE_FREE(srv);		smbw_busy--;}/***************************************************** when we fork we have to close all connections and filesin the child*******************************************************/int smbw_fork(void){	pid_t child;	int p[2];	char c=0;	pstring line;	struct smbw_file *file, *next_file;	struct smbw_server *srv, *next_srv;	if (pipe(p)) return real_fork();	child = real_fork();	if (child) {		/* block the parent for a moment until the sockets are                   closed */		close(p[1]);		read(p[0], &c, 1);		close(p[0]);		return child;	}	close(p[0]);	/* close all files */	for (file=smbw_files;file;file=next_file) {		next_file = file->next;		close(file->fd);	}	/* close all server connections */	for (srv=smbw_srvs;srv;srv=next_srv) {		next_srv = srv->next;		smbw_srv_close(srv);	}	slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());	smbw_setshared(line,smbw_cwd);	/* unblock the parent */	write(p[1], &c, 1);	close(p[1]);	/* and continue in the child */	return 0;}#ifndef NO_ACL_WRAPPER/***************************************************** say no to acls*******************************************************/ int smbw_acl(const char *pathp, int cmd, int nentries, aclent_t *aclbufp){	if (cmd == GETACL || cmd == GETACLCNT) return 0;	errno = ENOSYS;	return -1;}#endif#ifndef NO_FACL_WRAPPER/***************************************************** say no to acls*******************************************************/ int smbw_facl(int fd, int cmd, int nentries, aclent_t *aclbufp){	if (cmd == GETACL || cmd == GETACLCNT) return 0;	errno = ENOSYS;	return -1;}#endif#ifdef HAVE_EXPLICIT_LARGEFILE_SUPPORT#ifdef HAVE_STAT64/* this can't be in wrapped.c because of include conflicts */ void stat64_convert(struct stat *st, struct stat64 *st64){	st64->st_size = st->st_size;	st64->st_mode = st->st_mode;	st64->st_ino = st->st_ino;	st64->st_dev = st->st_dev;	st64->st_rdev = st->st_rdev;	st64->st_nlink = st->st_nlink;	st64->st_uid = st->st_uid;	st64->st_gid = st->st_gid;	st64->st_atime = st->st_atime;	st64->st_mtime = st->st_mtime;	st64->st_ctime = st->st_ctime;#ifdef HAVE_STAT_ST_BLKSIZE	st64->st_blksize = st->st_blksize;#endif#ifdef HAVE_STAT_ST_BLOCKS	st64->st_blocks = st->st_blocks;#endif}#endif#ifdef HAVE_READDIR64 void dirent64_convert(struct dirent *d, struct dirent64 *d64){	d64->d_ino = d->d_ino;	d64->d_off = d->d_off;	d64->d_reclen = d->d_reclen;	pstrcpy(d64->d_name, d->d_name);}#endif#endif#ifdef HAVE___XSTAT/* Definition of `struct stat' used in the linux kernel..  */struct kernel_stat {	unsigned short int st_dev;	unsigned short int __pad1;	unsigned long int st_ino;	unsigned short int st_mode;	unsigned short int st_nlink;	unsigned short int st_uid;	unsigned short int st_gid;	unsigned short int st_rdev;	unsigned short int __pad2;	unsigned long int st_size;	unsigned long int st_blksize;	unsigned long int st_blocks;	unsigned long int st_atime_;	unsigned long int __unused1;	unsigned long int st_mtime_;	unsigned long int __unused2;	unsigned long int st_ctime_;	unsigned long int __unused3;	unsigned long int __unused4;	unsigned long int __unused5;};/* * Prototype for gcc in 'fussy' mode. */ void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf); void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf){#ifdef _STAT_VER_LINUX_OLD	if (vers == _STAT_VER_LINUX_OLD) {		memcpy(st, kbuf, sizeof(*st));		return;	}#endif	ZERO_STRUCTP(st);	st->st_dev = kbuf->st_dev;	st->st_ino = kbuf->st_ino;	st->st_mode = kbuf->st_mode;	st->st_nlink = kbuf->st_nlink;	st->st_uid = kbuf->st_uid;	st->st_gid = kbuf->st_gid;	st->st_rdev = kbuf->st_rdev;	st->st_size = kbuf->st_size;#ifdef HAVE_STAT_ST_BLKSIZE	st->st_blksize = kbuf->st_blksize;#endif#ifdef HAVE_STAT_ST_BLOCKS	st->st_blocks = kbuf->st_blocks;#endif	st->st_atime = kbuf->st_atime_;	st->st_mtime = kbuf->st_mtime_;	st->st_ctime = kbuf->st_ctime_;}#endif

⌨️ 快捷键说明

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