#! /bin/sh
#
#   verify.sh -- データが消えているか確認する
#
#	使い方: /bin/sh verify.sh step ディスク
#		step: スキップする長さ
#		ディスク: デバイスファイルで指定、先頭の「/dev/」は省く
#		例: /bin/sh verify.sh 0 ad0 (ディスク全部)
#		    /bin/sh verify.sh 90 ad0 (全体の1/10)
#		    /bin/sh verify.sh 990 ad0 (全体の1/100)
#
#	0.0: Jul.  8, 2005 by Dai ISHIJIMA (for wpout06)
#	0.2: Aug.  1, 2006 (タイムスタンプ for wpout07)
#	0.3: Feb. 10, 2007 (ログ記録 for wpout08)
#	0.4: Feb. 15, 2007 (エンターキー長押し対策)
#	0.5: Sep. 12, 2007 (wpout09)
#	0.6: Oct.  6, 2007 (計算を32ビット符号付き整数の範囲で行う)
#	0.7: Dec. 23, 2007 (バーグラフ表示の計算修正)
#	0.8: Jan.  2, 2008 (ログ修正)
#	0.9: Apr. 19, 2009 (確認メッセージ, wpout10)
#	1.0: Mar. 21, 2014 (残り時間計算修正)
#	1.1: Mar. 22, 2014 (画面のちらつきを減らす (更新を減らす))
#

ERRORLOG="${ERRORLOG:-/tmp/wperrlog.txt}"
exec 2>> $ERRORLOG
echo "# start $0, $@" 1>&2
echo '# ---------------------------- #' 1>&2

# 単独でも動くように
LOGFIL="${LOGFIL:-/tmp/wpoutlog.txt}"
DMESG="${DMESG:-/var/run/dmesg.boot}"
PATTERNFIL="${PATTERNFIL:-/tmp/pattern.dat}"
dispupd="${DISPUPD:-2}"

echo '# ---------------------------- #' >> $LOGFIL
echo -n "script $0 started on " >> $LOGFIL
date >> $LOGFIL

step="${1:-1}"
disk="${2:-ad0}"
dmesg="${DMESG:-/var/run/dmesg.boot}"
# 10Mバイト単位で確認
vblklen="${VBLKLEN:-10485760}"
# 一度に1Mバイト
vbs="${VBS:-1048576}"
vunit=$(( $vbs / 1048576 ))
# 一度に10ブロック
vcnt=$(( $vblklen / $vbs ))

#
resultfil=/tmp/result

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

if [ ! -r /dev/$disk ]; then
	dialog	--title "$title" \
		--msgbox "ディスク $disk が存在しないか、読めません" \
		5 64
	exit 1
fi

dname=`sed -n -E "/^${disk}:.*<.*>/p" $dmesg | sed 's/.*\(<.*>\).*/\1/'`
dbytes=`disksize -p /dev/$disk`

bytes=`disksize -B /dev/$disk`

# 確認のパラメータ
mbytes=`disksize -m /dev/$disk`
# ブロックサイズ単位でのディスクサイズ
max=$(( $mbytes / $vunit ))

msg="ディスク ${disk} ${dname} の\n"
msg="${msg}データ ${bytes}バイトが\n"
msg="${msg}消去されていることを確認します。\n"
msg="${msg}\n                      よろしいですか?"

sh dummyread.sh
dialog --title "$title" --yesno "$msg" 9 64

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

# 結果
zero=0
one=0
maybe=0
unerased=0
checked=0

startsec=`tinydate '+%s'`
rems=''

# 開始時刻
startstamp=`date '+%Y-%m-%d %H:%M'`

#
echo "v ---------------------------- v" >> $LOGFIL
echo -n "verify started on " >> $LOGFIL
date >> $LOGFIL
echo "  $disk ($dname) $bytes bytes" >> $LOGFIL

nerrs=0
skip=0
xcent=100
xmill=1000
mcent=$max
mmill=$max
if [ $max -gt 1048576 ]; then
	xcent=1
	xmill=1
	mcent=$(( ( $max + 99 ) / 100 ))
	mmill=$(( ( $max + 999 ) / 1000 ))
