// SPDX-FileCopyrightText: edef // SPDX-License-Identifier: OSL-3.0 use { libc::{c_int, ENOSYS, EROFS}, log::{debug, warn}, }; fn main() { env_logger::init(); let store = fossil::Store::open("fossil.db").unwrap(); fuser::mount2(Filesystem::open(store), "mnt", &[]).unwrap(); } struct Filesystem { store: fossil::Store, } impl Filesystem { fn open(store: fossil::Store) -> Filesystem { Filesystem { store } } } impl fuser::Filesystem for Filesystem { fn init( &mut self, _req: &fuser::Request<'_>, _config: &mut fuser::KernelConfig, ) -> Result<(), c_int> { Ok(()) } fn destroy(&mut self) {} fn lookup( &mut self, _req: &fuser::Request<'_>, parent: u64, name: &std::ffi::OsStr, reply: fuser::ReplyEntry, ) { warn!( "[Not Implemented] lookup(parent: {:#x?}, name {:?})", parent, name ); reply.error(ENOSYS); } fn forget(&mut self, _req: &fuser::Request<'_>, _ino: u64, _nlookup: u64) {} fn getattr(&mut self, _req: &fuser::Request<'_>, ino: u64, reply: fuser::ReplyAttr) { warn!("[Not Implemented] getattr(ino: {:#x?})", ino); reply.error(ENOSYS); } fn setattr( &mut self, _req: &fuser::Request<'_>, _ino: u64, _mode: Option, _uid: Option, _gid: Option, _size: Option, _atime: Option, _mtime: Option, _ctime: Option, _fh: Option, _crtime: Option, _chgtime: Option, _bkuptime: Option, _flags: Option, reply: fuser::ReplyAttr, ) { reply.error(EROFS); } fn readlink(&mut self, _req: &fuser::Request<'_>, ino: u64, reply: fuser::ReplyData) { debug!("[Not Implemented] readlink(ino: {:#x?})", ino); reply.error(ENOSYS); } fn mknod( &mut self, _req: &fuser::Request<'_>, _parent: u64, _name: &std::ffi::OsStr, _mode: u32, _umask: u32, _rdev: u32, reply: fuser::ReplyEntry, ) { reply.error(EROFS); } fn mkdir( &mut self, _req: &fuser::Request<'_>, _parent: u64, _name: &std::ffi::OsStr, _mode: u32, _umask: u32, reply: fuser::ReplyEntry, ) { reply.error(EROFS); } fn unlink( &mut self, _req: &fuser::Request<'_>, _parent: u64, _name: &std::ffi::OsStr, reply: fuser::ReplyEmpty, ) { reply.error(EROFS); } fn rmdir( &mut self, _req: &fuser::Request<'_>, parent: u64, name: &std::ffi::OsStr, reply: fuser::ReplyEmpty, ) { debug!( "[Not Implemented] rmdir(parent: {:#x?}, name: {:?})", parent, name, ); reply.error(ENOSYS); } fn symlink( &mut self, _req: &fuser::Request<'_>, _parent: u64, _name: &std::ffi::OsStr, _link: &std::path::Path, reply: fuser::ReplyEntry, ) { reply.error(EROFS); } fn rename( &mut self, _req: &fuser::Request<'_>, _parent: u64, _name: &std::ffi::OsStr, _newparent: u64, _newname: &std::ffi::OsStr, _flags: u32, reply: fuser::ReplyEmpty, ) { reply.error(EROFS); } fn link( &mut self, _req: &fuser::Request<'_>, _ino: u64, _newparent: u64, _newname: &std::ffi::OsStr, reply: fuser::ReplyEntry, ) { reply.error(EROFS); } fn open(&mut self, _req: &fuser::Request<'_>, _ino: u64, _flags: i32, reply: fuser::ReplyOpen) { reply.opened(0, 0); } fn read( &mut self, _req: &fuser::Request<'_>, ino: u64, fh: u64, offset: i64, size: u32, flags: i32, lock_owner: Option, reply: fuser::ReplyData, ) { warn!( "[Not Implemented] read(ino: {:#x?}, fh: {}, offset: {}, size: {}, \ flags: {:#x?}, lock_owner: {:?})", ino, fh, offset, size, flags, lock_owner ); reply.error(ENOSYS); } fn write( &mut self, _req: &fuser::Request<'_>, _ino: u64, _fh: u64, _offset: i64, _data: &[u8], _write_flags: u32, _flags: i32, _lock_owner: Option, reply: fuser::ReplyWrite, ) { reply.error(EROFS); } fn flush( &mut self, _req: &fuser::Request<'_>, ino: u64, fh: u64, lock_owner: u64, reply: fuser::ReplyEmpty, ) { debug!( "[Not Implemented] flush(ino: {:#x?}, fh: {}, lock_owner: {:?})", ino, fh, lock_owner ); reply.error(ENOSYS); } fn release( &mut self, _req: &fuser::Request<'_>, _ino: u64, _fh: u64, _flags: i32, _lock_owner: Option, _flush: bool, reply: fuser::ReplyEmpty, ) { reply.ok(); } fn fsync( &mut self, _req: &fuser::Request<'_>, ino: u64, fh: u64, datasync: bool, reply: fuser::ReplyEmpty, ) { debug!( "[Not Implemented] fsync(ino: {:#x?}, fh: {}, datasync: {})", ino, fh, datasync ); reply.error(ENOSYS); } fn opendir( &mut self, _req: &fuser::Request<'_>, _ino: u64, _flags: i32, reply: fuser::ReplyOpen, ) { reply.opened(0, 0); } fn readdir( &mut self, _req: &fuser::Request<'_>, ino: u64, fh: u64, offset: i64, reply: fuser::ReplyDirectory, ) { warn!( "[Not Implemented] readdir(ino: {:#x?}, fh: {}, offset: {})", ino, fh, offset ); reply.error(ENOSYS); } fn readdirplus( &mut self, _req: &fuser::Request<'_>, ino: u64, fh: u64, offset: i64, reply: fuser::ReplyDirectoryPlus, ) { debug!( "[Not Implemented] readdirplus(ino: {:#x?}, fh: {}, offset: {})", ino, fh, offset ); reply.error(ENOSYS); } fn releasedir( &mut self, _req: &fuser::Request<'_>, _ino: u64, _fh: u64, _flags: i32, reply: fuser::ReplyEmpty, ) { reply.ok(); } fn fsyncdir( &mut self, _req: &fuser::Request<'_>, ino: u64, fh: u64, datasync: bool, reply: fuser::ReplyEmpty, ) { debug!( "[Not Implemented] fsyncdir(ino: {:#x?}, fh: {}, datasync: {})", ino, fh, datasync ); reply.error(ENOSYS); } fn statfs(&mut self, _req: &fuser::Request<'_>, _ino: u64, reply: fuser::ReplyStatfs) { reply.statfs(0, 0, 0, 0, 0, 512, 255, 0); } fn setxattr( &mut self, _req: &fuser::Request<'_>, _ino: u64, _name: &std::ffi::OsStr, _value: &[u8], _flags: i32, _position: u32, reply: fuser::ReplyEmpty, ) { reply.error(EROFS); } fn getxattr( &mut self, _req: &fuser::Request<'_>, _ino: u64, _name: &std::ffi::OsStr, _size: u32, reply: fuser::ReplyXattr, ) { reply.error(ENOSYS); } fn listxattr( &mut self, _req: &fuser::Request<'_>, _ino: u64, _size: u32, reply: fuser::ReplyXattr, ) { reply.error(ENOSYS); } fn removexattr( &mut self, _req: &fuser::Request<'_>, _ino: u64, _name: &std::ffi::OsStr, reply: fuser::ReplyEmpty, ) { reply.error(EROFS); } fn access(&mut self, _req: &fuser::Request<'_>, ino: u64, mask: i32, reply: fuser::ReplyEmpty) { debug!("[Not Implemented] access(ino: {:#x?}, mask: {})", ino, mask); reply.error(ENOSYS); } fn create( &mut self, _req: &fuser::Request<'_>, _parent: u64, _name: &std::ffi::OsStr, _mode: u32, _umask: u32, _flags: i32, reply: fuser::ReplyCreate, ) { reply.error(EROFS); } fn getlk( &mut self, _req: &fuser::Request<'_>, _ino: u64, _fh: u64, _lock_owner: u64, _start: u64, _end: u64, _typ: i32, _pid: u32, reply: fuser::ReplyLock, ) { reply.error(ENOSYS); } fn setlk( &mut self, _req: &fuser::Request<'_>, _ino: u64, _fh: u64, _lock_owner: u64, _start: u64, _end: u64, _typ: i32, _pid: u32, _sleep: bool, reply: fuser::ReplyEmpty, ) { reply.error(ENOSYS); } fn bmap( &mut self, _req: &fuser::Request<'_>, _ino: u64, _blocksize: u32, _idx: u64, reply: fuser::ReplyBmap, ) { reply.error(ENOSYS); } fn ioctl( &mut self, _req: &fuser::Request<'_>, _ino: u64, _fh: u64, _flags: u32, _cmd: u32, _in_data: &[u8], _out_size: u32, reply: fuser::ReplyIoctl, ) { reply.error(ENOSYS); } fn fallocate( &mut self, _req: &fuser::Request<'_>, _ino: u64, _fh: u64, _offset: i64, _length: i64, _mode: i32, reply: fuser::ReplyEmpty, ) { reply.error(EROFS); } fn lseek( &mut self, _req: &fuser::Request<'_>, ino: u64, fh: u64, offset: i64, whence: i32, reply: fuser::ReplyLseek, ) { debug!( "[Not Implemented] lseek(ino: {:#x?}, fh: {}, offset: {}, whence: {})", ino, fh, offset, whence ); reply.error(ENOSYS); } fn copy_file_range( &mut self, _req: &fuser::Request<'_>, _ino_in: u64, _fh_in: u64, _offset_in: i64, _ino_out: u64, _fh_out: u64, _offset_out: i64, _len: u64, _flags: u32, reply: fuser::ReplyWrite, ) { reply.error(EROFS); } }