summaryrefslogtreecommitdiff
path: root/misc/verifoo
diff options
context:
space:
mode:
authorTimmy Keller <tjk@tjkeller.xyz>2024-09-02 08:44:38 -0500
committerTimmy Keller <tjk@tjkeller.xyz>2024-09-02 08:44:38 -0500
commita4373a898e65604f58299c947882f50294dd813f (patch)
treed07fd4eb4ccf9fef1fa8a73d1160b7174c7c317e /misc/verifoo
parent988cadef2c2e51adbfa64da83ec7d25a8de3d924 (diff)
downloadscripts-a4373a898e65604f58299c947882f50294dd813f.tar.xz
scripts-a4373a898e65604f58299c947882f50294dd813f.zip
various changes over time
Diffstat (limited to 'misc/verifoo')
-rwxr-xr-xmisc/verifoo110
1 files changed, 110 insertions, 0 deletions
diff --git a/misc/verifoo b/misc/verifoo
new file mode 100755
index 0000000..34089cb
--- /dev/null
+++ b/misc/verifoo
@@ -0,0 +1,110 @@
+#!/bin/sh
+
+help() {
+cat << HELPDOC
+usage: $(basename "$0") [options] [file]...
+
+OPTIONS:
+ -h, --help show this menu
+ -c, --check read and verify checksums from file
+ -r, --recursive produce a checksum for all files in a directory recursively
+ --recursive-sum produce a checksum for a directory. sensitive to filenames
+ --recursive-sum-nopath produce a checksum for a directory. not sensitive to filenames/placement
+ -s, --silent produce no output to stderr
+ -v, --verbose output a progress bar of hash progress if pv is avaliable (wip)
+
+MODES:
+ -S, --sha use sha1sum for checksums
+ -M, --md5 use md5sum for checksums
+ -X, --xxh use xxhsum for checksums (default if avaliable with sha1sum as fallback)
+HELPDOC
+}
+
+# set defaults
+cat="pv -F'%r_[%b]_[%t]_[%e]_%p'"
+! command -v pv >/dev/null && cat=cat
+
+hash=xxhsum
+! command -v xxhsum >/dev/null && hash=sha1sum
+
+hashfiles=""
+verbose=1
+recursive=""
+outputfile=""
+
+while true; do
+ case "$1" in
+ -c|--check) [ -n "$2" ] && hashfiles="$hashfiles $2" && shift ;;
+ -s|--silent) verbose=0 ;;
+ -v|--verbose) verbose=2 ;;
+ --recursive|-r) recursive=3 ;;
+ --recursive-sum) recursive=2 ;;
+ --recursive-sum-nopath) recursive=1 ;;
+ -S|--sha) hash=sha1sum ;;
+ -M|--md5) hash=md5sum ;;
+ -X|--xxh) hash=xxhsum ;;
+ -h|--help) help; exit 0 ;;
+ -*) help; exit 1 ;;
+ *) break ;;
+ esac
+ shift
+done
+
+case $verbose in
+ 0) cat=cat ;;
+ 1) cat=cat ;;
+esac
+
+# run hash
+while [ -n "$1" ]; do
+ if [ -d "$1" ]; then # is directory
+ # check if using -r flag
+ case "$recursive" in
+ 1)
+ # get hash of all files, sort hashes, hash hashes
+ # TODO make pv work in this mode
+
+ #catd="$cat"
+ #if [ $verbose -ge 2 ] && [ "$catd" != "cat" ]; then
+ # total_files=$(du -a "$1" | wc -l)
+ # catd="pv -l -s$total_files -F'[%b/$total_files]_[%t]_[%e]_%p'"
+ #fi
+ #sum=`find "$1" -type f -print0 | xargs -r0 $hash | $catd | cut -d' ' -f1 | sort | $hash | cut -d' ' -f1` 2>/dev/null
+ sum=`find "$1" -type f -print0 | xargs -r0 $hash | cut -d' ' -f1 | sort | $hash | cut -d' ' -f1` 2>/dev/null
+ echo "r/$sum $1"
+ ;;
+ 2)
+ # hash sorted filenames
+ # sort all filenames w/ full path and hash
+ # hash those sums together
+ # `tar -c -f - "$1" | $hash` is a good idea but it doesn't work since changes to the fs affect tar
+ filehash=`find "$1" -type f -print0 | sort -z | xargs -r0 $cat | $hash | cut -d' ' -f1`
+ pathhash=`find "$1" -printf "%P\0" | sort -z | $hash | cut -d' ' -f1`
+ sum=`printf "$filehash$pathhash" | $hash | cut -d' ' -f1`
+ echo "p/$sum $1"
+ ;;
+ 3)
+ # sort files and hash each one in sequence
+ # TODO make pv work in this mode
+ find "$1" -type f -print0 | sort -z | xargs -r0 $hash
+ ;;
+ *)
+ [ $verbose -ge 1 ] && echo "-r not specified for directory $1. Exiting"
+ exit 1
+ ;;
+ esac
+ else # is file
+ if ! [ -f "$1" ]; then
+ [ $verbose -gt 1 ] && echo "File $1 does not exist. Exiting"
+ exit 1
+ fi
+ files="$1"
+
+ while [ -f "$2" ]; do
+ files="$files\0$2"
+ shift
+ done
+ printf "$files" | xargs -r0 $hash
+ fi
+ shift
+done