|
5 | 5 |
|
6 | 6 | // spell-checker:ignore (ToDO) algo, algoname, bitlen, regexes, nread, nonames |
7 | 7 |
|
8 | | -use clap::ArgAction; |
9 | | -use clap::builder::ValueParser; |
10 | | -use clap::value_parser; |
11 | | -use clap::{Arg, ArgMatches, Command}; |
12 | 8 | use std::ffi::{OsStr, OsString}; |
13 | | -use std::fs::File; |
14 | | -use std::io::{BufReader, Read, stdin}; |
15 | 9 | use std::iter; |
16 | 10 | use std::num::ParseIntError; |
17 | 11 | use std::path::Path; |
18 | 12 |
|
| 13 | +use clap::builder::ValueParser; |
| 14 | +use clap::{Arg, ArgAction, ArgMatches, Command, value_parser}; |
| 15 | + |
| 16 | +use uucore::checksum::compute::{ |
| 17 | + ChecksumComputeOptions, figure_out_output_format, perform_checksum_computation, |
| 18 | +}; |
19 | 19 | use uucore::checksum::validate::{ |
20 | 20 | ChecksumValidateOptions, ChecksumVerbose, perform_checksum_validation, |
21 | 21 | }; |
22 | | -use uucore::checksum::{ |
23 | | - AlgoKind, ChecksumError, SizedAlgoKind, calculate_blake2b_length, digest_reader, |
24 | | - escape_filename, |
25 | | -}; |
26 | | -use uucore::error::{UResult, strip_errno}; |
27 | | -use uucore::sum::Digest; |
| 22 | +use uucore::checksum::{AlgoKind, ChecksumError, SizedAlgoKind, calculate_blake2b_length}; |
| 23 | +use uucore::error::UResult; |
| 24 | +use uucore::line_ending::LineEnding; |
28 | 25 | use uucore::{format_usage, translate}; |
29 | 26 |
|
30 | 27 | const NAME: &str = "hashsum"; |
31 | | -// Using the same read buffer size as GNU |
32 | | -const READ_BUFFER_SIZE: usize = 32 * 1024; |
33 | | - |
34 | | -struct Options<'a> { |
35 | | - algo: SizedAlgoKind, |
36 | | - digest: Box<dyn Digest + 'static>, |
37 | | - binary: bool, |
38 | | - binary_name: &'a str, |
39 | | - //check: bool, |
40 | | - tag: bool, |
41 | | - nonames: bool, |
42 | | - //status: bool, |
43 | | - //quiet: bool, |
44 | | - //strict: bool, |
45 | | - //warn: bool, |
46 | | - zero: bool, |
47 | | - //ignore_missing: bool, |
48 | | -} |
49 | 28 |
|
50 | 29 | /// Creates a hasher instance based on the command-line flags. |
51 | 30 | /// |
@@ -186,9 +165,9 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { |
186 | 165 | }; |
187 | 166 | let check = matches.get_flag("check"); |
188 | 167 | let status = matches.get_flag("status"); |
189 | | - let quiet = matches.get_flag("quiet") || status; |
| 168 | + let quiet = matches.get_flag("quiet"); |
190 | 169 | let strict = matches.get_flag("strict"); |
191 | | - let warn = matches.get_flag("warn") && !status; |
| 170 | + let warn = matches.get_flag("warn"); |
192 | 171 | let ignore_missing = matches.get_flag("ignore-missing"); |
193 | 172 |
|
194 | 173 | if ignore_missing && !check { |
@@ -232,33 +211,37 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { |
232 | 211 | return Err(ChecksumError::StrictNotCheck.into()); |
233 | 212 | } |
234 | 213 |
|
235 | | - let nonames = *matches |
| 214 | + let no_names = *matches |
236 | 215 | .try_get_one("no-names") |
237 | 216 | .unwrap_or(None) |
238 | 217 | .unwrap_or(&false); |
239 | | - let zero = matches.get_flag("zero"); |
| 218 | + let line_ending = LineEnding::from_zero_flag(matches.get_flag("zero")); |
240 | 219 |
|
241 | 220 | let algo = SizedAlgoKind::from_unsized(algo_kind, length)?; |
242 | 221 |
|
243 | | - let opts = Options { |
244 | | - algo, |
| 222 | + let opts = ChecksumComputeOptions { |
| 223 | + algo_kind: algo, |
245 | 224 | digest: algo.create_digest(), |
246 | | - binary, |
247 | | - binary_name: &binary_name, |
248 | | - tag: matches.get_flag("tag"), |
249 | | - nonames, |
250 | | - //status, |
251 | | - //quiet, |
252 | | - //warn, |
253 | | - zero, |
254 | | - //ignore_missing, |
| 225 | + output_format: figure_out_output_format( |
| 226 | + algo, |
| 227 | + matches.get_flag(options::TAG), |
| 228 | + binary, |
| 229 | + /* raw */ false, |
| 230 | + /* base64: */ false, |
| 231 | + ), |
| 232 | + line_ending, |
| 233 | + no_names, |
255 | 234 | }; |
256 | 235 |
|
| 236 | + let files = matches.get_many::<OsString>(options::FILE).map_or_else( |
| 237 | + // No files given, read from stdin. |
| 238 | + || Box::new(iter::once(OsStr::new("-"))) as Box<dyn Iterator<Item = &OsStr>>, |
| 239 | + // At least one file given, read from them. |
| 240 | + |files| Box::new(files.map(OsStr::new)) as Box<dyn Iterator<Item = &OsStr>>, |
| 241 | + ); |
| 242 | + |
257 | 243 | // Show the hashsum of the input |
258 | | - match matches.get_many::<OsString>(options::FILE) { |
259 | | - Some(files) => hashsum(opts, files.map(|f| f.as_os_str())), |
260 | | - None => hashsum(opts, iter::once(OsStr::new("-"))), |
261 | | - } |
| 244 | + perform_checksum_computation(opts, files) |
262 | 245 | } |
263 | 246 |
|
264 | 247 | mod options { |
@@ -498,75 +481,3 @@ fn uu_app(binary_name: &str) -> (Command, bool) { |
498 | 481 |
|
499 | 482 | (command, is_hashsum_bin) |
500 | 483 | } |
501 | | - |
502 | | -#[allow(clippy::cognitive_complexity)] |
503 | | -fn hashsum<'a, I>(mut options: Options, files: I) -> UResult<()> |
504 | | -where |
505 | | - I: Iterator<Item = &'a OsStr>, |
506 | | -{ |
507 | | - let binary_marker = if options.binary { "*" } else { " " }; |
508 | | - let mut err_found = None; |
509 | | - for filename in files { |
510 | | - let filename = Path::new(filename); |
511 | | - |
512 | | - let mut file = BufReader::with_capacity( |
513 | | - READ_BUFFER_SIZE, |
514 | | - if filename == OsStr::new("-") { |
515 | | - Box::new(stdin()) as Box<dyn Read> |
516 | | - } else { |
517 | | - let file_buf = match File::open(filename) { |
518 | | - Ok(f) => f, |
519 | | - Err(e) => { |
520 | | - eprintln!( |
521 | | - "{}: {}: {}", |
522 | | - options.binary_name, |
523 | | - filename.to_string_lossy(), |
524 | | - strip_errno(&e) |
525 | | - ); |
526 | | - err_found = Some(ChecksumError::Io(e)); |
527 | | - continue; |
528 | | - } |
529 | | - }; |
530 | | - Box::new(file_buf) as Box<dyn Read> |
531 | | - }, |
532 | | - ); |
533 | | - |
534 | | - let sum = match digest_reader( |
535 | | - &mut options.digest, |
536 | | - &mut file, |
537 | | - options.binary, |
538 | | - options.algo.bitlen(), |
539 | | - ) { |
540 | | - Ok((sum, _)) => sum, |
541 | | - Err(e) => { |
542 | | - eprintln!( |
543 | | - "{}: {}: {}", |
544 | | - options.binary_name, |
545 | | - filename.to_string_lossy(), |
546 | | - strip_errno(&e) |
547 | | - ); |
548 | | - err_found = Some(ChecksumError::Io(e)); |
549 | | - continue; |
550 | | - } |
551 | | - }; |
552 | | - |
553 | | - let (escaped_filename, prefix) = escape_filename(filename); |
554 | | - if options.tag { |
555 | | - println!( |
556 | | - "{prefix}{} ({escaped_filename}) = {sum}", |
557 | | - options.algo.to_tag() |
558 | | - ); |
559 | | - } else if options.nonames { |
560 | | - println!("{sum}"); |
561 | | - } else if options.zero { |
562 | | - // with zero, we don't escape the filename |
563 | | - print!("{sum} {binary_marker}{}\0", filename.display()); |
564 | | - } else { |
565 | | - println!("{prefix}{sum} {binary_marker}{escaped_filename}"); |
566 | | - } |
567 | | - } |
568 | | - match err_found { |
569 | | - None => Ok(()), |
570 | | - Some(e) => Err(Box::new(e)), |
571 | | - } |
572 | | -} |
0 commit comments