#!/bin/sh -h
# @(#) installpatch 4.12 94/11/21 SMI
# is_server feature is disabled for now....
#
# Exit Codes:	0	No error
#		1	Usage error
#		2	Attempt to apply a patch that's already been applied
#		3	Effective UID is not root
#		4	Attempt to save original files failed
#		5	pkgadd failed
#		6	Patch is obsoleted
#		7	Invalid package directory
#		8	Attempting to patch a package that is not installed
#		9	Cannot access /usr/sbin/pkgadd (client problem)
#		10	Package validation errors
#		11	Error adding patch to root template
#		12	Patch script terminated due to signal
#		13	Symbolic link included in patch
#		14	NOT USED
#		15	The prepatch script had a return code other than 0.
#		16	The postpatch script had a return code other than 0.
#		17	Mismatch of the -d option between a previous patch
#			install and the current one.
#

# Set the path for use with these scripts.

PATH=/usr/sbin:/usr/bin:$PATH
export PATH

umask 022

# Global Files
EXISTFILES=/tmp/existfiles.$$
PATCHFILES=/tmp/patchfiles.$$
PKGCOFILE=/tmp/pkgchk.out.$$ 
VALERRFILE=/tmp/valerr.$$
VALWARNFILE=/tmp/valwarn.$$
ADMINTFILE=/tmp/admin.tmp.$$
ADMINFILE=/tmp/admin.$$
KBYTESFILE=/tmp/kbytes_required.$$
LOGFILE=/tmp/pkgaddlog.$$

client=no
#force="no"
is_a_root_pkg=no
#is_server="no"
patchdir=
patchnum=
patchbase=
patchrev=
pkglist=
printpatches="no"
rootlist=
saveold="yes"
validate="yes"
isapplied="no"

ROOTDIR="/"
PATCHDB="/var/sadm/patch"
PKGDB="/var/sadm/pkg"
SOFTINFO="/var/sadm/softinfo"
PKGDBARG=""

