From fb0543dfe4e7023da35ffa43935a091c2e3ac1aa Mon Sep 17 00:00:00 2001 From: Q Date: Thu, 29 Feb 2024 21:30:19 +0200 Subject: [PATCH] new hashing --- bin/hash-update | 1 + files/hash-update | 129 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 120000 bin/hash-update create mode 100755 files/hash-update diff --git a/bin/hash-update b/bin/hash-update new file mode 120000 index 0000000..c5e4cee --- /dev/null +++ b/bin/hash-update @@ -0,0 +1 @@ +../files/hash-update \ No newline at end of file diff --git a/files/hash-update b/files/hash-update new file mode 100755 index 0000000..06a26ba --- /dev/null +++ b/files/hash-update @@ -0,0 +1,129 @@ +#!/bin/bash + +function helpexit() { + echo 'Create or append md5/sha* list of files +Usage: + Creating hashes: hash-update [-r] [-t hash-type] [-f list_name] [[files to hash]] + Checking hashes: hash-update -c [-f list_name] + -r recursive + -c check + -t hash-type defaults to sha256. choose from md5, sha1, sha256, sha512 etc.. + -f list_name is [type]sums.txt by default + If files to check omitted, list files in current folder + + Check files with "sha256sum -c sha256sums.txt", or passing -c to this script. + To update hashes, simply delete the sha256sums file. +' + exit +} + +function valid_type() { + local valid + for valid in b2 md5 sha1 sha224 sha256 sha384 sha512; do + if [[ "$1" = "$valid" ]]; then + return 0 + fi + done + return 1 +} + +recursive=0 +check=0 +hashtype=sha256 + +paths=() +for ((i=1; i<=${#@}; i++)) { + j=$(( i + 1 )) + [[ "${!i}" = "-h" ]] && helpexit + [[ "${!i}" = "--help" ]] && helpexit + [[ "${!i}" = "-r" ]] && { recursive=1; continue; } + [[ "${!i}" = "-c" ]] && { check=1; continue; } + [[ "${!i}" = "-t" ]] && { hashtype="${!j}"; i=$(( $i + 1 )); continue; } + [[ "${!i}" = "-f" ]] && { list_name="${!j}"; i=$(( $i + 1 )); continue; } + paths+=("${!i}") +} +valid_type "$hashtype" || { + echo Type "$hashtype" is not valid. + echo Choose from b2 md5 sha1 sha224 sha256 sha384 sha512 + exit 1 +} + +if [[ -z "$list_name" ]]; then + list_name="${hashtype}sums.txt" +fi +SUMBIN="${hashtype}sum" +which $SUMBIN &>/dev/null || { + echo $SUMBIN not in PATH + exit 1 +} + +if [[ $check -eq 1 ]]; then + $SUMBIN -c "$list_name" + exit $? +fi + +if [[ ${#paths[@]} -eq 0 ]]; then + paths+=(".") +fi +which pv &>/dev/null && PVBIN=$( which pv ) +set -e +echo "Updating: $list_name" +test -f "$list_name" || touch "$list_name" +updates_done=0 +_update() { + if [ "$1" = "$list_name" ]; then + return + fi + if [[ -L "$1" ]]; then + echo "$1 is a symlink" + return + fi + if test -d "$1"; then + echo "$1 is a directory" + return + fi + if test -f "$1"; then + if sed 's,^[^ ]\+ ,,' "$list_name" | grep -qFx "$1"; then + echo "Exists: $1" + else + echo "New: $1" + size=$( stat -c %s "$1" ) + if [[ $size -gt 100000000 ]] && [[ -n "$PVBIN" ]]; then + # Use pv is size > 100MB + sum=$( $PVBIN "$1" | $SUMBIN | awk '{ print $1 }' ) + printf "%s %s\n" "$sum" "$1" >> "$list_name" + else + $SUMBIN "$1" >> "$list_name" + fi + updates_done=1 + fi + fi +} +shopt -s globstar +shopt -s nullglob +for ((i=0; i<=${#paths[@]}; i++)) { + if [[ -d "${paths[$i]}" ]]; then + pathname="${paths[$i]}" + pathname="${pathname%%/}" + if [[ "$recursive" -eq 1 ]]; then + for file in "${pathname}"/**; do + file="${file#./}" + _update "$file" + done + else + for file in "${pathname}"/*; do + file="${file#./}" + _update "$file" + done + fi + fi + if [[ -f "${paths[$i]}" ]]; then + file="${paths[$i]}" + file="${file#./}" + _update "$file" + fi +} + +if [[ $updates_done -eq 1 ]]; then + sort -k 2 -o "$list_name" "$list_name" +fi