# This class action script copies the files being replaced
# into a package being constructed in $BUILD_DIR. This class
# action script is only appropriate for regular files that
# are installed by simply copying them into place.
#
# For special package objects such as edittable files, the patch
# producer must supply appropriate class action scripts.
#
# directory format options.
#
#       @(#)i.script 1.14 01/04/09 SMI
#
# Copyright (c) 1995 by Sun Microsystems, Inc.
# All rights reserved
#

change_from_to()
{
	d="$1"
	old="$2"
	new="$3"

	sed -e "s/$2/$3/" $d > /tmp/tmp.$$
	cp /tmp/tmp.$$ $dst

	# clean up
	rm -f /tmp/*.$$
}

#
# update_action_line:
#
# takes three params:
#	1. dest file name;
#	2. new line to after last 'action ...' line;
#	3. old line to delete;
#
# algorithm:
#	if the "$new" line is already in the file "$d", then return, else
#	find the line number of the last "action ..." line in the "$d" file
#	add the supplied "$new" line after the current last "action ..." line
#	if the "$old" line is in the file, remove it
#
update_action_line()
{

	d="$1"
	new="$2"
	old="$3"

	# check for the "$new line"
	if fgrep "$new" $d >/dev/null 2>&1 ; then
		return		# no work needs to be done
	fi

	# find last '^action ...' line
	line_no="`grep -n '^action' $d|tail -1|awk -F: '{print $1}'`"

	# add new line after last '^action ...' line
	sed -e "$line_no a\\
$new" $d > /tmp/tmp.$$

	# copy temp file back to dest file, removing old line (if present)
	grep -v "^$old" /tmp/tmp.$$ > $d
}

update_ufs_ident_line()
{
        d="$1"

        # get the line and check if up to date
        if grep '^ident ufs .* rmdisk' $d >/dev/null 2>&1 ; then
                :
        else
                #edit ident ufs line
                sed -e '/^ident ufs ident_ufs/ s/$/ rmdisk/' \
                        $dst >/tmp/tmp.$$
                cp /tmp/tmp.$$ $dst

                # clean up
                rm -f /tmp/*.$$
        fi
}

update_pcfs_ident_line()
{
        d="$1"

        # check for the "$new line"
        if grep '^ident pcfs .* rmdisk' $d >/dev/null 2>&1 ; then
                :
        else
                #edit ident pcfs line
                sed -e '/^ident pcfs ident_pcfs/ s/$/ rmdisk/' \
                        $dst >/tmp/tmp.$$
                cp /tmp/tmp.$$ $dst

                # clean up
                rm -f /tmp/*.$$
        fi
}

add_udfs_ident_line()
{
	d="$1"
	new="$2"

	if grep '^ident udfs .* rmdisk' $d >/dev/null 2>&1 ; then
		:
	elif grep '^ident udfs' $d >/dev/null 2>&1 ; then
		# edit ident udfs line
                sed -e '/^ident udfs ident_udfs/ s/$/ rmdisk/' \
                       	$dst >/tmp/tmp.$$
		cp /tmp/tmp.$$ $dst
	else
		# find last '^ident ...' line
		line_no="`grep -n '^ident' $d|tail -1|awk -F: '{print $1}'`"

		# add new line after last '^ident ...' line
		sed -e "$line_no a\\
$new" $d > /tmp/tmp.$$
		cp /tmp/tmp.$$ $dst
	fi

	# clean up
	rm -f /tmp/*.$$
}

update_mount_line()
{

	d="$1"
	new="mount * hsfs udfs ufs -o nosuid"
	file="/tmp/tmp.$$"
	flag=0

	# check for the "new" line
	if fgrep "$new" $d >/dev/null 2>&1 ; then
		flag=1
	fi

nawk '

/^#/ {

	# Comment Line
	print;
	next
}

/^mount/ {

	# Mount Line

	pcfs_flag=0

	if ( match($0, /pcfs/) > 0 ) {
		if ( match($0, /[       ](ufs|udfs|hsfs)/) <= 0 ) {
			print;
			next
		}
		else {
			pcfs_flag=1;
		}
	}
	if ( match($0, /(nosuid|suid)/) > 0 ){
		print;
		next
	}
	else {
		if ( match($0, /-o/) > 0) {
			pos = index($0, "-o");
			string = substr($0, pos);
			if (pcfs_flag == 1) {
				print $1" " $2" " "pcfs " string;
				sub(/pcfs[      ]*/, "");
			}
			sub(/-o[        ]/, "-o nosuid,");
			print;
			next
		}
	}
}

