# This script creates the backout package for a patch package
#
# directory format options.
#
# @(#) postinstall 1.9 98/07/29 SMI
#
# Copyright (c) 1995 by Sun Microsystems, Inc.
# All rights reserved
#

# 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
}

PATH=/usr/sadm/bin:$PATH

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

#
# 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
#
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.
		LINE=`pkgproto $Proto_Path=$path`
		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

		# Remove the file only if it's OK'd by removef
		rm `removef $PKGINST $Client_Path` 1>/dev/null 2>&1
	done
	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

	pkgmk -o -d $STAGE_DIR 1>/dev/null 2>&1
	pkgtrans -s $STAGE_DIR $ARCHIVE_DIR/undo $PKG 1>/dev/null 2>&1
	compress $ARCHIVE_DIR/undo
	retcode=$?
	if [ "$PATCH_UNDO_ARCHIVE" != "none" ]; then
		if [ $retcode != 0 ]; then
			build_remote_file "undo"
		else
			build_remote_file "undo.Z"
		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}*`
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 additional operations are required for this package, place
# those package-specific commands here.

have_entry()
{
	srchfile=$BASEDIR$1
	/usr/bin/grep "$2" $srchfile > /dev/null 2>&1
	return $?
}

/usr/bin/grep "^spwr[ 	]" $BASEDIR/etc/name_to_major > /dev/null 2>&1

if [ $? -ne 0 ]
then
	add_drv -b $BASEDIR $BASEDIR/kernel/drv/spwr
fi

have_entry /etc/driver_aliases ""pci10b8,a011""
if [ $? = 1 ]; then
	cat >> $BASEDIR//etc/driver_aliases << EOL
spwr "pci10b8,a011"
EOL
fi

have_entry /platform/i86pc/boot/solaris/devicedb/master "pci10b8,a011"
if [ $? = 1 ]; then
	cat >> $BASEDIR//platform/i86pc/boot/solaris/devicedb/master << EOL
pci10b8,a011 pci10b8,a011 net pci spwr.bef "SMC EtherPower II 10/100 (9432)"
EOL
fi

edit_sysfile()
{
        editfile=$BASEDIR$1
        /usr/bin/sed "$2" $editfile > /tmp/$$.sedout
        cp /tmp/$$.sedout $editfile
        rm /tmp/$$.sedout
        return $?
}

# Rename hostnames, make device tree entries and create devlinks
update_hostnames_files()
{
# File names used
tempfile=/tmp/$$a.tmp
temp1file=/tmp/$$b.tmp
temp2file=/tmp/$$c.tmp
tempextension=upgrade.temp.$$
tempscript=/tmp/$$.upgrade.sh

hostname=etc/hostname

# Find the ppa and instance numbers and make it easy to sort
# note: elxl must come before elx
for driver in elxl elx iprb spwr
do

  # Fix for BugId 4160438
  # Test for duplicate instance numbers.
  # This should not happen but can, if DU3 was applied with a card
  # present in the machine which was not supported in 2.6 FCS
  # supported in DU3.  (Only applies to elxl upgrade.)
  if [ "$driver" = "elxl" ]
  then
    P2I=/${BASEDIR}/etc/path_to_inst
    if [ -n "`grep $driver $P2I | sort +n1 -n | awk '{ print $2 }'|uniq -d`" ]
    then
      # Correct duplicated instances by renumbering them above the highest
      # instance number currently in use.
      echo WARNING: $driver has duplicate instances numbers.... Correcting....
      echo WARNING: Please check hostname files names are correct for $driver.
      # Find the highest instance number currently in used for $driver
      count=`grep $driver $P2I | sort +n1 -n | awk '{ print $2 }'|tail -1`
      for X in `grep $driver $P2I | sort +n1 -n | awk '{ print $2 }'|uniq -d`
      do
        rm -f $tempfile
        cat $P2I |sed /' '$X' *\"'$driver'\"'/d > $tempfile
        # Renumber the duplicate instances.
        for Y in `cat $P2I |sed -n /' '$X' *\"'$driver'\"'/p | sed s/' '/=/g`
        do
          Y=`echo $Y | sed s/=/' '/g`
          count=`expr $count + 1`
          echo `echo $Y | awk '{ print $1 }'` $count' "'$driver'"' >> $tempfile
        done
      mv -f $tempfile $P2I
      done
      chmod 444 $P2I
    fi
  fi
  #  End of fix for BugId 4160438.


  # create empty temporary file to stop error messages occuring
  # should there be no drivers to upgrade.
  cat /dev/null > $tempfile
  cat /dev/null > $temp1file
  cat /dev/null > $temp2file
  rm -f $tempscript

  # find ppa and instance information for old system.

  # elx upgrade
  if [ "$driver" = "elx" ]
  then
    if [ -z "`ls -L ${BASEDIR}/dev/elxl* 2> /dev/null`" ] # elxl not already there
    then

      # The next bit is the same as in 2.6 DU3
      /usr/bin/grep "^elxl[ 	]" $BASEDIR/etc/name_to_major > /dev/null 2>&1

      if [ $? -ne 0 ]
      then
	add_drv -b $BASEDIR $BASEDIR/kernel/drv/elxl
      fi

      # Remove elx entries for 3c90x cards from master file.
      editfile=${BASEDIR}/boot/solaris/devicedb/master
      tmpfile=/tmp/$$.sedout
      cat $editfile | /usr/bin/sed '/^pci10b7,90.*elx.bef/d' > $tmpfile
      cp $tmpfile $editfile

      # Now make sure all the elxl entries are present
      for devid in 9000 9001 9004 9005 9006 9050 9051 9055 9056 ; do
	grep pci10b7,$devid $editfile > /dev/null 2>&1
	if [ $? -ne 0 ]
	then
		cat | grep pci10b7,$devid >> $editfile << EOF
pci10b7,9000 pci10b7,9000 net pci elxl.bef "3Com 3C900-TPO Etherlink XL"
pci10b7,9001 pci10b7,9001 net pci elxl.bef "3Com 3C900-COMBO Etherlink XL"
pci10b7,9004 pci10b7,9004 net pci elxl.bef "3Com 3C900B-TPO Etherlink XL"
pci10b7,9005 pci10b7,9005 net pci elxl.bef "3Com 3C900B-COMBO Etherlink XL"
pci10b7,9006 pci10b7,9006 net pci elxl.bef "3Com 3C900B-TPC Etherlink XL"
pci10b7,9050 pci10b7,9050 net pci elxl.bef "3Com 3C905-TX Fast Etherlink XL 10/100"
pci10b7,9051 pci10b7,9051 net pci elxl.bef "3Com 3C905-T4 Fast Etherlink XL 10/100"
pci10b7,9055 pci10b7,9055 net pci elxl.bef "3Com 3C905B-TX Fast Etherlink XL 10/100"
pci10b7,9056 pci10b7,9056 net pci elxl.bef "3Com 3C905B-T4 Fast Etherlink XL 10/100"
EOF
	fi
      done

      edit_sysfile /etc/driver_aliases  "/elx[^l].*pci10b7,90/s/elx/elxl/"

      editfile=${BASEDIR}/etc/driver_aliases
      for devid in 9000 9001 9004 9005 9006 9050 9051 9055 9056
      do
	grep pci10b7,$devid $editfile > /dev/null 2>&1
	if [ $? -ne 0 ]
	then
          echo elxl \"pci10b7,$devid\" >> $editfile
	fi
      done


      # The elxl driver now supports some devices that were previously
      # supported by the elx driver.  Thus, some /dev/elx[0-9] devices
      # will have changed to /dev/elxl[0-9].
      #
      # We therefore need to rename nodes under /dev and /devices
      # and may also need to rename some files /etc/hostname.elx*
      #
      # Unfortunately the usual ITU trick of drvconfig -R will not work,
      # because the elx driver will probably be attached to some of
      # the nodes which now want to be elxl nodes.
      #
      # Example:
      # There were 3 elx devices in the system before elxl was installed.
      # Now, /dev/elx1 is being supported by the elxl driver. thus:
      #
      #  elx0 remains elx0.
      #  elx1 becomes elxl0.
      #  elx2 becomes elx1.
      # (gld-assigned network PPAs aren't bound to device instances)


      ELXCOUNT=0
      ELXLCOUNT=0
      DEVICECOUNT=0

      cd ${BASEDIR}/dev

      /usr/bin/ls -l ${BASEDIR}/dev/elx[0-9]* 2> /dev/null | /usr/bin/sed 's/.*->[	 ]*//' | \
      while read DEVLINK
      do
	# Look for elx devices which will remain elx devices
	ISPCI=`echo $DEVLINK | grep pci`
	DEVSTRING=`echo $DEVLINK | grep pci10b7,5900``echo $DEVLINK | grep pci10b7,5950`
	if [ ${DEVSTRING}X != "X" -o ${ISPCI}X = "X" ] 
	then
          if [ ${ISPCI}X = "X" -o $ELXCOUNT -eq $DEVICECOUNT ]
          then
            ELXCOUNT=`expr $ELXCOUNT + 1`
            DEVICECOUNT=`expr $DEVICECOUNT + 1`
            continue;
          fi
          NEWNAME=`echo $DEVLINK | /usr/bin/sed 's/[0-9]*$/'$ELXCOUNT/`
          MAJOR=`cat ${BASEDIR}/etc/name_to_major | \
          awk '$1 == "elx" { print $2 }'`
          rm -f ${BASEDIR}/dev/$DEVLINK > /dev/null 2>&1
          mknod ${BASEDIR}/dev/$NEWNAME c $MAJOR \
          `expr $ELXCOUNT + 1` > /dev/null 2>&1
          chmod 600 ${BASEDIR}/dev/$NEWNAME
          rm -f elx$ELXCOUNT > /dev/null 2>&1
          ln -s $NEWNAME elx$ELXCOUNT
          if [ -f ${BASEDIR}/etc/hostname.elx${DEVICECOUNT} ]
          then
            mv ${BASEDIR}/etc/hostname.elx${DEVICECOUNT} \
              ${BASEDIR}/etc/hostname.elx${ELXCOUNT}
          fi
          ELXCOUNT=`expr $ELXCOUNT + 1`
          DEVICECOUNT=`expr $DEVICECOUNT + 1`
        else
          NEWNAME=`echo $DEVLINK | /usr/bin/sed 's/[0-9]*$/'l$ELXLCOUNT/`
          MAJOR=`cat ${BASEDIR}/etc/name_to_major | \
          awk '$1 == "elxl" { print $2 }'`
          rm -f ${BASEDIR}/dev/$DEVLINK > /dev/null 2>&1
          mknod ${BASEDIR}/dev/$NEWNAME c $MAJOR \
          `expr $ELXLCOUNT + 1` > /dev/null 2>&1
          chmod 600 ${BASEDIR}/dev/$NEWNAME
          ln -s $NEWNAME elxl$ELXLCOUNT
          if [ -f ${BASEDIR}/etc/hostname.elx${DEVICECOUNT} ]
          then
            mv ${BASEDIR}/etc/hostname.elx${DEVICECOUNT} \
              ${BASEDIR}/etc/hostname.elxl${ELXLCOUNT}
          fi
          ELXLCOUNT=`expr $ELXLCOUNT + 1`
          DEVICECOUNT=`expr $DEVICECOUNT + 1`
	fi
      done

      # Now handle the generic devices
      if [ -x ${BASEDIR}/dev/elx0 ]
      then
        rm -f ${BASEDIR}/dev/elx > /dev/null 2>&1
        DEVNAME=`ls -l ${BASEDIR}/dev/elx0 | sed -e 's/.*->[	 ]*//' \
          -e 's/[0-9]*$//'`
        MAJOR=`cat ${BASEDIR}/etc/name_to_major | \
          awk '$1 == "elx" { print $2 }'`
        mknod $DEVNAME c $MAJOR 0 > /dev/null 2>&1
        rm -f elx
        ln -s $DEVNAME elx
        chmod 600 $DEVNAME
      fi

      if [ -x ${BASEDIR}/dev/elxl0 ]
      then
        DEVNAME=`ls -l ${BASEDIR}/dev/elxl0 | sed -e 's/.*->[	 ]*//' \
          -e 's/[0-9]*$//'`
        MAJOR=`cat ${BASEDIR}/etc/name_to_major | \
          awk '$1 == "elxl" { print $2 }'`
        mknod $DEVNAME c $MAJOR 0 > /dev/null 2>&1
        rm -f elxl
        ln -s $DEVNAME elxl
        chmod 600 $DEVNAME
      fi
      # The end of bit which is the same as in 2.6 DU3

    fi # End of check for elxl absance

  else # non elx upgrade
    ls -l ${BASEDIR}/dev/$driver?* 2> /dev/null |sed s/' '/=/g > $temp2file
    echo "#!/sbin/sh" > $tempscript
    for data in `cat $temp2file`
    do
      ppa=`echo $data | sed s/'^.*:'$driver//`
      path=`echo $data | sed s/':'$driver'.*$'//|sed s/'^.*\/devices'//`
      ptoinst=`grep $path ${BASEDIR}/etc/path_to_inst`
      instance=`echo $ptoinst | sed s/'"'$driver'"'//|sed s/'".*"'//`
      instance=`expr $instance`

      major=`grep "^$driver" ${BASEDIR}/etc/name_to_major | sed s/'^'$driver' *'//`
      minor=`expr $instance + 1`

      # note ${BASEDIR}/dev/$driver is not touched.
      # Rename build entries in /devices 
      rm -f ${BASEDIR}/devices/$path':'$driver$instance
      mknod ${BASEDIR}/devices/$path':'$driver$instance c $major $minor
      chmod 600 ${BASEDIR}/devices/$path':'$driver$instance

      # Update devlinks
      echo "rm -f ${BASEDIR}/dev/$driver$ppa" >> $tempscript           # remove old devlink
      echo "rm -f ${BASEDIR}/dev/$driver$instance" >> $tempscript
      echo "ln -s ${BASEDIR}/devices/$path':'$driver$instance ${BASEDIR}/dev/$driver$instance" >> $tempscript
      

      echo $driver::$ppa==$driver::$instance >> $tempfile  
    done
      sort -r $tempscript > $tempscript.$tempextension
      rm -f $tempscript
      eval . $tempscript.$tempextension
      rm -f $tempscript.$tempextension
  fi # End of check to see if an elx or non-elx is being upgraded



  # Rename hostfiles to tempory files
  for data in `cat $tempfile` 
  do
    olddata="`echo $data | sed s/'==.*'//`"

    ppa="`echo $olddata|sed s/'.*::'//`"
    driver="`echo $olddata|sed s/'::.*'//`"

    if ( [ -f ${BASEDIR}/$hostname.$driver$ppa ] ); then
      mv -f ${BASEDIR}/$hostname.$driver$ppa ${BASEDIR}/$hostname.$driver$ppa.$tempextension
    fi
  done  # End of renaming hostname files to tempory files

  # Rename tempory files to hostname.driver_instance 
  for data in `cat $tempfile` 
  do
    olddata="`echo $data | sed s/'==.*'//`"
    newdata="`echo $data | sed s/'.*=='//`"

    driver="`echo $olddata|sed s/'::.*'//`"
    ppa="`echo $olddata|sed s/'.*::'//`"


    newdriver="`echo $newdata|sed s/'::.*'//`"
    instance="`echo  $newdata|sed s/'.*::'//`"

    if ( [ -f ${BASEDIR}/$hostname.$driver$ppa.$tempextension ] ); then
        mv -f ${BASEDIR}/$hostname.$driver$ppa.$tempextension ${BASEDIR}/$hostname.$newdriver$instance
        echo $hostname.$driver$ppa renamed to $hostname.$newdriver$instance
    fi
  done # End of renaming tempory files to new hostname files.
done # End of looping through driver list.

# make next reboot do a reconfigure
touch ${BASEDIR}/reconfigure

rm -f $tempfile
rm -f $temp1file
rm -f $temp2file
}
update_hostnames_files


exit 0
