2 Unix SMB/Netbios implementation.
4 Wrap disk only vfs functions to sidestep dodgy compilers.
5 Copyright (C) Tim Potter 1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* Check for NULL pointer parameters in vfswrap_* functions */
26 #define VFS_CHECK_NULL
28 /* We don't want to have NULL function pointers lying around. Someone
29 is sure to try and execute them. These stubs are used to prevent
32 int vfswrap_dummy_connect(connection_struct
*conn
, char *service
, char *user
)
34 return 0; /* Return >= 0 for success */
37 void vfswrap_dummy_disconnect(connection_struct
*conn
)
43 SMB_BIG_UINT
vfswrap_disk_free(connection_struct
*conn
, char *path
, BOOL small_query
, SMB_BIG_UINT
*bsize
,
44 SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
49 if ((path
== NULL
) || (bsize
== NULL
) || (dfree
== NULL
) ||
52 smb_panic("NULL pointer passed to vfswrap_disk_free() function\n");
56 result
= sys_disk_free(path
, small_query
, bsize
, dfree
, dsize
);
60 /* Directory operations */
62 DIR *vfswrap_opendir(connection_struct
*conn
, char *fname
)
66 START_PROFILE(syscall_opendir
);
70 smb_panic("NULL pointer passed to vfswrap_opendir()\n");
74 result
= opendir(fname
);
75 END_PROFILE(syscall_opendir
);
79 struct dirent
*vfswrap_readdir(connection_struct
*conn
, DIR *dirp
)
81 struct dirent
*result
;
83 START_PROFILE(syscall_readdir
);
87 smb_panic("NULL pointer passed to vfswrap_readdir()\n");
91 result
= readdir(dirp
);
92 END_PROFILE(syscall_readdir
);
96 int vfswrap_mkdir(connection_struct
*conn
, char *path
, mode_t mode
)
100 START_PROFILE(syscall_mkdir
);
102 #ifdef VFS_CHECK_NULL
104 smb_panic("NULL pointer passed to vfswrap_mkdir()\n");
108 result
= mkdir(path
, mode
);
112 * We need to do this as the default behavior of POSIX ACLs
113 * is to set the mask to be the requested group permission
114 * bits, not the group permission bits to be the requested
115 * group permission bits. This is not what we want, as it will
116 * mess up any inherited ACL bits that were set. JRA.
118 int saved_errno
= errno
; /* We may get ENOSYS */
119 if (conn
->vfs_ops
.chmod_acl
!= NULL
) {
120 if ((conn
->vfs_ops
.chmod_acl(conn
, path
, mode
) == -1) && (errno
== ENOSYS
))
125 END_PROFILE(syscall_mkdir
);
129 int vfswrap_rmdir(connection_struct
*conn
, char *path
)
133 START_PROFILE(syscall_rmdir
);
135 #ifdef VFS_CHECK_NULL
137 smb_panic("NULL pointer passed to vfswrap_rmdir()\n");
141 result
= rmdir(path
);
142 END_PROFILE(syscall_rmdir
);
146 int vfswrap_closedir(connection_struct
*conn
, DIR *dirp
)
150 START_PROFILE(syscall_closedir
);
152 #ifdef VFS_CHECK_NULL
154 smb_panic("NULL pointer passed to vfswrap_closedir()\n");
158 result
= closedir(dirp
);
159 END_PROFILE(syscall_closedir
);
163 /* File operations */
165 int vfswrap_open(connection_struct
*conn
, char *fname
, int flags
, mode_t mode
)
169 START_PROFILE(syscall_open
);
171 #ifdef VFS_CHECK_NULL
173 smb_panic("NULL pointer passed to vfswrap_open()\n");
177 result
= sys_open(fname
, flags
, mode
);
178 END_PROFILE(syscall_open
);
182 int vfswrap_close(files_struct
*fsp
, int fd
)
186 START_PROFILE(syscall_close
);
189 END_PROFILE(syscall_close
);
193 ssize_t
vfswrap_read(files_struct
*fsp
, int fd
, char *data
, size_t n
)
197 START_PROFILE_BYTES(syscall_read
, n
);
199 #ifdef VFS_CHECK_NULL
201 smb_panic("NULL pointer passed to vfswrap_read()\n");
205 result
= read(fd
, data
, n
);
206 END_PROFILE(syscall_read
);
210 ssize_t
vfswrap_write(files_struct
*fsp
, int fd
, char *data
, size_t n
)
214 START_PROFILE_BYTES(syscall_write
, n
);
216 #ifdef VFS_CHECK_NULL
218 smb_panic("NULL pointer passed to vfswrap_write()\n");
222 result
= write(fd
, data
, n
);
223 END_PROFILE(syscall_write
);
227 SMB_OFF_T
vfswrap_lseek(files_struct
*fsp
, int filedes
, SMB_OFF_T offset
, int whence
)
231 START_PROFILE(syscall_lseek
);
233 result
= sys_lseek(filedes
, offset
, whence
);
234 END_PROFILE(syscall_lseek
);
238 int vfswrap_rename(connection_struct
*conn
, char *old
, char *new)
242 START_PROFILE(syscall_rename
);
244 #ifdef VFS_CHECK_NULL
245 if ((old
== NULL
) || (new == NULL
)) {
246 smb_panic("NULL pointer passed to vfswrap_rename()\n");
250 result
= rename(old
, new);
251 END_PROFILE(syscall_rename
);
255 int vfswrap_fsync(files_struct
*fsp
, int fd
)
260 START_PROFILE(syscall_fsync
);
263 END_PROFILE(syscall_fsync
);
270 int vfswrap_stat(connection_struct
*conn
, char *fname
, SMB_STRUCT_STAT
*sbuf
)
274 START_PROFILE(syscall_stat
);
276 #ifdef VFS_CHECK_NULL
277 if ((fname
== NULL
) || (sbuf
== NULL
)) {
278 smb_panic("NULL pointer passed to vfswrap_stat()\n");
282 result
= sys_stat(fname
, sbuf
);
283 END_PROFILE(syscall_stat
);
287 int vfswrap_fstat(files_struct
*fsp
, int fd
, SMB_STRUCT_STAT
*sbuf
)
291 START_PROFILE(syscall_fstat
);
293 #ifdef VFS_CHECK_NULL
295 smb_panic("NULL pointer passed to vfswrap_fstat()\n");
299 result
= sys_fstat(fd
, sbuf
);
300 END_PROFILE(syscall_fstat
);
304 int vfswrap_lstat(connection_struct
*conn
, char *path
, SMB_STRUCT_STAT
*sbuf
)
308 START_PROFILE(syscall_lstat
);
310 #ifdef VFS_CHECK_NULL
311 if ((path
== NULL
) || (sbuf
== NULL
)) {
312 smb_panic("NULL pointer passed to vfswrap_lstat()\n");
316 result
= sys_lstat(path
, sbuf
);
317 END_PROFILE(syscall_lstat
);
321 int vfswrap_unlink(connection_struct
*conn
, char *path
)
325 START_PROFILE(syscall_unlink
);
327 #ifdef VFS_CHECK_NULL
329 smb_panic("NULL pointer passed to vfswrap_unlink()\n");
333 result
= unlink(path
);
334 END_PROFILE(syscall_unlink
);
338 int vfswrap_chmod(connection_struct
*conn
, char *path
, mode_t mode
)
342 START_PROFILE(syscall_chmod
);
344 #ifdef VFS_CHECK_NULL
346 smb_panic("NULL pointer passed to vfswrap_chmod()\n");
351 * We need to do this due to the fact that the default POSIX ACL
352 * chmod modifies the ACL *mask* for the group owner, not the
353 * group owner bits directly. JRA.
357 if (conn
->vfs_ops
.chmod_acl
!= NULL
) {
358 int saved_errno
= errno
; /* We might get ENOSYS */
359 if ((result
= conn
->vfs_ops
.chmod_acl(conn
, path
, mode
)) == 0) {
360 END_PROFILE(syscall_chmod
);
363 /* Error - return the old errno. */
367 result
= chmod(path
, mode
);
368 END_PROFILE(syscall_chmod
);
372 int vfswrap_fchmod(files_struct
*fsp
, int fd
, mode_t mode
)
375 struct vfs_ops
*vfs_ops
= &fsp
->conn
->vfs_ops
;
377 START_PROFILE(syscall_fchmod
);
380 * We need to do this due to the fact that the default POSIX ACL
381 * chmod modifies the ACL *mask* for the group owner, not the
382 * group owner bits directly. JRA.
385 if (vfs_ops
->fchmod_acl
!= NULL
) {
386 int saved_errno
= errno
; /* We might get ENOSYS */
387 if ((result
= vfs_ops
->fchmod_acl(fsp
, fd
, mode
)) == 0) {
388 END_PROFILE(syscall_chmod
);
391 /* Error - return the old errno. */
395 result
= fchmod(fd
, mode
);
396 END_PROFILE(syscall_fchmod
);
400 int vfswrap_chown(connection_struct
*conn
, char *path
, uid_t uid
, gid_t gid
)
404 START_PROFILE(syscall_chown
);
406 #ifdef VFS_CHECK_NULL
408 smb_panic("NULL pointer passed to vfswrap_chown()\n");
412 result
= sys_chown(path
, uid
, gid
);
413 END_PROFILE(syscall_chown
);
417 int vfswrap_fchown(files_struct
*fsp
, int fd
, uid_t uid
, gid_t gid
)
421 START_PROFILE(syscall_fchown
);
423 result
= fchown(fd
, uid
, gid
);
424 END_PROFILE(syscall_fchown
);
428 int vfswrap_chdir(connection_struct
*conn
, char *path
)
432 START_PROFILE(syscall_chdir
);
434 #ifdef VFS_CHECK_NULL
436 smb_panic("NULL pointer passed to vfswrap_chdir()\n");
440 result
= chdir(path
);
441 END_PROFILE(syscall_chdir
);
445 char *vfswrap_getwd(connection_struct
*conn
, char *path
)
449 START_PROFILE(syscall_getwd
);
451 #ifdef VFS_CHECK_NULL
453 smb_panic("NULL pointer passed to vfswrap_getwd()\n");
457 result
= sys_getwd(path
);
458 END_PROFILE(syscall_getwd
);
462 int vfswrap_utime(connection_struct
*conn
, char *path
, struct utimbuf
*times
)
466 START_PROFILE(syscall_utime
);
468 #ifdef VFS_CHECK_NULL
469 if ((path
== NULL
) || (times
== NULL
)) {
470 smb_panic("NULL pointer passed to vfswrap_utime()\n");
474 result
= utime(path
, times
);
475 END_PROFILE(syscall_utime
);
479 int vfswrap_ftruncate(files_struct
*fsp
, int fd
, SMB_OFF_T len
)
482 START_PROFILE(syscall_ftruncate
);
484 #ifdef HAVE_FTRUNCATE_EXTEND
485 result
= sys_ftruncate(fd
, len
);
486 END_PROFILE(syscall_ftruncate
);
490 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
491 extend a file with ftruncate. Provide alternate implementation
494 struct vfs_ops
*vfs_ops
= &fsp
->conn
->vfs_ops
;
499 currpos
= vfs_ops
->lseek(fsp
, (SMB_OFF_T
)0, SEEK_CUR
);
504 /* Do an fstat to see if the file is longer than
505 the requested size (call ftruncate),
506 or shorter, in which case seek to len - 1 and write 1
508 if(vfs_ops
->fstat(fsp
, &st
)<0) {
513 if (S_ISFIFO(st
.st_mode
)) {
519 if(st
.st_size
== len
) {
524 if(st
.st_size
> len
) {
525 /* Yes this is *deliberately* sys_ftruncate ! JRA */
526 result
= sys_ftruncate(fd
, len
);
530 if(vfs_ops
->lseek(fsp
, len
-1, SEEK_SET
) != len
-1) {
534 if(vfs_ops
->write(fsp
, &c
, 1)!=1) {
538 /* Seek to where we were */
539 if(vfs_ops
->lseek(fsp
, currpos
, SEEK_SET
) != currpos
) {
544 END_PROFILE(syscall_ftruncate
);
550 BOOL
vfswrap_lock(files_struct
*fsp
, int fd
, int op
, SMB_OFF_T offset
, SMB_OFF_T count
, int type
)
554 START_PROFILE(syscall_fcntl_lock
);
556 result
= fcntl_lock(fd
, op
, offset
, count
,type
);
557 END_PROFILE(syscall_fcntl_lock
);
561 size_t vfswrap_fget_nt_acl(files_struct
*fsp
, int fd
, SEC_DESC
**ppdesc
)
563 return get_nt_acl(fsp
, ppdesc
);
566 size_t vfswrap_get_nt_acl(files_struct
*fsp
, char *name
, SEC_DESC
**ppdesc
)
568 return get_nt_acl(fsp
, ppdesc
);
571 BOOL
vfswrap_fset_nt_acl(files_struct
*fsp
, int fd
, uint32 security_info_sent
, SEC_DESC
*psd
)
573 return set_nt_acl(fsp
, security_info_sent
, psd
);
576 BOOL
vfswrap_set_nt_acl(files_struct
*fsp
, char *name
, uint32 security_info_sent
, SEC_DESC
*psd
)
578 return set_nt_acl(fsp
, security_info_sent
, psd
);
581 int vfswrap_chmod_acl(connection_struct
*conn
, char *name
, mode_t mode
)
583 return chmod_acl(name
, mode
);
586 int vfswrap_fchmod_acl(files_struct
*fsp
, int fd
, mode_t mode
)
588 return fchmod_acl(fd
, mode
);