Listing 5: getfiles.scr
#!/bin/ksh
#
# getfiles.scr
#
# NOTE: You must be root to execute this script.
#
# This script restores the specific files from a fileset created using
# the backup script backup.scr.
#
# If the tape device being used is an 8 mm tape the blocksize is set
# to 1024 for the duration of the read operation and reset to the previous
# value at the end. If this script is stopped or aborts the blocksize
# should be manually changed to the previous value.
#
# The format of the tape is as follows:
#
# BOT
# header file (format is below) (tar format)
# EOF
# filesystem 1 (backup format)
# EOF
# filesystem 2 (backup format)
# EOF
# .
# .
# filesystem n (backup format)
# EOF
#
# Header File Format
#
# Line 1: hostname
# Line 2: date and time
# Line 3: Level indicator
# Lines 4-n+3: i FILESYSTEM_NAME
# (where i is 1 for the first, 2 for the second, and
# so on. This is the value of the advance file command
# to get this filesystem.)
#
# Parameters:
#
# p1 : (required) the number ofthe backup set to which contains the files
# to restore. The parameter can be obtained from the tape header
# file !backuplist which is written on the beginning of the tape.
#
# p2 : (required) the directory to restore the files to.
#
# p3 : (required) the file(s) to restore from the tape. If more
# than one file is to be restored enclose the list in single quotes
# and separate the members by a space (example: './afile ./bfile').
# The names must exactly match the filenames as they appear on the
# tape listing produced with the listfiles.scr script. If the file
# specifies a directory name all of the files under that directory
# are restored in addition to the directory itself.
#
# p4 : (optional) the tape device to read backups from. The /dev/
# qualifier and the .n suffix may be present or absent, i.e.
# /dev/rmt1.1 is the same as /dev/rmt1 is the same as rmt1.1 is
# the same as rmt1. If a .n suffix is used on the device name
# (i.e. rmt0.3), it MUST be a non-rewinding device, or the
# successive filesystems will overwrite one another. The
# non-rewinding device suffixes are .1, .3, .5, & .7. If the
# .n suffix is absent then the value .1 (i.e. $DEFAULT_SUFFIX)
# is used. If the parameter is omitted the value /dev/rmt0.1
# is used.
#
# Exit Status:
#
# 0 : Tape listing completed successfully
# 91: Must be root to execute
# 92: Error rewinding the tape
# 93: Error advancing the tape
# 94: Wrong number of parameters
# 95: Invalid backup set number in param 1
# 96: Could not change tape blocksize
# 97: Invalid directory in param 2
# 98: Tape drive in param 4 does not exist on this system
# 99: Tape drive in param 4 specifies a rewinding tape
#
#
DEFAULT_TAPE=/dev/rmt0
DEFAULT_SUFFIX='.1'
DEFAULT_BLOCKSIZE="1024"
USAGE="$0 which_backup_set directory_to_receive_files \
files_to_restore_in_quotes [optional_tape_device]"
integer j
integer savep1
blocksize=-1
basetape=""
#########################################################################
#
# If the selected tape drive is an 8mm unit, this function will set
# the block size of the drive to 1024. If the current value is
# different it is saved and restored later.
#
set_blocksize()
{
blocksize=-1 # -1 means reset unnecessary
if [[ -n `lsdev -Cc tape | grep $basetape | grep 8mm` ]]
then
blocksize=`lsattr -E -a block_size -l $basetape | cut -f2 -d' '`
if [[ $blocksize != $DEFAULT_BLOCKSIZE ]]
then
chdev -l $basetape -a block_size=$DEFAULT_BLOCKSIZE >/dev/null
if [[ $? = 0 ]]
then
print "$basetape changed (old blocksize = $blocksize, new = $DEFAULT_BLOCKSIZE)"
else
print "Could not change tape blocksize to $DEFAULT_BLOCKSIZE. Exiting."
exit 96
fi
fi
fi
}
#########################################################################
#
# If the tape blocksize was changed earlier, restore the old
# value.
#
reset_blocksize()
{
if [[ $blocksize != -1 && \
$blocksize != $DEFAULT_BLOCKSIZE ]]
then
chdev -l $basetape -a block_size=$blocksize >/dev/null
if [[ $? = 0 ]]
then
print "$basetape changed (blocksize = previous value of $blocksize)"
else
print "Could not change tape blocksize to $blocksize. Exiting."
exit 96
fi
fi
}
#########################################################################
#
# This function rewinds a tape
#
rewind()
{
tctl -f $tapedev rewind
if [[ $? != 0 ]]
then
print "Error rewinding $tapedev. Exiting."
exit 92
fi
}
#########################################################################
#
# This function advances the tape one filemark (to skip the tar header)
#
skip_1_filemark()
{
tctl -f $tapedev fsf 1
if [[ $? != 0 ]]
then
print "Error advancing $tapedev 1 filemark. Exiting."
exit 93
fi
}
#########################################################################
#
# This function checks the parameters and sets up the $tapedev symbol.
#
checkparm()
{
if [[ $savecount < 3 || \
$savecount > 4 ]]
then
print "Wrong number of parameters, usage = $USAGE. Exiting."
exit 94
fi
if (( savep1 < 1 || \
savep1 > 99 ))
then
print "Sorry, parm 1 must be a backup set (1-99). Exiting."
exit 95
fi
if [[ ! -d $savep2 ]]
then
print "Sorry, parm 2 must be a directory. Exiting."
exit 97
fi
tapedev=${DEFAULT_TAPE}${DEFAULT_SUFFIX}
if [[ $savecount = 4 ]]
then
tapedev="/dev/`basename $savep3`"
if [[ `print $tapedev | cut -c6-8` != "rmt" || \
-z `ls $tapedev 2>/dev/null` ]]
then
print "Sorry, parm 4 must specify a tape device on your system. Exiting."
exit 98
fi
if [[ -z `print $tapedev | grep "\."` ]]
then
tapedev=$tapedev${DEFAULT_SUFFIX}
else
suffix=`print $tapedev | cut -f2 -d'.'`
if [[ $suffix != 1 && \
$suffix != 3 && \
$suffix != 5 && \
$suffix != 7 ]]
then
print "Sorry, parm 4 must specify a non-rewinding tape device."
exit 99
fi
fi
fi
basetape=`basename $tapedev | cut -f1 -d'.'`
}
#########################################################################
#
# main
#
# make sure we're root first
#
if [[ `whoami` != "root" ]]
then
print "Sorry, you must be root to execute this script. Exiting."
exit 91
fi
savecount=$#
savep1=$1
savep2=$2
savep3=$3
savep4=$4
checkparm # check the parms
rewind # rewind the tape
set_blocksize # set the tape blocksize
skip_1_filemark # move past the header file
cd $savep2 # point to restore area
# restore the contents
# with stdin as a herefile
restore -qvf $tapedev -s${savep1} -x ${savep3} <<-EOF
1
yes
EOF
reset_blocksize # reset the tape blocksize
exit 0
|