diff options
Diffstat (limited to 'misc/verifoo')
| -rwxr-xr-x | misc/verifoo | 110 | 
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  | 
