:
#	@(#) dda.sh 1.7 89/07/25 
#
#	Copyright (C) The Santa Cruz Operation, 1988, 1989.
#	This Module contains Proprietary Information of
#	The Santa Cruz Operation, and should be treated as Confidential.
#

# dda - UNIX 3.2 VP/ix DDA initialization
#
PATH=/etc:/bin:/usr/bin
LANG=english_us.ascii
export PATH LANG

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

name=dda
funcs="ddaopen ddaclose ddaioctl ddaintr" 

# 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 ..."; 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" ] && 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 "\n${mesg}or enter 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 "\nError: $*" >&2
	return $FAIL
}

# Configure error message
conferr()  {
	error "\nConfigure 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
}

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

		# Not fully installed. Do so here
		getyn "\nDo 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 "\nInvoking /etc/custom\n"
		/etc/custom -o -i LINK || {
			# custom exited unsuccessfully
			error "custom failed to install Link Kit successfully.  Please try again."
			cleanup $FAIL
		}
	done
}

asklink()  {
	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. Then you
must reboot your system by executing  /etc/shutdown -i0  before the 
changes you have specified will be implemented.\n"
			return $FAIL 
		}
	return $OK
}

 # re-link new kernel
 klink() {
 	cd /etc/conf/cf.d
 	./link_unix || { 
 		echo "\nError: Kernel link failed."
 		cleanup $FAIL
 	}
 	return $OK
 }


# ---------- DEVICE ROUTINES ---------  This routine creates devices.
#					

# Create appropriate devices.  
# usage:  mkdevice name major# minor#
mkdevice() {
	[ -c /dev/$1 ] && return $OK
	mknod /dev/$1 c $2 $3 || {
		error "mknod failed to create /dev/$1."
		return $FAIL
	}
	chmod 622 /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. 
# It returns OK only if driver is fully installed.
# 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.
# 	YES:  Device has a major number and the -Y option is set in  
#	      the sdevice file.
# Where variables are set:
# name: script beginning	
confchk () {
	cf_state=
	major=
	cd /etc/conf/cf.d
	major=`./configure -j $name` || {
		cf_state=NO
		return $FALSE
	}
	cf_state=PART
	if [ -f ../sdevice.d/$name ] 
	then
		fieldval=`awk '{print $2}' ../sdevice.d/$name` || {
			error "awk failed to read sdevice file."
			cleanup $FAIL
		}
		[ "$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 $FALSE
}

# Add driver according to cf_state. 
# Where variables are set:
# name: script start	funcs: script start	cf_state: confchk()
# major: confchk() if cf_state=PART
confadd() {
	
	cd /etc/conf/cf.d
	case $cf_state in

	NO) 	echo "\nAdding device to system configuration files ...\c" >&2
		major=`./configure -j NEXTMAJOR`
		./configure -c -a $funcs -m $major -R > conflog ||  {
			conferr
			return $FAIL
		} ;;
	PART)   echo "\nUpdating system configuration ...\c" >&2
	        ./configure -a -c -m $major -Y -R > conflog ||  {
			conferr
			return $FAIL
		} ;;
	esac
	echo "\n\nSystem configuration files have been successfully modified."
	change=YES
	rm -f conflog
	return $OK
}

# Configure driver out of system configuration files by unsetting -Y option.
# Where variables are set:
# major: confchk() 
confrm() {
	cd /etc/conf/cf.d
	echo "\nUpdating system files to effect removal of driver ...\c"
	./configure -c -d -m $major -Y -R > conflog 2>&1 || {
		conferr
		return $FAIL
	}
	echo "\n\nSystem configuration files have been successfully modified."
	rm -f conflog
	change=YES
	return $OK
}

# ---------- MAIN ROUTINES ---------- 	These routines execute the flow of 
#					events to complete the task 
#					corresponding to the main menu.

add_dda()  {

	# Check state of driver in system configuration files.
	confchk && {
 		getyn "
DDA routines are already present in system configuration files. 
Do you wish to relink the kernel ?" && {
			klink
			cleanup $OK
		}
		return $FAIL
	}

	# Modify system configuration files to include driver.
	confadd || cleanup $FAIL
	# Create device node
	mkdevice dda $major 1 
	return $OK
}

rm_dda()  {
	confchk || {
		echo "
DDA routines are not currently present in system configuration files."
		return $FAIL
	}
	# Update system configuration files.
	confrm || return $FAIL
	# Remove associted device.
	rm -f /dev/dda
	return $OK
}

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

cd /
set_trap
permschk
linkchk

clearscr 
while
	mesg="\n\n\nDDA Driver Configuration Program \n
	1. Add DDA driver from the system.
	2. Remove DDA driver from the system.
	
Select an option "
do
	prompt || break
  	case $cmd in
		1) add_dda && break  ;;

		2) rm_dda && break   ;;

		*) echo "\n$cmd is not valid. Try again."
		   continue  ;;
	esac
done
	
if [ "$change" = "YES" ] 
then
	if [ "$_RELINK" -o "$_NOPROMPT" ]
	then
		klink
	else
		asklink && klink  
	fi
fi

cleanup $OK
