# This script creates the backout package for a patch package
#
# directory format options.
#
# ident	"@(#)postinstall	1.20	07/10/18 SMI"
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#

# Description:
#       Set the TYPE parameter for the remote file
#
# Parameters:
#       none
#
# Globals set:
#	TYPE
#

POSTINSTALL_ERR_LOG="$PKG_INSTALL_ROOT/var/sadm/patch/$SUNW_PATCHID/postinstall_log.$$"
RET_STATUS=0

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
}

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

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_PROGRESSIVE" = "true" ]; then
        # remove the scripts that are left behind
        install_scripts=`dirname $0`
        rm $install_scripts/checkinstall $install_scripts/patch_checkinstall $install_scripts/patch_postinstall

	# If this is being used in an old-style patch, insert
	# the old-style script commands here.

	#XXXOld_CommandsXXX#

	exit 0
fi

#
# 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
	cd $BASEDIR

	cat $Our_Deletes | while read path; do
		Reg_File=0

		if valpath -l $path; then
			Client_Path="$CLIENT_BASEDIR/$path"
			Build_Path="$RELOC_DIR/$path"
			Proto_Path=$BASEDIR/$path
		else	# It's an absolute path
			Client_Path=$path
			Build_Path="$ROOT_DIR$path"
			Proto_Path=$PKG_INSTALL_ROOT$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
			if [ "$Proto_Path" = "$path" ]; then
				LINE=`echo $LINE | sed -e "s|$Proto_Path|$Build_Path|2"`
			else
				LINE=`echo $LINE | sed -e "s|$Proto_Path|$Build_Path|"`
			fi

			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
		
		if [ "$SAFEMODE_INSTALL" = "true" ]; then
			# Handle deletion of an object for safemode patching
			HandleSafemodeDeleteObject $PKGINST $Client_Path
		else
			# Remove the file only if it's OK'd by removef
			rm `/usr/sbin/removef $PKGINST $Client_Path` 1>/dev/null 2>&1
		fi

	done
	/usr/sbin/removef -f $PKGINST

	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
		/usr/bin/pkgtrans -s $STAGE_DIR $ARCHIVE_DIR/undo $PKG 1>>$POSTINSTALL_ERR_LOG 2>&1
		retcode=$?
		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
	# remove the scripts that are left behind
	install_scripts=`dirname $0`
	rm $install_scripts/checkinstall $install_scripts/patch_checkinstall $install_scripts/patch_postinstall
fi

#
# 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 -f $PKGSAV/$patch/remote 
                mv $TEMP_REMOTE $PKGSAV/$patch/remote  
                rm -f $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 -f $POSTINSTALL_ERR_LOG
	exit $RET_STATUS
else
	rm -f $POSTINSTALL_ERR_LOG
fi

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

#XXXSpecial_CommandsXXX#

#
# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# ident	"@(#)postinstall	1.9	07/09/20 SMI"
#
# *
# * U.S. Government Rights - Commercial software. Government users are subject
# * to the Sun Microsystems, Inc. standard license agreement and applicable
# * provisions of the FAR and its supplements.
#
# This distribution may include materials developed by third parties. Sun,
# Sun Microsystems, the Sun logo and Solaris are trademarks or registered
#  trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
#
#

# The source package contains a directory having an embedded
# pound sign.  While this character is legal in filenames,
# and pkgadd and friends don't object to it, some RE tools
# aren't too happy about it, so in this package we replace the
# pound with an underscore, and rename the directory after
# installation (and update the package database too).

# The source package contains a directory having an embedded
# pound sign.  While this character is legal in filenames,
# and pkgadd and friends don't object to it, some RE tools
# aren't too happy about it, so in this package we replace the
# pound with an underscore, and rename the directory after
# installation (and update the package database too).


#
# We have to differentiate between a pkgadd relocations
# and a Solaris install, since Solaris uses pkgadd -R 
# as well. Solaris installs on /a mounted filesystem.
#
#
# set a flag for if a Solaris Install
#


# define stmts of files used for crackle
#

spapm_reg=/etc/snmp/conf/spapm.reg
spapm_rsrc=/etc/snmp/conf/spapm.rsrc

spama_conf=/etc/opt/SUNWspa/spama.conf 
tmp_spama_conf=/tmp/spama.conf
tmp_spama_out=tmp/spama.out
spa_location=/etc/opt/SUNWspa
sma_location=/etc/sma/snmp

