Add chroot
applet
This commit is contained in:
parent
eeb9a61fa3
commit
862ad82b47
@ -24,6 +24,7 @@ code between applets, making for an overall smaller binary.
|
|||||||
- chgrp
|
- chgrp
|
||||||
- chmod
|
- chmod
|
||||||
- chown
|
- chown
|
||||||
|
- chroot
|
||||||
- clear
|
- clear
|
||||||
- cut
|
- cut
|
||||||
- dirname
|
- dirname
|
||||||
@ -35,6 +36,7 @@ code between applets, making for an overall smaller binary.
|
|||||||
- head
|
- head
|
||||||
- hostname
|
- hostname
|
||||||
- link
|
- link
|
||||||
|
- logname
|
||||||
- mkfifo
|
- mkfifo
|
||||||
- mknod
|
- mknod
|
||||||
- mountpoint
|
- mountpoint
|
||||||
|
71
src/cmd/chroot/mod.rs
Normal file
71
src/cmd/chroot/mod.rs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
use super::Cmd;
|
||||||
|
use clap::{Arg, Command};
|
||||||
|
use std::{
|
||||||
|
env, io,
|
||||||
|
os::unix::{fs, process::CommandExt},
|
||||||
|
process,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Chroot;
|
||||||
|
|
||||||
|
impl Cmd for Chroot {
|
||||||
|
fn cli(&self) -> clap::Command {
|
||||||
|
Command::new("chroot")
|
||||||
|
.about("run command or interactive shell with special root directory")
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.args([
|
||||||
|
Arg::new("dir")
|
||||||
|
.short('d')
|
||||||
|
.long("directory")
|
||||||
|
.help("change to this directory after performing the chroot instead of '/'")
|
||||||
|
.value_name("DIRECTORY"),
|
||||||
|
Arg::new("newroot")
|
||||||
|
.value_name("NEWROOT")
|
||||||
|
.num_args(1)
|
||||||
|
.required(true),
|
||||||
|
Arg::new("command")
|
||||||
|
.value_name("COMMAND")
|
||||||
|
.num_args(1)
|
||||||
|
.required(false),
|
||||||
|
Arg::new("arg")
|
||||||
|
.value_name("ARG")
|
||||||
|
.num_args(1..)
|
||||||
|
.requires("command")
|
||||||
|
.allow_hyphen_values(true)
|
||||||
|
.required(false),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let Some(matches) = matches else {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, "no input").into());
|
||||||
|
};
|
||||||
|
let Some(newroot) = matches.get_one::<String>("newroot") else {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, "no new root given").into());
|
||||||
|
};
|
||||||
|
let mut command = if let Some(c) = matches.get_one::<String>("command") {
|
||||||
|
process::Command::new(c)
|
||||||
|
} else if let Ok(s) = env::var("SHELL") {
|
||||||
|
process::Command::new(s)
|
||||||
|
} else {
|
||||||
|
process::Command::new("/bin/sh")
|
||||||
|
};
|
||||||
|
let mut command = &mut command;
|
||||||
|
if let Some(mut args) = matches.get_many::<String>("arg") {
|
||||||
|
command = command.args(&mut args);
|
||||||
|
}
|
||||||
|
fs::chroot(newroot)?;
|
||||||
|
if let Some(d) = matches.get_one::<String>("dir") {
|
||||||
|
env::set_current_dir(d)?;
|
||||||
|
} else {
|
||||||
|
env::set_current_dir("/")?;
|
||||||
|
}
|
||||||
|
return Err(command.exec().into());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<crate::Path> {
|
||||||
|
Some(crate::Path::UsrSbin)
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ mod bootstrap;
|
|||||||
mod cat;
|
mod cat;
|
||||||
mod chmod;
|
mod chmod;
|
||||||
mod chown;
|
mod chown;
|
||||||
|
mod chroot;
|
||||||
mod clear;
|
mod clear;
|
||||||
mod cp;
|
mod cp;
|
||||||
mod cut;
|
mod cut;
|
||||||
@ -72,6 +73,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
"chmod" => Some(Box::new(chmod::Chmod::default())),
|
"chmod" => Some(Box::new(chmod::Chmod::default())),
|
||||||
"chgrp" => Some(Box::new(chown::Chgrp::default())),
|
"chgrp" => Some(Box::new(chown::Chgrp::default())),
|
||||||
"chown" => Some(Box::new(chown::Chown::default())),
|
"chown" => Some(Box::new(chown::Chown::default())),
|
||||||
|
"chroot" => Some(Box::new(chroot::Chroot::default())),
|
||||||
"clear" => Some(Box::new(clear::Clear::default())),
|
"clear" => Some(Box::new(clear::Clear::default())),
|
||||||
"cut" => Some(Box::new(cut::Cut::default())),
|
"cut" => Some(Box::new(cut::Cut::default())),
|
||||||
"dirname" => Some(Box::new(dirname::Dirname::default())),
|
"dirname" => Some(Box::new(dirname::Dirname::default())),
|
||||||
@ -105,7 +107,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COMMANDS: [&str; 37] = [
|
pub static COMMANDS: [&str; 38] = [
|
||||||
"base32",
|
"base32",
|
||||||
"base64",
|
"base64",
|
||||||
"basename",
|
"basename",
|
||||||
@ -113,6 +115,7 @@ pub static COMMANDS: [&str; 37] = [
|
|||||||
"chgrp",
|
"chgrp",
|
||||||
"chmod",
|
"chmod",
|
||||||
"chown",
|
"chown",
|
||||||
|
"chroot",
|
||||||
"clear",
|
"clear",
|
||||||
"cut",
|
"cut",
|
||||||
"dirname",
|
"dirname",
|
||||||
|
Loading…
Reference in New Issue
Block a user