#! /bin/sh

# @(#)install_ipc	195.3 - 90/10/03

########################################################################
#
# install_ipc -- take the SunIPC patches and install them on the system
#
# This script install new kernel driver files into the system.  This
# script is entirely self contained.  As long as the kernel driver
# files are present in the same directory, everything will work fine.
#
# The script attempts to figure out which architectures are eligible
# for installation.  It asks the user to pick one or more architectures
# from this set for installation.  It then copies in the driver files and
# modifies the kernel "conf/files" file to reflect these new driver files.
#
# The SunIPC driver files are a set of three files.  They are pc.o,
# pc_conf.o, and if_me.o on the SunIPC 1.2 release tape.  We rename
# the files (and change the database of files associated with the "pc"
# driver) so that you can run the SunIPC install script either before
# or after you run this patch script.  The only thing you have to
# do is re-make your kernel if you run this script *after* the SunIPC
# installation.  If you run this script first then you only have to
# run the normal SunIPC installation.
#
# The new driver files have names like "sun4-4_1-pc.o", where the
# right architecture is substituted for sun4, and 4_1 is the SunOS
# release number.
#
########################################################################


ARCH=`arch -k`
SUNOS=4_1_1
ARCHLIST="sun3 sun3x sun4"
FILES="pc.o pc_conf.o if_me.o"

ALT_SUNOS=`echo ${SUNOS} | sed -e "s/_/./g"`

#
# there are two things we must to to install these patches:
# the first thing is to copy the new .o files into the appropriate
# OBJ directory.  The second thing is to modify the "files" file
# to reflect these new .o files.
#



########################################################################
#
# boiler plate code
#
########################################################################

#
# the only place we read from stdin
#
stdin_log () {
    read $1
}

#
# return "yes" or "no" into shell variable named $1.  $2 is the user prompt.
#
get_yesno () {
    yesno=""
    while [ ! "$yesno" ]
    do
        echo ""
        echo -n "$2 [yes|no]? "
        stdin_log yesno
        case "$yesno" in
        [yY]*)  yesno=yes ;;
        [nN]*)  yesno=no ;;
        *)      echo "" ; echo 'Please enter "yes" or "no".' ; yesno="" ;;
        esac
    done
    eval $1="$yesno"
}

#
# return "yes" or "no" into shell variable named $1.  $2 is the user prompt.
# $3 is the default answer to use
#
get_yesno_def () {
    yesno=""
    while [ ! "$yesno" ]
    do
        echo ""
        echo -n "$2 [yes|no]($3)? "
        stdin_log yesno
        case "$yesno" in
        [yY]*)  yesno=yes ;;
        [nN]*)  yesno=no ;;
	"")	yesno="$3" ;;
        *)      echo "" ; echo 'Please enter "Yes" or "No".' ; yesno="" ;;
        esac
    done
    eval $1="$yesno"
}
 

#
# give the user a chance to bail out (no arguments)
#
check_continue () {
    if [ ! "$DEFAULT" ]
    then
	get_yesno_def continue "Do you want to continue" yes
	if [ "$continue" = no ]
	then
	    echo ""
	    echo "$SH_NAME : Terminating"
	    cleanup 1
	fi
    fi
}


#
# generic user prompt routine with no default
# $1 is the variable to set
# $2 is the prompt
#
get_ans () {
    echo ""
    echo -n "$2: "
    stdin_log new_ans
    eval $1="$new_ans"
}

#
# generic user prompt routine with default
# $1 is the variable to set
# $2 is the prompt
# $3 is the default answer
#
get_ans_def() {
    echo ""
    echo -n "$2 [$3]: "
    stdin_log new_ans
    if [ "$new_ans" = "" ]
    then
	new_ans="$3"
    fi
    eval $1="$new_ans"
}

#
# provide a single script exit point -- clean up and go away
#
cleanup () {
    exit $1
}


#
# visually separate unrelated sections
#
newsection() {
    echo ""
    echo "--------------------------"
}

########################################################################
#
# begin the real code
#
########################################################################


#
# step 1: figure out which architectures are available
#

