:
#ident "@(#)tape.sh	1.7 91/07/12"
#
#	Copyright (C) The Santa Cruz Operation, 1986-1989.
#	Portions Copyright (C) Altos Computer Systems 1989, 1990.
#	This Module contains Proprietary Information of
#	Altos Computer Systems, The Santa Cruz Operation 
#	and should be treated as Confidential.
#
# tape - UNIX 3.2 Tape Drive Initialization
#
PATH=/etc:/bin:/usr/bin:/altos/bin
LANG=english_us.ascii
export PATH LANG

# Set change to NO
change=NO
tmp=/tmp/tp.$$
DEFAULT=/etc/default/tape

# Define return values
: ${OK=0} ${FAIL=1} ${STOP=10} ${HALT=11}

# Function definitions
##########################

# ---------- STANDARD ROUTINES -------- These routines are commen to scripts
#					requiring kernel relinking.

# Define traps for critical and non critical code.
set_trap()  {	
	trap 'echo "
	Interrupted! Exiting ..."; sleep 2; cleanup 1' 1 2 3 15
}
unset_trap()  {
	trap '' 1 2 3 15
}
 
# Remove temp files and exit with the status passed as argument
cleanup() {
	trap '' 1 2 3 15
	[ "$tmp" ] && rm -f $tmp*
	exit $1
}

# clear the screen if it is supported
clearscr() {
	# check if the terminal environment is set up
	[ "$TERM" ] && [ -x /bin/clear ] && clear 2> /dev/null
}

# Prompt for yes or no answer - returns non-zero for no
getyn() {
	while	echo "
	$* (y/n):  \c">&2
	do	read yn rest
		case $yn in
		[yY])	return $OK 			;;
		[nN])	return $FAIL			;;
		*)	echo "
	Please answer 'y' or 'n'." >&2	;;
		esac
	done
}

# Prompt with mesg, return non-zero on q
prompt() {
	while	echo "
	${mesg}or type 'q' to ${quit}:  \c" >&2
	do	read cmd
		case $cmd in
		+x|-x)	set $cmd					;;
		Q|q)	return $FAIL					;;
		!*)	eval `expr "$cmd" : "!\(.*\)"`			;;
		"")	# If there is an argument use it as the default
			# else loop until 'cmd' is set
			[ "$1" ] && { 
				cmd=$1
				return $OK
			}
			: continue
			;;
		*)	return $OK					;;
		esac
	done
}

# Print an error message
error() {
	echo "
	Error:  $*" >&2
	return $FAIL
}

# Configure error message
conferr()  {
	error "
	Configure failed to update system configuration.
	Check /etc/conf/cf.d/conflog for details."
}

# perms list needed if link kit must be installed
permschk () {
	if [ -f /etc/perms/extmd ]; then
		PERM=/etc/perms/extmd
	else
		error "
	Cannot locate /etc/perms/extmd. Needed to verify
 	linkkit installation."
		cleanup $FAIL
	fi
	return $OK
}

# test to see if link kit is installed
linkchk()  {
	cd /
	until	fixperm -i -d LINK $PERM
	do	case $? in
		4)  echo "
	The Link Kit is not installed." >&2	;;
		5)  echo "
	The Link Kit is only partially installed." >&2  ;;
		*)  echo "
	Error testing for Link Kit.  Exiting..." >&2 
			cleanup $FAIL  ;;
		esac

		# Not fully installed. Do so here
		getyn "Do you wish to install it now?" || {
			# answered no
			echo "
	The link kit must be installed to run this 
	program.  Exiting ..."
			cleanup $OK
		}

		# answered yes, so install link kit
		echo "
	Invoking /etc/custom...
"
		sleep 2
		/etc/custom -o -i LINK || {
			# custom exited unsuccessfully
			error "
	'custom' failed to install Link Kit successfully.
	Please try again."
			cleanup $FAIL
		}
	done
}

asklink()  {
	clear
	getyn "

	You must create a new kernel to effect the 
	driver change you specified.  Do you wish to 
	create a new kernel now?"  ||  {
		echo "
	To create a new kernel execute 

		/etc/conf/cf.d/link_unix. 

	You must then reboot your system by executing

		/etc/shutdown -i0

	before the changes you have specified will be 
	implemented."
		[ "$DRIVER" = "Stp" ] && {
			echo "
	Also, if other changes are made to the SCSI 
	devices prior to the rebuilding and rebooting 
	of the kernel, then any previous SCSI device 
	changes will be void.
"
		}
		return $FAIL 
	}
	return $OK
}

# re-link new kernel
klink() {
	cd /etc/conf/cf.d
	./link_unix || { 
		echo "
	Error:  Kernel link failed."
		cleanup $FAIL
	}
	return $OK
}
 
# ---------- DEVICE ROUTINE ---------  This routine creates devices
#					

# create appropriate devices.  arguments are name of device and minor dev #
# usage:  mkdevice name minor#
# Global variables used:  
#	$dev_major: add routines
mkdevice() {
	rm -f /dev/$1
	mknod /dev/$1 c $dev_major $2 || {
		error "
	mkdev tape: mknod failed to create /dev/$1."
		return $FAIL 
	}
	chmod 666 /dev/$1
	return $OK 
}

# ---------- CONFIGURE ROUTINES ------- These routines extract information 
#					from and modify kernel configuration
#					files and parameters.

