diff options
-rw-r--r-- | source3/smbd/vfs.c | 215 |
1 files changed, 114 insertions, 101 deletions
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 7304229f8d..b0bc1a9f4d 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1,8 +1,8 @@ /* Unix SMB/Netbios implementation. Version 1.9. - vfs initialisation and support functions - Copyright (C) Tim Potter 1992-1998 + VFS initialisation and support functions + Copyright (C) Tim Potter 1999 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 @@ -33,61 +33,16 @@ struct vfs_syminfo { void *fptr; }; -struct vfs_ops dl_ops; - -struct vfs_syminfo vfs_syminfo[] = { - - /* Global operations */ - - {"vfs_init", &dl_ops.init}, - - /* Disk operations */ - - {"vfs_connect", &dl_ops.connect}, - {"vfs_disconnect", &dl_ops.disconnect}, - {"vfs_disk_free", &dl_ops.disk_free}, - - /* Directory operations */ - - {"vfs_opendir", &dl_ops.opendir}, - {"vfs_readdir", &dl_ops.readdir}, - {"vfs_mkdir", &dl_ops.mkdir}, - {"vfs_rmdir", &dl_ops.rmdir}, - {"vfs_closedir", &dl_ops.closedir}, - - /* File operations */ - - {"vfs_open", &dl_ops.open}, - {"vfs_close", &dl_ops.close}, - {"vfs_read", &dl_ops.read}, - {"vfs_write", &dl_ops.write}, - {"vfs_lseek", &dl_ops.lseek}, - {"vfs_rename", &dl_ops.rename}, - {"vfs_sync", &dl_ops.sync}, - {"vfs_stat", &dl_ops.stat}, - {"vfs_fstat", &dl_ops.fstat}, - {"vfs_lstat", &dl_ops.lstat}, - {"vfs_lock", &dl_ops.lock}, - {"vfs_unlink", &dl_ops.unlink}, - {"vfs_chmod", &dl_ops.chmod}, - {"vfs_utime", &dl_ops.utime}, - - {NULL, 0} -}; - /* Default vfs hooks. WARNING: The order of these initialisers is - very important. Change at your own peril. */ + very important. They must be in the same order as defined in + vfs.h. Change at your own peril. */ struct vfs_ops default_vfs_ops = { - /* Global operations */ - - NULL, /* init */ - /* Disk operations */ - NULL, /* connect */ - NULL, /* disconnect */ + vfswrap_dummy_connect, + vfswrap_dummy_disconnect, vfswrap_disk_free, /* Directory operations */ @@ -117,54 +72,24 @@ struct vfs_ops default_vfs_ops = { }; /**************************************************************************** - call vfs_init function of loadable module -****************************************************************************/ -#ifdef HAVE_LIBDL -BOOL do_vfs_init(char *vfs_object) -{ - void *handle, (*fptr)(void); - - DEBUG(3, ("Calling vfs_init for module %s\n", vfs_object)); - - handle = dlopen(vfs_object, RTLD_NOW); - if (!handle) { - DEBUG(0, ("Error opening %s: %s\n", vfs_object, dlerror())); - return False; - } - - fptr = dlsym(handle, "vfs_init"); - - /* Call initialisation function */ - - if (fptr != NULL) { - fptr(); - } - - dlclose(handle); - - return True; -} -#endif - -/**************************************************************************** initialise default vfs hooks ****************************************************************************/ int vfs_init_default(connection_struct *conn) { DEBUG(3, ("Initialising default vfs hooks\n")); - bcopy(&default_vfs_ops, &conn->vfs_ops, sizeof(conn->vfs_ops)); - return 0; + memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(conn->vfs_ops)); + return True; } /**************************************************************************** initialise custom vfs hooks ****************************************************************************/ #ifdef HAVE_LIBDL -int vfs_init_custom(connection_struct *conn) +BOOL vfs_init_custom(connection_struct *conn) { - void *handle, *fptr; - int index; + void *handle; + struct vfs_ops *ops, *(*fptr)(void); DEBUG(3, ("Initialising custom vfs hooks from %s\n", lp_vfsobj(SNUM(conn)))); @@ -175,30 +100,118 @@ int vfs_init_custom(connection_struct *conn) if (!handle) { DEBUG(0, ("Error opening %s: %s\n", lp_vfsobj(SNUM(conn)), dlerror())); - return -1; + return False; } - /* Read list of symbols */ + /* Get handle on vfs_init() symbol */ - for(index = 0; vfs_syminfo[index].name; index++) { - fptr = dlsym(handle, vfs_syminfo[index].name); - if (fptr == NULL) { - DEBUG(0, ("Symbol %s not found in %s\n", vfs_syminfo[index].name, - lp_vfsobj(SNUM(conn)))); - return -1; - } + fptr = dlsym(handle, "vfs_init"); + if (fptr == NULL) { + DEBUG(0, ("No vfs_init() symbol found in %s\n", + lp_vfsobj(SNUM(conn)))); + return False; + } + + dlclose(handle); + + /* Initialise vfs_ops and fill in unused operations with default + (disk based) ones. There's probably a neater way to do this. */ - *((void **)vfs_syminfo[index].fptr) = fptr; + if ((ops = fptr()) == NULL) { + return False; + } + + memcpy(&conn->vfs_ops, ops, sizeof(conn->vfs_ops)); + + if (conn->vfs_ops.connect == NULL) { + conn->vfs_ops.connect = default_vfs_ops.connect; } - /* Copy loaded symbols into connection struct */ + if (conn->vfs_ops.disconnect == NULL) { + conn->vfs_ops.disconnect = default_vfs_ops.disconnect; + } - bcopy(&dl_ops, &conn->vfs_ops, sizeof(dl_ops)); - dlclose(handle); + if (conn->vfs_ops.disk_free == NULL) { + conn->vfs_ops.disk_free = default_vfs_ops.disk_free; + } + + if (conn->vfs_ops.opendir == NULL) { + conn->vfs_ops.opendir = default_vfs_ops.opendir; + } - do_vfs_init(lp_vfsobj(SNUM(conn))); + if (conn->vfs_ops.readdir == NULL) { + conn->vfs_ops.readdir = default_vfs_ops.readdir; + } + + if (conn->vfs_ops.mkdir == NULL) { + conn->vfs_ops.mkdir = default_vfs_ops.mkdir; + } - return 0; + if (conn->vfs_ops.rmdir == NULL) { + conn->vfs_ops.rmdir = default_vfs_ops.rmdir; + } + + if (conn->vfs_ops.closedir == NULL) { + conn->vfs_ops.closedir = default_vfs_ops.closedir; + } + + if (conn->vfs_ops.open == NULL) { + conn->vfs_ops.open = default_vfs_ops.open; + } + + if (conn->vfs_ops.close == NULL) { + conn->vfs_ops.close = default_vfs_ops.close; + } + + if (conn->vfs_ops.read == NULL) { + conn->vfs_ops.read = default_vfs_ops.read; + } + + if (conn->vfs_ops.write == NULL) { + conn->vfs_ops.write = default_vfs_ops.write; + } + + if (conn->vfs_ops.lseek == NULL) { + conn->vfs_ops.lseek = default_vfs_ops.lseek; + } + + if (conn->vfs_ops.rename == NULL) { + conn->vfs_ops.rename = default_vfs_ops.rename; + } + + if (conn->vfs_ops.sync == NULL) { + conn->vfs_ops.sync = default_vfs_ops.sync; + } + + if (conn->vfs_ops.stat == NULL) { + conn->vfs_ops.stat = default_vfs_ops.stat; + } + + if (conn->vfs_ops.fstat == NULL) { + conn->vfs_ops.fstat = default_vfs_ops.fstat; + } + + if (conn->vfs_ops.lstat == NULL) { + conn->vfs_ops.lstat = default_vfs_ops.lstat; + } + + if (conn->vfs_ops.lock == NULL) { + conn->vfs_ops.lock = default_vfs_ops.lock; + } + + if (conn->vfs_ops.unlink == NULL) { + conn->vfs_ops.unlink = default_vfs_ops.unlink; + } + + if (conn->vfs_ops.chmod == NULL) { + conn->vfs_ops.chmod = default_vfs_ops.chmod; + } + + if (conn->vfs_ops.utime == NULL) { + conn->vfs_ops.utime = default_vfs_ops.utime; + } + + return True; } #endif |