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"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.3"
|
||||
@ -30,15 +39,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.78"
|
||||
version = "1.0.79"
|
||||
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]]
|
||||
name = "clap"
|
||||
version = "4.1.1"
|
||||
version = "4.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec7a4128863c188deefe750ac1d1dfe66c236909f845af04beed823638dc1b2"
|
||||
checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
@ -49,18 +64,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.1.0"
|
||||
version = "4.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce8955d4e8cd4f28f9a01c93a050194c4d131e73ca02f6636bcddbed867014d7"
|
||||
checksum = "3d6540eedc41f8a5a76cf3d8d458057dcdf817be4158a55b5f861f7a5483de75"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete_nushell"
|
||||
version = "0.1.8"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "956ceeff3734be0ba9e15998f1f1a487cd2928b31444209e8fcd92b30efac13a"
|
||||
checksum = "c7fa41f5e6aa83bd151b70fd0ceaee703d68cd669522795dc812df9edad1252c"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
@ -85,6 +100,15 @@ dependencies = [
|
||||
"roff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
@ -109,6 +133,7 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -153,18 +178,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01"
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
|
||||
checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
@ -172,11 +194,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
|
||||
checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"hermit-abi 0.3.0",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
@ -217,9 +239,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.6"
|
||||
version = "0.36.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
|
||||
checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
@ -244,19 +266,45 @@ version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "shitbox"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"blake2",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_complete_nushell",
|
||||
"clap_mangen",
|
||||
"data-encoding",
|
||||
"digest",
|
||||
"libc",
|
||||
"md-5",
|
||||
"sc",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
"walkdir",
|
||||
@ -274,6 +322,12 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
@ -348,9 +402,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
version = "0.45.0"
|
||||
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 = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
|
10
Cargo.toml
10
Cargo.toml
@ -7,17 +7,21 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
atty = "0.2"
|
||||
blake2 = "0.10"
|
||||
clap = "4.1"
|
||||
clap_complete = "4.0"
|
||||
clap_complete = "4.1"
|
||||
clap_complete_nushell = "0.1"
|
||||
clap_mangen = "0.2"
|
||||
data-encoding = "2.3"
|
||||
digest = "0.10.6"
|
||||
libc = "0.2"
|
||||
md-5 = "0.10.5"
|
||||
md-5 = "0.10"
|
||||
sc = "0.2"
|
||||
sha1 = "0.10"
|
||||
sha2 = "0.10"
|
||||
termcolor = "1.1"
|
||||
textwrap = { version = "0.16", default-features = false, features = ["smawk"] }
|
||||
walkdir = "2.3.2"
|
||||
walkdir = "2.3"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
|
@ -41,6 +41,7 @@ code between applets, making for an overall smaller binary.
|
||||
- md5sum
|
||||
- mkfifo
|
||||
- mknod
|
||||
- mktemp
|
||||
- mountpoint
|
||||
- nologin
|
||||
- nproc
|
||||
|
@ -44,3 +44,18 @@ pub fn color() -> Arg {
|
||||
.long("color")
|
||||
.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 clap::{Arg, ArgAction, Command};
|
||||
use md5::{Digest, Md5};
|
||||
use std::{
|
||||
fmt::Write,
|
||||
fs::File,
|
||||
io::{self, BufRead, BufReader, Read},
|
||||
process, error::Error,
|
||||
use crate::{
|
||||
args,
|
||||
hash::{self, HashType},
|
||||
};
|
||||
use clap::Command;
|
||||
use md5::{Digest, Md5};
|
||||
use std::{io, process};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Md5sum;
|
||||
@ -17,17 +16,7 @@ impl Cmd for Md5sum {
|
||||
.about("compute and check MD5 message digest")
|
||||
.author("Nathan Fisher")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.args([
|
||||
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("-"),
|
||||
])
|
||||
.args([args::check(), args::file()])
|
||||
}
|
||||
|
||||
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()
|
||||
);
|
||||
}
|
||||
let fd = File::open(f)?;
|
||||
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;
|
||||
}
|
||||
}
|
||||
hash::check_sums(f, HashType::Md5, &mut erred)?;
|
||||
} else {
|
||||
let mut hasher = Md5::new();
|
||||
let mut buf = vec![];
|
||||
if 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}");
|
||||
let hasher = Md5::new();
|
||||
let s = hash::compute_hash(f, hasher)?;
|
||||
println!("{s} {f}");
|
||||
}
|
||||
}
|
||||
if erred > 0 {
|
||||
|
@ -44,6 +44,9 @@ mod realpath;
|
||||
mod rev;
|
||||
mod rm;
|
||||
mod rmdir;
|
||||
mod sha1sum;
|
||||
mod sha224sum;
|
||||
mod sha256sum;
|
||||
mod shitbox;
|
||||
mod sleep;
|
||||
mod sync;
|
||||
@ -108,6 +111,9 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||
"rev" => Some(Box::new(rev::Rev::default())),
|
||||
"rm" => Some(Box::new(rm::Rm::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())),
|
||||
"sleep" => Some(Box::new(sleep::Sleep::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",
|
||||
"base64",
|
||||
"basename",
|
||||
@ -157,8 +163,11 @@ pub static COMMANDS: [&str; 44] = [
|
||||
"rev",
|
||||
"rm",
|
||||
"rmdir",
|
||||
"sleep",
|
||||
"sha1sum",
|
||||
"sha224sum",
|
||||
"sha256sum",
|
||||
"shitbox",
|
||||
"sleep",
|
||||
"sync",
|
||||
"true",
|
||||
"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;
|
||||
mod cmd;
|
||||
pub mod fs;
|
||||
pub mod hash;
|
||||
pub mod math;
|
||||
pub mod mode;
|
||||
pub mod pw;
|
||||
|
Loading…
Reference in New Issue
Block a user