Simplified Cmd trait, trimmed 600K from binary size
This commit is contained in:
parent
76e7036da9
commit
a8c8ba5819
@ -8,26 +8,10 @@ use std::{
|
||||
};
|
||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Base32 {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Base32 {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "base32",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Base32;
|
||||
|
||||
impl Cmd for Base32 {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new("base32")
|
||||
.author("Nathan Fisher")
|
||||
@ -121,7 +105,7 @@ impl Cmd for Base32 {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,26 +8,10 @@ use std::{
|
||||
};
|
||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Base64 {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Base64 {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "base64",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Base64;
|
||||
|
||||
impl Cmd for Base64 {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> Command {
|
||||
Command::new("base64")
|
||||
.author("Nathan Fisher")
|
||||
@ -119,7 +103,7 @@ impl Cmd for Base64 {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +113,7 @@ fn decode_base64(mut contents: String, ignore: bool) -> Result<(), Box<dyn Error
|
||||
} else {
|
||||
contents = contents.replace('\n', "");
|
||||
}
|
||||
let decoded = BASE64.decode(&contents.as_bytes())?;
|
||||
let decoded = BASE64.decode(contents.as_bytes())?;
|
||||
let output = String::from_utf8(decoded)?;
|
||||
println!("{}\n", output.trim_end());
|
||||
Ok(())
|
||||
|
@ -2,28 +2,12 @@ use super::Cmd;
|
||||
use clap::{Arg, ArgMatches, Command};
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Basename {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Basename {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "basename",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Basename;
|
||||
|
||||
impl Cmd for Basename {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("basename")
|
||||
.about("Print NAME with any leading directory components removed.")
|
||||
.long_about(
|
||||
"Print NAME with any leading directory components removed.\n\
|
||||
@ -62,6 +46,6 @@ impl Cmd for Basename {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
@ -11,20 +11,8 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Bootstrap {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Bootstrap {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "bootstrap",
|
||||
path: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Bootstrap;
|
||||
|
||||
impl Bootstrap {
|
||||
fn all() -> clap::Command {
|
||||
@ -127,12 +115,8 @@ impl Bootstrap {
|
||||
}
|
||||
|
||||
impl Cmd for Bootstrap {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("bootstrap")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.author("Nathan Fisher")
|
||||
.about("Install shitbox into the filesystem")
|
||||
@ -212,7 +196,7 @@ impl Cmd for Bootstrap {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +209,8 @@ pub trait BootstrapCmd {
|
||||
|
||||
impl BootstrapCmd for dyn Cmd {
|
||||
fn completion(&self, outdir: &Path, gen: &str) -> Result<(), io::Error> {
|
||||
let name = self.name();
|
||||
let cmd = self.cli();
|
||||
let name = cmd.get_name();
|
||||
let mut cmd = self.cli();
|
||||
if !outdir.exists() {
|
||||
fs::create_dir_all(outdir)?;
|
||||
@ -249,7 +234,7 @@ impl BootstrapCmd for dyn Cmd {
|
||||
Some(p) => path.push(p.to_str(usr)),
|
||||
None => return None,
|
||||
}
|
||||
path.push(self.name());
|
||||
path.push(self.cli().get_name());
|
||||
Some(path)
|
||||
}
|
||||
|
||||
@ -289,7 +274,7 @@ impl BootstrapCmd for dyn Cmd {
|
||||
|
||||
fn manpage(&self, prefix: &str) -> Result<(), io::Error> {
|
||||
let command = self.cli();
|
||||
let fname = match self.name() {
|
||||
let fname = match command.get_name() {
|
||||
"bootstrap" => "shitbox-bootstrap.1".to_string(),
|
||||
s => format!("{s}.1"),
|
||||
};
|
||||
|
@ -5,10 +5,6 @@ use clap::Command;
|
||||
pub struct Clear;
|
||||
|
||||
impl Cmd for Clear {
|
||||
fn name(&self) -> &str {
|
||||
"clear"
|
||||
}
|
||||
|
||||
fn cli(&self) -> Command {
|
||||
Command::new("clear")
|
||||
.about("clear the terminal's screen")
|
||||
|
@ -2,26 +2,10 @@ use super::Cmd;
|
||||
use clap::{Arg, ArgAction, Command};
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Dirname {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Dirname {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "dirname",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Dirname;
|
||||
|
||||
impl Cmd for Dirname {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new("dirname")
|
||||
.about("strip last component from file name")
|
||||
@ -61,6 +45,6 @@ impl Cmd for Dirname {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,13 @@
|
||||
use super::Cmd;
|
||||
use crate::Path;
|
||||
use clap::{Arg, Command};
|
||||
use std::{env, error::Error};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Echo {
|
||||
name: &'static str,
|
||||
path: Option<Path>,
|
||||
}
|
||||
|
||||
impl Default for Echo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "echo",
|
||||
path: Some(crate::Path::Bin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Echo;
|
||||
|
||||
impl Cmd for Echo {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("echo")
|
||||
.about("Display a line of text")
|
||||
.long_about("Echo the STRING(s) to standard output")
|
||||
.author("Nathan Fisher")
|
||||
@ -39,7 +22,7 @@ impl Cmd for Echo {
|
||||
fn run(&self, _matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn Error>> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let idx = match crate::progname() {
|
||||
Some(s) if s.as_str() == self.name() => 1,
|
||||
Some(s) if s.as_str() == "echo" => 1,
|
||||
Some(_) => 2,
|
||||
None => unreachable!(),
|
||||
};
|
||||
@ -60,6 +43,6 @@ impl Cmd for Echo {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::Bin)
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,14 @@
|
||||
use crate::Cmd;
|
||||
use super::Cmd;
|
||||
use clap::{value_parser, Arg, ArgMatches, Command};
|
||||
use std::{
|
||||
error::Error,
|
||||
io::{self, BufRead},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Factor {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Factor {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "factor",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Factor;
|
||||
|
||||
impl Cmd for Factor {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> Command {
|
||||
Command::new("factor")
|
||||
.about("factor numbers")
|
||||
@ -59,7 +43,7 @@ impl Cmd for Factor {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,30 +1,13 @@
|
||||
use super::Cmd;
|
||||
use crate::Path;
|
||||
use clap::Command;
|
||||
use std::{error::Error, process};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct False {
|
||||
name: &'static str,
|
||||
path: Option<Path>,
|
||||
}
|
||||
|
||||
impl Default for False {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "false",
|
||||
path: Some(crate::Path::Bin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct False;
|
||||
|
||||
impl Cmd for False {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("false")
|
||||
.about("Does nothing unsuccessfully")
|
||||
.long_about("Exit with a status code indicating failure")
|
||||
.author("Nathan Fisher")
|
||||
@ -34,7 +17,7 @@ impl Cmd for False {
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<Path> {
|
||||
self.path
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
Some(crate::Path::Bin)
|
||||
}
|
||||
}
|
||||
|
@ -6,28 +6,12 @@ use std::{
|
||||
};
|
||||
use textwrap::{fill, wrap_algorithms::WrapAlgorithm};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Fold {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Fold {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "fold",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Fold;
|
||||
|
||||
impl Cmd for Fold {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> Command {
|
||||
Command::new(self.name)
|
||||
Command::new("fold")
|
||||
.about("Wrap each input line to fit in specified width")
|
||||
.author("Nathan Fisher")
|
||||
.after_long_help("With no FILE, or when FILE is -, read standard input")
|
||||
@ -84,12 +68,12 @@ impl Cmd for Fold {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_line(line: &str, args: &ArgMatches) {
|
||||
let width = args.get_one("WIDTH").map(|x| *x).unwrap_or(80);
|
||||
let width = args.get_one("WIDTH").map_or(80, |x| *x);
|
||||
if args.get_flag("OPTIMAL") {
|
||||
let line = line.replace('\t', " ");
|
||||
let opts = textwrap::Options::new(width).wrap_algorithm(WrapAlgorithm::new_optimal_fit());
|
||||
|
@ -7,10 +7,6 @@ use std::io;
|
||||
pub struct Groups;
|
||||
|
||||
impl Cmd for Groups {
|
||||
fn name(&self) -> &str {
|
||||
"groups"
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new("groups")
|
||||
.about("display current group names")
|
||||
|
@ -9,28 +9,12 @@ use std::{
|
||||
};
|
||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Head {
|
||||
name: &'static str,
|
||||
path: Option<Path>,
|
||||
}
|
||||
|
||||
impl Default for Head {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "head",
|
||||
path: Some(crate::Path::Bin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Head;
|
||||
|
||||
impl Cmd for Head {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> Command {
|
||||
Command::new(self.name)
|
||||
Command::new("head")
|
||||
.author("Nathan Fisher")
|
||||
.about("Display first lines of a file")
|
||||
.long_about(
|
||||
@ -133,7 +117,7 @@ impl Cmd for Head {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<Path> {
|
||||
self.path
|
||||
Some(crate::Path::Bin)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,14 @@
|
||||
use super::Cmd;
|
||||
use crate::Path;
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
use std::{error::Error, io};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Hostname {
|
||||
name: &'static str,
|
||||
path: Option<Path>,
|
||||
}
|
||||
|
||||
pub const HOSTNAME: Hostname = Hostname {
|
||||
name: "hostname",
|
||||
path: Some(Path::Bin),
|
||||
};
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Hostname;
|
||||
|
||||
impl Cmd for Hostname {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
.author("The JeanG3nie <jeang3nie@hitchhiker-linux.org>")
|
||||
Command::new("hostname")
|
||||
.author("Nathan Fisher")
|
||||
.about("Prints the name of the current host. The super-user can set the host name by supplying an argument.")
|
||||
.args([
|
||||
Arg::new("NAME")
|
||||
@ -62,6 +49,6 @@ impl Cmd for Hostname {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::Bin)
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,6 @@ use std::{fs, io};
|
||||
pub struct Link;
|
||||
|
||||
impl Cmd for Link {
|
||||
fn name(&self) -> &str {
|
||||
"link"
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new("link")
|
||||
.about("call the link function to create a link to a file")
|
||||
@ -29,23 +25,17 @@ impl Cmd for Link {
|
||||
let Some(matches) = matches else {
|
||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "no input")));
|
||||
};
|
||||
let f1 = match matches.get_one::<String>("file1") {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return Err(Box::new(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"missing file 1",
|
||||
)))
|
||||
}
|
||||
let Some(f1) = matches.get_one::<String>("file1") else {
|
||||
return Err(Box::new(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"missing file 1",
|
||||
)))
|
||||
};
|
||||
let f2 = match matches.get_one::<String>("file2") {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return Err(Box::new(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"missing file 2",
|
||||
)))
|
||||
}
|
||||
let Some(f2) = matches.get_one::<String>("file2") else {
|
||||
return Err(Box::new(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"missing file 2",
|
||||
)))
|
||||
};
|
||||
fs::hard_link(f1, f2)?;
|
||||
if matches.get_flag("verbose") {
|
||||
|
@ -48,12 +48,12 @@ pub use {
|
||||
};
|
||||
|
||||
pub trait Cmd: fmt::Debug + Sync {
|
||||
fn name(&self) -> &str;
|
||||
fn cli(&self) -> clap::Command;
|
||||
fn run(&self, matches: Option<&ArgMatches>) -> Result<(), Box<dyn Error>>;
|
||||
fn path(&self) -> Option<crate::Path>;
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||
match name {
|
||||
"base64" => Some(Box::new(Base64::default())),
|
||||
|
@ -9,28 +9,12 @@ use std::{
|
||||
process,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Mountpoint {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Mountpoint {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "mountpoint",
|
||||
path: Some(crate::Path::Bin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Mountpoint;
|
||||
|
||||
impl Cmd for Mountpoint {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("mountpoint")
|
||||
.about("see if a directory or file is a mountpoint")
|
||||
.author("Nathan Fisher")
|
||||
.after_long_help(
|
||||
@ -77,12 +61,11 @@ impl Cmd for Mountpoint {
|
||||
};
|
||||
let file = matches.get_one::<String>("file").unwrap();
|
||||
if matches.get_flag("fs-devno") {
|
||||
match fs_devno(file)? {
|
||||
Some(maj_min) => println!("{maj_min}"),
|
||||
None => {
|
||||
println!("{file} is not a mountpoint");
|
||||
process::exit(32);
|
||||
}
|
||||
if let Some(maj_min) = fs_devno(file)? {
|
||||
println!("{maj_min}");
|
||||
} else {
|
||||
println!("{file} is not a mountpoint");
|
||||
process::exit(32);
|
||||
}
|
||||
} else if matches.get_flag("devno") {
|
||||
let devno = devno(file)?;
|
||||
@ -94,18 +77,16 @@ impl Cmd for Mountpoint {
|
||||
println!("{file} is a mountpoint");
|
||||
}
|
||||
return Ok(());
|
||||
} else {
|
||||
if !matches.get_flag("quiet") {
|
||||
println!("{file} is not a mountpoint");
|
||||
}
|
||||
process::exit(32);
|
||||
} else if !matches.get_flag("quiet") {
|
||||
println!("{file} is not a mountpoint");
|
||||
}
|
||||
process::exit(32);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::Bin)
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +95,7 @@ fn is_mountpoint(path: &str) -> Result<bool, Box<dyn Error>> {
|
||||
let reader = BufReader::new(fd);
|
||||
for line in reader.lines() {
|
||||
let line = line?;
|
||||
if let Some(mntpt) = line.split_whitespace().skip(1).next() {
|
||||
if let Some(mntpt) = line.split_whitespace().nth(1) {
|
||||
if mntpt == path {
|
||||
return Ok(true);
|
||||
}
|
||||
@ -135,7 +116,7 @@ fn fs_devno(path: &str) -> Result<Option<String>, Box<dyn Error>> {
|
||||
let line = line?;
|
||||
let mut line = line.split_whitespace().skip(2);
|
||||
if let Some(maj_min) = line.next() {
|
||||
if let Some(mntpt) = line.skip(1).next() {
|
||||
if let Some(mntpt) = line.nth(1) {
|
||||
if mntpt == path {
|
||||
return Ok(Some(String::from(maj_min)));
|
||||
}
|
||||
|
@ -2,28 +2,12 @@ use super::Cmd;
|
||||
use clap::Command;
|
||||
use std::process;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Nologin {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Nologin {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "nologin",
|
||||
path: Some(crate::Path::Sbin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Nologin;
|
||||
|
||||
impl Cmd for Nologin {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("nologin")
|
||||
.author("Nathan Fisher")
|
||||
.about("Denies a user account login ability")
|
||||
}
|
||||
@ -34,6 +18,6 @@ impl Cmd for Nologin {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::Sbin)
|
||||
}
|
||||
}
|
||||
|
@ -2,28 +2,12 @@ use super::Cmd;
|
||||
use clap::{Arg, ArgAction, Command};
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Nproc {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Nproc {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "nproc",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Nproc;
|
||||
|
||||
impl Cmd for Nproc {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("nproc")
|
||||
.author("Nathan Fisher")
|
||||
.about("Print the number of processing units available")
|
||||
.arg(
|
||||
@ -48,6 +32,6 @@ impl Cmd for Nproc {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::Cmd;
|
||||
use super::Cmd;
|
||||
use clap::{Arg, ArgAction, Command};
|
||||
use std::{
|
||||
fs::File,
|
||||
@ -6,28 +6,12 @@ use std::{
|
||||
};
|
||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Rev {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Rev {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "rev",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Rev;
|
||||
|
||||
impl Cmd for Rev {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("rev")
|
||||
.about("reverse lines characterwise")
|
||||
.author("Nathan Fisher")
|
||||
.args([
|
||||
@ -82,7 +66,7 @@ impl Cmd for Rev {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,31 +6,10 @@ use std::{
|
||||
process,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Shitbox {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Shitbox {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "shitbox",
|
||||
path: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const SHITBOX: Shitbox = Shitbox {
|
||||
name: "shitbox",
|
||||
path: None,
|
||||
};
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Shitbox;
|
||||
|
||||
impl Cmd for Shitbox {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
let subcommands: Vec<Command> = {
|
||||
let mut s = vec![];
|
||||
@ -44,7 +23,7 @@ impl Cmd for Shitbox {
|
||||
}
|
||||
s
|
||||
};
|
||||
Command::new(self.name)
|
||||
Command::new("shitbox")
|
||||
.about("The box store multitool of embedded Linux")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.propagate_version(true)
|
||||
@ -70,6 +49,6 @@ impl Cmd for Shitbox {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,13 @@
|
||||
use super::Cmd;
|
||||
use crate::Path;
|
||||
use clap::{value_parser, Arg, ArgAction, ArgMatches, Command};
|
||||
use std::{env, error::Error, thread, time::Duration};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Sleep {
|
||||
name: &'static str,
|
||||
path: Option<Path>,
|
||||
}
|
||||
|
||||
impl Default for Sleep {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "sleep",
|
||||
path: Some(crate::Path::Bin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Sleep;
|
||||
|
||||
impl Cmd for Sleep {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("sleep")
|
||||
.about("Suspend execution for an interval of time")
|
||||
.long_about(
|
||||
"The sleep utility suspends execution for a minimum of the specified number of seconds.\n\
|
||||
@ -54,7 +37,7 @@ impl Cmd for Sleep {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<Path> {
|
||||
self.path
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
Some(crate::Path::Bin)
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,13 @@
|
||||
use super::Cmd;
|
||||
use crate::Path;
|
||||
use clap::Command;
|
||||
use std::{error::Error, process};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct True {
|
||||
name: &'static str,
|
||||
path: Option<Path>,
|
||||
}
|
||||
|
||||
impl Default for True {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "true",
|
||||
path: Some(crate::Path::Bin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct True;
|
||||
|
||||
impl Cmd for True {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("true")
|
||||
.about("Does nothing successfully")
|
||||
.long_about("Exit with a status code indicating success")
|
||||
.author("Nathan Fisher")
|
||||
@ -34,7 +17,7 @@ impl Cmd for True {
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<Path> {
|
||||
self.path
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
Some(crate::Path::Bin)
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,6 @@ use std::{env, fs::File, io, os::unix::prelude::MetadataExt, path::PathBuf, proc
|
||||
pub struct Which;
|
||||
|
||||
impl Cmd for Which {
|
||||
fn name(&self) -> &str {
|
||||
"which"
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new("which")
|
||||
.about("Write the full path of COMMAND(s) to standard output")
|
||||
@ -31,12 +27,11 @@ impl Cmd for Which {
|
||||
let mut failures = 0;
|
||||
if let Some(commands) = matches.get_many::<String>("COMMAND") {
|
||||
for command in commands {
|
||||
match which(command, &path) {
|
||||
Some(p) => println!("{p}"),
|
||||
None => {
|
||||
println!("{}: no {} in ({})", self.name(), command, &rawpath);
|
||||
failures += 1;
|
||||
}
|
||||
if let Some(p) = which(command, &path) {
|
||||
println!("{p}");
|
||||
} else {
|
||||
println!("which: no {} in ({})", command, &rawpath);
|
||||
failures += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1,19 +1,14 @@
|
||||
use std::ffi::CStr;
|
||||
|
||||
use {
|
||||
super::Cmd,
|
||||
clap::Command,
|
||||
libc::{geteuid, getpwuid},
|
||||
std::ffi::CStr,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Whoami;
|
||||
|
||||
impl Cmd for Whoami {
|
||||
fn name(&self) -> &str {
|
||||
"whoami"
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new("whoami")
|
||||
.about("print effective user name")
|
||||
|
@ -2,28 +2,12 @@ use super::Cmd;
|
||||
use clap::{Arg, Command};
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Yes {
|
||||
name: &'static str,
|
||||
path: Option<crate::Path>,
|
||||
}
|
||||
|
||||
impl Default for Yes {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "yes",
|
||||
path: Some(crate::Path::UsrBin),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Yes;
|
||||
|
||||
impl Cmd for Yes {
|
||||
fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn cli(&self) -> clap::Command {
|
||||
Command::new(self.name)
|
||||
Command::new("yes")
|
||||
.about("output a string repeatedly until killed")
|
||||
.author("Nathan Fisher")
|
||||
.arg(Arg::new("msg").num_args(1).default_value("y"))
|
||||
@ -40,6 +24,6 @@ impl Cmd for Yes {
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<crate::Path> {
|
||||
self.path
|
||||
Some(crate::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,13 @@ pub enum Path {
|
||||
}
|
||||
|
||||
impl Path {
|
||||
#[must_use]
|
||||
pub fn to_str(&self, usr: bool) -> &'static str {
|
||||
match self {
|
||||
Self::Bin => "bin",
|
||||
Self::UsrBin if usr => "usr/bin",
|
||||
Self::UsrBin => "bin",
|
||||
Self::Sbin => "sbin",
|
||||
Self::UsrSbin if usr => "usr/sbin",
|
||||
Self::UsrSbin => "sbin",
|
||||
Self::Bin | Self::UsrBin => "bin",
|
||||
Self::Sbin | Self::UsrSbin => "sbin",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,35 +25,28 @@ pub fn get_eusername<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||
}
|
||||
|
||||
pub fn get_uid_for_name(name: &str) -> Option<u32> {
|
||||
let user = match CString::new(name.as_bytes()) {
|
||||
Ok(n) => n,
|
||||
Err(_) => return None,
|
||||
};
|
||||
let uid = unsafe {
|
||||
let Ok(user) = CString::new(name.as_bytes()) else { return None };
|
||||
unsafe {
|
||||
let pw = libc::getpwnam(user.as_ptr());
|
||||
if pw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some((*pw).pw_uid)
|
||||
}
|
||||
};
|
||||
uid
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_pgid_for_name(name: &str) -> Option<u32> {
|
||||
let user = match CString::new(name.as_bytes()) {
|
||||
Ok(n) => n,
|
||||
Err(_) => return None,
|
||||
};
|
||||
let gid = unsafe {
|
||||
let Ok(user) = CString::new(name.as_bytes()) else { return None };
|
||||
unsafe {
|
||||
let pw = libc::getpwnam(user.as_ptr());
|
||||
if pw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some((*pw).pw_gid)
|
||||
}
|
||||
};
|
||||
gid
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_grpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||
@ -89,6 +82,7 @@ pub fn get_gids() -> Result<Vec<u32>, num::TryFromIntError> {
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
pub fn get_gids_for_name(name: &str) -> Result<Vec<u32>, Box<dyn Error>> {
|
||||
let gid = match get_pgid_for_name(name) {
|
||||
Some(g) => g as libc::gid_t,
|
||||
@ -111,7 +105,7 @@ pub fn get_gids_for_name(name: &str) -> Result<Vec<u32>, Box<dyn Error>> {
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(buf[0..ct as usize].iter().map(|x| *x as u32).collect())
|
||||
Ok(buf[0..ct as usize].to_vec())
|
||||
}
|
||||
|
||||
pub fn get_group_names() -> Result<Vec<String>, Box<dyn Error>> {
|
||||
|
Loading…
Reference in New Issue
Block a user