mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
Merge remote-tracking branch 'origin/main' into lossy-string-cleanup
This commit is contained in:
+18
-18
@@ -36,7 +36,7 @@ jobs:
|
||||
name: Style/cargo-deny
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: EmbarkStudios/cargo-deny-action@v2
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
- { os: macos-latest , features: "feat_Tier1,feat_require_unix,feat_require_unix_utmpx" }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
# - { os: macos-latest , features: feat_os_macos }
|
||||
# - { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
@@ -168,7 +168,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
@@ -238,7 +238,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -265,7 +265,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -398,7 +398,7 @@ jobs:
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -427,7 +427,7 @@ jobs:
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
@@ -453,7 +453,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -593,7 +593,7 @@ jobs:
|
||||
- { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows }
|
||||
- { os: windows-latest , target: aarch64-pc-windows-msvc , features: feat_os_windows, use-cross: use-cross , skip-tests: true }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
@@ -875,7 +875,7 @@ jobs:
|
||||
run: |
|
||||
## VARs setup
|
||||
echo "TEST_SUMMARY_FILE=busybox-result.json" >> $GITHUB_OUTPUT
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
@@ -958,7 +958,7 @@ jobs:
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
TEST_SUMMARY_FILE="toybox-result.json"
|
||||
outputs TEST_SUMMARY_FILE
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
@@ -1047,7 +1047,7 @@ jobs:
|
||||
# FIXME: Re-enable Code Coverage on windows, which currently fails due to "profiler_builtins". See #6686.
|
||||
# - { os: windows-latest , features: windows, toolchain: nightly-x86_64-pc-windows-gnu }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{ matrix.job.toolchain }}
|
||||
@@ -1164,7 +1164,7 @@ jobs:
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1191,7 +1191,7 @@ jobs:
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
# - { os: windows-latest , features: feat_os_windows } https://github.com/uutils/coreutils/issues/7044
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1212,7 +1212,7 @@ jobs:
|
||||
needs: [ min_version, deps ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1254,7 +1254,7 @@ jobs:
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1275,7 +1275,7 @@ jobs:
|
||||
needs: [ min_version, deps ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run ShellCheck
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Setup shfmt
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Initialize job variables
|
||||
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
steps:
|
||||
#### Get the code, setup cache
|
||||
- name: Checkout code (uutils)
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: 'uutils'
|
||||
persist-credentials: false
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
with:
|
||||
workspaces: "./uutils -> target"
|
||||
- name: Checkout code (GNU coreutils)
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: 'coreutils/coreutils'
|
||||
path: 'gnu'
|
||||
@@ -170,7 +170,7 @@ jobs:
|
||||
steps:
|
||||
#### Get the code, setup cache
|
||||
- name: Checkout code (uutils)
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: 'uutils'
|
||||
persist-credentials: false
|
||||
@@ -192,7 +192,7 @@ jobs:
|
||||
with:
|
||||
workspaces: "./uutils -> target"
|
||||
- name: Checkout code (GNU coreutils)
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: 'coreutils/coreutils'
|
||||
path: 'gnu'
|
||||
@@ -329,7 +329,7 @@ jobs:
|
||||
|
||||
outputs TEST_SUMMARY_FILE AGGREGATED_SUMMARY_FILE
|
||||
- name: Checkout code (uutils)
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: 'uutils'
|
||||
persist-credentials: false
|
||||
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger --name-match=kvm
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Collect information about runner
|
||||
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
- { package: uu_wc }
|
||||
- { package: uu_factor }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
@@ -156,7 +156,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Initialize workflow variables
|
||||
@@ -194,7 +194,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -206,7 +206,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -230,7 +230,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run test in devcontainer
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install/setup prerequisites
|
||||
shell: bash
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
@@ -130,7 +130,7 @@ jobs:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
name: Build and test uufuzz examples
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
name: Build the fuzzers
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
- { name: fuzz_non_utf8_paths, should_pass: true }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
@@ -211,7 +211,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Download all stats
|
||||
|
||||
+12
-12
@@ -36,7 +36,7 @@ jobs:
|
||||
- { os: macos-latest , features: "feat_os_macos" }
|
||||
- { os: windows-latest , features: "feat_os_windows" }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -76,7 +76,7 @@ jobs:
|
||||
name: L10n/Fluent Syntax Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Setup Python
|
||||
@@ -131,7 +131,7 @@ jobs:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -301,7 +301,7 @@ jobs:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -416,7 +416,7 @@ jobs:
|
||||
- { os: ubuntu-latest , features: "feat_os_unix" }
|
||||
- { os: macos-latest , features: "feat_os_macos" }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -567,7 +567,7 @@ jobs:
|
||||
- { os: ubuntu-latest , features: "feat_os_unix" }
|
||||
- { os: macos-latest , features: "feat_os_macos" }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -900,7 +900,7 @@ jobs:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1131,7 +1131,7 @@ jobs:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1151,7 +1151,7 @@ jobs:
|
||||
name: L10n/Locale Embedding - Cat Utility
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1183,7 +1183,7 @@ jobs:
|
||||
name: L10n/Locale Embedding - Ls Utility
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1215,7 +1215,7 @@ jobs:
|
||||
name: L10n/Locale Embedding - Multicall Binary
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -1252,7 +1252,7 @@ jobs:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
job:
|
||||
- { features: unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Prepare, build and test
|
||||
@@ -121,7 +121,7 @@ jobs:
|
||||
job:
|
||||
- { features: unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Prepare, build and test
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
job:
|
||||
- { os: windows-latest, distribution: Ubuntu-24.04, features: feat_os_unix}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install WSL2
|
||||
|
||||
Generated
+13
-13
@@ -345,18 +345,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.52"
|
||||
version = "4.5.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa8120877db0e5c011242f96806ce3c94e0737ab8108532a76a3300a01db2ab8"
|
||||
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.52"
|
||||
version = "4.5.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02576b399397b659c26064fbc92a75fede9d18ffd5f80ca1cd74ddab167016e1"
|
||||
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -367,9 +367,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.60"
|
||||
version = "4.5.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e602857739c5a4291dfa33b5a298aeac9006185229a700e5810a3ef7272d971"
|
||||
checksum = "39615915e2ece2550c0149addac32fb5bd312c657f43845bb9088cb9c8a7c992"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
@@ -1578,7 +1578,7 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
"portable-atomic-util",
|
||||
"serde_core",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1876,7 +1876,7 @@ version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2034,9 +2034,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parse_datetime"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4955561bc7aa4c40afcfd2a8c34297b13164ae9ac3b30ac348737befdc98e4c"
|
||||
checksum = "acea383beda9652270f3c9678d83aa58cbfc16880343cae0c0c8c7d6c0974132"
|
||||
dependencies = [
|
||||
"jiff",
|
||||
"num-traits",
|
||||
@@ -2441,7 +2441,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.11.0",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2747,7 +2747,7 @@ dependencies = [
|
||||
"getrandom 0.3.3",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4410,7 +4410,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+2
-2
@@ -450,7 +450,7 @@ install: build install-manpages install-completions install-locales
|
||||
mkdir -p $(INSTALLDIR_BIN)
|
||||
ifneq (,$(and $(findstring stdbuf,$(UTILS)),$(findstring feat_external_libstdbuf,$(CARGOFLAGS))))
|
||||
mkdir -p $(DESTDIR)$(LIBSTDBUF_DIR)
|
||||
$(INSTALL) -m 755 $(BUILDDIR)/deps/libstdbuf* $(DESTDIR)$(LIBSTDBUF_DIR)/
|
||||
$(INSTALL) -m 755 $(BUILDDIR)/deps/libstdbuf.* $(DESTDIR)$(LIBSTDBUF_DIR)/
|
||||
endif
|
||||
ifeq (${MULTICALL}, y)
|
||||
$(INSTALL) -m 755 $(BUILDDIR)/coreutils $(INSTALLDIR_BIN)/$(PROG_PREFIX)coreutils
|
||||
@@ -473,7 +473,7 @@ endif
|
||||
|
||||
uninstall:
|
||||
ifneq ($(OS),Windows_NT)
|
||||
rm -f $(DESTDIR)$(LIBSTDBUF_DIR)/libstdbuf*
|
||||
rm -f $(DESTDIR)$(LIBSTDBUF_DIR)/libstdbuf.*
|
||||
-rm -d $(DESTDIR)$(LIBSTDBUF_DIR) 2>/dev/null || true
|
||||
endif
|
||||
ifeq (${MULTICALL}, y)
|
||||
|
||||
+27
-311
@@ -3,271 +3,25 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (ToDO) fname, algo
|
||||
// spell-checker:ignore (ToDO) fname, algo, bitlen
|
||||
|
||||
use clap::builder::ValueParser;
|
||||
use clap::{Arg, ArgAction, Command};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read, Write, stdin, stdout};
|
||||
use std::iter;
|
||||
use std::path::Path;
|
||||
use uucore::checksum::compute::{
|
||||
ChecksumComputeOptions, figure_out_output_format, perform_checksum_computation,
|
||||
};
|
||||
use uucore::checksum::validate::{
|
||||
ChecksumValidateOptions, ChecksumVerbose, perform_checksum_validation,
|
||||
};
|
||||
use uucore::checksum::{
|
||||
ALGORITHM_OPTIONS_BLAKE2B, ALGORITHM_OPTIONS_BSD, ALGORITHM_OPTIONS_CRC,
|
||||
ALGORITHM_OPTIONS_CRC32B, ALGORITHM_OPTIONS_SHA2, ALGORITHM_OPTIONS_SHA3,
|
||||
ALGORITHM_OPTIONS_SYSV, ChecksumError, ChecksumOptions, ChecksumVerbose, HashAlgorithm,
|
||||
LEGACY_ALGORITHMS, SUPPORTED_ALGORITHMS, calculate_blake2b_length_str, detect_algo,
|
||||
digest_reader, perform_checksum_validation, sanitize_sha2_sha3_length_str,
|
||||
AlgoKind, ChecksumError, SUPPORTED_ALGORITHMS, SizedAlgoKind, calculate_blake2b_length_str,
|
||||
sanitize_sha2_sha3_length_str,
|
||||
};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::translate;
|
||||
|
||||
use uucore::{
|
||||
encoding,
|
||||
error::{FromIo, UResult, USimpleError},
|
||||
format_usage,
|
||||
line_ending::LineEnding,
|
||||
os_str_as_bytes, show,
|
||||
sum::Digest,
|
||||
};
|
||||
|
||||
struct Options {
|
||||
algo_name: &'static str,
|
||||
digest: Box<dyn Digest + 'static>,
|
||||
output_bits: usize,
|
||||
length: Option<usize>,
|
||||
output_format: OutputFormat,
|
||||
line_ending: LineEnding,
|
||||
}
|
||||
|
||||
/// Reading mode used to compute digest.
|
||||
///
|
||||
/// On most linux systems, this is irrelevant, as there is no distinction
|
||||
/// between text and binary files. Refer to GNU's cksum documentation for more
|
||||
/// information.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum ReadingMode {
|
||||
Binary,
|
||||
Text,
|
||||
}
|
||||
|
||||
impl ReadingMode {
|
||||
#[inline]
|
||||
fn as_char(&self) -> char {
|
||||
match self {
|
||||
Self::Binary => '*',
|
||||
Self::Text => ' ',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether to write the digest as hexadecimal or encoded in base64.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum DigestFormat {
|
||||
Hexadecimal,
|
||||
Base64,
|
||||
}
|
||||
|
||||
impl DigestFormat {
|
||||
#[inline]
|
||||
fn is_base64(&self) -> bool {
|
||||
*self == Self::Base64
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds the representation that shall be used for printing a checksum line
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum OutputFormat {
|
||||
/// Raw digest
|
||||
Raw,
|
||||
|
||||
/// Selected for older algorithms which had their custom formatting
|
||||
///
|
||||
/// Default for crc, sysv, bsd
|
||||
Legacy,
|
||||
|
||||
/// `$ALGO_NAME ($FILENAME) = $DIGEST`
|
||||
Tagged(DigestFormat),
|
||||
|
||||
/// '$DIGEST $FLAG$FILENAME'
|
||||
/// where 'flag' depends on the reading mode
|
||||
///
|
||||
/// Default for standalone checksum utilities
|
||||
Untagged(DigestFormat, ReadingMode),
|
||||
}
|
||||
|
||||
impl OutputFormat {
|
||||
#[inline]
|
||||
fn is_raw(&self) -> bool {
|
||||
*self == Self::Raw
|
||||
}
|
||||
}
|
||||
|
||||
fn print_legacy_checksum(
|
||||
options: &Options,
|
||||
filename: &OsStr,
|
||||
sum: &str,
|
||||
size: usize,
|
||||
) -> UResult<()> {
|
||||
debug_assert!(LEGACY_ALGORITHMS.contains(&options.algo_name));
|
||||
|
||||
// Print the sum
|
||||
match options.algo_name {
|
||||
ALGORITHM_OPTIONS_SYSV => print!(
|
||||
"{} {}",
|
||||
sum.parse::<u16>().unwrap(),
|
||||
size.div_ceil(options.output_bits),
|
||||
),
|
||||
ALGORITHM_OPTIONS_BSD => {
|
||||
// The BSD checksum output is 5 digit integer
|
||||
let bsd_width = 5;
|
||||
print!(
|
||||
"{:0bsd_width$} {:bsd_width$}",
|
||||
sum.parse::<u16>().unwrap(),
|
||||
size.div_ceil(options.output_bits),
|
||||
);
|
||||
}
|
||||
ALGORITHM_OPTIONS_CRC | ALGORITHM_OPTIONS_CRC32B => {
|
||||
print!("{sum} {size}");
|
||||
}
|
||||
_ => unreachable!("Not a legacy algorithm"),
|
||||
}
|
||||
|
||||
// Print the filename after a space if not stdin
|
||||
if filename != "-" {
|
||||
print!(" ");
|
||||
let _dropped_result = stdout().write_all(os_str_as_bytes(filename)?);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_tagged_checksum(options: &Options, filename: &OsStr, sum: &String) -> UResult<()> {
|
||||
// Print algo name and opening parenthesis.
|
||||
print!(
|
||||
"{} (",
|
||||
match (options.algo_name, options.length) {
|
||||
// Multiply the length by 8, as we want to print the length in bits.
|
||||
(ALGORITHM_OPTIONS_BLAKE2B, Some(l)) => format!("BLAKE2b-{}", l * 8),
|
||||
(ALGORITHM_OPTIONS_BLAKE2B, None) => "BLAKE2b".into(),
|
||||
(name, _) => name.to_ascii_uppercase(),
|
||||
}
|
||||
);
|
||||
|
||||
// Print filename
|
||||
let _dropped_result = stdout().write_all(os_str_as_bytes(filename)?);
|
||||
|
||||
// Print closing parenthesis and sum
|
||||
print!(") = {sum}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_untagged_checksum(
|
||||
filename: &OsStr,
|
||||
sum: &String,
|
||||
reading_mode: ReadingMode,
|
||||
) -> UResult<()> {
|
||||
// Print checksum and reading mode flag
|
||||
print!("{sum} {}", reading_mode.as_char());
|
||||
|
||||
// Print filename
|
||||
let _dropped_result = stdout().write_all(os_str_as_bytes(filename)?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Calculate checksum
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `options` - CLI options for the assigning checksum algorithm
|
||||
/// * `files` - A iterator of [`OsStr`] which is a bunch of files that are using for calculating checksum
|
||||
fn cksum<'a, I>(mut options: Options, files: I) -> UResult<()>
|
||||
where
|
||||
I: Iterator<Item = &'a OsStr>,
|
||||
{
|
||||
let mut files = files.peekable();
|
||||
|
||||
while let Some(filename) = files.next() {
|
||||
// Check that in raw mode, we are not provided with several files.
|
||||
if options.output_format.is_raw() && files.peek().is_some() {
|
||||
return Err(Box::new(ChecksumError::RawMultipleFiles));
|
||||
}
|
||||
|
||||
let filepath = Path::new(filename);
|
||||
let stdin_buf;
|
||||
let file_buf;
|
||||
if filepath.is_dir() {
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
translate!("cksum-error-is-directory", "file" => filepath.maybe_quote())
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle the file input
|
||||
let mut file = BufReader::new(if filename == "-" {
|
||||
stdin_buf = stdin();
|
||||
Box::new(stdin_buf) as Box<dyn Read>
|
||||
} else {
|
||||
file_buf = match File::open(filepath) {
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
show!(err.map_err_context(|| filepath.maybe_quote().to_string()));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
Box::new(file_buf) as Box<dyn Read>
|
||||
});
|
||||
|
||||
let (sum_hex, sz) =
|
||||
digest_reader(&mut options.digest, &mut file, false, options.output_bits)
|
||||
.map_err_context(|| translate!("cksum-error-failed-to-read-input"))?;
|
||||
|
||||
// Encodes the sum if df is Base64, leaves as-is otherwise.
|
||||
let encode_sum = |sum: String, df: DigestFormat| {
|
||||
if df.is_base64() {
|
||||
encoding::for_cksum::BASE64.encode(&hex::decode(sum).unwrap())
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
};
|
||||
|
||||
match options.output_format {
|
||||
OutputFormat::Raw => {
|
||||
let bytes = match options.algo_name {
|
||||
ALGORITHM_OPTIONS_CRC | ALGORITHM_OPTIONS_CRC32B => {
|
||||
sum_hex.parse::<u32>().unwrap().to_be_bytes().to_vec()
|
||||
}
|
||||
ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => {
|
||||
sum_hex.parse::<u16>().unwrap().to_be_bytes().to_vec()
|
||||
}
|
||||
_ => hex::decode(sum_hex).unwrap(),
|
||||
};
|
||||
// Cannot handle multiple files anyway, output immediately.
|
||||
stdout().write_all(&bytes)?;
|
||||
return Ok(());
|
||||
}
|
||||
OutputFormat::Legacy => {
|
||||
print_legacy_checksum(&options, filename, &sum_hex, sz)?;
|
||||
}
|
||||
OutputFormat::Tagged(digest_format) => {
|
||||
print_tagged_checksum(&options, filename, &encode_sum(sum_hex, digest_format))?;
|
||||
}
|
||||
OutputFormat::Untagged(digest_format, reading_mode) => {
|
||||
print_untagged_checksum(
|
||||
filename,
|
||||
&encode_sum(sum_hex, digest_format),
|
||||
reading_mode,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
print!("{}", options.line_ending);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
use uucore::error::UResult;
|
||||
use uucore::line_ending::LineEnding;
|
||||
use uucore::{format_usage, translate};
|
||||
|
||||
mod options {
|
||||
pub const ALGORITHM: &str = "algorithm";
|
||||
@@ -330,46 +84,9 @@ fn handle_tag_text_binary_flags<S: AsRef<OsStr>>(
|
||||
Ok((tag, binary))
|
||||
}
|
||||
|
||||
/// Use already-processed arguments to decide the output format.
|
||||
fn figure_out_output_format(
|
||||
algo: &HashAlgorithm,
|
||||
tag: bool,
|
||||
binary: bool,
|
||||
raw: bool,
|
||||
base64: bool,
|
||||
) -> OutputFormat {
|
||||
// Raw output format takes precedence over anything else.
|
||||
if raw {
|
||||
return OutputFormat::Raw;
|
||||
}
|
||||
|
||||
// Then, if the algo is legacy, takes precedence over the rest
|
||||
if LEGACY_ALGORITHMS.contains(&algo.name) {
|
||||
return OutputFormat::Legacy;
|
||||
}
|
||||
|
||||
let digest_format = if base64 {
|
||||
DigestFormat::Base64
|
||||
} else {
|
||||
DigestFormat::Hexadecimal
|
||||
};
|
||||
|
||||
// After that, decide between tagged and untagged output
|
||||
if tag {
|
||||
OutputFormat::Tagged(digest_format)
|
||||
} else {
|
||||
let reading_mode = if binary {
|
||||
ReadingMode::Binary
|
||||
} else {
|
||||
ReadingMode::Text
|
||||
};
|
||||
OutputFormat::Untagged(digest_format, reading_mode)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sanitize the `--length` argument depending on `--algorithm` and `--length`.
|
||||
fn maybe_sanitize_length(
|
||||
algo_cli: Option<&str>,
|
||||
algo_cli: Option<AlgoKind>,
|
||||
input_length: Option<&str>,
|
||||
) -> UResult<Option<usize>> {
|
||||
match (algo_cli, input_length) {
|
||||
@@ -377,12 +94,12 @@ fn maybe_sanitize_length(
|
||||
(_, None) => Ok(None),
|
||||
|
||||
// For SHA2 and SHA3, if a length is provided, ensure it is correct.
|
||||
(Some(algo @ (ALGORITHM_OPTIONS_SHA2 | ALGORITHM_OPTIONS_SHA3)), Some(s_len)) => {
|
||||
(Some(algo @ (AlgoKind::Sha2 | AlgoKind::Sha3)), Some(s_len)) => {
|
||||
sanitize_sha2_sha3_length_str(algo, s_len).map(Some)
|
||||
}
|
||||
|
||||
// For BLAKE2b, if a length is provided, validate it.
|
||||
(Some(ALGORITHM_OPTIONS_BLAKE2B), Some(len)) => calculate_blake2b_length_str(len),
|
||||
(Some(AlgoKind::Blake2b), Some(len)) => calculate_blake2b_length_str(len),
|
||||
|
||||
// For any other provided algorithm, check if length is 0.
|
||||
// Otherwise, this is an error.
|
||||
@@ -399,7 +116,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
|
||||
let algo_cli = matches
|
||||
.get_one::<String>(options::ALGORITHM)
|
||||
.map(String::as_str);
|
||||
.map(AlgoKind::from_cksum)
|
||||
.transpose()?;
|
||||
|
||||
let input_length = matches
|
||||
.get_one::<String>(options::LENGTH)
|
||||
@@ -416,7 +134,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
|
||||
if check {
|
||||
// cksum does not support '--check'ing legacy algorithms
|
||||
if algo_cli.is_some_and(|algo_name| LEGACY_ALGORITHMS.contains(&algo_name)) {
|
||||
if algo_cli.is_some_and(AlgoKind::is_legacy) {
|
||||
return Err(ChecksumError::AlgorithmNotSupportedWithCheck.into());
|
||||
}
|
||||
|
||||
@@ -436,8 +154,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
// Execute the checksum validation based on the presence of files or the use of stdin
|
||||
|
||||
let verbose = ChecksumVerbose::new(status, quiet, warn);
|
||||
let opts = ChecksumOptions {
|
||||
binary: binary_flag,
|
||||
let opts = ChecksumValidateOptions {
|
||||
ignore_missing,
|
||||
strict,
|
||||
verbose,
|
||||
@@ -449,31 +166,30 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
// Not --check
|
||||
|
||||
// Set the default algorithm to CRC when not '--check'ing.
|
||||
let algo_name = algo_cli.unwrap_or(ALGORITHM_OPTIONS_CRC);
|
||||
let algo_kind = algo_cli.unwrap_or(AlgoKind::Crc);
|
||||
|
||||
let (tag, binary) = handle_tag_text_binary_flags(std::env::args_os())?;
|
||||
|
||||
let algo = detect_algo(algo_name, length)?;
|
||||
let algo = SizedAlgoKind::from_unsized(algo_kind, length)?;
|
||||
let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));
|
||||
|
||||
let output_format = figure_out_output_format(
|
||||
&algo,
|
||||
algo,
|
||||
tag,
|
||||
binary,
|
||||
matches.get_flag(options::RAW),
|
||||
matches.get_flag(options::BASE64),
|
||||
);
|
||||
|
||||
let opts = Options {
|
||||
algo_name: algo.name,
|
||||
digest: (algo.create_fn)(),
|
||||
output_bits: algo.bits,
|
||||
length,
|
||||
let opts = ChecksumComputeOptions {
|
||||
algo_kind: algo,
|
||||
output_format,
|
||||
line_ending,
|
||||
binary: false,
|
||||
no_names: false,
|
||||
};
|
||||
|
||||
cksum(opts, files)?;
|
||||
perform_checksum_computation(opts, files)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -434,6 +434,15 @@ fn process_utf8_line<W: Write>(line: &str, ctx: &mut FoldContext<'_, W>) -> URes
|
||||
let mut iter = line.char_indices().peekable();
|
||||
|
||||
while let Some((byte_idx, ch)) = iter.next() {
|
||||
// Include combining characters with the base character
|
||||
while let Some(&(_, next_ch)) = iter.peek() {
|
||||
if unicode_width::UnicodeWidthChar::width(next_ch).unwrap_or(1) == 0 {
|
||||
iter.next();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let next_idx = iter.peek().map(|(idx, _)| *idx).unwrap_or(line_bytes.len());
|
||||
|
||||
if ch == '\n' {
|
||||
|
||||
@@ -19,7 +19,7 @@ path = "src/hashsum.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = { workspace = true }
|
||||
uucore = { workspace = true, features = ["checksum", "sum"] }
|
||||
uucore = { workspace = true, features = ["checksum", "encoding", "sum"] }
|
||||
fluent = { workspace = true }
|
||||
|
||||
[[bin]]
|
||||
|
||||
+65
-203
@@ -3,54 +3,28 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (ToDO) algo, algoname, regexes, nread, nonames
|
||||
// spell-checker:ignore (ToDO) algo, algoname, bitlen, regexes, nread, nonames
|
||||
|
||||
use clap::ArgAction;
|
||||
use clap::builder::ValueParser;
|
||||
use clap::value_parser;
|
||||
use clap::{Arg, ArgMatches, Command};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read, stdin};
|
||||
use std::iter;
|
||||
use std::num::ParseIntError;
|
||||
use std::path::Path;
|
||||
use uucore::checksum::ChecksumError;
|
||||
use uucore::checksum::ChecksumOptions;
|
||||
use uucore::checksum::ChecksumVerbose;
|
||||
use uucore::checksum::HashAlgorithm;
|
||||
use uucore::checksum::calculate_blake2b_length;
|
||||
use uucore::checksum::create_sha3;
|
||||
use uucore::checksum::detect_algo;
|
||||
use uucore::checksum::digest_reader;
|
||||
use uucore::checksum::escape_filename;
|
||||
use uucore::checksum::perform_checksum_validation;
|
||||
use uucore::display::{Quotable, print_verbatim};
|
||||
use uucore::error::{UResult, strip_errno};
|
||||
use uucore::format_usage;
|
||||
use uucore::sum::{Digest, Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256};
|
||||
use uucore::translate;
|
||||
|
||||
use clap::builder::ValueParser;
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command, value_parser};
|
||||
|
||||
use uucore::checksum::compute::{
|
||||
ChecksumComputeOptions, figure_out_output_format, perform_checksum_computation,
|
||||
};
|
||||
use uucore::checksum::validate::{
|
||||
ChecksumValidateOptions, ChecksumVerbose, perform_checksum_validation,
|
||||
};
|
||||
use uucore::checksum::{AlgoKind, ChecksumError, SizedAlgoKind, calculate_blake2b_length};
|
||||
use uucore::error::UResult;
|
||||
use uucore::line_ending::LineEnding;
|
||||
use uucore::{format_usage, translate};
|
||||
|
||||
const NAME: &str = "hashsum";
|
||||
// Using the same read buffer size as GNU
|
||||
const READ_BUFFER_SIZE: usize = 32 * 1024;
|
||||
|
||||
struct Options<'a> {
|
||||
algoname: &'static str,
|
||||
digest: Box<dyn Digest + 'static>,
|
||||
binary: bool,
|
||||
binary_name: &'a str,
|
||||
//check: bool,
|
||||
tag: bool,
|
||||
nonames: bool,
|
||||
//status: bool,
|
||||
//quiet: bool,
|
||||
//strict: bool,
|
||||
//warn: bool,
|
||||
output_bits: usize,
|
||||
zero: bool,
|
||||
//ignore_missing: bool,
|
||||
}
|
||||
|
||||
/// Creates a hasher instance based on the command-line flags.
|
||||
///
|
||||
@@ -64,10 +38,10 @@ struct Options<'a> {
|
||||
/// the output length in bits or an Err if multiple hash algorithms are specified or if a
|
||||
/// required flag is missing.
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult<HashAlgorithm> {
|
||||
let mut alg: Option<HashAlgorithm> = None;
|
||||
fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult<(AlgoKind, Option<usize>)> {
|
||||
let mut alg: Option<(AlgoKind, Option<usize>)> = None;
|
||||
|
||||
let mut set_or_err = |new_alg: HashAlgorithm| -> UResult<()> {
|
||||
let mut set_or_err = |new_alg: (AlgoKind, Option<usize>)| -> UResult<()> {
|
||||
if alg.is_some() {
|
||||
return Err(ChecksumError::CombineMultipleAlgorithms.into());
|
||||
}
|
||||
@@ -76,80 +50,57 @@ fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult<HashAlgorithm> {
|
||||
};
|
||||
|
||||
if matches.get_flag("md5") {
|
||||
set_or_err(detect_algo("md5sum", None)?)?;
|
||||
set_or_err((AlgoKind::Md5, None))?;
|
||||
}
|
||||
if matches.get_flag("sha1") {
|
||||
set_or_err(detect_algo("sha1sum", None)?)?;
|
||||
set_or_err((AlgoKind::Sha1, None))?;
|
||||
}
|
||||
if matches.get_flag("sha224") {
|
||||
set_or_err(detect_algo("sha224sum", None)?)?;
|
||||
set_or_err((AlgoKind::Sha224, None))?;
|
||||
}
|
||||
if matches.get_flag("sha256") {
|
||||
set_or_err(detect_algo("sha256sum", None)?)?;
|
||||
set_or_err((AlgoKind::Sha256, None))?;
|
||||
}
|
||||
if matches.get_flag("sha384") {
|
||||
set_or_err(detect_algo("sha384sum", None)?)?;
|
||||
set_or_err((AlgoKind::Sha384, None))?;
|
||||
}
|
||||
if matches.get_flag("sha512") {
|
||||
set_or_err(detect_algo("sha512sum", None)?)?;
|
||||
set_or_err((AlgoKind::Sha512, None))?;
|
||||
}
|
||||
if matches.get_flag("b2sum") {
|
||||
set_or_err(detect_algo("b2sum", None)?)?;
|
||||
set_or_err((AlgoKind::Blake2b, None))?;
|
||||
}
|
||||
if matches.get_flag("b3sum") {
|
||||
set_or_err(detect_algo("b3sum", None)?)?;
|
||||
set_or_err((AlgoKind::Blake3, None))?;
|
||||
}
|
||||
if matches.get_flag("sha3") {
|
||||
match matches.get_one::<usize>("bits") {
|
||||
Some(bits) => set_or_err(create_sha3(*bits)?)?,
|
||||
Some(bits @ (224 | 256 | 384 | 512)) => set_or_err((AlgoKind::Sha3, Some(*bits)))?,
|
||||
Some(bits) => return Err(ChecksumError::InvalidLengthForSha(bits.to_string()).into()),
|
||||
None => return Err(ChecksumError::LengthRequired("SHA3".into()).into()),
|
||||
}
|
||||
}
|
||||
if matches.get_flag("sha3-224") {
|
||||
set_or_err(HashAlgorithm {
|
||||
name: "SHA3-224",
|
||||
create_fn: Box::new(|| Box::new(Sha3_224::new())),
|
||||
bits: 224,
|
||||
})?;
|
||||
set_or_err((AlgoKind::Sha3, Some(224)))?;
|
||||
}
|
||||
if matches.get_flag("sha3-256") {
|
||||
set_or_err(HashAlgorithm {
|
||||
name: "SHA3-256",
|
||||
create_fn: Box::new(|| Box::new(Sha3_256::new())),
|
||||
bits: 256,
|
||||
})?;
|
||||
set_or_err((AlgoKind::Sha3, Some(256)))?;
|
||||
}
|
||||
if matches.get_flag("sha3-384") {
|
||||
set_or_err(HashAlgorithm {
|
||||
name: "SHA3-384",
|
||||
create_fn: Box::new(|| Box::new(Sha3_384::new())),
|
||||
bits: 384,
|
||||
})?;
|
||||
set_or_err((AlgoKind::Sha3, Some(384)))?;
|
||||
}
|
||||
if matches.get_flag("sha3-512") {
|
||||
set_or_err(HashAlgorithm {
|
||||
name: "SHA3-512",
|
||||
create_fn: Box::new(|| Box::new(Sha3_512::new())),
|
||||
bits: 512,
|
||||
})?;
|
||||
set_or_err((AlgoKind::Sha3, Some(512)))?;
|
||||
}
|
||||
if matches.get_flag("shake128") {
|
||||
match matches.get_one::<usize>("bits") {
|
||||
Some(bits) => set_or_err(HashAlgorithm {
|
||||
name: "SHAKE128",
|
||||
create_fn: Box::new(|| Box::new(Shake128::new())),
|
||||
bits: *bits,
|
||||
})?,
|
||||
Some(bits) => set_or_err((AlgoKind::Shake128, Some(*bits)))?,
|
||||
None => return Err(ChecksumError::LengthRequired("SHAKE128".into()).into()),
|
||||
}
|
||||
}
|
||||
if matches.get_flag("shake256") {
|
||||
match matches.get_one::<usize>("bits") {
|
||||
Some(bits) => set_or_err(HashAlgorithm {
|
||||
name: "SHAKE256",
|
||||
create_fn: Box::new(|| Box::new(Shake256::new())),
|
||||
bits: *bits,
|
||||
})?,
|
||||
Some(bits) => set_or_err((AlgoKind::Shake256, Some(*bits)))?,
|
||||
None => return Err(ChecksumError::LengthRequired("SHAKE256".into()).into()),
|
||||
}
|
||||
}
|
||||
@@ -199,10 +150,10 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
|
||||
None => None,
|
||||
};
|
||||
|
||||
let algo = if is_hashsum_bin {
|
||||
let (algo_kind, length) = if is_hashsum_bin {
|
||||
create_algorithm_from_flags(&matches)?
|
||||
} else {
|
||||
detect_algo(&binary_name, length)?
|
||||
(AlgoKind::from_bin_name(&binary_name)?, length)
|
||||
};
|
||||
|
||||
let binary = if matches.get_flag("binary") {
|
||||
@@ -214,9 +165,9 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
|
||||
};
|
||||
let check = matches.get_flag("check");
|
||||
let status = matches.get_flag("status");
|
||||
let quiet = matches.get_flag("quiet") || status;
|
||||
let quiet = matches.get_flag("quiet");
|
||||
let strict = matches.get_flag("strict");
|
||||
let warn = matches.get_flag("warn") && !status;
|
||||
let warn = matches.get_flag("warn");
|
||||
let ignore_missing = matches.get_flag("ignore-missing");
|
||||
|
||||
if ignore_missing && !check {
|
||||
@@ -228,16 +179,14 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
|
||||
// on Windows, allow --binary/--text to be used with --check
|
||||
// and keep the behavior of defaulting to binary
|
||||
#[cfg(not(windows))]
|
||||
let binary = {
|
||||
{
|
||||
let text_flag = matches.get_flag("text");
|
||||
let binary_flag = matches.get_flag("binary");
|
||||
|
||||
if binary_flag || text_flag {
|
||||
return Err(ChecksumError::BinaryTextConflict.into());
|
||||
}
|
||||
|
||||
false
|
||||
};
|
||||
}
|
||||
|
||||
// Execute the checksum validation based on the presence of files or the use of stdin
|
||||
// Determine the source of input: a list of files or stdin.
|
||||
@@ -248,52 +197,51 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
|
||||
|
||||
let verbose = ChecksumVerbose::new(status, quiet, warn);
|
||||
|
||||
let opts = ChecksumOptions {
|
||||
binary,
|
||||
let opts = ChecksumValidateOptions {
|
||||
ignore_missing,
|
||||
strict,
|
||||
verbose,
|
||||
};
|
||||
|
||||
// Execute the checksum validation
|
||||
return perform_checksum_validation(
|
||||
input.iter().copied(),
|
||||
Some(algo.name),
|
||||
Some(algo.bits),
|
||||
opts,
|
||||
);
|
||||
return perform_checksum_validation(input.iter().copied(), Some(algo_kind), length, opts);
|
||||
} else if quiet {
|
||||
return Err(ChecksumError::QuietNotCheck.into());
|
||||
} else if strict {
|
||||
return Err(ChecksumError::StrictNotCheck.into());
|
||||
}
|
||||
|
||||
let nonames = *matches
|
||||
let no_names = *matches
|
||||
.try_get_one("no-names")
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(&false);
|
||||
let zero = matches.get_flag("zero");
|
||||
let line_ending = LineEnding::from_zero_flag(matches.get_flag("zero"));
|
||||
|
||||
let opts = Options {
|
||||
algoname: algo.name,
|
||||
digest: (algo.create_fn)(),
|
||||
output_bits: algo.bits,
|
||||
let algo = SizedAlgoKind::from_unsized(algo_kind, length)?;
|
||||
|
||||
let opts = ChecksumComputeOptions {
|
||||
algo_kind: algo,
|
||||
output_format: figure_out_output_format(
|
||||
algo,
|
||||
matches.get_flag(options::TAG),
|
||||
binary,
|
||||
/* raw */ false,
|
||||
/* base64: */ false,
|
||||
),
|
||||
line_ending,
|
||||
binary,
|
||||
binary_name: &binary_name,
|
||||
tag: matches.get_flag("tag"),
|
||||
nonames,
|
||||
//status,
|
||||
//quiet,
|
||||
//warn,
|
||||
zero,
|
||||
//ignore_missing,
|
||||
no_names,
|
||||
};
|
||||
|
||||
let files = matches.get_many::<OsString>(options::FILE).map_or_else(
|
||||
// No files given, read from stdin.
|
||||
|| Box::new(iter::once(OsStr::new("-"))) as Box<dyn Iterator<Item = &OsStr>>,
|
||||
// At least one file given, read from them.
|
||||
|files| Box::new(files.map(OsStr::new)) as Box<dyn Iterator<Item = &OsStr>>,
|
||||
);
|
||||
|
||||
// Show the hashsum of the input
|
||||
match matches.get_many::<OsString>(options::FILE) {
|
||||
Some(files) => hashsum(opts, files.map(|f| f.as_os_str())),
|
||||
None => hashsum(opts, iter::once(OsStr::new("-"))),
|
||||
}
|
||||
perform_checksum_computation(opts, files)
|
||||
}
|
||||
|
||||
mod options {
|
||||
@@ -524,89 +472,3 @@ fn uu_app(binary_name: &str) -> (Command, bool) {
|
||||
|
||||
(command, is_hashsum_bin)
|
||||
}
|
||||
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn hashsum<'a, I>(mut options: Options, files: I) -> UResult<()>
|
||||
where
|
||||
I: Iterator<Item = &'a OsStr>,
|
||||
{
|
||||
let binary_marker = if options.binary { "*" } else { " " };
|
||||
let mut err_found = None;
|
||||
for filename in files {
|
||||
let filename = Path::new(filename);
|
||||
|
||||
let mut file = BufReader::with_capacity(
|
||||
READ_BUFFER_SIZE,
|
||||
if filename == OsStr::new("-") {
|
||||
Box::new(stdin()) as Box<dyn Read>
|
||||
} else {
|
||||
let file_buf = match File::open(filename) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"{}: {}: {}",
|
||||
options.binary_name,
|
||||
filename.maybe_quote(),
|
||||
strip_errno(&e)
|
||||
);
|
||||
err_found = Some(ChecksumError::Io(e));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
Box::new(file_buf) as Box<dyn Read>
|
||||
},
|
||||
);
|
||||
|
||||
let sum = match digest_reader(
|
||||
&mut options.digest,
|
||||
&mut file,
|
||||
options.binary,
|
||||
options.output_bits,
|
||||
) {
|
||||
Ok((sum, _)) => sum,
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"{}: {}: {}",
|
||||
options.binary_name,
|
||||
filename.maybe_quote(),
|
||||
strip_errno(&e)
|
||||
);
|
||||
err_found = Some(ChecksumError::Io(e));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let (escaped_filename, prefix) = escape_filename(filename);
|
||||
if options.tag {
|
||||
if options.algoname == "blake2b" {
|
||||
if options.digest.output_bits() == 512 {
|
||||
println!("BLAKE2b ({escaped_filename}) = {sum}");
|
||||
} else {
|
||||
// special case for BLAKE2b with non-default output length
|
||||
println!(
|
||||
"BLAKE2b-{} ({escaped_filename}) = {sum}",
|
||||
options.digest.output_bits()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
println!(
|
||||
"{prefix}{} ({escaped_filename}) = {sum}",
|
||||
options.algoname.to_ascii_uppercase()
|
||||
);
|
||||
}
|
||||
} else if options.nonames {
|
||||
println!("{sum}");
|
||||
} else if options.zero {
|
||||
// with zero, we don't escape the filename
|
||||
print!("{sum} {binary_marker}");
|
||||
print_verbatim(filename).unwrap();
|
||||
print!("\0");
|
||||
} else {
|
||||
println!("{prefix}{sum} {binary_marker}{escaped_filename}");
|
||||
}
|
||||
}
|
||||
match err_found {
|
||||
None => Ok(()),
|
||||
Some(e) => Err(Box::new(e)),
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user