#
# Description:
#	If a prepatch executable exists in the $1 directory, execute it.
#	If the return code is 0, continue. Otherwise, exit with code 15.
#
# Parameters:
#	$1	- patch directory.
# Globals Set:
#	none
#
execute_prepatch()
{
retcode=
if [ -x "$1/prepatch" ]; then
	/usr/bin/echo "Executing prepatch script..."
	$1/prepatch
	retcode=$?
	if [ "$retcode" != "0" ]; then
		/usr/bin/echo "The prepatch script exited with return code $retcode."
		/usr/bin/echo "Installpatch is terminating."
		rm -fr /tmp/*.$$
		exit 15
	fi
fi
}

#
# Description:
#	If a postpatch executable exists in the $1 directory, execute it.
#	If the return code is 0, continue. Otherwise, if this is not
#	a re-installation of the patch, execute the 
#	backoutpatch script and exit with a return code 16.
#	If this is a re-installation, don't backout the patch. Instead,
#	send a message to the user.
#
# Parameters:
#	$1	- patch database directory
#	$2	- patch number
#	$3	- patch directory.
# Globals Set:
#	none
#
execute_postpatch()
{
retcode=
if [ -x "$3/postpatch" ]; then
	/usr/bin/echo "Executing postpatch script..."
	$3/postpatch
	retcode=$?
	if [ "$retcode" != "0" ]; then
		/usr/bin/echo "The postpatch script exited with return code $retcode."
		if [ "$isapplied" = "no" ]; then
			cp $1/$2/log /tmp/log.$2
			/usr/bin/echo "Backing out patch:"
			cd $3
			if [ "$ROOTDIR" != "/" ]; then
				./backoutpatch $PKGDBARG $2
			else
				./backoutpatch $2
			fi
			/usr/bin/echo "Installpatch is terminating."
			/usr/bin/echo "See /tmp/log.$2 for more details."
		else
			echo "Not backing out patch because this is a re-installation." >> $1/$2/log
			echo "The system may be in an unstable state!" >> $1/$2/log
			/usr/bin/echo "Installpatch is terminating."
			echo "See $1/$2/log for more details."
		fi
		rm -fr /tmp/*.$$
		exit 16
	fi
fi
}

#
#
# Description:
#	Give a list of applied patches similar in format to the showrev -p
#	command. Had to write my own because the showrev command won't take
#	a -R option.
#
# Parameters:
#	$1	- package database directory
# Globals Set:
#	none
#
myshowrev()
{
olddir=`pwd`
cd $1
patches=
patches=`grep -l SUNW_PATCHID ./*/pkginfo | \
xargs sed -n 's/^SUNW_PATCHID=//p' | sort -u`
#patches=`sed -n 's/^SUNW_PATCHID=//p' ./*/pkginfo | sort -u`
if [ "$patches" != "" ]; then
	for apatch in $patches; do
		outstr="Patch: $apatch Obsoletes: "
		patchvers=`grep -l "SUNW_PATCHID=$apatch" ./*/pkginfo | \
		sed 's,^./\(.*\)/pkginfo$,\1,'`
		obsoletes_printed="n"
		for vers in $patchvers; do
			if [ "$obsoletes_printed" = "n" ]; then
				outstr="$outstr`sed -n 's/SUNW_OBSOLETES=//p' ./$vers/pkginfo` Packages: "
				outstr="$outstr$vers `sed -n 's/VERSION=//p' ./$vers/pkginfo`"
				obsoletes_printed="y"
			else
				outstr="$outstr, $vers `sed -n 's/VERSION=//p' ./$vers/pkginfo`"
			fi
		done
		/usr/bin/echo $outstr
	done
else
	/usr/bin/echo "No patches are installed"
fi
cd $olddir
}

#
# Description:
#	Validate the patch directory, and parse out the patch number and
#	patch revision from the first pkginfo file found in the patch
#	packages.
# Parameters:
#	$1	- patch directory
# Globals Set:
#	patchnum
#	patchbase
#	patchrev

activate_patch()
{
	cd $1
	for i in */pkginfo; do
#
# Find the patch number in one of the pkginfo files. If there is no pkginfo
# file having a SUNW_PATCHID=xxxxxx entry, send an error to the user and
# exit.
#
		patchnum=`grep '^SUNW_PATCHID' $i 2>/dev/null | sed 's/.*=[ 	]*\([^ 	]*\).*/\1/'`
		break;
	done
	if [ "$patchnum" = "" ]; then
		/usr/bin/echo "$1 packages are not proper patch packages."
		/usr/bin/echo 'See "Instructions for applying the patch" in the README file.'
		exit 7
#
# Get the patch base number (the patch number up to the -) and the patch
# revision number (the patch number after the -).
#
	else
		patchbase=`expr $patchnum : '\(.*\)-.*'`
		patchrev=`expr $patchnum : '.*-\(.*\)'`
	fi
}

# Description:
#	Build the admin file for later use by non-interactive pkgadd
# Parameters:
#	none
# Globals Used:
#	ADMINTFILE

build_admin_file() {
cat > $ADMINTFILE << EOF
mail=
instance=unique
partial=nocheck
runlevel=nocheck
idepend=nocheck
rdepend=nocheck
space=quit
setuid=nocheck
conflict=nocheck
action=nocheck
EOF
}

# Description:
#	See if there is any work to be done. If none of the packages to
#	which the patch applies are installed and there is no spooling work
#	to do for the client root templates, then you're done.
#	NEW:
#	If SUNWcar, SUNWcsd or SUNWcsr is included in the patch,
#	but the package is not on the list to be patched, then print an
#	error message and die. At least one instance of these packages
#	should be patched if included in the patch.
# Parameters:
#	$1	- client status
#	$2	- were any of the packages root packages?
# Globals Used:
#	pkglist
#	rootlist
#	patchdir

check_for_action() {
	if [ "$pkglist" = "" -a "$rootlist" = "" ]; then
#
# In the first case, the system is not a client, however, there are still
# no packages to patch. This will only occur if the packages in question
# have not been installed on the system.
#
		if [ $1 = no -o $2 = yes ] ; then
 			/usr/bin/echo "None of the packages to patch are installed on this system."
			/usr/bin/echo "Installpatch is terminating."
			exit 8
#
# In the second case, the system is a client system. There are two types of
# packages for client systems: root packages (those packages installed on
# the client machines) and packages installed only on the server. Installpatch
# will exit if the machine is a client, and there are no root packages to be
# patched.
#
		else
			/usr/bin/echo "This patch is not applicable to client systems."
			/usr/bin/echo "Installpatch is terminating."
			exit 0
		fi
	fi
}

# Description:
#	Check to see if the patch has already been applied
# Parameters:
#	$1	- patch database directory
#	$2	- patch number
# Globals Set:
#	isapplied will be set to "yes" if this is a re-application of a patch. This
#	will not necessarily cause a bail out if there are packages that should be
#	installed that were not installed the first time the patch was applied.
#
check_if_applied() {
	if myshowrev $PKGDB | grep -s "^Patch:[ 	]*$2" > /dev/null 2>&1 ; then
#		/usr/bin/echo "Patch $2 has already been applied. See README file for instructions."
#		/usr/bin/echo "Installpatch is terminating."
#		rm -f /tmp/*.$$
#		exit 2
		isapplied="yes"
	else
		rm -fr $1/$2
	fi
}

# Description:
#	Generate a list of packages to be installed. Remove from the previously
#	generated $pkglist any packages that have already been patched. This
#	procedure is called only for a patch re-installation.
# Parameters:
#	$1	- package database directory
#	$2	- patch database directory
#	$3	- patch number
# Globals Used:
#	pkglist
# Globals Set:
#	pkglist

gen_uninstalled_pkgs() {
	pkg=
	for i in $pkglist; do
		if myshowrev $1 | grep "^Patch:[ 	]*$3" | \
			grep -s $i > /dev/null 2>&1 ; then
			continue
		else
			pkg="$pkg $i"
		fi
	done
	if [ "$pkg" = "" ]; then
		echo "Patch $3 has already been applied. See README file for instructions."
		echo "Installpatch is terminating."
		rm -f /tmp/*.$$
		exit 2
	else
		echo "Re-installing patch $3..."
		echo "" >> $2/$3/log
		echo "Re-installing Patch." >> $2/$3/log
	fi
	pkglist="$pkg"
}


# Description:
#	Check to see if the patch is obsoleted by an earlier patch
# Parameters:
#	none
# Globals used:
#	PKGDB
#	patchbase
#	patchrev
# Globals set:
#	isapplied

check_if_obsolete() {
	currentdir=`pwd`
#
# Search for patches with the same patch base, but a greater than
# rev. If an equal to rev, set the isapplied global to "yes"
#
	oldRevs=
	cd $PKGDB
	oldRevs=`grep "SUNW_PATCHID=$patchbase" ./*/pkginfo | \
	         sed 's/^.*-\([0-9][0-9]\).*$/\1/' | sort -u`
	if [ "$oldRevs" != "" ]; then
		oldRevs=`echo $oldRevs | sort -u`
		for ii in $oldRevs X; do
			if [ "$ii" = "X" ]; then
				break;
			fi
			if [ "$ii" = "$patchrev" ]; then
				isapplied="yes"
				continue
			elif [ "$ii" -gt "$patchrev" ]; then
				print_obsolete_msg "$patchbase-$ii"
				exit 6
			fi
		done
	fi
#
# Now search for patches that specifically obsolete the current patch.
# Ignore if the patchpase of the obsoletor is the same as the obsoletee.
#
	if myshowrev $PKGDB | grep -v "Patch: $patchbase" | \
	grep -s "Obsoletes:.*$patchbase.*Packages:" > /dev/null 2>&1; then
		print_obsolete_msg
		myshowrev $PKGDB | \
		grep -v "Patch: $patchbase" | \
		grep "Obsoletes:.*$patchbase.*Packages:"
		exit 6
	fi
	cd $currentdir
}

# Description:
# 		CURRENTLY DISABLED
# Parameters:
#		none

check_if_server() {
	/usr/bin/echo > /dev/null
      # if grep -s "SPOOLED_ROOT" $SOFTINFO/$prodver > /dev/null 2>&1
      # then
      #		is_server="yes"
      # fi
}

# Description:
#	Determine if the patch contains any symbolic links. If so, die with
#	an error and a message to the user. I assume the patch will be tested
#	at least once in-house before getting to a non-sun user, so an
#	external user should NEVER see a symbolic link message.
# Parameters:
#	None
# Globals Set:
#	None.
# Globals Used:
#	$patchdir
#
check_for_symbolic_link() {
	rm -f /tmp/symlink.$$ > /dev/null 2>&1
	olddir=`pwd`
	cd $patchdir
	for ii in * X; do
		if [ "$ii" = X ]; then
			break
		fi
		if [ ! -d "$ii" ]; then
			continue
		fi
#
# Comment out ignoring symbolic links for packages with no current
# instance. New packages will not be added using installpatch.
#
#		grep -s "VERSION=.*PATCH=" $1/$2/$ii/pkginfo
#		if [ $? != 0 ]; then
#			continue
#		fi
		symlinks=
		symlinks=`sed -n '/^[^ 	]*[ 	]*s[ 	]/p' $1/$2/$ii/pkgmap`
		if [ "$symlinks" != "" ]; then
			/usr/bin/echo "Symbolic link in package $ii" >> /tmp/symlink.$$
		fi
	done
	if [ -s /tmp/symlink.$$ ]; then
		/usr/bin/echo
		cat /tmp/symlink.$$
		/usr/bin/echo
		/usr/bin/echo "Symbolic links can't be part of a patch."
		/usr/bin/echo "Installpatch is terminating."
		rm -f /tmp/*.$$
		exit 13
	fi
	cd $olddir
}

# Description:
#	Find package instance of originally-installed package. Extract the
#	PKGID, ARCH, and VERSION by scanning the pkginfo files of each patch
#	package. Check to see if the packages that are being patched were 
#	actually installed on the system in the first place.
# Parameters:
#	$1	- package database directory
#	$2	- patch directory
# Globals Set:
#	pkglist
#	is_a_root_pkg
# Globals Use:
#	pkglist

check_pkgs_installed() {
	i=
	j=
	pkginst=
	finalpkglist=
	minver=
	Pkgpatchver=
	Pkgarch=
	Pkgabbrev=
	Pkgver=
	Pkgtype=
	OrigPkgver=
#
# Search the installed pkginfo files for matches with the list of packages
# to be patched. The package names are listed in global pkglist. These names
# correspond to the package database subdirectory names.
#
	for i in $pkglist; do
#
# Get the package abbreviation from the pkginfo file.
#
		Pkgabbrev=`sed -n 's/^[ 	]*PKG[ 	]*=[ 	]*\([^ 	]*\)[	 ]*$/\1/p' $i/pkginfo`
#
# Get the package architecture from the pkginfo file.
#
		Pkgarch=`sed -n 's/^[ 	]*ARCH[ 	]*=[ 	]*\([^ 	]*\)[	 ]*$/\1/p' $i/pkginfo`
#
# Get the package version number.
#
		Pkgver=`sed -n \
		   -e 's/^[ 	]*VERSION[ 	]*=[ 	]*\([^ 	]*\)\.[0-9][0-9]*[ 	]*$/\1/p' \
		   -e 's/^[ 	]*VERSION[ 	]*=[ 	]*\([^ 	]*\),PATCH=.*$/\1/p' $i/pkginfo `
		minver=`expr $Pkgver : '\(.*\)\.0$'`
		while [ "$minver" != "" ] ; do
		        Pkgver=$minver
		        minver=`expr $Pkgver : '\(.*\)\.0$'`
		done
		Pkgpatchver=`sed -n 's/^[ 	]*VERSION[ 	]*=[ 	]*\([^ 	]*\)[^ 	]*$/\1/p' $i/pkginfo`
		Pkgtype=`sed -n 's/^[ 	]*SUNW_PKGTYPE[ 	]*=[ 	]*\([^ 	]*\)[	 ]*$/\1/p' $i/pkginfo`
		if [ "$Pkgtype" = "root" ] ; then
			is_a_root_pkg=yes
		fi
#
#	Determine if this is a new package to be installed. If so, add
#	the package to the final package list and force it to be
#	pkgadd`ed even if there is no current instance.
#
#	This capability is commented out. New packages are not to be
#	installed by installpatch.
#
#		newpkg="yes"
#		if grep -s "VERSION=.*PATCH=" $2/$i/pkginfo > /dev/null 2>&1
#		then
#			newpkg="no"
#		fi
#		if [ "$newpkg" = "yes" ]; then
#			finalpkglist="$finalpkglist $i,NO_CURRENT_INSTANCE"
#			continue;
#		fi
# 		/usr/bin/echo ""
		for j in $1/$Pkgabbrev X; do
			if [ "$j" = "X" ]; then
				break
			fi
			if [ ! -d "$j" ] && \
			   [ ! -d "$j.*" ]; then
				/usr/bin/echo "Package not patched:" >> $LOGFILE
				/usr/bin/echo "PKG=$Pkgabbrev" >> $LOGFILE
				/usr/bin/echo "Original package not installed" >> $LOGFILE
			fi
		done
		for j in $1/$Pkgabbrev $1/$Pkgabbrev.* X; do
			if [ "$j" = "X" ] ; then
				break
			fi
			if [ ! -d $j ] ; then
				continue;
			fi
		        OrigPkgver=`sed -n 's/^VERSION=\(.*\)$/\1/p' $j/pkginfo`
		        minver=`expr $OrigPkgver : '\(.*\)\.0$'`
		        while [ "$minver" != "" ] ; do
		                OrigPkgver=$minver
		                minver=`expr $OrigPkgver : '\(.*\)\.0$'`
		        done
		        if grep -s "^PKG=$Pkgabbrev$" $j/pkginfo >/dev/null 2>&1 \
		           && grep -s "^ARCH=$Pkgarch$" $j/pkginfo >/dev/null 2>&1 \
		           && [ "$OrigPkgver" = "$Pkgver" ] ;
		        then
		                pkginst=`basename $j`
		                finalpkglist="$finalpkglist $i,$pkginst"
		                break;
		        else
				/usr/bin/echo "Package not patched:" >> $LOGFILE
				/usr/bin/echo "PKG=$Pkgabbrev" >> $LOGFILE
				/usr/bin/echo "ARCH=$Pkgarch" >> $LOGFILE
				/usr/bin/echo "VERSION=$OrigPkgver" >> $LOGFILE
				tmp=""
		           	tmp=`grep "^ARCH=$Pkgarch$" $j/pkginfo 2>/dev/null`
				if [ "$tmp" = "" ]; then
					/usr/bin/echo "Architecture mismatch" >> $LOGFILE
				fi
		           	if  [ "$OrigPkgver" != "$Pkgver" ] ; then
					/usr/bin/echo "Version mismatch" >> $LOGFILE
				fi
				/usr/bin/echo "" >> $LOGFILE
			fi
		done
		#
		#  If j is X, matching package instance was never found.  If
		#  in force mode, add package to list anyway.
		# if [ "$j" = "X"]; then
		#	if [ "$force" = "yes" ] ; then
		#        	finalpkglist="$finalpkglist $i,NO_CURRENT_INSTANCE"
		#	fi
		# fi
		# if [ "$is_server" = "yes" ]; then
		#        if [ "$Pkgarch" = "sparc" ]; then
		#                Pkgarch="sparc.all"
		#        fi
		#        org_template=$Pkgabbrev"_"$Pkgver"_"$Pkgarch
		#        if grep "SPOOLED_ROOT=$Pkgarch:/export/root/templates/$prodver/$org_template" $SOFTINFO/$prodver >/dev/null 2>&1
		#        then
		#                spoolsize=`/usr/bin/du -ks $i | sed 's/ .*//'`
		#                rootlist="$rootlist $i,$Pkgabbrev"_"$Pkgpatchver"_"$Pkgarch",$spoolsize
		#        fi
		# fi
	done
	pkglist=$finalpkglist
}

