#!/bin/sh
#
# |-----------------------------------------------------------|
# | Copyright (c) 1991, 1990 MIPS Computer Systems, Inc.      |
# | All Rights Reserved                                       |
# |-----------------------------------------------------------|
# |          Restricted Rights Legend                         |
# | Use, duplication, or disclosure by the Government is      |
# | subject to restrictions as set forth in                   |
# | subparagraph (c)(1)(ii) of the Rights in Technical        |
# | Data and Computer Software Clause of DFARS 252.227-7013.  |
# |         MIPS Computer Systems, Inc.                       |
# |         950 DeGuigne Avenue                               |
# |         Sunnyvale, California 94088-3650, USA             |
# |-----------------------------------------------------------|
#
# $Header: idinstall,v 1.3.2.1 92/06/24 13:34:43 marker Exp $
# v4.51 RISC/OS version of the AT&T idinstall utility.
#
# This is a shell script that replaces the AT&T binary
# executable. The syntax is now the following:
#
#	idinstall -a <driver> [-s <suffix>] [-o <suffix>] 
# or
#	idinstall -d <driver> [-s <suffix>]
#
# where
#	-a	installs the specified <driver>
#	-d	removes the specified <driver>
#	-k  keep driver files (do not remove from current directory)
#	-s <suffix> specifies the new system name suffix
#	-o <suffix> specifies the system name suffix
#		that will be used as the base for building 
#		the new system.
#
# Options -a and -d cannot be specified at the same time.
# Options -k and -d cannot be specified at the same time.
#
# Option -s is optional. If not specified, the default argument
# is 'local'. If specified with -a, the driver will be added to 
# designated configuration files. If specified with -d, the driver 
# will be removed from the existing configuration files. 'std'
# cannot be specified as an argument.
#
# Option -o has no meaning if -d is specified. An error is returned.
#
# Option -o is optional when -a and -s is specified. If not 
# specified, the default argument is 'local'. If sysgen.rxxxx_sys
# does not exist, then it is created using the sysgen config file
# of the currently running system. If -o is specified, then 
# sysgen.rxxxx_<suffix> and kernel.rxxxx_<suffix> must
# exist in /usr/src/uts/mips/master.d, even if it is 'sys'.
#
# For example, 'idinstall -a ipx' installs the ipx driver into
# the config files for unix.rxxxx_sys since -s is not specified.
# If needed, these config files are created from the config files 
# of the currently running system since -o is not specified.
#
# Likewise, 'idinstall -a ipx -s pnw' installs the ipx
# driver in the configuration for new system /unix.rxxxx_pnw
# where rxxxx is the appropriate model number (e.g. r2400).
# The configuration for /unix.rxxxx_pnw will be based upon the
# configuration of the currently running system.

#	MODIFICATION HISTORY
#	CChan		11/01/90	Initial Coding
#	TDhar		12/07/90	1) Trap Interrupts
#					2) Give the suffix when calling any
#					   other id tools.
#					3) Check if the specified vector or
#					   base address are in use or not.
#	TDhar		12/10/90	4) Check if the specified major # is in
#					   use or not
#	TDhar		12/21/90	For 6000 series machine boot area is
#					/usr/src/uts/mips/bootarea_ii.
#	TDhar		01/18/91	A master file with blank lines at the
#					begining will not cause any problem
#					any more.
#	TDhar		04/10/91	Change the default suffix to local

# Setup some global variables
cdir=`pwd`
root=/
masterd=/usr/src/uts/mips/master.d
idbin=/etc/conf/bin

# Do a uname -t to find out if it is 6000 series machine or not. If so
# bootarea will be /usr/src/uts/mips/bootarea_ii
model=`uname -t`
case "$model"
in
	RC62*) 	 suffix=local
		 boot=/usr/src/uts/mips/bootarea_ii;;
	m2000-6|m2000-8) suffix=ijc_local
	  	boot=/usr/src/uts/mips/bootarea_i;;
	*) 	 suffix=local
		 boot=/usr/src/uts/mips/bootarea_i;;
esac