ok_arch=""
for a in ${ARCHLIST}
do
    ok=yes
    for file in ${FILES}
    do
	if [ ! -s ${a}-${SUNOS}-${file} ]
	then
	    ok=no
	fi
    done

    if [ "$ok" = yes ]
    then
	ok_arch="$ok_arch $a"
    fi
done

# update the archlist with the ones we found

if [ ! "$ok_arch" ]
then
    echo
    echo "Error: There are not a complete set of patch files available."
    cleanup 1
fi
ARCHLIST="$ok_arch"


#
# now look to see which kernels are present
#

ok_arch=""
for a in ${ARCHLIST}
do
    os="/export/exec/kvm/${a}.sunos.${ALT_SUNOS}/sys/${a}/conf"
    if [ -d ${os} ]
    then
	ok_arch="$ok_arch $a"
    fi
done

if [ ! "$ok_arch" ]
then
    echo "Error: could not find any installed kernels that matched"
    echo "the available patches.  The following architectures were"
    echo "searched:"
    echo ""
    echo "       $ARCHLIST"
    echo ""
    echo "$0: aborting"
    cleanup 1
fi

ARCHLIST="$ok_arch"


#
# ask the user which one he is interested in
#

ok_arch=""
for a in $ARCHLIST
do
    get_yesno_def ans \
	"Do you want to install the SunIPC patches for $a machines" "yes"

    if [ "$ans" = "yes" ]
    then
	ok_arch="$ok_arch $a"
    fi
done

if [ ! "$ok_arch" ]
then
    echo ""
    echo "Error: no architectures selected"
    cleanup 1
fi

ARCHLIST="$ok_arch"

#
#  we're done with configuration questions.  start the install
#

echo ""
echo "---------------------"
echo ""
echo "Starting the installation.  You may safely ignore all lines that end"
echo 'in "...".  Anything else is an error.'

for a in $ARCHLIST
do
    # example path: /export/exec/kvm/sun4.sunos.4.1/sys/sun4

    prefix="/export/exec/kvm/$a.sunos.${ALT_SUNOS}/sys/$a"

    echo ""
    echo "Installing files for $a architecture..."
    echo ""

    #
    # first copy in the .o files
    #
    for f in $FILES
    do
	docopy=yes

	file="${a}-${SUNOS}-${f}"
	fullpath=${prefix}/OBJ/${file}
	if [ -f $fullpath ]
	then
	    get_yesno_def docopy "$fullpath already exists.  Overwrite it" yes

	    if [ "$docopy" = yes ]
	    then
		echo "removing ${fullpath}..."
		rm -f $fullpath
	    fi
	fi

	if [ "$docopy" = yes ]
	then
	    echo "adding $fullpath..."
	    cp $file $fullpath

	    if [ $? -ne 0 ]
	    then
		get_yesno_def answer \
		    "Error: could not copy in $fullpath.  Abort" no

		if [ "$answer" = yes ]
		then
		    cleanup 1
		fi
	    fi
	fi
    done

    #
    # now modify the "files" file
    #
    fullpath="${prefix}/conf/files"

    mkbak=yes
    if [ -s "${fullpath}.orig" ]
    then
	get_yesno_def mkbak \
	    "Backup file ${fullpath}.orig exists.  Overwrite" no

	if [ "$mkbak" = yes ]
	then
	    echo "removing ${fullpath}.orig..."
	    rm -f "${fullpath}.orig"
	fi
    fi

    if [ "$mkbak" = yes ]
    then
	# make a backup file
	echo "saving ${fullpath}.orig..."
	mv "${fullpath}" "${fullpath}.orig"
    fi

    echo "modifying ${fullpath}..."

    # delete the old
    sed -e "/sunif\/.*if_me\.c/d" -e "/sundev\/pc\.c/d" \
        -e "/sundev\/sun.*pc\.c/d" \
	-e "/sundev\/.*pc_conf\.c/d" "${fullpath}.orig" > "${fullpath}"

    # add the new
    echo "sunif/${a}-${SUNOS}-if_me.c optional pc INET device-driver" \
	>> ${fullpath}
    echo "sundev/${a}-${SUNOS}-pc.c optional pc device-driver" \
	>> ${fullpath}
    echo "sundev/${a}-${SUNOS}-pc_conf.c optional pc device-driver" \
	>> ${fullpath}
done

cleanup 0