# Description:
#	If validation is being done, and pkgchk reported ERRORs, bail out.
#	If no validation is being done, keep a list of files that failed
#	validation. If this patch needs to be backed out, don't do an installf
#	on these files. Any files that failed validation before the patch was
#	applied should still fail validation after the patch is backed out.
#	This will be the .validation.errors file in the patch directory.
# Parameters:
#	$1	- validation status [ "yes" or "no" ]
# Globals Used:
#	PKGCOFILE
#	VALERRFILE

check_validation() {
	if [ "$1" = "yes" -a -s $PKGCOFILE ]; then
		if grep -s ERROR $PKGCOFILE >/dev/null 2>&1 ; then
			/usr/bin/echo "The following validation error was found: \n"
			cat $PKGCOFILE
			/usr/bin/echo
			/usr/bin/echo "See the README file for instructions regarding"
			/usr/bin/echo "patch validation errors."
			/usr/bin/echo "Installpatch is terminating."
			rm -f /tmp/*.$$
			exit 10
		fi
			
	fi
	if [ -s $VALWARNFILE ]; then
		cp $VALWARNFILE $VALERRFILE
	fi
}

# Description:
# 	Create a spooling area in the sadm/patch/<patchID> tree for files
# 	which are being replaced by the patch. Store the validation error
# 	file with it.
# Parameters:
#	$1	- patch database directory
#	$2	- patch number
# Globals Used:
#	VALERRFILE

create_archive_area() {
	if [ ! -d $1/$2/save ] ; then
		/usr/bin/echo "Creating patch archive area..."
		mkdir -p -m 750 $1/$2/save
		/usr/bin/chown -h -f -R root $1/$2
		chgrp -h -f -R sys $1/$2
	fi
	if [ -s $VALERRFILE ] ; then
		cp $VALERRFILE $1/$2/.validation.errors
	fi
}

# Description:
#	Scan the patch package maps for a list of affected files.
# Parameters:
#	$1	- package database directory
#	$2	- package relocation argument
# Globals Used:
#	PKGCOFILE
#	PATCHFILES
#	pkglist

gen_install_filelist() {
	pkgfiles=/tmp/pkgfiles.$$
	resfiles=/tmp/resolvedfiles.$$
	macrofiles=/tmp/pkgmacros.$$
	pkginst=
	pkginfofile=
	patchpkg=
	basedir=
	i=
	rm -f $PATCHFILES
	/usr/bin/echo "Generating list of files to be patched..."
	for i in $pkglist; do
		patchpkg=`expr $i : '\(.*\),.*'`
		pkginst=`expr $i : '.*,\(.*\)'`
		if [ "$pkginst" = "NO_CURRENT_INSTANCE" ] ; then
#
# Install a package to be patched if it isn't currently installed????
#
			pkginfofile="$patchpkg/pkginfo"
		else
			pkginfofile="$1/$pkginst/pkginfo"
		fi
#
# parse out the base directory from the pkginfo file. First, remove the BASEDIR
# keyword together with the = and any whitespace. Then remove any / at the end
# of the line. Finally, replace any /a partitions with /
#
		basedir=`grep '^BASEDIR' $pkginfofile | \
		    sed -e 's@.*=\ *@@' -e 's@/$@@' -e 's@/a$@/@'`
#
# Parse out the pkgmap files to get the file names. First, get rid of all
# checksum ifno. Then get rid of all info file entries.
# Replace all BASEDIR values with emptiness (BASEDIR will be prepended).
# Delete all entries that are the BASEDIR without a file (directory entries).
# Get the file name. If it's a symbolic link, keep the link, don't follow
# it to the file.
#
		sed -e '/^:/d' \
		    -e '/^[^ ][^ ]* i/d' \
		    -e 's, \$BASEDIR/, ,' \
		    -e '/ \$BASEDIR /d' \
		    -e 's/^[^ ]* . \([^ ]*\) \([^ ]*\).*$/\2 \1/' \
		    -e 's/=.*//' $patchpkg/pkgmap > $pkgfiles
#
# Resolve any macros in the list of files before determining if the
# file is relocatable.
#
		if [ -s $pkgfiles ]; then
			# resolve any macros in the list of files
			(rm -f $macrofiles $resfiles
			cat $pkginfofile |
			while read i
			do
				/usr/bin/echo `/usr/bin/echo $i| sed -e 's/^\(.*\)=.*/\1/'`=\"`/usr/bin/echo $i|sed -e 's/^\(.*\=\)//'`\" | grep -v '^PATH' >> $macrofiles
			done
			. $macrofiles
		        cat $pkgfiles |
		        while read i
		        do
				eval /usr/bin/echo $i >> $resfiles
			done)
#
# Prepend the basedir to the file name if the file is relocatable, then
# add it to the pkgfile list. 
#
			mv $resfiles $pkgfiles
			sed "s,^\([^/]\),$basedir/&," $pkgfiles > $resfiles
#
#	If there are some files to patch in the package, see if they have
#	validation errors. Ignore any validation errors for files having
#	class action scripts. The remaining validation errors will be put
#	in a validation error file.
#
			if [ -s $resfiles ]; then
				cat $resfiles |
				while read j ; do
					jfile=`/usr/bin/echo $j | \
					sed 's/^\([^ ]*\).*/\1/'`
					class=`/usr/bin/echo $j | \
					sed 's/^[^ ]* \(.*\)/\1/'`
					badfile=
					badfile=`/usr/sbin/pkgchk $2 -p $jfile\
						$patchpkg 2>&1 | \
						grep "^ERROR:" | \
						sed -n 's/^ERROR:[ 	]*//p'`
					if [ "$badfile" != "" ]; then
						if [ "$class" != "" -a "$class" != "preserve" -a ! -f $patchdir/$patchpkg/install/i.$class ]; then
							/usr/sbin/pkgchk $2 -p $jfile\
							$patchpkg >> $PKGCOFILE 2>&1
						fi
						/usr/bin/echo $jfile >> $VALWARNFILE
					fi
				done
			fi
		 	sed 's/^\([^ ]*\).*/\1/' $resfiles >> $PATCHFILES
		fi
	done
}

