#!/bin/sh
# This script initializes the backout data for a patch package
# directory format options.
# 
# @(#)SUNWutu.preinstall	1.1   06/09/00     1.1
#
# Copyright (c) 1995 by Sun Microsystems, Inc.
# All rights reserved
#
PATCH_NO_UNDO=false


PATH=/usr/sadm/bin:$PATH
recovery="no"

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=$BUILD_DIR/files/reloc
ROOT_DIR=$BUILD_DIR/files/root
PROTO_FILE=$BUILD_DIR/prototype
ORIGPKGINFO=$PKG_INSTALL_ROOT/var/sadm/pkg/$PKGINST/pkginfo
PKGINFO_FILE=$BUILD_DIR/pkginfo
THIS_DIR=`dirname $0`
INSTALLINGPKGINFO=`dirname $THIS_DIR`

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

	#XXXOld_CommandsXXX#

	exit 0
fi

#
# Unless specifically denied, initialize the backout patch data by
# creating the build directory and copying over the original pkginfo
# which pkgadd saved in case it had to be restored.
#
if [ "$PATCH_NO_UNDO" != "true" ] && [ "$recovery" = "no" ]; then
	if [ -d $BUILD_DIR ]; then
		rm -r $BUILD_DIR
	fi

	# If this is a retry of the same patch then recovery is set to
	# yes. Which means there is a build directory already in
	# place with the correct backout data.

	if [ "$recovery" = "no" ]; then
		mkdir $BUILD_DIR
		mkdir -p $RELOC_DIR
		mkdir $ROOT_DIR
	fi

	#
	# Here we initialize the backout pkginfo file by first
	# copying over the old pkginfo file and then adding the
	# ACTIVE_PATCH parameter so the backout will know what patch
	# it's backing out.
	#
	# NOTE : Within the installation, pkgparam returns the
	# original data.
	#
	pkgparam -v $PKGINST | nawk '
		$1 ~ /PATCHLIST/	{ next; }
		$1 ~ /CLASSES/		{ next; }
		$1 ~ /PATCH_OBSOLETES/	{ next; }
		$1 ~ /ACTIVE_OBSOLETES/	{ next; }
		$1 ~ /SUNW_OBSOLETES/	{ next; }
		$1 ~ /ACTIVE_PATCH/	{ next; }
		$1 ~ /SUNW_PATCHID/	{ next; }
		$1 ~ /UPDATE/		{ next; }
		$1 ~ /SCRIPTS_DIR/	{ next; }
		$1 ~ /PATCH_NO_UNDO/	{ next; }
		$1 ~ /INSTDATE/		{ next; }
		$1 ~ /PKGINST/		{ next; }
		$1 ~ /OAMBASE/		{ next; }
		$1 ~ /PATH/		{ next; }
		{ print; } ' | sed s,\'\"\'\"\',ApOsTrOpHe,g > $PKGINFO_FILE

        # The previous is needed to workaround pkgparam
        # inserting '"'"' for every ' it finds in the
        # pkginfo file. see bugid 4052001.

	# If there is an undo script delivered with this patch pkg
	# there is a possibility that when the patch gets backed out
	# it may not get executed due to the CLASSES macro in the
	# original pkginfo file may not contain the class
	# identifier. Thus we need to merge the old CLASSES macro and
	# the installing patch pkgs CLASSES macro.

	nawk ' $1 ~ /CLASSES/ {print $0} ' $INSTALLINGPKGINFO/pkginfo \
		| sed s/CLASSES=// > /tmp/installingCLASSES.$$
 
	classIDs=`nawk ' $1 ~ /CLASSES/ {print $0} ' $ORIGPKGINFO \
		| sed s/CLASSES=//`
 
	for instClass in $classIDs; do
		notFound=`grep "$instClass" /tmp/installingCLASSES.$$`
		if [ -z "$notFound" ]; then
			newCLASSESlist="$instClass $newCLASSESlist"
		fi
		notFound=""
	done
 
	classes=`nawk ' $1 ~ /CLASSES/ {print $0} ' $ORIGPKGINFO`  
	newCLASSESlist="$classes $newCLASSESlist"  
	
	echo "$newCLASSESlist" >> $PKGINFO_FILE
	echo "ACTIVE_PATCH=$SUNW_PATCHID" >> $PKGINFO_FILE
	echo "ACTIVE_OBSOLETES=$ACTIVE_OBSOLETES" >> $PKGINFO_FILE

	rm /tmp/installingCLASSES.$$

	# And now initialize the backout prototype file with the
	# pkginfo file just formulated.
	echo "i pkginfo" > $PROTO_FILE

	# Copy over the backout scripts including the undo class
	# action scripts
	for script in $SCRIPTS_DIR/*; do
		srcscript=`basename $script`
		targscript=`echo $srcscript | nawk '
			{ script=$0; }
			/u\./ {
				sub("u.", "i.", script);
				print script;
				next;
			}
			/patch_/ {
				sub("patch_", "", script);
				print script;
				next;
			}
			{ print "dont_use" } '`
		if [ "$targscript" = "dont_use" ]; then
			continue
		fi

		echo "i $targscript=$FILE_DIR/$targscript" >> $PROTO_FILE
		cp $SCRIPTS_DIR/$srcscript $FILE_DIR/$targscript
	done

	#
	# Now add entries to the prototype file that won't be passed to
	# class action scripts. If the entry is brand new, add it to the
	# deletes file for the backout package.
	#
	Our_Pkgmap=`dirname $SCRIPTS_DIR`/pkgmap
	BO_Deletes=$FILE_DIR/deletes

	nawk -v basedir=${BASEDIR:-/} '
		BEGIN { count=0; }
		{
			token = $2;
			ftype = $1;
		}
		$1 ~ /[#\!:]/ { next; }
		$1 ~ /[0123456789]/ {
			if ( NF >= 3) {
				token = $3;
				ftype = $2;
			} else {
				next;
			}
		}
		{ if (ftype == "i" || ftype == "e" || ftype == "f" || ftype == "v" || ftype == "d") { next; } }
		{
			equals=match($4, "=")-1;
			if ( equals == -1 ) { print $3, $4; }
			else { print $3, substr($4, 0, equals); }
		}
		' < $Our_Pkgmap | while read class path; do
			#
			# NOTE: If pkgproto is passed a file that is
			# actually a hard link to another file, it
			# will return ftype "f" because the first link
			# in the list (consisting of only one file) is
			# viewed by pkgproto as the source and always
			# gets ftype "f".
			#
			# If this isn't replacing something, then it
			# just goes to the deletes list.
			#
			if valpath -l $path; then
				Chk_Path="$BASEDIR/$path"
				Build_Path="$RELOC_DIR/$path"
				Proto_From="$BASEDIR"
			else	# It's an absolute path
				Chk_Path="$PKG_INSTALL_ROOT$path"
				Build_Path="$ROOT_DIR$path"
				Proto_From="$PKG_INSTALL_ROOT"
			fi

			#
			# Hard links have to be restored as regular files.
			# Unlike the others in this group, an actual
			# object will be required for the pkgmk.
			#
       			if [ -f "$Chk_Path" -a ! -h "$Chk_Path" ] ; then
				mkdir -p `dirname $Build_Path`
				cp -p $Chk_Path $Build_Path
				cd $Proto_From
				pkgproto -c $class "$Build_Path=$path" 1>> $PROTO_FILE 2> /dev/null
				cd $THIS_DIR
			elif [ -h "$Chk_Path" -o \
			     -c "$Chk_Path" -o \
			     -b "$Chk_Path" -o \
			     -p "$Chk_Path" ]; then
				pkgproto -c $class "$Chk_Path" 1>> $PROTO_FILE 2> /dev/null
			else
				echo $path >> $BO_Deletes
			fi
		done
fi

# If additional operations are required for this package, place
# those package-specific commands here.

#XXXSpecial_CommandsXXX#

#############################################################################
#
# IMPORTANT
#
# The first instance of this patch changes the following directories and
# files to links pointing to /tmp/SUNWut/...
#
#	d /var/opt/SUNWut/displays -> /tmp/SUNut/config/displays
#	d /var/opt/SUNWut/idle -> /tmp/SUNut/config/idle
#	d /var/opt/SUNWut/tokens -> /tmp/SUNut/config/tokens
#	f /etc/dt/config/Xservers -> /tmp/SUNut/config/xconfig/Xservers
#	r /etc/dt/config/Xconfig -> /tmp/SUNut/config/xconfig/Xconfig
#
# When removing the patch we need to ensure that we replace these links
# with the original real directories and files if we are the last instance
# being removed
#
#############################################################################

####################################
# Do patch preinstall work
####################################

#
# Part 1
#
# New feature from 108303-02
#
# Move libc_ut.so libs to secure directories (newly created if
# necessary) and make links from old ones
#
unset LD_PRELOAD

LIBDIR=$PKG_INSTALL_DIR/usr/lib
SLIBDIR=$PKG_INSTALL_DIR/usr/lib/secure
WECREATED=

if [ ! -d $SLIBDIR ]
then
	/bin/mkdir -p -m 0755 $SLIBDIR/sparcv9 2> /dev/null
	[ $? = 0 ] && WECREATED=true
fi

for lib in libc_ut.so sparcv9/libc_ut.so
do
	if [ -h $LIBDIR/$lib -a -f $SLIBDIR/$lib ]
	then
		# This is what we want
		continue
	fi

	if [ -f $LIBDIR/$lib -a -d $SLIBDIR ]
	then
		/bin/cp -p $LIBDIR/$lib $SLIBDIR/$lib 2> /dev/null
		if [ $? = 0 ]
		then
			/bin/rm $LIBDIR/$lib
			/bin/ln -s $SLIBDIR/$lib $LIBDIR/$lib
		fi
	fi
done

#
# Part 2
#
# Remove existing session/display instances before adding patch
#
ETCXCONFIG=$PKG_INSTALL_DIR/etc/dt/config/Xconfig
ETCXSERVERS=$PKG_INSTALL_DIR/etc/dt/config/Xservers

for F in $ETCXCONFIG $ETCXSERVERS
do
	[ ! -f "$F" ] && continue
	cp $F /tmp/tmp.$$
	nawk '
		BEGIN { remove_lines=0 }
		/# BEGIN SUNRAY CONFIGURATION/ {
			remove_lines=1;
			print $0
			next
		}
		/# END SUNRAY CONFIGURATION/ { remove_lines=0 }
		remove_lines != 0 { next }
		{ print $0 }
	' /tmp/tmp.$$ > $F
done




####################################
# Build preinstall for patch backout
####################################
cd $FILE_DIR

#
# Part 1
#
# Deals with converting the soft links in /var/opt/SUNWut
# to real directories if this patch was the first instance
# of 108303-XX installed (i.e. on top of FCS release)
#

/bin/ls $PKG_INSTALL_DIR/var/sadm/pkg/SUNWutu/save/108303-?? 2> /dev/null
if [ $? -ne 0 ]; then
	FIRSTINST=0
else
	FIRSTINST=1
fi



if [ $FIRSTINST ]
then
	echo '

DPYDIR=/var/opt/SUNWut/displays
IDLEDIR=/var/opt/SUNWut/idle
TOKDIR=/var/opt/SUNWut/tokens

if [ -h "$DPYDIR" -a -d "$DPYDIR" ]; then
	/bin/rm -f "$DPYDIR"
	/bin/mkdir -m 0750 "$DPYDIR" 2> /dev/null
fi
if [ -h "$IDLEDIR" -a -d "$IDLEDIR" ]; then
	/bin/rm -f $IDLEDIR
	/bin/mkdir -m 0755 "$IDLEDIR" 2> /dev/null
fi
if [ -h "$TOKDIR" -a -d "$TOKDIR" ]; then
	/bin/rm -f $TOKDIR
	/bin/mkdir -m 0700 "$TOKDIR" 2> /dev/null
fi
' > preinstall
fi

#
# Part 2
#
# Removes existing session/display instances before
# removing this patch
#
echo '

if [ -h "'$ETCXCONFIG'" -o -f "'$ETCXCONFIG'" ]; then
	:
else
	echo "#" 				 > '$ETCXCONFIG'
	echo "# SUNWut required parameters:"	>> '$ETCXCONFIG'
	echo "#"				>> '$ETCXCONFIG'
	echo "Dtlogin.pidFile: /var/dt/Xerrors"	>> '$ETCXCONFIG'
	echo "Dtlogin.servers: Xservers"	>> '$ETCXCONFIG'
	echo "Dtlogin*startup: Xstartup"	>> '$ETCXCONFIG'
	echo "Dtlogin*setup:   Xsetup"		>> '$ETCXCONFIG'
fi

for F in '$ETCXCONFIG' '$ETCXSERVERS'
do
	[ ! -f "$F" -a ! -h "$F" ] && continue
	/bin/cp $F /tmp/tmp.$$ 2> /dev/null
' >> preinstall


# NOTE: By deleting whatever is there (file or link we ensure a file
# (and not a link) is created further on. This is what we want if
# this has been the first installed instance of this patch. See note
# above for more details
if [ $FIRSTINST ]
then
	echo '
	rm -f $F
' >> preinstall
fi

echo '
	/bin/nawk ' "'" '
		BEGIN { remove_lines=0 }
		/# BEGIN SUNRAY CONFIGURATION/ {
			remove_lines=1;
			print $0
			next
		}
		/# END SUNRAY CONFIGURATION/ { remove_lines=0 }
		remove_lines != 0 { next }
		{ print $0 }
	' "'" ' /tmp/tmp.$$ > $F
done
rm -f /tmp/tmp.$$

' >> preinstall

#
# Part 3
#
# Do this if:
#	(a) we are 108303-02 (where this feature was introduced)
#	(b) and/or we are the last instance installed
#
# Moves the libc_ut.so libraries (32bit and 64bit)
# versions back to their original locations. Should
# try to remove /usr/lib/secure if we created it.
#
if [ $FIRSTINST -o $SUNW_PATCHID = "108303-02" ]
then
	echo '

LIBDIR=/usr/lib
SLIBDIR=/usr/lib/secure

for lib in libc_ut.so sparcv9/libc_ut.so
do
	if [ -f $SLIBDIR/$lib ]
	then
		/bin/rm -f $LIBDIR/$lib
		/bin/cp -p $SLIBDIR/$lib $LIBDIR/$lib
		/bin/rm -f $SLIBDIR/$lib
	fi
done
' >> preinstall
fi

if [ "$WECREATED" = "true" ]
then
	 echo '

/bin/rmdir $SLIBDIR/sparcv9 2> /dev/null
/bin/rmdir $SLIBDIR 2> /dev/null
' >> preinstall
fi

		
echo 'exit 0' >> preinstall

#
# Part 4
# 
# Construct the actual prototype file entry.
#
echo "i preinstall=$FILE_DIR/preinstall" >> $PROTO_FILE

rm -f /tmp/tmp.$$

exit 0
