Added doc comments

This commit is contained in:
Nathan Fisher 2023-01-14 10:36:08 -05:00
parent b401aaad47
commit c6e162ebc8
6 changed files with 119 additions and 30 deletions

1
src/chmod/mod.rs Normal file
View File

@ -0,0 +1 @@
//! Functions for parsing and managing permissions

View File

@ -1,44 +1,45 @@
use clap::ArgMatches;
use std::{error::Error, fmt};
pub mod base32;
pub mod base64;
pub mod basename;
pub mod bootstrap;
mod base32;
mod base64;
mod basename;
mod bootstrap;
mod cat;
mod chmod;
pub mod clear;
mod clear;
mod cp;
pub mod cut;
mod cut;
mod date;
mod dd;
pub mod dirname;
pub mod echo;
pub mod factor;
pub mod r#false;
pub mod fold;
mod dirname;
mod echo;
mod factor;
mod r#false;
mod fold;
mod getty;
pub mod groups;
pub mod head;
pub mod hostname;
pub mod link;
mod groups;
mod head;
mod hostname;
mod link;
mod ln;
mod ls;
pub mod mountpoint;
mod mountpoint;
mod mv;
pub mod nologin;
pub mod nproc;
mod nologin;
mod nproc;
mod pwd;
pub mod rev;
mod rev;
mod rm;
mod rmdir;
pub mod shitbox;
pub mod sleep;
pub mod sync;
pub mod r#true;
pub mod which;
pub mod whoami;
pub mod yes;
mod shitbox;
mod sleep;
mod sync;
mod r#true;
mod unlink;
mod which;
mod whoami;
mod yes;
#[allow(clippy::module_name_repetitions)]
pub use {
@ -46,15 +47,24 @@ pub use {
bootstrap::Bootstrap, clear::Clear, cut::Cut, dirname::Dirname, echo::Echo, factor::Factor,
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,
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 {
/// Defines the cli of the applet
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>>;
/// Returns the path relative to the binary where the link to this applet
/// will be installed
fn path(&self) -> Option<crate::Path>;
}
/// Parses a string into a command to run
#[must_use]
#[allow(clippy::box_default)]
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())),
"sync" => Some(Box::new(SyncCmd::default())),
"true" => Some(Box::new(True::default())),
"unlink" => Some(Box::new(Unlink::default())),
"which" => Some(Box::new(Which::default())),
"whoami" => Some(Box::new(Whoami::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",
"base64",
"basename",
@ -112,6 +123,7 @@ pub static COMMANDS: [&str; 26] = [
"shitbox",
"sync",
"true",
"unlink",
"which",
"whoami",
"yes",

50
src/cmd/unlink/mod.rs Normal file
View 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)
}
}

View File

@ -1,17 +1,22 @@
#![warn(clippy::all, clippy::pedantic)]
use std::{env, path::PathBuf, process, string::ToString};
pub mod cmd;
pub mod chmod;
mod cmd;
pub use cmd::Cmd;
pub mod math;
/// User and group related functionality
pub mod pw;
/// Defines the location relative to the binary where a command will be installed
#[derive(Debug, Clone, Copy)]
pub enum Path {
/// /bin
Bin,
/// /sbin
Sbin,
/// /usr/bin
UsrBin,
/// /usr/sbin
UsrSbin,
}
@ -27,6 +32,7 @@ impl Path {
}
}
/// Returns the basename of the command as it was called
#[must_use]
pub fn progname() -> Option<String> {
env::args()
@ -39,6 +45,9 @@ pub fn progname() -> Option<String> {
.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]
pub fn progpath() -> Option<PathBuf> {
match progname() {
@ -47,6 +56,7 @@ pub fn progpath() -> Option<PathBuf> {
}
}
/// The entry point of the program
pub fn run() {
if let Some(progname) = progname() {
if let Some(command) = cmd::get(&progname) {

View File

@ -1,3 +1,4 @@
//! Math related functions not included in std
#[must_use]
pub fn is_prime(num: u64) -> bool {
match num {

View File

@ -1,9 +1,13 @@
//! Wraps certain libc functions around groups and users
use std::{
error::Error,
ffi::{c_int, CStr, CString},
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> {
let user = unsafe {
let uid = libc::getuid();
@ -14,6 +18,9 @@ pub fn get_username<'a>() -> Result<&'a str, std::str::Utf8Error> {
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> {
let user = unsafe {
let uid = libc::geteuid();
@ -24,6 +31,7 @@ pub fn get_eusername<'a>() -> Result<&'a str, std::str::Utf8Error> {
user.to_str()
}
/// Gets the uid associated with the given name
#[must_use]
pub fn get_uid_for_name(name: &str) -> Option<u32> {
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]
pub fn get_pgid_for_name(name: &str) -> Option<u32> {
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> {
let group = unsafe {
let gid = libc::getgid();
@ -60,6 +72,9 @@ pub fn get_grpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
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> {
let group = unsafe {
let gid = libc::getegid();