# Description:
#	Generate a list of files which are "to be patched." Determine their
#	total size in bytes to figure out the space requirements of backing
#	them up.
# Parameters:
#	none
# Globals Used:
#	PATCHFILES
#	EXISTFILES
#	KBYTESFILE

gen_patch_filelist() {
	tmp_total=0
	size=
	kbytes_total=0
	kb=0
	if [ -s $PATCHFILES ] ; then
		cat $PATCHFILES |
		(while read j
		do
			if ls -d $ROOTDIR$j >/dev/null 2>&1
			then
				/usr/bin/echo "."$j >> $EXISTFILES
				size=`wc -c $ROOTDIR$j`
				size=`/usr/bin/echo $size | sed 's/\ .*//'`
				if [ "$size" != "" ]; then
					tmp_total=`expr $tmp_total + $size`
				fi
				if [ $tmp_total -ge 1024 ]; then
					kb=`expr $tmp_total / 1024`
					tmp_total=`expr $tmp_total - $kb \* 1024 `
					kbytes_total=`expr $kbytes_total + $kb`
				fi
			fi
		done;
		if [ "$tmp_total" != "" ]; then
			kbytes_total=`expr $kbytes_total + 1`
		fi
		/usr/bin/echo $kbytes_total > $KBYTESFILE)
		
	else
		rm -f $EXISTFILES
	fi
}

