corz.org uses cookies to remember that you've seen this notice explaining that corz.org uses cookies, okay!
set -e
algorithm='md5'
hashext='hash'
append=1
extensionless=1
force_zenity=0
hybrid=1
ignore_extensions=('desktop' 'ini' 'lnk' 'directory' 'nfo' 'm3u' 'pls' 'url' 'sfv')
fallback_dir="$HOME/Hashes"
tmpfile='/tmp/checksum.tmp'
errlog='/tmp/checksum-errors.log'
keep_errlog=0
dh_max=600
show_times=1
mode=
mask=
folder=0
filebad=0
notifypid=0
existing=()
fb=0
diag_height=600
me="${0
path="${!
opath="$path"
here="$(pwd)"
rm -rf "$errlog"
rm -rf "$tmpfile"
start_time=$(date +%s)
SwitchAlgo() {
case "$1" in
sha1)
algo='sha1'
tool='sha1sum'
hashlen=40
;;
sha2)
algo='sha2'
tool='sha256sum'
hashlen=64
;;
sha3)
algo='sha3'
tool='sha384sum'
hashlen=96
;;
sha5)
algo='sha5'
tool='sha512sum'
hashlen=128
;;
*)
algo='md5'
tool='md5sum'
hashlen=32
;;
esac
}
CheckMultiHash() {
cat "$1" | while read line; do
xhash=${line%% *}
file=${line
if [[ $xhash =~ ^[[:xdigit:]]+$ ]]; then
if [[ ! -f "$file" ]]; then
echo "$file: $algo: MISSING"
echo "$1: $algo: MISSING: $file" >> "$errlog"
continue
fi
case ${
32)
SwitchAlgo 'md5'
nnh=$($tool "$file")
nnh=${nnh:0:32}
;;
40)
SwitchAlgo 'sha1'
nnh=$($tool "$file")
nnh=${nnh:0:40}
;;
64)
SwitchAlgo 'sha2'
nnh=$($tool "$file")
nnh=${nnh:0:64}
;;
96)
SwitchAlgo 'sha3'
nnh=$($tool "$file")
nnh=${nnh:0:96}
;;
128)
SwitchAlgo 'sha5'
nnh=$($tool "$file")
nnh=${nnh:0:128}
;;
*)
continue
;;
esac
if [[ "$nnh" = "$xhash" ]]; then
echo "$file: $algo: OK"
else
echo "$file: $algo: FAILED"
echo "$1: $algo: FAILED: $file" >> "$errlog"
fi
fi
done | tee -a "$tmpfile"
}
SetDialogHeight() {
fl=$(wc -l < "$1" )
diag_height=$((100+(fl*=30)))
if [[ $diag_height -gt $dh_max ]] || [[ $diag_height -lt 50 ]]; then diag_height=$dh_max; fi
}
grabhashes() {
while read; do
hash=${REPLY%% *}
[[ ${
done < "$1"
}
notify_user() {
case $dlg_mode in
0)
echo
echo "$2 hashes in \"$1\" .."
echo "** To abort, press Ctrl-C **"
echo
;;
1 | 3)
zenity --notification --text="checksum: $3 in progress (click to hide)" \
--window-icon="$HOME/.local/share/icons/checksum.png" &
notifypid="$!"
;;
2)
kdialog --title "Checksum: $3 in progress.." --passivepopup \
"(click here to hide this notification)" 5
;;
esac
}
log_out() {
if [[ -s "$errlog" ]]; then
echo "" >> "$tmpfile"
echo "THERE WERE ERRORS!" >> "$tmpfile"
echo "" >> "$tmpfile"
cat "$errlog" >> "$tmpfile"
else
echo "" >> "$tmpfile"
echo "All checksums 100% AOK!" >> "$tmpfile"
fi
}
TestDirWrite() {
tname="$1.$(date +%s%N).test"
echo "write***test" > "$tname"
wtest=$(cat "$tname")
rm -rf "$tname"
if [[ $wtest = "write***test" ]]; then
rodir=0
else
rodir=1
fi
return 0
} > /dev/null 2>&1 || true
case "$me" in
k*)
dlg_mode=2
;;
g*)
dlg_mode=1
;;
*)
dlg_mode=0
;;
esac
case "$me" in
*md5) algorithm="md5" ;;
*sha1) algorithm="sha1" ;;
*sha2) algorithm="sha2" ;;
*sha3) algorithm="sha3" ;;
*sha5) algorithm="sha5" ;;
esac
while [[ $
case "$1" in
--kde) dlg_mode=2 ;;
--zenity | --zen) force_zenity=1 ;;
--hybrid) hybrid=1 ;;
--xl) extensionless=1 ;;
--append) append=1 ;;
--noappend) append=0 ;;
--algo) hashext="algo" ;;
--md5) algorithm="md5" ;;
--sha | --sha1) algorithm="sha1" ;;
--sha2) algorithm="sha2" ;;
--sha3) algorithm="sha3" ;;
--sha5) algorithm="sha5" ;;
--mask*) mask="$1" ;;
esac
shift
done
SwitchAlgo "$algorithm"
hash_types=([0]="md5" [1]="sha1" [2]="sha2" [3]="sha3" [4]="sha5")
for i in "${hash_types[@]}"; do
if [[ $i = "$hashext" ]]; then
hashext="algo"
break
fi
done
[[ "$hashext" = "algo" ]] && hashext="$algo"
ignore_extensions=("$hashext" "${hash_types[@]}" "${ignore_extensions[@]}")
if [[ $hybrid -eq 1 ]] && [[ $dlg_mode -ne 0 ]]; then
dlg_mode=3;
[[ ! -x /usr/bin/zenity ]] && dlg_mode=2;
[[ ! -x /usr/bin/kdialog ]] && dlg_mode=1;
fi
[[ $force_zenity -eq 1 ]] && [[ $dlg_mode -eq 2 ]] && dlg_mode=1
[[ ! -x /usr/bin/kdialog ]] && [[ $dlg_mode -eq 2 ]] && dlg_mode=1
if [[ ! -x /usr/bin/zenity ]] && [[ $dlg_mode -eq 1 ]]; then
if [[ -x /usr/bin/kdialog ]]; then
dlg_mode=2
else
dlg_mode=0
echo "*** NOTE ***"
echo "Checksum can use zentiy to display dialogs in your desktop. "
echo "To install zenity (on a debian-based system, like Ubuntu) do:"
echo
echo " sudo apt-get install zenity"
echo
echo "For other systems, check your package manager's man page, or"
echo "compile from source. See: http://freshmeat.net/projects/zenity"
echo
fi
fi
case "$me" in
checksum* | kchecksum* | gchecksum*)
mode="create"
usg_str=""
;;
verify* | kverify* | gverify*)
mode="verify"
usg_str="Hash "
;;
esac
[[ "$mode" = '' ]] && exit 2
if [[ "$path" = "$0" ]] || [[ ! -a "$path" ]]; then
msg='*** NO PATH WAS SPECIFIED! ***'
gmsg='Something bad happened. Please reinstall checksum!'
if [[ "$path" = "$0" ]]; then
msg='*** NO SUCH PATH! ***'
gmsg='Checksum got sent a non-existant path!!!'
fi
case $dlg_mode in
0)
echo
echo "$msg"
echo
echo "Usage: To $mode hashes.."
echo
echo $me' <'$usg_str'File|Directory>'
echo
;;
1 | 3)
zenity --error --title 'Error!!!' --text "$gmsg" \
--width=280 --timeout=20 --window-icon="$HOME/.local/share/icons/checksum.png"
;;
2)
kdialog --error "$gmsg" -title 'Checksum Error! '
;;
esac
exit 1
fi
filename=${path
fileext=${filename
[[ -d "$path" ]] && folder=1
[[ "$fileext" = "$filename" ]]&& fileext=""
if [[ -f "$path" ]] && [[ "$mode" = "create" ]]; then
if [[ "$fileext" = "$algo" ]] || [[ "$fileext" = "$hashext" ]]; then
hasherr='This is a checksum file. You can verify it.'
case $dlg_mode in
0)
echo "$hasherr"
;;
1 | 3)
zenity --info --title "Hashes Of Hashes!" --text="$hasherr" --timeout=10 \
--window-icon="$HOME/.local/share/icons/checksum.png"
;;
2)
kdialog --msgbox "$hasherr" --title "Checksum WHAT!?! "
;;
esac
exit 11
fi
fi
if [[ "$mode" = "create" ]]; then
if [[ $folder -eq 1 ]]; then
if [[ "${path%quot; == "$path" ]]; then local" shell usage.. cd foo && checksum bar
hashfile="$filename.$hashext"
original" path, for any fall-back hashing..
opath="$here/$path"
else
hashfile="$path/$filename.$hashext"
fi
cd "$path"
else
if [[ "${path%quot; == "$path" ]]; then
path="./"
fi
if [[ $extensionless -eq 1 ]]; then
hashfile="${path%${filename%\.*}.$hashext"
else
hashfile="${path%$filename.$hashext"
fi
cd "${path%
fi
if [[ ! -f "$hashfile" ]]; then
TestDirWrite $hashfile
[[ $rodir -eq 1 ]] && fb="$hashfile"
else
if [[ ! -w "$hashfile" ]]; then
fb="$hashfile"
else
if [[ $append -eq 1 ]]; then
grabhashes "$hashfile"
else
case $dlg_mode in
0)
until [[ "$answer" != "" ]]; do
echo
echo 'HASH FILE EXISTS!'
echo 'Do you wish to overwrite it?'
echo
select answer in yes no; do
[[ "$answer" != 'yes' ]] && exit 9
break
done
done
echo
;;
1)
zanswer=$(zenity --question --title='Checksum File Exists!!!' --width=280 \
--text="A checksum file already exists.\nShall I overwrite it?" \
--timeout=10 --window-icon="$HOME/.local/share/icons/checksum.png")
[[ "$zanswer" ]] && exit 9
;;
2 | 3)
kdialog \
--warningyesno " A checksum file already exists. \n Shall I overwrite it? " \
--dontagain 'checksum:do_overwrite' \
--title 'Checksum File Exists!!! '
;;
esac
fi
fi
fi
if [[ "$fb" != 0 ]]; then
[[ ! -d "$fallback_dir" ]] && mkdir "$fallback_dir"
hashfile="$fallback_dir/${hashfile}"
[[ -f "$hashfile" ]] && grabhashes "$hashfile"
fi
if [[ ! -f "$hashfile" ]] || [[ $append -eq 0 ]]; then
echo '
echo '
[[ "$fb" != 0 ]] && echo " >> "$hashfile"
fi
if [[ ! -w "$hashfile" ]]; then
echo 'I am having trouble creating the checksum file.'
echo "Check the permission on your fallback location: $fallback_dir"
exit 9
fi
notify_user "$hashfile" 'Creating' 'Hashing'
if [[ $folder -eq 1 ]]; then
if [[ "$mask" != '' ]]; then
fmask=
mask="${mask # remove "--mask=" part
until [[ "$mask" = ',' ]]; do
tmask=$(echo "$mask" | cut -d\, -f1)
fmask=" -iname '$tmask'$fmask"
mask="${mask
[[ "$(echo "$mask" | cut -s -d\, -f1)" = "" ]] && mask="$mask,"
[[ "$mask" != ',' ]] && fmask=" -o $fmask"
done
fi
[[ "$fmask" != '' ]] && fmask=" \( $fmask \) "
eval "find . -type f ${fmask} -print" | while read i; do
thisname="${i
thisext="${thisname
for j in "${ignore_extensions[@]}"; do
if [[ $j = "$thisext" ]]; then
[[ $dlg_mode -eq 0 ]] && echo "*** ** skipping IGNORED file ** *** ${i
continue 2
fi
done
if [[ $append -eq 1 ]]; then
for xfile in "${existing[@]}"; do
if [[ "$xfile" = "$i" ]]; then
[[ $dlg_mode -eq 0 ]] && echo "*** ** skipping checked file ** *** ${i
continue 2
fi
done
fi
if [[ "$fb" != 0 ]]; then
$tool -b "${opath}/${i 2>>"$errlog" | tee -a "$hashfile"
else
$tool -b "${i}" 2>>"$errlog" | tee -a "$hashfile"
fi
done
else
if [[ "$fb" != 0 ]]; then
echo "fallback hash foo"
$tool -b "${i}" 2>>"$errlog" | tee -a "$hashfile"
else
$tool -b "$filename" 2>>"$errlog" | tee -a "$hashfile"
fi
SetDialogHeight "$hashfile"
fi
[[ "$notifypid" -ne 0 ]] && kill "$notifypid"
case $dlg_mode in
0)
echo
echo 'All done with hashing.'
echo
;;
1)
zenity --info --title 'All Done!' --text='Checksum operation complete. ' --timeout=10 \
--window-icon="$HOME/.local/share/icons/checksum.png"
;;
2 | 3)
kdialog --msgbox ' Checksum operation complete! ' \
--title 'Checksum Complete! ' \
--dontagain 'checksum:notify_when_complete'
;;
esac
else
if [[ $folder -eq 1 ]]; then
notify_user "${path% 'Verifying' 'verification'
cd "$path"
find . -type f \( -name "*.$hashext" -o -name "*.${hash_types[0]}" \
-o -name "*.${hash_types[1]}" -o -name "*.${hash_types[2]}" \
-o -name "*.${hash_types[3]}" -o -name "*.${hash_types[4]}" \) -print | while read i; do
chkerror=0
hashfname="${i}"
thishext="${hashfname
cd "$path/${i%quot;
echo "$hashfname: " >> "$tmpfile"
if [[ "$thishext" = "$hashext" ]]; then
CheckMultiHash "$hashfname"
else
SwitchAlgo "$thishext"
cout=$($tool --check -- "$hashfname" 2>>"$errlog") || chkerror=1
echo "$cout" | tee -a "$tmpfile"
fi
if [[ "$chkerror" == 1 ]]; then
echo "IN: $i" >> "$errlog"
echo "" >> "$errlog"
fi
echo "" >> "$tmpfile"
done
if [[ -s "$tmpfile" ]]; then
echo "" >> "$tmpfile"
log_out
SetDialogHeight "$tmpfile"
fi
[[ "$notifypid" -ne 0 ]] && kill "$notifypid"
case $dlg_mode in
1 | 3)
if [[ -s "$tmpfile" ]]; then
zenity --text-info --editable --filename="$tmpfile" --title='Checksum Results..' \
--width=600 --height=$diag_height --window-icon="$HOME/.local/share/icons/checksum.png"
else
zenity --info --title 'Nothing done!' --text='No checksum files were found! ' --timeout=10 \
--window-icon="$HOME/.local/share/icons/checksum.png"
fi
;;
2)
if [[ -s "$tmpfile" ]]; then
kdialog --textbox "$tmpfile" 600 $diag_height \
--title 'Checksum Results.. '
else
kdialog --sorry 'No checksum files were found!' \
--title 'Nothing done! '
fi
;;
esac
else
cd "${path%quot;
hashfile="$path"
notify_user "$filename" 'Verifying' 'verification'
if [[ "${hashfile = "$hashext" ]]; then
CheckMultiHash "$hashfile"
else
SwitchAlgo "${hashfile
if [[ "$dlg_mode" -eq 0 ]]; then
$tool --check -- "$hashfile" 2>>"$errlog"
else
$tool --check -- "$hashfile" >> $tmpfile 2>>"$errlog" || echo "IN: $hashfile" >> "$errlog"
fi
fi
log_out
SetDialogHeight "$tmpfile"
[[ "$notifypid" -ne 0 ]] && kill "$notifypid"
case $dlg_mode in
0)
echo
echo 'All done with verification!'
echo
;;
1 | 3)
zenity --text-info --title='Checksum Results' --filename="$tmpfile" --width=600 \
--height=$diag_height --window-icon="$HOME/.local/share/icons/checksum.png" \
--text="Verifying hashes in \"$filename\". This may take a moment.."
;;
2)
kdialog --textbox $tmpfile 600 $diag_height --title 'Checksum Results.. '
;;
esac
fi
if [[ "$keep_errlog" -eq 1 ]] && [[ -s "$errlog" ]]; then
cp "$tmpfile" "${path%checksum_errors [$(date)].log"
cat "$errlog" >> "${path%checksum_errors [$(date)].log"
fi
fi
if [[ "$show_times" = 1 ]]; then
finish_time=$(date +%s)
echo "All done in $((finish_time - start_time)) seconds."
fi
exit 0
Welcome to corz.org!
Since switching hosts (I hope you are alright, Ed! Wherever you are …) quite a few things seems to be wonky.
Juggling two energetic boys (of very different ages) on Coronavirus lockdown, I'm unlikely to have them all fixed any time soon. Mail me! to prioritise!