# This script initializes the backout data for a patch package # directory format options. # #pragma ident "@(#)preinstall 1.18 06/09/07 SMI" # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # 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 $SCRIPTS_DIR`/pkginfo" 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 not containing the class # identifier. Thus we need to merge the old CLASSES macro and # the installing patch pkgs CLASSES macro. nawk ' $1 ~ /CLASSES/ {print $0} ' $ORIGPKGINFO \ | sed s/CLASSES=// > /tmp/installingCLASSES.$$ classIDs=`nawk ' $1 ~ /CLASSES/ {print $0} ' $INSTALLINGPKGINFO \ | 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 # # Adding hard link entries into the proto file. # nawk -v basedir=${BASEDIR:-/} ' { ftype = $1; } $1 ~ /[0123456789]/ { if ( NF >= 3) { ftype = $2; } else { next; } } { if (ftype == "l") { print $0; } else { next; } } ' < $Our_Pkgmap 1>> $PROTO_FILE 2> /dev/null 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 == "l" || 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 # # 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 # If we're up against a file system that can't be # written to, skip adding the link to the backout # package. Check the links parent directory for # writablility. If the parent directory does # not exist yet, check its parent directory until # the parent directory is $BASEDIR or # $PKG_INSTALL_ROOT dirPath=`dirname "$Chk_Path"` while [ "$dirPath" != "$Proto_From" ]; do # If path doesn't exist check parent path if valpath -n $dirPath; then dirPath=`dirname "$dirPath"` else break fi done if [ "$dirPath" != "$Proto_From" ]; then /usr/bin/touch $dirPath/.testpatchadd.$$ \ > /dev/null 2>&1 if [ $? != 0 ]; then continue fi rm -f $dirPath/.testpatchadd.$$ fi 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=$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# exit 0