#!/bin/sh

#  tapefiles

# For the beginning of this script, search forward
# for "The script starts here".

# --------------------------------------------------------------------
# This script assumes that /dev/tape is a symlink to /dev/nht0, the
# non-rewinding tape device (i.e., the device that does not
# automatically rewind the tape after each write), because the "mt" 
# command uses the default device /dev/tape.
# If this is not the case, edit the definition of "MTCOMMAND" below
# to include the device as an argument to mt, as in
# MTCOMMAND="/bin/mt -f /dev/nht0"
# (in which you many also need to change the path to the mt command
# if it's not in /bin).

# --------------------------------------------------------------------

umask 022

BACKUPDIR=/var/backups
LOGFILE=$BACKUPDIR/Backups.log
MESSAGEFILE=$BACKUPDIR/Backups.messages
MTCOMMAND=/bin/mt

# --------------------------------------------------------------------
# --------------------------------------------------------------------
# Define functions:


wait_until_tape_ready () {

# We wait a maximum of 60 seconds until the tape drive
# is ready to perform another command.  
# (It generally needs only 5 seconds.)
# We do this by using "mt tell" to inquire into the current
# tape position, and check to see if that command completed
# successfully.
# We check this every 5 seconds and return 0 when it's ready.
# If it's not ready after 60 seconds, we exit with a return value of 1

    let NUMTRIES=1
    until [ $NUMTRIES -gt 12 ]; do
      $MTCOMMAND tell > /dev/null 2>&1
      if [ $? -eq 0 ]; then
        return 0
      fi
      sleep 5
      let NUMTRIES=NUMTRIES+1
      $MTCOMMAND tell > /dev/null 2>&1
    done
    echo "  Error: Tape still not ready after 60 seconds: `date`"\
                            | tee -a $MESSAGEFILE
    echo "  Script exiting" | tee -a $MESSAGEFILE
    exit 1

} # wait_until_tape_ready


# --------------------------------------------------------------------

rewind_tape () {

    echo "Rewinding tape, `date`..." | tee -a $MESSAGEFILE
    wait_until_tape_ready
    $MTCOMMAND rewind
    if [ $? -ne 0 ];then
	echo "  Error: Unable to rewind the tape: `date`"\
                		| tee -a $MESSAGEFILE
	echo "  Script exiting" | tee -a $MESSAGEFILE
	exit 1
    fi

} # rewind_tape

# --------------------------------------------------------------------

retension_tape () {

    echo "Retensioning tape, `date`..." | tee -a $MESSAGEFILE
    wait_until_tape_ready
    $MTCOMMAND retension
    if [ $? -ne 0 ];then
	echo "  Error: Unable to retension the tape: `date`"\
		| tee -a $MESSAGEFILE
	echo "  (Is there a tape in the drive?)" | tee -a $MESSAGEFILE
	echo "  Script exiting" | tee -a $MESSAGEFILE
	exit 1
    fi

} # retension_tape

# --------------------------------------------------------------------


copyafile () {

    echo "Seeking to the end of data on the tape, `date`..."\
		| tee -a $MESSAGEFILE
    wait_until_tape_ready
    $MTCOMMAND eod
    if [ $? -ne 0 ];then
      echo "  Error: Unable to seek to the end of the data: `date`" \
           | tee -a $MESSAGEFILE
      echo "  Script exiting" | tee -a $MESSAGEFILE
      exit 1
    fi

    # Find the present block number, and delete all non-digits
    # from the output of "mt tell" so that we have only the number:
    echo "Reading block number before starting to copy, `date`"\
                 | tee -a $MESSAGEFILE
    wait_until_tape_ready
    BLOCKNO=`$MTCOMMAND tell | tr -d -c 0123456789`


    echo >> $LOGFILE
    echo "Beginning to copy $FILENAME to tape, `date`" >> $LOGFILE
    echo "    beginning at block $BLOCKNO"  >> $LOGFILE
    echo "Beginning to copy $FILENAME to tape, `date`" | tee -a $MESSAGEFILE
    cp $FILENAME /dev/tape
    echo "    Copying complete: `date`" >> $LOGFILE
    echo "    Copying complete: `date`" | tee -a $MESSAGEFILE


    echo "Reading block number after copying file, `date`"\
                 | tee -a $MESSAGEFILE
    wait_until_tape_ready
    NEWBLOCKNO=`$MTCOMMAND tell | tr -d -c 0123456789`
    echo "    The next file will begin at block $NEWBLOCKNO" >> $LOGFILE

    echo | tee -a $MESSAGEFILE

    # Go back to the beginning of the newly written file,
    # and run a compare.  
    echo "Seeking to beginning of new file before comparing..." \
         | tee -a $MESSAGEFILE
    $MTCOMMAND seek $BLOCKNO


    echo "Beginning compare of newly copied file: `date`" | tee -a $MESSAGEFILE
    wait_until_tape_ready
    cmp $FILENAME /dev/tape >> $MESSAGEFILE 2>&1
    echo "Compare of newly copied file completed: `date`" | tee -a $MESSAGEFILE


    echo "Rewinding tape, `date`..." | tee -a $MESSAGEFILE
    wait_until_tape_ready
    rewind_tape

} # copyafile

# --------------------------------------------------------------------
# --------------------------------------------------------------------

# The script starts here!!!!!!!!!!!!!!!!


if [ "$1" = "" ]
  then
  echo Error: Files to be copied must be named on command line
  echo Usage: tapefiles filename
  echo Script exiting
  exit 1
fi


# retension the tape once before we start 
# (We'll do it once again before copying each file).
echo "We retension the tape once before doing anything else."
echo "We'll also retension it again before copying each file."
retension_tape


# Do the copying:
while [ "$1" != "" ]; do

    FILENAME=$1

    if [ ! -f $FILENAME ]; then
      echo "Error: The file $FILENAME does not exist: `date`"\
		| tee -a $MESSAGEFILE
      echo "Script exiting" | tee -a $MESSAGEFILE
      exit 1
    fi

    echo "We will copy the file $FILENAME to tape: `date`"\
		| tee -a $MESSAGEFILE
    retension_tape
    copyafile "$FILENAME"
    shift

done



echo "Putting tape offline, `date`..." | tee -a $MESSAGEFILE
wait_until_tape_ready
$MTCOMMAND offline

echo "Script complete: `date`" | tee -a $MESSAGEFILE
echo "" | tee -a $MESSAGEFILE
exit 0