{
	#Lines other than comment lines and those for mount options.
	print;
	next
}' $d > $file

if [ $flag -eq 0 ]
then
	echo "" >> $file
	echo "$new" >> $file
	cat $file > $d
else
	cat $file > $d
fi

# Clean-up
rm -f $file

}

PATH=/usr/sadm/bin:$PATH
PATH="/usr/bin:/usr/sbin:${PATH}"

ECHO="/usr/bin/echo"
SED="/usr/bin/sed"
PKGPROTO="/usr/bin/pkgproto"
EXPR="/usr/bin/expr"	# used by dirname
MKDIR="/usr/bin/mkdir"
CP="/usr/bin/cp"
RM="/usr/bin/rm"
MV="/usr/bin/mv"
KSH="/usr/bin/ksh"

recovery="no"
Pn=$$
procIdCtr=0

CMDS_USED="$KSH $ECHO $SED $PKGPROTO $EXPR $MKDIR $CP $RM $MV"
LIBS_USED=""

if [ "$PKG_INSTALL_ROOT" = "/" ]; then
	PKG_INSTALL_ROOT=""
fi

# Check to see if this is a patch installation retry.
if [ "$INTERRUPTION" = "yes" ]; then
	if [ -d "$PKG_INSTALL_ROOT/var/tmp/$SUNW_PATCHID.$PKGINST" ] || [ -d "$PATCH_BUILD_DIR/$SUNW_PATCHID.$PKGINST" ]; then
		recovery="yes"
	fi
fi

if [ -n "$PATCH_BUILD_DIR" -a -d "$PATCH_BUILD_DIR" ]; then
	BUILD_DIR="$PATCH_BUILD_DIR/$SUNW_PATCHID.$PKGINST"
else
	BUILD_DIR="$PKG_INSTALL_ROOT/var/tmp/$SUNW_PATCHID.$PKGINST"
fi

FILE_DIR=$BUILD_DIR/files
RELOC_DIR=$FILE_DIR/reloc
ROOT_DIR=$FILE_DIR/root
BO_Deletes=$FILE_DIR/deletes
PROGNAME=`basename $0`

if [ "$PATCH_PROGRESSIVE" = "true" ]; then
	PATCH_NO_UNDO="true"
fi

# Since this is generic, figure out the class.
Class=`echo $PROGNAME | nawk ' { print substr($0, 3)  }'`

# Since this is an update, $BASEDIR is guaranteed to be correct
BD=${BASEDIR:-/}

cd $BD

#
# First, figure out the dynamic libraries that can trip us up.
#
if [ -z "$PKG_INSTALL_ROOT" ]; then
	if [ -x /usr/bin/ldd ]; then
		LIB_LIST=`/usr/bin/ldd $CMDS_USED | sort -u | nawk '
			$1 ~ /\// { continue; }
			{ printf "%s ", $3 } '`
	else
		LIB_LIST="/usr/lib/libc.so.1 /usr/lib/libdl.so.1 /usr/lib/libw.so.1 /usr/lib/libintl.so.1 /usr/lib/libgen.so.1 /usr/lib/libadm.so.1 /usr/lib/libelf.so.1"
	fi
fi

#
# Now read the list of files in this class to be replaced. If the file
# is already in place, then this is a change and we need to copy it
# over to the build directory if undo is allowed. If it's a new entry
# (No $dst), then it goes in the deletes file for the backout package.
#

LD_LIB_DIR=$PKG_INSTALL_ROOT/var/tmp/LDLIB.$$