fi
lastdisp=0
dispintv=0
while [ $skip -lt $max ]; do
	# 計時
	cursec=`tinydate '+%s'`
	# バーグラフ
	p=$(( ( $xcent * $skip ) / $mcent ))
	m=$(( ( $xmill * $skip ) / $mmill ))
	q=$(( $p / 2 ))
	i=0
	bar=''
	while [ $i -lt $q ]; do
		bar="$bar"'#'
		i=$(( $i + 1 ))
	done
	while [ $i -lt 50 ]; do
		bar="$bar"'_'
		i=$(( $i + 1 ))
	done
	# 残り時間
	elapsed=$(( $cursec - $startsec ))
	if [ $elapsed -gt 10 ]; then
		if [ $m -gt 0 ]; then
			remain=$(( ( 1000 - $m ) * $elapsed / $m + 1 ))
			if [ $remain -gt 120 ]; then
				rems=$(( ( $remain + 59 ) / 60 ))
				rems="残り およそ${rems}分"
			else
				rems="残り およそ${remain}秒"
			fi
		fi
	fi
	if [ $elapsed -gt 120 ]; then
		elas=$(( ( $elapsed + 30 ) / 60 ))
		elas="${elas}分"
	else
		elas="${elapsed}秒"
	fi
	#
	text="ディスク ${disk} のデータをチェックしています。\n"
	text="${text}${max}ブロックのうち${skip}ブロック／${p}% 終了\n"
	text="${text}${elas} 経過  ${rems}  \n\n"
	text="${text}        0%|${bar}|100%"
	text="${text}\n${errormsg}"
	dispintv=$(( $cursec - $lastdisp ))
	if [ $dispintv -ge $dispupd ]; then
		dialog --title "$title" --infobox "$text" 8 72
		lastdisp=$cursec
	else
		echo -e '\r\c'
	fi
	case "x$progchar" in
		xO) progchar='.' ;;
		xo) progchar='O' ;;
		*)  progchar='o' ;;
	esac
	echo -n "$progchar $status2"
	case x$DEBUG in
		x[Yy]*)
			status2='now in debug mode...'
			errormsg=''
			sleep 1
			;;
		*)
			status=`(dd if=/dev/$disk ibs=$vbs skip=$skip count=$vcnt | check -s) 2>&1`
			case $? in
				0) zero=$(( $zero + $vcnt )) ;;
				1) one=$(( $one + $vcnt )) ;;
				2) maybe=$(( $maybe + $vcnt )) ;;
				*) unerased=$(( $unerased + $vcnt )) ;;
			esac
			status2=`echo "$status" | sed -n '/transfer/p'`
			errormsg=`echo "$status" | sed -n -E '/records (in|out)$/!p' | sed -n '/transferred in/!p'`
			;;
	esac
	# 最下行に出すステータスが空のとき
	case x"$status2" in
		x)
			status2="skipping unerased block $unerased at $skip"
			;;
	esac
	# 記録
	case x"$skip" in
		x0)
			echo "skip: $skip, $status2" >> $LOGFIL
			;;
	esac
	case x"${nerrs}"x"${errormsg}" in
		x[0-8]x?*)
			echo "errmesg[${nerrs}]: $errormsg" >> $LOGFIL
			nerrs=$(( $nerrs + 1 ))
			;;
		x9x?*)
			echo "errmesg[${nerrs}]: $errormsg" >> $LOGFIL
			echo "Too many errors encounterd..." >> $LOGFIL
			nerrs=$(( $nerrs + 1 ))
			;;
	esac
	# 次ループ
	checked=$(( $checked + $vcnt ))
	skip=$(( $skip + $vcnt + $step ))
done

sleep 2

#
echo "skip: $skip, $status2" >> $LOGFIL
echo "number of error messages: $nerrs" >> $LOGFIL
echo -n "verify finished on" >> $LOGFIL
date >> $LOGFIL
echo "  $disk ($dname, $dbytes), max = $max, checked = $checked" >> $LOGFIL
echo "^ ---------------------------- ^" >> $LOGFIL

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

# 終了時刻
endstamp=`date '+%H:%M'`

unerased=$(( $unerased + $maybe ))
zp=$(( $zero * 100 / $checked ))
op=$(( $one * 100 / $checked ))
np=$(( $unerased * 100 / $checked ))

msg="ディスク ($disk, $dbytes バイト) のチェックが終了しました (${elas})\n"
msg="${msg}全 $max ブロック中の $checked ブロックを検査しました\n"
msg="${msg}  '0' で消去されているブロック数: $zero ($zp %)\n"
msg="${msg}  '1' で消去されているブロック数: $one ($op %)\n"
msg="${msg}  それ以外 (未消去) のブロック数: $unerased ($np %)\n"

# ログ保存
echo "Verified $checked blocks" > /tmp/verify-log.$disk
echo -n " erased with 0:${zp}%, 1:${op}%, " >> /tmp/verify-log.$disk
echo "unerased:${np}%" >> /tmp/verify-log.$disk
echo " $startstamp -> $endstamp" >> /tmp/verify-log.$disk

sh dummyread.sh

# なぜか止まる?
#echo -n "final confirmation message displayed on " >> $LOGFIL
#date >> $LOGFIL

dialog	--title "$title" \
	--msgbox "$msg" 10 72

#
echo '# ---------------------------- #' 1>&2

exit 0

# EOF
