# This script creates the backout package for a patch package
#
# directory format options.
#
#pragma ident	"@(#)postinstall	1.32	11/02/03 SMI"
#
# Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
#

# Definitions for override safety mechanism
PATCH_OVERRIDE_LIB="${PKG_INSTALL_ROOT}/usr/lib/patch/patch_override_lib"

# Check if we messaging is ready. Returns 0 on success, 1 on failure
# On successful run it leaves MSG_FILENAME variable defined
# 
# Usage:
#
# check_patch_script_messaging
#
check_patch_script_messaging()
{
	TMP_DIRNAME="/var/run"
	MSG_FILENAME="${TMP_DIRNAME}/patchadd_msg_file_${SUNW_PATCHID}"

	if [ -w "${MSG_FILENAME}" ] ; then
		unset TMP_DIRNAME
		return 0
	else
		unset TMP_DIRNAME
		unset MSG_FILENAME
		return 1
	fi
}

# This function prepares a message to be printed to stdout towards the end
# of postpatch execution. If the message file is not ready, it at least tries
# immediate output to stdout which is currently know to work only in patch
# level scripts.
#
# Usage:
#
# print_patch_message "text_of_message_to_be_printed_out"
#
print_patch_message()
{
	if check_patch_script_messaging; then
		echo "$*" >> "${MSG_FILENAME}"
	else
		echo "$*"
	fi

	return 0
}

