#!/bin/sh 
#
# Exit Status:
# 0 Alles Ok
# 1 Illegal Request
# 2 Fatal Error
#

# try to hit all the possibilities here
prefix=/usr
exec_prefix=${prefix}
sbindir=${exec_prefix}/sbin
libexecdir=/usr/lib/amanda

PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
export PATH

#
#      Changer config file (changerfile)
#
#      resend_mail=900         # 15 minutes
#      timeout_mail=604800     # 7 days
#      request="tty"           # Use the tty to ask the user to change tape.
#                              # Can't be use by cron
#      request="email"         # Send an email to ask the user to change tape.
#      request="tty_email"     # Use the tty if it exist or send an email.
#                      #Default is "tty_email"
#
#

if [ -d "/var/log/amanda" ]; then
	logfile=/var/log/amanda/changer.debug
else
	logfile=/dev/null
fi

USE_VERSION_SUFFIXES="no"
if test "$USE_VERSION_SUFFIXES" = "yes"; then
	SUF="-2.5.2p1"
else
	SUF=
fi

myname=$0

EGREP='/bin/egrep'

if [ -x $sbindir/ammt$SUF ]; then
	MT=$sbindir/ammt$SUF
	MTF=-f
elif [ -x "/bin/mt" ]; then
	MT=/bin/mt
	MTF=-f
else
	answer="<none> $myname: mt program not found"
	code=1
	echo "Exit -> $answer" >> $logfile
	echo "$answer"
	exit $code
fi
echo MT "->" $MT $MTF >> $logfile

if [ -x $sbindir/amdd$SUF ]; then
	DD=$sbindir/amdd$SUF
elif [ -x "/bin/dd" ]; then
	DD=/bin/dd
else
	answer="<none> $myname: dd program not found"
	code=1
	echo "Exit -> $answer" >> $logfile
	echo "$answer"
	exit $code
fi
echo DD "->" $DD >> $logfile

MAILER=/usr/bin/mail
ONLINEREGEX="ONLINE|READY|sense[_ ]key[(]0x0[)]|sense key error = 0|^er=0$|, mt_erreg: 0x0|^Current Driver State: at rest$"
REPORTTO=`amgetconf$SUF mailto`
tape=`amgetconf$SUF tapedev`

if [ -z "$tape" ]; then
  echo "<none> tapedev not specified in amanda.conf."
  exit 2
fi

ORG=`amgetconf$SUF ORG`

firstslot=1
lastslot=99
resend_mail=900		# 15 minutes
timeout_mail=604800 	# 7 days

changerfile=`amgetconf$SUF changerfile`

conf_match=`expr "$changerfile" : .\*\.conf\$`
if [ $conf_match -ge 6 ]; then
        configfile=$changerfile
        changerfile=`echo $changerfile | sed 's/.conf$//g'`
else
        configfile=$changerfile.conf
fi

cleanfile=$changerfile-clean
accessfile=$changerfile-access
slotfile=$changerfile-slot
[ ! -f $cleanfile ] && echo 0 > $cleanfile
[ ! -f $accessfile ] && echo 0 > $accessfile
[ ! -f $slotfile ] && echo $firstslot > $slotfile
cleancount=`cat $cleanfile`
accesscount=`cat $accessfile`
slot=`cat $slotfile`

request_tty() {
	if > /dev/tty; then
		echo -n "Insert tape into slot $1 and press return" > /dev/tty
		read ANSWER < /dev/tty
	else
		echo "no /dev/tty to ask to change tape"
		exit 1
	fi
}


###
# If $changerfile exists, source it into this script.  One reason is to
# override the request() function above which gets called to request
# that a tape be mounted.  Here is an alternate versions of request()
# that does things more asynchronous:
#
request_email() {
	# Send E-mail about the mount request and wait for the drive
	# to go ready by checking the status once a minute.  Repeat
	# the E-mail once an hour in case it gets lost.
	timeout=0
	gtimeout=$timeout_mail
	while true;do
		if [ $gtimeout -le 0 ]; then
			echo "timeout waiting for tape online"
			exit 1;
		fi
		if [ $timeout -le 0 ]; then
			msg="insert Amanda tape into slot $1 ($tape)"
			subject="$ORG AMANDA TAPE MOUNT REQUEST FOR SLOT $1"
			echo "$msg" | $MAILER -s "$subject" $REPORTTO
			timeout=$resend_mail
		fi
		echo "     -> rewind $tape" >> $logfile
		$MT $MTF $tape rewind >> $logfile 2>&1
		echo "     -> status $tape" >> $logfile
		used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
		echo "     -> loaded <$used>" >> $logfile
		if [ ! -z "$used" ];then
		break
		fi
		sleep 60
		timeout=`expr $timeout - 60`
		gtimeout=`expr $gtimeout - 60`
	done
}
request_tty_email() {
	if > /dev/tty; then
		echo -n "Insert tape into slot $1 and press return" > /dev/tty
		read ANSWER < /dev/tty
	else
		request_email "$1"
	fi
}

