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