#![warn(missing_docs, bad_style, unused, unused_extern_crates, unused_import_braces, unused_qualifications, missing_debug_implementations)]
extern crate libc;
#[macro_use]
extern crate log;
extern crate time;
extern crate thread_scoped;
use std::convert::AsRef;
use std::io;
use std::ffi::OsStr;
use std::path::Path;
use libc::{c_int, ENOSYS};
use time::Timespec;
pub use fuse::FUSE_ROOT_ID;
pub use fuse::consts;
pub use reply::{Reply, ReplyEmpty, ReplyData, ReplyEntry, ReplyAttr, ReplyOpen};
pub use reply::{ReplyWrite, ReplyStatfs, ReplyCreate, ReplyLock, ReplyBmap, ReplyDirectory};
pub use reply::ReplyXattr;
#[cfg(target_os = "macos")]
pub use reply::ReplyXTimes;
pub use request::Request;
pub use session::{Session, BackgroundSession};
mod argument;
mod channel;
mod fuse;
mod reply;
mod request;
mod session;
#[derive(Clone, Copy, Debug, Hash, PartialEq)]
pub enum FileType {
NamedPipe,
CharDevice,
BlockDevice,
Directory,
RegularFile,
Symlink,
}
#[derive(Clone, Copy, Debug)]
pub struct FileAttr {
pub ino: u64,
pub size: u64,
pub blocks: u64,
pub atime: Timespec,
pub mtime: Timespec,
pub ctime: Timespec,
pub crtime: Timespec,
pub kind: FileType,
pub perm: u16,
pub nlink: u32,
pub uid: u32,
pub gid: u32,
pub rdev: u32,
pub flags: u32,
}
pub trait Filesystem {
fn init (&mut self, _req: &Request) -> Result<(), c_int> {
Ok(())
}
fn destroy (&mut self, _req: &Request) {
}
fn lookup (&mut self, _req: &Request, _parent: u64, _name: &OsStr, reply: ReplyEntry) {
reply.error(ENOSYS);
}
fn forget (&mut self, _req: &Request, _ino: u64, _nlookup: u64) {
}
fn getattr (&mut self, _req: &Request, _ino: u64, reply: ReplyAttr) {
reply.error(ENOSYS);
}
fn setattr (&mut self, _req: &Request, _ino: u64, _mode: Option<u32>, _uid: Option<u32>, _gid: Option<u32>, _size: Option<u64>, _atime: Option<Timespec>, _mtime: Option<Timespec>, _fh: Option<u64>, _crtime: Option<Timespec>, _chgtime: Option<Timespec>, _bkuptime: Option<Timespec>, _flags: Option<u32>, reply: ReplyAttr) {
reply.error(ENOSYS);
}
fn readlink (&mut self, _req: &Request, _ino: u64, reply: ReplyData) {
reply.error(ENOSYS);
}
fn mknod (&mut self, _req: &Request, _parent: u64, _name: &OsStr, _mode: u32, _rdev: u32, reply: ReplyEntry) {
reply.error(ENOSYS);
}
fn mkdir (&mut self, _req: &Request, _parent: u64, _name: &OsStr, _mode: u32, reply: ReplyEntry) {
reply.error(ENOSYS);
}
fn unlink (&mut self, _req: &Request, _parent: u64, _name: &OsStr, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn rmdir (&mut self, _req: &Request, _parent: u64, _name: &OsStr, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn symlink (&mut self, _req: &Request, _parent: u64, _name: &OsStr, _link: &Path, reply: ReplyEntry) {
reply.error(ENOSYS);
}
fn rename (&mut self, _req: &Request, _parent: u64, _name: &OsStr, _newparent: u64, _newname: &OsStr, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn link (&mut self, _req: &Request, _ino: u64, _newparent: u64, _newname: &OsStr, reply: ReplyEntry) {
reply.error(ENOSYS);
}
fn open (&mut self, _req: &Request, _ino: u64, _flags: u32, reply: ReplyOpen) {
reply.opened(0, 0);
}
fn read (&mut self, _req: &Request, _ino: u64, _fh: u64, _offset: u64, _size: u32, reply: ReplyData) {
reply.error(ENOSYS);
}
fn write (&mut self, _req: &Request, _ino: u64, _fh: u64, _offset: u64, _data: &[u8], _flags: u32, reply: ReplyWrite) {
reply.error(ENOSYS);
}
fn flush (&mut self, _req: &Request, _ino: u64, _fh: u64, _lock_owner: u64, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn release (&mut self, _req: &Request, _ino: u64, _fh: u64, _flags: u32, _lock_owner: u64, _flush: bool, reply: ReplyEmpty) {
reply.ok();
}
fn fsync (&mut self, _req: &Request, _ino: u64, _fh: u64, _datasync: bool, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn opendir (&mut self, _req: &Request, _ino: u64, _flags: u32, reply: ReplyOpen) {
reply.opened(0, 0);
}
fn readdir (&mut self, _req: &Request, _ino: u64, _fh: u64, _offset: u64, reply: ReplyDirectory) {
reply.error(ENOSYS);
}
fn releasedir (&mut self, _req: &Request, _ino: u64, _fh: u64, _flags: u32, reply: ReplyEmpty) {
reply.ok();
}
fn fsyncdir (&mut self, _req: &Request, _ino: u64, _fh: u64, _datasync: bool, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn statfs (&mut self, _req: &Request, _ino: u64, reply: ReplyStatfs) {
reply.statfs(0, 0, 0, 0, 0, 512, 255, 0);
}
fn setxattr (&mut self, _req: &Request, _ino: u64, _name: &OsStr, _value: &[u8], _flags: u32, _position: u32, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn getxattr (&mut self, _req: &Request, _ino: u64, _name: &OsStr, _size: u32, reply: ReplyXattr) {
reply.error(ENOSYS);
}
fn listxattr (&mut self, _req: &Request, _ino: u64, _size: u32, reply: ReplyXattr) {
reply.error(ENOSYS);
}
fn removexattr (&mut self, _req: &Request, _ino: u64, _name: &OsStr, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn access (&mut self, _req: &Request, _ino: u64, _mask: u32, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn create (&mut self, _req: &Request, _parent: u64, _name: &OsStr, _mode: u32, _flags: u32, reply: ReplyCreate) {
reply.error(ENOSYS);
}
fn getlk (&mut self, _req: &Request, _ino: u64, _fh: u64, _lock_owner: u64, _start: u64, _end: u64, _typ: u32, _pid: u32, reply: ReplyLock) {
reply.error(ENOSYS);
}
fn setlk (&mut self, _req: &Request, _ino: u64, _fh: u64, _lock_owner: u64, _start: u64, _end: u64, _typ: u32, _pid: u32, _sleep: bool, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
fn bmap (&mut self, _req: &Request, _ino: u64, _blocksize: u32, _idx: u64, reply: ReplyBmap) {
reply.error(ENOSYS);
}
#[cfg(target_os = "macos")]
fn setvolname (&mut self, _req: &Request, _name: &OsStr, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
#[cfg(target_os = "macos")]
fn exchange (&mut self, _req: &Request, _parent: u64, _name: &OsStr, _newparent: u64, _newname: &OsStr, _options: u64, reply: ReplyEmpty) {
reply.error(ENOSYS);
}
#[cfg(target_os = "macos")]
fn getxtimes (&mut self, _req: &Request, _ino: u64, reply: ReplyXTimes) {
reply.error(ENOSYS);
}
}
pub fn mount<FS: Filesystem, P: AsRef<Path>> (filesystem: FS, mountpoint: &P, options: &[&OsStr]) -> io::Result<()>{
Session::new(filesystem, mountpoint.as_ref(), options).and_then(|mut se| se.run())
}
pub unsafe fn spawn_mount<'a, FS: Filesystem+Send+'a, P: AsRef<Path>> (filesystem: FS, mountpoint: &P, options: &[&OsStr]) -> io::Result<BackgroundSession<'a>> {
Session::new(filesystem, mountpoint.as_ref(), options).and_then(|se| se.spawn())
}