use std::time::{Duration, SystemTime};
use fuser::FileAttr as FuseFileAttr;
use fuser::{FileType, Request, TimeOrNow};
use libc::mode_t;
use super::BorrowedFileHandle;
use super::LockType;
pub use std::io::SeekFrom;
pub fn seek_from_raw(whence: Option<i32>, offset: i64) -> SeekFrom {
match whence {
Some(w) => match w {
libc::SEEK_SET => SeekFrom::Start(
offset
.try_into()
.expect("Invalid negative seek offset for file start"),
),
libc::SEEK_CUR => SeekFrom::Current(offset),
libc::SEEK_END => SeekFrom::End(offset),
_ => panic!("Invalid seek code"),
},
None => SeekFrom::Start(
offset
.try_into()
.expect("Invalid negative seek offset for file start"),
),
}
}
#[derive(Debug, Clone, Copy)]
pub enum DeviceType {
RegularFile,
Directory,
CharacterDevice { major: u32, minor: u32 },
BlockDevice { major: u32, minor: u32 },
NamedPipe,
Socket,
Symlink,
Unknown,
}
impl DeviceType {
pub fn from_rdev(rdev: mode_t) -> Self {
use libc::*;
let major: u32 = (rdev >> 8).into(); let minor: u32 = (rdev & 0xFF).into(); match rdev {
x if x & S_IFREG != 0 => DeviceType::RegularFile,
x if x & S_IFDIR != 0 => DeviceType::Directory,
x if x & S_IFCHR != 0 => DeviceType::CharacterDevice { major, minor },
x if x & S_IFBLK != 0 => DeviceType::BlockDevice { major, minor },
x if x & S_IFIFO != 0 => DeviceType::NamedPipe,
x if x & S_IFSOCK != 0 => DeviceType::Socket,
x if x & S_IFLNK != 0 => DeviceType::Symlink,
_ => DeviceType::Unknown,
}
}
pub fn to_rdev(&self) -> mode_t {
use libc::*;
match self {
DeviceType::RegularFile => S_IFREG,
DeviceType::Directory => S_IFDIR,
DeviceType::CharacterDevice { major, minor } => {
let device = ((major & 0xFF) << 8) | (minor & 0xFF);
(device as mode_t) | S_IFCHR
}
DeviceType::BlockDevice { major, minor } => {
let device = ((major & 0xFF) << 8) | (minor & 0xFF);
(device as mode_t) | S_IFBLK
}
DeviceType::NamedPipe => S_IFIFO,
DeviceType::Socket => S_IFSOCK,
DeviceType::Symlink => S_IFLNK,
DeviceType::Unknown => 0, }
}
}
#[derive(Debug, Clone)]
pub struct StatFs {
pub total_blocks: u64,
pub free_blocks: u64,
pub available_blocks: u64,
pub total_files: u64,
pub free_files: u64,
pub block_size: u32,
pub max_filename_length: u32,
pub fragment_size: u32,
}
impl StatFs {
pub fn default() -> Self {
StatFs {
total_blocks: u64::MAX,
free_blocks: u64::MAX,
available_blocks: u64::MAX,
total_files: u64::MAX / 2,
free_files: u64::MAX / 2,
block_size: 4096,
max_filename_length: 255,
fragment_size: 4096,
}
}
}
#[derive(Debug, Clone)]
pub struct RequestInfo {
pub id: u64,
pub uid: u32,
pub gid: u32,
pub pid: u32,
}
impl<'a> From<&Request<'a>> for RequestInfo {
fn from(req: &Request<'a>) -> Self {
Self {
id: req.unique(),
uid: req.uid(),
gid: req.gid(),
pid: req.pid(),
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct FileAttribute {
pub size: u64,
pub blocks: u64,
pub atime: SystemTime,
pub mtime: SystemTime,
pub ctime: SystemTime,
pub crtime: SystemTime,
pub kind: FileType,
pub perm: u16,
pub nlink: u32,
pub uid: u32,
pub gid: u32,
pub rdev: u32,
pub blksize: u32,
pub flags: u32,
pub ttl: Option<Duration>,
pub generation: Option<u64>,
}
impl FileAttribute {
pub(crate) fn to_fuse(self, ino: u64) -> (FuseFileAttr, Option<Duration>, Option<u64>) {
(
FuseFileAttr {
ino,
size: self.size,
blocks: self.blocks,
atime: self.atime,
mtime: self.mtime,
ctime: self.ctime,
crtime: self.crtime,
kind: self.kind,
perm: self.perm,
nlink: self.nlink,
uid: self.uid,
gid: self.gid,
rdev: self.rdev,
blksize: self.blksize,
flags: self.flags,
},
self.ttl,
self.generation,
)
}
}
#[derive(Debug)]
pub struct SetAttrRequest<'a> {
pub mode: Option<u32>,
pub uid: Option<u32>,
pub gid: Option<u32>,
pub size: Option<u64>,
pub atime: Option<TimeOrNow>,
pub mtime: Option<TimeOrNow>,
pub ctime: Option<SystemTime>,
pub crtime: Option<SystemTime>,
pub chgtime: Option<SystemTime>,
pub bkuptime: Option<SystemTime>,
pub flags: Option<()>,
pub file_handle: Option<BorrowedFileHandle<'a>>,
}
impl<'a> SetAttrRequest<'a> {
pub fn new() -> Self {
Self {
mode: None,
uid: None,
gid: None,
size: None,
atime: None,
mtime: None,
ctime: None,
crtime: None,
chgtime: None,
bkuptime: None,
flags: None,
file_handle: None,
}
}
pub fn mode(mut self, mode: u32) -> Self {
self.mode = Some(mode);
self
}
pub fn uid(mut self, uid: u32) -> Self {
self.uid = Some(uid);
self
}
pub fn gid(mut self, gid: u32) -> Self {
self.gid = Some(gid);
self
}
pub fn size(mut self, size: u64) -> Self {
self.size = Some(size);
self
}
pub fn atime(mut self, atime: TimeOrNow) -> Self {
self.atime = Some(atime);
self
}
pub fn mtime(mut self, mtime: TimeOrNow) -> Self {
self.mtime = Some(mtime);
self
}
pub fn ctime(mut self, ctime: SystemTime) -> Self {
self.ctime = Some(ctime);
self
}
pub fn crtime(mut self, crtime: SystemTime) -> Self {
self.crtime = Some(crtime);
self
}
pub fn chgtime(mut self, chgtime: SystemTime) -> Self {
self.chgtime = Some(chgtime);
self
}
pub fn bkuptime(mut self, bkuptime: SystemTime) -> Self {
self.bkuptime = Some(bkuptime);
self
}
pub fn flags(mut self, flags: ()) -> Self {
self.flags = Some(flags);
self
}
pub fn file_handle(mut self, file_handle: BorrowedFileHandle<'a>) -> Self {
self.file_handle = Some(file_handle);
self
}
}
#[derive(Debug)]
pub struct LockInfo {
pub start: u64,
pub end: u64,
pub lock_type: LockType,
pub pid: u32,
}