Added doc comments
This commit is contained in:
parent
b401aaad47
commit
c6e162ebc8
1
src/chmod/mod.rs
Normal file
1
src/chmod/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
//! Functions for parsing and managing permissions
|
@ -1,44 +1,45 @@
|
|||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use std::{error::Error, fmt};
|
use std::{error::Error, fmt};
|
||||||
|
|
||||||
pub mod base32;
|
mod base32;
|
||||||
pub mod base64;
|
mod base64;
|
||||||
pub mod basename;
|
mod basename;
|
||||||
pub mod bootstrap;
|
mod bootstrap;
|
||||||
mod cat;
|
mod cat;
|
||||||
mod chmod;
|
mod chmod;
|
||||||
pub mod clear;
|
mod clear;
|
||||||
mod cp;
|
mod cp;
|
||||||
pub mod cut;
|
mod cut;
|
||||||
mod date;
|
mod date;
|
||||||
mod dd;
|
mod dd;
|
||||||
pub mod dirname;
|
mod dirname;
|
||||||
pub mod echo;
|
mod echo;
|
||||||
pub mod factor;
|
mod factor;
|
||||||
pub mod r#false;
|
mod r#false;
|
||||||
pub mod fold;
|
mod fold;
|
||||||
mod getty;
|
mod getty;
|
||||||
pub mod groups;
|
mod groups;
|
||||||
pub mod head;
|
mod head;
|
||||||
pub mod hostname;
|
mod hostname;
|
||||||
pub mod link;
|
mod link;
|
||||||
mod ln;
|
mod ln;
|
||||||
mod ls;
|
mod ls;
|
||||||
pub mod mountpoint;
|
mod mountpoint;
|
||||||
mod mv;
|
mod mv;
|
||||||
pub mod nologin;
|
mod nologin;
|
||||||
pub mod nproc;
|
mod nproc;
|
||||||
mod pwd;
|
mod pwd;
|
||||||
pub mod rev;
|
mod rev;
|
||||||
mod rm;
|
mod rm;
|
||||||
mod rmdir;
|
mod rmdir;
|
||||||
pub mod shitbox;
|
mod shitbox;
|
||||||
pub mod sleep;
|
mod sleep;
|
||||||
pub mod sync;
|
mod sync;
|
||||||
pub mod r#true;
|
mod r#true;
|
||||||
pub mod which;
|
mod unlink;
|
||||||
pub mod whoami;
|
mod which;
|
||||||
pub mod yes;
|
mod whoami;
|
||||||
|
mod yes;
|
||||||
|
|
||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
pub use {
|
pub use {
|
||||||
@ -46,15 +47,24 @@ pub use {
|
|||||||
bootstrap::Bootstrap, clear::Clear, cut::Cut, dirname::Dirname, echo::Echo, factor::Factor,
|
bootstrap::Bootstrap, clear::Clear, cut::Cut, dirname::Dirname, echo::Echo, factor::Factor,
|
||||||
fold::Fold, groups::Groups, head::Head, link::Link, mountpoint::Mountpoint, nologin::Nologin,
|
fold::Fold, groups::Groups, head::Head, link::Link, mountpoint::Mountpoint, nologin::Nologin,
|
||||||
nproc::Nproc, r#false::False, r#true::True, rev::Rev, shitbox::Shitbox, sleep::Sleep,
|
nproc::Nproc, r#false::False, r#true::True, rev::Rev, shitbox::Shitbox, sleep::Sleep,
|
||||||
sync::Sync as SyncCmd, which::Which, whoami::Whoami, yes::Yes,
|
sync::Sync as SyncCmd, unlink::Unlink, which::Which, whoami::Whoami, yes::Yes,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Defines a command or applet, it's cli interface, and it's installation directory
|
||||||
|
/// relative to the binary
|
||||||
pub trait Cmd: fmt::Debug + Sync {
|
pub trait Cmd: fmt::Debug + Sync {
|
||||||
|
/// Defines the cli of the applet
|
||||||
fn cli(&self) -> clap::Command;
|
fn cli(&self) -> clap::Command;
|
||||||
|
/// Runs the applet
|
||||||
|
/// # Errors
|
||||||
|
/// Bubbles up any errors to the caller
|
||||||
fn run(&self, matches: Option<&ArgMatches>) -> Result<(), Box<dyn Error>>;
|
fn run(&self, matches: Option<&ArgMatches>) -> Result<(), Box<dyn Error>>;
|
||||||
|
/// Returns the path relative to the binary where the link to this applet
|
||||||
|
/// will be installed
|
||||||
fn path(&self) -> Option<crate::Path>;
|
fn path(&self) -> Option<crate::Path>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses a string into a command to run
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(clippy::box_default)]
|
#[allow(clippy::box_default)]
|
||||||
pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||||
@ -81,6 +91,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
"sleep" => Some(Box::new(Sleep::default())),
|
"sleep" => Some(Box::new(Sleep::default())),
|
||||||
"sync" => Some(Box::new(SyncCmd::default())),
|
"sync" => Some(Box::new(SyncCmd::default())),
|
||||||
"true" => Some(Box::new(True::default())),
|
"true" => Some(Box::new(True::default())),
|
||||||
|
"unlink" => Some(Box::new(Unlink::default())),
|
||||||
"which" => Some(Box::new(Which::default())),
|
"which" => Some(Box::new(Which::default())),
|
||||||
"whoami" => Some(Box::new(Whoami::default())),
|
"whoami" => Some(Box::new(Whoami::default())),
|
||||||
"yes" => Some(Box::new(Yes::default())),
|
"yes" => Some(Box::new(Yes::default())),
|
||||||
@ -88,7 +99,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COMMANDS: [&str; 26] = [
|
pub static COMMANDS: [&str; 27] = [
|
||||||
"base32",
|
"base32",
|
||||||
"base64",
|
"base64",
|
||||||
"basename",
|
"basename",
|
||||||
@ -112,6 +123,7 @@ pub static COMMANDS: [&str; 26] = [
|
|||||||
"shitbox",
|
"shitbox",
|
||||||
"sync",
|
"sync",
|
||||||
"true",
|
"true",
|
||||||
|
"unlink",
|
||||||
"which",
|
"which",
|
||||||
"whoami",
|
"whoami",
|
||||||
"yes",
|
"yes",
|
||||||
|
50
src/cmd/unlink/mod.rs
Normal file
50
src/cmd/unlink/mod.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use clap::{Arg, ArgAction, Command};
|
||||||
|
use std::{io, ffi::CString, process};
|
||||||
|
use super::Cmd;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Unlink;
|
||||||
|
|
||||||
|
impl Cmd for Unlink {
|
||||||
|
fn cli(&self) -> clap::Command {
|
||||||
|
Command::new("unlink")
|
||||||
|
.about("call the unlink function to remove the specified file")
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.args([
|
||||||
|
Arg::new("verbose")
|
||||||
|
.help("display user feedback upon success")
|
||||||
|
.short('v')
|
||||||
|
.long("verbose")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("file")
|
||||||
|
.value_name("FILE")
|
||||||
|
.required(true)
|
||||||
|
.num_args(1..),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let Some(matches) = matches else {
|
||||||
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "no input")));
|
||||||
|
};
|
||||||
|
if let Some(files) = matches.get_many::<String>("file") {
|
||||||
|
for f in files {
|
||||||
|
let fname = CString::new(f.as_str())?;
|
||||||
|
let ret = unsafe { libc::unlink(fname.as_ptr()) };
|
||||||
|
if matches.get_flag("verbose") && ret == 0 {
|
||||||
|
println!("unlink: {f}");
|
||||||
|
} else if ret != 0 {
|
||||||
|
let err = io::Error::last_os_error();
|
||||||
|
eprintln!("unlink: cannot unlink {f}: {err}");
|
||||||
|
process::exit(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<crate::Path> {
|
||||||
|
Some(crate::Path::UsrBin)
|
||||||
|
}
|
||||||
|
}
|
14
src/lib.rs
14
src/lib.rs
@ -1,17 +1,22 @@
|
|||||||
#![warn(clippy::all, clippy::pedantic)]
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
use std::{env, path::PathBuf, process, string::ToString};
|
use std::{env, path::PathBuf, process, string::ToString};
|
||||||
|
|
||||||
pub mod cmd;
|
pub mod chmod;
|
||||||
|
mod cmd;
|
||||||
pub use cmd::Cmd;
|
pub use cmd::Cmd;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
/// User and group related functionality
|
|
||||||
pub mod pw;
|
pub mod pw;
|
||||||
|
|
||||||
|
/// Defines the location relative to the binary where a command will be installed
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Path {
|
pub enum Path {
|
||||||
|
/// /bin
|
||||||
Bin,
|
Bin,
|
||||||
|
/// /sbin
|
||||||
Sbin,
|
Sbin,
|
||||||
|
/// /usr/bin
|
||||||
UsrBin,
|
UsrBin,
|
||||||
|
/// /usr/sbin
|
||||||
UsrSbin,
|
UsrSbin,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +32,7 @@ impl Path {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the basename of the command as it was called
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn progname() -> Option<String> {
|
pub fn progname() -> Option<String> {
|
||||||
env::args()
|
env::args()
|
||||||
@ -39,6 +45,9 @@ pub fn progname() -> Option<String> {
|
|||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the path to the binary, if called as "shitbox". Used in the bootstrap
|
||||||
|
/// applet to find the binary location in order to install it into it's permanent
|
||||||
|
/// location
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn progpath() -> Option<PathBuf> {
|
pub fn progpath() -> Option<PathBuf> {
|
||||||
match progname() {
|
match progname() {
|
||||||
@ -47,6 +56,7 @@ pub fn progpath() -> Option<PathBuf> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The entry point of the program
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
if let Some(progname) = progname() {
|
if let Some(progname) = progname() {
|
||||||
if let Some(command) = cmd::get(&progname) {
|
if let Some(command) = cmd::get(&progname) {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//! Math related functions not included in std
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_prime(num: u64) -> bool {
|
pub fn is_prime(num: u64) -> bool {
|
||||||
match num {
|
match num {
|
@ -1,9 +1,13 @@
|
|||||||
|
//! Wraps certain libc functions around groups and users
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
ffi::{c_int, CStr, CString},
|
ffi::{c_int, CStr, CString},
|
||||||
io, num,
|
io, num,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Gets the current username of this process
|
||||||
|
/// # Errors
|
||||||
|
/// The user name must be valid utf8
|
||||||
pub fn get_username<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
pub fn get_username<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||||
let user = unsafe {
|
let user = unsafe {
|
||||||
let uid = libc::getuid();
|
let uid = libc::getuid();
|
||||||
@ -14,6 +18,9 @@ pub fn get_username<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
|||||||
user.to_str()
|
user.to_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the current effective user name of this process
|
||||||
|
/// # Errors
|
||||||
|
/// The user name must be valid utf8
|
||||||
pub fn get_eusername<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
pub fn get_eusername<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||||
let user = unsafe {
|
let user = unsafe {
|
||||||
let uid = libc::geteuid();
|
let uid = libc::geteuid();
|
||||||
@ -24,6 +31,7 @@ pub fn get_eusername<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
|||||||
user.to_str()
|
user.to_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the uid associated with the given name
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_uid_for_name(name: &str) -> Option<u32> {
|
pub fn get_uid_for_name(name: &str) -> Option<u32> {
|
||||||
let Ok(user) = CString::new(name.as_bytes()) else { return None };
|
let Ok(user) = CString::new(name.as_bytes()) else { return None };
|
||||||
@ -37,6 +45,7 @@ pub fn get_uid_for_name(name: &str) -> Option<u32> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the gid for the main group associated with the given user
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_pgid_for_name(name: &str) -> Option<u32> {
|
pub fn get_pgid_for_name(name: &str) -> Option<u32> {
|
||||||
let Ok(user) = CString::new(name.as_bytes()) else { return None };
|
let Ok(user) = CString::new(name.as_bytes()) else { return None };
|
||||||
@ -50,6 +59,9 @@ pub fn get_pgid_for_name(name: &str) -> Option<u32> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the main group name for the current process
|
||||||
|
/// # Errors
|
||||||
|
/// The name must be valid utf8
|
||||||
pub fn get_grpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
pub fn get_grpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||||
let group = unsafe {
|
let group = unsafe {
|
||||||
let gid = libc::getgid();
|
let gid = libc::getgid();
|
||||||
@ -60,6 +72,9 @@ pub fn get_grpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
|||||||
group.to_str()
|
group.to_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the effective group for the current process
|
||||||
|
/// # Errors
|
||||||
|
/// The name must be valid utf8
|
||||||
pub fn get_egrpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
pub fn get_egrpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||||
let group = unsafe {
|
let group = unsafe {
|
||||||
let gid = libc::getegid();
|
let gid = libc::getegid();
|
||||||
|
Loading…
Reference in New Issue
Block a user