# Description:
# 	Assemble a list of the package package IDs contained in the patch
#	(at least one diretory with a pkginfo file must exist due to checks
#	in activate_patch)
# Parameters:
#	none
# Globals Set:
#	pkglist

gen_patchpkg_list() {
	pkg=
	for i in */pkginfo X; do
		if [ "$i" = "X" ]; then
			break
		fi
		pkg=`expr $i : '\(.*\)/pkginfo'`
		pkglist="$pkglist $pkg"
	done
}

# Description:
#	Get the product version <name>_<version> of local Solaris installation
# Parameters:
#	$1	- softinfo directory path
# Globals Set:
#	prodver

get_os_version() {
	Product=
	Instver=
	Product=`sed -n 's/^OS=\(.*\)/\1/p' $1/INST_RELEASE`
	Instver=`sed -n 's/^VERSION=\(.*\)/\1/p' $1/INST_RELEASE`
	prodver=$Product"_"$Instver
}

# Description:
# 	Actually install patch packages which apply to the system
# Parameters:
#	$1	- patch database directory
#	$2	- patch number
#	$3	- patch directory
#	$4	- package add relocation argument
#	$5	- package database directory
# Globals Used:
#	ADMINTFILE
#	ADMINFILE
#	pkglist

install_patch_pkgs() {
	i=
	ij=
	pkginst=
	pkginfofile=
	pkgadderr=
	patchpkg=
	basedir=
#
#	Write out the contents of the logfile if there were any
#	messages. Do this now, because the $1/$2 directory may not
#	exist before this point.
#
	if [ -f $LOGFILE ]; then
		cat $LOGFILE >> $1/$2/log
		rm -f $LOGFILE
	fi
	/usr/bin/echo "Installing patch packages..."
	for ij in $pkglist; do
		i=`expr $ij : '\(.*\),.*'`
		pkginst=`expr $ij : '.*,\(.*\)'`
		if [ "$pkginst" = "NO_CURRENT_INSTANCE" ] ; then
			pkginfofile="$3/$i/pkginfo"
		else
			pkginfofile="$5/$pkginst/pkginfo"
		fi
		basedir=`grep '^BASEDIR' $pkginfofile | sed -e 's@.*=\ *@@' -e 's@/a/@/@' -e 's@/a$@/@'`
		mkdir -m 750 $1/$2/$i
		cp $i/pkgmap $1/$2/$i/pkgmap
		cp $i/pkginfo $1/$2/$i/pkginfo
 		cp $ADMINTFILE $ADMINFILE
		/usr/bin/echo basedir=$basedir >>$ADMINFILE
	
		/usr/bin/echo "\nDoing pkgadd of $i package:"
		/usr/sbin/pkgadd $4 -S -a $ADMINFILE -n -d $3 $i >$LOGFILE 2>&1
		pkgadderr=$?
		cat $LOGFILE >> $1/$2/log
		cat $LOGFILE | grep -v "^$"
		rm -f $LOGFILE
		if [ $pkgadderr != 0 -a $pkgadderr != 2 -a \
		     $pkgadderr != 10 -a $pkgadderr != 20 ]; then
			/usr/bin/echo "Pkgadd of $i package failed with error code $pkgadderr."
			/usr/bin/echo "Pkgadd of $i package failed with error code $pkgadderr." >> $1/$2/log
			if [ "$isapplied" = "no" ]; then
				/usr/bin/echo "See /tmp/log.$2 for reason for failure."
				cp $1/$2/log /tmp/log.$2
				/usr/bin/echo "Backing out patch:"
				cd $3
				if [ "$ROOTDIR" != "/" ]; then
					./backoutpatch $PKGDBARG $2
				else
					./backoutpatch $2
				fi
			else
				echo "See $1/$2/log for reason for failure."
				echo "Will not backout patch...patch re-installation."
				echo "Warning: The system may be in an unstable state!"
			fi
			/usr/bin/echo "Installpatch is terminating."
			rm -fr /tmp/*.$$
			exit 5
		fi
	done
}

# Description:
# 	Parse the arguments and set all affected global variables
# Parameters:
#	Argument list passed into installpatch 
# Globals Set:
#	validate
#	saveold
#	force
#	printpatches
#	patchdir
#	ROOTDIR
#	PATCHDB
#	PKGDB
#	SOFTINFO
#	PKGDBARG
# Globals Used:
#	prodver
#	SOFTINFO
#	PKGDB
#	PATCHDB

parse_args() {
	service_specified="n"
	rootdir_specified="n"
	while [ "$1" != "" ]
	do
		case $1 in
		-u)	validate="no"; shift;;
		-d)	saveold="no"; shift;;
		-p)	printpatches="yes"; shift;;
#		-f)	force="yes"; shift;;
		-S)	shift
			if [ "$rootdir_specified" = "y" ]; then
				/usr/bin/echo "The -S and -R arguments are mutually exclusive."
				print_usage
				exit 1
			fi
			get_os_version $SOFTINFO
			if [ "$1" != "$prodver" ]; then
				if [ -d "/export/$1$PKGDB" ]; then
					ROOTDIR=/export/$1
					PATCHDB=$ROOTDIR$PATCHDB
					PKGDB=$ROOTDIR$PKGDB
					SOFTINFO=$ROOTDIR$SOFTINFO
					PKGDBARG="-R $ROOTDIR"
					service_specified="y"
				else
					/usr/bin/echo "The $1 service cannot be found on this system."
					print_usage
					exit 1
				fi
			fi
			shift;;
		-V)	/usr/bin/echo "@(#) installpatch 4.12 94/11/16" ; exit 0;;
		-R)	shift
			if [ "$service_specified" = "y" ]; then
				/usr/bin/echo "The -S and -R arguments are mutually exclusive."
				print_usage
				exit 1
			fi
			if [ ! -d "$1" ]; then
				/usr/bin/echo "The Package Install Root directory $1 cannot be found on this system."
				print_usage
				exit 1
			else
				ROOTDIR=$1
				PATCHDB=$ROOTDIR$PATCHDB
				PKGDB=$ROOTDIR$PKGDB
				SOFTINFO=$ROOTDIR$SOFTINFO
				PKGDBARG="-R $ROOTDIR"
				rootdir_specified="y"
			fi
			shift;;

		-*)	print_usage; exit 1;;
		 *)	break;;
		esac
	done
	if [ "$printpatches" = "yes" ]; then
		myshowrev $PKGDB
		exit 0
	fi
	if [ "$1" = "" ]; then
		/usr/bin/echo "No patch directory specified."
		print_usage
		exit 1
	fi
	if [ ! -d $1 ]; then
		/usr/bin/echo "Patch directory '$1' does not exist."
		print_usage
		exit 1
	fi
#
#	Derive the full path name from a (possibly) relative path name.
#
	olddir=`pwd`
	cd $1
	patchdir=`pwd`
	cd $olddir
	/usr/bin/echo "@(#) installpatch 4.12 94/11/16"
}

# Description:
#	Scan all pkginfo files for installed packages for a PATCH
#	identifier string and print out the associated package info
# Parameters:
#	$1 	- patch database directory

# Description:
#	Print the patch obsolecensce message
# Parameters:
#	$1	- number of patch which obsoleted this patch

print_obsolete_msg() {
	/usr/bin/echo "This patch is obsoleted by patch $1 which has already"
	/usr/bin/echo "been applied to this system. Patch installation is aborted."
}

# Description:
#	Print the list of patch packages which were applied, and those
#	which were not.
# Parameters:
#	none
# Globals Used:
#	pkglist

print_results() {
	i=
	p=
	/usr/bin/echo "\nPatch packages installed:"
	if [ -s "$pkglist" ]; then
		/usr/bin/echo "		none"
	else
		for i in $pkglist; do
			p=`expr $i : '\(.*\),.*'`
			/usr/bin/echo "	$p"
		done
	fi
}

# Description:
#	Usage message
# Parameters:
#	none

print_usage() {
cat << EOF

   Usage: installpatch [-u -d -p -V] [-S <service> | -R <root_path>] <patch directory>
 Options:
          -u	Turn off file validation.  Allows the patch to be
		applied even if some of the files to be patched have
		been modified since original installation.
   	  -d	Don't back up the files to be patched.  This means
		that the patch can't be backed out.
   	  -p	Print a list of the patches currently applied
   	  -V	Print script version number
   	  -S <service>
		Specify an alternate service (e.g. Solaris_2.3) for
		patch package processing references. Cannot be specified
		with the -R option.
          -R <root_path>
		Define the full path name of a subdirectory to use as the
		root_path. All package system information files are assumed
		to be located in a directory tree starting in the
		specified root_path. All patch files generated from the
		installpatch will be located in the same directory tree.
		Cannot be specified with the -S option.
EOF
}

# Description:
# 	Archive files which will be overwritten by the patch application,
#	if the patch actually affects any existing files.
# Parameters:
#	$1	- patch database directory
#	$2	- patch number
#	$3	- patch directory
#	$4	- save old files [ "yes" or "no" ]
# Globals Used:
#	EXISTFILES
#	KBYTESFILE

save_overwritten_files() {
	olddir=
	kbytes_avail=
	kbytes_required=
	bytes=
	if [ ! -s $EXISTFILES ] ; then
		touch $1/$2/.nofilestosave
	elif [ "$4" = "yes" ]; then
		/usr/bin/echo "Saving a copy of existing files to be patched..."
		# Is there enough space? Use sed to extract the fourth field of
		# df output (can't use awk because it may not be installed).
		kbytes_avail=`df -k $1 | tail -1 | \
		  sed 's/^[^ 	]*[ 	]*[^ 	]*[ 	]*[^ 	]*[ 	]*\([^ 	]*\).*/\1/'`
		bytes=`cat $KBYTESFILE`
		kbytes_required=`expr $bytes`
		if [ $kbytes_required -gt $kbytes_avail ]; then
			/usr/bin/echo "Insufficient space in $1 to save old files."
			/usr/bin/echo "Space required in kilobytes:  $kbytes_required"
			/usr/bin/echo "Space available in kilobytes:  $kbytes_avail"
			if [ "$isapplied" = no ]; then
				cd $3
				if [ "$ROOTDIR" != "/" ]; then
					./backoutpatch $PKGDBARG $2
				else
					./backoutpatch $2
				fi
				rm -fr $1/$2
			fi
			rm -f /tmp/*.$$
			exit 4
		fi
		cd $ROOTDIR
		if [ "$isapplied" = "no" ]; then
			cpio -oL -O $1/$2/save/archive.cpio <$EXISTFILES
		else
			cp $1/$2/save/archive.cpio* /tmp
			if [ -f /tmp/archive.cpio.Z ]; then
				uncompress /tmp/archive.cpio.Z
			fi
			cpio -oAL -O /tmp/archive.cpio <$EXISTFILES
		fi
		if [ $? != 0 ]; then
			echo "Save of old files failed. \c"
			echo "See README file for instructions."
			if [ "$isapplied" = "no" ]; then
				cd $3
				if [ "$ROOTDIR" != "/" ]; then
					./backoutpatch $PKGDBARG $2
				else
					./backoutpatch $2
				fi
				rm -fr $1/$2
			fi
			/usr/bin/echo "Installpatch is terminating."
			rm -f /tmp/*.$$
			exit 4
		fi
		if [ -x /usr/bin/compress ]; then
			if [ "$isapplied" = "no" ]; then
				compress $1/$2/save/archive.cpio
			else
				compress /tmp/archive.cpio
			fi
			if [ $? = 0 ]; then
				echo "	File compression used"
			else
				echo "	No file compression used."
			fi
		else
			echo "	No file compression used."
		fi
		if [ "$isapplied" = "yes" ]; then
			cp /tmp/archive.cpio* $1/$2/save
		fi
		chmod 600 $1/$2/save/archive.cpio*
		touch $1/$2/.oldfilessaved
	fi
	cd $3
}

# Description:
#	Finish up the patch
# Parameters:
#	$1	- patch database directory
#	$2	- patch number

set_patch_status() {
	mv -f /tmp/ACTION.$patchnum $1/$2 >/dev/null 2>&1
	cp -p README.$2 backoutpatch $1/$2 >/dev/null 2>&1
	cp -p prebackout postbackout $1/$2 > /dev/null 2>&1
	rm -f /tmp/*.$$
	rm -f /tmp/archive.cpio*
}

# Description:
# 	Spool a copy of the patch into the client root template area
#			NOT IMPLEMENTED AT THIS TIME
# Parameters:
#	none

spool_client_patch() {
	/usr/bin/echo > /dev/null
      #	if [ "$is_server" = "yes" ]
      #	then
      #		/usr/bin/echo "Spooling patch packages to root templates for future clients"
      #		/usr/bin/echo "[NOTE: existing clients will need patches applied individually]"
      #		for i in $rootlist; do
      #			patchpkg=`expr $i : '\([^,]*\),.*'`
      #			spoolloc=`expr $i : '[^,]*,\([^,]*\),.*'`
      #			spoolsize=`expr $i : '[^,]*,[^,]*,\(.*\)'`
      #			arch=`expr $spoolloc : '[^_]*_[^_]*_\(.*\)'`
      #			ver=`expr $spoolloc : '[^_]*_\([^_]*\)_.*'`
      #			abbrev=`expr $spoolloc : '\([^_]*\)_.*'`
      #			/usr/bin/echo $patchpkg $spoolloc $spoolsize $arch $ver $abbrev
      #	
      #			if [ ! -d /export/root/templates/$prodver/$spoolloc ]; then
      #				mkdir -m 750 -p /export/root/templates/$prodver/$spoolloc
      #			fi
      #			find $patchpkg -print | cpio -pd /export/root/templates/$prodver/$spoolloc
      #			if [ $? != 0 ]; then
      #				/usr/bin/echo "Error while adding patch to root template."
      #				/usr/bin/echo "See README file for instructions."
      #				rm -fr /export/root/templates/$prodver/$spoolloc
      #				cd $patchdir
      #				./backoutpatch -s $patchnum
      #				/usr/bin/echo "Installpatch is terminating."
      #				rm -fr $PATCHDB/$patchnum
      #				rm -f /tmp/*.$$
      #				exit 11
      #			fi
      #
      #			/usr/bin/echo SPOOLED_ROOT=$arch":"/export/root/templates/$prodver/$spoolloc >> $SOFTINFO/$prodver
      #			/usr/bin/echo ROOT=$arch:$abbrev,$spoolsize,$ver >> $SOFTINFO/$prodver
      #			/usr/bin/echo /SPOOLED_ROOT=$arch":".export.root.templates.$prodver.$spoolloc/d >> $PATCHDB/$patchnum/softinfo_sed
      #			/usr/bin/echo /ROOT=$arch:$abbrev,$spoolsize,$ver/d >> $PATCHDB/$patchnum/softinfo_sed
      #			/usr/bin/echo "/export/root/templates/$prodver/$spoolloc" >> $PATCHDB/$patchnum/spooled_dirs
      #		done
      #	fi
}

# Description:
# Parameters:
#	$1	- patch database directory
#	$2	- patch number
#	$3	- patch directory

trap_backoutsaved() {
	/usr/bin/echo "Interrupt signal detected."
	if [ "$isapplied" = "no" ]; then
		echo "Backing out patch:"
		cd $3
		if [ "$ROOTDIR" != "/" ]; then
			./backoutpatch $PKGDBARG $2
		else
			./backoutpatch $2
		fi
		rm -fr $1/$2
	else
		cp /tmp/archive.cpio* $1/$2/save
		rm -f /tmp/archive.cpio*
		echo "Installpatch Interrupted." >> $1/$2/log
	fi
	/usr/bin/echo "Installpatch is terminating."
	rm -f /tmp/*.$$
	exit 12
}

# Description:
# Parameters:
#	$1	- patch directory
#	$2	- patch number

trap_backout() {
	/usr/bin/echo "Interrupt signal detected."
	echo "Backing out Patch:"
	cd $1
	if [ "$ROOTDIR" != "/" ]; then
		./backoutpatch $PKGDBARG $2
	else
		./backoutpatch $2
	fi
	if [ "$isapplied" = "yes" ]; then
		rm -f /tmp/archive.cpio*
	fi
	/usr/bin/echo "Installpatch is terminating."
	rm -f /tmp/*.$$
	exit 12
}

# Description:
# Parameters:
# 	$1	- patch database directory
#	$2	- patch number

trap_notinstalled() {
	/usr/bin/echo "Interrupt signal detected. Patch not installed."
	/usr/bin/echo "Installpatch is terminating."
	rm -f /tmp/*.$$
	if [ "$isapplied" = "no" ]; then
		rm -fr $1/$2
	else
		echo "Install Interrupted." >> $1/$2/log
	fi
	exit 12
}

# Description:
#	 Make sure effective UID is '0'
# Parameters:
#	none

validate_uid() {
	uid=`/usr/bin/id | sed 's/uid=\([0-9]*\)(.*/\1/'`
	if [ "$uid" != "0" ] ; then
		/usr/bin/echo "You must be root to execute this script."
		exit 3
	fi
}

