--- /dev/null
+#!/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