#!/bin/bash

### sticktest
##		Dieses Skript testet angeschlossene Speichermedien darauf, wie viele Gibi-Bytes 
##		sich darauf speichern und wieder lesen lassen.
##		Es hilft gefälschte oder kaputte USB-Sticks zu erkennen.

### Aufruf:
##		sticktest /MountPoint [-r]

### Optionen
##	-r	Löschen aller zum Test verwendeten Dateien

### Autor:
## Jörg Reinholz, Kassel, Germany

### Lizenz:
## GPL, LGPL or MPL: show https://code.fastix.org/lizenz.php

if [ -z $1 ]; then
	echo "Fehler: Kein Mountpoint angegeben.";
	exit 2;
fi

MountPoint=$1;
isMountPoint=$( grep -P "/dev/.* $MountPoint " < /proc/self/mounts| wc -l );
if [ 1 -ne $isMountPoint ]; then
	echo "Fehler: $MountPoint ist kein Mountpoint oder kein gemountetes Gerät";
	exit 4;
fi

echo -e "Ok. Das wird jetzt eine Weile dauern...\n\n";

#set -x

oldDir="${PWD}";
TMPDIR="/tmp";
BaseFile=$(mktemp);
TestFile=$(mktemp);
LogFile=/tmp/test.log;

if [ -f ${LogFile} ]; then
	truncate -s 0 ${LogFile};
else
	touch ${LogFile};
fi

err=0;
num=0;

dd if=/dev/urandom of=${BaseFile} bs=4096 count=255744 status=none;

while [ 0 -eq ${err} ]; do
	num=$((${num} + 1));
	cp "${BaseFile}" "${TestFile}";
	dd if=/dev/urandom bs=4096 count=$((256*25)) status=none >> $TestFile;
	cp --no-clobber "${TestFile}" "${MountPoint}/TestFile.${num}" || err=1;
	sync "${MountPoint}/TestFile.${num}";

	if [ 1 = $err ]; then
		echo "(Kein Fehler:) ${MountPoint}/TestFile.${num} konnte nicht mehr oder nicht mehr vollständig geschrieben werden.";
		echo "Prüfung nachfolgend.";
	fi

	if [ -r "${MountPoint}/TestFile.${num}" ]; then
		echo -n "${MountPoint}/TestFile.${num}:" >> ${LogFile};
		md5A=$(md5sum -b < ${TestFile} | tr -d " *-");
		md5B=$(md5sum -b < ${MountPoint}/TestFile.${num} | tr -d " *-");
		[ 0 = $err ] && echo ${md5A} >> ${LogFile};
		[ 1 = $err ] && echo ${md5B} >> ${LogFile};

		if [ ${md5A} = ${md5B} ]; then
			[ 0 = $err ] && echo "Das Schreiben von ${num} Gigabytes war SCHEINBAR erfolgreich.";
		else
			[ 0 = $err ] && echo "ALARM: Prüfsummenfehler in Datei ${MountPoint}/TestFile.${num}";
		fi
	fi
done

files=($(cut -d':' -f1 ${LogFile}));
sums=($(cut -d':' -f2 ${LogFile}));

echo -e "\nAbschließende Tests (Prüfen aller Dateien):";

err=0;
for i in $(seq 0 $((${#files[@]}-1))); do
	file=${files[${i}]};
        sum=${sums[${i}]};
        sumTest=$(md5sum -b < "${file}" | tr -d " *-");
	echo -e "\nDatei: '${file}'";
        echo "   Erwartete Prüfsumme: ${sum}";
        echo "Tatsächliche Prüfsumme: ${sumTest}";
	if [ "${sum}" = "${sumTest}" ]; then 
		echo "* Identisch: O.K.*";
	else
		echo "# FEHLER nach ${i} GigaBytes! #";
	fi
	[ "$2" = "-r" ] && rm "${file}";
done

if [ 1 == $err ]; then
		echo "###########################################";
		echo "# Der Stick hat den Test NICHT bestanden! #";                
		echo "###########################################";		
fi

echo '------------------------------------';
echo '| Der Stick hat den Test bestanden |';                
echo '------------------------------------';

if [ "$2" = "-r" ]; then
	rm $BaseFile;
	rm $TestFile;
fi
cd "$oldDir";
exit $err;