# Make sure there is at least one argument
if [ $# -eq 0 ]
then
	echo 'Either -a or -d must be specified.'
	echo 'USAGE: idinstall -a -d [-s <suffix>] [-o <old_suffix>]'
	exit 1
fi

# Setup default values
aflg=0
dflg=0
kflg=0
sflg=0
oflg=0
newsys=$suffix
oldsys=$suffix

# Parse the command line
while getopts a:d:ks:o: option
do
	case "$option"
	in
		a) aflg=1
		   driver=$OPTARG;;
		d) dflg=1
		   driver=$OPTARG;;
        k) kflg=1;;
		s) sflg=1
		   newsys=$OPTARG;;
		o) oflg=1
		   oldsys=$OPTARG;;
		*) echo 'USAGE: idinstall -a -d -s <suffix> -o <old_sufix>\n'
		   exit 1;;
	esac
done

# Check for illegal option combinations
if [ $aflg -eq 0 -a $dflg -eq 0 ]
then
	echo '$0: Either -a or -d must be specified'
	exit 1
fi

if [ $aflg -eq 1 -a $dflg -eq 1 ]
then
	echo '$0: Cannot use the -a and -d options at the same time'
	exit 1
fi

if [ $kflg -eq 1 -a $dflg -eq 1 ]
then
	echo '$0: Cannot use the -k and -d options at the same time'
	exit 1
fi

if [ $oflg -eq 1 -a $dflg -eq 1 ]
then
	echo '$0: Cannot use the -o and -d options at the same time'
	exit 1
fi

# Check for invalid option arguments
if [ $newsys = std -o $newsys = 'ijc' ]
then
	echo "$0: Cannot specify 'std' or 'ijc' for -s"
	exit 1
fi

trap '' 1 2 3 9 15

# Build the corresponding kernel and sysgen filenames for the
# 'old' system.
stdunix=`$idbin/idfindsys -u`
oldunix=`echo $stdunix | sed "s/_.*\$/_$oldsys/"`
oldsysgen=`echo $oldunix | sed 's/unix/sysgen/'`
oldkernel=`echo $oldunix | sed 's/unix/kernel/'`

if [ $oflg -eq 1 ]
then
	# If -o specified, but config file not found, return an error.
	if [ ! -f $masterd/$oldsysen ]
	then
		echo "Config file $oldsysgen for -o system not found"
		exit 1
	fi
else
	# If -o not specified, then create the *_sys config files (if 
	# needed) from the config files of the currently running system.
	$idbin/idmakesys -s $newsys
	if [ $? -ne 0 ]
	then
		echo "idinstall aborted. Could not find appropriate"
		echo "configuration files. Rerun with -o option"
		exit 1
	fi
fi

# Build the new system filenames. If -s specified, then $newsys
# is the -s argument, else it is 'sys'.
newunix=`echo $oldunix | sed "s/_.*\$/_$newsys/"`
newsysgen=`echo $oldsysgen | sed "s/_.*\$/_$newsys/"`
newkernel=`echo $oldkernel | sed "s/_.*\$/_$newsys/"`

# begin -d processing
# -d specified. Remove the driver 
if [ $dflg -eq 1 ] 
then
	# If -d, then target sysgen file must exist
	if [ ! -f $masterd/$newsysgen ]
	then
		echo "$0: Target system $newunix for idinstall -d not found"
		exit 1
	fi

	# Find the io vector in the sysgen file and remove it if needed.
	# Unless installed via idinstall -a, it will not be found.
	grep "++$driver++" $masterd/$newsysgen 1>/dev/null 2>/dev/null
	if [ $? -eq 0 ]
	then
		# The io vector comment line should be of the form
		# * Prime++$driver++io vector, :n
		# where n is the number of lines to delete (including
		# the comment line).
		num=`grep "++$driver++" $masterd/$newsysgen | cut -d':' -f2`
# Cannot insert <tab>'s for prettiness here
vi $masterd/$newsysgen << viscript > /dev/null 2>&1

