#! /bin/sh
#
#   fine-erase.sh -- 複数回書き込みで念入りにディスクのデータを消去する
#
#	使い方: /bin/sh fine-erase.sh 消し方 ディスク
#		消し方: [0z1fRr]+
#		ディスク: デバイスファイルで指定、先頭の「/dev/r」は省く
#		例: /bin/sh fine-erase.sh 0101010 ad0
#
#	0.0: Jun. 27, 2004 by Dai ISHIJIMA
#	0.1: Jul. 11, 2004
#

stuffs="${1:-fz}"
disk="${2:-ad0}"

if [ ! -w /dev/r$disk ]; then
	echo "$0: disk '$disk' does not exist or is not writable"
	echo "Usage: $0 [0|1|R|z|f|r]... disk"
	echo "Example: $0 R10R10 ad0"
	exit 1
fi

title="${TITLE:-ハードディスク消去ツール『wipe-out』}"

dmesg=/var/run/dmesg.boot
dname=`sed -n -E "/^${disk}:.*<.*>/p" $dmesg | sed 's/.*\(<.*>\).*/\1/'`
bytes=`diskinfo -B /dev/r$disk`

msg="ディスク ${disk} ${dname} の\n"
msg="${msg}全データ ${bytes}バイトを、\n"

nstuff=0
for stuff in `echo $stuffs | sed 's/\(.\)/\1 /g'` ; do
	case x"$stuff" in
		x[0z])	msg="${msg}0、" ;;
		x[1f])	msg="${msg}1、" ;;
		x[Rr])	msg="${msg}R、" ;;
	esac
	nstuff=`expr $nstuff + 1`
done

msg="${msg}の順に\n${nstuff}回上書きして消去します\n"
msg="${msg}\n                      よろしいですか?"

dialog --title "$title" --yesno "$msg" 10 64

case x"$?" in
	x1)
		dialog	--title "$title" \
			--infobox 'ディスクの消去をキャンセルしました' 3 64
		sleep 2
		exit 1
		;;
esac


msg="本当に${disk}のデータを消去していいですか?"

dialog	--title "$title" \
	--hline "$dname" \
	--yesno "$msg" \
	5 72

case x"$?" in
	x1)
		dialog	--title "$title" \
			--infobox 'ディスクの消去をキャンセルしました' 3 64
		sleep 2
		exit 1
		;;
esac

# 消去のパラメータ
bytes=`diskinfo -b /dev/r$disk`

obs=`expr 1024 '*' 1024`
ibs=1024
icnt=32768
ocnt=32
max=`expr '(' $bytes + $obs - 1 ')' / $obs`

stage=0
xstage=1
startsec=`tinydate '+%s'`
totalrems=''

for stuff in `echo $stuffs | sed 's/\(.\)/\1 /g'` ; do
	skip=0
	stagestart=`tinydate '+%s'`
	case "$stuff" in
		[0z]) method="'0'を上書きして" ;;
		[1f]) method="'1'を上書きして" ;;
		[Rr]) method="ランダムデータを上書きして" ;;
	esac
	rems=''
	while [ $skip -le $max ]; do
		# 計時
		cursec=`tinydate '+%s'`
		# バーグラフ
		p=`expr 100 '*' $skip / $max`
		m=`expr 1000 '*' $skip / $max`
		q=`expr $p / 2`
		i=0
		bar=''
		while [ $i -lt $q ]; do
			bar="$bar"'#'
			i=`expr $i + 1`
		done
		while [ $i -lt 50 ]; do
			bar="$bar"'_'
			i=`expr $i + 1`
		done
		# 残り時間
		elapsed=`expr $cursec - $stagestart`
		if [ $m -gt 0 ]; then
			remain=`expr '(' 1000 - $m ')' '*' $elapsed / $m + 1`
			if [ $remain -gt 120 ]; then
				rems=`expr '(' $remain + 59 ')' / 60`
				rems="残り およそ${rems}分"
			else
				rems="残り およそ${remain}秒"
			fi
		fi
		if [ $elapsed -gt 120 ]; then
			elas=`expr '(' $elapsed + 30 ')' / 60`
			elas="${elas}分"
		else
			elas="${elapsed}秒"
		fi
		# 全体バーグラフ
		pp=`expr '(' $p + 100 '*' $stage ')' / $nstuff`
		mm=`expr '(' $m + 1000 '*' $stage ')' / $nstuff`
		q=`expr $pp / 2`
		i=0
		totalbar=''
		while [ $i -lt $q ]; do
			totalbar="$totalbar"'#'
			i=`expr $i + 1`
		done
		while [ $i -lt 50 ]; do
			totalbar="$totalbar"'_'
			i=`expr $i + 1`
		done
		ee=`expr $cursec - $startsec`
		if [ $mm -gt 0 ]; then
			rr=`expr '(' 1000 - $mm ')' '*' $ee / $mm + 1`
			if [ $rr -gt 120 ]; then
				totalrems=`expr '(' $rr + 59 ')' / 60`
				totalrems="残り およそ${totalrems}分"
			else
				totalrems="残り およそ${rr}秒"
			fi
		fi
		if [ $ee -gt 120 ]; then
			totalelas=`expr '(' $ee + 30 ')' / 60`
			totalelas="${totalelas}分"
		else
			totalelas="${ee}秒"
		fi
		#
		text="ディスク ${disk} のデータを消去しています。\n\n"
		text="${text}全 ${nstuff} 工程中の ${xstage} 番め  "
		text="${text} 全体の ${pp}% 終了\n"
		text="${text}${totalelas} 経過  ${totalrems}  \n\n"
		text="${text}        0%|${totalbar}|100%\n\n"
		text="${text}この工程では${method}、データを消去しています。\n"
		text="${text}${p}% 終了  "
		text="${text}${elas} 経過  ${rems}  \n\n"
		text="${text}        0%|${bar}|100%\n\n"
		text="${text}\n${errormsg}"
		dialog --title "$title" --infobox "$text" 15 72
		echo -n "$status2"
		case x$DEBUG in
			x[Yy]*)
				status2='now in debug mode...'
				errormsg=''
				sleep 1
				;;
			*)
				status=`stuff -$stuff | dd ibs=$ibs obs=$obs seek=$skip count=$icnt of=/dev/r$disk 2>&1`
				status2=`echo "$status" | sed -n '/transfer/p'`
				errormsg=`echo "$status" | sed -n -E '/records (in|out)$/!p' | sed -n '/transferred in/!p'`
				;;
		esac
		# 次ループ
		skip=`expr $skip + $ocnt`
	done
	stage=`expr $stage + 1`
	xstage=`expr $xstage + 1`
done

sleep 2

cursec=`tinydate '+%s'`
elapsed=`expr $cursec - $startsec`
if [ $elapsed -gt 120 ]; then
	min=`expr $elapsed / 60`
	sec=`expr $elapsed - $min '*' 60`
	elas="${min}分${sec}秒"
else
	elas="${elapsed}秒"
fi

dialog	--title "$title" \
	--msgbox "ディスクのデータ消去が終了しました (${elas})" 5 72

exit 0

# EOF