# Description:
#	Assume that any system on which the SUNWcsu package is NOT
#	installed is a client. It is a safe bet that this criterion
#	will remain valid through Solaris 2.3. Later releases may require
#	that this test be changed. Make sure pkgadd is executable too.
# Parameters:
#	none
# Globals Set:
#	client

verify_client() {
	/usr/bin/pkginfo -q SUNWcsu
	if [ $? != 0 ]; then
		client=yes
		sum /usr/sbin/pkgadd > /dev/null 2>&1
		if [ $? != 0 ]; then
			/usr/bin/echo "The /usr/sbin/pkgadd command is not executable."
			/usr/bin/echo "See the README file for instructions for making this"
			/usr/bin/echo "command executable."
			exit 9
		fi
	fi
}

############################################
#		Main Routine		   #
############################################

#
# -	Get the product version <name>_<version> of local Solaris
#	installation (sets the prodver global variable)
# -	Parse the argument list and set globals accordingly
# -	Make sure the user is running as 'root'
#
/usr/bin/echo
parse_args $*
validate_uid
get_os_version "$SOFTINFO"

#
# Change to the patch directory and set globals according to the patchID
# found in the pkginfo files of the patch packages
#
activate_patch "$patchdir"

#
# -	Check to see if patch has already been applied, and exit if already
# 	applied successfully
# -	Check whether patch has been obsoleted by a prior patch
# -	Determine if system being patch is a client, and make sure pkgadd
#	is usable servers must export to clients for read-only root access)
# -	Determine if system being patched is a server (CURRENTLY DISABLED)
#
# -	Make sure the patch doesn`t contain any symbolic links. If it does,
#	print out an error. Sustaining engineering will need to re-engineer
#	the patch to replace a symbolic link in one of the pre or post install
#	scripts.
#
check_if_applied "$PATCHDB" "$patchnum"