# This routine sets cf_state and the device major number if applicable. 
# Possible values for cf_state are as follows. 
# 	NO: Device not present in mdevice file and therefore has
#	      no major number.
# 	PART: Device present in mdevice file but the -Y option in the configure
#      	      field of the sdevice file is not set. This causes the driver to 
#	      be excluded from the next reconfiguration.
# 	All:  Device has a major number and the -Y option is set in  
#	      the sdevice file.
confchk () {
	name=$1
	cf_state= 	major=
	cd /etc/conf/cf.d
	major=`./configure -j $name` || {
		cf_state=NO
		return $FAIL
	}
	cf_state=PART
	if [ -r ../sdevice.d/$name ] 
	then
		vars=$*
		set `cat ../sdevice.d/$name` || {
			error "
	'cat' failed to read sdevice file."
			cleanup $FAIL
		}
		fieldval=$2
		set $vars
		[ "$fieldval" = "Y" ] && {
			cf_state=YES
			return $OK
		}
	else
		getyn "
	This device has an entry in the master device 
	file but no corresponding system device entry.  
	Do you wish to continue and have a default 
	entry created?" || cleanup $FAIL
	fi
	return $FAIL
}

# Add driver according to cf_state. 
# Global variables used and where set:
# 	$fns: add routines; $cf_state: confchk(); 
#	$major: confchk() or add routine
confadd() {
	
	cd /etc/conf/cf.d
	case $cf_state in

	NO) 	echo "

	Adding device to system configuration files ...\c" >&2
		major=`./configure -j NEXTMAJOR`
		[ "$ipl" ] && IPL="-l $ipl"
		[ "$iv" ] && IV="-v $iv"
		./configure -a $fns -c -R -m $major $IPL $IV > conflog 2>&1 || {
			conferr
			return $FAIL
		} ;;
	PART)   echo "

	Updating system configuration ...\c" >&2
	        ./configure -a -c -m $major -Y -R > conflog ||  {
			conferr
			return $FAIL
		} ;;
	esac
	echo "

	System files have been successfully updated."
	change=YES
	rm -f conflog
	sleep 2
	return $OK
}

# Configure driver out of system configuration files by unsetting -Y option.
# Global variables used and where set:
#	$major: confchk() 
confrm() {
	cd /etc/conf/cf.d
	echo "

	Updating system files to effect removal 
	of driver ...\c"
	./configure -c -d -m $major -Y -R > conflog 2>&1 || {
		conferr
		return $FAIL
	}
	echo "

	System files have been updated."
	rm -f conflog
	change=YES
	sleep 2
	return $OK
}

# -------TAPE SPECIFIC ROUTINES ------- These routines are specific to 
#					mkdev tape. 
#					

# Edit $DEFAULT.
# This file contains the default device used by /usr/bin/tape and also  
# keeps track of the current driver for use by this script.
# The routine will add curdriver if it is not present in DEFAULT.
edit_def () {
	driver=$1
	case $driver in
		ct) 	tpdev=xct0	cdriv=ct		;;
		ir) 	tpdev=xctmini	cdriv=ir		;;
		ft) 	tpdev=xctmini	cdriv=ft		;;
		Stp) 	tpdev=xct0	cdriv=Stp${SCSIpos}	;;
		NONE)   tpdev=xct0	cdriv=NONE		;;
	esac
	cp $DEFAULT $DEFAULT.00 || {
		error "
	Cannot backup $DEFAULT"
		cleanup $FAIL
	}
	trap 'mv $DEFAULT.00 $DEFAULT; cleanup $FAIL' 1 2 3 15
	sed "/curdriver/d" $DEFAULT > $tmp
	echo "curdriver=$cdriv" >> $tmp
	sed "s!device = /dev/.*!device = /dev/$tpdev!" $tmp > $DEFAULT
	set_trap
}

# ------- Add Drivers -------- 		These routines add tape drivers to 
#					configuration files and create 
#					necassary devices

# This program examines the mscsi file and returns the number of
# SCSI tape devices configured. SCSIpos is used to calculate minor
# device numbers for SCSI tapes.
# Global variables set: 
#	SCSIpos
find_SCSIpos() {
	[ -r /etc/conf/cf.d/mscsi ] || {
		error "
	Cannot read /etc/conf/cf.d/mscsi."
		cleanup $FAIL
	}
	tnum=`sed '/^*/d' /etc/conf/cf.d/mscsi | sed '/^-/d' | grep -c "Stp"` 
	[ -n "$tnum" ] || {
		error "
	Grep failed to read /etc/conf/cf.d/mscsi."
		cleanup $FAIL
	}
	# SCSI numbering starts at 0.
	SCSIpos=`expr $tnum - 1`
	return $OK
}

# This routine sets MINIpos, used to calculate the minor device number
# for mini tape devices.
# Global variables used and where set:
# 	$DESCR: menu routines
# Global variables set: 
#	MINIpos
ask_MINIpos() {
	minidef=$1
	tnum=
	clear
	mesg="

	If you have changed the unit number for the 
	$DESCR enter the new number 
	[1-4] or press <Return> to use the default value 
	of $minidef "
	while :
	do	prompt $minidef || return $FAIL
		case $cmd in
		[1-4])	tnum=$cmd
			break
			;;
		*)	echo "
	$cmd is not valid. Please choose a number 
	between 1 and 4."
			continue
			;;
		esac
	done
	# Numbering starts at 0 for minor number calculation.
	MINIpos=`expr $tnum - 1`
	return $OK
}