# These defines statements are for 
# the editing of /etc/services
#
services_file=$BASEDIR/etc/inet/services
services_bak=$BASEDIR/tmp/services.bak
services_out=$BASEDIR/tmp/services.out
SNMPD_FILE=$BASEDIR/etc/sma/snmp/snmpd.conf

RM=/usr/bin/rm
CP=/usr/bin/cp


#########################################################
#							#
#		edit /etc/services			#
#							#
#########################################################

#
# this routine checks for a pre-existing entry
# of snmpd in the etc/services file
#

check_for_snmpd() {
 cat "$services_bak" | awk '{print $1,$2}' | while read attr value
    do
	if [ "$attr" = "snmpd" ] && [ "$value" = "161/udp" ] 
	    then
	# create a services.out file if there is already 
	# an entry
	    echo "exists" >> $services_out
	fi
    done
}

#
# this routine checks if there is a services.out file
# if so, then there is already an entry in the services
# file for snmpd, if not, add it
#

add_entry() {

#
# if this file exists, then there is already an entry
# and do nothing
#
    if [ -f $services_out ] 
    then
	return
    else
    echo "snmpd           161/udp        snmp             # SMA snmp daemon" >> $services_bak
    fi

return

}

#
# make a copy of the services file
#

make_copy() {
    $CP -p $services_file $services_bak
}

#
# remove working files
#

cleanup_services() {

if [ -f $services_out ] 
	then
    	$RM $services_out
fi

#
# anything done to root at Install time is
# still relative to the mounted filesytem /a
# so for this one case we have to be aware.
#


	    $CP -p $services_bak $BASEDIR/etc/inet/services

if [ -f $services_bak ]
       then
       $RM $services_bak
fi

}

# First make a copy of the /etc/services file to work with


make_copy

# check for existence of snmpd entry

check_for_snmpd

# Add an entry if needed

add_entry

#cleanup

cleanup_services


#########################################################
#							#
# Edit the snmpd.conf file				#
#							#
#########################################################

edit_snmpd_file() {
	#
	# only add the line if it is not already there
	#
	/usr/bin/egrep -s "$1" $SNMPD_FILE || echo "$1" >> $SNMPD_FILE
}

#
# edit snmpd.conf to add the dlmod statements to the file.
# 

if [ $ARCH = "sparc" ]
then
	edit_snmpd_file "dlmod seaProxy /usr/sfw/lib/sparcv9/libseaProxy.so"
	edit_snmpd_file "dlmod seaExtensions /usr/sfw/lib/sparcv9/libseaExtensions.so"
else
# Solaris booted in 32bit mode during installation, we cannot determine the isainfo
# for AMD64. So we are adding all four entries hoping that any of the two libraries
# will be loaded when snmpd comes up.

	edit_snmpd_file "# We require amd64 entries for 64/32 bit support"
	edit_snmpd_file "dlmod seaProxy /usr/sfw/lib/libseaProxy.so"
	edit_snmpd_file "dlmod seaExtensions /usr/sfw/lib/libseaExtensions.so"
	edit_snmpd_file "dlmod seaProxy /usr/sfw/lib/amd64/libseaProxy.so"
	edit_snmpd_file "dlmod seaExtensions /usr/sfw/lib/amd64/libseaExtensions.so"
fi

#
# end edit snmpd file
#

#################################################################################
#
# - check START_MASTER_AGENT in crackle-ii's spama.conf file,
#
# if "yes" then replace it with "no" and check MASTER_AGENT_REQ_PORT atribute
# for a port number other then the default, 161, if it is a non-default port 
# number add it to the snmpd.conf's agentaddress token, need to stop/start the
# crackle-ii master agent
#
# if "no", don't do anything and continue on with other migration steps
# 
# - other migration step
#    Disable sma entity MIB implementation, if applicable.
#
#################################################################################

