Parse mount options in any position, fork before mount by default

This commit is contained in:
Travis Burtrum 2022-08-04 00:57:54 -04:00
parent 93135ccdff
commit c0f4a33e86
1 changed files with 69 additions and 34 deletions

View File

@ -3,8 +3,8 @@ use fuser::{
ReplyOpen, Request,
};
use libc::{
c_int, EINVAL, EIO, ENOENT, EPERM, O_ACCMODE, O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR,
O_TRUNC, O_WRONLY,
c_int, exit, fork, setsid, EINVAL, EIO, ENOENT, EPERM, O_ACCMODE, O_APPEND, O_CREAT, O_EXCL,
O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY,
};
use log::{debug, error, warn};
use serde::{Deserialize, Serialize};
@ -591,16 +591,39 @@ impl Filesystem for CacheFs {
}
}
pub fn daemon() {
unsafe {
match fork() {
// child
0 => {
if setsid() == -1 {
error!("error executing setsid()");
exit(1);
}
}
-1 => {
error!("error executing fork()");
exit(1);
}
// parent
_ => exit(0),
}
}
}
fn main() {
env_logger::init();
let mut args = env::args_os().skip(1);
if args.next() != Some(OsStr::from_bytes(b"-o").to_os_string()) {
panic!("-o must be second argument");
}
let mut cmd_opts = "ro".to_string();
let mut cache_dir = "".to_string();
let mut default_permissions = true;
let mut fork_daemon = true;
let mut count = 0;
let mut pos_args = [None, None];
while let Some(arg) = args.next() {
if arg == "-o" {
let opts = args.next().expect("found -o but missing opts");
let opts = opts.to_str().expect("non-utf8 opts").split(',');
for opt in opts {
@ -615,6 +638,7 @@ fn main() {
match opt {
"ro" => (),
"no_default_permissions" => default_permissions = false,
"no_daemon" | "no_fork" | "nodaemon" | "nofork" => fork_daemon = false,
"rw" => panic!("rw is not supported"),
opt => {
cmd_opts.push(',');
@ -631,9 +655,16 @@ fn main() {
if default_permissions && !cmd_opts.contains(",default_permissions,") {
cmd_opts.push_str(",default_permissions");
}
} else if count < pos_args.len() {
pos_args[count] = Some(arg);
count += 1
} else {
panic!("too many arguments");
}
}
let remote_dir = PathBuf::from(args.next().expect("missing dir"));
let mountpoint = args.next().expect("missing mountpoint");
let remote_dir = PathBuf::from(pos_args[0].as_ref().expect("missing dir"));
let mountpoint = pos_args[1].as_ref().expect("missing mountpoint");
let cache_dir = PathBuf::from(cache_dir);
debug!(
@ -649,6 +680,10 @@ fn main() {
let cmd_opts = OsString::from(cmd_opts);
let options = [OsStr::new("-o"), cmd_opts.as_os_str()];
if fork_daemon {
daemon();
}
#[allow(deprecated)]
fuser::mount(cache, mountpoint, &options).expect("mount failed");
}