request() {
	if [ X"$request" = X"tty" ]; then
		request_tty "$1"
	else if [ X"$request" = X"email" ]; then
		request_email "$1"
	else
		request_tty_email "$1"
	fi
	fi
}

if [ -f $configfile ]; then
	. $configfile
fi

#

eject() { 
	echo "     -> rewind $tape" >> $logfile
	$MT $MTF $tape rewind >> $logfile 2>&1
	echo "     -> status $tape" >> $logfile
	used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
	echo "     -> loaded <$used>" >> $logfile
	if [ ! -z "$used" ];then
		echo "     -> offline $tape" >> $logfile
		$MT $MTF $tape offline >> $logfile 2>&1
		answer="$slot $tape"
		code=0
	else
		answer="<none> $myname: Drive was not loaded"
		code=1
	fi
	echo "Exit -> $answer" >> $logfile
	echo "$answer"
	exit $code
}

#

reset() {
	echo "     -> rewind $tape" >> $logfile
	$MT $MTF $tape rewind >> $logfile 2>&1
	echo "     -> status $tape" >> $logfile
	used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
	echo "     -> loaded <$used>" >> $logfile
	if [ ! -z "$used" ];then
		answer="$slot $tape"
	else
		answer="0 $tape"
	fi
	echo "Exit -> $answer" >> $logfile
	echo "$answer"
	exit 0
}

# load #

loadslot() {
	echo "     -> rewind $tape" >> $logfile
	$MT $MTF $tape rewind >> $logfile 2>&1
	echo "     -> status $tape" >> $logfile
	used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
	echo "     -> loaded <$used>" >> $logfile
	whichslot=$1
	case $whichslot in
	current)
		load=$slot
		[ $load -eq 0 ] && load=$firstslot
		[ $load -gt $lastslot ] && load=$firstslot
		[ $load -lt $firstslot ] && load=$lastslot
		;;
	next|advance)
		load=`expr $slot + 1`
		[ $load -gt $lastslot ] && load=$firstslot
		;;
	prev)
		load=`expr $slot - 1`
		[ $load -lt $firstslot ] && load=$lastslot
		;;
	first)
		load=$firstslot
		;;
	last)
		load=$lastslot
		;;
	[0-9]|[0-9][0-9])
		if [ $1 -lt $firstslot -o $1 -gt $lastslot ]; then
			answer="<none> $myname: slot must be $firstslot .. $lastslot"
			echo "Exit -> $answer" >> $logfile
			echo "$answer"
			exit 1
		fi
		load=$1
		;;
	*)
		answer="<none> $myname: illegal slot: $1"
		echo "Exit -> $answer" >> $logfile
		echo "$answer"
		exit 1
		;;
	esac
	#
	if [ ! -z "$used" -a $load = $slot ];then
		# already loaded
		answer="$slot $tape"
		echo "Exit -> $answer" >> $logfile
		echo "$answer"
		exit 0
	fi

	# if [ $load = $ecleanslot ]; then
	# expr $cleancount + 1 > $cleanfile
	# echo 0 > $accessfile
	# else
	expr $accesscount + 1 > $accessfile
	# if [ $accesscount -gt 9 ]; then
	# $myname -slot $cleanslot >/dev/null
	# used=0
	# fi
	# fi	

	#
	if [ ! -z "$used" ]; then
		echo "     -> offline $tape" >> $logfile
		$MT $MTF $tape offline >> $logfile 2>&1
		used=""
	fi
	if [ $whichslot = advance ]; then
		tape=/dev/null
	else
		echo "     -> load   $load" >> $logfile
		while [ -z "$used" ]; do
			request $load
			echo "     -> rewind $tape" >> $logfile
			$MT $MTF $tape rewind >> $logfile 2>&1
			echo "     -> status $tape" >> $logfile
			used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
			echo "     -> loaded <$used>" >> $logfile
		done
		$DD if=$tape bs=32k count=1 >> $logfile 2>&1
	fi
	echo $load > $slotfile
	answer="$load $tape"
	echo "Exit -> $answer" >> $logfile
	echo "$answer"
	exit 0
}

#

info() {
	echo "     -> rewind $tape" >> $logfile
	$MT $MTF $tape rewind >> $logfile 2>&1
	echo "     -> status $tape" >> $logfile
	used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
	echo "     -> loaded <$used>" >> $logfile
	if [ -z "$used" ];then
		answer="0 $lastslot 1"
	else
		answer="$slot $lastslot 1"
	fi
	echo "Exit -> $answer" >> $logfile
	echo "$answer"
	exit 0
}

#
# main part
#

echo Args "->" "$@" >> $logfile
while [ $# -ge 1 ];do
	case $1 in
	-slot)
		shift
		loadslot $*
		;;
	-info)
		shift
		info
		;;
	-reset)
		shift
		reset
		;;
	-eject)
		shift
		eject
		;;
	*)
		echo "<none> $myname: Unknown option $1"
		exit 2
		;;
	esac
done

exit 0
