-
Notifications
You must be signed in to change notification settings - Fork 0
/
csum
executable file
·108 lines (86 loc) · 2.16 KB
/
csum
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/bin/bash
# version 1.0
set -eu
run() {
echo>&2 "+ $*"
"$@"
}
usage() {
cat >&2 <<EOM
usage: $(basename "$0") FILE...
Check a checksum file and associated gnupg signatures.
For each checksum FILE listed, verify the GnuPG signature from FILE.gpg, then
determine what hash (md5, sha1, sha2) algorithm it uses, and check all of the
checksums of the listed files.
Hashes of missing files will be silently skipped (using --ignore-missing).
This is especially useful for verifying the SHA256SUMS, SHA256SUMS.gpg files
that accompany software downloads.
EOM
}
if [ $# -eq 0 ]; then
usage
exit 1
fi
colorecho() {
color="$1"
shift
if [ ! -t 1 ]; then
echo "$*"
return
fi
case "$color" in
black|gray|grey) fg=30 ;;
red) fg=31 ;;
green) fg=32 ;;
yellow) fg=33 ;;
blue) fg=34 ;;
magenta|purple|violet) fg=35 ;;
cyan) fg=36 ;;
white) fg=37 ;;
*)
echo >&2 "colorecho: unknown color: $color"
return 1
;;
esac
echo -ne "\033[1;${fg}m"
echo -n "$*"
echo -e "\033[m"
}
errx() {
code=$1
shift
colorecho red "$(basename "$0"): $*" >&2
exit "$code"
}
warn() {
colorecho yellow "$(basename "$0"): $*" >&2
}
delayerr=
for file in "$@"; do
first_hash="$(head -1 "$file" | cut -f 1 -d' ')"
hashlen=${#first_hash}
case $hashlen in
32) cmd=md5sum ;;
40) cmd=sha1sum ;;
56) cmd=sha224sum ;;
64) cmd=sha256sum ;;
98) cmd=sha384sum ;;
128) cmd=sha512sum ;;
*)
errx 3 "'$file' has unexpected hash length: $hashlen"
;;
esac
if [ -r "$file.gpg" ]; then
run gpg --verify "$file.gpg" "$file"
else
warn "Warning: no signature found at $file.gpg"
delayerr=5
fi
run "$cmd" -c --strict --ignore-missing "$file" && ret=$? || ret=$?
if [ "$ret" -ne 0 ]; then
errx "$ret" "$cmd exited with error status $ret"
fi
done
if [ -n "$delayerr" ]; then
exit "$delayerr"
fi