# Create all non-default tape devices. 
# Global variables used and where set:
# 	$SCSIpos: find_SCSIpos(); $MINIpos: find_MINIpos()
mk_nodes() {
	driver=$1
	case $driver in
	ct) 	#  Qic-02 Cartridge Tape.
		# Since ct can only be a default device, we create the
		# nodes in lnk_defaults. 
		devs=
		;;
	ir) 	#  Irwin mini tape.
		# mkdevice "rir0"   3 
		# mkdevice "xir0" 131
		# MINIpos is the unit number and is set in addmini.
		minor=`expr 0 + $MINIpos`;   mkdevice "rir0"    $minor
		minor=`expr 128 + $MINIpos`; mkdevice "xir0"    $minor
		devs="\t/dev/rir0\t/dev/xir0"
		;;
	ft) 	#  Qic-40 mini tape.
		# mkdevice "rft0"   1
		# mkdevice "xft0" 129
		# MINIpos is the unit number and is set in addqic40.
		minor=`expr 0 + $MINIpos`;   mkdevice "rft0"    $minor
		minor=`expr 128 + $MINIpos`; mkdevice "xft0"    $minor
		devs="\t/dev/rft0\t/dev/xft0"
		;;
	 Stp) 	#  Scsi tape driver.
		# Minor number is determined by adding base number plus
		# position of device in mscsi file. SCSIpos set in addscsi.
		minor=`expr 0 + $SCSIpos`;   mkdevice "rStp${SCSIpos}"    $minor
		minor=`expr 8 + $SCSIpos`;   mkdevice "nrStp${SCSIpos}"   $minor
		minor=`expr 16 + $SCSIpos`;  mkdevice "vrStp${SCSIpos}"   $minor
		minor=`expr 24 + $SCSIpos`;  mkdevice "nvrStp${SCSIpos}"  $minor

		# low density SCSI tape drives
		minor=`expr 32 + $SCSIpos`;  mkdevice "lrStp${SCSIpos}"   $minor
		minor=`expr 40 + $SCSIpos`;  mkdevice "nlrStp${SCSIpos}"  $minor
		minor=`expr 48 + $SCSIpos`;  mkdevice "vlrStp${SCSIpos}"  $minor
		minor=`expr 56 + $SCSIpos`;  mkdevice "nvlrStp${SCSIpos}" $minor

		# medium density SCSI tape drives
		minor=`expr 64 + $SCSIpos`;  mkdevice "mrStp${SCSIpos}"   $minor
		minor=`expr 72 + $SCSIpos`;  mkdevice "nmrStp${SCSIpos}"  $minor
		minor=`expr 80 + $SCSIpos`;  mkdevice "vmrStp${SCSIpos}"  $minor
		minor=`expr 88 + $SCSIpos`;  mkdevice "nvmrStp${SCSIpos}" $minor

		# high density SCSI tape drives
		minor=`expr 96 + $SCSIpos`;  mkdevice "hrStp${SCSIpos}"   $minor
		minor=`expr 104 + $SCSIpos`; mkdevice "nhrStp${SCSIpos}"  $minor
		minor=`expr 112 + $SCSIpos`; mkdevice "vhrStp${SCSIpos}"  $minor
		minor=`expr 120 + $SCSIpos`; mkdevice "nvhrStp${SCSIpos}" $minor

		minor=`expr 128 + $SCSIpos`; mkdevice "xStp${SCSIpos}"    $minor
		devs=\
"\t/dev/rStp${SCSIpos}\t/dev/nrStp${SCSIpos}\t/dev/xStp${SCSIpos}\n\
\t/dev/lrStp${SCSIpos}\t/dev/mrStp${SCSIpos}\t/dev/hrStp${SCSIpos}\n\
\t/dev/nlrStp${SCSIpos}\t/dev/nmrStp${SCSIpos}\t/dev/nhrStp${SCSIpos}\n\
\t/dev/vlrStp${SCSIpos}\t/dev/vmrStp${SCSIpos}\t/dev/vhrStp${SCSIpos}\n\
\t/dev/nvlrStp${SCSIpos}\t/dev/nvmrStp${SCSIpos}\t/dev/nvhrStp${SCSIpos}\n\
\t/dev/vrStp${SCSIpos}\t/dev/nvrStp${SCSIpos}"
		;;
	esac
	[ -n "$devs" ] && echo "`clear`

	The following special devices have been 
	created:\n\n$devs

	Press return to continue:  \c"
	read a
}

# Link a tapes nodes to the default devices. Note that this does not 
# necessarily mean that this tape is also the one listed in $DEFAULT.
# Global variables used and where set:
# 	$SCSIpos: find_SCSIpos(); $DESCR: menu routines
lnk_defaults() {
	driver=$1
	devs=
	[ -d /dev/rmt ] || mkdir /dev/rmt
	case $driver in
	ct) 	#   Qic-02 Cartridge Tape. 
		# Qic-02 must use the default nodes. Therefore all ct nodes are
		# created here.
		rm_defaults "ct"
		mkdevice rct0	   0;  ln /dev/rct0	/dev/rmt/0b
		mkdevice nrct0     8;  ln /dev/nrct0 	/dev/rmt/0bn
		mkdevice rct2	  16;  ln /dev/rct2	/dev/rmt/0a
		mkdevice nrct2    24;  ln /dev/nrct2	/dev/rmt/0an
		mkdevice erct0    32;  ln /dev/erct0	/dev/rmt/0be
		mkdevice xct0    128 
		devs="/dev/xct0