/++$driver++
${num}dd:x!
viscript
	fi

	# Find the driver in the sysgen file and remove it.
	# Search for driver installed via idinstall -a
	grep "==$driver==" $masterd/$newsysgen 1>/dev/null 2>/dev/null
	if [ $? -eq 0 ]
	then
# Cannot insert <tab>'s for prettiness here
vi $masterd/$newsysgen << viscript > /dev/null

/==$driver==
2dd:x!
viscript
	fi

	# Search for driver installed via manual edit
	grep "^INCLUDE:[ 	]$driver[ 	]*$" $masterd/$newsysgen 1>/dev/null 2>/dev/null
	if [ $? -eq 0 ]
	then
		line=`grep -n "INCLUDE:[ 	]$driver[ 	]*$" $masterd/$newsysgen | cut -d':' -f1`
# Cannot insert <tab>'s for prettiness here
vi $masterd/$newsysgen <<viscript > /dev/null

${line}Gdd:x!
viscript
	fi

	# Remove <driver> space.c file if needed
	if [ -f $masterd/$driver ]
	then 
		rm $masterd/$driver 
	fi

	# Remove <driver>.o if needed
	if [ -f $boot/$driver.o ]
	then
		rm $boot/$driver.o
	fi

	# Find the driver in the Makefile and remove it.
	# Hopefully, the driver is on its own separate line, but
	# we cannot assume this.
	# Create a backup copy of the Makefile
	cp $masterd/Makefile $masterd/Makefile.bu
	grep "[ 	]$driver[ 	]" $masterd/Makefile 1>/dev/null 2>/dev/null
	if [ $? -eq 0 ]
	then
		numdrivers=`grep "[ 	]$driver[ 	]" $masterd/Makefile | sed 's/\\\//' | wc -w`
		if [ $numdrivers -ne 0 ]
		then
			if [ $numdrivers -eq 1 ]
			then
				# Driver is on its own line. Remove entire line.
			ed $masterd/Makefile << !! > /dev/null 2>&1
			/[ 	]$driver[ 	]/d
			w
			q
!!
			else
			# Line has other drivers on it. Just remove driver.
				xx=`grep "^\	$driver[ 	]" $masterd/Makefile`
				if [ $? = 0 ]
				then
					ed $masterd/Makefile << !! > /dev/null 2>&1
					/[	]$driver[ 	]/s//	/
					w
					q
!!
				else
					ed $masterd/Makefile << !! > /dev/null 2>&1
					/[ 	]$driver[ 	]/s// /
					w
					q
!!
				fi
			fi
		fi
	fi
fi

# end -d processing

# begin -a processing
# -a specified. Install a new driver
# The specified driver is installed from the current directory.
if [ $aflg -eq 1 ]
then
	# Check to see that all the needed files are in the current
	# directory. The Node file is only needed for real drivers.
	if [ ! -f Master -a ! -f $driver ]
	then
		echo "Either Master or $driver must exist"
		echo "idinstall aborted"
		exit 1
	fi

	if [ ! -f Driver.o -a ! -f $driver.o ]
	then
		echo "Either Driver.o or $driver.o must exist"
		echo "idinstall aborted"
		exit 1
	fi

	# Create the new kernel and sysgen config files if needed
	# Remember, we cannot copy a file to itself
	if [ $newunix != $oldunix ]
	then
		cp $masterd/$oldsysgen $masterd/$newsysgen
		cp $masterd/$oldkernel $masterd/$newkernel
	fi
