#include "fuseapp.h" #include #include #include #include #include #include static FuseAppBase * fuseApp; FuseAppBase::FuseAppBase() { } FuseAppBase::~FuseAppBase() { } void * FuseAppBase::init(fuse_conn_info*) { return NULL; } int FuseAppBase::opt_parse(void*, const char *, int, fuse_args*) { return 1; } int FuseAppBase::access(const char *, int) { return -ENOSYS; } int FuseAppBase::chmod(const char *, mode_t) { return -ENOSYS; } int FuseAppBase::chown(const char *, uid_t, gid_t) { return -ENOSYS; } int FuseAppBase::create(const char *, mode_t, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::fgetattr(const char *, struct stat *, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::flush(const char *, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::fsync(const char *, int, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::fsyncdir(const char *, int, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::ftruncate(const char *, off_t, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::getattr(const char *, struct stat *) { return -ENOSYS; } int FuseAppBase::getxattr(const char *, const char *, char *, size_t) { return -ENOSYS; } int FuseAppBase::link(const char *, const char *) { return -ENOSYS; } int FuseAppBase::listxattr(const char *, char *, size_t) { return -ENOSYS; } int FuseAppBase::mkdir(const char *, mode_t) { return -ENOSYS; } int FuseAppBase::mknod(const char *, mode_t, dev_t) { return -ENOSYS; } int FuseAppBase::open(const char *, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::opendir(const char *, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::read(const char *, char *, size_t, off_t, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::readlink(const char *, char *, size_t) { return -ENOSYS; } int FuseAppBase::release(const char *, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::releasedir(const char *, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::removexattr(const char *, const char *) { return -ENOSYS; } int FuseAppBase::rename(const char *, const char *) { return -ENOSYS; } int FuseAppBase::rmdir(const char *) { return -ENOSYS; } int FuseAppBase::setxattr(const char *, const char *, const char *, size_t, int) { return -ENOSYS; } int FuseAppBase::statfs(const char *, struct statvfs *) { return -ENOSYS; } int FuseAppBase::symlink(const char *, const char *) { return -ENOSYS; } int FuseAppBase::truncate(const char *, off_t) { return -ENOSYS; } int FuseAppBase::unlink(const char *) { return -ENOSYS; } int FuseAppBase::write(const char *, const char *, size_t, off_t, struct fuse_file_info *) { return -ENOSYS; } int FuseAppBase::lock(const char *, struct fuse_file_info *, int, struct flock *) { return -ENOSYS; } int FuseAppBase::utimens(const char *, const struct timespec[2]) { return -ENOSYS; } int FuseAppBase::bmap(const char *, size_t, uint64_t *) { return -ENOSYS; } int FuseAppBase::onError(const std::exception & e) throw() { fprintf(stderr, "Unknown exception calling (what: %s)\n", e.what()); return -ENOSYS; } template class fuseCall { public: template static int helper(Args ... a) { try { return (fuseApp->*f)(a...); } catch (const std::exception & ex) { if (int rtn = fuseApp->onError(ex)) { return rtn; } return helper(a...); } catch (...) { fprintf(stderr, "Unknown exception calling %s\n", typeid(f).name()); return -ENOSYS; } } }; static void * fuseInit (struct fuse_conn_info *conn) { return fuseApp->init(conn); } static void fuseDestroy(void *) { delete fuseApp; } int FuseAppBase::run(int & argc, char** & argv, FuseAppBase * fa) { struct fuse_opt fuse_opts[] = { { NULL, 0, 0 } }; fuseApp = fa; struct fuse_operations operations = { fuseCall::helper<&FuseAppBase::getattr>, fuseCall::helper<&FuseAppBase::readlink>, NULL, // getdir deprecated fuseCall::helper<&FuseAppBase::mknod>, fuseCall::helper<&FuseAppBase::mkdir>, fuseCall::helper<&FuseAppBase::unlink>, fuseCall::helper<&FuseAppBase::rmdir>, fuseCall::helper<&FuseAppBase::symlink>, fuseCall::helper<&FuseAppBase::rename>, fuseCall::helper<&FuseAppBase::link>, fuseCall::helper<&FuseAppBase::chmod>, fuseCall::helper<&FuseAppBase::chown>, fuseCall::helper<&FuseAppBase::truncate>, NULL, // utime deprecated fuseCall::helper<&FuseAppBase::open>, fuseCall::helper<&FuseAppBase::read>, fuseCall::helper<&FuseAppBase::write>, fuseCall::helper<&FuseAppBase::statfs>, fuseCall::helper<&FuseAppBase::flush>, fuseCall::helper<&FuseAppBase::release>, fuseCall::helper<&FuseAppBase::fsync>, fuseCall::helper<&FuseAppBase::setxattr>, fuseCall::helper<&FuseAppBase::getxattr>, fuseCall::helper<&FuseAppBase::listxattr>, fuseCall::helper<&FuseAppBase::removexattr>, fuseCall::helper<&FuseAppBase::opendir>, fuseCall::helper<&FuseAppBase::readdir>, fuseCall::helper<&FuseAppBase::releasedir>, fuseCall::helper<&FuseAppBase::fsyncdir>, fuseInit, fuseDestroy, fuseCall::helper<&FuseAppBase::access>, fuseCall::helper<&FuseAppBase::create>, fuseCall::helper<&FuseAppBase::ftruncate>, fuseCall::helper<&FuseAppBase::fgetattr> #if (FUSE_MINOR_VERSION >= 6) , fuseCall::helper<&FuseAppBase::lock>, fuseCall::helper<&FuseAppBase::utimens>, fuseCall::helper<&FuseAppBase::bmap> #if (FUSE_MINOR_VERSION >= 8) , 0, // flag_nullpath_ok #if (FUSE_MINOR_VERSION >= 9) 0, // flag_nopath 0, // flag_utime_omit_ok #endif 0, // flag_reserved NULL, // ioctl NULL // poll #if (FUSE_MINOR_VERSION >= 9) , NULL, // writebuf NULL, // readbuf NULL // flock #endif #endif #endif }; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); if (fuse_opt_parse(&args, fuseApp, fuse_opts, fuseCall::helper<&FuseAppBase::opt_parse>) == -1) { exit(1); } return fuse_main(args.argc, args.argv, &operations, fa); }