\t/dev/rct0 \tlinked to  /dev/rmt/0b\n\t/dev/nrct0 \tlinked to  /dev/rmt/0bn
\t/dev/rct2 \tlinked to  /dev/rmt/0a\n\t/dev/nrct2 \tlinked to  /dev/rmt/0an
\t/dev/erct0 \tlinked to  /dev/rmt/0be"
		;;
	ir) 	#  Irwin mini tape. 
		if [ -c /dev/rir0 -a -c /dev/xir0 ]; then
			rm_defaults "ir"
			ln /dev/rir0  /dev/rctmini 
			ln /dev/xir0  /dev/xctmini
			devs="/dev/rctmini \tlinked to /dev/rir0
\t/dev/xctmini \tlinked to /dev/xir0"
		fi
		;;
	ft) 	#  Qic-40 mini tape.
		if [ -c /dev/rft0 -a -c /dev/xft0 ]; then
			rm_defaults "ft"
			ln /dev/rft0  /dev/rctmini
			ln /dev/xft0  /dev/xctmini
			devs="/dev/rctmini \tlinked to /dev/rft0
\t/dev/xctmini \tlinked to /dev/xft0"
		fi
		;;
	 Stp) 	#  Scsi tape driver.
		if [ -c /dev/rStp${SCSIpos} -a -c /dev/nrStp${SCSIpos} \
		     -a -c /dev/xStp${SCSIpos} ]; then
			rm_defaults "Stp"
			ln /dev/rStp${SCSIpos}   /dev/rct0
			ln /dev/rStp${SCSIpos}   /dev/rmt/0b

			ln /dev/nrStp${SCSIpos}  /dev/nrct0 
			ln /dev/nrStp${SCSIpos}  /dev/rmt/0bn

			ln /dev/xStp${SCSIpos}   /dev/xct0

			devs="/dev/xct0 \tlinked to  /dev/xStp${SCSIpos}
\t/dev/rct0 \tlinked to  /dev/rStp${SCSIpos} \tand /dev/rmt/0b
\t/dev/nrct0 \tlinked to  /dev/nrStp${SCSIpos} \tand /dev/rmt/0bn"
		fi
		;;
	esac
	if [ -n "$devs" ]; then
		echo "`clear`

	Default special devices have been created 
	with the following links:

	$devs

	Press return to continue:  \c"
	read a
	else
		error "
	Tape driver $DRIVER nodes do not 
	exist or are not character special. Cannot 
	link to default devices.

	Press return to continue:  \c"
	read a
		return $FAIL
	fi
	return $OK
}

# Check $DEFAULT for presence of another default tape drive.
# Global variables used and where set:
# 	$DESCR: menu routines
def_driveclash() {
	# curdriver is added to $DEFAULT the first time mkdev tape runs.
	grep -s "curdriver" $DEFAULT > /dev/null && {
		grep -s "curdriver=NONE" $DEFAULT > /dev/null || { 
			clear
			getyn "

	Another Tape Drive is currently listed as 
	the default in $DEFAULT.  Do you 
	wish to change this to the current 
	$DESCR?" || return $FAIL
		}
	}
	return $OK
}
	
# Check for conflicting default devices. Return OK if no conflict. 
# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines 
def_nodeclash() {
	case $DRIVER in
	ct) 	#  Qic-02 Cartridge Tape.
		# Check for conflicts with SCSI.
		confchk "Stp" || return $OK
		echo "
	The presence of a SCSI Tape Drive has been 
	detected. The $DESCR must use default devices 
	to function properly. Therefore, any SCSI 
	links to default devices will be removed. 
	Access to a SCSI tape can be made through the 
	following devices: 

	/dev/rStp[0-7]	/dev/xStp[0-7]	/dev/nrStp[0-7]"
		return $OK
		;;

	ft|ir) 	#  Qic-40 mini tape or Irwin mini tape.
		grep "device = /dev/xctmini" $DEFAULT > /dev/null 2>&1 && {
			clear
			getyn "

	Another tape drive is currently linked to 
	the default device /dev/xctmini.  Do you 
	wish to remove this link and have the 
	$DESCR linked to the 
	default devices?" || return $FAIL
		}
		return $OK
		;;

	Stp) 	#  Scsi tape driver.
		# Check for conflict with ct devices.
################
#
# Since Altos machines are SCSI-based, we do not need to
# do this.
#
#		confchk "ct" && {
#			echo "`clear`
#
#	The presence of a Cartridge Tape Drive has 
#	been detected. The Cartridge Tape Drive must 
#	use the default devices to function properly. 
#	Therefore, SCSI devices will be created without 
#	default device links.
#
#	Press return to continue:  \c"
#			read a
#			return $FAIL
#		}
################
		# Is another SCSI Drive the current default.
		grep -s "curdriver=Stp" $DEFAULT > /dev/null && {
			clear
			getyn "

	Another SCSI Tape Drive is currently linked to 
	the default device /dev/xct0.  Would you like 
	the current SCSI Drive linked to the default 
	devices?" || return $FAIL
		}
		return $OK 
		;;
	esac
}

