Create generic hash
module; Add sha1sum
, sha224sum
and sha256sum
applets
This commit is contained in:
parent
8df1f99f70
commit
5e0c1141ef
107
Cargo.lock
generated
107
Cargo.lock
generated
@ -19,6 +19,15 @@ version = "1.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blake2"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.3"
|
version = "0.10.3"
|
||||||
@ -30,15 +39,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.78"
|
version = "1.0.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.1.1"
|
version = "4.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ec7a4128863c188deefe750ac1d1dfe66c236909f845af04beed823638dc1b2"
|
checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
@ -49,18 +64,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_complete"
|
name = "clap_complete"
|
||||||
version = "4.1.0"
|
version = "4.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce8955d4e8cd4f28f9a01c93a050194c4d131e73ca02f6636bcddbed867014d7"
|
checksum = "3d6540eedc41f8a5a76cf3d8d458057dcdf817be4158a55b5f861f7a5483de75"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_complete_nushell"
|
name = "clap_complete_nushell"
|
||||||
version = "0.1.8"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "956ceeff3734be0ba9e15998f1f1a487cd2928b31444209e8fcd92b30efac13a"
|
checksum = "c7fa41f5e6aa83bd151b70fd0ceaee703d68cd669522795dc812df9edad1252c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
@ -85,6 +100,15 @@ dependencies = [
|
|||||||
"roff",
|
"roff",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
@ -109,6 +133,7 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer",
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -153,18 +178,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.2.6"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-lifetimes"
|
name = "io-lifetimes"
|
||||||
version = "1.0.4"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
|
checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
@ -172,11 +194,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is-terminal"
|
name = "is-terminal"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
|
checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.2.6",
|
"hermit-abi 0.3.0",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
@ -217,9 +239,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.36.6"
|
version = "0.36.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
|
checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"errno",
|
"errno",
|
||||||
@ -244,19 +266,45 @@ version = "0.2.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "010e18bd3bfd1d45a7e666b236c78720df0d9a7698ebaa9c1c559961eb60a38b"
|
checksum = "010e18bd3bfd1d45a7e666b236c78720df0d9a7698ebaa9c1c559961eb60a38b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha1"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shitbox"
|
name = "shitbox"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
|
"blake2",
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
"clap_complete_nushell",
|
"clap_complete_nushell",
|
||||||
"clap_mangen",
|
"clap_mangen",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
|
"digest",
|
||||||
"libc",
|
"libc",
|
||||||
"md-5",
|
"md-5",
|
||||||
"sc",
|
"sc",
|
||||||
|
"sha1",
|
||||||
|
"sha2",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
@ -274,6 +322,12 @@ version = "0.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -348,9 +402,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.42.0"
|
version = "0.45.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.42.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm",
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc",
|
||||||
|
10
Cargo.toml
10
Cargo.toml
@ -7,17 +7,21 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
atty = "0.2"
|
atty = "0.2"
|
||||||
|
blake2 = "0.10"
|
||||||
clap = "4.1"
|
clap = "4.1"
|
||||||
clap_complete = "4.0"
|
clap_complete = "4.1"
|
||||||
clap_complete_nushell = "0.1"
|
clap_complete_nushell = "0.1"
|
||||||
clap_mangen = "0.2"
|
clap_mangen = "0.2"
|
||||||
data-encoding = "2.3"
|
data-encoding = "2.3"
|
||||||
|
digest = "0.10.6"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
md-5 = "0.10.5"
|
md-5 = "0.10"
|
||||||
sc = "0.2"
|
sc = "0.2"
|
||||||
|
sha1 = "0.10"
|
||||||
|
sha2 = "0.10"
|
||||||
termcolor = "1.1"
|
termcolor = "1.1"
|
||||||
textwrap = { version = "0.16", default-features = false, features = ["smawk"] }
|
textwrap = { version = "0.16", default-features = false, features = ["smawk"] }
|
||||||
walkdir = "2.3.2"
|
walkdir = "2.3"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
@ -41,6 +41,7 @@ code between applets, making for an overall smaller binary.
|
|||||||
- md5sum
|
- md5sum
|
||||||
- mkfifo
|
- mkfifo
|
||||||
- mknod
|
- mknod
|
||||||
|
- mktemp
|
||||||
- mountpoint
|
- mountpoint
|
||||||
- nologin
|
- nologin
|
||||||
- nproc
|
- nproc
|
||||||
|
@ -44,3 +44,18 @@ pub fn color() -> Arg {
|
|||||||
.long("color")
|
.long("color")
|
||||||
.value_parser(["always", "ansi", "auto", "never"])
|
.value_parser(["always", "ansi", "auto", "never"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check() -> Arg {
|
||||||
|
Arg::new("check")
|
||||||
|
.help("read checksums from the FILEs and check them")
|
||||||
|
.short('c')
|
||||||
|
.long("check")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn file() -> Arg {
|
||||||
|
Arg::new("file")
|
||||||
|
.value_name("FILE")
|
||||||
|
.num_args(1..)
|
||||||
|
.default_value("-")
|
||||||
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use super::Cmd;
|
use super::Cmd;
|
||||||
use clap::{Arg, ArgAction, Command};
|
use crate::{
|
||||||
use md5::{Digest, Md5};
|
args,
|
||||||
use std::{
|
hash::{self, HashType},
|
||||||
fmt::Write,
|
|
||||||
fs::File,
|
|
||||||
io::{self, BufRead, BufReader, Read},
|
|
||||||
process, error::Error,
|
|
||||||
};
|
};
|
||||||
|
use clap::Command;
|
||||||
|
use md5::{Digest, Md5};
|
||||||
|
use std::{io, process};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Md5sum;
|
pub struct Md5sum;
|
||||||
@ -17,17 +16,7 @@ impl Cmd for Md5sum {
|
|||||||
.about("compute and check MD5 message digest")
|
.about("compute and check MD5 message digest")
|
||||||
.author("Nathan Fisher")
|
.author("Nathan Fisher")
|
||||||
.version(env!("CARGO_PKG_VERSION"))
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
.args([
|
.args([args::check(), args::file()])
|
||||||
Arg::new("check")
|
|
||||||
.help("read checksums from the FILEs and check them")
|
|
||||||
.short('c')
|
|
||||||
.long("check")
|
|
||||||
.action(ArgAction::SetTrue),
|
|
||||||
Arg::new("file")
|
|
||||||
.value_name("FILE")
|
|
||||||
.num_args(1..)
|
|
||||||
.default_value("-"),
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
@ -43,49 +32,11 @@ impl Cmd for Md5sum {
|
|||||||
io::Error::new(io::ErrorKind::Other, "no file specified").into()
|
io::Error::new(io::ErrorKind::Other, "no file specified").into()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let fd = File::open(f)?;
|
hash::check_sums(f, HashType::Md5, &mut erred)?;
|
||||||
let reader = BufReader::new(fd);
|
|
||||||
for line in reader.lines() {
|
|
||||||
let line = line?;
|
|
||||||
let mut split = line.split_whitespace();
|
|
||||||
let sum = split.next().ok_or::<Box<dyn Error>>(
|
|
||||||
io::Error::new(io::ErrorKind::Other, "invalid checksum file").into(),
|
|
||||||
)?;
|
|
||||||
let file = split.next().ok_or::<Box<dyn Error>>(
|
|
||||||
io::Error::new(io::ErrorKind::Other, "invalid checksum file").into(),
|
|
||||||
)?;
|
|
||||||
let mut hasher = Md5::new();
|
|
||||||
let mut buf = vec![];
|
|
||||||
let mut fd = File::open(file)?;
|
|
||||||
let _s = fd.read_to_end(&mut buf)?;
|
|
||||||
hasher.update(&buf);
|
|
||||||
let res = hasher.finalize();
|
|
||||||
let mut s = String::new();
|
|
||||||
for c in res {
|
|
||||||
write!(s, "{c:x}")?;
|
|
||||||
}
|
|
||||||
if s.as_str() == sum {
|
|
||||||
println!("{file}: OK");
|
|
||||||
} else {
|
|
||||||
println!("{file}: FAILED");
|
|
||||||
erred += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let mut hasher = Md5::new();
|
let hasher = Md5::new();
|
||||||
let mut buf = vec![];
|
let s = hash::compute_hash(f, hasher)?;
|
||||||
if f == "-" {
|
println!("{s} {f}");
|
||||||
let _s = io::stdin().read_to_end(&mut buf)?;
|
|
||||||
} else {
|
|
||||||
let mut fd = File::open(f)?;
|
|
||||||
let _s = fd.read_to_end(&mut buf)?;
|
|
||||||
}
|
|
||||||
hasher.update(&buf);
|
|
||||||
let res = hasher.finalize();
|
|
||||||
for c in res {
|
|
||||||
print!("{c:x}");
|
|
||||||
}
|
|
||||||
println!(" {f}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if erred > 0 {
|
if erred > 0 {
|
||||||
|
@ -44,6 +44,9 @@ mod realpath;
|
|||||||
mod rev;
|
mod rev;
|
||||||
mod rm;
|
mod rm;
|
||||||
mod rmdir;
|
mod rmdir;
|
||||||
|
mod sha1sum;
|
||||||
|
mod sha224sum;
|
||||||
|
mod sha256sum;
|
||||||
mod shitbox;
|
mod shitbox;
|
||||||
mod sleep;
|
mod sleep;
|
||||||
mod sync;
|
mod sync;
|
||||||
@ -108,6 +111,9 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
"rev" => Some(Box::new(rev::Rev::default())),
|
"rev" => Some(Box::new(rev::Rev::default())),
|
||||||
"rm" => Some(Box::new(rm::Rm::default())),
|
"rm" => Some(Box::new(rm::Rm::default())),
|
||||||
"rmdir" => Some(Box::new(rmdir::Rmdir::default())),
|
"rmdir" => Some(Box::new(rmdir::Rmdir::default())),
|
||||||
|
"sha1sum" => Some(Box::new(sha1sum::Sha1sum::default())),
|
||||||
|
"sha224sum" => Some(Box::new(sha224sum::Sha224sum::default())),
|
||||||
|
"sha256sum" => Some(Box::new(sha256sum::Sha256sum::default())),
|
||||||
"shitbox" => Some(Box::new(shitbox::Shitbox::default())),
|
"shitbox" => Some(Box::new(shitbox::Shitbox::default())),
|
||||||
"sleep" => Some(Box::new(sleep::Sleep::default())),
|
"sleep" => Some(Box::new(sleep::Sleep::default())),
|
||||||
"sync" => Some(Box::new(sync::Sync::default())),
|
"sync" => Some(Box::new(sync::Sync::default())),
|
||||||
@ -121,7 +127,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COMMANDS: [&str; 44] = [
|
pub static COMMANDS: [&str; 47] = [
|
||||||
"base32",
|
"base32",
|
||||||
"base64",
|
"base64",
|
||||||
"basename",
|
"basename",
|
||||||
@ -157,8 +163,11 @@ pub static COMMANDS: [&str; 44] = [
|
|||||||
"rev",
|
"rev",
|
||||||
"rm",
|
"rm",
|
||||||
"rmdir",
|
"rmdir",
|
||||||
"sleep",
|
"sha1sum",
|
||||||
|
"sha224sum",
|
||||||
|
"sha256sum",
|
||||||
"shitbox",
|
"shitbox",
|
||||||
|
"sleep",
|
||||||
"sync",
|
"sync",
|
||||||
"true",
|
"true",
|
||||||
"unlink",
|
"unlink",
|
||||||
|
53
src/cmd/sha1sum/mod.rs
Normal file
53
src/cmd/sha1sum/mod.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use super::Cmd;
|
||||||
|
use crate::{
|
||||||
|
args,
|
||||||
|
hash::{self, HashType},
|
||||||
|
};
|
||||||
|
use clap::Command;
|
||||||
|
use sha1::{Digest, Sha1};
|
||||||
|
use std::{io, process};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Sha1sum;
|
||||||
|
|
||||||
|
impl Cmd for Sha1sum {
|
||||||
|
fn cli(&self) -> clap::Command {
|
||||||
|
Command::new("sha1sum")
|
||||||
|
.about("compute and check SHA1 message digest")
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.args([args::check(), args::file()])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let Some(matches) = matches else {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, "no input").into());
|
||||||
|
};
|
||||||
|
if let Some(files) = matches.get_many::<String>("file") {
|
||||||
|
let mut erred = 0;
|
||||||
|
for f in files {
|
||||||
|
if matches.get_flag("check") {
|
||||||
|
if f == "-" {
|
||||||
|
return Err(
|
||||||
|
io::Error::new(io::ErrorKind::Other, "no file specified").into()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
hash::check_sums(f, HashType::Sha1, &mut erred)?;
|
||||||
|
} else {
|
||||||
|
let hasher = Sha1::new();
|
||||||
|
let s = hash::compute_hash(f, hasher)?;
|
||||||
|
println!("{s} {f}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if erred > 0 {
|
||||||
|
println!("sha1sum: WARNING: {erred} computed checksum did NOT match");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<crate::Path> {
|
||||||
|
Some(crate::Path::UsrBin)
|
||||||
|
}
|
||||||
|
}
|
53
src/cmd/sha224sum/mod.rs
Normal file
53
src/cmd/sha224sum/mod.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use super::Cmd;
|
||||||
|
use crate::{
|
||||||
|
args,
|
||||||
|
hash::{self, HashType},
|
||||||
|
};
|
||||||
|
use clap::Command;
|
||||||
|
use sha2::{Digest, Sha224};
|
||||||
|
use std::{io, process};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Sha224sum;
|
||||||
|
|
||||||
|
impl Cmd for Sha224sum {
|
||||||
|
fn cli(&self) -> clap::Command {
|
||||||
|
Command::new("sha224sum")
|
||||||
|
.about("compute and check SHA1 message digest")
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.args([args::check(), args::file()])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let Some(matches) = matches else {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, "no input").into());
|
||||||
|
};
|
||||||
|
if let Some(files) = matches.get_many::<String>("file") {
|
||||||
|
let mut erred = 0;
|
||||||
|
for f in files {
|
||||||
|
if matches.get_flag("check") {
|
||||||
|
if f == "-" {
|
||||||
|
return Err(
|
||||||
|
io::Error::new(io::ErrorKind::Other, "no file specified").into()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
hash::check_sums(f, HashType::Sha224, &mut erred)?;
|
||||||
|
} else {
|
||||||
|
let hasher = Sha224::new();
|
||||||
|
let s = hash::compute_hash(f, hasher)?;
|
||||||
|
println!("{s} {f}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if erred > 0 {
|
||||||
|
println!("sha224sum: WARNING: {erred} computed checksum did NOT match");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<crate::Path> {
|
||||||
|
Some(crate::Path::UsrBin)
|
||||||
|
}
|
||||||
|
}
|
53
src/cmd/sha256sum/mod.rs
Normal file
53
src/cmd/sha256sum/mod.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use super::Cmd;
|
||||||
|
use crate::{
|
||||||
|
args,
|
||||||
|
hash::{self, HashType},
|
||||||
|
};
|
||||||
|
use clap::Command;
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
|
use std::{io, process};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Sha224sum;
|
||||||
|
|
||||||
|
impl Cmd for Sha224sum {
|
||||||
|
fn cli(&self) -> clap::Command {
|
||||||
|
Command::new("sha256sum")
|
||||||
|
.about("compute and check SHA1 message digest")
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.args([args::check(), args::file()])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let Some(matches) = matches else {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, "no input").into());
|
||||||
|
};
|
||||||
|
if let Some(files) = matches.get_many::<String>("file") {
|
||||||
|
let mut erred = 0;
|
||||||
|
for f in files {
|
||||||
|
if matches.get_flag("check") {
|
||||||
|
if f == "-" {
|
||||||
|
return Err(
|
||||||
|
io::Error::new(io::ErrorKind::Other, "no file specified").into()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
hash::check_sums(f, HashType::Sha256, &mut erred)?;
|
||||||
|
} else {
|
||||||
|
let hasher = Sha256::new();
|
||||||
|
let s = hash::compute_hash(f, hasher)?;
|
||||||
|
println!("{s} {f}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if erred > 0 {
|
||||||
|
println!("sha256sum: WARNING: {erred} computed checksum did NOT match");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<crate::Path> {
|
||||||
|
Some(crate::Path::UsrBin)
|
||||||
|
}
|
||||||
|
}
|
73
src/hash/mod.rs
Normal file
73
src/hash/mod.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
use {
|
||||||
|
digest::{Digest, FixedOutput, HashMarker},
|
||||||
|
md5::Md5,
|
||||||
|
sha1::Sha1,
|
||||||
|
sha2::{Sha224, Sha256, Sha384, Sha512},
|
||||||
|
std::{
|
||||||
|
error::Error,
|
||||||
|
fmt::Write,
|
||||||
|
fs::File,
|
||||||
|
io::{self, BufRead, BufReader, Read},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub enum HashType {
|
||||||
|
Blake2b,
|
||||||
|
Md5,
|
||||||
|
Sha1,
|
||||||
|
Sha224,
|
||||||
|
Sha256,
|
||||||
|
Sha384,
|
||||||
|
Sha512,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compute_hash<T>(file: &str, mut hasher: T) -> Result<String, Box<dyn Error>>
|
||||||
|
where
|
||||||
|
T: Default + FixedOutput + HashMarker,
|
||||||
|
{
|
||||||
|
let mut buf = vec![];
|
||||||
|
if file == "-" {
|
||||||
|
let _s = io::stdin().read_to_end(&mut buf)?;
|
||||||
|
} else {
|
||||||
|
let mut fd = File::open(file)?;
|
||||||
|
let _s = fd.read_to_end(&mut buf)?;
|
||||||
|
}
|
||||||
|
let mut s = String::new();
|
||||||
|
hasher.update(&buf);
|
||||||
|
let res = hasher.finalize();
|
||||||
|
for c in res {
|
||||||
|
write!(s, "{c:02x}")?;
|
||||||
|
}
|
||||||
|
Ok(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_sums(file: &str, hashtype: HashType, erred: &mut usize) -> Result<(), Box<dyn Error>> {
|
||||||
|
let fd = File::open(file)?;
|
||||||
|
let reader = BufReader::new(fd);
|
||||||
|
for line in reader.lines() {
|
||||||
|
let line = line?;
|
||||||
|
let mut split = line.split_whitespace();
|
||||||
|
let sum = split.next().ok_or::<io::Error>(
|
||||||
|
io::Error::new(io::ErrorKind::Other, "invalid checksum file").into(),
|
||||||
|
)?;
|
||||||
|
let file = split.next().ok_or::<io::Error>(
|
||||||
|
io::Error::new(io::ErrorKind::Other, "invalid checksum file").into(),
|
||||||
|
)?;
|
||||||
|
let s = match hashtype {
|
||||||
|
HashType::Blake2b => unimplemented!(),
|
||||||
|
HashType::Md5 => compute_hash(file, Md5::new())?,
|
||||||
|
HashType::Sha1 => compute_hash(file, Sha1::new())?,
|
||||||
|
HashType::Sha224 => compute_hash(file, Sha224::new())?,
|
||||||
|
HashType::Sha256 => compute_hash(file, Sha256::new())?,
|
||||||
|
HashType::Sha384 => compute_hash(file, Sha384::new())?,
|
||||||
|
HashType::Sha512 => compute_hash(file, Sha512::new())?,
|
||||||
|
};
|
||||||
|
if s.as_str() == sum {
|
||||||
|
println!("{file}: OK");
|
||||||
|
} else {
|
||||||
|
println!("{file}: FAILED");
|
||||||
|
*erred += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -5,6 +5,7 @@ pub mod args;
|
|||||||
pub mod bitflags;
|
pub mod bitflags;
|
||||||
mod cmd;
|
mod cmd;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
|
pub mod hash;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod mode;
|
pub mod mode;
|
||||||
pub mod pw;
|
pub mod pw;
|
||||||
|
Loading…
Reference in New Issue
Block a user