#! /bin/csh -f
########################################################################
#
#       Copyright 1993 by the Massachusetts Institute of Technology.
#       All rights reserved.
#
#       Developed by the Intelligent Engineering Systems Laboratory
#       M.I.T., Cambridge, Massachusetts.
#
#       THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS
#       OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not
#       limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF
#       MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
#       THAT THE USE OF THE LISCENCED SOFTWARE OR DOCUMENTATION WILL NOT
#       INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER
#       RIGHTS.
#
#       The name of Massachusetts Institute of Technology or M.I.T. may
#       NOT be used in advertising or publicity pertaining to distribution
#       of the software. Title to copyright in this software and any
#       associated documentation shall at all times remain with M.I.T.,
#       and USER agrees to preserve the same.
#
#       Permission to use, copy, modify, and distribute this material
#       for any purpose and without fee is hereby granted, provided that
#       the above copyright notice and this permission notice appear in
#       all copies.
#
###########################################################################
#			Author Info:					  #
###########################################################################
# Jim Culbert                                                             #
# Research Engineer							  #
# M.I.T Intelligent Engineering Systems Laboratory                        #
# Room 1-272                                                              #
# Cambridge, Ma. 02139.                                                   #
#									  #
# Phone (617) 253-7134                                                    #
# e-mail: culbert@iesl.mit.edu                                            #
###########################################################################
#			Program Info:					  #
###########################################################################
# This script installs the multicast extensions released by Xerox PARC.	  #
# It relies heavily on their directory structuring. If they change	  #
# the release structure this install will need to be modified.		  #
# 									  #
# The Script figures out which kernel release you are running and	  #
# installs the appropriate files. It then builds a config file		  #
# runs config, makes the kernel and optionally installs it for you.	  #
#									  #
# Have Fun.								  #
###########################################################################
# A number of "improvements", minor fixes and addition of RSVP made in    #
# August, 1994 by Steve Casner, USC/ISI, casner@isi.edu.		  #
# System directory mirror feature added in December, 1994 by Paul Stewart,#
# RPI, stewart@rpi.edu, with UI modifications by Steve Casner.            #
# "Uninstall" feature added in February, 1995 by Steve Casner.            #
# Check for "upgrade" subdirs, optional selection of BPF modules, choice  #
# of RSRR and/or SNMP mrouted versions, installation of patches for all   #
# available architectures and optional looping to build kernels for each, #
# option to add multiple tunnels to mrouted.conf, and redirection of      #
# patch output to log file added May 1995 by Steve Casner.                #
###########################################################################

set TSTAMP = `date +%T`
set MV = "mv"
set CP = "cp -p"
set WHOAMI = `whoami`

# Offer the option of uninstalling an old set of patches, presumably
# as a precursor to running again to install a new set.

echo "Do you wish to UNinstall patches from an old mcast release rather than"
echo -n "install a new one (then run again to do the new install)? (y/n) [n]: "
set resp = $<
if ( "$resp" == "y" ) then
    set UNINSTALL = 1
    set p = "unp"
    set P = "Unp"
else
    set UNINSTALL = 0
    set p = "p"
    set P = "P"
endif

# Must run as root to install binaries; check if user wants do do only
# the kernel build if not root.

if ( $WHOAMI != "root" && $UNINSTALL == 0 ) then
    echo "Must be root to install binaries."
    echo -n "Do you wish to just build kernel and not install? (y/n) [y]: "
    set resp = $<
    if ( "$resp" == "n" ) then
	echo "Aborting install..."
	goto ABORT
    endif
endif

# Must have the patch program to install patches. Do not run
# unless you have a patch program!!

if ( -x "/usr/local/bin/patch" ) then
    set PATCH_PROG = /usr/local/bin/patch
else if ( -x "/usr/bin/patch" ) then
    set PATCH_PROG = /usr/bin/patch
else
    echo -n Enter full path for \"patch\" program:" "
    set resp = $<
    if ( -x "$resp" ) then
	set PATCH_PROG = $resp
    else
	echo "Unable to locate patch program. ABORT."
	goto ABORT
    endif
endif

#####################################################################
# Locate the directory where the extensions have been untarred.
#####################################################################

set MCAST_DIR = `pwd`
if ( $UNINSTALL == 1 ) then
    echo -n "Directory to find old Multicast extensions [$MCAST_DIR]: "
else
    echo -n "Directory to find Multicast extensions [$MCAST_DIR]: "
endif
set resp = $<
if ( "$resp" != "" ) set MCAST_DIR = $resp
if ( ! -d $MCAST_DIR ) then
    echo "Could not locate multicast extension directory $MCAST_DIR"
    echo ABORT
    goto ABORT
endif