# Add the QIC-02 driver to configuration files and make devices. 
# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines; $major: confchk() or confadd()
# Global variables set:
# 	fns, dev_major	
addqic02 () {
	# Check for the presence of the link kit. Install if it not present.
	permschk && linkchk

	confchk "$DRIVER"  && {
		clear
		getyn "

	The ${DESCR}r is already present 
	in system configuration files.  Do you wish to 
	continue?" || return $FAIL 
	}
	# ctconfig allows user to modify interrupt and base address
	# (it edits values in /etc/conf/pack.d/ct/space.c )
	cd /etc/conf/pack.d/ct
	./ctconfig || {
		error "
	The system must be configured in order to 
	use the $DESCR.  Exiting ...\n"
		cleanup $FAIL 
	}
	# Remove tmp file created by ctconfig.
	rm -f /tmp/ctconfig*
        fns="ctinit ctioctl ctread ctwrite ctopen ctclose"
	confadd || cleanup $FAIL
	cd /

	# Set dev_major for use in mkdevice(). 
	dev_major=$major
	# mk_nodes() is not required ct. Nodes created in lnk_defaults().
	# Presently, def_nodeclash will always return true for ct since
	# it must use default devices. 
	def_nodeclash && {
		# Link driver to default devices.
		lnk_defaults "$DRIVER"
		def_driveclash && {
			# edit /etc/default/tape.
			edit_def "$DRIVER"
		}
	}
	return $OK
}

# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines; $major: confchk() or confadd() 
# 	$SCSIpos: find_SCSIpos()
# Global variables set:
# 	dev_major, change
addscsi () {
	# Check for the presence of the link kit. Install if it not present.
	permschk && linkchk

	# Configure the driver if necassary.
	confchk "$DRIVER"  || {
		# Add scsi driver to config files.
		confadd || cleanup $FAIL
	}
	find_SCSIpos ; oSCSIpos=$SCSIpos
	[ $oSCSIpos -ge 7 ] && {
		echo "
	Sorry, the maximum of eight SCSI Tape Drives 
	has been reached. Unable to configure another 
	one."
		return $FAIL
	}
	clear
	getyn "

	The SCSI Tape Drive must be configured before 
	use.  Do you wish to configure the SCSI Tape 
	Drive now?" || {
		echo "
	The SCSI Tape Driver has been added to system 
	configuration files.  However, 
	/etc/conf/cf.d/mscsi must also be updated 
	before using a SCSI Tape Drive. It is advisable 
	to reinvoke 'mkdev tape' to accomplish this.

	Press return to continue:  \c"
	read a
		return $FAIL
}
	# Edit /etc/conf/cf.d/mscsi
	/bin/sh /usr/lib/mkdev/.scsi -a -t -n -o || return $FAIL

	while :
	do 	find_SCSIpos ; nSCSIpos=$SCSIpos
	 	differ=`expr $nSCSIpos - $oSCSIpos`
	 	case $differ in
	 	0) 	
			getyn "
	The number of SCSI Tape Drives has not been 
	changed.  Do you wish to try again?" || return $FAIL
			;;
		[1-8]) 	break
			;;
		    9) 	echo "
	A maximum of eight SCSI Tape Drives are allowed.
	Please reconfigure."
			return $FAIL
			;;
		*) 	error "$differ not valid."
			return $FAIL
			;;
		esac
		echo "
	Invoking the interface to the master SCSI device 
	file."
		/bin/sh /usr/lib/mkdev/.scsi -a -t -n -o || return $FAIL
	done
	change=YES

	# Set dev_major for use in mkdevice(). 
	dev_major=$major

	SCSIpos=$oSCSIpos
	while [ $SCSIpos -lt $nSCSIpos ]
	do
		SCSIpos=`expr $SCSIpos + 1`
		# Create pure scsi devices.
		mk_nodes "$DRIVER"
	done
	def_nodeclash && {
		# Link driver to default devices.
		lnk_defaults "$DRIVER"
		def_driveclash && {
			# edit /etc/default/tape.
			edit_def "$DRIVER"
		}
	}
	return $OK
}

# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines;  $major: confchk() or confadd()
#	$MINIpos: ask_MINIpos()
# Global variables set:
# 	fns, dev_major
addqic40 () {
	# Check for the presence of the link kit. Install if it not present.
	permschk && linkchk

	confchk "$DRIVER" && {
		getyn "
	The ${DESCR}r is already present 
	in system configuration files.  Do you wish to 
	continue?" || return $FAIL 
	}
	# Set the unit number MINIpos. "2" is the default.
	ask_MINIpos "2" || return $FAIL

	fns="ftinit ftioctl ftread ftwrite ftopen ftclose ftpoll"
	# Add to configuration files.
	confadd || cleanup $FAIL

	# Set dev_major for use in mkdevice(). major was set in confchk().
	dev_major=$major
	# Create pure qic-40 devices.
	mk_nodes "$DRIVER"
	def_nodeclash && {
		# Link driver to default devices.
		lnk_defaults "$DRIVER"
		def_driveclash && {
			# edit /etc/default/tape.
			edit_def "$DRIVER"
		}
	}
	return $OK
}

