# Copyright (c) 1986, 1987 AT&T
# All Rights Reserved
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
# The copyright notice above does not evidence any
# actual or intended publication of such source code.
#ident "@(#)tapepkg 1.1.2.3"
# Script to install/remove multiple packages from SCSI tape.
#menu# install/remove packages from SCSI tape.
#help#
#help# Tapepkg will allow you to install or remove software packages from
#help# SCSI tape. You will be asked to select the tape drive to be
#help# used and which packages you wish to install (remove) from the tape
#help# (the tape is first scanned to determine which packages are
#help# contained on it).
#help#
#help# After selecting the packages to be installed (removed), the packages
#help# are then read from the tape and installed (removed).
#help#
#help# Any packages requiring user interaction will require input at the
#help# time of installation.
PATH=$PATH:/usr/lbin
export PATH
set -u
export INSTTAPE
INSTTAPE=
TMPNODE=
EC=1 # Default exit condition is ERROR
ALL=
REBOOT=0 # Default is not re-boot required.
P4NAME=
LOCK=/tmp/tapelock$$
FILE=/usr/tmp/INSTCMD$$ # file to hold installation/removal commands
# (list of files to be installed/removed)
trap 'cleanup' 0 1 2 3 15
> $FILE # Zero file
echo " \n\n\nColumbia MCC tape load procedure\n\n"
display_1 () {
echo "\nFine. Please keep in mind that the following SMSCRC software packages"
echo "require operator intervention, even though you have requested that"
echo "default responses be used."
echo ""
echo " 0015AA 10Base5 Network Interface"
echo " 0015DA SNA/3270 Emulator"
echo " 0015DA BSC/3270 Emulator"
echo ""
echo "If any of the above packages are contained on your load tape, they"
echo "will require you to provide hardware configuration information."
}
## Check to see if setup has been run on the machine
if [ -s /etc/rc2.d/S00firstcheck ]
then
echo "The procedure \"setup\" has not been run on this machine."
echo "Please run this procedure to initialize the system date and time"
echo "before attempting to load software.\n\n"
echo "Procedure aborted.\n"
exit 1
fi
## Determine how many Prelude packages have been loaded.
if [ -f /usr/options/pre-* ]
then
PRE1=`ls /usr/options/pre-*|wc|cut -c1-7`
else
PRE1=""
fi
if ls /tmp/tapelock* 2>/dev/null 1>&2
then echo "\n\n\07
NOTICE: Only one person at a time may install/remove packages
from SCSI tape.
Someone else is using this command at this time-
Try again later.\n\n"
cleanup
else /usr/bin/id > $LOCK # Set up lock file
fi
# make sure that partition 4 can be referenced by "devnm / | sed s/s0/s4/"
root=`/etc/devnm / | sed 's/ .*//'`
case $root in
*d0s0)
P4NAME=`echo $root | sed s/s0/s4/`
break
;;
*mir000)
/etc/scsi/mirror `echo $root | sed s/dsk/rdsk/` | \
grep '^Disk' >/tmp/$$mirror
P4NAME=`
while read aline
do
set -- $aline
if [ "$3" = ":" ]
then
root=\`echo $4 | sed 's/rdsk/dsk/; s/d0s0/d0s4/'\`
else
root=\`echo $5 | sed 's/rdsk/dsk/; s/d0s0/d0s4/'\`
fi
if [ ! -b $root -o \`expr $root : '.*d0s4$'\` -eq 0 ]
then
continue
fi
if dd if=$root count=1 >/dev/null 2>/tmp/$$dd
then
echo "1+0 records in\n1+0 records out" >/tmp/$$echo
if cmp -s /tmp/$$echo /tmp/$$dd
then
echo $root
break
fi
fi
done < /tmp/$$mirror`
if [ -z "$P4NAME" ]
then
echo ERROR: $0 cannot locate partition 4 on the root device.
cleanup
fi
break
;;
*)
echo ERROR: $0 cannot determine the root device. A \"devnm /\" should
echo have responded with either /dev/dsk/c\?t\?d0s0 or /dev/dsk/mir000.
cleanup
;;
esac
diskumount () {
# perform a umount, complain if it doesn't work
msg=`/etc/umount ${ddrive} 2>&1`
case "${msg}" in
'' ) echo "\n\n";;
*' busy' )
echo >&2 "
The file system is \"busy\" which means that either some command
is using files under it or someone is logged in and currently
in a directory within the file system."
cleanup
;;
*' not mounted' ) ;;
* ) admerr $0 "/etc/umount got '${msg}'"
cleanup;;
esac
}
tinstall () {
# Tape install/remove version of sysadm installpkg/removepkg
#
trap 'EC=0; cleanup' 1 2 15
maxtry=5
ddrive=$P4NAME
while true
do
if readpkg ${INSTTAPE:?}
then :
else echo "Package read FAILED."
cleanup
fi
fulllabel=`disklabel -y $$ ${ddrive}`
fsname=
label=
eval `labelfsname "${fulllabel}"`
if [ "$label" = $1 ]
then break # Found it!
else maxtry=`expr $maxtry - 1`
echo "\nTape out of sync: Looking for $1, read $label"
if [ "$maxtry" = 0 ]
then echo "Could not recover...\n\n"
rewind
cleanup
else echo "Trying to re-sync the tape..."
fi
fi
done
case "${fsname}" in
instal | install )
trap 'trap "" 1 2; cd /; diskumount; cleanup' 0
/etc/umount ${ddrive} 2>/dev/null
chmod 700 /install
if /etc/mount ${ddrive} /install -r
then : # OK
else cleanup
fi
;;
* )
echo >&2 '
This removable medium is not labeled properly and will not work.'
cleanup
;;
esac
trap 'trap "" 1 2; cd /; diskumount; cleanup' 0
cd /tmp
case $INSTRM in
install) if [ ! -r /install/install/INSTALL ]
then
admerr $0 'Improperly built software removable medium.'
diskumount
cleanup
fi
if [ $DEFINS = default -a -s /install/install/DINSTALL ]
then
cp /install/install/DINSTALL $$INSTALL
else
cp /install/install/INSTALL $$INSTALL
fi;;
remove) if [ ! -r /install/install/UNINSTALL ]
then
echo >&2 ' This package will not remove itself.
Consult the instructions that came with the medium.'
diskumount
return # On to next package in list...
fi
cp /install/install/UNINSTALL $$INSTALL;;
*) echo "ERROR in tinstall/INSTRM case."
cleanup
;;
esac
chmod +x $$INSTALL
trap '' 1 2 # Block interrupts
if [ "$INSTRM" = install -a -r /etc/coredirs -a ! -f $$installpkg ]
then
# A problem in cpio makes it change the modes and
# ownership of directories it did not create. This trick
# records and later restores the existing values. The
# directories to be protected are listed in /etc/coredirs.
cpio -o </etc/coredirs >$$installpkg 2>/dev/null
fi
/tmp/$$INSTALL ${ddrive} /install || echo \
'WARNING: Installation/removal may not have completed properly.'
if [ "$INSTRM" = install -a -f $$installpkg ]
then
# Restore the directory modes and ownerships.
cpio -id <$$installpkg >/dev/null 2>&1
fi
rm -f $$INSTALL
diskumount
trap 'cleanup' 0 1 2
}
rewind () {
# Shell to rewind tape
# removes the "n" at the end of the device name
# If tape is at BOT, reads until first FILE Mark, then rewinds.
case `askx -q " Do you wish to install or remove packages?\n" \
-c "install remove quit i r q"` in
install|i) INSTRM=install;;
remove|r) INSTRM=remove;;
quit|q) EC=0; cleanup;;
esac
DEFINS=nodefault
if [ $INSTRM = "install" ]
then
case `askx -q " Do you wish to use default responses for the software packages?\n" \
-c "yes no quit y n q"` in
yes|y) DEFINS=default;;
no|n) DEFINS=nodefault;;
quit|q) EC=0; cleanup;;
esac
fi
export DEFINS
if [ $DEFINS = default ]
then
display_1
fi
echo "\n"
INSTTAPE=`selectdevice -q \
"Select the tape drive to use:" -c $$ /dev/rSA qtape`
echo "\07
Insert the removable medium for the package(s) you want to $INSTRM
into the `basename $INSTTAPE` drive.
Press <RETURN> when ready. Type q to quit. \c"
read a
echo
if [ "$a" = q ]
then EC=0; cleanup
fi
# Take the sysadm name and transform it into the /dev/rmt
# name with the no-rewind option
inode=`ls -i $INSTTAPE | cut -c1-6`
newname=`ls -i /dev/rmt | grep "$inode" 2>/dev/null | cut -c7-`
if [ -z "$newname" ]
then echo "ERROR: cannot determine /dev/rmt name from SA name."
cleanup
fi
# is87-23107 & is87-21901
# Make tape software operate with any tape device
TMPNODE=/tmp/${newname}
ls -og /dev/rmt/${newname}n | \
(
IFS=",$IFS"
read perm links major minor otherstuff
/etc/mknod $TMPNODE c $major 0
/etc/mknod ${TMPNODE}n c $major 1
)
INSTTAPE=${TMPNODE}n
#
# Remove package list and try to read it from the tape...
rm -f /usr/tmp/pkglist 2>/dev/null
cd /usr/tmp; cpio -ic \*pkglist < $INSTTAPE >/dev/null 2>&1
if [ $? = 1 ]
then echo "\n\n\
The medium may not be properly inserted.
Re-insert the medium and try again.\n\n"
cleanup
fi
if [ ! -f /usr/tmp/pkglist ]
then # read of pkglist from tape failed... rewind and try again.
rewind
dd if=$INSTTAPE of=/dev/null bs=9k 2>/dev/null # Skip file
dd if=$INSTTAPE of=/dev/null bs=9k 2>/dev/null # Skip file
cpio -ic \*pkglist < $INSTTAPE >/dev/null 2>&1
if [ ! -f /usr/tmp/pkglist ]
then echo "\07\nRead of tape package header FAILED.\n"; cleanup
fi
fi
NPKGS=`cat /usr/tmp/pkglist | wc -l`
> $FILE
for pkg in `cat /usr/tmp/pkglist`
do
echo $pkg | sed 's/=/ /g' |
sed 's/.*%\(.*\)%\(.*\)%\(.*\)%.*$/skip \1 # \2 # RB=\3/' >> $FILE
done
while true
do
INVALID=false
> ${FILE}.ed
echo "\n\nPackages available:\n"
cat /usr/tmp/pkglist | sed 's/%.*$//' | pr -2tn5w80 | sed 's/=/ /g'
echo "\n\07Enter selection(s) to $INSTRM [all help quit]: \c"
read a
if [ ! "$a" ]
then echo >&2 "\n\07You must enter something."
a=help
fi
for i in $a
do
case $i in
[1-9] | [0-9][0-9])
# Normal number
if [ "$i" -gt "$NPKGS" ]
then echo >&2 "\n\07Choice ($i) out of range."
INVALID=true; break
fi
echo "${i}s/skip[^#]*#/tinstall/" >> ${FILE}.ed
;;
[1-9]-[1-9] |\
[1-9]-[0-9][0-9] |\
[0-9][0-9]-[0-9][0-9])
# Range
eval `echo $i | sed 's/\(.*\)-\(.*\)$/start=\1 end=\2/'`
if [ "$start" -gt "$end" ]
then echo >&2 "\n\07Invalid range: $i"
INVALID=true; break
fi
if [ "$end" -gt "$NPKGS" ]
then echo >&2 "\n\07Invalid range: $i"
INVALID=true; break
fi
j=$start
while [ "$j" -le "$end" ]
do
echo "${j}s/skip[^#]*#/tinstall/" >> ${FILE}.ed
j=`expr $j + 1`
done
;;
all|ALL) # all choices
j=1
while [ "$j" -le "$NPKGS" ]
do
echo "${j}s/skip[^#]*#/tinstall/" >> ${FILE}.ed
j=`expr $j + 1`
done
;;
q|quit|Q|QUIT)
echo "\n\n\07QUIT- Nothing ${INSTRM}ed.\n"
EC=0; cleanup
;;
h|help|H|HELP|?)
echo "\n\n\
Enter the number(s) of the packages you wish to install/remove.
You may enter:
o numbers seperated by spaces (eg. 1 4 10)
o ranges of numbers (eg. 4-9)
o combinations of numbers and ranges (eg. 1 3 10-15)
o all - $INSTRM all packages
o quit - do not $INSTRM anything
Enter <CR> to continue: \c"
read a
INVALID=true; break
;;
*) echo >&2 "\n\07Invalid input: $i"
INVALID=true; break
;;
esac
done
if [ "$INVALID" = false ]
then break
fi
done
echo "\$a\nskip rope\n.\n\$\n?^tinstall?ka\n'a,\$s/^skip/delete/\ng/^delete/d\nw\nq" >> ${FILE}.ed
cat ${FILE}.ed | ed - $FILE >/dev/null 2>&1
echo "rewind" >> $FILE # Rewind tape when done installing/removing
# Execute the file containing commands for installation/removal...
$FILE
if grep "tinstall.*RB=2" $FILE > /dev/null 2>&1
then REBOOT=2
elif grep "tinstall.*RB=1" $FILE > /dev/null 2>&1
then REBOOT=1
else REBOOT=0
fi
case $REBOOT in
0) #No re-boot necessary
;;
1) #init 6 required
echo "\n\nExecute \"cd /; shutdown -i6 -g0 -y\" and"
echo "wait for the \"Console Login:\" prompt."
;;
2) #init 0 required on removepkg, init 6 on installpkg
if [ "$INSTRM" = install ]
then
echo "\n\nExecute \"cd /; shutdown -i6 -g0 -y\" and"
echo "wait for the \"Console Login:\" prompt."
else
echo "You have requested the removal of a package that"
echo "contains a hardware device. If the removal of the"
echo "software has completed successfully, you now need"
echo "to remove associated the hardware."
echo "\n\nExecute \"cd /; shutdown -i0 -g0 -y\" and"
echo "wait for the machine to power down- then remove the"
echo "hardware."
fi
;;
*) echo "An error has occured within the $0 command."
cleanup
;;
esac
## Determine how many Prelude packages have been loaded during this session
##
if [ -f /usr/options/pre-* ]
then
PRE2=`ls /usr/options/pre-*|wc|cut -c1-7` > /dev/null 2>&1
else
PRE2=""
fi
##
## Execute pradmin to rebuild the Prelude menus if Prelude packages have been
## loaded during this session
if [ $DEFINS = default -a "$PRE1" != "$PRE2" ]
then
echo "\nRebuilding Prelude menu for newly installed Prelude software."
/usr/bin/pradmin <<-EOFX >/dev/null 2>&1
in
q
EOFX
fi
echo "\07\n\nThe ${INSTRM}pkg from SCSI tape has completed-\
\nYou may remove the tape after the rewind is complete.\n\n"