#!/bin/sh
#
# Bacula interface for the autochanger
# Special version for IBM Ultrium LTO 3581 L28
# 
# Copyright (C) 2006 Simone Piccardi.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA  02111-1307   USA
#

##
## From the standard (Debian Sarge) script
##
#
#  If you set in your Device resource
#
#  Changer Command = "path-to-this-script/mtx-changer" %c %o %S %a %d
#    you will have the following input to this script:
#
#  mtx-changer "changer-device" "command" "slot" "archive-device" "drive-index"
#		   $1		   $2	    $3	      $4	       $5
#
#  for example:
#
#  mtx-changer /dev/sg0 load 1 /dev/nst0 0 (on a Linux system)
#
#  If you need to an offline, refer to the drive as $4
#    e.g.   mt -f $4 offline
#
#  Many changers need an offline after the unload. Also many
#   changers need a sleep 60 after the mtx load.
#
#  N.B. If you change the script, take care to return either 
#   the mtx exit code or a 0. If the script exits with a non-zero
#   exit code, Bacula will assume the request failed.
#

##
## Please note that the IBM Ultrium LTO 3581 L28 doesnt have a SCSI changing
## device, so you need to give the commands for tape change from the telnet 
## interface. This means that the first argument of the script, 
## changer-device, is always ignored. You can put whatever you want in the 
## configuration file as changer device. 
##
## This script use netcat (nc) to send command to the telnet server on the 
## device, so you need to have nc installed, and the tape library connected
## to your network (or directly to the bacula server). You also need to know 
## the IP address of the tape library (put it in the variable IPADDR), and 
## the username and password for the admin user of the tape (this version 
## use the values admin/secure, from the brand setting), if you changed them 
## put the new values in the CONN variable.
##
## The timeout values for nc were choosen after by hand after some tests, I'm 
## not sure they are the best values that you can choose, but they worked on 
## my setup. The script use the internal commands of the telnet interface, I 
## dont know if there are different versions of those, anyway they worked on
## my setup...
##

#
# Variables definition
#
IPADDR=192.168.1.2
CONN="\n\nlgi\nadmin\nsecure\n"
OUT="\nlgo\n"

if test $# -lt 2 ; then
  echo "usage: mtx-changer ctl-device command slot archive-device drive"
  echo "  Insufficient number of arguments arguments given."
  echo "  Mimimum usage is first two arguments ..."
  exit 1
fi

# Setup arguments
ctl=$1
cmd="$2"
slot=$3
device=$4
# If drive not given, default to 0
if test $# = 5 ; then
  drive=$5
else
  drive=0
fi

#
# Check for special cases where only 2 arguments are needed, 
#  all others are a minimum of 3
case $cmd in
   loaded)
     ;;
   unload)
     ;;
   list)
     ;;
   slots)
     ;;
   *)
     if test $# -lt 3; then
	echo "usage: mtx-changer ctl-device command slot archive-device drive"
	echo "	Insufficient number of arguments arguments given."
	echo "	Mimimum usage is first three arguments ..."
	exit 1
     fi
     ;;
esac


case $cmd in 
   unload)
#     echo "Doing mtx -f $ctl unload $slot $drive"
#
# enable the following line if you need to eject the cartridge
#     mt -f $device offline
      TEMPFILE=$(tempfile -p bacula)
      if test x$slot = x; then
	 echo -e "$CONN unl $OUT"| nc -i 2 -w 20 $IPADDR 23 > $TEMPFILE
      else
	 echo -e "$CONN unl $slot $OUT"| nc -i 2 -w 20 $IPADDR 23 > $TEMPFILE
      fi
      grep "Command executed successfully" $TEMPFILE > /dev/null
      rtn=$?
      rm $TEMPFILE
      exit $rtn
      ;;

   load)
#     echo "Doing mtx -f $ctl load $slot $drive"
      TEMPFILE=$(tempfile -p bacula)
      echo -e "$CONN ld $slot $OUT"| nc -i 2 -w 20 $IPADDR 23 > $TEMPFILE
      grep "Command executed successfully" $TEMPFILE > /dev/null
      rtn=$?
      rm $TEMPFILE
#
# Increase the sleep time if you have a slow device
# or remove the sleep and add the following:
#     wait_for_drive $device
      sleep 15
      exit $rtn
      ;;

   list) 
#     echo "Requested list"
      echo -e "\n\ninv\n"| nc -i 2 -w 6 $IPADDR 23 | tail -n 15 | grep -E -e "(Present|Drive)" | awk '{print $1":"}'
# Comment out the previous line and add a line here
# to print "fake" barcodes.
#
      ;;

   loaded)
      echo -e "\n\ninv\n"| nc -i 2 -w 6 $IPADDR 23 | tail -n 15 | grep Drive | awk '{print $1}'
      rtn=$?
      if [ "$rtn" != 0 ]; then 
          echo 0
      fi
      exit $rtn
      ;;

   slots)
#     echo "Request slots"
# My tape has just 8 slots, don't know other model, so if needed 
# you must change this
      echo 8
      
      ;;
esac