# add irwin minitape driver
# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines; $major: confchk() or confadd()
#	$MINIpos: ask_MINIpos()
# Global variables set:
# 	fns, dev_major	
addmini () {
	# Check for the presence of the link kit. Install if it not present.
	permschk && linkchk

	confchk "$DRIVER" && {
		getyn "
	The ${DESCR}r is already present 
	in system configuration files.  Do you wish to 
	continue?" ||  return $FAIL
	}
	# Set the unit number MINIpos. "2" is the default.
	ask_MINIpos "2" || return $FAIL

	fns="irinit irioctl irread irwrite iropen irclose irpoll"
	# Add to configuration files.
	confadd || cleanup $FAIL

	# Set dev_major for use in mkdevice(). major was set in confchk().
	dev_major=$major
	# Create pure irwin devices.
	mk_nodes "$DRIVER"
	def_nodeclash && {
		# Link driver to default devices.
		lnk_defaults "$DRIVER"
		def_driveclash && {
			# edit /etc/default/tape.
			edit_def "$DRIVER"
		}
	}
	return $OK
}	

# ------- Remove Drivers -------- 	These routines remove tape drivers from 
#					configuration files and delete 
#					appropriate devices.

# Global variables set:
# 	SCSIpos	
askSCSI_def() {
	echo "`clear`

	The interface to the master SCSI device file 
	will now be invoked.  Choose option 3 from the 
	main menu. This will print a table of all SCSI 
	devices configured.

	Starting at the top of the table, ignoring 
	non-tape devices, count down to the SCSI Tape 
	Drive you would like to become the new default.

	For instance, if the first Tape Drive listed 
	after a hard disk is the one you want to choose, 
	this would be denoted by position 1.  Quit out 
	of that program.  You will then be prompted for 
	the position of that Tape Drive.

	Press return to continue:  \c"

	read dummy

	/bin/sh /usr/lib/mkdev/.scsi -o
	while mesg="
	Please enter the position of the SCSI Tape 
	Drive you would like to become the new default\n\t"
	do prompt || return $FAIL
		case $cmd in
		[1-8])	tnum=`expr $cmd - 1`
			if [ -c /dev/xStp${tnum} ]; then
				SCSIpos=$tnum
				break
			else
				echo "
	Error:  There are no corresponding special 
	devices for the SCSI device chosen.
"
			continue
			fi		;;
		*) 	echo "
	$cmd not valid. Please enter a number between 1-8." 	;;
		esac
	done
	return $OK
}

# Global variables used and where set:
# 	$DRIVER: menu routines
# 	$SCSIpos: askSCSI_def() or find_SCSIpos()
is_default() {
	case $DRIVER in
	ct) 	#  Qic-02 Cartridge Tape.
		grep "curdriver=ct" $DEFAULT > /dev/null 2>&1 && return $OK
		;;

	ft) 	#  Qic-40 mini tape.
		grep "curdriver=ft" $DEFAULT > /dev/null 2>&1 && return $OK
		;;

	ir) 	#  Irwin mini tape.
		grep "curdriver=ir" $DEFAULT > /dev/null 2>&1 && return $OK
		;;

	Stp) 	#  Scsi tape driver.
		tag="curdriver=Stp${SCSIpos}"
		grep "$tag" $DEFAULT > /dev/null 2>&1 && return $OK
		;;
	esac
	return $FAIL
}

# Remove all non-default tape devices. 
# Global variables used and where set:
# 	$SCSIpos: askSCSI_def() 
rm_nodes() {
	driver=$1
	case $driver in
	ct) 	# Qic-02 Cartridge Tape.
		# Since ct always was the default device, we remove the
		# nodes in lnk_defaults
		;;
	ir) 	# Irwin mini tape.
		rm -rf /dev/rir0   /dev/xir0
		;;
	ft) 	# Qic-40 mini tape.
		rm -rf /dev/rft0  /dev/xft0
		;;
	Stp) 	# Scsi tape driver.
		rm -rf 	/dev/rStp${SCSIpos}    /dev/nrStp${SCSIpos}  	\
			/dev/xStp${SCSIpos}    /dev/vrStp${SCSIpos}  	\
			/dev/nvrStp${SCSIpos}				\
			/dev/lrStp${SCSIpos}   /dev/nlrStp${SCSIpos} 	\
			/dev/mrStp${SCSIpos}   /dev/nmrStp${SCSIpos}  	\
			/dev/hrStp${SCSIpos}   /dev/nhrStp${SCSIpos} 	\
			/dev/vlrStp${SCSIpos}  /dev/nvlrStp${SCSIpos} 	\
			/dev/vmrStp${SCSIpos}  /dev/nvmrStp${SCSIpos} 	\
			/dev/vhrStp${SCSIpos}  /dev/nvhrStp${SCSIpos} 
		;;
	esac
}

# Remove default tape devices. 
rm_defaults() {
	driver=$1
	case $driver in
	ct) 	# Qic-02 Cartridge Tape.
		# Qic-02 can only be the default drive. 
		rm -rf /dev/rct0   	/dev/rmt/0b
		rm -rf /dev/nrct0 	/dev/rmt/0bn
		rm -rf /dev/rct2	/dev/rmt/0a
		rm -rf /dev/nrct2	/dev/rmt/0an
		rm -rf /dev/erct0	/dev/rmt/0be
		rm -rf /dev/xct0    
		;;
	ir) 	# Irwin mini tape.
	 	rm -rf /dev/rctmini  /dev/xctmini
		;;
	ft) 	# Qic-40 mini tape.
	 	rm -rf /dev/rctmini  /dev/xctmini
		;;
	 Stp) 	# Scsi tape driver.
		rm -rf /dev/rct0   /dev/rmt/0b
		rm -rf /dev/nrct0  /dev/rmt/0bn
		rm -rf /dev/xct0
		;;
	esac
	return $OK
}

# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines
rmqic02 () {
	# Check for the presence of the link kit. Install if it not present.
	permschk && linkchk
	confchk "$DRIVER" || {
		echo "

	The ${DESCR}r is not currently 
	configured."
		sleep 2
		return $FAIL
	}
	confrm || cleanup $FAIL
	rm_nodes "$DRIVER"
	is_default && {
		echo "`clear`

	Removing default tape devices."
		rm_defaults "$DRIVER"
		edit_def "NONE"
	} 
	echo "
	${DESCR}r and associated devices 
	have been removed.

	Press return to continue:  \c"
	read a
	return $OK
}
	
# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines
rmmini () {
	# Check for the presence of the link kit. Install if it not present.
	permschk && linkchk
	confchk "$DRIVER" || {
		echo "

	The ${DESCR}r is not currently 
	configured."
		sleep 2
		return $FAIL
	}
	confrm || cleanup $FAIL
	rm_nodes "$DRIVER"
	is_default && {
		echo "`clear`

	Removing default tape devices."
		rm_defaults "$DRIVER"
		edit_def "NONE"
	} 
	echo "
	${DESCR}r and associated devices 
	have been removed.

	Press return to continue:  \c"
	read a
	return $OK
}

# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines
rmqic40 () {
	# Check for the presence of the link kit. Install if it not present.
	permschk && linkchk
	confchk "$DRIVER" || {
		echo "

	The ${DESCR}r is not currently 
	configured."
		sleep 2
		return $FAIL
	}
	confrm || cleanup $FAIL
	rm_nodes "$DRIVER"
	is_default && {
		echo "`clear`

	Removing default tape devices."
		rm_defaults "$DRIVER"
		edit_def "NONE"
	} 
	echo "
	${DESCR}r and associated devices 
	have been removed.

	Press return to continue:  \c"
	read a
	return $OK
}

# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines; 
# 	$SCSIpos: find_SCSIpos() 
rmscsi() {
	confchk "$DRIVER" || {
		echo "

	The ${DESCR}r is not currently 
	configured."
		sleep 2
		return $FAIL
	}
	find_SCSIpos ; oSCSIpos=$SCSIpos
	if [ $oSCSIpos -lt 0 ] 
	then
		clear
		getyn "

	There are currently no SCSI Tape Drives 
	configured in the /etc/conf/cf.d/mscsi
	file.  Do you wish to continue."	|| return $FAIL
		# Pretend we have 8 so we can remove any nodes created and
		# remove scsi driver from kernel.
		oSCSIpos=7
	else
		# Edit /etc/conf/cf.d/mscsi
		/bin/sh /usr/lib/mkdev/.scsi -r -t -n -o || return $FAIL
	fi
	find_SCSIpos ; nSCSIpos=$SCSIpos
	differ=`expr $oSCSIpos - $nSCSIpos`
	case $differ in
 	0) 	
		echo "
	The number of SCSI Tape Drives has not been 
	changed."
		sleep 2
		return $FAIL
		;;
	[1-8]) 	:	# OK
		;;
	*) 	error "$differ not valid."
			sleep 2
			return $FAIL
		;;
	esac
	change=YES

	SCSIpos=$oSCSIpos
	while [ $SCSIpos -gt $nSCSIpos ]
	do
		rm_nodes "$DRIVER"
		is_default && { 
			echo "`clear`

	Removing default tape devices."
			rm_defaults "$DRIVER"
			edit_def "NONE"
		} 
		SCSIpos=`expr $SCSIpos - 1`
	done

	[ $SCSIpos -eq -1 ] && { 
		permschk && linkchk
	#	confrm || cleanup $FAIL
	}
	echo "
	The SCSI Tape Drive specified and associated 
	devices have been removed.

	Press return to continue:  \c"
	read a
	return $OK
}

# ----- Change Default Tape ------	These routines implement a change
#					in the default tape drive.

#  Qic-02 Cartridge Tape.
# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines; 
changeqic02()  {
	confchk "$DRIVER" || {
		echo "

	The ${DESCR}r is not currently 
	installed."
		sleep 2
		return 
	}
	# QIC-02 is always linked to the default devices. Just edit $DEFAULT
	edit_def "$DRIVER"
	return
}

#  Irwin mini tape.
# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines; 
changemini()  {
	confchk "$DRIVER" || {
		echo "

	The ${DESCR}r is not currently 
	installed."
		sleep 2
		return 
	}
	lnk_defaults "$DRIVER"
	edit_def "$DRIVER"
	return
}

#  Qic-40 mini tape.
# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines; 
changeqic40()  {
	confchk "$DRIVER" || {
		echo "

	The ${DESCR}r is not currently 
	installed."
		sleep 2
		return 
	}
	lnk_defaults "$DRIVER"
	edit_def "$DRIVER"
	return
}

