diff options
author | Jeremy Allison <jra@samba.org> | 2001-09-05 20:01:12 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2001-09-05 20:01:12 +0000 |
commit | c7d1b06f31550289a864fd09165d3545f207b80e (patch) | |
tree | 7b8ca440190c37aed6d518d3971bc0a138b1bea7 | |
parent | 6c08c74b2ed498b326c8829ac1f68988ab31d050 (diff) | |
download | samba-c7d1b06f31550289a864fd09165d3545f207b80e.tar.gz samba-c7d1b06f31550289a864fd09165d3545f207b80e.tar.xz samba-c7d1b06f31550289a864fd09165d3545f207b80e.zip |
Moved functionality into vfs finally.
Jeremy.
-rw-r--r-- | source/Makefile.in | 2 | ||||
-rw-r--r-- | source/client/clitar.c | 2 | ||||
-rw-r--r-- | source/include/proto.h | 9 | ||||
-rw-r--r-- | source/lib/util.c | 15 | ||||
-rw-r--r-- | source/smbd/notify_kernel.c | 2 | ||||
-rw-r--r-- | source/smbd/vfs-wrap.c | 101 |
6 files changed, 96 insertions, 35 deletions
diff --git a/source/Makefile.in b/source/Makefile.in index a2f40c7963b..e37692cfc1a 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -103,7 +103,7 @@ TDB_OBJ = tdb/tdb.o tdb/spinlock.o tdb/tdbutil.o LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \ lib/getsmbpass.o lib/interface.o lib/kanji.o lib/md4.o \ lib/interfaces.o lib/pidfile.o lib/replace.o \ - lib/signal.o lib/system.o lib/doscalls.o lib/time.o \ + lib/signal.o lib/system.o lib/time.o \ lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \ lib/bitmap.o lib/crc32.o lib/snprintf.o lib/wins_srv.o \ lib/util_array.o lib/util_str.o lib/util_sid.o \ diff --git a/source/client/clitar.c b/source/client/clitar.c index 4bb658f9521..335c92eecf1 100644 --- a/source/client/clitar.c +++ b/source/client/clitar.c @@ -1719,7 +1719,7 @@ int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind) SMB_STRUCT_STAT stbuf; extern time_t newer_than; - if (dos_stat(argv[Optind], &stbuf) == 0) { + if (sys_stat(dos_to_unix(argv[Optind],False), &stbuf) == 0) { newer_than = stbuf.st_mtime; DEBUG(1,("Getting files newer than %s", asctime(LocalTime(&newer_than)))); diff --git a/source/include/proto.h b/source/include/proto.h index 6beee9071b8..9eeea171cd3 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -64,12 +64,6 @@ void check_log_size( void ); void dbgflush( void ); BOOL dbghdr( int level, char *file, char *func, int line ); -/*The following definitions come from lib/doscalls.c */ - -int dos_open(char *fname,int flags,mode_t mode); -int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf); -int copy_reg(char *source, const char *dest); - /*The following definitions come from lib/error.c */ uint32 map_nt_error_from_unix(int unix_error); @@ -943,7 +937,6 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups); char *Atoic(char *p, int *n, char *c); char *get_numlist(char *p, uint32 **num, int *count); BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf); -int file_rename(char *from, char *to); time_t file_modtime(char *fname); BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st); SMB_OFF_T get_file_size(char *file_name); @@ -4444,7 +4437,7 @@ int vfswrap_close(files_struct *fsp, int fd); ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n); ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n); SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence); -int vfswrap_rename(connection_struct *conn, char *old, char *new); +int vfswrap_rename(connection_struct *conn, char *oldname, char *newname); int vfswrap_fsync(files_struct *fsp, int fd); int vfswrap_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf); int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf); diff --git a/source/lib/util.c b/source/lib/util.c index 1fe96edd210..285fa3f3a1d 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -195,21 +195,6 @@ BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf) } /******************************************************************* - Rename a unix file. -********************************************************************/ - -int file_rename(char *from, char *to) -{ - int rcode = rename (from, to); - - if (errno == EXDEV) { - /* Rename across filesystems needed. */ - rcode = copy_reg (from, to); - } - return rcode; -} - -/******************************************************************* Check a files mod time. ********************************************************************/ diff --git a/source/smbd/notify_kernel.c b/source/smbd/notify_kernel.c index d7408c06b57..f1e40793c85 100644 --- a/source/smbd/notify_kernel.c +++ b/source/smbd/notify_kernel.c @@ -125,7 +125,7 @@ static void *kernel_register_notify(connection_struct *conn, char *path, uint32 int fd; unsigned long kernel_flags; - fd = dos_open(path, O_RDONLY, 0); + fd = sys_open(dos_to_unix(path,False),O_RDONLY, 0); if (fd == -1) { DEBUG(3,("Failed to open directory %s for change notify\n", path)); diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c index 1fd8d07d048..8e579634249 100644 --- a/source/smbd/vfs-wrap.c +++ b/source/smbd/vfs-wrap.c @@ -235,21 +235,104 @@ SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int wh return result; } -int vfswrap_rename(connection_struct *conn, char *old, char *new) +/********************************************************* + For rename across filesystems Patch from Warren Birnbaum + <warrenb@hpcvscdp.cv.hp.com> +**********************************************************/ + +static int copy_reg(char *source, const char *dest) { - int result; + SMB_STRUCT_STAT source_stats; + int ifd; + int ofd; + + if (sys_lstat (source, &source_stats) == -1) + return -1; + + if (!S_ISREG (source_stats.st_mode)) + return -1; + + if (unlink (dest) && errno != ENOENT) + return -1; + + if((ifd = sys_open (source, O_RDONLY, 0)) < 0) + return -1; + + if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 ) { + int saved_errno = errno; + close (ifd); + errno = saved_errno; + return -1; + } + + if (transfer_file(ifd, ofd, (size_t)-1) == -1) { + int saved_errno = errno; + close (ifd); + close (ofd); + unlink (dest); + errno = saved_errno; + return -1; + } + + if (close (ifd) == -1) { + int saved_errno = errno; + close (ofd); + errno = saved_errno; + return -1; + } + if (close (ofd) == -1) + return -1; + + /* + * chown turns off set[ug]id bits for non-root, + * so do the chmod last. + */ + + /* Try to copy the old file's modtime and access time. */ + { + struct utimbuf tv; - START_PROFILE(syscall_rename); + tv.actime = source_stats.st_atime; + tv.modtime = source_stats.st_mtime; + utime (dest, &tv); + } + + /* + * Try to preserve ownership. For non-root it might fail, but that's ok. + * But root probably wants to know, e.g. if NFS disallows it. + */ + + if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) + return -1; + + if (chmod (dest, source_stats.st_mode & 07777)) + return -1; + + if (unlink (source) == -1) + return -1; + + return 0; +} + +int vfswrap_rename(connection_struct *conn, char *oldname, char *newname) +{ + int result; + + START_PROFILE(syscall_rename); #ifdef VFS_CHECK_NULL - if ((old == NULL) || (new == NULL)) { - smb_panic("NULL pointer passed to vfswrap_rename()\n"); - } + if ((oldname == NULL) || (newname == NULL)) { + smb_panic("NULL pointer passed to vfswrap_rename()\n"); + } #endif - result = rename(old, new); - END_PROFILE(syscall_rename); - return result; + result = rename(oldname, newname); + if (errno == EXDEV) { + /* Rename across filesystems needed. */ + result = copy_reg(oldname, newname); + } + END_PROFILE(syscall_rename); + return result; } int vfswrap_fsync(files_struct *fsp, int fd) |