use std::error::Error;
use std::path::PathBuf;
use birdcage::process::Command;
use birdcage::{Birdcage, Exception, Sandbox};
use clap::{Parser, ValueHint};
#[derive(Parser)]
#[clap(author, about)]
struct Cli {
#[clap(short = 'r', long, value_name = "PATH", value_hint = ValueHint::AnyPath)]
allow_read: Vec<PathBuf>,
#[clap(short = 'w', long, value_name = "PATH", value_hint = ValueHint::AnyPath)]
allow_write: Vec<PathBuf>,
#[clap(short = 'e', long, value_name = "PATH", value_hint = ValueHint::AnyPath)]
allow_execute: Vec<PathBuf>,
#[clap(long, value_name = "VAR")]
allow_env: Vec<String>,
#[clap(short = 'n', long)]
allow_networking: bool,
cmd: String,
#[clap(allow_hyphen_values = true, multiple_values = true)]
args: Vec<String>,
}
fn main() -> Result<(), Box<dyn Error>> {
let cli = Cli::parse();
let mut birdcage = Birdcage::new();
for path in cli.allow_read {
birdcage.add_exception(Exception::Read(path))?;
}
for path in cli.allow_write {
birdcage.add_exception(Exception::WriteAndRead(path))?;
}
for path in cli.allow_execute {
birdcage.add_exception(Exception::ExecuteAndRead(path))?;
}
for var in cli.allow_env {
birdcage.add_exception(Exception::Environment(var))?;
}
if cli.allow_networking {
birdcage.add_exception(Exception::Networking)?;
}
let mut command = Command::new(cli.cmd);
command.args(&cli.args);
let mut child = birdcage.spawn(command)?;
child.wait()?;
std::process::exit(0);
}