#
#   prev  | curr | .nofilestosave | Is it OK to |  How to verify previous
#   save  | save |    exist?      |  continue?  |    save/no_save state
#  -------+------+----------------+-------------+-----------------------------
#         |      |      yes       |             | a. empty save directory
#  1. yes | yes  |----------------|  continue   +-----------------------------
#         |      |       no       |             | b. NON empty save directory
#  -------+------+----------------+-------------+-----------------------------
#         |      |      yes       |  continue   | a. empty save directory
#  2. yes |  no  |----------------+-------------+-----------------------------
#         |      |       no       |  terminate  | b. NON empty save directory
#  -------+------+----------------+-------------+-----------------------------
#  3.  no |  no  |       no       |  continue   |    empty save directory
#  -------+------+----------------+-------------+-----------------------------
#  4.  no | yes  |       no       |  terminate  |    empty save directory
#  -------+------+----------------+-------------+-----------------------------
#
if [ "$isapplied" = "yes" ]
then
    if [ "$saveold" = "no" ]
    then
        if [ ! -f "${PATCHDB}/${patchnum}/.nofilestosave" -a \
            \( -f "${PATCHDB}/${patchnum}/save/archive.cpio" -o \
               -f "${PATCHDB}/${patchnum}/save/archive.cpio.Z" \) ]
        then
            # condition #2b - terminate
            /bin/echo "A previous installation of patch $patchnum was invoked"
            /bin/echo "that saved files that were to be patched.  Since files"
            /bin/echo "were saved, you must run this instance of installpatch"
            /bin/echo "apply this patch WITHOUT the -d option."
            exit 17
        elif [ -f "${PATCHDB}/${patchnum}/.nofilestosave"     -a \
              ! -f "${PATCHDB}/${patchnum}/save/archive.cpio" -a \
              ! -f "${PATCHDB}/${patchnum}/save/archive.cpio.Z"   ]
        then
            # condition #2a - rm .nofilestosave
            /usr/bin/rm ${PATCHDB}/${patchnum}/.nofilestosave
        fi
    else
        if [ ! -f "${PATCHDB}/${patchnum}/.nofilestosave"    -a \
             ! -f "${PATCHDB}/${patchnum}/save/archive.cpio" -a \
             ! -f "${PATCHDB}/${patchnum}/save/archive.cpio.Z"   ]
        then
            # condition #4 - terminate
            /bin/echo "A previous installation of patch $patchnum was invoked"
            /bin/echo "with the -d option.  (i.e. Do not save files that would"
            /bin/echo "be patched)  Therefore, this invocation of installpatch"
            /bin/echo "must also be run with the -d option."
            exit 17
        fi
    fi
