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 + -
显示快捷键?