2000-02-03 05:10:09 +00:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
2000-10-05 19:04:41 +00:00
Wrap disk only vfs functions to sidestep dodgy compilers .
2000-02-03 05:10:09 +00:00
Copyright ( C ) Tim Potter 1998
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 0213 9 , USA .
*/
# include "includes.h"
/* Check for NULL pointer parameters in vfswrap_* functions */
# define VFS_CHECK_NULL
/* We don't want to have NULL function pointers lying around. Someone
is sure to try and execute them . These stubs are used to prevent
this possibility . */
2000-10-06 03:21:49 +00:00
int vfswrap_dummy_connect ( connection_struct * conn , char * service , char * user )
2000-02-03 05:10:09 +00:00
{
return 0 ; /* Return >= 0 for success */
}
2000-10-06 18:13:52 +00:00
void vfswrap_dummy_disconnect ( connection_struct * conn )
2000-02-03 05:10:09 +00:00
{
}
/* Disk operations */
2000-10-06 03:21:49 +00:00
SMB_BIG_UINT vfswrap_disk_free ( connection_struct * conn , char * path , BOOL small_query , SMB_BIG_UINT * bsize ,
2000-02-03 05:10:09 +00:00
SMB_BIG_UINT * dfree , SMB_BIG_UINT * dsize )
{
SMB_BIG_UINT result ;
# ifdef VFS_CHECK_NULL
if ( ( path = = NULL ) | | ( bsize = = NULL ) | | ( dfree = = NULL ) | |
( dsize = = NULL ) ) {
smb_panic ( " NULL pointer passed to vfswrap_disk_free() function \n " ) ;
}
# endif
result = sys_disk_free ( path , small_query , bsize , dfree , dsize ) ;
return result ;
}
/* Directory operations */
2000-10-06 03:21:49 +00:00
DIR * vfswrap_opendir ( connection_struct * conn , char * fname )
2000-02-03 05:10:09 +00:00
{
DIR * result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_opendir ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( fname = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_opendir() \n " ) ;
}
# endif
result = opendir ( fname ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_opendir ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
struct dirent * vfswrap_readdir ( connection_struct * conn , DIR * dirp )
2000-02-03 05:10:09 +00:00
{
struct dirent * result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_readdir ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( dirp = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_readdir() \n " ) ;
}
# endif
result = readdir ( dirp ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_readdir ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_mkdir ( connection_struct * conn , char * path , mode_t mode )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_mkdir ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( path = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_mkdir() \n " ) ;
}
# endif
result = mkdir ( path , mode ) ;
2001-01-23 01:52:30 +00:00
if ( result = = 0 ) {
/*
* We need to do this as the default behavior of POSIX ACLs
* is to set the mask to be the requested group permission
* bits , not the group permission bits to be the requested
* group permission bits . This is not what we want , as it will
* mess up any inherited ACL bits that were set . JRA .
*/
2001-03-26 19:18:06 +00:00
int saved_errno = errno ; /* We may get ENOSYS */
2001-01-23 01:52:30 +00:00
if ( conn - > vfs_ops . chmod_acl ! = NULL ) {
2001-03-26 19:18:06 +00:00
if ( ( conn - > vfs_ops . chmod_acl ( conn , path , mode ) = = - 1 ) & & ( errno = = ENOSYS ) )
errno = saved_errno ;
2001-01-23 01:52:30 +00:00
}
}
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_mkdir ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_rmdir ( connection_struct * conn , char * path )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_rmdir ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( path = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_rmdir() \n " ) ;
}
# endif
result = rmdir ( path ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_rmdir ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_closedir ( connection_struct * conn , DIR * dirp )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_closedir ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( dirp = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_closedir() \n " ) ;
}
# endif
result = closedir ( dirp ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_closedir ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
/* File operations */
2000-10-06 03:21:49 +00:00
int vfswrap_open ( connection_struct * conn , char * fname , int flags , mode_t mode )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_open ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( fname = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_open() \n " ) ;
}
# endif
result = sys_open ( fname , flags , mode ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_open ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_close ( files_struct * fsp , int fd )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_close ) ;
2000-02-03 05:10:09 +00:00
result = close ( fd ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_close ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
ssize_t vfswrap_read ( files_struct * fsp , int fd , char * data , size_t n )
2000-02-03 05:10:09 +00:00
{
ssize_t result ;
2000-10-06 18:13:52 +00:00
START_PROFILE_BYTES ( syscall_read , n ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( data = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_read() \n " ) ;
}
# endif
result = read ( fd , data , n ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_read ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
ssize_t vfswrap_write ( files_struct * fsp , int fd , char * data , size_t n )
2000-02-03 05:10:09 +00:00
{
ssize_t result ;
2000-10-06 18:13:52 +00:00
START_PROFILE_BYTES ( syscall_write , n ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( data = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_write() \n " ) ;
}
# endif
result = write ( fd , data , n ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_write ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
SMB_OFF_T vfswrap_lseek ( files_struct * fsp , int filedes , SMB_OFF_T offset , int whence )
2000-02-03 05:10:09 +00:00
{
SMB_OFF_T result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_lseek ) ;
2000-02-03 05:10:09 +00:00
result = sys_lseek ( filedes , offset , whence ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_lseek ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_rename ( connection_struct * conn , char * old , char * new )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_rename ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( ( old = = NULL ) | | ( new = = NULL ) ) {
smb_panic ( " NULL pointer passed to vfswrap_rename() \n " ) ;
}
# endif
result = rename ( old , new ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_rename ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_fsync ( files_struct * fsp , int fd )
2000-02-03 05:10:09 +00:00
{
2000-04-04 18:44:04 +00:00
# ifdef HAVE_FSYNC
2000-10-06 18:13:52 +00:00
int result ;
START_PROFILE ( syscall_fsync ) ;
result = fsync ( fd ) ;
END_PROFILE ( syscall_fsync ) ;
return result ;
2000-04-04 18:44:04 +00:00
# else
return 0 ;
# endif
2000-02-03 05:10:09 +00:00
}
2000-10-06 03:21:49 +00:00
int vfswrap_stat ( connection_struct * conn , char * fname , SMB_STRUCT_STAT * sbuf )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_stat ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( ( fname = = NULL ) | | ( sbuf = = NULL ) ) {
smb_panic ( " NULL pointer passed to vfswrap_stat() \n " ) ;
}
# endif
result = sys_stat ( fname , sbuf ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_stat ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_fstat ( files_struct * fsp , int fd , SMB_STRUCT_STAT * sbuf )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_fstat ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( sbuf = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_fstat() \n " ) ;
}
# endif
result = sys_fstat ( fd , sbuf ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_fstat ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_lstat ( connection_struct * conn , char * path , SMB_STRUCT_STAT * sbuf )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_lstat ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( ( path = = NULL ) | | ( sbuf = = NULL ) ) {
smb_panic ( " NULL pointer passed to vfswrap_lstat() \n " ) ;
}
# endif
result = sys_lstat ( path , sbuf ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_lstat ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_unlink ( connection_struct * conn , char * path )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_unlink ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( path = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_unlink() \n " ) ;
}
# endif
result = unlink ( path ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_unlink ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_chmod ( connection_struct * conn , char * path , mode_t mode )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_chmod ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( path = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_chmod() \n " ) ;
}
# endif
2001-01-23 01:52:30 +00:00
/*
* We need to do this due to the fact that the default POSIX ACL
* chmod modifies the ACL * mask * for the group owner , not the
* group owner bits directly . JRA .
*/
2001-03-26 19:18:06 +00:00
2001-01-23 01:52:30 +00:00
if ( conn - > vfs_ops . chmod_acl ! = NULL ) {
2001-03-26 19:18:06 +00:00
int saved_errno = errno ; /* We might get ENOSYS */
2001-01-23 01:52:30 +00:00
if ( ( result = conn - > vfs_ops . chmod_acl ( conn , path , mode ) ) = = 0 ) {
END_PROFILE ( syscall_chmod ) ;
return result ;
}
2001-03-26 19:18:06 +00:00
/* Error - return the old errno. */
errno = saved_errno ;
2001-01-23 01:52:30 +00:00
}
2000-02-03 05:10:09 +00:00
result = chmod ( path , mode ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_chmod ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_chown ( connection_struct * conn , char * path , uid_t uid , gid_t gid )
2000-09-27 19:09:59 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_chown ) ;
2000-09-27 19:09:59 +00:00
# ifdef VFS_CHECK_NULL
if ( path = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_chown() \n " ) ;
}
# endif
result = sys_chown ( path , uid , gid ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_chown ) ;
2000-09-27 19:09:59 +00:00
return result ;
}
2000-10-06 03:21:49 +00:00
int vfswrap_chdir ( connection_struct * conn , char * path )
2000-09-27 19:09:59 +00:00
{
2000-10-06 18:13:52 +00:00
int result ;
START_PROFILE ( syscall_chdir ) ;
2000-09-27 19:09:59 +00:00
# ifdef VFS_CHECK_NULL
if ( path = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_chdir() \n " ) ;
}
# endif
2000-10-06 18:13:52 +00:00
result = chdir ( path ) ;
END_PROFILE ( syscall_chdir ) ;
return result ;
2000-09-27 19:09:59 +00:00
}
2000-10-06 03:21:49 +00:00
char * vfswrap_getwd ( connection_struct * conn , char * path )
2000-09-27 19:09:59 +00:00
{
2000-10-06 18:13:52 +00:00
char * result ;
START_PROFILE ( syscall_getwd ) ;
2000-09-27 19:09:59 +00:00
# ifdef VFS_CHECK_NULL
if ( path = = NULL ) {
smb_panic ( " NULL pointer passed to vfswrap_getwd() \n " ) ;
}
# endif
2000-10-06 18:13:52 +00:00
result = sys_getwd ( path ) ;
END_PROFILE ( syscall_getwd ) ;
return result ;
2000-09-27 19:09:59 +00:00
}
2000-10-06 03:21:49 +00:00
int vfswrap_utime ( connection_struct * conn , char * path , struct utimbuf * times )
2000-02-03 05:10:09 +00:00
{
int result ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_utime ) ;
2000-02-03 05:10:09 +00:00
# ifdef VFS_CHECK_NULL
if ( ( path = = NULL ) | | ( times = = NULL ) ) {
smb_panic ( " NULL pointer passed to vfswrap_utime() \n " ) ;
}
# endif
result = utime ( path , times ) ;
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_utime ) ;
2000-02-03 05:10:09 +00:00
return result ;
}
2000-04-22 00:33:16 +00:00
2000-11-16 00:59:18 +00:00
int vfswrap_ftruncate ( files_struct * fsp , int fd , SMB_OFF_T len )
2000-04-22 00:33:16 +00:00
{
2000-11-16 00:59:18 +00:00
int result = - 1 ;
2000-10-06 18:13:52 +00:00
START_PROFILE ( syscall_ftruncate ) ;
2000-11-16 00:59:18 +00:00
# ifdef HAVE_FTRUNCATE_EXTEND
result = sys_ftruncate ( fd , len ) ;
END_PROFILE ( syscall_ftruncate ) ;
return result ;
# else
/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
extend a file with ftruncate . Provide alternate implementation
for this */
struct vfs_ops * vfs_ops = fsp - > conn - > vfs_ops ;
SMB_STRUCT_STAT st ;
char c = 0 ;
SMB_OFF_T currpos ;
currpos = vfs_ops - > lseek ( fsp , ( SMB_OFF_T ) 0 , SEEK_CUR ) ;
if ( currpos = = - 1 ) {
goto done ;
}
/* Do an fstat to see if the file is longer than
the requested size ( call ftruncate ) ,
or shorter , in which case seek to len - 1 and write 1
byte of zero */
if ( vfs_ops - > fstat ( fsp , & st ) < 0 ) {
goto done ;
}
# ifdef S_ISFIFO
if ( S_ISFIFO ( st . st_mode ) ) {
result = 0 ;
goto done ;
}
# endif
if ( st . st_size = = len ) {
result = 0 ;
goto done ;
}
if ( st . st_size > len ) {
/* Yes this is *deliberately* sys_ftruncate ! JRA */
result = sys_ftruncate ( fd , len ) ;
goto done ;
}
if ( vfs_ops - > lseek ( fsp , len - 1 , SEEK_SET ) ! = len - 1 ) {
goto done ;
}
if ( vfs_ops - > write ( fsp , & c , 1 ) ! = 1 ) {
goto done ;
}
/* Seek to where we were */
if ( vfs_ops - > lseek ( fsp , currpos , SEEK_SET ) ! = currpos ) {
goto done ;
}
done :
2000-10-06 18:13:52 +00:00
END_PROFILE ( syscall_ftruncate ) ;
2000-04-22 00:33:16 +00:00
return result ;
2000-12-08 19:59:22 +00:00
# endif
2000-04-22 00:33:16 +00:00
}
2000-05-02 03:20:47 +00:00
2000-10-06 03:21:49 +00:00
BOOL vfswrap_lock ( files_struct * fsp , int fd , int op , SMB_OFF_T offset , SMB_OFF_T count , int type )
2000-05-02 03:20:47 +00:00
{
2000-10-06 18:13:52 +00:00
BOOL result ;
START_PROFILE ( syscall_fcntl_lock ) ;
result = fcntl_lock ( fd , op , offset , count , type ) ;
END_PROFILE ( syscall_fcntl_lock ) ;
return result ;
}
size_t vfswrap_fget_nt_acl ( files_struct * fsp , int fd , SEC_DESC * * ppdesc )
{
return get_nt_acl ( fsp , ppdesc ) ;
}
size_t vfswrap_get_nt_acl ( files_struct * fsp , char * name , SEC_DESC * * ppdesc )
{
return get_nt_acl ( fsp , ppdesc ) ;
}
BOOL vfswrap_fset_nt_acl ( files_struct * fsp , int fd , uint32 security_info_sent , SEC_DESC * psd )
{
return set_nt_acl ( fsp , security_info_sent , psd ) ;
}
BOOL vfswrap_set_nt_acl ( files_struct * fsp , char * name , uint32 security_info_sent , SEC_DESC * psd )
{
return set_nt_acl ( fsp , security_info_sent , psd ) ;
2000-05-02 03:20:47 +00:00
}
2001-01-23 01:52:30 +00:00
int vfswrap_chmod_acl ( connection_struct * conn , char * name , mode_t mode )
{
return chmod_acl ( name , mode ) ;
}
int vfswrap_fchmod_acl ( files_struct * fsp , int fd , mode_t mode )
{
return fchmod_acl ( fd , mode ) ;
}