# Global variables used and where set:
# 	$DRIVER, $DESCR: menu routines; 
# 	$SCSIpos: find_SCSIpos() or askSCSI_def
changescsi()  {
	confchk "$DRIVER" || {
		echo "

	The ${DESCR}r is not currently 
	installed."
		sleep 2
		return 
	}
	# If ct exists, we want to let it keep it's default status.

################
#
# Since Altos machines are SCSI-based, we do not need to
# do this.
#
#	confchk "ct" && {
#		echo "`clear`
#
#	The presence of the Cartridge Tape Driver has 
#	been detected. The Cartridge Tape Drive must 
#	use the default devices to function properly. 
#	Therefore, to use a SCSI Drive as the default, 
#	you must first remove the Cartridge Tape.
#
#	Press return to continue:  \c"
#		read a
#		return 
#	}
################

	# This will return the number of SCSI tape drives.
	find_SCSIpos 
	if [ $SCSIpos -gt 0 ]; then 
		# This routine will reset SCSIpos to the one they want.
		askSCSI_def || return $OK
		lnk_defaults "$DRIVER"
	else
		lnk_defaults "$DRIVER"
	fi
	edit_def "$DRIVER"
	return
}

# -------  MENU ROUTINES  ------- 	These routines present a menu,
#					prompt the user, set global variables
#					and execute appropriate routines.

# find out what they want to install
installmenu () {
quit="return\n\tto the main menu"
mesg="`clear`

	Tape Drive Installation Menu


	1.  Install a Cartridge Tape Drive
	2.  Install a Mini-Cartridge Tape Drive
	3.  Install a QIC-40 Tape Drive
	4.  Install a SCSI Tape Drive

	Select an option "

	while :
	do prompt || return
		itape=$cmd
		quit="return to the main menu"
		case $itape in
		1) 	DESCR="Cartridge Tape Drive" 		DRIVER=ct
	   		addqic02 || return		
			;;
		2) 	DESCR="Mini-Cartridge Tape Drive" 	DRIVER=ir
	   		addmini || return 				
			;;
		3) 	DESCR="QIC-40 Tape Drive" 		DRIVER=ft
	   		addqic40 || return				
			;;
		4) 	DESCR="SCSI Tape Drive" 		DRIVER=Stp
	   		addscsi	|| return				
			;;
		*) error "Please enter 1, 2, 3, 4 or 'q' to quit"	
		quit="return\n\tto the main menu"
	   	continue				;;
		esac
		break
	done
}

# find out what they want to remove
removemenu () {
	quit="\n\treturn to the main menu"
	mesg="`clear`

	Tape Drive Removal Menu


	1.  Remove Cartridge Tape Drive
	2.  Remove Mini-Cartridge Tape Drive
	3.  Remove Qic-40 Tape Drive
	4.  Remove SCSI Tape Drive

	Enter your selection "

	while :
	do prompt || return
		rtape=$cmd
		case $rtape in
		1) 	DESCR="Cartridge Tape Drive" 		DRIVER=ct
	   		rmqic02 || return		
			;;
		2) 	DESCR="Mini-Cartridge Tape Drive" 	DRIVER=ir
	   		rmmini || return 				
			;;
		3) 	DESCR="QIC-40 Tape Drive" 		DRIVER=ft
	   		rmqic40 || return				
			;;
		4) 	DESCR="SCSI Tape Drive" 		DRIVER=Stp
	   		rmscsi	|| return				
			;;
		*) error "Please enter 1, 2, 3, 4 or 'q' to quit"	
	   	continue				;;
		esac
		break
	done
}

changemenu() {
	quit="return to the main menu"
	mesg="`clear`

	Default Tape Drive Update Menu


	1.  Cartridge Tape Drive
	2.  Mini-Cartridge Tape Drive
	3.  Qic-40 Tape Drive
	4.  SCSI Tape Drive

	Please select the tape drive you would 
	like to have linked to default devices
	"

	while :
	do prompt || return
		ctape=$cmd
		case $ctape in
		1) 	DESCR="Cartridge Tape Drive" 		DRIVER=ct
	   		changeqic02 	|| return
			;;
		2) 	DESCR="Mini-Cartridge Tape Drive" 	DRIVER=ir
	   		changemini 	|| return
			;;
		3) 	DESCR="QIC-40 Tape Drive" 		DRIVER=ft
	   		changeqic40 	|| return
			;;
		4) 	DESCR="SCSI Tape Drive" 		DRIVER=Stp
	   		changescsi	|| return
			;;
		*) error "Please enter 1, 2, 3, 4 or 'q' to quit"	
	   	continue				;;
		esac
		break
	done
}

# main()
#########################

set_trap
cd /
clearscr
while mesg="`clear`

	Tape Drive Configuration


	1.  Install a Tape Drive
	2.  Remove a Tape Drive
	3.  Change default Tape Drive 

	Enter your selection "
	quit="quit"
do prompt || break
# reset these flags prior to each pass through menu
major=
IPL=
IV=
select=$cmd
case $select in
	1) installmenu		;;
	2) removemenu		;;
	3) changemenu		;;
	*) echo "
	Please select either 1, 2 or 3"
	   continue		;;
esac
done

if [ "$change" = "YES" ] 
then

	if [ "$_RELINK" -o "$_NOPROMPT" ]
	then
		klink
	else
		asklink && klink  
	fi
fi

cleanup $OK
