Add df
applet; Finalize some bootstrap details;
This commit is contained in:
parent
888cc3272b
commit
5a7c2008b5
41
Cargo.lock
generated
41
Cargo.lock
generated
@ -78,9 +78,9 @@ version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127"
|
||||
checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
@ -169,9 +169,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.4"
|
||||
version = "4.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
|
||||
checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
@ -182,11 +182,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.1.1"
|
||||
version = "4.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6540eedc41f8a5a76cf3d8d458057dcdf817be4158a55b5f861f7a5483de75"
|
||||
checksum = "bd125be87bf4c255ebc50de0b7f4d2a6201e8ac3dc86e39c0ad081dc5e7236fe"
|
||||
dependencies = [
|
||||
"clap 4.1.4",
|
||||
"clap 4.1.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -195,7 +195,7 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fa41f5e6aa83bd151b70fd0ceaee703d68cd669522795dc812df9edad1252c"
|
||||
dependencies = [
|
||||
"clap 4.1.4",
|
||||
"clap 4.1.6",
|
||||
"clap_complete",
|
||||
]
|
||||
|
||||
@ -210,19 +210,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_mangen"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb258c6232b4d728d13d6072656627924c16707aae6267cd5a1ea05abff9a25c"
|
||||
checksum = "48283ce8d5cd9513633949a674a0442bcb507ab61ed6533863437052ddbb494b"
|
||||
dependencies = [
|
||||
"clap 4.1.4",
|
||||
"clap 4.1.6",
|
||||
"roff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
@ -333,9 +333,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01"
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
@ -359,7 +359,7 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.0",
|
||||
"hermit-abi 0.3.1",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
@ -578,7 +578,7 @@ dependencies = [
|
||||
"atty",
|
||||
"bitflags-mini",
|
||||
"blake2b_simd",
|
||||
"clap 4.1.4",
|
||||
"clap 4.1.6",
|
||||
"clap_complete",
|
||||
"clap_complete_nushell",
|
||||
"clap_mangen",
|
||||
@ -593,6 +593,7 @@ dependencies = [
|
||||
"sc",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"size-display",
|
||||
"termcolor",
|
||||
"textwrap 0.16.0",
|
||||
"unistd",
|
||||
@ -606,6 +607,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||
|
||||
[[package]]
|
||||
name = "size-display"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9df415f09e1c4d4f58cd0cd08b2f5385bc07cf1878e7a7846abc2225fa00e1e1"
|
||||
|
||||
[[package]]
|
||||
name = "smawk"
|
||||
version = "0.3.1"
|
||||
|
@ -37,6 +37,7 @@ md5 = { version = "0.10", package = "md-5" }
|
||||
sc = { workspace = true }
|
||||
sha1 = "0.10"
|
||||
sha2 = "0.10"
|
||||
size-display = "0.1"
|
||||
termcolor = "1.1"
|
||||
textwrap = { version = "0.16", default-features = false, features = ["smawk"] }
|
||||
walkdir = "2.3"
|
||||
|
@ -27,6 +27,7 @@ code between applets, making for an overall smaller binary.
|
||||
- chroot
|
||||
- clear
|
||||
- cut
|
||||
- df
|
||||
- dirname
|
||||
- echo
|
||||
- false
|
||||
|
@ -395,4 +395,3 @@ fn links(prefix: &str, usr: bool, cmd: &ArgMatches) -> Result<(), Box<dyn Error>
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
150
corebox/commands/df/mod.rs
Normal file
150
corebox/commands/df/mod.rs
Normal file
@ -0,0 +1,150 @@
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
use mount::MntEntries;
|
||||
use shitbox::Cmd;
|
||||
use size_display::Size;
|
||||
use std::{error::Error, fmt, io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Df;
|
||||
|
||||
impl Cmd for Df {
|
||||
fn cli(&self) -> Command {
|
||||
Command::new("df")
|
||||
.about("report free disk space")
|
||||
.author("Nathan Fisher")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.disable_help_flag(true)
|
||||
.args([
|
||||
Arg::new("kilobytes")
|
||||
.help("Use 1024-byte units, instead of the default 512-byte units, when writing space figures.")
|
||||
.short('k')
|
||||
.long("kilobytes")
|
||||
.action(ArgAction::SetTrue),
|
||||
Arg::new("human")
|
||||
.help("print sizes in powers of 1024 (e.g., 1023M)")
|
||||
.short('h')
|
||||
.long("human-readable")
|
||||
.conflicts_with("kilobytes")
|
||||
.action(ArgAction::SetTrue),
|
||||
Arg::new("file")
|
||||
.value_name("FILE")
|
||||
.num_args(1..)
|
||||
])
|
||||
}
|
||||
|
||||
fn run(&self, matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||
let units = if matches.get_flag("kilobytes") {
|
||||
Units::Kilo
|
||||
} else if matches.get_flag("human") {
|
||||
Units::Natural
|
||||
} else {
|
||||
Units::Posix
|
||||
};
|
||||
println!("Filesystem {units} Used Avail Capacity Mounted on");
|
||||
if let Some(files) = matches.get_many::<String>("file") {
|
||||
for f in files {
|
||||
let entry = MntEntries::new("/proc/mounts")?
|
||||
.filter(|e| e.dir.as_str() == f)
|
||||
.next()
|
||||
.ok_or(io::Error::new(io::ErrorKind::Other, "no such filesystem"))?;
|
||||
print_stats(&entry.fsname, &entry.dir, units)?;
|
||||
}
|
||||
} else {
|
||||
let entries = MntEntries::new("/proc/mounts")?.filter(|x| {
|
||||
x.fstype != "proc"
|
||||
&& x.fstype != "sysfs"
|
||||
&& x.fstype != "securityfs"
|
||||
&& x.fstype != "cgroup2"
|
||||
&& x.fstype != "pstore"
|
||||
&& x.fstype != "bpf"
|
||||
&& x.fstype != "autofs"
|
||||
&& x.fstype != "hugetlbfs"
|
||||
&& x.fstype != "tracefs"
|
||||
&& x.fstype != "debugfs"
|
||||
&& x.fstype != "configfs"
|
||||
&& x.fstype != "devpts"
|
||||
&& x.fstype != "efivarfs"
|
||||
&& x.fstype != "ramfs"
|
||||
&& x.fstype != "binfmt_misc"
|
||||
&& x.fstype != "fuse.gvfsd-fuse"
|
||||
&& x.fstype != "fuse.portal"
|
||||
&& x.fstype != "mqueue"
|
||||
&& x.fstype != "fusectl"
|
||||
});
|
||||
for e in entries {
|
||||
print_stats(&e.fsname, &e.dir, units)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<shitbox::Path> {
|
||||
Some(shitbox::Path::UsrBin)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
enum Units {
|
||||
Posix,
|
||||
Kilo,
|
||||
Natural,
|
||||
}
|
||||
|
||||
impl fmt::Display for Units {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Posix => write!(f, "512-blocks"),
|
||||
Self::Kilo => write!(f, " 1K-blocks"),
|
||||
Self::Natural => write!(f, " Size"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_stats(fs: &str, mntpt: &str, units: Units) -> Result<(), Box<dyn Error>> {
|
||||
let p = PathBuf::from(mntpt);
|
||||
if p.exists() {
|
||||
let st = shitbox::stat::statfs(mntpt)?;
|
||||
let bs = match units {
|
||||
Units::Posix => st.f_frsize / 512,
|
||||
Units::Kilo => st.f_frsize / 1024,
|
||||
Units::Natural => st.f_frsize,
|
||||
};
|
||||
let total = st.f_blocks * bs as u64;
|
||||
let avail = st.f_bfree * bs as u64;
|
||||
let used = total - avail;
|
||||
let mut capacity = if total > 0 { (used * 100) / total } else { 0 };
|
||||
if used * 100 != capacity * (used + avail) {
|
||||
capacity += 1;
|
||||
}
|
||||
if units == Units::Natural {
|
||||
print_human(fs, mntpt, total, avail, used, capacity);
|
||||
return Ok(());
|
||||
}
|
||||
println!("{fs:<12} {total:>9} {used:>9} {avail:>9} {capacity:>7}% {mntpt}");
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "fs does not exist").into())
|
||||
}
|
||||
}
|
||||
|
||||
fn print_human(fs: &str, mntpt: &str, total: u64, avail: u64, used: u64, capacity: u64) {
|
||||
// Unfortunately these strings must be printed separately due to the way the
|
||||
// library formats size display, as 0 will be a shorter string due to having
|
||||
// no suffix, throwing off column alignment
|
||||
print!("{fs:<12}");
|
||||
if total > 0 {
|
||||
print!("{:>9.1}", Size(total));
|
||||
} else {
|
||||
print!("{total:>10}");
|
||||
}
|
||||
if used > 0 {
|
||||
print!("{:>9.1}", Size(used));
|
||||
} else {
|
||||
print!("{used:>10}");
|
||||
}
|
||||
if avail > 0 {
|
||||
println!("{:9.1} {capacity:>7}% {mntpt}", Size(avail));
|
||||
} else {
|
||||
println!("{avail:>10} {capacity:>7}% {mntpt}");
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ mod cp;
|
||||
mod cut;
|
||||
mod date;
|
||||
mod dd;
|
||||
mod df;
|
||||
mod dirname;
|
||||
mod echo;
|
||||
mod expand;
|
||||
@ -66,6 +67,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||
"chroot" => Some(Box::new(chroot::Chroot::default())),
|
||||
"corebox" => Some(Box::new(corebox::Corebox::default())),
|
||||
"cut" => Some(Box::new(cut::Cut::default())),
|
||||
"df" => Some(Box::new(df::Df::default())),
|
||||
"dirname" => Some(Box::new(dirname::Dirname::default())),
|
||||
"echo" => Some(Box::new(echo::Echo::default())),
|
||||
"factor" => Some(Box::new(factor::Factor::default())),
|
||||
@ -102,7 +104,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||
}
|
||||
}
|
||||
|
||||
pub static COMMANDS: [&str; 42] = [
|
||||
pub static COMMANDS: [&str; 43] = [
|
||||
"base32",
|
||||
"base64",
|
||||
"basename",
|
||||
@ -113,6 +115,7 @@ pub static COMMANDS: [&str; 42] = [
|
||||
"chroot",
|
||||
"corebox",
|
||||
"cut",
|
||||
"df",
|
||||
"dirname",
|
||||
"echo",
|
||||
"false",
|
||||
|
@ -395,4 +395,3 @@ fn links(prefix: &str, usr: bool, cmd: &ArgMatches) -> Result<(), Box<dyn Error>
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use errno::Errno;
|
||||
use sc::*;
|
||||
use std::{ffi::CString, error::Error};
|
||||
use std::{error::Error, ffi::CString};
|
||||
|
||||
mod mntent;
|
||||
mod mntentries;
|
||||
|
@ -6,11 +6,12 @@ use blkid::{
|
||||
tag::{PartitionTag, SuperblockTag, TagType},
|
||||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::{self, Write},
|
||||
fs::File,
|
||||
io::{self, BufRead, BufReader},
|
||||
path::PathBuf,
|
||||
str::FromStr, error::Error,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
/// The information for a mount broken out into a struct
|
||||
|
@ -1,6 +1,12 @@
|
||||
use errno::Errno;
|
||||
use sc::*;
|
||||
use std::{ffi::CString, error::Error};
|
||||
use std::{
|
||||
error::Error,
|
||||
ffi::{c_long, CString},
|
||||
fs::File,
|
||||
mem,
|
||||
os::fd::AsRawFd,
|
||||
};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn mknod(path: &str, mode: u32, dev: u64) -> Result<(), Box<dyn Error>> {
|
||||
@ -37,3 +43,17 @@ pub fn mkfifo(path: &str, mode: u32) -> Result<(), Box<dyn Error>> {
|
||||
Err(Errno::from(ret).into())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn statfs(dir: &str) -> Result<libc::statvfs, Box<dyn Error>> {
|
||||
let mut buf = mem::MaybeUninit::<libc::statvfs>::uninit();
|
||||
let fd = File::open(dir)?;
|
||||
let ret = unsafe { libc::fstatvfs(fd.as_raw_fd(), buf.as_mut_ptr()) };
|
||||
if ret == 0 {
|
||||
let buf = unsafe { buf.assume_init() };
|
||||
Ok(buf)
|
||||
} else {
|
||||
let e = unsafe { *libc::__errno_location() };
|
||||
Err(Errno::from(e as c_long).into())
|
||||
}
|
||||
}
|
||||
|
@ -395,4 +395,3 @@ fn links(prefix: &str, usr: bool, cmd: &ArgMatches) -> Result<(), Box<dyn Error>
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user