This commit was manufactured by cvs2svn to create branch 'SAMBA_2_2'.
[Samba.git] / source / smbd / vfs-wrap.c
bloba7ddbb4376e18ecd97d349a89cc1f158bf2bb2f1
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
22 #include "includes.h"
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
30 this possibility. */
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)
41 /* Disk operations */
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)
46 SMB_BIG_UINT result;
48 #ifdef VFS_CHECK_NULL
49 if ((path == NULL) || (bsize == NULL) || (dfree == NULL) ||
50 (dsize == NULL)) {
52 smb_panic("NULL pointer passed to vfswrap_disk_free() function\n");
54 #endif
56 result = sys_disk_free(path, small_query, bsize, dfree, dsize);
57 return result;
60 /* Directory operations */
62 DIR *vfswrap_opendir(connection_struct *conn, char *fname)
64 DIR *result;
66 START_PROFILE(syscall_opendir);
68 #ifdef VFS_CHECK_NULL
69 if (fname == NULL) {
70 smb_panic("NULL pointer passed to vfswrap_opendir()\n");
72 #endif
74 result = opendir(fname);
75 END_PROFILE(syscall_opendir);
76 return result;
79 struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp)
81 struct dirent *result;
83 START_PROFILE(syscall_readdir);
85 #ifdef VFS_CHECK_NULL
86 if (dirp == NULL) {
87 smb_panic("NULL pointer passed to vfswrap_readdir()\n");
89 #endif
91 result = readdir(dirp);
92 END_PROFILE(syscall_readdir);
93 return result;
96 int vfswrap_mkdir(connection_struct *conn, char *path, mode_t mode)
98 int result;
100 START_PROFILE(syscall_mkdir);
102 #ifdef VFS_CHECK_NULL
103 if (path == NULL) {
104 smb_panic("NULL pointer passed to vfswrap_mkdir()\n");
106 #endif
108 result = mkdir(path, mode);
110 if (result == 0) {
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))
121 errno = saved_errno;
125 END_PROFILE(syscall_mkdir);
126 return result;
129 int vfswrap_rmdir(connection_struct *conn, char *path)
131 int result;
133 START_PROFILE(syscall_rmdir);
135 #ifdef VFS_CHECK_NULL
136 if (path == NULL) {
137 smb_panic("NULL pointer passed to vfswrap_rmdir()\n");
139 #endif
141 result = rmdir(path);
142 END_PROFILE(syscall_rmdir);
143 return result;
146 int vfswrap_closedir(connection_struct *conn, DIR *dirp)
148 int result;
150 START_PROFILE(syscall_closedir);
152 #ifdef VFS_CHECK_NULL
153 if (dirp == NULL) {
154 smb_panic("NULL pointer passed to vfswrap_closedir()\n");
156 #endif
158 result = closedir(dirp);
159 END_PROFILE(syscall_closedir);
160 return result;
163 /* File operations */
165 int vfswrap_open(connection_struct *conn, char *fname, int flags, mode_t mode)
167 int result;
169 START_PROFILE(syscall_open);
171 #ifdef VFS_CHECK_NULL
172 if (fname == NULL) {
173 smb_panic("NULL pointer passed to vfswrap_open()\n");
175 #endif
177 result = sys_open(fname, flags, mode);
178 END_PROFILE(syscall_open);
179 return result;
182 int vfswrap_close(files_struct *fsp, int fd)
184 int result;
186 START_PROFILE(syscall_close);
188 result = close(fd);
189 END_PROFILE(syscall_close);
190 return result;
193 ssize_t vfswrap_read(files_struct *fsp, int fd, char *data, size_t n)
195 ssize_t result;
197 START_PROFILE_BYTES(syscall_read, n);
199 #ifdef VFS_CHECK_NULL
200 if (data == NULL) {
201 smb_panic("NULL pointer passed to vfswrap_read()\n");
203 #endif
205 result = read(fd, data, n);
206 END_PROFILE(syscall_read);
207 return result;
210 ssize_t vfswrap_write(files_struct *fsp, int fd, char *data, size_t n)
212 ssize_t result;
214 START_PROFILE_BYTES(syscall_write, n);
216 #ifdef VFS_CHECK_NULL
217 if (data == NULL) {
218 smb_panic("NULL pointer passed to vfswrap_write()\n");
220 #endif
222 result = write(fd, data, n);
223 END_PROFILE(syscall_write);
224 return result;
227 SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
229 SMB_OFF_T result;
231 START_PROFILE(syscall_lseek);
233 result = sys_lseek(filedes, offset, whence);
234 END_PROFILE(syscall_lseek);
235 return result;
238 int vfswrap_rename(connection_struct *conn, char *old, char *new)
240 int result;
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");
248 #endif
250 result = rename(old, new);
251 END_PROFILE(syscall_rename);
252 return result;
255 int vfswrap_fsync(files_struct *fsp, int fd)
257 #ifdef HAVE_FSYNC
258 int result;
260 START_PROFILE(syscall_fsync);
262 result = fsync(fd);
263 END_PROFILE(syscall_fsync);
264 return result;
265 #else
266 return 0;
267 #endif
270 int vfswrap_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf)
272 int result;
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");
280 #endif
282 result = sys_stat(fname, sbuf);
283 END_PROFILE(syscall_stat);
284 return result;
287 int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
289 int result;
291 START_PROFILE(syscall_fstat);
293 #ifdef VFS_CHECK_NULL
294 if (sbuf == NULL) {
295 smb_panic("NULL pointer passed to vfswrap_fstat()\n");
297 #endif
299 result = sys_fstat(fd, sbuf);
300 END_PROFILE(syscall_fstat);
301 return result;
304 int vfswrap_lstat(connection_struct *conn, char *path, SMB_STRUCT_STAT *sbuf)
306 int result;
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");
314 #endif
316 result = sys_lstat(path, sbuf);
317 END_PROFILE(syscall_lstat);
318 return result;
321 int vfswrap_unlink(connection_struct *conn, char *path)
323 int result;
325 START_PROFILE(syscall_unlink);
327 #ifdef VFS_CHECK_NULL
328 if (path == NULL) {
329 smb_panic("NULL pointer passed to vfswrap_unlink()\n");
331 #endif
333 result = unlink(path);
334 END_PROFILE(syscall_unlink);
335 return result;
338 int vfswrap_chmod(connection_struct *conn, char *path, mode_t mode)
340 int result;
342 START_PROFILE(syscall_chmod);
344 #ifdef VFS_CHECK_NULL
345 if (path == NULL) {
346 smb_panic("NULL pointer passed to vfswrap_chmod()\n");
348 #endif
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);
361 return result;
363 /* Error - return the old errno. */
364 errno = saved_errno;
367 result = chmod(path, mode);
368 END_PROFILE(syscall_chmod);
369 return result;
372 int vfswrap_fchmod(files_struct *fsp, int fd, mode_t mode)
374 int result;
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);
389 return result;
391 /* Error - return the old errno. */
392 errno = saved_errno;
395 result = fchmod(fd, mode);
396 END_PROFILE(syscall_fchmod);
397 return result;
400 int vfswrap_chown(connection_struct *conn, char *path, uid_t uid, gid_t gid)
402 int result;
404 START_PROFILE(syscall_chown);
406 #ifdef VFS_CHECK_NULL
407 if (path == NULL) {
408 smb_panic("NULL pointer passed to vfswrap_chown()\n");
410 #endif
412 result = sys_chown(path, uid, gid);
413 END_PROFILE(syscall_chown);
414 return result;
417 int vfswrap_fchown(files_struct *fsp, int fd, uid_t uid, gid_t gid)
419 int result;
421 START_PROFILE(syscall_fchown);
423 result = fchown(fd, uid, gid);
424 END_PROFILE(syscall_fchown);
425 return result;
428 int vfswrap_chdir(connection_struct *conn, char *path)
430 int result;
432 START_PROFILE(syscall_chdir);
434 #ifdef VFS_CHECK_NULL
435 if (path == NULL) {
436 smb_panic("NULL pointer passed to vfswrap_chdir()\n");
438 #endif
440 result = chdir(path);
441 END_PROFILE(syscall_chdir);
442 return result;
445 char *vfswrap_getwd(connection_struct *conn, char *path)
447 char *result;
449 START_PROFILE(syscall_getwd);
451 #ifdef VFS_CHECK_NULL
452 if (path == NULL) {
453 smb_panic("NULL pointer passed to vfswrap_getwd()\n");
455 #endif
457 result = sys_getwd(path);
458 END_PROFILE(syscall_getwd);
459 return result;
462 int vfswrap_utime(connection_struct *conn, char *path, struct utimbuf *times)
464 int result;
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");
472 #endif
474 result = utime(path, times);
475 END_PROFILE(syscall_utime);
476 return result;
479 int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
481 int result = -1;
482 struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
483 SMB_STRUCT_STAT st;
484 char c = 0;
485 SMB_OFF_T currpos;
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
499 for this */
500 currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR);
501 if (currpos == -1) {
502 goto done;
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) {
510 goto done;
513 #ifdef S_ISFIFO
514 if (S_ISFIFO(st.st_mode)) {
515 result = 0;
516 goto done;
518 #endif
520 if (st.st_size == len) {
521 result = 0;
522 goto done;
525 if (st.st_size > len) {
526 /* the sys_ftruncate should have worked */
527 goto done;
530 if (vfs_ops->lseek(fsp, fd, len-1, SEEK_SET) != len -1) {
531 goto done;
534 if (vfs_ops->write(fsp, fd, &c, 1)!=1) {
535 goto done;
538 /* Seek to where we were */
539 if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos) {
540 goto done;
542 result = 0;
543 done:
545 END_PROFILE(syscall_ftruncate);
546 return result;
549 BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
551 BOOL result;
553 START_PROFILE(syscall_fcntl_lock);
555 result = fcntl_lock(fd, op, offset, count,type);
556 END_PROFILE(syscall_fcntl_lock);
557 return result;
560 int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *newpath)
562 int result;
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");
569 #endif
571 result = sys_symlink(oldpath, newpath);
572 END_PROFILE(syscall_symlink);
573 return result;
576 int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_t bufsiz)
578 int result;
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");
585 #endif
587 result = sys_readlink(path, buf, bufsiz);
588 END_PROFILE(syscall_readlink);
589 return result;
592 size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc)
594 size_t result;
596 START_PROFILE(fget_nt_acl);
597 result = get_nt_acl(fsp, ppdesc);
598 END_PROFILE(fget_nt_acl);
599 return result;
602 size_t vfswrap_get_nt_acl(files_struct *fsp, char *name, SEC_DESC **ppdesc)
604 size_t result;
606 START_PROFILE(get_nt_acl);
607 result = get_nt_acl(fsp, ppdesc);
608 END_PROFILE(get_nt_acl);
609 return result;
612 BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
614 BOOL result;
616 START_PROFILE(fset_nt_acl);
617 result = set_nt_acl(fsp, security_info_sent, psd);
618 END_PROFILE(fset_nt_acl);
619 return result;
622 BOOL vfswrap_set_nt_acl(files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd)
624 BOOL result;
626 START_PROFILE(set_nt_acl);
627 result = set_nt_acl(fsp, security_info_sent, psd);
628 END_PROFILE(set_nt_acl);
629 return result;
632 int vfswrap_chmod_acl(connection_struct *conn, char *name, mode_t mode)
634 int result;
636 START_PROFILE(chmod_acl);
637 result = chmod_acl(name, mode);
638 END_PROFILE(chmod_acl);
639 return result;
642 int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode)
644 int result;
646 START_PROFILE(fchmod_acl);
647 result = fchmod_acl(fd, mode);
648 END_PROFILE(fchmod_acl);
649 return result;