pushd $MCAST_DIR >&! /dev/null
set nonomatch
set dirlist = *.upgrade
set verlist
while ( $#dirlist != 0 )
    set current = $dirlist[1]
    if ( ! -d $current ) then
	shift dirlist
	continue
    endif
    set verlist = ($verlist $current:r)
    shift dirlist
end
unset nonomatch
if ( "$verlist" != "" && $UNINSTALL == 0 ) then
    echo -n "Is this to be a full installation (not an upgrade)? (y/n) [y]: "
    set resp = $<
    if ( "$resp" == "n" ) then
	echo "Upgrades from these versions available: $verlist"
	while ( $#verlist != 0 )
	    set current = $verlist[1]
	    echo -n "Upgrade from multicast release $current? (y/n) [y]: "
	    set resp = $<
	    if ( "$resp" != "n" ) then
		set MCAST_DIR = $MCAST_DIR/$current.upgrade
		break
	    endif
	    shift verlist
	end
	if ( $#verlist == 0 ) then
	    echo "(No upgrade selected, assuming full installation)"
	endif
    endif
endif
popd >&! /dev/null

#####################################################################
# Locate the directory tree where the patches are to be installed.
#####################################################################

if ( $WHOAMI == "root" ) then
    set INSTALL_ROOT = /usr/sys
else
    set INSTALL_ROOT = ""
endif
set INSTALL_MIRROR = ""

echo -n "Do you wish to mirror system directory (.../sys) before ${p}atching?"
echo -n " (y/n) [n]: "
set resp = $<
if ( "$resp" == "y" ) then
    set INSTALL_MIRROR = /usr/sys
    echo -n "System directory to be mirrored [$INSTALL_MIRROR]: "
    set resp = $<
    if ( "$resp" != "" ) then
	set INSTALL_MIRROR = $resp
	set resp = `echo $resp | colrm 2`
	if ( "$resp" != "/" ) then
	    set INSTALL_MIRROR = "`pwd`/$INSTALL_MIRROR"
	    echo "(Using full pathname $INSTALL_MIRROR)"
	endif
    endif
    set INSTALL_ROOT = "$MCAST_DIR/`uname -m`-`uname -r`"
    if ( ! -d "$INSTALL_MIRROR" ) then
	echo "Sorry, $INSTALL_MIRROR doesn't exist."
	echo ABORT
	goto ABORT
    endif
endif

if ( "$INSTALL_ROOT" != "" ) then
    if ( "$INSTALL_MIRROR" == "" ) then
	if ( $UNINSTALL == 1 ) then
	    echo -n "System directory under which to remove patches"
	else
	    echo -n "System directory under which to install patches"
	endif
	echo -n " [$INSTALL_ROOT]: "
    else
	if ( $UNINSTALL == 1 ) then
	    echo -n "New directory for files with patches removed"
	    echo " (mirrored from $INSTALL_MIRROR)"
	else
	    echo -n "New directory to install patches into (mirrored from"
	    echo " $INSTALL_MIRROR)"
	endif
	echo -n " [$INSTALL_ROOT]: "
    endif
    set resp = $<
    if ( "$resp" != "" ) set INSTALL_ROOT = $resp
else
    while ( "$INSTALL_ROOT" == "" )
	if ( $UNINSTALL == 1 ) then
	  echo -n "System directory (.../sys) under which to remove patches: "
	else
	  echo -n "System directory (.../sys) under which to install patches: "
	endif
	set INSTALL_ROOT = $<
	if ( "$INSTALL_ROOT" == "" ) then
	    echo "Must specify system directory."
	endif
    end
endif
set resp = `echo $INSTALL_ROOT | colrm 2`
if ( "$resp" != "/" ) then
    set INSTALL_ROOT = "`pwd`/$INSTALL_ROOT"
    echo "(Using full pathname $INSTALL_ROOT)"
endif

if ( "$INSTALL_MIRROR" != "" ) then
    if ( -e $INSTALL_ROOT ) then
	echo -n "Is it okay to remove the old $INSTALL_ROOT directory?"
	echo -n " (y/n) [y]: "
	set resp = $<
	if ( "$resp" == "n" ) then
	    echo "Aborting..."
	    goto ABORT
	else
	    echo "Removing old directory..."
	    rm -rf $INSTALL_ROOT
	    if ( -e $INSTALL_ROOT ) then
		echo "Remove unsuccessful.  Aborting..."
		goto ABORT
	    endif
	endif
    endif
    mkdir -p $INSTALL_ROOT
endif

if ( ! -d $INSTALL_ROOT || ! -w $INSTALL_ROOT ) then
    echo "System directory $INSTALL_ROOT not writable."
    echo ABORT
    goto ABORT
endif

set LOG = $INSTALL_ROOT/patchlog.$TSTAMP
if ( $UNINSTALL == 0 ) then
 echo "Log of installation of IP multicast kernel extensions executed on" > $LOG
else
 echo "Log of removal of IP multicast kernel extensions executed on" > $LOG
endif
echo `date` >> $LOG
echo "" >> $LOG
echo "Multicast release in $MCAST_DIR" >> $LOG
echo "Installed into $INSTALL_ROOT" >> $LOG
if ( "$INSTALL_MIRROR" != "" ) then
    echo "Mirrored from $INSTALL_MIRROR" >> $LOG
endif

#####################################################################
# Get os release information.
#####################################################################

echo Looking for system release level information........

# 1) First grok output from uname
set OS_REL = `uname -r`

# 2) Compare this to information in conf.common. If different
#    then something is really funny. Warn the user and let her
#    choose.

set WARN = 0
if ( $OS_REL != `cat /usr/sys/conf.common/RELEASE` ) set WARN = 1

# 3) The kernel is always the best place to check!! Look to see if
#    the groked string is found in the kernel somewhere. It should be.
#    If not, then warn and let the user decide.

set tmp = `strings /vmunix | grep $OS_REL`
if ( "$tmp" == "" ) set WARN = 1

# If strangeness warn....

if ( $WARN == 1 ) then
    echo "WARNING: Discrepancy found in kernel release information."
    echo "Default release may be wrong."
endif

echo -n "Enter Kernel Release [$OS_REL]: "
set resp = $<
if ( "$resp" != "" ) set OS_REL = $resp
echo "Kernel release $OS_REL" >> $LOG

#####################################################################
# Find out if they want to be able to support mrouting.
#####################################################################
	
if ( $UNINSTALL == 0 ) then
    set MROUTING_FLAG = 0
    echo -n "Do you wish to support multicast routing? (y/n) [y]: "
    set resp = $<
    if ( "$resp" != "n" ) then
	set MROUTING_FLAG = 1
	echo "Including support for multicast routing" >> $LOG
    else
	echo "Not including support for multicast routing" >> $LOG
    endif

#####################################################################
# Find out if they want to be able to support RSVP.
#####################################################################
	
    set RSVP_FLAG = 0
    echo -n "Do you wish to support RSVP (resource reservation protocol)?"
    echo -n " (y/n) [y]: "
    set resp = $<
    if ( "$resp" != "n" ) then
	set RSVP_FLAG = 1
	echo "Including support for RSVP" >> $LOG
    else
	echo "Not including support for RSVP" >> $LOG
    endif
endif

#####################################################################
# Find out if they want to be able to support BPF.
#####################################################################
	
set BPF_FLAG = 0
if ( $UNINSTALL == 0 ) then
    echo -n "Have you already installed BPF in this kernel? (y/n) [n]: "
else
    echo -n "Was BPF included when the old patches were installed? (y/n) [n]: "
endif
set resp = $<
if ( "$resp" == "y" ) then
    set BPF_FLAG = 1
    echo "Using BPF versions of .diff and .o files" >> $LOG
else
    echo "Not using BPF versions of .diff and .o files" >> $LOG
endif

#####################################################################
# Get the kernel architecture.
#####################################################################

set karch = `arch -k`
echo "Machine architecture $karch" >> $LOG
echo "" >> $LOG

#####################################################################
# Last chance to chicken out. Show configuration, prompt then go!
#####################################################################

if ( $UNINSTALL == 0 ) then
	echo "Installing multicast extensions for $karch binaries."
endif
echo -n "Continue? (y/n) [y]: "
set resp = $<
if ( "$resp" == "n" ) then
    echo "Aborting..."
    goto ABORT
endif

#####################################################################
# Generate the release directory name. Current nomenclature is
# sys.sunos41x. Thus all we have to do is pick off the last digit
# of the release information and append. Pretty rickety code....
#####################################################################

# This is very "non-portable"....
set REL_LEVEL = $OS_REL:e
set OS_REL_DIR = sys.sunos41$REL_LEVEL

#####################################################################
# Ready to go. First push to the untarred directory.
#####################################################################

# Existance sanity checks.

pushd $MCAST_DIR >&! /dev/null

if ( ! -d $OS_REL_DIR ) then
    echo "Could not locate extension directory $MCAST_DIR/$OS_REL_DIR"
    echo ABORT
    goto ABORT
endif

cd $OS_REL_DIR

set KARCH_OBJ_DIR = $karch.OBJ
# Don't care for uninstall
if ( $UNINSTALL == 0 && ! -d $KARCH_OBJ_DIR ) then
    echo "Could not locate objects for kernel architecture $karch"
    echo ABORT
    goto ABORT
endif

# Ok if we're here, we can proceed to patch the files

echo "${P}atching files in directories under $INSTALL_ROOT node,"
echo "logfile $LOG ....."
echo ""

#
# Mirror the sys directory if selected.
# I don't think a full blown lndir is worth it.
#
if ( "$INSTALL_MIRROR" != "" ) then
    ln -s $INSTALL_MIRROR/* $INSTALL_ROOT
    if ( $status != 0 ) then
	echo "Problem during mirroring. ABORT"
	goto ABORT
    endif
endif

set dirlist = *
set unpatched = 0
set nonexc = 0
set nonexh = 0
set nonexo = 0
set includes = 0

#####################################################################
# GO!
#	while( there are more directories )
#		if its a directory we're interested in then
#			goto that directory
#			for all the files in that directory
#				Locate corresponding system file
#				execute appropriate patch/cp manuver
#			go back to release directory
#
#####################################################################

# BEGIN DIRECTORY INSTALL LOOP

while ( $#dirlist != 0 )

    set current = $dirlist[1]

# If the file is not a directory, then we do not do anything with it

    if ( ! -d $current ) then
	shift dirlist
	continue
    endif

#######################################################################
# If the file ends in .OBJ, then it is an object file directory. There
# may be more than one sunxx.OBJ subdir for multiple architectures,
# but we'll do them all in case multiple kernels are needed so long as
# the corresponding sunxx/OBJ directory exists.
# If mirroring, make sure the directory is real and not a symbolic link.
# If the directory does not exist and it is not for an architecture
# other than the selected one, complain and create an empty directory.
# Finally, push to the directory and begin install loop.
#######################################################################

    if ( $current:e == "OBJ" ) then
	if ( $UNINSTALL == 1 ) then
	    shift dirlist
	    continue
	endif
	set current = $current:r
	if ( { test -h $INSTALL_ROOT/$current } ) then
	    if ( "$INSTALL_MIRROR" != "" ) then
		set SYMLINK = $INSTALL_MIRROR/$current
	    else
		set SYMLINK = \
		    `/bin/ls -l $INSTALL_ROOT/$current | awk '{print $NF}'` 
	    endif
	    rm $INSTALL_ROOT/$current
	    mkdir $INSTALL_ROOT/$current
	    if ( "`ls $SYMLINK | head -1`" != "") then
		ln -s $SYMLINK/* $INSTALL_ROOT/$current
		if ( -e $INSTALL_ROOT/$current/machine ) then
		    rm $INSTALL_ROOT/$current/machine
		    ln -s . $INSTALL_ROOT/$current/machine
		endif
	    endif
	endif
	set current = $current/OBJ
    endif
    if ( { test -h $INSTALL_ROOT/$current } ) then
	if ( "$INSTALL_MIRROR" != "" ) then
	    set SYMLINK = $INSTALL_MIRROR/$current
	else
	    set SYMLINK = \
		`/bin/ls -l $INSTALL_ROOT/$current | awk '{print $NF}'` 
	endif
	rm $INSTALL_ROOT/$current
	mkdir $INSTALL_ROOT/$current
	if ( "`ls $SYMLINK | head -1`" != "") then
	    ln -s $SYMLINK/* $INSTALL_ROOT/$current
	    if ( -e $INSTALL_ROOT/$current/machine ) then
		rm $INSTALL_ROOT/$current/machine
		ln -s . $INSTALL_ROOT/$current/machine
	    endif
	endif
    endif
    if ( ! -d $INSTALL_ROOT/$current ) then
	if ( $current:h == $karch || \
	     ! ( -d $current/conf || $current:t == "OBJ" ) ) then
	    echo "WARNING: Directory $INSTALL_ROOT/$current does not exist;" | \
		 tee -a $LOG
	    echo "Creating an empty one." | tee -a $LOG
	    mkdir $INSTALL_ROOT/$current
	else
	    shift dirlist
	    continue
	endif
    endif
    pushd $dirlist[1] >&! /dev/null

#######################################################################
# The following is really anal. Prints out a pretty banner for each 
# directory subtree that is being installed. Prints out a line of 
# hash marks as a delimiter, a message and calculates where the
# hash mark should be placed at the end of the line.
#######################################################################

    set dlim = "##########################################################"
    if ( $UNINSTALL == 0 ) then
	echo "Installing files in $current"
	set mess = "#        Installing files in $current"
    else
	echo "Uninstalling files in $current"
	set mess = "#        Uninstalling files in $current"
    endif

    set mess_len = `expr length "$mess"`
    set dlim_len = `expr length $dlim`

    @ dlim_len -= $mess_len
    @ dlim_len--

    echo $dlim >> $LOG
    echo -n "$mess" >> $LOG
    repeat $dlim_len echo -n " " >> $LOG
    echo "#" >> $LOG

    echo $dlim >> $LOG


# BEGIN FILE INSTALL LOOP

    set nonomatch
    set filelist = *
    set filelist2 = */*
    if ( "$filelist2" != "*/*") then
	set filelist = ( $filelist $filelist2 )
    endif
    unset nonomatch
    if ( "$filelist" != "*") then
	foreach file ( $filelist )

#######################################################################
#
# For (second level) directories, just make them real if mirroring.
#
# For files, switch on the file ending. Possible cases are:
#
#	Ending		     Action
#	--------------------------------
#	.diff		Apply diff patch
#
#	.bpf.diff	Apply in place of .diff patch if BPF is requested
#
#	.c .o .h	install new source or object.
#
#	.o.rsvp		use in place of .o if RSVP is requested
#
#	.o.bpf		use in place of .o if BPF is requested
#
#	default		complain and do nothing
#
#######################################################################

	    if ( -d $file ) then
		if ( { test -h $INSTALL_ROOT/$current/$file } ) then
		    if ( "$INSTALL_MIRROR" != "" ) then
			set SYMLINK = $INSTALL_MIRROR/$current/$file
		    else
			set SYMLINK = `/bin/ls -l $INSTALL_ROOT/$current/$file | awk '{print $NF}'` 
		    endif
		    rm $INSTALL_ROOT/$current/$file
		    mkdir $INSTALL_ROOT/$current/$file
		    if ( "`ls $SYMLINK | head -1`" != "") then
			ln -s $SYMLINK/* $INSTALL_ROOT/$current/$file
		    endif
		endif
		continue
	    endif

	    set filef = $file

	    if ( $UNINSTALL == 1 && $file:e != "diff") continue

	    switch ( $file:e ) 

		case "diff":
		    set filer = $file:r
		    if ( $filer:e == "bpf" ) then
			set filer = $filer:r
			if ( $BPF_FLAG == 0 ) then
			    echo "Not using" `pwd`/$file >> $LOG
			    echo "" >> $LOG
			    breaksw
			endif
		    else
			if ( $BPF_FLAG == 1 && \
			     -e $filer.bpf.diff ) then
			    echo "Not using" `pwd`/$file >> $LOG
			    echo "" >> $LOG
			    breaksw
			endif
		    endif

		    if ( -e $INSTALL_ROOT/$current/$filer ) then

			echo "${P}atching" \
			     $INSTALL_ROOT/$current/$filer \
			     "with $file" >> $LOG
			# because root can't update across NFS
			if ( { test -h $INSTALL_ROOT/$current/$filer } ) then
			    mv $INSTALL_ROOT/$current/$filer \
				$INSTALL_ROOT/$current/$filer.$TSTAMP
			    $CP $INSTALL_ROOT/$current/$filer.$TSTAMP \
				$INSTALL_ROOT/$current/$filer
			    rm $INSTALL_ROOT/$current/$filer.$TSTAMP
			endif
			if ( $UNINSTALL == 1 ) then
			    $PATCH_PROG -R -N -b .orig.$TSTAMP\
			    $INSTALL_ROOT/$current/$filer \
			    $file >>& $LOG
			    set sstatus = $status
			else
			    $PATCH_PROG -N -b .orig.$TSTAMP\
			    $INSTALL_ROOT/$current/$filer \
			    $file >>& $LOG
			    set sstatus = $status
			endif					
			if ( $sstatus != 0 ) then
			    @ unpatched++
			    echo "******** This is bad." >> $LOG
			endif

			if ( $WHOAMI == "root" && $filer:e == "h" && \
				$UNINSTALL == 0 ) then
			    if ( $includes == 0) then
				echo "Installing files in /usr/include"
				@ includes++
			    endif
			    echo "Updating /usr/include/$current/$filer" >> $LOG
			    if ( -e /usr/include/$current/$filer ) then
				echo "Original moved to" \
				    /usr/include/$current/$filer.orig.$TSTAMP \
				    >> $LOG
				$MV /usr/include/$current/$filer \
				    /usr/include/$current/$filer.orig.$TSTAMP
			    endif
			    $CP $INSTALL_ROOT/$current/$filer \
				/usr/include/$current/$filer
			endif

			echo "" >> $LOG
		    else
			echo "WARNING: Attempt to ${p}atch" \
			     $INSTALL_ROOT/$current/$filer \
			     "failed." >> $LOG
			echo "File did not exist." >> $LOG
			echo "" >> $LOG
			if ( "$filer:e" == "c" ) then
			    @ nonexc++
			else if ( "$filer:e" == "h" ) then
			    # Ugly special case checks here:
			    if ( "$filer:r" == "if_bqe" ) breaksw
			    @ nonexh++
			else
			    @ nonexo++
			endif
		    endif
		    breaksw

		case "h":
		    if ( $WHOAMI == "root" ) then
			if ( $includes == 0) then
			    echo "Installing files in /usr/include"
			    @ includes++
			endif
			if ( -e /usr/include/$current/$file ) then
			    echo "Updating /usr/include/$current/$file"\
				 >> $LOG
			    echo "Original moved to" \
			     "/usr/include/$current/$file.orig.$TSTAMP"\
			     >> $LOG
			    $MV /usr/include/$current/$file \
				/usr/include/$current/$file.orig.$TSTAMP
			else
			    echo "Installing" \
				 /usr/include/$current/$file >> $LOG
			endif
			$CP $file /usr/include/$current/$file
		    endif
		    goto INSTALL

		case "rsvp":
		    if ( $RSVP_FLAG == 0 ) then
			echo "Not using" `pwd`/$file >> $LOG
			echo "" >> $LOG
			breaksw
		    else
			set file = $file:r
			goto INSTALL
		    endif

		case "bpf":
		    if ( $BPF_FLAG == 0 ) then
			echo "Not using" `pwd`/$file >> $LOG
			echo "" >> $LOG
			breaksw
		    else
			set file = $file:r
			goto INSTALL
		    endif

		case "o":
		    if ( ( $RSVP_FLAG == 1 && -e $file.rsvp ) || \
			 ( $BPF_FLAG == 1 && -e $file.bpf ) ) then
			echo "Not using" `pwd`/$file >> $LOG
			echo "" >> $LOG
			breaksw
		    endif
		case "c":
INSTALL:
		    if ( -e $INSTALL_ROOT/$current/$file ) then

			echo "Replacing" \
			     $INSTALL_ROOT/$current/$file >> $LOG
			echo "with" `pwd`/$filef >> $LOG
			echo "Backup made to" \
			     $INSTALL_ROOT/$current/$file.orig.$TSTAMP \
			     >> $LOG

			$MV $INSTALL_ROOT/$current/$file \
			    $INSTALL_ROOT/$current/$file.orig.$TSTAMP
		    else
			echo "Installing" `pwd`/$filef >> $LOG
			echo "as" $INSTALL_ROOT/$current/$file >> $LOG
		    endif

		    $CP $filef $INSTALL_ROOT/$current/$file
		    echo "" >> $LOG

		    breaksw

		default:

		    echo "Unrecognized extension on file $file" >> $LOG
		    echo "" >> $LOG
	    endsw

	end
    endif
# END FILE INSTALL LOOP

    popd >&! /dev/null

    shift dirlist

end
# END DIRECTORY INSTALL LOOP

popd >&! /dev/null

#####################################################################
# Report a summary of what went wrong, if anything.
#####################################################################

echo ""
echo "----- Kernel patch installation summary -----"
echo $dlim >> $LOG
echo "#                         SUMMARY                        #" >> $LOG
echo $dlim >> $LOG

if ( $nonexc > 0 ) then
    if ( $nonexc > 1 ) then
	echo "There were $nonexc nonexistent .c files not ${p}atched." | \
	     tee -a $LOG
    else
	echo "There was $nonexc nonexistent .c file not ${p}atched." | \
	     tee -a $LOG
    endif
    echo "(This is expected if you don't have a full source release.)" | \
	     tee -a $LOG
    echo "" | tee -a $LOG
endif
if ( $nonexh > 0 ) then
    if ( $nonexh > 1 ) then
	echo "There were $nonexh nonexistent .h files not ${p}atched." | \
	     tee -a $LOG
    else
	echo "There was $nonexh nonexistent .h file not ${p}atched." | \
	     tee -a $LOG
    endif
    echo "(This is unusual.)" | tee -a $LOG
    echo "" | tee -a $LOG
endif
if ( $nonexo > 0 ) then
    if ( $nonexo > 1 ) then
	echo "There were $nonexo nonexistent non-[ch] files not ${p}atched." | \
	     tee -a $LOG
    else
	echo "There was $nonexo nonexistent non-[ch] file not ${p}atched." | \
	     tee -a $LOG
    endif
    echo "(This is unusual.)" | tee -a $LOG
    echo "" | tee -a $LOG
endif
if ( $unpatched == 0 ) then
    echo "All existing source files were ${p}atched successfully." | tee -a $LOG
else
    if ( $UNINSTALL == 1 ) then
	echo -n "**** Patch removal failed for $unpatched of the existing" | \
	     tee -a $LOG
    else
	echo -n "**** Patches failed for $unpatched of the existing" | \
	     tee -a $LOG
    endif
    echo " source files." | tee -a $LOG
    echo "**** This is a bad sign.  Look for *.rej and in logfile"
    echo "**** $LOG to figure out why."
    echo "**** This is a bad sign." >> $LOG
    if ( $UNINSTALL == 0 ) then
	echo ""
	echo "Script will continue but will not build the kernel."
    endif
endif

echo ""
if ( $UNINSTALL == 1 ) then
    echo "Removal of multicast patches from source files completed."
    echo "" 
    echo "The multicast options remain in the old config file, but"
    echo "will be removed before the new options are added if you use"
    echo "the old config file as the template for the new install."
    echo "The old multicast .o files have not been touched, but will"
    echo "be replaced with new ones when the new install is done."
    goto DONE
endif

#####################################################################
# If we are supporting mrouting, find out if they want to set up this
# machine as an mrouter and if so install the mrouted.conf file.
#####################################################################

if ( $WHOAMI == "root" && $MROUTING_FLAG == 1 ) then

    echo "Do you wish to configure a multicast tunnel on this machine,"
    echo -n "that is, create a new mrouted.conf file? (y/n) [y]: "
    set resp = $<
    if ( "$resp" == "n" ) goto NO_MROUTED_CONF

    echo "Configuring mrouted......"

# Get IP address for local host.

#   set ypup = `ypwhich`
    set ypup = `ps ax | grep ypbind | grep -v grep`
    set tmp = `hostname`
    if ( $#ypup > 0 ) then
	set localip = `ypcat hosts | grep $tmp | awk '{print $1}'`
    else
	set localip = `cat /etc/hosts | grep $tmp | awk '{print $1}'`
    endif

    echo -n "/REPLACE/ c" > $INSTALL_ROOT/tmp.$TSTAMP

    set resp = "y"
    while ( "$resp" == "y" )
	echo -n "Enter local tunnel endpoint address [$localip]: "
	set resp = $<
	if ( "$resp" != "" ) set localip = $resp

	echo -n "Enter peer address for other end of tunnel: "
	set mcast_peer = $<

	set METRIC = 1
	echo -n "Enter tunnel metric for $localip <=> $mcast_peer tunnel "
	echo -n "[$METRIC]: "
	set resp = $< 
	if ( "$resp" != "" ) set METRIC = $resp

	set THRESH = 64
	echo -n "Enter tunnel threshold for $localip <=> $mcast_peer tunnel "
	echo -n "[$THRESH]: "
	set resp = $< 
	if ( "$resp" != "" ) set THRESH = $resp

	echo "\" >> $INSTALL_ROOT/tmp.$TSTAMP
	echo -n "tunnel	$localip	$mcast_peer	metric $METRIC	threshold $THRESH" >> $INSTALL_ROOT/tmp.$TSTAMP

	echo -n "Do you wish to add another (downstream) tunnel? (y/n) [n]: "
	set resp = $<
    end
    echo "" >> $INSTALL_ROOT/tmp.$TSTAMP

#####################################################################
# Use the example file in mrouted directory to build user's new
# configuration. Relies on there being one line in the example
# with the keyword "REPLACE" in it!!!!
#####################################################################

    if ( -e /etc/mrouted.conf ) then
	echo -n "Found a mrouted.conf in /etc. Moving to "
	echo mrouted.conf.orig.$TSTAMP
	$MV /etc/mrouted.conf /etc/mrouted.conf.orig.$TSTAMP
    endif

    if ( ! -e $MCAST_DIR/mrouted/mrouted.conf ) then
	echo -n "Could not find template mrouted.conf in"
	echo " $MCAST_DIR/mrouted."
	echo "Build it yourself. Sorry."
    else
	cat $MCAST_DIR/mrouted/mrouted.conf | \
	  sed -f $INSTALL_ROOT/tmp.$TSTAMP >! /etc/mrouted.conf

	# Sanity. If distribution changes example so that the
	# REPLACE key is missing, automatic installation of
	# mrouted.conf will not work.  Need to check for this
	# and warn the user if it happens.

	set tmp = `diff $MCAST_DIR/mrouted/mrouted.conf /etc/mrouted.conf`
	if ( "$tmp" == "" ) then
	    echo WARNING: Did not find keyword \"REPLACE\" in example.
	    echo Manually edit /etc/mrouted.conf file.
	endif
    endif
    rm $INSTALL_ROOT/tmp.$TSTAMP

NO_MROUTED_CONF:

#####################################################################
# Install mrouted program.
#####################################################################

    echo -n "Do you wish to install mrouted? (y/n) [y]: "
    set resp = $<
    if ( "$resp" != "n" ) then
	set MROUTED_LOC = /usr/local
	set MROUTED = mrouted
	set MROUTED_SNMP = mrouted.snmp
	if ( $RSVP_FLAG == 1 && -e $MCAST_DIR/mrouted/$MROUTED.rsrr ) then
	    set MROUTED = $MROUTED.rsrr
	    set MROUTED_SNMP = $MROUTED_SNMP.rsrr
	endif
	if ( -e $MCAST_DIR/mrouted/$MROUTED_SNMP ) then
	    echo -n "Do you wish to install SNMP version of mrouted? (y/n) [n]: "
	    set resp = $<
	    if ( "$resp" == "y" ) set MROUTED = $MROUTED_SNMP
	endif
	if ( ! -e $MCAST_DIR/mrouted/$MROUTED ) then
	    echo -n "Could not locate "
	    echo $MCAST_DIR/mrouted/$MROUTED executable. Install yourself.
	else
	    echo -n "Enter location for installation of mrouted program "
	    echo -n "[$MROUTED_LOC]: "
	    set resp = $<
	    if ( "$resp" != "" ) set MROUTED_LOC = $resp
	    if ( -e $MROUTED_LOC/mrouted ) then
		echo -n "Found an mrouted in $MROUTED_LOC. Moving to "
		echo mrouted.orig.$TSTAMP
		$MV $MROUTED_LOC/mrouted \
		    $MROUTED_LOC/mrouted.orig.$TSTAMP
	    endif
	    echo "Installing $MROUTED as $MROUTED_LOC/mrouted"
	    $CP $MCAST_DIR/mrouted/$MROUTED $MROUTED_LOC/mrouted
	endif

	echo "NOTE: User should modify rc.local to run mrouted on reboots."
    endif

endif


echo ""
if ( $unpatched > 0 ) then
    echo "Files installed. Generating kernel config file."
else
    echo "Files installed. Building kernel."
endif

#####################################################################
# All the object have been installed, and the .h and .c files
# have been patched. Build that sucker.
#####################################################################

set VMUNIX_DIR = ""
BUILD_LOOP:

# Move into the system directory for selected kernel architecture

pushd $INSTALL_ROOT/$karch >&! /dev/null

#first generate a config file.

set MCAST_TEMPL = "GENERIC"
while ( 1 )
    echo -n "Kernel configuration template [$MCAST_TEMPL]: "
    set resp = $<
    if ( "$resp" != "" ) set MCAST_TEMPL = $resp
    if ( -e "conf/$MCAST_TEMPL" ) break
    echo "Unable to locate configuration template:"
    echo $INSTALL_ROOT/$karch/conf/$MCAST_TEMPL
    if ( "$MCAST_TEMPL" == "GENERIC" ) then
	set MCAST_TEMPL = "none"
    else
	set MCAST_TEMPL = "GENERIC"
    endif
end

# Generate a kernel identifier

set KNAME = MULTICAST-$OS_REL
echo -n "Enter ident for new kernel [$KNAME]: "
set resp = $<
if ( "$resp" != "" ) set KNAME = $resp

# Do the config stuff

if ( { test -h conf } ) then
    if ( "$INSTALL_MIRROR" != "" ) then
	set SYMLINK = $INSTALL_MIRROR/$karch/conf
    else
	set SYMLINK = `/bin/ls -l conf | awk '{print $NF}'` 
    endif
    rm conf
    mkdir conf
    if ( "`ls $SYMLINK | head -1`" != "") then
	ln -s $SYMLINK/* conf
    endif
endif
if ( { test -h $KNAME } ) then
    rm $KNAME
endif

cd conf

# Safety precaution.

if ( -e "$KNAME" ) then 
    if ( "$MCAST_TEMPL" == "$KNAME" ) then
	echo "Backing up existing config file $KNAME"
	echo "as $KNAME.orig.$TSTAMP"
	$MV $KNAME $KNAME.orig.$TSTAMP
	set MCAST_TEMPL = $KNAME.orig.$TSTAMP
    else
	echo "Old config file $KNAME found,"
	echo "moving to $KNAME.orig.$TSTAMP"
	$MV $KNAME $KNAME.orig.$TSTAMP
    endif
endif

#####################################################################
# All sun kernels need the INET option set. This is standard
# practice (see the README in the config dir).
# Look for the INET option entry in the template config file and
# and insert new multicasting entries in the output config file.
# Change the identifier to the new identifier.
# To handle upgrades, existing options lines are deleted first.
#####################################################################

echo -n "/options[\ \	]MULTICAST/ d\
/options[\ \	]MROUTING/ d\
/options[\ \	]RSVP_ISI/ d\
/options[\ \	]INET/ a\\
options	MULTICAST	# multicast kernel extension" \
  >> $INSTALL_ROOT/tmp.$TSTAMP

if ( $MROUTING_FLAG == 1 ) then
    echo -n "\\
options	MROUTING" >> $INSTALL_ROOT/tmp.$TSTAMP
endif
if ( $RSVP_FLAG == 1 ) then
    echo -n "\\
options	RSVP_ISI	# reservation protocol hooks" \
	 >> $INSTALL_ROOT/tmp.$TSTAMP
endif

set IDENT = \"$KNAME\"
echo "\
/^ident/ c\\
ident		$IDENT" >> $INSTALL_ROOT/tmp.$TSTAMP

cat $MCAST_TEMPL | sed -f $INSTALL_ROOT/tmp.$TSTAMP >! $KNAME
rm $INSTALL_ROOT/tmp.$TSTAMP

# If we don't have a new config file, something went wrong!

if ( -e $KNAME ) then
    echo "Kernel config file built."
else
    echo "Config file build failed.  Edit one manually."
endif

# Proceed only if it looks like the patches were installed correctly.
# (This is a somewhat weak check.)

if ( $unpatched > 0 ) then
    echo ""
    echo -n "The kernel cannot be completed because $unpatched "
    if ( $unpatched > 1 ) then
	echo "files were"
    else
	echo "file was"
    endif
    echo "not patched successfully.  Look for *.rej and in logfile"
    echo "$LOG to figure out why."
endif

if ( ! -e $KNAME || $unpatched > 0 ) then
    echo "Then manually run /etc/config, make, and boot."
    goto ABORT
endif


#####################################################################
# Now actually build the kernel
#####################################################################

echo "Running config for new kernel."

/etc/config $KNAME

if ( $status != 0 ) then
    echo "Problem during config. ABORT"
    goto ABORT
endif

# Config will create the build directory when executed. If it isn't
# found, something failed in config.

if ( ! -d $INSTALL_ROOT/$karch/$KNAME ) then
    echo "Unable to locate $INSTALL_ROOT/$karch/$KNAME"
    echo "Problem during config? ABORT"
    goto ABORT
endif


# If we find the directory, go there and compile the kernel

cd ../$KNAME

echo Making new vmunix.....

make

if ( $status != 0 ) then
    echo "Problem during make. ABORT"
    goto ABORT
endif

if ( ! -e vmunix ) then
    echo "make failed. go figure...."
    echo ABORT
    goto ABORT
endif

echo "Install and build complete."

# Remember where we built the kernel for this machine's architecture.

if ( "$VMUNIX_DIR" == "" ) set VMUNIX_DIR = $INSTALL_ROOT/$karch/$KNAME
popd >&! /dev/null

#####################################################################
# If there are multiple architecture directories available, ask if
# kernels should be built for the others as well.
#####################################################################

set dirlist = $INSTALL_ROOT/*/OBJ
if ( $#dirlist > 1 ) then
    echo ""
    while ( 1 )
	echo -n "Do you want to build a kernel for another architecture?"
	echo -n " (y/n) [n]: "
	set resp = $<
	if ( "$resp" != "y" ) break
	echo -n "Next architecture to be built: "
	set karch = $<
	if ( "$karch" != "" ) then
	    if ( ! -d "$INSTALL_ROOT/$karch/conf" ) then
		echo "Unable to locate architecture config directory:"
		echo $INSTALL_ROOT/$karch/conf
		continue
	    endif
	    if ( ! -d "$INSTALL_ROOT/$karch/OBJ" ) then
		echo "Unable to locate architecture OBJ directory:"
		echo $INSTALL_ROOT/$karch/OBJ
		continue
	    endif
	    if ( ! -d $MCAST_DIR/$OS_REL_DIR/$karch.OBJ ) then
		echo -n "No multicast object files installed for"
		echo " architecture $karch"
		continue
	    endif
	    echo "Building kernel for $karch architecture."
	    goto BUILD_LOOP
	endif
    end
endif

echo ""

#####################################################################
# If we make it here, we have a new kernel. We prompt the user
# as to whether she wants to install it or not. Optionally
# reboot after install.
#####################################################################

if ( $WHOAMI == "root" ) then
    echo -n "Install new kernel? (y/n) [y]: "
    set resp = $<
else
    set resp = "n"
endif
if ( "$resp" != "n" ) then
    $MV /vmunix /vmunix.orig.$TSTAMP
    $CP $VMUNIX_DIR/vmunix /vmunix

    echo New vmunix installed.
    echo -n "Reboot? (y/n) [y]: "
    set resp = $<
    if ( "$resp" != "n" ) then
	/etc/reboot
    endif

else
    echo "Install new kernel manually and reboot."	
endif

DONE:

exit 0

ABORT:

exit 1
