#!/bin/sh
#
# $OpenBSD: chio-changer-openbsd,v 1.1 2012/07/04 12:02:56 ajacoutot Exp $
#
# Bacula interface to chio(1) autoloader for OpenBSD
#
# Adapted from NetBSD pkgsrc and examples/autochangers in bacula source)
# by Antoine Jacoutot <ajacoutot@openbsd.org> for OpenBSD.
# Tested on an LTO-4 device with 8 slots.
# The user Bacula is running as needs rw access to the ch(4) and st(4)
# devices.
#
# If you set in your Device resource:
#      Changer Command = "/path/to/chio-changer-openbsd %c %o %S %a %d"
# you will have the following input to this script:
#      chio-changer-openbsd "changer-device" "command" "slot" "archive-device" "drive-index"
#                            $1               $2        $3     $4               $5
#
# So Bacula will always call with all the following arguments, even though
#     in come cases, not all are used.
#
# N.B. If you change the script, take care to return either 
#      the chio exit code or a 0. If the script exits with a non-zero
#      exit code, Bacula will assume the request failed.

CHIO=/bin/chio

# time (in seconds) for the unit to settle after (un)loading a tape
SLEEP=1

usage() {
	echo "usage: ${0##*/} ctl-device command [slot archive-device drive-index]"
}

# check parameters count
check_parm_count() {
	pCount=$1
	pCountNeed=$2
	if test ${pCount} -lt ${pCountNeed}; then
		usage
		echo "!!! insufficient number of arguments given"
		exit 1
	if test ${pCount} -lt 2; then
		usage
		echo "!!! mimimum usage is the first two arguments"
		exit 1
	else
		usage
		echo "!!! command expected ${pCountNeed} arguments"
		exit 1
	fi
		usage
		exit 1
	fi
}

# check arguments count for specific actions
case $2 in
	list|listall)
		check_parm_count $# 2
		;;
	slots)
		check_parm_count $# 2
		;;
	transfer)
		check_parm_count $# 4
		;;
	*)
		check_parm_count $# 5
		;;
esac


# get arguments
ctl=$1
cmd="$2"
slot=$3
device=$4
drive=$5

case ${cmd} in 
	unload)
		${CHIO} -f ${ctl} move drive ${drive} slot $((${slot} - 1))
		rtn=$?
		[ ${rtn} -eq 0 ] && sleep ${SLEEP}
		exit ${rtn}
		;;

	load)
		${CHIO} -f ${ctl} move slot $((${slot} - 1)) drive ${drive}
		rtn=$?
		[ ${rtn} -eq 0 ] && sleep ${SLEEP}
		exit ${rtn}
		;;
	list)
		${CHIO} -f ${ctl} status -v slot | \
			sed -ne 's/^slot *\([0-9]*:\).*FULL.*voltag.*<\(.*\):.*/\1\2/p' | \
			awk -F: '{print $1 + 1 ":" $2 }'
		exit $?
		;;

	listall)
		echo "The listall command is not implemented on OpenBSD."
		exit 1
		;;

	loaded)
		local _slot=`${CHIO} -f ${ctl} status -v | egrep '^slot.*<ACCESS> voltag: <:[0-9]>$' | awk '{ print $2 }' | awk -F: '{ print $1 + 1 }'`
		[ -z "${_slot}" ] && _slot=0
		echo ${_slot}
		exit $?
		;;
	slots)
		${CHIO} -f ${ctl} params | awk "/slots/{print \$2}"
		exit $?
		;;
	transfer)
		slotdest=${device}
		${CHIO} -f ${ctl} move slot $((${slot} - 1)) slot ${slotdest}
		exit $?
		;;
esac
