corz.org uses cookies to remember that you've seen this notice explaining that corz.org uses cookies, okay!
corz.org text viewer..
[currently viewing: / linux/ software/ checksum/ checksum.sh - raw]
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:
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