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 struct vfs_ops
*vfs_ops
= &fsp
->conn
->vfs_ops
;
487 START_PROFILE(syscall_ftruncate
);
489 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
490 sys_ftruncate if the system supports it. Then I discovered that
491 you can have some filesystems that support ftruncate
492 expansion and some that don't! On Linux fat can't do
493 ftruncate extend but ext2 can. */
494 result
= sys_ftruncate(fd
, len
);
495 if (result
== 0) goto done
;
497 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
498 extend a file with ftruncate. Provide alternate implementation
500 currpos
= vfs_ops
->lseek(fsp
, fd
, 0, SEEK_CUR
);
505 /* Do an fstat to see if the file is longer than the requested
506 size in which case the ftruncate above should have
507 succeeded or shorter, in which case seek to len - 1 and
508 write 1 byte of zero */
509 if (vfs_ops
->fstat(fsp
, fd
, &st
) < 0) {
514 if (S_ISFIFO(st
.st_mode
)) {
520 if (st
.st_size
== len
) {
525 if (st
.st_size
> len
) {
526 /* the sys_ftruncate should have worked */
530 if (vfs_ops
->lseek(fsp
, fd
, len
-1, SEEK_SET
) != len
-1) {
534 if (vfs_ops
->write(fsp
, fd
, &c
, 1)!=1) {
538 /* Seek to where we were */
539 if (vfs_ops
->lseek(fsp
, fd
, currpos
, SEEK_SET
) != currpos
) {
545 END_PROFILE(syscall_ftruncate
);
549 BOOL
vfswrap_lock(files_struct
*fsp
, int fd
, int op
, SMB_OFF_T offset
, SMB_OFF_T count
, int type
)
553 START_PROFILE(syscall_fcntl_lock
);
555 result
= fcntl_lock(fd
, op
, offset
, count
,type
);
556 END_PROFILE(syscall_fcntl_lock
);
560 int vfswrap_symlink(connection_struct
*conn
, const char *oldpath
, const char *newpath
)
564 START_PROFILE(syscall_symlink
);
566 #ifdef VFS_CHECK_NULL
567 if ((oldpath
== NULL
) || (newpath
== NULL
))
568 smb_panic("NULL pointer passed to vfswrap_symlink()\n");
571 result
= sys_symlink(oldpath
, newpath
);
572 END_PROFILE(syscall_symlink
);
576 int vfswrap_readlink(connection_struct
*conn
, const char *path
, char *buf
, size_t bufsiz
)
580 START_PROFILE(syscall_readlink
);
582 #ifdef VFS_CHECK_NULL
583 if ((path
== NULL
) || (buf
== NULL
))
584 smb_panic("NULL pointer passed to vfswrap_readlink()\n");
587 result
= sys_readlink(path
, buf
, bufsiz
);
588 END_PROFILE(syscall_readlink
);
592 size_t vfswrap_fget_nt_acl(files_struct
*fsp
, int fd
, SEC_DESC
**ppdesc
)
596 START_PROFILE(fget_nt_acl
);
597 result
= get_nt_acl(fsp
, ppdesc
);
598 END_PROFILE(fget_nt_acl
);
602 size_t vfswrap_get_nt_acl(files_struct
*fsp
, char *name
, SEC_DESC
**ppdesc
)
606 START_PROFILE(get_nt_acl
);
607 result
= get_nt_acl(fsp
, ppdesc
);
608 END_PROFILE(get_nt_acl
);
612 BOOL
vfswrap_fset_nt_acl(files_struct
*fsp
, int fd
, uint32 security_info_sent
, SEC_DESC
*psd
)
616 START_PROFILE(fset_nt_acl
);
617 result
= set_nt_acl(fsp
, security_info_sent
, psd
);
618 END_PROFILE(fset_nt_acl
);
622 BOOL
vfswrap_set_nt_acl(files_struct
*fsp
, char *name
, uint32 security_info_sent
, SEC_DESC
*psd
)
626 START_PROFILE(set_nt_acl
);
627 result
= set_nt_acl(fsp
, security_info_sent
, psd
);
628 END_PROFILE(set_nt_acl
);
632 int vfswrap_chmod_acl(connection_struct
*conn
, char *name
, mode_t mode
)
636 START_PROFILE(chmod_acl
);
637 result
= chmod_acl(name
, mode
);
638 END_PROFILE(chmod_acl
);
642 int vfswrap_fchmod_acl(files_struct
*fsp
, int fd
, mode_t mode
)
646 START_PROFILE(fchmod_acl
);
647 result
= fchmod_acl(fd
, mode
);
648 END_PROFILE(fchmod_acl
);