#!/bin/ksh

PKGCOND=/usr/bin/pkgcond

ip_mv_patchid=125504-01

last_patch() {
    ## returns the number of patches installed at or above this rev.
    root_dir=${ROOTDIR:-/}
    
    ## parse id and rev
    pid=`echo $1 | cut -d\- -f1`
    prev=`echo $1 | cut -d\- -f2`
    patch_cnt=0
    
    ## get all installed refernces to the installed patch base id
    installed_patches=`patchadd -p -R $root_dir | sed -n -e 's/Req.*//' -e 's/[a-zA-Z]*://g' -e 's/,//g' -e "/$pid/p"`
    
    for x in $installed_patches ; do
	base=`echo $x  | cut -d\- -f1`
	rev=`echo $x | cut -d\- -f2`
	if [ $pid -eq $base ] && [ $rev -ge $prev ] ; then
            ## count all installed patches includeing this patch
	    patch_cnt=`expr $patch_cnt + 1`
	fi
    done
    
    return $patch_cnt
}


# new types/classes for SUNWcsr are used in mapping below
# postbackout will restore original types/classes

SUNWcnetr_to_SUNWcsr="
e preserve etc/aggregation.conf
e dhcpagent etc/default/dhcpagent
e preserve etc/default/inetinit
e preserve etc/default/ipsec
e preserve etc/default/mpathd
f none etc/inet/datemsk.ndpd
f none etc/inet/ike/config.sample
e ipsecalgsbase etc/inet/ipsecalgs
f none etc/inet/ipsecinit.sample
f none etc/inet/secret/ike.preshared
f none etc/inet/secret/ipseckeys.sample
e sock2path etc/inet/sock2path
s none etc/sock2path
f none sbin/dladm
dr none etc
dr none etc/default
dr none etc/inet
d none etc/inet/ike
d none etc/inet/ike/crls
d none etc/inet/ike/publickeys
d none etc/inet/secret
d none etc/inet/secret/ike.privatekeys
dr none sbin"

SUNWipfr_to_SUNWcsr="
e preserve etc/ipf/ipf.conf
f none lib/svc/method/ipfilter
f manifest var/svc/manifest/network/ipfilter.xml
f none lib/svc/method/pfil
f manifest var/svc/manifest/network/pfil.xml
di none etc/ipf
dr none lib/svc/method
dr none lib/svc
dr none lib
dr none var/svc/manifest/network
dr none var/svc/manifest
dr none var/svc
dr none var"

chpkg_global () {
    srcpkg=$1
    dstpkg=$2

    pkgmapfilter=/var/run/.$$.chpkg.$$.filter.$$
    > $pkgmapfilter

    echo "$3" | while read type class object ; do
	[ -z "$object" ] && continue

	if [ "$type" = "di" ] ; then
	    [ -e "$ROOTDIR/$object" ] && installf -R ${ROOTDIR:-/} $dstpkg /$object

	elif [ "$type" = "dr" ] ; then
	    removef -R ${ROOTDIR:-/} $srcpkg /$object > /dev/null
	    echo " $object[ =]" >> $pkgmapfilter

	else
	    removef -R ${ROOTDIR:-/} $srcpkg /$object > /dev/null
	    if [ "$type" = "d" ] ; then 
		[ -e "$ROOTDIR/$object" ] && installf -R ${ROOTDIR:-/} $dstpkg /$object
		
	    elif [ "$type" = "s" ] ; then 
		[ -h "$ROOTDIR/$object" ] && installf -c $class -R ${ROOTDIR:-/} $dstpkg /$object

	    else
		[ -e "$ROOTDIR/$object" ] && installf -c $class -R ${ROOTDIR:-/} $dstpkg /$object $type
	    fi
	    echo " $object[ =]" >> $pkgmapfilter
	fi

    done

    removef -R ${ROOTDIR:-/} -f $srcpkg
    installf -R ${ROOTDIR:-/} -f $dstpkg

    pspool_pkgmap=${ROOTDIR:-/}var/sadm/pkg/$srcpkg/save/pspool/$srcpkg/pkgmap
    [ -f "$pspool_pkgmap" ] && {
	egrep -f $pkgmapfilter $pspool_pkgmap > /var/run/${srcpkg}_pspool_pkgmap_removed
	egrep -f $pkgmapfilter -v $pspool_pkgmap > $pspool_pkgmap.tmp
	mv $pspool_pkgmap.tmp $pspool_pkgmap
    }
    rm $pkgmapfilter
}



ExecuteInProperEnvironment () {
    
   ##  $PKGCOND is_path_writable $ROOTDIR/usr/bin
#   /usr/bin/touch ${ROOTDIR}/usr/bin/.test.$$ > /dev/null 2>&1 && {
#       /usr/bin/rm /usr/bin/.test.$$ > /dev/null 2>&1
#   }
    
    if $PKGCOND is_whole_root_nonglobal_zone > /dev/null 2>&1 ; then
        # Execute non-global whole root zone commands.
        # Should be same action as the default action.
	global_context=false
	return 0
    fi
    
    if $PKGCOND is_nonglobal_zone > /dev/null 2>&1 ; then
        # Execute non-global zone commands. Should be no action here
	global_context=false
	return 0
    fi
    
    if $PKGCOND is_netinstall_image > /dev/null 2>&1 ; then
        # Execute commands applicable to patching the mini-root.
        # There are usually no actions to take here since your patching
        # the mini-root on an install server.
	return 0
    fi
    
    if $PKGCOND is_mounted_miniroot > /dev/null 2>&1 ; then
        # Execute commands specific to the mini-root
	return 0
    fi
    
    if $PKGCOND is_diskless_client > /dev/null 2>&1 ; then
        # Execute commands specific to diskless client
	return 0
    fi
    
    if $PKGCOND is_alternative_root > /dev/null 2>&1 ; then
        # Execute commands specific to an alternate root
	return 0
    fi
    
    if $PKGCOND is_global_zone > /dev/null 2>&1 ; then
        # In a global zone and system is mounted on /.
        # Execute all commands.
	return 0
    fi
    
    return 1
}


CheckZones()
{
    if [ "$ROOTDIR" = "/" -a -x /usr/bin/zonename ] ; then
	ZONENAME=`/usr/bin/zonename`
	if [ ${ZONENAME} = "global" ] ; then
	    GLOBAL_ZONE=true
	else
	    GLOBAL_ZONE=false
	fi
    else
        # Unable to determine zone
	GLOBAL_ZONE=true
    fi
}


## Since files are being transferred from hollow to non-hollow pkgs, 
## and non-global zones don't have hollow pkg files, it is sufficient
## to do the transfer in the global zone only

global_context=true

if [ -x "$PKGCOND" ] ; then
    ExecuteInProperEnvironment
else
    CheckZones
    if [ "${GLOBAL_ZONE}" = "true" ] ; then
	:
    else
	global_context=false
    fi
fi


if [ "$global_context" = "true" ] ; then
    last_patch $ip_mv_patchid
    if [ "$?" -eq "0" ] ; then
	pkginfo -R ${ROOTDIR:-/} -q SUNWcnetr && chpkg_global SUNWcnetr SUNWcsr "$SUNWcnetr_to_SUNWcsr"
	pkginfo -R ${ROOTDIR:-/} -q SUNWipfr && chpkg_global SUNWipfr SUNWcsr "$SUNWipfr_to_SUNWcsr"
    fi
fi

exit 0

