summaryrefslogtreecommitdiff
path: root/misc/verify
blob: 5f0430ce8cdd69efe2c86a781c04b6b280b63991 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/bin/sh
NORM="\033[0m"
CYN="\033[0;36m"
GRN="\033[0;32m"
RED="\033[0;31m"

printhelp() {
cat << HELPDOC
Usage: $(basename "$0") [options] [file/directory]...

OPTIONS:
  -m, --md5                Create/verify md5 checksum
  -s[mode], --sha[mode]    Create/verify sha[mode] checksum
  -x[mode], --xxh[mode]    Create/verify xxh[mode] checksum (default)
  -c [alg], --crypt [alg]  Create/verify [alg] checksum (uses [alg]sum program; e.g. '-c sha256' uses sha256sum)
  -v, --verify             Verify files with existing checksums
  -h, --help               Print help
HELPDOC
}

crypt=xxh
while true; do
	case "$1" in
		-m|--md5)	crypt=md5 ;;
		-s*|--sha*)	crypt=sha$(echo "$1" | tr -cd [:digit:]) ;;
		-x*|--xxh*)	crypt=xxh$(echo "$1" | tr -cd [:digit:]) ;;
		-c|--crypt)	crypt=$2 && shift ;; # Shift twice
		-v|--verify)	verify=1 ;;
		-h|--help)	printhelp; exit 0 ;;
		-*)		printhelp; exit 2 ;;
		*)		break ;;
	esac
	shift
done
hashalg=${crypt}sum
command -v $hashalg >/dev/null || (echo "Hashing algorithm '$hashalg' does not exist!" && exit 2)

while [ -n "$1" ]; do
	file="$1"
	[ ! "`echo "$file" | sed "s/.$crypt$//"`" = "$file" ] && shift && continue # Skip hash files
	[ ! -e "$file" ] && echo "file '$file' does not exist!" && exit 1
	[ -d "$file" ] && type=directory || type=file
	hashfile="$file.$crypt"
	[ -n "$verify" ] && [ ! -e "$hashfile" ] && shift && continue # Skip files without a hash in verify mode

	echo "Getting $crypt checksum of $type '$file'..."
	hash=`find "$file" -type f -print0 | sort -z | xargs -r0 pv -EE -F'%r [%b] [%t] [%e] %p' | $hashalg | cut -d' ' -f1`

	if [ -e "$hashfile" ]; then
		phash=`cat "$hashfile"`
		[ $phash = $hash ] \
			&& echo "${GRN}Success: $type matches saved checksum!" \
			|| (echo "${RED}Error: $type does not match saved checksum!\nExpected checksum: $phash\nActual checksum: $hash" && ec=1)
	else
		echo $hash > "$hashfile" \
			&& echo "${CYN}$crypt checksum file saved at '$hashfile'!" \
			|| (echo "${RED}'$hashfile' could not be created!\n$crypt checksum of $type '$file' is $hash" && ec=1)
	fi
	printf "$NORM"; [ -n "$2" ] && echo
	shift
done
exit $ec