#Do some testing before changing system configuration
	type=`/etc/conf/bin/idfindsys -b`
	if [ $type = 'AT' ]
	then
		type='ATBUS:'
	else
		type='VECTOR:'
	fi
	vnum=0
	if [ -f Vector ]
	then
		grep -v "^\*"  Vector|sed -e "/^[ 	]*$/d" > vect$$
		vnum=`cat vect$$|wc -l`
		if [ $vnum != 0 ]
		then
			count=0
			while [ $count != $vnum ]
			do
				chk_str="-s $newsys"
				vector=0
				base=0
				count=`expr $count + 1`
				line=`sed -n ${count}p vect$$`
				bus=`echo $line|cut -d' ' -f1`
				line=`echo $line|sed -e s/${bus}\ //`
				echo $line > /tmp/id$$
				echo "export vector base" >> /tmp/id$$
				chmod 755 /tmp/id$$
				. /tmp/id$$
				rm /tmp/id$$
				if [ $bus != $type ]
				then
					echo "$0: Wrong Directive in Vector file"
					exit 1

				fi
				if [ $type = 'ATBUS:' -a $vector != 0 ]
				then
					echo "$0: vector=$vector is not expected in Vector file"
					exit 1
				fi
				if [ $vector != 0 ]
				then 
		    			chk_str="${chk_str} -v $vector"
				fi
				if [ $base != 0 ]
				then
		    			chk_str="${chk_str} -b $base"
				fi
				if [ $vector != 0 -o $base != 0 ]
				then
					/etc/conf/bin/idcheck ${chk_str}
					if [ $? = 100 ]
					then
						echo "$0: Error in Vector file"
						exit 1
					fi
				fi

			done
		fi
	fi			#if Vector
#Check for duplicate Major device number
	lne=0
	if [ -f ./Master ]
	then
		lne=`grep -v "^\*" ./Master|sed -e "/^[ 	]*$/d"|sed -n 1p`
	else
		lne=`grep -v "^\*" ./$driver|sed -e "/^[ 	]*$/d"|sed -n 1p`
	fi
	lne=${lne:=0}
	if [ "$lne" != 0 ]
	then
		set $lne
		if [ ! -z $3 -a $3 != '-' ]
		then
			mlist=`echo $3|sed "s,\,,\ ,g"`
			for k in $mlist
			do
				/etc/conf/bin/idcheckmajor -m $k
				if [ $? != 0 ]
				then
					echo "$0: Error in Master file"
					exit 1
				fi
			done
		fi
	fi
	# Copy either Master or <driver> into master.d
	if [ -f Master ]
	then
		cp Master $masterd/$driver
	else
		cp $driver $masterd
	fi

	# Copy Driver.o or <driver>.o into bootarea_i
	if [ -f Driver.o ]
	then
		cp Driver.o $boot/$driver.o
	else
		cp $driver.o $boot
	fi

	# Remove files if -k not specified
	if [ $kflg -eq 0 ]
	then
		rm $driver 2>/dev/null
		rm Master 2>/dev/null
		rm $driver.o 2>/dev/null
		rm Driver.o 2>/dev/null
	fi

	# Add INCLUDE definition to sysgen config file, if needed.
	# Add identifying comment. It is needed by -d.
	grep "INCLUDE:[ 	]$driver[ 	]*$" $masterd/$newsysgen 1>/dev/null 2>/dev/null
	if [ $? -eq 1 ]	
	then
		echo "* Prime==$driver==driver" >> $masterd/$newsysgen
		echo "INCLUDE: $driver " >> $masterd/$newsysgen
	fi

	# Add driver name to Makefile after the line MASTERS = 
	# Driver names are added one to a line.
	# Create backup copy of Makefile
	cp $masterd/Makefile $masterd/Makefile.bu
	grep "[ 	]$driver[ 	]" $masterd/Makefile 1>/dev/null 2>/dev/null
	if [ $? -eq 1 ]
	then
# Cannot insert <tab>'s for prettiness here
vi $masterd/Makefile << viscript > /dev/null 2>&1

/MASTERS =
o	$driver \\:x!
viscript
	fi

	# If the Vector file exists then insert it into the sysgen
	# config file.
	if [ $vnum != 0 ]
	then
		vnum=`expr ${vnum} + 1`
		echo "*Prime++$driver++io_vector:$vnum" > vct$$
		cat vect$$ >> vct$$
		rm vect$$
# Cannot insert <tab>'s for prettiness here
vi $masterd/$newsysgen << viscript > /dev/null

/^${type}
:r vct$$
:x!
viscript
	rm vct$$

	fi

	# Now make the node (if needed). Execute the Node file which 
	# contains the 'mknod' command that must be executed.
	if [ -f Node ]
	then
		chmod +r Node
		sh ./Node 2>/dev/null
	fi
fi
# end -a processing
exit 0