procIdCtr=0
while read src dst; do
	if [ "$PATCH_PROGRESSIVE" = "true" ]; then
		# If this is being used in an old-style patch, insert
		# the old-style script commands here.

		#XXXOld_CommandsXXX#
		echo >/dev/null	# dummy
	fi

	if [ "${PATCH_NO_UNDO}" != "true" ]; then
		#
		# Here we construct the path to the appropriate source
		# tree for the build. First we try to strip BASEDIR. If
		# there's no BASEDIR in the path, we presume that it is
		# absolute and construct the target as an absolute path
		# by stripping PKG_INSTALL_ROOT. FS_Path is the path to
		# the file on the file system (for deletion purposes).
		# Build_Path is the path to the object in the build
		# environment.
		#
		# The following rootPath variable accounts for a BASEDIR
		# that is used as a regular variable within the path and
		# not as a variable that a path needs to be relocated to.

		rootPath=`$ECHO $src | $SED s@"$INST_DATADIR/$PKGINST"@@ | \
			nawk -F/ '{print $2}'`
		if [ "$rootPath" = "root" ]; then
			FS_Path=$dst
		elif [ "$BD" = "/" ]; then
			FS_Path=`$ECHO $dst | $SED s@"$BD"@@`
		else
			FS_Path=`$ECHO $dst | $SED "s|$BD/||"`
		fi

		# If it's an absolute path the attempt to strip the
		# BASEDIR will have failed.
		if [ "$dst" = "$FS_Path" ]; then
			if [ -z "$PKG_INSTALL_ROOT" ]; then
				FS_Path=$dst
				Build_Path="$ROOT_DIR$dst"
			else
				Build_Path="$ROOT_DIR"`echo $dst | \
				    $SED "s|$PKG_INSTALL_ROOT||"`
				FS_Path=`echo $dst | \
				    $SED "s|$PKG_INSTALL_ROOT||"`
			fi
		else
			Build_Path="$RELOC_DIR/$FS_Path"
		fi

		if [ -f "$dst" ]; then	# If this is replacing something
			cd $FILE_DIR
			#
			# Construct the prototype file entry. We replace
			# the pointer to the filesystem object with the
			# build directory object.
			#
			echo "e rmmconf $FS_Path=$Build_Path ? ? ?" >> \
				$BUILD_DIR/prototype
			# Now copy over the file
			if [ "$recovery" = "no" ]; then
				DirName=`dirname $Build_Path`
				$MKDIR -p $DirName
				$CP -p $dst $Build_Path
			else
				# If this file is already in the build area skip it
				if [ -f "$Build_Path" ]; then
					cd $BD
					continue
				else
					DirName=`dirname $Build_Path`
					if [ ! -d "$DirName" ]; then
						$MKDIR -p $DirName
					fi
					$CP -p $dst $Build_Path
				fi
			fi

			cd $BD
		else	# It's brand new
			$ECHO $FS_Path >> $BO_Deletes
		fi
	fi

	# If special processing is required for each src/dst pair,
	# add that here.
	#
	#XXXSpecial_CommandsXXX#
	#
	if [ ! -f $dst ] ; then
		cp $src $dst
	else
		# save the 'ident' line from the 'new' file
		grep '@(#)rmmount.conf' $src \
		    > /tmp/newident.$$ 2>/dev/null

		# save all but the 'ident' line from the old (orig) file
		grep -v '@(#)rmmount.conf' $dst \
		    > /tmp/rest.$$ 2>/dev/null

		# concatenate the new ident and the old data, replacing old
		cat /tmp/newident.$$ /tmp/rest.$$ > $dst

		# catch all just replace rmscsi with rmdisk everwhere
		# in action as well as any other file systems added
		change_from_to $dst rmscsi rmdisk

		# get the new 'action rmdisk ...' line
		new_action_line="`grep '^action rmdisk action_filemgr' $src`"

		# ensure that default rmdisk line is up to date
		update_action_line $dst "$new_action_line" \
		    '# there is no old action line to remove'

                # ensure that default rmdisk line is up to date
                update_ufs_ident_line $dst 
                update_pcfs_ident_line $dst
		add_udfs_ident_line $dst \
			"ident udfs ident_udfs.so cdrom floppy rmdisk"

		# ensure that safe mount line is added
		update_mount_line $dst

		# restore permissions if they changed
		chmod 0444 $dst
		chgrp bin $dst
	fi
done
 
# If additional operations are required for this package, place
# those package-specific commands here.

#XXXSpecial_CommandsXXX#

exit 0