#
# Start crackle-II edits
#
# Need to add crackle-II non-default port number to the snmpd.conf's token 
# agentaddress 
#
add_port_to_sma() {

    #
    # "Add the agentaddress token in snmpd.conf with the crackle-II " 
    # "port number to it along with sma's default port.  SMA out of "
    # "the box does not have this defined."
    #

    cat "$tmp_snmpd_conf" | awk '{print $1,$2}' | while read attr value
    do

	if [ "$attr" = "agentaddress" ]
	then
	    sed -e "s/^agentaddress /agentaddress $1,/" "$tmp_snmpd_conf" >"$tmp_snmpd_out"
	    cp -p "$tmp_snmpd_out" "$tmp_snmpd_conf"
	    break
	fi

    done

    #
    # agentaddress token was not defined, add it to snmpd.conf,
    # use tmp_snmpd_out to see if agentaddress was nor defined or not
    #

    if [ -s "$tmp_snmpd_out" ]
    then
	echo "agentaddress was defined"
    else
	echo "agentaddress was not defined"
	echo "" >> "$tmp_snmpd_conf"
	echo "agentaddress 161,$1" >> "$tmp_snmpd_conf"
    fi

}

#
# Disable sma entity MIB implementation
#
disable_sma_entity_mib() {
    #
    # "uncommnet sma entity mib dlmod entry if present"
    #
    sed -e "s/^dlmod entity/#dlmod entity/" "$tmp_snmpd_conf" > "$tmp_snmpd_out"
    cp -p "$tmp_snmpd_out" "$tmp_snmpd_conf"
}

#
# create temporary snmpd.conf
#
create_tmp_snmpd_conf() {

    if [ -s "$tmp_snmpd_conf" ]
    then

	echo "already exists, created when adding a non-default port to snmpd.conf"
    else 
	cp "$snmpd_conf" "$tmp_snmpd_conf"
    fi
}



#
# Copy the configuration files that have been modified for crackle-ii migration
# to SMA
#

copy_files() {

    if [ -s "$tmp_snmpd_conf" ]
    then
	cp "$tmp_snmpd_conf" "$sma_location"
    fi

    if [ -s "$tmp_spama_conf" ]
    then
	cp "$tmp_spama_conf" "$spa_location"
	chmod 600 "$spama_conf"
	#
	# Stop - start crackle-ii
	#
	/etc/init.d/spama stop
	/etc/init.d/spama start
    fi
}

#
# cleanup
#
cleanup() {

    $RM /tmp/spama.*
    $RM /tmp/snmpd.*

}

#
# Check these files for the Crackle-II installation
#
if [ -s "$spapm_reg" ] && [ -s "$spapm_rsrc" ]
then

    #
    # Check if START_MASTER_AGENT is set to yes, if it is, set it to no, and
    # continue the migration configuration process
    #
    cp "$spama_conf" "$tmp_spama_conf"
    cat "$tmp_spama_conf"  | awk -F= '{print $1,$2}' | while read attr value
    do 
	if [ "$attr" = "START_MASTER_AGENT" ] && [ "$value" = "yes" ]
	then

	    sed -e "s/^START_MASTER_AGENT=yes/START_MASTER_AGENT=no/" "$tmp_spama_conf" > "$tmp_spama_out"

	    cp "$tmp_spama_out" "$tmp_spama_conf"

	    #
	    # check if the crackle-ii non-default port needs to be migrated 
	    # to sma
	    #
	    cat "$tmp_spama_conf" | awk -F= '{print $1,$2}' | while read attr value
	    do
		if [ "$attr" = "MASTER_AGENT_REQ_PORT" ]
		then

		    if [ "$value" = "161" ] || [ -z "$value" ]
		    then
			echo "using defualt port 161"
		    else 
			# create temporary snmpd.conf
			create_tmp_snmpd_conf

			#
			# "port is not empty or not the default, 161 "
			# "need to modify snmpd.conf, adding this udp port "
			#
			add_port_to_sma $value

		    fi
		fi
	    done
	    break;
    	fi
    done

    #
    # create temporary snmpd.conf, if not already created above
    # 
    create_tmp_snmpd_conf

    #
    # Disable sma entity MIB implementation
    #
    disable_sma_entity_mib

    #
    # Copy new spama.conf and snmpd.conf, if available
    # and restart daemons
    #
    copy_files

    #
    # clean up temp files created
    #
    cleanup
fi

#
# end of crackle script
#

#
# check if sma should be enabled (sma.tmp was set in preinstall)
if [ -f $BASEDIR/var/sma.tmp ]; then
	touch  $BASEDIR/var/svc/profile/upgrade
	cat >> $BASEDIR/var/svc/profile/upgrade <<\_SMA
if [ `/sbin/zonename` = global ]; then
	/usr/sbin/svcadm enable svc:/application/management/sma:default
fi
_SMA
	rm -f $BASEDIR/var/sma.tmp
fi

exit 0
