diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2004-11-11 15:20:05 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2004-11-11 15:20:05 +0000 |
commit | 30e8eb3e135291717eceaae69162fceb91d30aa1 (patch) | |
tree | 1db0567746719aeebe993981e2744d0340cfcc3e /lufis/lufis.c | |
parent | 3d60e7641b52ac98d789ab091c6ada143dba5f69 (diff) | |
download | libfuse-30e8eb3e135291717eceaae69162fceb91d30aa1.tar.gz |
move perl python and lufis directories one level up
Diffstat (limited to 'lufis/lufis.c')
-rw-r--r-- | lufis/lufis.c | 800 |
1 files changed, 0 insertions, 800 deletions
diff --git a/lufis/lufis.c b/lufis/lufis.c deleted file mode 100644 index 5509bdf..0000000 --- a/lufis/lufis.c +++ /dev/null @@ -1,800 +0,0 @@ -#define _GNU_SOURCE - -#include <lufs/fs.h> -#include <lufs/proto.h> -#include <fuse.h> -#include "list.h" -#include "dircache.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dlfcn.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/vfs.h> - -/* statfs extension for captivefs */ -struct lufs_sbattr_ { /* struct statfs64 */ - unsigned long long sb_bytes; - unsigned long long sb_bytes_free; - unsigned long long sb_bytes_available; - unsigned long long sb_files; - unsigned long long sb_ffree; -}; - -struct fs_operations { - void *(*init)(struct list_head*, struct dir_cache*, struct credentials*, void**); - void (*free)(void*); - int (*mount)(void*); - void (*umount)(void*); - int (*readdir)(void*, char*, struct directory*); - int (*stat)(void*, char*, struct lufs_fattr*); - int (*mkdir)(void*, char*, int); - int (*rmdir)(void*, char*); - int (*create)(void*, char*, int); - int (*unlink)(void*, char*); - int (*rename)(void*, char*, char*); - int (*open)(void*, char*, unsigned); - int (*release)(void*, char*); - int (*read)(void*, char*, long long, unsigned long, char*); - int (*write)(void*, char*, long long, unsigned long, char*); - int (*readlink)(void*, char*, char*, int); - int (*link)(void*, char*, char*); - int (*symlink)(void*, char*, char*); - int (*setattr)(void*, char*, struct lufs_fattr*); - int (*statfs)(void*, struct lufs_sbattr_*); -}; - -static struct fs_operations lu_fops; -static void *lu_dlhandle; -static struct list_head lu_cfg; -static void *lu_global_ctx; -static struct credentials lu_cred; -static void *lu_context; -static struct dir_cache *lu_cache; - -#define BUF_SIZE 1024 -#define PASSWD "/etc/passwd" -#define GROUP "/etc/group" - -int lu_check_to(int rd_fd, int wr_fd, int time_out){ - fd_set rd, wr; - int res, maxfd = 0; - struct timeval tv; - - FD_ZERO(&rd); - FD_ZERO(&wr); - - if(rd_fd){ - FD_SET(rd_fd, &rd); - maxfd = rd_fd > maxfd ? rd_fd : maxfd; - } - - if(wr_fd){ - FD_SET(wr_fd, &wr); - maxfd = wr_fd > maxfd ? wr_fd : maxfd; - } - - tv.tv_sec = time_out; - tv.tv_usec = 0; - - do{ - res = select(maxfd + 1, &rd, &wr, NULL, &tv); - - }while((res < 0) && (errno == EINTR)); - - if(res > 0) - return 0; - - if(res < 0){ - WARN("select call failed: %s", strerror(errno)); - return -errno; - } - - WARN("operation timed out!"); - - return -ETIMEDOUT; -} - -int lu_atomic_read(int fd, char *buf, int len, int time_out){ - int res, offset = 0; - - do{ - if((time_out) && ((res = lu_check_to(fd, 0, time_out)) < 0)) - return res; - - do{ - res = read(fd, buf + offset, len - offset); - }while((res < 0) && (errno == EINTR)); - - if(res <= 0){ - WARN("read call failed: %s", strerror(errno)); - return (res < 0) ? -errno : (offset > 0 ? offset : -EPIPE); - } - - offset += res; - - }while(offset < len); - - return offset; -} - -int lu_atomic_write(int fd, char *buf, int len, int time_out){ - int res, offset = 0; - - do{ - if((time_out) && ((res = lu_check_to(0, fd, time_out)) < 0)) - return res; - - do{ - res = write(fd, buf + offset, len - offset); - }while((res < 0) && (errno == EINTR)); - - if(res <= 0){ - WARN("write call failed: %s", strerror(errno)); - return (res < 0) ? -errno : (offset > 0 ? offset : -EPIPE); - } - - offset += res; - - }while(offset < len); - - return offset; -} - -static int get_filesystem(const char *fs) -{ - char *buf; - void *dlhandle; - - if(!(buf = (char*)malloc(strlen(fs) + 32))) - return -1; - - sprintf(buf, "liblufs-%s.so", fs); - if(!(dlhandle = dlopen(buf, RTLD_LAZY))){ - ERROR(dlerror()); - goto fail; - } - - sprintf(buf, "%s_init", fs); - if(!(lu_fops.init = (void*(*)(struct list_head*, struct dir_cache*, struct credentials*, void**))dlsym(dlhandle, buf))){ - ERROR(dlerror()); - goto fail_fops; - } - - sprintf(buf, "%s_free", fs); - if(!(lu_fops.free = (void(*)(void*))dlsym(dlhandle, buf))){ - ERROR(dlerror()); - goto fail_fops; - } - - sprintf(buf, "%s_mount", fs); - if(!(lu_fops.mount = (int(*)(void*))dlsym(dlhandle, buf))){ - ERROR(dlerror()); - goto fail_fops; - } - - sprintf(buf, "%s_umount", fs); - if(!(lu_fops.umount = (void(*)(void*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_readdir", fs); - if(!(lu_fops.readdir = (int(*)(void*, char*, struct directory*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_stat", fs); - if(!(lu_fops.stat = (int(*)(void*, char*, struct lufs_fattr*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_mkdir", fs); - if(!(lu_fops.mkdir = (int(*)(void*, char*, int))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_rmdir", fs); - if(!(lu_fops.rmdir = (int(*)(void*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_create", fs); - if(!(lu_fops.create = (int(*)(void*, char*, int))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_unlink", fs); - if(!(lu_fops.unlink = (int(*)(void*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_rename", fs); - if(!(lu_fops.rename = (int(*)(void*, char*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_open", fs); - if(!(lu_fops.open = (int(*)(void*, char*, unsigned))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_release", fs); - if(!(lu_fops.release = (int(*)(void*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_read", fs); - if(!(lu_fops.read = (int(*)(void*, char*, long long, unsigned long, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_write", fs); - if(!(lu_fops.write = (int(*)(void*, char*, long long, unsigned long, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_readlink", fs); - if(!(lu_fops.readlink = (int(*)(void*, char*, char*, int))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_link", fs); - if(!(lu_fops.link = (int(*)(void*, char*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_symlink", fs); - if(!(lu_fops.symlink = (int(*)(void*, char*, char*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - - sprintf(buf, "%s_setattr", fs); - if(!(lu_fops.setattr = (int(*)(void*, char*, struct lufs_fattr*))dlsym(dlhandle, buf))) - ERROR(dlerror()); - sprintf(buf, "%s_statfs", fs); - lu_fops.statfs = (int(*)(void*, struct lufs_sbattr_*))dlsym(dlhandle, buf); - - lu_dlhandle = dlhandle; - free(buf); - return 0; - - fail_fops: - dlclose(dlhandle); - fail: - free(buf); - return -1; -} - -static int lu_getattr_native(const char *path, struct lufs_fattr *fattr) -{ - if(!lu_fops.stat) - return -ENOSYS; - - memset(fattr, 0, sizeof(struct lufs_fattr)); - if(lu_cache_lookup_file(lu_cache, (char *) path, fattr, NULL, 0) < 0) { - if(lu_fops.stat(lu_context, (char *) path, fattr) < 0) - return -ENOENT; - } - return 0; -} - -static int lu_getattr(const char *path, struct stat *stbuf) -{ - struct lufs_fattr fattr; - int res; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - stbuf->st_mode = fattr.f_mode; - stbuf->st_nlink = fattr.f_nlink; - stbuf->st_uid = fattr.f_uid; - stbuf->st_gid = fattr.f_gid; - stbuf->st_size = fattr.f_size; - stbuf->st_atime = fattr.f_atime; - stbuf->st_mtime = fattr.f_mtime; - stbuf->st_ctime = fattr.f_ctime; - stbuf->st_blksize = fattr.f_blksize; - stbuf->st_blocks = fattr.f_blocks; - - return 0; -} - -static int lu_readlink(const char *path, char *buf, size_t size) -{ - int len; - struct lufs_fattr fattr; - - if(!lu_fops.readlink) - return -ENOSYS; - - if(lu_cache_lookup_file(lu_cache, (char *) path, &fattr, buf, size) < 0 || - strcmp(buf, "") == 0) { - if((len = lu_fops.readlink(lu_context, (char *) path, buf, size)) < 0) - return -EPERM; - - /* FUSE leaves one extra char free at the end */ - buf[len] = '\0'; - } - - return 0; -} - -static int lu_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler) -{ - struct directory *dir; - - if(!lu_fops.readdir) - return -ENOSYS; - - if(lu_cache_readdir(lu_cache, (char *) path, h, filler) < 0){ - if(!(dir = lu_cache_mkdir((char *) path))) - return -1; - - if(lu_fops.readdir(lu_context, (char *) path, dir) < 0){ - lu_cache_killdir(dir); - return -1; - } - lu_cache_add_dir(lu_cache, dir); - - if(lu_cache_readdir(lu_cache, (char *) path, h, filler) < 0) { - return -EPERM; - } - } - return 0; -} - -static int lu_mknod(const char *path, mode_t mode, dev_t rdev) -{ - (void) rdev; - if(!S_ISREG(mode) || !lu_fops.create) - return -ENOSYS; - - if(lu_fops.create(lu_context, (char *) path, mode) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_mkdir(const char *path, mode_t mode) -{ - if(!lu_fops.mkdir) - return -ENOSYS; - - if(lu_fops.mkdir(lu_context, (char *) path, mode) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_unlink(const char *path) -{ - if(!lu_fops.unlink) - return -ENOSYS; - - if(lu_fops.unlink(lu_context, (char *) path) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_rmdir(const char *path) -{ - if(!lu_fops.rmdir) - return -ENOSYS; - - if(lu_fops.rmdir(lu_context, (char *) path) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_symlink(const char *from, const char *to) -{ - if(!lu_fops.symlink) - return -ENOSYS; - - if(lu_fops.symlink(lu_context, (char *) from, (char *) to) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) to); - return 0; -} - -static int lu_rename(const char *from, const char *to) -{ - if(!lu_fops.rename) - return -ENOSYS; - - if(lu_fops.rename(lu_context, (char *) from, (char *) to) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) from); - lu_cache_invalidate(lu_cache, (char *) to); - return 0; -} - -static int lu_link(const char *from, const char *to) -{ - if(!lu_fops.link) - return -ENOSYS; - - if(lu_fops.link(lu_context, (char *) from, (char *) to) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) from); - lu_cache_invalidate(lu_cache, (char *) to); - return 0; -} - -static int lu_chmod(const char *path, mode_t mode) -{ - int res; - struct lufs_fattr fattr; - - if(!lu_fops.setattr) - return -ENOSYS; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - fattr.f_mode = mode; - if(lu_fops.setattr(lu_context, (char *) path, &fattr) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_chown(const char *path, uid_t uid, gid_t gid) -{ - int res; - struct lufs_fattr fattr; - - if(!lu_fops.setattr) - return -ENOSYS; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - if(uid != (uid_t) -1) - fattr.f_uid = uid; - if(gid != (gid_t) -1) - fattr.f_gid = gid; - if(lu_fops.setattr(lu_context, (char *) path, &fattr) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; - -} - -static int lu_truncate(const char *path, off_t size) -{ - int res; - struct lufs_fattr fattr; - - if(!lu_fops.setattr) - return -ENOSYS; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - fattr.f_size = size; - if(lu_fops.setattr(lu_context, (char *) path, &fattr) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - -static int lu_utime(const char *path, struct utimbuf *buf) -{ - int res; - struct lufs_fattr fattr; - - if(!lu_fops.setattr) - return -ENOSYS; - - res = lu_getattr_native(path, &fattr); - if(res < 0) - return res; - - fattr.f_atime = buf->actime; - fattr.f_mtime = buf->modtime; - if(lu_fops.setattr(lu_context, (char *) path, &fattr) < 0) - return -EPERM; - - lu_cache_invalidate(lu_cache, (char *) path); - return 0; -} - - -static int lu_open(const char *path, int flags) -{ - if(!lu_fops.open) - return -ENOSYS; - - if(lu_fops.open(lu_context, (char *) path, flags & O_ACCMODE) < 0) - return -EPERM; - - return 0; -} - -static int lu_read(const char *path, char *buf, size_t size, off_t offset) -{ - int res; - if(!lu_fops.read) - return -ENOSYS; - - if((res = lu_fops.read(lu_context, (char *) path, offset, size, buf)) < 0) - return -EPERM; - - return res; -} - -static int lu_write(const char *path, const char *buf, size_t size, - off_t offset) -{ - if(!lu_fops.write) - return -ENOSYS; - - if(lu_fops.write(lu_context, (char *) path, offset, size, (char *) buf) < 0) - return -EPERM; - - return size; -} - -static int lu_release(const char *path, int flags) -{ - (void) flags; - if(!lu_fops.release) - return -ENOSYS; - - if(lu_fops.release(lu_context, (char *) path) < 0) - return -EPERM; - - return 0; -} - -#if FUSE_MAJOR_VERSION < 2 -static int lu_statfs(struct fuse_statfs *stbuf) -#else -static int lu_statfs(const char *path, struct statfs *stbuf) -#endif -{ - struct lufs_sbattr_ sbattr; - - memset(&sbattr, 0, sizeof(sbattr)); - if(lu_fops.statfs) { - if(lu_fops.statfs(lu_context, &sbattr) < 0) - return -EPERM; - } - -#if FUSE_MAJOR_VERSION < 2 - stbuf->blocks = sbattr.sb_bytes / 512; - stbuf->blocks_free = sbattr.sb_bytes_available / 512; - stbuf->files = sbattr.sb_files; - stbuf->files_free = sbattr.sb_ffree; - stbuf->namelen = 255; -#else - (void) path; - stbuf->f_bsize = 512; - stbuf->f_blocks = sbattr.sb_bytes / 512; - stbuf->f_bfree = sbattr.sb_bytes_free / 512; - stbuf->f_bavail = sbattr.sb_bytes_available / 512; - stbuf->f_files = sbattr.sb_files; - stbuf->f_ffree = sbattr.sb_ffree; - stbuf->f_namelen = 255; -#endif - return 0; -} - -static int load_credentials(void) -{ - static char buf[BUF_SIZE]; - char srch_str[MAX_LEN + 4]; - long int uid, gid; - int res, offset, chunk, readlen; - char *c; - - TRACE("loading remote credentials for %s", lu_cred.user); - - if((!lu_fops.open) || (!lu_fops.read) || (!lu_fops.release)){ - WARN("unsupported operation"); - return -1;; - } - - lu_cred.uid = lu_cred.gid = -1; - - if(lu_fops.open(lu_context, PASSWD, O_RDONLY) < 0){ - TRACE("could not open %s", PASSWD); - return -1; - } - - sprintf(srch_str, "\n%s:", lu_cred.user); - chunk = strlen(srch_str) + 64; - readlen = BUF_SIZE - chunk - 1; - - memset(buf, 32, chunk); - offset = 0; - - do{ - res = lu_fops.read(lu_context, PASSWD, offset, readlen, (buf + chunk)); - if(res > 0){ - *(buf + chunk + res) = 0; - - if((c = strstr(buf, srch_str))){ - TRACE("username found!"); - if(!(c = strchr(c + strlen(srch_str), ':'))){ - TRACE("separator not found!"); - }else{ - if(sscanf(c , ":%li:%li:", &uid, &gid) != 2){ - TRACE("uid/gid not found!"); - }else{ - TRACE("uid: %li, gid: %li", uid, gid); - - lu_cred.uid = uid; - lu_cred.gid = gid; - - break; - } - } - } - - memcpy(buf, buf + BUF_SIZE - chunk - 1, chunk); - offset += res; - } - }while(res == readlen); - - lu_fops.release(lu_context, PASSWD); - - if(res <= 0){ - TRACE("read failed"); - return -1; - } - - - if(lu_fops.open(lu_context, GROUP, O_RDONLY) < 0){ - TRACE("could not open %s", GROUP); - return -1; - } - - sprintf(srch_str, ":%li:", (long)lu_cred.gid); - chunk = strlen(srch_str) + 64; - readlen = BUF_SIZE - chunk - 1; - - memset(buf, 32, chunk); - offset = 0; - - do{ - res = lu_fops.read(lu_context, GROUP, offset, readlen, (buf + chunk)); - if(res > 0){ - *(buf + chunk + res) = 0; - - if((c = strstr(buf, srch_str))){ - TRACE("group found!"); - if(!(c = (char*)memrchr(buf, '\n', (c - buf)))){ - TRACE("separator not found!"); - }else{ - *(strchr(c, ':')) = 0; - if(strlen(c + 1) >= MAX_LEN){ - TRACE("groupname too long"); - }else{ - strcpy(lu_cred.group, c + 1); - TRACE("group: %s", lu_cred.group); - break; - } - } - } - - memcpy(buf, buf + BUF_SIZE - chunk - 1, chunk); - offset += res; - } - }while(res == readlen); - - lu_fops.release(lu_context, GROUP); - - if(res <= 0){ - TRACE("read failed"); - return -1; - } - - return 0; -} - -static int lufis_init(int *argcp, char **argvp[]) -{ - int argc = *argcp; - char **argv = *argvp; - int res; - char *opts; - const char *fs_name; - - if(argc < 2) { - fprintf(stderr, "usage: %s opts\n", argv[0]); - return -1; - } - - INIT_LIST_HEAD(&lu_cfg); - opts = argv[1]; - if(lu_opt_parse(&lu_cfg, "MOUNT", opts) < 0){ - ERROR("could not parse options!"); - return -1; - } - - lu_opt_loadcfg(&lu_cfg, "/etc/lufsd.conf"); - - (*argcp)--; - (*argvp)++; - argv[1] = argv[0]; - - - lu_cache = lu_cache_create(&lu_cfg); - if(!lu_cache) - return -1; - - if(!(fs_name = lu_opt_getchar(&lu_cfg, "MOUNT", "fs"))){ - ERROR("you need to specify a file system!"); - return -1; - } - - res = get_filesystem(fs_name); - if(res == -1) - return -1; - - if(!(lu_context = lu_fops.init(&lu_cfg, lu_cache, &lu_cred, &lu_global_ctx))) { - ERROR("could not initialize file system!"); - return -1; - } - - res = lu_fops.mount(lu_context); - if(res) { - if(load_credentials() < 0) - TRACE("could not load credentials."); - else - TRACE("credentials loaded."); - } else { - WARN("fs mount failed..."); - } - - return 0; -} - -static void lufis_cleanup(void) -{ - if(lu_fops.umount) - lu_fops.umount(lu_context); - lu_fops.free(lu_context); -} - -static struct fuse_operations lu_oper = { - .getattr = lu_getattr, - .readlink = lu_readlink, - .getdir = lu_getdir, - .mknod = lu_mknod, - .mkdir = lu_mkdir, - .symlink = lu_symlink, - .unlink = lu_unlink, - .rmdir = lu_rmdir, - .rename = lu_rename, - .link = lu_link, - .chmod = lu_chmod, - .chown = lu_chown, - .truncate = lu_truncate, - .utime = lu_utime, - .open = lu_open, - .read = lu_read, - .write = lu_write, - .release = lu_release, - .statfs = lu_statfs, -}; - -int main(int argc, char *argv[]) -{ - int res; - - res = lufis_init(&argc, &argv); - if(res == -1) - exit(1); - - fuse_main(argc, argv, &lu_oper); - lufis_cleanup(); - - return 0; -} |