Skip to content

Commit

Permalink
Merge pull request uutils#5803 from D9nni/cksum
Browse files Browse the repository at this point in the history
cksum: Add --raw argument
  • Loading branch information
sylvestre authored Jan 10, 2024
2 parents 0071442 + 9a76997 commit 19a9380
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 2 deletions.
57 changes: 55 additions & 2 deletions src/uu/cksum/src/cksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@

// spell-checker:ignore (ToDO) fname, algo
use clap::{crate_version, value_parser, Arg, ArgAction, Command};
use hex::decode;
use hex::encode;
use std::error::Error;
use std::ffi::OsStr;
use std::fmt::Display;
use std::fs::File;
use std::io::{self, stdin, BufReader, Read};
use std::io::{self, stdin, stdout, BufReader, Read, Write};
use std::iter;
use std::path::Path;
use uucore::{
error::{FromIo, UResult},
error::{FromIo, UError, UResult},
format_usage, help_about, help_section, help_usage,
sum::{
div_ceil, Blake2b, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha512, Sm3,
Expand All @@ -36,6 +39,31 @@ const ALGORITHM_OPTIONS_SHA512: &str = "sha512";
const ALGORITHM_OPTIONS_BLAKE2B: &str = "blake2b";
const ALGORITHM_OPTIONS_SM3: &str = "sm3";

#[derive(Debug)]
enum CkSumError {
RawMultipleFiles,
}

impl UError for CkSumError {
fn code(&self) -> i32 {
match self {
Self::RawMultipleFiles => 1,
}
}
}

impl Error for CkSumError {}

impl Display for CkSumError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::RawMultipleFiles => {
write!(f, "the --raw option is not supported with multiple files")
}
}
}
}

fn detect_algo(
program: &str,
length: Option<usize>,
Expand Down Expand Up @@ -110,6 +138,7 @@ struct Options {
output_bits: usize,
untagged: bool,
length: Option<usize>,
raw: bool,
}

/// Calculate checksum
Expand All @@ -123,6 +152,11 @@ fn cksum<'a, I>(mut options: Options, files: I) -> UResult<()>
where
I: Iterator<Item = &'a OsStr>,
{
let files: Vec<_> = files.collect();
if options.raw && files.len() > 1 {
return Err(Box::new(CkSumError::RawMultipleFiles));
}

for filename in files {
let filename = Path::new(filename);
let stdin_buf;
Expand All @@ -141,6 +175,17 @@ where
let (sum, sz) = digest_read(&mut options.digest, &mut file, options.output_bits)
.map_err_context(|| "failed to read input".to_string())?;

if options.raw {
let bytes = match options.algo_name {
ALGORITHM_OPTIONS_CRC => sum.parse::<u32>().unwrap().to_be_bytes().to_vec(),
ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => {
sum.parse::<u16>().unwrap().to_be_bytes().to_vec()
}
_ => decode(sum).unwrap(),
};
stdout().write_all(&bytes)?;
return Ok(());
}
// The BSD checksum output is 5 digit integer
let bsd_width = 5;
match (options.algo_name, not_file) {
Expand Down Expand Up @@ -238,6 +283,7 @@ mod options {
pub const FILE: &str = "file";
pub const UNTAGGED: &str = "untagged";
pub const LENGTH: &str = "length";
pub const RAW: &str = "raw";
}

#[uucore::main]
Expand Down Expand Up @@ -298,6 +344,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
output_bits: bits,
length,
untagged: matches.get_flag(options::UNTAGGED),
raw: matches.get_flag(options::RAW),
};

match matches.get_many::<String>(options::FILE) {
Expand Down Expand Up @@ -354,5 +401,11 @@ pub fn uu_app() -> Command {
.help("digest length in bits; must not exceed the max for the blake2 algorithm and must be a multiple of 8")
.action(ArgAction::Set),
)
.arg(
Arg::new(options::RAW)
.long(options::RAW)
.help("emit a raw binary digest, not hexadecimal")
.action(ArgAction::SetTrue),
)
.after_help(AFTER_HELP)
}
24 changes: 24 additions & 0 deletions tests/by-util/test_cksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,30 @@ fn test_length_is_zero() {
.stdout_is_fixture("length_is_zero.expected");
}

#[test]
fn test_raw_single_file() {
for algo in ALGOS {
new_ucmd!()
.arg("--raw")
.arg("lorem_ipsum.txt")
.arg(format!("--algorithm={algo}"))
.succeeds()
.no_stderr()
.stdout_is_fixture_bytes(format!("raw/{algo}_single_file.expected"));
}
}
#[test]
fn test_raw_multiple_files() {
new_ucmd!()
.arg("--raw")
.arg("lorem_ipsum.txt")
.arg("alice_in_wonderland.txt")
.fails()
.no_stdout()
.stderr_contains("cksum: the --raw option is not supported with multiple files")
.code_is(1);
}

#[test]
fn test_blake2b_fail_on_directory() {
let (at, mut ucmd) = at_and_ucmd!();
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/cksum/raw/blake2b_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�����`�x� �f��W���Et�B��l��W^J�0�aX´��8�����5�B��9m��
1 change: 1 addition & 0 deletions tests/fixtures/cksum/raw/bsd_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�
1 change: 1 addition & 0 deletions tests/fixtures/cksum/raw/crc_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�Ph
Binary file added tests/fixtures/cksum/raw/md5_single_file.expected
Binary file not shown.
1 change: 1 addition & 0 deletions tests/fixtures/cksum/raw/sha1_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�к�؈:=�m毽(%,��
Binary file not shown.
1 change: 1 addition & 0 deletions tests/fixtures/cksum/raw/sha256_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�� PP� 0�Pg�^� �SkE���C[�+?
Expand Down
3 changes: 3 additions & 0 deletions tests/fixtures/cksum/raw/sha384_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
K�
2�i���J��Mϸ��/g������LZ{WZ3S�
��H�
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/cksum/raw/sha512_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�Td�%V�Վ�sؚ�!�Yyu)���f���������|T,�Bn^Oऊ�Vg�D k!=���
1 change: 1 addition & 0 deletions tests/fixtures/cksum/raw/sm3_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
m)k�] ��(�0���CyM��g@�p��i��
1 change: 1 addition & 0 deletions tests/fixtures/cksum/raw/sysv_single_file.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I

0 comments on commit 19a9380

Please sign in to comment.