fi

check_if_obsolete "$PATCHDB"

verify_client

check_if_server

check_for_symbolic_link "$patchdir"

trap 'trap_notinstalled "$PATCHDB" "$patchnum"' 1 2 3 15

#
#	If there is a prepatch file in the $patchdir directory,
#	execute it. If the return code is not 0, exit installpatch
#	with an error.
#	Don't re-execute a prepatch script if this is a re-installation
#

if [ "$isapplied" = "no" ]; then
	execute_prepatch "$patchdir"
fi

# -	Generate list of patch packages to be installed
# -	Find out those packages which are already installed on
#	the system
# -	Check to see if there is any work to do
# -	Generate list of files to be installed
# -	Check for validation errors
# -	Generate a list of files to be patched that already exist
# -	Create patch archive and save area

gen_patchpkg_list

#	If this is a re-installation of the patch, remove the already installed
#	packages from the package list. If all packages in the patch have already
#	been applied, then exit.
#

if [ "$isapplied" = "yes" ]; then
	gen_uninstalled_pkgs $PKGDB $PATCHDB $patchnum
fi

check_pkgs_installed "$PKGDB" "$patchdir"

check_for_action "$client" "$is_a_root_pkg"

gen_install_filelist "$PKGDB" "$PKGDBARG"

check_validation "$validate"

gen_patch_filelist

create_archive_area "$PATCHDB" "$patchnum"

trap 'trap_backoutsaved "$PATCHDB" "$patchnum" "$patchdir"' 1 2 3 15

# -	Save current versions of files to be patched
# -	On servers, spool the patch into /export/root/templates for
#	future clients (CURRENTLY DISABLED)
# -	Build admin file for later use by pkgadd

save_overwritten_files "$PATCHDB" "$patchnum" "$patchdir" "$saveold"

spool_client_patch

build_admin_file

trap 'trap_backout "$patchdir" "$patchnum"' 1 2 3 15

# -	Install the patch packages
# -	Print results of install
# -	Save ACTION file if exists, README file and backoutpatch
#	script

install_patch_pkgs "$PATCHDB" "$patchnum" "$patchdir" "$PKGDBARG" "$PKGDB"

execute_postpatch "$PATCHDB" "$patchnum" "$patchdir"

print_results

set_patch_status "$PATCHDB" "$patchnum"

/usr/bin/echo "\nPatch installation completed."
/usr/bin/echo "See $PATCHDB/$patchnum/log for more details."

exit 0