# script in a fucntion so that it can be overridden if needed - generic
postinstall_deflt()
{
	# Description:
	#       Set the TYPE parameter for the remote file
	#
	# Parameters:
	#       none
	#
	# Globals set:
	#	TYPE
	#

	set_TYPE_parameter () {
		if [ ${PATCH_UNDO_ARCHIVE:?????} = "/dev" ]; then
			# handle device specific stuff
			TYPE="removable"
		else
			TYPE="filesystem"
		fi
	}

	#
	# Description:
	#       Build the remote file that points to the backout data
	#
	# Parameters:
	#       $1:	the un/compressed undo archive
	#
	# Globals set:
	#	UNDO, STATE

	build_remote_file () {
		remote_path=$PKGSAV/$SUNW_PATCHID/remote
		set_TYPE_parameter
		STATE="active"

		if [ $1 = "undo" ]; then
			UNDO="undo"
		else
			UNDO="undo.Z"
		fi

		cat > $remote_path <<- EOF
	# Backout data stored remotely
	TYPE=$TYPE
	FIND_AT=$ARCHIVE_DIR/$UNDO
	STATE=$STATE
	EOF
	}

	SED="/usr/bin/sed"
	CP="/usr/bin/cp"
	RM="/usr/bin/rm -f"
	MV="/usr/bin/mv"
	EXPR="/usr/bin/expr"
	RMF="/usr/sbin/removef"
	XARGS="/usr/bin/xargs"
	NAWK="/usr/bin/nawk"
	POSTINSTALL_ERR_LOG="$PKG_INSTALL_ROOT/var/run/$SUNW_PATCHID.postinstall_log.$$"
	RET_STATUS=0

	PATH=/usr/sadm/bin:$PATH
	PATCH_COMMON_LIB="/usr/lib/patch/patch_common_lib"
	SAFEMODE_FAILED="Exiting! Patch deferred activation failed"

	# Set LC_ALL to avoid risk of undefined behavior
	LC_ALL=C
	export LC_ALL

	if [ "$SAFEMODE_INSTALL" = "true" ] ; then
		if [ ! -s "$PATCH_COMMON_LIB" ]; then
			puttext "$SAFEMODE_FAILED"
			exit 1
		fi
		. $PATCH_COMMON_LIB
		InitSafemode || {
			puttext $SAFEMODE_FAILED
			exit 1
		}
	fi

	if [ "$PKG_INSTALL_ROOT" = "/" ]; then
		PKG_INSTALL_ROOT=""
	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

	if [ ! -n "$PATCH_UNDO_ARCHIVE" ]; then
		PATCH_UNDO_ARCHIVE="none"
	fi

	FILE_DIR=$BUILD_DIR/files
	RELOC_DIR=$FILE_DIR/reloc
	ROOT_DIR=$FILE_DIR/root
	BO_Deletes=$FILE_DIR/deletes
	THIS_DIR=`dirname $0`
	PROTO_FILE=$BUILD_DIR/prototype
	TEMP_REMOTE=$PKGSAV/$SUNW_PATCHID/temp

	# If patch includes pkg_* scripts, deliver them into the pspool area
	#
	PKGDB="/var/sadm/pkg/$PKGINST"
	PSPOOL_PKG="$PKGDB/save/pspool/$PKGINST"


	for script in $SCRIPTS_DIR/*; do
		srcscript=`basename $script`
		targscript=`echo $srcscript | $NAWK '
			/^pkg_/ {
				print "pspool";
				next;
			}
			{ print "dont_use" } '`
		if [ "$targscript" = "dont_use" ]; then
			continue
		fi
		if [ "$targscript" = "pspool" ]; then
			# If the target script is a pspool script, then we need
			# to do the following:
			#	1) If the script is delivered for the first time
			#	   then add it to the deletes file of the undo
			#	   package.
			#	2) Else backup the script in the undo package,
			#	   replace the script and update the undo packag
			#	   prototype file.
			script=`echo $srcscript | $SED 's/pkg_//'`
			if [ -d "$PKG_INSTALL_ROOT$PSPOOL_PKG/install" ] ; then
				# We are delivering script into pspool area
				[ "$PATCH_NO_UNDO" != "true" ] && {
					if [ -f "$PKG_INSTALL_ROOT$PSPOOL_PKG/install/$script" ]; then
						$MV $PKG_INSTALL_ROOT$PSPOOL_PKG/install/$script $FILE_DIR/$srcscript
						echo "i $srcscript=$FILE_DIR/$srcscript" >> $PROTO_FILE
					else
						echo "$PSPOOL_PKG/install/$script" >> $BO_Deletes
					fi
				}
				$CP $SCRIPTS_DIR/$srcscript $PKG_INSTALL_ROOT$PSPOOL_PKG/install/$script
			fi
			if [ -d "$PKG_INSTALL_ROOT$PKGDB/install" ] ; then
				# If patch delivers pkg_* scripts which is pkgrm relevant
				# deliver them also into /var/sadm/install/pkg/<pkg>/install
				scripttype=`echo $srcscript | $NAWK '
					/^pkg_preremove$|^pkg_postremove$|^pkg_r\./ {
						print "pkgremove";
						next;
					}
					{ print "dont_use" } '`

				if [ "$scripttype" = "pkgremove" ] ; then
					[ "$PATCH_NO_UNDO" != "true" ] && {
					if [ -f "$PKG_INSTALL_ROOT$PKGDB/install/$script" ]; then
						# Due to previously existing bug scripts could be different
						# in /var/sadm/pkg/<pkg>/install and
						# /var/sadm/pkg/<pkg>/save/pspool/<pkg>/install
						# After backout we will go back to the exactly same state
						# Because of that we create pkgrm_* file in backout package
						$MV $PKG_INSTALL_ROOT$PKGDB/install/$script $FILE_DIR/pkgrm_$script
						echo "i pkgrm_$script=$FILE_DIR/pkgrm_$script" >> $PROTO_FILE
					else
						echo "$PKGDB/install/$script" >> $BO_Deletes
					fi
					}
					$CP $SCRIPTS_DIR/$srcscript $PKG_INSTALL_ROOT$PKGDB/install/$script
				fi
			fi
		fi
	done
	
	#
	# At this point we either have a deletes file or we don't. If we do,
	# we create a prototype entry.
	#
	if [ -f $BO_Deletes ]; then
		echo "i deletes=$BO_Deletes" >> $BUILD_DIR/prototype
	fi

	if [ -f $BUILD_DIR/pkginfo ] ; then
		/usr/bin/grep "^SUNW_PATCH_SAFE_MODE=" $SCRIPTS_DIR/../pkginfo >> \
		    $BUILD_DIR/pkginfo
	fi 

	#
	# Now delete everything in the deletes list after transferring
	# the file to the backout package and the entry to the prototype
	# file. Remember that the pkgmap will get the CLIENT_BASEDIR path
	# but we have to actually get at it using the BASEDIR path. Also
	# remember that removef will import our PKG_INSTALL_ROOT
	#
	# If this is a safemode patch package and it has a deletes file in it
	# then handle the deletion of an object for safemode patching.
	#
	Our_Deletes=$THIS_DIR/deletes
	if [ -f $Our_Deletes ]; then
		PSPOOL_DIR="/var/sadm/pkg/$PKGINST/save/pspool/$PKGINST/install"
		UNREGISTER_LIST=/var/run/.$$.unregister.paths.$$
		UNREGISTER_BATCH=/var/run/.$$.unregister.batch.$$
		$RM $UNREGISTER_LIST

		cd $BASEDIR
		cat $Our_Deletes | while read path; do
			# If this patch is deleting any pspool script, then the
			# deleted file would have any entry for the script
			# relative to the PKG_INSTALL_ROOT. We have to parse it
			# and process it as follows.
			#	1) build the complete path.
			#	2) move the file to undo package.
			#	3) Add it to the prototype file of undo package.
			Dir=`/usr/bin/dirname "$path"`
			if [ "$Dir" = "$PSPOOL_DIR" ]; then
				path="${PKG_INSTALL_ROOT:-/}$path"
				if [ -f "$path" ]; then
					filename=`/usr/bin/basename "$path"`
					spoolname="pkg_$filename"
					spoolfile="$FILE_DIR/$spoolname"
					mv -f "$path" "$spoolfile"
					echo "i $spoolname=$spoolfile" >> $BUILD_DIR/prototype
				fi
				continue;
			fi
			Reg_File=0
			# Checking whether path is absolute or relative
			if echo "$path" | grep '^/' 2>&1 1>/dev/null ; then
				# It's an absolute path
				Client_Path=$path
				Build_Path="$ROOT_DIR$path"
				Proto_Path=$PKG_INSTALL_ROOT$path
			else
				Client_Path="$CLIENT_BASEDIR/$path"
				Build_Path="$RELOC_DIR/$path"
				Proto_Path=$BASEDIR/$path
			fi

			# If BASEDIR/CLIENTBASEDIR = "/", then the previous prepends
			# an extra / i.e. //. The sed command later can't find a
			# Proto_Path with // and therefore will not substitute the
			# correct build_Path resulting in the backout pkg not being
			# created.

			if [ "$CLIENT_BASEDIR" = "/" ]; then
				Client_Path=`echo "$Client_Path" | $SED 's|^\/\/|\/|'`
				Proto_Path=`echo "$Proto_Path" | $SED 's|^\/\/|\/|'`
			fi
				
			# Note: If the file isn't really there, pkgproto
			# doesn't write anything but displays an error
			# so check for the file before processing.

			if [ -f "$Proto_Path" ]; then
				LINE=`pkgproto "$Proto_Path=$path"`
			else
				continue
			fi

			ftype=`echo "$LINE" | $NAWK '{ print $1 }'`
			if [ "$ftype" = "f" ]; then
				Reg_File=1
			fi

			if [ $Reg_File = 1 ]; then
				# Add source file to the prototype entry
                                # nawk is used here instead of sed because sed
                                # allows only substitution of RE (regular 
                                # expressions) and we can't be sure that $dst
                                # will not contain special characters 

				LINE=`echo "$LINE" | $NAWK -v \
				    Proto_Path="$Proto_Path" -v \
				    Build_Path="$Build_Path" -v path="$path" '
        				{ 
                    			ind = index($3,Proto_Path);
                    			if (ind == 0) {
                        			print $0;
                        			next;
                    			}
                    			len = length(Proto_Path);
                    			if (Proto_Path == path) {
                        			ind2 = index(substr($3,ind+len),Proto_Path);
                        			if (ind2 == 0) {
                                			print $0;
                                			next;
                        			}
                        			ind = ind + len + ind2 - 1;     
                    			}
                    			rec = substr($3,1,ind-1) Build_Path substr($3,ind+len);
					$3 = rec;
					print $0;
                  			}
				'`
				DirName=`dirname "$Build_Path"`
				# make room in the build tree
				mkdir -p "$DirName"
				$CP -p "$Proto_Path" "$Build_Path"
			fi

			# Insert it into the prototype file
			echo "$LINE" 1>>$PROTO_FILE 2>/dev/null
			echo "$Client_Path" >> $UNREGISTER_LIST
		done

		if [ -s "$UNREGISTER_LIST" ]; then
			if [ "$SAFEMODE_INSTALL" = "true" ]; then
				# We need to group the deletes entries for
				# performance reasons. Only 100 entries are
				# taken in a single batch, since we don't want
				# to exceed the number of arguments passed
				# during removef program invocation, and 100
				#  seems to a good tradeoff.

				batch_start_line=1
				batch_end_line=100

				while true ; do
					/usr/bin/sed -n "$batch_start_line,$batch_end_line p" $UNREGISTER_LIST > $UNREGISTER_BATCH
					[ -s $UNREGISTER_BATCH ] || break

					# Handle deletion of an object for
					# safemode patching
					# We do not use xargs here because xargs
					# can't handle shell function calls
	
					HandleSafemodeDeleteObject $PKGINST "`/usr/bin/tr '\n' ' ' < $UNREGISTER_BATCH`"

					batch_start_line=`$EXPR $batch_start_line + 100`
					batch_end_line=`$EXPR $batch_end_line + 100`
				done
			else
				# Remove the file only if it's OK'd by removef
				# We don't need to group deletes entries here
				# because xargs does it for us

				$XARGS $RMF $PKGINST < $UNREGISTER_LIST | \
				while read path; do
					$RM "$path"
				done
			fi
			$RMF -f $PKGINST
		fi
		$RM $UNREGISTER_LIST $UNREGISTER_BATCH

		$RM $Our_Deletes
	fi

	#
	# Unless specifically denied, make the backout package.
	#
	if [ "$PATCH_NO_UNDO" != "true" ]; then
		cd $BUILD_DIR	# We have to build from here.

		if [ "$PATCH_UNDO_ARCHIVE" != "none" ]; then
			STAGE_DIR="$PATCH_UNDO_ARCHIVE"
			ARCHIVE_DIR="$PATCH_UNDO_ARCHIVE/$SUNW_PATCHID/$PKGINST"
			mkdir -p $ARCHIVE_DIR
			mkdir -p $PKGSAV/$SUNW_PATCHID
		else
			if [ -d $PKGSAV/$SUNW_PATCHID ]; then
				rm -r $PKGSAV/$SUNW_PATCHID
			fi
			STAGE_DIR=$PKGSAV
			ARCHIVE_DIR=$PKGSAV/$SUNW_PATCHID
			mkdir $ARCHIVE_DIR
		fi

		ERR_LOG_DIR=`dirname $POSTINSTALL_ERR_LOG`
		if [ ! -d $ERR_LOG_DIR ]; then
			mkdir -p $ERR_LOG_DIR
		fi

		/usr/bin/pkgmk -o -d $STAGE_DIR 1>$POSTINSTALL_ERR_LOG 2>&1
		retcode=$?
		if [ "$retcode" != 0 ]; then
			echo "pkgmk(1) failed with error code $retcode" >> $POSTINSTALL_ERR_LOG
			echo "The $PKGINST backout package will not get created" >> $POSTINSTALL_ERR_LOG
			RET_STATUS=1
		else
			# Save current mask value using Bourne shell umask
			MASK=`umask`
			# undo package should be readable only for root
			umask 077
			/usr/bin/pkgtrans -s $STAGE_DIR $ARCHIVE_DIR/undo $PKG 1>>$POSTINSTALL_ERR_LOG 2>&1
			retcode=$?
			# set umask back to original value
			umask $MASK
			if [ "$retcode" != 0 ]; then
				echo "pkgtrans(1) failed with error code $retcode" >> $POSTINSTALL_ERR_LOG
				echo "The $PKGINST backout package will not get created" >> $POSTINSTALL_ERR_LOG
				RET_STATUS=1
			else
				compress $ARCHIVE_DIR/undo
				retcode=$?
				if [ "$retcode" != 0 ]; then
					echo "compress(1) returned error code $retcode"
					echo "The $PKGINST backout package will not be compressed."
					echo "Continuing to process backout package."
				fi
				if [ "$PATCH_UNDO_ARCHIVE" != "none" ]; then
					if [ $retcode != 0 ]; then
						build_remote_file "undo"
					else
						build_remote_file "undo.Z"
					fi
				fi
			fi
		fi

		$RM -r $STAGE_DIR/$PKG

		cd ..
		$RM -r $BUILD_DIR
	fi

	# remove the scripts that are left behind
	install_scripts=`dirname $0`
	$RM $install_scripts/checkinstall $install_scripts/patch_* \
	    $install_scripts/pkg_* $install_scripts/u.* $install_scripts/i.*

	#
	# Since this apparently worked, we'll mark as obsoleted the prior
	# versions of this patch - installpatch deals with explicit obsoletions.
	#
	cd ${PKG_INSTALL_ROOT:-/}
	cd var/sadm/pkg

	active_base=`echo $SUNW_PATCHID | $NAWK '
		{ print substr($0, 1, match($0, "-")-1) } '`

	List=`ls -d $PKGINST/save/${active_base}* 2>/dev/null`
	if [ $? -ne 0 ]; then
		List=""
	fi

	for savedir in $List; do
	        patch=`basename $savedir` 
	        if [ $patch = $SUNW_PATCHID ]; then
			break
		fi

	        # If we get here then the previous patch gets deleted
		if [ -f $savedir/undo ]; then
			$MV $savedir/undo $savedir/obsolete
			echo $SUNW_PATCHID >> $savedir/obsoleted_by
		elif [ -f $savedir/undo.Z ]; then
			$MV $savedir/undo.Z $savedir/obsolete.Z
			echo $SUNW_PATCHID >> $savedir/obsoleted_by
	        elif  [ -f $savedir/remote ]; then
	                `grep . $PKGSAV/$patch/remote | sed 's|STATE=.*|STATE=obsolete|' > $TEMP_REMOTE` 
	                $RM $PKGSAV/$patch/remote 
	                $MV $TEMP_REMOTE $PKGSAV/$patch/remote  
	                $RM $TEMP_REMOTE 
	                echo $SUNW_PATCHID >> $savedir/obsoleted_by
		elif  [ -f $savedir/obsolete -o -f $savedir/obsolete.Z ]; then
			echo $SUNW_PATCHID >> $savedir/obsoleted_by
		fi
	done

	if [ "$RET_STATUS" != 0 ]; then
		cat $POSTINSTALL_ERR_LOG
		echo "Execution of postinstall encountered problems"
		echo "postinstall exited with 1"
		$RM $POSTINSTALL_ERR_LOG
		exit $RET_STATUS
	else
		$RM $POSTINSTALL_ERR_LOG
	fi
}

# script in a fucntion so that it can be overridden if needed - particular
postinstall_merge()
{
	# If additional operations are required for this package, place
	# those package-specific commands here.

	#XXXSpecial_CommandsXXX#
#!/bin/sh
#
# Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
#
#ident	"@(#)postinstall	1.7	14/03/10 SMI"
#

# This postinstall script updates BIND SMF properties and completes
# any other tasks required to install BIND.  The script is used during
# pkgadd and also during patch installation - the contents are copied
# into patch scripts; changes to this file should be notified to patch
# folks in RTI if the patch script also needs updating.
#
# This script creates another script that then updates SMF and applies
# any necessary commands.  It is written this way to accommodate being
# run for an alternative root file system, such as when pkgadd or
# patchadd '-R root_path' option is used.  When '-R' is used the
# environment variable PKG_INSTALL_ROOT is set to the alternative
# root.  SMF commands at this time can only write to local repository
# and hence can only be executed when the alternative root is active.
# For this purpose contracted interface file
# ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade is updated with the
# commands necessary to be run during reboot.
#
# To prevent unnecessary reboot when the package or patch is installed
# to local root a unique temporary directory is used, if its not
# possible to create the temporary directory then the update file is
# used.
#
# Note: var/svc/profile/upgrade is a shared interface, commands may be
# been inserted before we have run and indeed more commands may be
# written afterwards, therefore we must be careful not to write
# inappropriate exit or return statements to it!

#
# Delete obsolete property groups from the repository.
#
smf_obs_pg() {
	service=$1
	property_group=$2

	cat >> $UPGRADE <<-EOF

	if svcprop -q -p $property_group $service; then
		svccfg -s $service delpg $property_group
	fi
	EOF
}

# Private SMF contracted interface file executed on reboot to apply settings.
UPGRADE=${PKG_INSTALL_ROOT}/var/svc/profile/upgrade
upgrade_on='reboot'

if [ -z "$PKG_INSTALL_ROOT" -o "$PKG_INSTALL_ROOT" = "/" ]; then
    PKG_INSTALL_ROOT=""
    # Create a safe directory for this script and for UPGRADE script to use.
    DNSTMP=`mktemp -d`
    if [ $? -eq 0 -a -n "$DNSTMP" ]; then
	# mktemp worked.  Install to root using unique temporary directory.
	UPGRADE="${DNSTMP}/BIND_UPGRADE"
	upgrade_on='now'
	echo "DNSTMP=$DNSTMP" > $UPGRADE
    else
	# This should not happen!
	echo 'mktemp failed!  BIND changes will be applied at reboot'>&2
	# SMF upgrade may already exist, reset DNSTMP.
        echo 'DNSTMP=""' >> $UPGRADE
    fi
else
    # SMF upgrade may already exist, reset DNSTMP.
    echo 'DNSTMP=""' >> $UPGRADE
fi

# BIND 9.3.4 integration introduces a smf_method(5) start script,
# option properties and removes the configuration file dependency.
# Each instance has to be upgraded to use the script instead of
# executing named(1M) directly.
cat >> $UPGRADE <<-\_UPDATE_START_METHOD
	oset=$@ # Remember current options if any.
	svc="svc:network/dns/server"
	if [ -z "$DNSTMP" ]; then
	    # Temporary directory used following a reboot.
	    #pragma PRC test_FIO43_C_CERT ignore-next-line
	    DNSTMP=`mktemp -d` || DNSTMP="/tmp"
	fi

	# fupdate is a dynamically created script which is used to
	# update the repository after the manifest is imported.
	fupdate="$DNSTMP/BIND_UPDATE"
	rm -f $fupdate

	# fdefault is a svccfg(1m) input file that adds new properties
	# to each instance.
	fdefault=$DNSTMP/BIND_OPTIONS
	echo 'addpg options application' > $fdefault
	echo 'setprop options/chroot_dir = astring: ("")' >> $fdefault
	echo 'setprop options/configuration_file = astring: ("")' >> $fdefault
	echo 'setprop options/debug_level = integer: ("0")' >> $fdefault
	echo 'setprop options/ip_interfaces = astring: ("all")' >> $fdefault
	echo 'setprop options/listen_on_port = integer: ("0")' >> $fdefault
	echo 'setprop options/server = astring: ("")' >> $fdefault
	echo 'setprop options/threads = integer: ("0")' >> $fdefault

	frefresh=$DNSTMP/BIND_REFRESH_METHOD
	echo 'addpg refresh method' > $frefresh
	echo 'setprop refresh/exec = astring: (":kill -HUP")' >> $frefresh
	echo 'setprop refresh/timeout_seconds = integer: ("60")' >> $frefresh

	privileges='basic,!proc_session,!proc_info,!file_link_any'
	privileges="$privileges,net_privaddr,file_dac_read"
	privileges="$privileges,file_dac_search,sys_resource,proc_chroot"

	# For each instance.
	for inst in `svcs -H -o INST $svc`
	do
	    # Config may default, be set from config_data, or from
	    # command line option.
	    unset config

	    # After import check if this instance needs updating with
	    # new properties.
	    echo "svcadm refresh $svc:$inst" >> $fupdate
	    echo 'unset refresh_inst' >> $fupdate
	    echo "if svcprop -q -p options $svc:$inst; then" >> $fupdate
	    echo '    :' >> $fupdate
	    echo 'else' >> $fupdate
	    echo "    svccfg -s $svc:$inst -f $fdefault" >> $fupdate
	    echo '    refresh_inst=1' >> $fupdate
	    echo 'fi' >> $fupdate

	    echo "if svcprop -q -p refresh $svc:$inst; then" >> $fupdate
	    echo '    :' >> $fupdate
	    echo 'else' >> $fupdate
	    echo "    svccfg -s $svc:$inst -f $frefresh" >> $fupdate
	    echo '    refresh_inst=1' >> $fupdate
	    echo 'fi' >> $fupdate

	    # fopt is a dynamically created instance specific input
	    # file for svccfg(1M).
	    fopt=$DNSTMP/BIND_UPDATE.$inst
	    rm -f $fopt

	    # Retrieve current exec string for this instance, removing
	    # quote characters.
	    cmd=`svcprop -p start/exec $svc:$inst | sed -e 's/\\\\//g'`
	    if [ $? -eq 0 -a -n "$cmd" ]; then
		set -- $cmd

		if [ "$1" = "/lib/svc/method/dns-server" ]; then
		    # No need to convert the converted.
		    continue
		elif [ "$1" != "/usr/sbin/named" ]; then
		    echo "setprop options/server=$1" >> $fopt
		fi

		# Update exec and privilileges.
		echo 'setprop start/exec="/lib/svc/method/dns-server %m %i"'\
		    >> $fopt
		echo "setprop start/privileges=\"$privileges\"" >> $fopt
		shift # dispose of command ready to check for options.

		# Retrieve current configuration file.
		if fmri=`svcprop -p config_data/entities $svc:$inst`; then
		    # Remove leading string,  file://localhost.
		    config=`echo $fmri | sed -e 's.^file://localhost..'`
		    # These should no longer be identical if sed worked.
		    if [ "$config" = "$fmri" ]; then
			# fmri is not of supported type, so ignore it.
			unset config
		    fi
		fi

		# Remove configuration file dependency.
		if svcprop -q -p config_data $svc:$inst; then
		    svccfg -s $svc:$inst delpg config_data
		fi

		# Convert command line options to supported
		# properties.  Other named(1M) options are
		# inappropriate for bind within SMF.
		while getopts :c:t:n:d:p:46 arg; do
		    case $arg in
		    c) config="$OPTARG";; # cmd line opt overrides.
		    t) echo "setprop options/chroot_dir=$OPTARG" >> $fopt;;
		    n) echo "setprop options/threads=$OPTARG" >> $fopt;;
		    d) echo "setprop options/debug_level=$OPTARG" >> $fopt;;
		    p) echo "setprop options/listen_on_port=$OPTARG" >> $fopt;;
		    4) echo "setprop options/ip_interfaces=IPv4" >> $fopt;;
		    6) echo "setprop options/ip_interfaces=IPv6" >> $fopt;;
		    esac
		done
		if [ -n "$config" -a "$config" != "/etc/named.conf"  ]; then
		    echo "setprop options/configuration_file=$config" >> $fopt
		fi
	    fi # start/exec prop

	    # Apply changed properties using svccfg(1M) command after import.
	    if [ -f $fopt ]; then
		echo "svccfg -s $svc:$inst -f $fopt" >> $fupdate
		# Must refresh for changes to take effect
		echo '    refresh_inst=1' >> $fupdate
		echo "rm $fopt" >> $fupdate
	    fi
	    echo 'if [ -n $refresh_inst ]; then' >> $fupdate
	    echo '    svcadm refresh $svc:$inst' >> $fupdate
	    echo 'fi' >> $fupdate

	done # for each instance
	# Restore previous command line args.
	if [ -n "$oset" ]; then
	    set -- $oset
	fi
	echo "rm -f $fdefault" >> $fupdate
	echo "rm -f $frefresh" >> $fupdate
_UPDATE_START_METHOD

# Remove historical dependencies if they exist.
smf_obs_pg network/dns/server usr
smf_obs_pg network/dns/server physical
smf_obs_pg network/dns/server start

cat >> $UPGRADE <<-\EOF

	# Delete the stale single_instance restriction.
	if svcprop -q -p general/single_instance $svc; then
	    svccfg -s network/dns/server delprop general/single_instance
	fi

	# Delete the common_name.
	if svcprop -q -p tm_common_name/C $svc; then
	    svccfg -s network/dns/server delprop tm_common_name/C
	fi

	# Import service manifest into the repository.
	svccfg import /var/svc/manifest/network/dns/server.xml

	# Apply BIND 9.3.4 conversion if applicable.
	if [ -f $fupdate ]; then
	    . $fupdate
	    rm $fupdate
	fi
EOF

#
# Enable svc:/network/dns/server if requested.
#
BASEPREFIX=`echo ${PKG_INSTALL_ROOT} | sed "s/\//_/g"`
FILENAME=`echo sunwbindr_dns"$BASEPREFIX" | cut -c 1-256`
#pragma PRC test_FIO43_C_CERT ignore-next-line
TMPFILE=/tmp/$FILENAME

if [ -f $TMPFILE ]; then
	echo "svcadm enable svc:network/dns/server:default" >> $UPGRADE
	rm $TMPFILE
fi

#
# Create rndc(1m) configuration if one does not exist.
#
if [ ! -f ${PKG_INSTALL_ROOT}/etc/rndc.key ] &&
	[ ! -f ${PKG_INSTALL_ROOT}/etc/rndc.conf ]; then
	echo "rndc-confgen -a"  >> $UPGRADE
fi

if [ "$upgrade_on" = 'now' ]; then
    . $UPGRADE
    # Clean up.
    rm $UPGRADE
    rmdir $DNSTMP
fi

return 0
}

# load the override lib if it exists
if [ -f "${PATCH_OVERRIDE_LIB}" -a -r "${PATCH_OVERRIDE_LIB}" ] ; then
   . "${PATCH_OVERRIDE_LIB}"
fi

# execute the script functions
postinstall_deflt "$@"
postinstall_merge "$@"

exit 0
