#!/sbin/sh # ***************************************************************** # * * # * Copyright 2006 Hewlett-Packard Development Company, L.P. * # * * # * The software contained on this media is proprietary to and * # * embodies the confidential technology of Hewlett-Packard * # * Development Company. Possession, use, duplication or * # * dissemination of the software and media is authorized only * # * pursuant to a valid written license from Hewlett-Packard * # * Company. * # * * # * RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure * # * by the U.S. Government is subject to restrictions as set * # * forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, * # * or in FAR 52.227-19, as applicable. * # * * # ***************************************************************** # @(#)$RCSfile: dupatch.sh,v $ $Revision: 1.1.2.8 $ (DEC) $Date: 2003/10/30 21:06:52 $ . /usr/share/lib/shell/libscp . /usr/share/lib/shell/Dialog . /usr/share/lib/shell/Lists . /usr/share/lib/shell/Strings [ -f /usr/share/lib/shell/libinstall ] && { . /usr/share/lib/shell/libinstall . /usr/share/lib/shell/libswdb } SetUpLogFile () { local_date=`date +%Y%b%d:%H:%M:%S` [ -d $_PATCHDIR/log ] || mkdir -m 755 -p $_PATCHDIR/log _EVENT_LOG="$_PATCHDIR/log/Dupatch_load_$local_date.log" _SLOG=$_EVENT_LOG if [ -f /usr/bin/gawk ]; then _AWK=/usr/bin/gawk else _AWK=/usr/bin/awk fi _AWKLOG=' BEGIN { printf("%s", NAME); } { print ">" $0 } ' [ "$_DPWD" ] || { _DPWD=`/bin/pwd`; export _DPWD } _USERNAME="" _USER="" _USERNOTES="Loading Patch Tools" } Main () { PATH=/sbin:/usr/lbin:/usr/sbin:/usr/bin _CONFIGPATH=/sys/conf export _CONFIGPATH _ARGS_DONE= _DPWD=`/bin/pwd`; export _DPWD _PROG=`basename $0`; export _PROG P_Make_TMP TRIM=Y P_Args $0 $* || P_Exit 1 P_SetRoot SetUpLogFile P_LogInit # standard routine echo "" >>$_SLOG if [ "$_PVS" -a "$_KIT_TOP" ]; then P_UpdateTools || P_Exit $? else { if [ "$_CMDLINE" ]; then { echo " ************************************************************************ Warning: To load new tools, you must put the -kit switch on the command line. No attempt is being made to load new tools. ************************************************************************ " | tee -a $_SLOG } else { P_KitLocGet || P_Exit 1 P_UpdateTools || P_Exit $? } fi } fi [ -f $_ROOT/usr/sbin/$_PROG ] || { P_Ferror 1 " Patch tools need to be installed on your system. As the super-user (root), please invoke $_PROG without command line arguments first. " } _DUPATCH_EXEC=Y; export _DUPATCH_EXEC [ -x $_ROOT/usr/sbin/$_PROG ] || P_Ferror 1 "ERROR: $_ROOT/usr/sbin/$_PROG is not executable..." exec $_ROOT/usr/sbin/$_PROG $* P_Exit $? } # @(#)$RCSfile: common.sh,v $ $Revision: 1.1.2.70 $ (DEC) $Date: 2006/11/22 04:59:02 $ P_AbsPath () { case $1 in .) # path is the current directory P=$_DPWD ;; /*) # absolute path provided P=$1 ;; *) # relative from current directory P=$_DPWD/$1 ;; esac echo $P | sed -e 's%/\./%/%g' -e 's%/\./%/%g' -e 's%///*%/%g' -e 's%/\.$%%' -e 's%*/$%%' } P_Args () { CMDPATH=$0; shift CL=`P_Remove_C_Space $*` P_ArgsSub $CL || return 1 return 0 } P_ArgsCheck () { P_ArgsMand || return 1 [ "$PATCH_DEBUG" ] && echo "\n=== final check stage in P_ArgsCheck ()" eval SWLIST=\$_${_TYPE}_SW ERROR=0 for CS in $_ALLSW { eval SW=\$_SW_$CS [ "$SW" ] || continue LSW="-`ToLower $CS" Member $CS $SWLIST || { P_Error " \"$LSW\" is not a valid switch with operation \"-`ToLower $_TYPE`\"" ERROR=1 continue } eval ARG=\$_ARG_$CS case $CS in CFGFILE) [ "$ARG" ] || { P_Error " The \"$LSW\" switch requires a file name as its argument." ERROR=1 continue } [ "$ARG" ] && { case $ARG in */*) # path provided P_Error " You must supply the name of the existing configuration file without specifying the pathname." ERROR=1 continue ;; esac } [ -f $_CONFIGPATH/$ARG ] || { P_Error " The configuration file \"$_CONFIGPATH/$ARG\" does not exist." ERROR=1 continue } ;; KIT | \ ROOT) [ "$ARG" ] || { P_Error " The \"$LSW\" switch requires a directory path as its argument." ERROR=1 continue } ARG=`P_AbsPath $ARG` [ -d "$ARG" ] || { P_Error " \"$ARG\" does not exist or is not a directory." ERROR=1 continue } case $CS in KIT) P_SetRoot P_KitLocCheck $ARG || ERROR=1 ;; ROOT) [ -d $ARG/usr/.smdb. ] || { P_Error " \"$ARG\" is not a valid directory for alternate root." ERROR=1 } ;; esac ;; NAME | \ NOTE) [ "$ARG" ] || { P_Error " The \"$LSW\" switch requires a text string as its argument." ERROR=1 } ;; DATA_FILE | \ LICENSE | \ NOBACKUP | \ NOLOG | \ PATCH_ID | \ PRECHECK_ONLY | \ PROCEED | \ PRODUCT_ID | \ REV | \ ROOT_PATH | \ SINGLE_USER | \ NOAUTO | \ NOROLL | \ PRODUCT_ID) [ "$ARG" ] && { P_Error " The \"$LSW\" switch does not require any argument." ERROR=1 } ;; TYPE) eval KEYLIST=\$_${CS}_KEY KER= if [ ! "$ARG" ]; then { KER=1 } else { UA=`ToUpper $ARG` eval _ARG_$CS='$UA' Member $UA $KEYLIST || KER=1 } fi [ "$KER" ] && { KEYLIST=`echo $KEYLIST | sed 's/ / | /g'` P_Error " The \"$LSW\" switch requires one of the following arguments: `ToLower $KEYLIST` " ERROR=1 } ;; PRODUCT) P_SetRoot P_ValidProd || { ERROR=1 continue } [ "$PATCH_DEBUG" ] && echo "\n=== Valid products are: $_VALIDPROD" NOT_VALID= U_VALIDPROD=`ToUpper $_VALIDPROD` case $_TYPE in INSTALL) PRODMAP=$_KIT_PRODMAP ;; DELETE) PRODMAP=$_SYS_PRODMAP ;; esac SEL_LIST= for P in $_PRODUCT_LIST { UA=`ToUpper $P` ALL_VALID="$U_VALIDPROD ALL" Member $UA $ALL_VALID || { NOT_VALID=1 P_Error " \"$P\" is not a valid product_id specification for this operation." continue } SEL=`S_ProdmapGet pvcode $PRODMAP $UA` SEL_LIST="$SEL_LIST $SEL" } [ "$NOT_VALID" ] && { ERROR=1 P_Error " Valid product_id specifications on your system for this operation are: " for V in $_VALIDPROD all { echo "\t\t$V" } continue } Member ALL `ToUpper $_PRODUCT_LIST` || { _PVS=$SEL_LIST } _ARG_PRODUCT=$_PVS [ "$PATCH_DEBUG" ] && { echo "=== _ARG_PRODUCT=$_ARG_PRODUCT" echo "=== _PRODUCT_LIST=$_PRODUCT_LIST" } ;; esac [ "$PATCH_DEBUG" ] && { eval SS=\$_SW_$CS eval AA=\$_ARG_$CS echo "=== _SW_$CS=$SS _ARG_$CS=$AA" } } case $_TYPE in INSTALL | DELETE ) [ "$_SW_PRODUCT" ] || { P_SetRoot P_ValidProd if [ $? = 0 ]; then { [ `Length $_VALIDPROD` -gt 1 ] && { P_Error " There are more than one products available for this operation. You must use the \"-product\" switch to specify the product(s). and the \"-product\" switch must preceed the \"-patch\" switch. Valid product_id specifications on your system for this operation are: " for V in $_VALIDPROD all { echo "\t\t$V" } ERROR=1 } } else ERROR=1 fi } ;; esac return "$ERROR" } P_ArgsData () { if [ "$_ARG_DATA" ]; then { _ARG_DATA=`P_AbsPath $_ARG_DATA` [ -f $_ARG_DATA ] || { P_Error " \"$_ARG_DATA\" does not exist or is not a file." return 1 } } else { P_Error " The \"-data\" switch requires a file path as its argument." return 1 } fi eval SWLIST=\$_${_TYPE}_SW TMP=$_DUPATCH_TMP/$_PROG.tmp unlink $TMP 2>/dev/null > $TMP || exit 1 [ "$_PRDFLG" ] || _CMD_LINE_ERR=Y _PATFLG=Y; _PRDFLG=Y; _PRD1ST=${_PRD1ST:-""}; _WHICHFIRST=${_WHICHFIRST:-""}; cat $_ARG_DATA | while read LINE do TMPERR= [ "$LINE" ] || continue LINE=`echo $LINE` case $LINE in \#*) continue ;; esac LINE=`echo $LINE | awk -F# '{print $1}'` LV=`echo $LINE | awk -F= '{print $1}'` LVAL=`ToUpper \`echo $LV\`` RV=`echo $LINE | awk -F= '{print $2}'` if [ $LVAL = "PATCH" ]; then RV=`P_Remove_Spaces $RV` RVAL=`ToUpper \`echo $RV\`` else RVAL=`echo $RV` fi [ ! "$LVAL" -a ! "$RVAL" ] && continue case "$LVAL" in PATCH | PRODUCT) { P_SetSwitch $LVAL $RVAL P_ArgsPidParse $LVAL $RVAL || continue case "$LVAL" in PATCH) [ -z "$_WHICHFIRST" ] && _WHICHFIRST=1; echo "_WHICHFIRST=1" >> $TMP [ "$_PATFLG" ] || { P_Error "\n\"$LV\" is not a valid data-file switch here; only one \"-patch\" switch per product switch allowed " TMPERR=Y echo "TMPERR=Y" >>$TMP continue } P_ArgsPatchAdd $TMP _PATFLG=; _PRDFLG=Y echo "_PATFLG=\"\"; _PRDFLG=Y;" >>$TMP ;; PRODUCT) [ -z "$_WHICHFIRST" ] && _WHICHFIRST=2; echo "_WHICHFIRST=2" >>$TMP [ "$_PRDFLG" ] || { P_Error "\n\"$LV\" is not a valid data-file switch here; was expecting \"-patch\" switch" TMPERR=Y echo "TMPERR=Y" >>$TMP continue } [ "$_PATFLG" ] && { _PRD1ST=Y echo "_PRD1ST=Y;" >>$TMP } _PRODUCT_LIST="$_PRODUCT_LIST $_ARG_PRODUCT" echo _PRODUCT_LIST=\"$_PRODUCT_LIST\" >>$TMP _PRDFLG=; _PATFLG=Y echo "_PRDFLG=\"\"; _PATFLG=Y;" >>$TMP ;; esac echo "_SW_$LVAL=$LVAL" >> $TMP echo _ARG_$LVAL=\"`echo $RVAL|sed 's/\"//g'`\" >>$TMP } ;; *) eval SW=\$_SW_$LVAL [ "$SW" ] || { echo "_SW_$LVAL=$LVAL" >> $TMP echo _ARG_$LVAL=\"`echo $RVAL|sed 's/\"//g'`\" >>$TMP } ;; esac done . $TMP [ "$TMPERR" ] && # any errors from TMP file? { rm -f $TMP # yup - bale out... return 1 } [ "$PATCH_DEBUG" ] && { echo "\n=== After processing data file" cat $TMP } rm -f $TMP return 0 } P_ArgsInit () { _OPS="-install | -delete | -track | -help" _DUPATCH_REV=52-00; export _DUPATCH_REV _MAX_LOGS=25; export _MAX_LOGS _CSPC="C" # special Customer Specific Patch Character export _CSPC _N_ALRDY_INS=0 _N_FAIL=0 _N_OK=0 _N_SEL=0 export _N_ALRDY_INS _N_FAIL _N_OK _N_SEL _CMDLINE= _ALLARGS=$* _PATFLG= _PRDFLG= _PRD1ST= export _PATFLG _PRDFLG _PRD1ST _CMD_LINE_ERR= _DATA_FILE_ERR= export _CMD_LINE_ERR _DATA_FILE_ERR OSKitDir=/var/adm/update/OSKit/instctrl export OSKitDir _DELETE_SW="CFGFILE \ DATA \ KIT \ NAME \ NOAUTO \ NOLOG \ NOROLL \ NOTE \ PATCH \ PROCEED \ PRODUCT \ ROOT" _HELP_SW="DATA_FILE \ KIT \ PATCH_ID \ PRODUCT_ID \ REV \ ROOT_PATH" _INSTALL_SW="CFGFILE \ DATA \ KIT \ LICENSE \ NAME \ NOAUTO \ NOBACKUP \ NOLOG \ NOROLL \ NOTE \ PATCH \ PRECHECK_ONLY \ PROCEED \ PRODUCT \ SINGLE_USER \ ROOT" _TRACK_SW="DATA \ KIT \ NOLOG \ ROOT \ TYPE" _DELETE_MAND="NAME NOTE PATCH" _INSTALL_MAND="KIT NAME NOTE PATCH" _PRECHECK_ONLY_MAND="KIT PATCH" _TRACK_MAND="TYPE" _HISTORY_MAND="PATCH" _HISTORY_ALL_MAND="REL CUST ALL" _HISTORY_KEY="REL CUST ALL" _HISTORY_ALL_KEY="REL CUST ALL" _TYPE_KEY="PATCH PATCH_LEVEL FILE KIT HISTORY HISTORY_ALL" _PRODUCT_LIST= _PATCH_LIST= _ALLSW="CFGFILE \ DATA \ DATA_FILE \ KIT \ LICENSE \ NAME \ NOAUTO \ NOBACKUP \ NOLOG \ NOROLL \ NOTE \ PATCH \ PATCH_ID \ PRECHECK_ONLY \ PROCEED \ PRODUCT \ PRODUCT_ID \ REV \ ROOT \ ROOT_PATCH \ SINGLE_USER \ TYPE" DELETE_USAGE=" $_PROG -delete [mandatory switches]: -name -note -patch [optional switches]: -cfgfile # configuration file for kernel rebuild -data -noauto # do not perform automatic kernel build and/or reboot -nolog # no session logging -noroll # if patching a cluster, do -proceed # proceed with patches that passed pre-deletion check -product * -root * mandatory when more than one product is available for operation. PLEASE NOTE that in this case, the \"-product\" and \"-patch\" switches MUST be paired together. ** if the -product switch is \"all\", then the -patch switch MUST ALSO BE \"all\"." HELP_USAGE=" $_PROG -help [optional switches]: -data_file # specifies data_file usage -kit -patch_id # specifies patch_id usage -rev # lists $_PROG revision -product_id # specifies product_id usage" INSTALL_USAGE=" $_PROG -install [mandatory switches]: -kit -name * -note * -patch * optional when -precheck_only is specified. [optional switches]: -cfgfile # configuration file for kernel rebuild -data -license # license agreement -noauto # do not perform automatic kernel build and/or reboot -nobackup -nolog # no session logging -noroll # if patching a cluster, do -precheck_only # check patch applicability without installing. -proceed # proceed with patches that passed pre-installation check -product * -root -single_user # if in multi-user, bring the system to single-user before installing patches. * mandatory when more than one product is available for operation. PLEASE NOTE that in this case, the \"-product\" and \"-patch\" switches MUST be paired together. ** if the -product switch is \"all\", then the -patch switch MUST ALSO BE \"all\"." TRACK_USAGE=" $_PROG -track [mandatory switches]: -type * * use \"file\" to list all patched files. * use \"kit\" to list installed patch kits. * use \"patch\" to list installed patches. * use \"patch_level\" to list installed verbose description of patch kits,CSPs or ERPs. * use \"history\" to list patch installations history. Requires -product switch when multiple products are on the system * use \"history_all\" to list history of all patch installations -kit # for loading new tools [optional switches]: -data -nolog # no session logging -root " ALL_USAGE="When invoked without any arguments, you will be presented with the interactive menu interface and will be prompted for needed command arguments. You can also use the command line interface to make the operations non-interactive. In this case, all mandatory switches must be specified. The following is a description of the command line interface: $DELETE_USAGE $HELP_USAGE $INSTALL_USAGE $TRACK_USAGE" DATA_FILE_USAGE=" : When using the \"-data\" switch, you must specify a data_file which is a file path and contains specifications with the following format: switch1=value switch2=value . . switch3 Example: kit = /mnt name = John Doe note = install April patch kit product = DIGITAL_UNIX_V4.0D patch = 27.01 63.00 74 83.01 product = TruCluster_V1.5 patch = 21.01 27.01 40 precheck_only nobackup - blank lines and comments (preceded with #) are allowed. - line continuation (\) is required if a specification spans multiple lines. - only one data-file switch is permitted per command-line - data-files cannot contain data-files " REV_USAGE=" Tru64 UNIX Patch Utility (Rev. $_DUPATCH_REV) " ROOT_PATH_USAGE=" : - the \"-root\" switch is similar to the \"-D\" switch of setld (8), which specifies an alternative root for the specified operation. - root_path must be the root of a complete Tru64 UNIX file system. - The default root_path is / for all operations. " _TOOLSUB=00000; export _TOOLSUB _PID=[0-9][0-9][0-9][0-9][0-9] _VID=[0-9][0-9] export _PID _VID } P_ArgsMand () { eval MANDLIST=\$_${_TYPE}_MAND [ "$_SW_PRECHECK_ONLY" ] && MANDLIST=$_PRECHECK_ONLY_MAND MAND_MISSING= for M in $MANDLIST { eval ARG=\$_ARG_$M [ "$ARG" ] || MAND_MISSING="$MAND_MISSING -`ToLower $M`" } [ "$MAND_MISSING" ] && { P_Error " You must specify the following mandatory switch(es): $MAND_MISSING" return 1 } return 0 } P_ArgsPatchAdd () { FILE=$1 [ "$_ARG_PATCH" ] || return 0 for J in $_ARG_PATCH { J=`ToUpper $J` if [ "$_ARG_PRODUCT" ]; then { for P in $_ARG_PRODUCT { _PATCH_LIST="$_PATCH_LIST $P:$J" } } else _PATCH_LIST="$_PATCH_LIST :$J" fi [ -f $FILE ] && echo _PATCH_LIST=\"$_PATCH_LIST\" >> $FILE } [ "$PATCH_DEBUG" ] && { echo "=== _PATCH_LIST=$_PATCH_LIST" } return 0 } P_ArgsPatchMap () { [ "$_PATCH_LIST" ] || return 0 WCOUNT=0; RES=0; PLIST= PSUB_ERROR= for J in $_PATCH_LIST { PROD=`echo $J | awk -F: '{print $1}'` PID=`echo $J | awk -F: '{print $2}'` if [ "$PROD" ]; then { if [ `Ucase $PROD` = ALL ]; then if [ `Ucase $PID` = ALL ]; then PVS=$_PVS else P_Error " If the product switch argument is \"all\" then the patch switch must have \"all\" as its argument" return 1 fi else PVS=`S_ProdmapGet pvcode $PRODMAP $PROD` fi } else { PVS=$_PVS } fi for PV in $PVS { PCODE=`expr "$PV" : '\(...\)...'` VCODE=`expr "$PV" : '...\(...\)'` eval PNAME=\$_PNAME$PV case "$PID" in ALL) ID=????? RV=?? RES=? ;; *) # process reserved, patch id, separate patch id and rev number. RES="`expr $PID : '^\(.\)'`" [ "$RES" = "$_CSPC" ] || { RES=0 } if [ "$RES" != "0" ]; then ID=`echo $PID | sed 's/^'$_CSPC'//' | awk -F. '{printf "%05d", $1}'` else ID=`echo $PID | awk -F. '{print $1}'` fi if [ "$ID" ]; then ID=`echo $ID | awk '{printf "%05d", $1}'` else ID=????? fi RV=`echo $PID | awk -F. '{print $2}'` if [ "$RV" ]; then RV=`echo $RV | awk '{printf "%02d", $1}'` else RV=?? fi [ "$PATCH_DEBUG" ] && echo "$PID->RES=$RES,ID=$ID.RV=$RV" ;; esac case "$_TYPE" in INSTALL) eval KITDIR=\$_KITDIR$PV PSUB=`(cd $KITDIR; ls ${PCODE}PAT${RES}${ID}${RV}${VCODE} 2>/dev/null)` [ "$PSUB" ] || { P_Error " $PNAME Patch \"$PID\" is not available on the specified patch kit." PSUB_ERROR=1 continue } STL_DepInit LIST= for S in $PSUB { STL_DepEval $S && { case $S in ???PAT?$_TOOLSUB*) continue ;; esac eval INSTDIR=\$_INSTDIR$PV SDESC=`S_ListPatches $S` P_Error "$SDESC is already installed and will not be included in this operation." continue } LIST="$LIST $S" } [ "$PID" = "ALL" ] && { _SUBS_TO_CHECK="$LIST" OK= NOT_OK= PareDownPatches $KITDIR/instctrl [ "$?" = 1 ] && { [ "$PATCH_DEBUG" ] && echo "NOT OK list = " $NOT_OK LIST=$OK } } unset NOT_OK OK SUBS_TO_CHECK PLIST="$PLIST $LIST" ;; DELETE|TRACK) PSUB=`(cd $_SMDB; ls ${PCODE}PAT${RES}${ID}${RV}${VCODE}.lk 2>/dev/null | sed 's/\.lk//')` [ "$PSUB" ] || { STR2="for $PNAME" case "$PID" in ALL) STR1="No patches" STR3=are ;; *) STR1="Patch \"$PID\"" STR3="is not" ;; esac P_Error " $STR1 $STR2 $STR3 installed on your system." continue } PLIST="$PLIST $PSUB" ;; esac } } _N_ALRDY_INS=$WCOUNT [ "$PSUB_ERROR" ] && return 1 _ARG_PATCH=`echo $PLIST` [ "$_TYPE" = DELETE ] && { _ARG_PATCH=`P_FilterTools lk $_SMDB $_ARG_PATCH` } [ "$PATCH_DEBUG" ] && echo "\n=== _ARG_PATCH=$_ARG_PATCH." [ "$_ARG_PATCH" ] || { case "$_TYPE" in INSTALL)STR=installable ;; DELETE) STR=deletable ;; TRACK) STR=trackable ;; esac [ "$_INSTALL_PRECHECK" ] && { P_Error " \007 ************************************************************** Pre-Installation Check COMPLETED with the following results: $_N_ALRDY_INS patches were already installed ************************************************************** \007 " } P_Error " There are no $STR patches as specified on the command line. " P_Exit 2 } TMP=$_DUPATCH_TMP/patchmap.tmp unlink $TMP 2>/dev/null > $TMP || exit 1 for P in $_ARG_PATCH { echo $P >> $TMP } _ARG_PATCH=`cat $TMP | sort -u` rm -f $TMP [ "$PATCH_DEBUG" ] && { echo "=== _ARG_PATCH=$_ARG_PATCH" } return 0 } P_ArgsPidMsg () {( PTYPE=$1 # PATCH or PRODUCT CASE=$2 SWITCH=`ToLower $PTYPE` PTYPE=`ToLower $SWITCH | sed 's/$/_id/'` TAB= PREFIX= [ "$_TYPE" = HELP ] && { PREFIX="\n<$PTYPE usage>:\n" TAB="\t- " } STR_ALLMIX="\n${TAB}The keyword 'all' can not be combined with other ${PTYPE}s." case $PTYPE in patch_id) STR_ID="\n${TAB}A valid patch_id specification is in the format of:\n\n\t\t'all' [c]xxxxx[.yy]\n\n\t\t\twhere \"xxxxx\" is the patch identifier,\n\t\t\tc is the CSP indicator,\n\t\t\tand \"yy\" is the patch revision.\n\n\t\tExamples:\n\n\t\t\t15\n\t\t\t200.11\n\t\t\tc10.2\n\t\t\t00111.02\n\n\t- Both xxxxx and yy are numeric values; leading zeros can be omitted.\n\n\t- Patch revision (yy), when left unspecified, maps to wildcarded \"??\".\n\n\t- Multiple patch_id specifications are separated by white space." ;; product_id) STR_ID="\n${TAB}A valid product_id specification is in the format of:\n\n\t\t'all' description_version\n\n\t\t\twhere \"description\" is the product description,\n\t\t\tand \"version\" is the product version.\n\n\t\tExamples:\n\n\t\t\tDIGITAL_UNIX_V4.0B\n\t\t\tTruCluster_V1.4A\n\n\t- product_id specifications are case insensitive.\n\n\t- Wildcards are not allowed in product_id specifications.\n\n\t- Multiple product_id specifications are separated by white space." ;; esac STR_ALL="$PREFIX$STR_ID\n$STR_ALLMIX\n" eval STR=\$STR_$CASE if [ "$_TYPE" = HELP ]; then echo $STR else P_Error $STR fi return 0 )} P_ArgsPidParse () {( PTYPE=$1; shift VAL=$* PID_ERR= [ "$VAL" ] || { P_ArgsPidMsg $PTYPE NOARG PID_ERR=1 } NUM=`Length $VAL` for P in $VAL { P=`ToUpper $P` case $P in ALL) [ "$NUM" -eq 1 ] && return 0 P_ArgsPidMsg $PTYPE ALLMIX PID_ERR=1 continue ;; esac [ "$PTYPE" = PRODUCT ] && continue ID=`echo $P| awk -F. '{print $1}'` RV=`echo $P | awk -F. '{print $2}'` [ "$ID" ] || { PID_ERR=1 P_Error " \"$P\" is not a valid patch_id specification." continue } case $ID in T64* ) ;; $_CSPC[0-9] | \ $_CSPC[0-9][0-9] | \ $_CSPC[0-9][0-9][0-9] | \ $_CSPC[0-9][0-9][0-9][0-9] | \ $_CSPC[0-9][0-9][0-9][0-9][0-9]) ;; [0-9] | \ [0-9][0-9] | \ [0-9][0-9][0-9] | \ [0-9][0-9][0-9][0-9] | \ [0-9][0-9][0-9][0-9][0-9]) ;; *) PID_ERR=1 P_Error " \"$P\" is not a valid patch_id specification." continue ;; esac [ "$RV" ] && { case $RV in [0-9] | \ [0-9][0-9]) ;; *) PID_ERR=1 P_Error " \"$P\" is not a valid patch_id specification." continue ;; esac } } [ "$PID_ERR" ] && { P_ArgsPidMsg $PTYPE ID ERR=1 } return $ERR )} P_ArgsSub () { P_ArgsInit $* [ "$_ARGS_DONE" ] && return 0 ERR=0 [ $# -eq 0 ] && return 0 _PATFLG=Y; _PRDFLG=Y; _PRD1ST=${_PRD1ST:-""}; _WHICHFIRST=${_WHICHFIRST:-""}; RT_NA_ONLY=1 while : do [ $# -eq 0 ] && break SW=$1 USW=`ToUpper $SW` S=`echo $SW | sed 's/^-//'` S=`ToUpper $S` case $USW in -DELETE | \ -HELP | \ -INSTALL| \ -TRACK ) [ "$_CMDLINE" ] && P_Ferror 1 " You can only specify ONE of the following operations in one command: $_OPS" _CMDLINE=$S _TYPE=$_CMDLINE _CMDLINE_TEXT="$CMDPATH $*" export _TYPE _CMDLINE _CMDLINE_TEXT case $USW in -INSTALL) P_CheckEnv Y N || return 1 ;; -DELETE) P_CheckEnv Y N || return 1 ;; esac shift RT_NA_ONLY=0 ;; -NOBACKUP| \ -CFGFILE | \ -DATA | \ -DATA_FILE| \ -HISTORY| \ -HISTORY_ALL| \ -KIT | \ -LICENSE | \ -NAME | \ -NOTE | \ -NOLOG | \ -PATCH_ID | \ -PRODUCT_ID | \ -PRECHECK_ONLY | \ -PROCEED | \ -REV | \ -ROOT | \ -ROOT_PATH | \ -SINGLE_USER | \ -NOAUTO | \ -NOROLL | \ -TYPE) [ $S = ROOT -o $S = NOAUTO ] || RT_NA_ONLY=0 P_SetSwitch $* shift $_SHIFT ;; -PATCH | -PRODUCT) P_SetSwitch $* shift $_SHIFT eval PLIST=\$_ARG_$S P_ArgsPidParse $S "$PLIST" || { ERR=1 continue } case $USW in -PATCH) if [ -z "$_WHICHFIRST" ]; then _WHICHFIRST=1 fi [ "$_PATFLG" ] || { P_Error "\n\"$SW\" is not a valid comman d-line switch here; only one \"-patch\" switch per product switch allowed" ERR=1 return 1 } P_ArgsPatchAdd /dev/null _PATFLG=; _PRDFLG=Y ;; -PRODUCT) if [ -z "$_WHICHFIRST" ]; then _WHICHFIRST=2 fi [ "$_PRDFLG" ] || { P_Error "\n\"$SW\" is not a valid comman d-line switch here; was expecting \"-patch\" switch" ERR=1 return 1 } [ "$_PATFLG" ] && _PRD1ST=Y _PRODUCT_LIST="$_PRODUCT_LIST $_ARG_PRODUCT" _PRDFLG=; _PATFLG=Y ;; esac RT_NA_ONLY=0 ;; *) # bad switches P_Error "\n\"$SW\" is not a valid switch" P_Usage $_TYPE P_Exit 1 ;; esac done [ $RT_NA_ONLY = 1 ] && { [ "$_SW_ROOT" ] && { export _SW_ROOT; export _ARG_ROOT; } [ "$_SW_NOAUTO" ] && { export _SW_NOAUTO; } _ARGS_DONE=1 export _ARGS_DONE return 0 } [ "$_TYPE" ] || { P_Usage P_Ferror 1 " For command line interface, you must specify one of the following operations: $_OPS specify no operations on the command line to use the menu interface. " } [ "$PATCH_DEBUG" ] && echo "\n=== operation = $_TYPE\n" [ "$_SW_DATA" ] && { P_ArgsData || ERR=1 } P_ArgsCheck || ERR=1 [ "$ERR" = 1 ] && { P_Usage $_TYPE return 1 } [ "$_CMD_LINE_ERR" ] && { P_Error "ERROR: -product / -patch pair mis-match found in comma nd-line - please correct before re-running dupatch..." P_Usage $_TYPE ERR=1 return 1 } [ "$_DATA_FILE_ERR" ] && { P_Error "ERROR: product / patch pair mis-match found in data-fi le - please correct before re-running dupatch..." P_Usage $_TYPE ERR=1 return 1 } [ "$_TYPE" = HELP ] && { P_Usage HELP P_Exit 0 } case "$_CMDLINE" in DELETE ) case "$_ARG_PATCH" in *T64* ) ;; * ) _RMIK= ;; esac ;; * ) _RMIK= ;; esac [ "$_RMIK" ] || { P_ArgsPatchMap || { P_Usage $_TYPE return 1 } } for S in $_ALLSW { export _SW_$S export _ARG_$S } _ARGS_DONE=1; export _ARGS_DONE return 0 } P_CheckEnv () { SUPER=$1 SINGLE=$2 ERR=0 [ "$SUPER" = Y ] && { [ `id -u` -ne "0" ] && { echo " This operation can be performed by the super-user (root) only." ERR=1 } } [ "$SINGLE" = Y -a "$_ROOT" = "/" ] && { set -- `who -r` while [ "$1" -a "$1" != "run-level" ] do shift done [ "$2" = "S" -o "$2" = "" ] || { echo " This operation can be performed in single-user mode only." ERR=1 } } return $ERR } P_Cleanup () { trap '' 0 P_Unlock_pat if [ "$_DUPATCH_TMP" != / -a ! -f "$SCHED_REBOOT" ]; then rm -rf $_DUPATCH_TMP [ "$PATCH_DEBUG" ] && echo "\n=== $_DUPATCH_TMP removed." fi S_ShellArgLimit on [ -f /etc/evmlogger.conf.orig ] && { mv /etc/evmlogger.conf.orig /etc/evmlogger.conf 2>/dev/null } } P_Error () { 1>&2 echo "$*" } P_Exit () { STAT=$1 P_Cleanup exit $STAT } P_Ferror () { STAT=$1 P_Error "$_PROG: $2" P_Exit $STAT } P_FilterTools () {( TYPE=$1 LOC=$2; shift 2 SUBS=$* TMP1=$_DUPATCH_TMP/filtertools.tmp1 if [ "$TYPE" = "lk" ]; then (cd $LOC; SWDB_FindInstalledSubsets "OSFPAT?$_TOOLSUB*") >$TMP1 else (cd $LOC; ls OSFPAT?$_TOOLSUB*.$TYPE 2>/dev/null | sed 's/\.'$TYPE'//g' ) >$TMP1 fi [ "$TMP1" ] || { echo $SUBS rm -f $TMP1 return 0 } TMP2=$_DUPATCH_TMP/filtertools.tmp2 > $TMP2 for S in $SUBS { echo $S >> $TMP2 } comm -23 $TMP2 $TMP1 rm -f $TMP1 $TMP2 return 0 )} P_GetFirstEntry () { echo $1 } P_HighestVerInstalled () { ( ID=$1 [ "$ID" = "OSF" ] && ID=OSFBASE cd $_SMDB VCODE=`ls -1 ${ID}*.lk 2>/dev/null | \ sed 's/\('$ID'\).*\(...\)\(\.lk\)/\2/' | \ sed 's/.*[\?\*].*//g' | sort -ru | head -1` [ "$VCODE" ] || VCODE=000 echo $VCODE return 0 ) } P_KitLocCheck () { P=`P_AbsPath $1` [ -d $P ] || { P_Error " $P does not exist" return 1 } TP= set -- `echo $P | sed 's#/# #g'` while [ $# -gt 0 ] do TP="/$TP/$1" [ -h "$TP" ] && { P_Error " This is a symbolic link. Please untar the patch kit at any mountable file system which is not a context dependant symbolic link." P_Exit 1 } shift done [ -d $P/kit ] && { [ -d $P/kit/instctrl ] || { P_Error " $P/kit does not contain a Tru64 UNIX setld format patch kit. " return 1 } [ -d $P/doc ] || { P_Error " $P/doc does not exist. $P does not contain a complete patch kit. " return 1 } P_KitLocSet $P single || return 1 return 0 } [ -d $P/*/kit/instctrl ] || { P_Error " $P does not contain any Tru64 UNIX setld format patch kit. " return 1 } [ -d $P/patch_tools ] || { P_Error " $P/patch_tools does not exist. $P does not contain a complete patch kit. " return 1 } [ -f $P/patch_tools/product_map ] || { P_Error " $P/patch_tools/product_map does not exist. $P does not contain a complete patch kit. " return 1 } P_KitLocSet $P multi || return 1 return 0 } P_KitLocGet () { [ "$_DUPATCH_EXEC" ] && { _DUPATCH_EXEC= return 0 } [ "$_ARG_KIT" ] && { P_KitLocCheck $_ARG_KIT return $? } STR="get back to the menu" [ "$TRIM" ] && STR=quit while : do Dialog " Enter path to the top of the patch distribution, or enter \"q\" to $STR " P $_KIT_TOP case $P in q|Q) return 1 ;; *) P_KitLocCheck $P && return 0 ;; esac done return 0 } P_KitLocSet () { _KIT_TOP=$1 _FORMAT=$2 [ "$_FORMAT" = single ] && { SUB_CTRL=`(cd $_KIT_TOP/kit/instctrl; ls -1 *.ctrl | head -1)` [ "$SUB_CTRL" ] || { P_Error " No subset control file (.ctrl) in $_KIT_TOP/kit/instctrl. " return 1 } SUB=`echo $SUB_CTRL | sed 's/\.ctrl//'` PRODUCT=`echo $SUB | sed 's/\(...\).*\(...\)$/\1\2/'` } _PVS= _KIT_PRODMAP= [ -f $_KIT_TOP/../patch_tools/product_map ] && _KIT_TOP=$_KIT_TOP/.. [ -f $_KIT_TOP/patch_tools/product_map ] && _KIT_PRODMAP=$_KIT_TOP/patch_tools/product_map if [ "$_KIT_PRODMAP" ]; then { for PROD in `cat $_KIT_PRODMAP | awk -F% '{print $1"%"$2"%"$3"% "}'` { eval `echo $PROD | \ awk -F% '{print "PNAME="$1" PCODE="$2" VCODE="$3}'` SYS_VCODE=`P_HighestVerInstalled $PCODE` [ "$VCODE" = "$SYS_VCODE" ] && { _PVS="$_PVS $PCODE$VCODE" } } } else { PCODE=`expr "$PRODUCT" : '\(...\)...'` VCODE=`expr "$PRODUCT" : '...\(...\)'` SYS_VCODE=`P_HighestVerInstalled $PCODE` [ "$VCODE" = "$SYS_VCODE" ] && { _PVS="$_PVS $PCODE$VCODE" } } fi P_ProdCacheInfo [ "$_PVS" ] || { P_Error " $_KIT_TOP does not contain any patch kit(s) applicable to your system. " return 1 } [ "$_FORMAT" = single ] && _PVS=$PRODUCT export _KIT_TOP _KIT_PRODMAP _PVS _FORMAT [ "$PATCH_DEBUG" ] && { echo "\n=== _KIT_TOP=$_KIT_TOP" echo "\n=== available _PVS=$_PVS" } return 0 } P_Lock_pat() { P_Cklock_pat || return 1 mknod $_DUPATCH_LK_DIR/patlock p echo $_PATCH_TERM > $_DUPATCH_LK_DIR/pat.tty.lock echo $_PATCH_TERM > $_DUPATCH_TMP/patchterm ( exec < $_DUPATCH_LK_DIR/patlock read X rm -f $_DUPATCH_LK_DIR/patlock $_DUPATCH_LK_DIR/pat.tty.lock ) & } P_Cklock_pat () { [ -p $_DUPATCH_LK_DIR/patlock ] && { [ -f $_DUPATCH_LK_DIR/pat.tty.lock ] || { rm -f $_DUPATCH_LK_DIR/patlock return 0 } TTY=`sed -e "s/\/dev\///" $_DUPATCH_LK_DIR/pat.tty.lock` [ "$TTY" ] || { rm -f $_DUPATCH_LK_DIR/patlock \ $_DUPATCH_LK_DIR/pat.tty.lock return 0 } set -- `who | grep $TTY` PERSON=$1; TTY=$2 [ "$PERSON" -a "$TTY" ] || { rm -f $_DUPATCH_LK_DIR/patlock \ $_DUPATCH_LK_DIR/pat.tty.lock return 0 } echo " The dupatch utility is currently locked by $PERSON on /dev/$TTY. If it is determined that this person is no longer running dupatch, the lock files can be removed by issuing the command \"rm $_DUPATCH_LK_DIR/pat*\" ." \ | fmt -78 return 1 } return 0 } P_Unlock_pat() { _TERM=`cat $_DUPATCH_LK_DIR/pat.tty.lock 2>/dev/null` _PATCH_TERM=`cat $_DUPATCH_TMP/patchterm 2>/dev/null` [ "$_TERM" = "$_PATCH_TERM" ] && { [ -p $_DUPATCH_LK_DIR/patlock ] && echo >$_DUPATCH_LK_DIR/patlock } trap 1 2 3 } P_UnlockAndExit() { SetupforReboot P_Unlock_pat P_Exit 1 } P_LogInit () { echo "\n" >> $_EVENT_LOG echo "$_DUPATCH_REV" | $_AWK -v NAME=DUPATCH_REV "$_AWKLOG" >> $_EVENT_LOG [ "$_CMDLINE" ] && { echo "$_DPWD" | $_AWK -v NAME=CUR_DIR "$_AWKLOG" >> $_EVENT_LOG echo "$_CMDLINE_TEXT" | $_AWK -v NAME=CMDLINE "$_AWKLOG" >> $_EVENT_LOG [ "$_ARG_DATA" ] && cat $_ARG_DATA | $_AWK -v NAME=DATAFILE "$_AWKLOG" >> $_EVENT_LOG } [ "$TRIM" ] || { CheckIfCluster && { if [ "$NOROLL_PATCH" ] then _TYPE2=$_TYPE"_NOROLL_PATCH" else _TYPE2=$_TYPE"_ROLLING_PATCH" fi _TYPE=$_TYPE2 } } ToLower $_TYPE | $_AWK -v NAME=TYPE "$_AWKLOG" >> $_EVENT_LOG echo "$_USERNAME" | $_AWK -v NAME=NAME "$_AWKLOG" >> $_EVENT_LOG echo "$USER" | $_AWK -v NAME=USER "$_AWKLOG" >> $_EVENT_LOG echo `date` | $_AWK -v NAME=DATE "$_AWKLOG" >> $_EVENT_LOG echo "$_USERNOTES" | $_AWK -v NAME=NOTES "$_AWKLOG" >> $_EVENT_LOG set -- `who -r` while [ "$1" -a "$1" != "run-level" ] do shift done if [ "$2" = "S" -o "$2" = "" ]; then _CURRENT_USER_MODE="Single_User" else _CURRENT_USER_MODE="Multi_User" fi echo "$_CURRENT_USER_MODE" | $_AWK -v NAME=CURRENT_MODE "$_AWKLOG" >> $_EVENT_LOG } P_Make_TMP () { _DUPATCH_TMP=/var/tmp/patch$$ mkdir -m 755 -p $_DUPATCH_TMP || { P_Error "Could not create directory $_DUPATCH_TMP. dupatch will terminate." P_Exit 1 } TMPDIR_CREATED=Y export TMPDIR_CREATED _DUPATCH_TMP } PareDownPatches () { OK= NOT_OK= [ "$_IS_SERVICEPACK" = "Y" ] || { return 0 } INSTDIR=$1 STL_DepInit for pat in $_SUBS_TO_CHECK { SWDB_IsInstalled $pat && { continue } eval `grep -E "^PATCH_DEPS=" $INSTDIR/$pat.ctrl` ERR= for SOME_SUB in $PATCH_DEPS { STL_DepEval $SOME_SUB || { ERR=1 NOT_OK="$NOT_OK $pat" continue 2 } } [ "$ERR" ] || OK="$OK $pat" } [ "$PATCH_DEBUG" ] && { echo "OK'd list = " $OK echo "NOT OK list = " $NOT_OK } [ "$NOT_OK" ] && return 1 return 0 } P_PatchesAvailable () { _FILE_TYPE=$1 LOC=$2 VAR=$3 MSG=$4 _PR=$5 TYSTR=$6 _PR=${_PR:-"?"} SYSVER=`P_HighestVerInstalled OSFBASE` [ "$SYSVER" -lt 505 ] && SYSVER="???" [ "$PATCH_DEBUG" ] && { echo "called P_PatchesAvailable(_FILE_TYPE=$_FILE_TYPE,LOC=$LOC,VAR=$VAR,MSG=$MSG,_PR=$5->$_PR,TYSTR=$TYSTR)" } SUBLIST=`(cd $LOC; ls ???PAT${_PR}${_PID}${_VID}${SYSVER}.${_FILE_TYPE} 2>/dev/null | sed 's/\.'$_FILE_TYPE'//g' )` [ "$PATCH_DEBUG" ] && echo "Found Subset List of $SUBLIST" SUBLIST=`P_FilterTools ${_FILE_TYPE} $LOC $SUBLIST` [ "$SUBLIST" ] && { eval $VAR=\$SUBLIST return 0 } [ "$MSG" = MSG ] && { STR= [ "$_ROOT" != / ] && STR=" (rooted at $_ROOT)" P_Error " *** There are no $TYSTR patches installed on your system$STR ***" } eval $VAR= return 1 } P_SCPExtDataEdit () { if [ -f $SCPEXTDIRBL/*.scp_extension ]; then { [ "$PATCH_DEBUG" ] && echo "Copying $SCPEXTDIRBL/*.scp_extension to $_SMDB" cp -p $SCPEXTDIRBL/*.scp_extension $_SMDB } fi SCP_EXT_DATA_LIST=`(cd $SCPEXTDIRBL; /bin/ls -1 *.scp_extension_data 2>/dev/null)` for SCPEXT_DATAFILE in $SCP_EXT_DATA_LIST { [ -f $_SMDB/$SCPEXT_DATAFILE ] || { [ "$PATCH_DEBUG" ] && echo "Copying $SCPEXT_DATAFILE to $_SMDB" cp -p $SCPEXTDIRBL/$SCPEXT_DATAFILE $_SMDB continue } sort -u $_SMDB/$SCPEXT_DATAFILE $SCPEXTDIRBL/$SCPEXT_DATAFILE > $PCITMP1 grep "^#" $PCITMP1 | sed 's/^\#//' > $PCITMP2 [ -s $PCITMP2 ] || { [ "$PATCH_DEBUG" ] && echo "Copying merged $SCPEXT_DATAFILE to $_SMDB" cp -p $PCITMP1 $_SMDB/$SCPEXT_DATAFILE continue } comm -23 $PCITMP1 $PCITMP2 > $PCITMP3 [ "$PATCH_DEBUG" ] && echo "Copying merged and deleted $SCPEXT_DATAFILE to $_SMDB" cp -p $PCITMP3 $_SMDB/$SCPEXT_DATAFILE } return } P_SetUpProductPaths () { Z1_TMP=$_DUPATCH_TMP/prodpath.tmp > $Z1_TMP # clear the output file while read prod_line; do N=`echo $prod_line | awk -F% '{print $1}'` P=`echo $prod_line | awk -F% '{print $2}'` V=`echo $prod_line | awk -F% '{print $3}'` PV=`echo $prod_line | awk -F% '{print $2$3}'` if [ -d $_KIT_TOP/$N/kit/instctrl ]; then { echo "_INSTDIR$PV='$_KIT_TOP/$N/kit/instctrl'" >> $Z1_TMP } fi done < $_KIT_PRODMAP YY=`cat $Z1_TMP` for XX in $YY { ZZ=`echo $XX | awk -F= '{print $1}'` eval $XX export $ZZ eval ZZ=\$$ZZ [ "$HARDCODE_NOTSERVICEPACK" ] || { grep -q -E "^PATCH_LAST_MODIFICATION_DATE=.*SP..\"$" \ $ZZ/*.ctrl && _IS_SERVICEPACK="Y" export _IS_SERVICEPACK } } rm $Z1_TMP } P_ProdCacheInfo () { FROM_KIT= BAD_KIT= BAD_PROD= case $_TYPE in INSTALL* | BASELINE) FROM_KIT=Y _KIT_CHECKED= ;; DOC) [ "$_PAT_REQ" = kit ] && FROM_KIT=Y ;; esac [ "$_TYPE" ] || FROM_KIT=Y [ "$_KIT_PRODMAP" ] || _KIT_PRODMAP=$_SYS_PRODMAP if [ ${_FORMAT} ] ; then if [ $_FORMAT = multi ]; then { P_SetUpProductPaths } fi fi TMP_OS_NAME="DIGITAL_UNIX" PCITMP1=$_DUPATCH_TMP/P_ProdCacheInfo.tmp1 PCITMP2=$_DUPATCH_TMP/P_ProdCacheInfo.tmp2 PCITMP3=$_DUPATCH_TMP/P_ProdCacheInfo.tmp3 >$PCITMP1 >$PCITMP2 >$PCITMP3 if [ "$FROM_KIT" ]; then { for PV in $_PVS { P=`expr $PV : '\(...\)'` V=`expr $PV : '.*\(...\)'` if [ $_FORMAT = multi ]; then { PNAME=`S_ProdmapGet name $_KIT_PRODMAP $P $V` PDESC=`S_ProdmapGet desc $_KIT_PRODMAP $P $V` [ $P = OSF ] && TMP_OS_NAME=$PNAME if [ -d $_KIT_TOP/$PNAME ]; then { eval _PNAME$PV='$PNAME' eval _KITDIR$PV='$_KIT_TOP/$PNAME/kit' eval _INSTDIR$PV='$_KIT_TOP/$PNAME/kit/instctrl' eval _SCPEXT_DIR$PV='$_KIT_TOP/$PNAME/kit/scp_extensions' eval _SCPEXT_DIRBL$PV='$_KIT_TOP/$PNAME/kit/scp_extensions/blocking_subsets' if [ -d $_KIT_TOP/$PNAME/doc/txt ]; then eval _DOCDIR$PV='$_KIT_TOP/$PNAME/doc/txt' else eval _DOCDIR$PV='$_KIT_TOP/$PNAME/doc' fi } else { BAD_PROD="$BAD_PROD $PV" if [ $PNAME != "" ]; then BAD_KIT="$BAD_KIT $PNAME" else BAD_KIT="$BAD_KIT $PV" fi } fi #end of kit not found } # end of multi else { if [ $P = "OSF" ]; then { eval _PNAME$PV='$_KIT_TOP' eval _KITDIR$PV='$_KIT_TOP/kit' eval _INSTDIR$PV='$_KIT_TOP/kit/instctrl' eval _DOCDIR$PV='$_KIT_TOP/doc' eval _SCPEXT_DIR$PV='$_KIT_TOP/kit/scp_extensions' eval _SCPEXT_DIRBL$PV='$_KIT_TOP/$PNAME/kit/scp_extensions/blocking_subsets' } else { echo "ERROR - Single patch kit can only be for the Operating System" | tee -a $_SLOG } fi } fi # end of single eval SCPEXTDIRBL=\$_SCPEXT_DIRBL$PV if [ -d "$SCPEXTDIRBL" ]; then P_SCPExtDataEdit fi eval _PDESC$PV='$PDESC' export _PNAME$PV _KITDIR$PV _INSTDIR$PV _DOCDIR$PV _PDESC$PV _SCPEXT_DIR$PV _SCPEXT_DIRBL$PV } # end of product loop if [ "$BAD_PROD" != "" ]; then { echo " ************************************************************************ Warning: The patch kit does not contain patches for: $BAD_KIT Tru64 UNIX and TruCluster products are typically patched at the same time. You are advised to verify that this kit is complete prior to applying patches. ************************************************************************ " | tee -a $_SLOG if [ "$_CMDLINE" ]; then { echo " *** Warning: The patch kit does not contain patches for: $BAD_KIT Automatically Proceeding with patching of the system" >> $_SLOG echo "Automatically Proceeding with patching of the system" } else { echo "Do you want to proceed with the patching of the system ? [n] \c" | tee -a $_SLOG read X; echo $X >> $_SLOG if [ "$X" != "Y" -a "$X" != "y" ]; then { echo " Terminating this run of Dupatch " | tee -a $_SLOG P_Exit 1 } fi } fi YY="" for XX in $_PVS { badflag=0 for BADPROD in $BAD_PROD { if [ "$XX" = "$BADPROD" ]; then { badflag=1 break } fi } if [ "$badflag" != "1" ]; then { YY="$YY"" $XX" } fi } _PVS="$YY" } fi [ "$PATCH_DEBUG" ] && { echo "applicable _PVS=$_PVS" echo for PV in $_PVS do eval echo _PNAME$PV=\$_PNAME$PV eval echo _KITDIR$PV=\$_KITDIR$PV eval echo _DOCDIR$PV=\$_DOCDIR$PV eval echo _INSTDIR$PV=\$_INSTDIR$PV eval echo _PDESC$PV=\$_PDESC$PV eval echo _SCPEXT_DIR$PV=\$_SCPEXT_DIR$PV eval echo _SCPEXT_DIRBL$PV=\$_SCPEXT_DIRBL$PV done } } else { for PV in $_PVS { P=`expr $PV : '\(...\)'` V=`expr $PV : '.*\(...\)'` PNAME=`S_ProdmapGet name $_SYS_PRODMAP $P $V` PDESC=`S_ProdmapGet desc $_SYS_PRODMAP $P $V` eval _PNAME$PV='$PNAME' eval _PDESC$PV='$PDESC' export _PNAME$PV _PDESC$PV } [ "$PATCH_DEBUG" ] && { echo "applicable _PVS=$_PVS" echo for PV in $_PVS do eval echo _PNAME$PV=\$_PNAME$PV eval echo _PDESC$PV=\$_PDESC$PV done } } fi return 0 } P_Remove_C_Space () { CH="" _pat_found=0 while [ -n "$*" ];do next=$1 shift if [ $_pat_found = "1" ]; then if [ $next = 'C' -o $next = 'c' ]; then next=$next$1 shift fi else if [ $next = "-patch" ]; then _pat_found=1 else X=`echo $next | sed 's/^\(-\).*/\1/'` if [ X = "-" ]; then _pat_found=0 fi fi fi CH="$CH $next" done echo $CH } P_Remove_Spaces () { CH="" while [ -n "$*" ];do next=$1 shift if [ $next = 'C' -o $next = 'c' ]; then next=$next$1 shift fi CH="$CH $next" done echo $CH } P_SelSysProds () { TYPE=$1 SELECT=$2; shift 2 # set to N in command line interface SS_SUBS=$* case $_TYPE in DELETE) LOC=$_SMDB ;; DOC) LOC=$_ALLDOC ;; esac ALL=$_DUPATCH_TMP/allsubs for S in $SS_SUBS { echo $S >> $ALL } _PVS=`cat $ALL | sed 's/^\(...\).*\(...\)$/\1\2/' | sort -u` [ `Length $_PVS` -gt 1 -a "$SELECT" = Y ] && { MenuPost product sys $_PVS || return 1 _PVS=$_MENULIST } _MENULIST= SLIST=$_DUPATCH_TMP/slist for PV in $_PVS { P=`expr "$PV" : '^\(...\)'` V=`expr "$PV" : '.*\(...\)$'` if [ "$TYPE" = "lk" ]; then SWDB_FindInstalledSubsets "${P}PAT?${_PID}${_VID}${V}" >$SLIST else (cd $LOC; ls ${P}PAT?${_PID}${_VID}${V}.$TYPE 2>/dev/null | sed 's/\.'$TYPE'//g') > $SLIST fi SS_SUBS=`comm -12 $ALL $SLIST` eval _SLIST$PV='$SS_SUBS' _MENULIST="$_MENULIST $SS_SUBS" } _MENULIST=`P_FilterTools $TYPE $LOC $_MENULIST` rm -f $ALL $SLIST export _PVS P_ProdCacheInfo return 0 } P_SetRoot () { [ "$_ROOT" ] && { if [ -z "${_ALTROOT}" ]; then { if [ "$_ROOT" = "/" ]; then _ALTROOT= else _ALTROOT="-D $_ROOT" _SW_NOAUTO=NOAUTO fi } fi export _ALTROOT _SW_NOAUTO if [ -z "${_PATCHDIR}" ]; then { if [ "$_ROOT" = "/" ]; then _PATCHDIR=/var/adm/patch else _PATCHDIR=$_ROOT/var/adm/patch fi [ -d $_PATCHDIR ] || mkdir $_PATCHDIR || { P_Error "Could not create directory $_PATCHDIR. dupatch will terminate." P_Exit 1 } } fi _SYS_PRODMAP=$_PATCHDIR/product_map export _PATCHDIR _SYS_PRODMAP return 0 } if [ "$_ARG_ROOT" ]; then { _ROOT=$_ARG_ROOT case "$_ROOT" in /*) ;; *) _ROOT=`(cd $_ROOT;Pwd)` esac _ALTROOT="-D $_ROOT" _SW_NOAUTO=NOAUTO _R=$_ROOT } else { _ROOT=/ _R= _ALTROOT= } fi if [ "$_ROOT" = "/" ]; then _PATCHDIR=/var/adm/patch else _PATCHDIR=$_ROOT/var/adm/patch fi _SMDB=./usr/.smdb. [ -d $_PATCHDIR ] || mkdir -p $_PATCHDIR _SYS_PRODMAP=$_PATCHDIR/product_map export _ROOT _R _SMDB _PATCHDIR _SYS_PRODMAP _ALTROOT _SW_NOAUTO cd $_ROOT [ "$PATCH_DEBUG" ] && { echo "\n=== " `uname -n` "is running OS" `uname -r` echo "\n=== P_SetRoot has exported these variables:" echo "\n=== _ROOT is $_ROOT" echo "\n=== _R is $_R" echo "\n=== _SMDB is $_SMDB" echo "\n=== _PATCHDIR is $_PATCHDIR" echo "\n=== _SYS_PRODMAP is $_SYS_PRODMAP" echo "\n=== _ALTROOT for setld is '$_ALTROOT'" echo "\n=== _SW_NOAUTO is $_SW_NOAUTO" echo "\n=== _SW_NOROLL is $_SW_NOROLL" } return 0 } P_SetSwitch () { SW=$1 S=`echo $SW | sed 's/^-//'` S=`ToUpper $S` eval _SW_$S='$S' ARG_CNT=0 eval _ARG_$S= shift ARGS= while : do [ $# -eq 0 ] && break case $1 in -*) break ;; *) ARGS="$ARGS $1" ARG_CNT=`expr $ARG_CNT + 1` shift ;; esac done ARGS=`echo $ARGS` eval _ARG_$S='$ARGS' [ "$PATCH_DEBUG" ] && eval echo _ARG_$S=\$_ARG_$S _SHIFT=`expr $ARG_CNT + 1` } P_UpdateTools () { [ "$_TOOLS_UPDATED" ] && return 0 _TOOLS_UPDATED= SYSVER=`P_HighestVerInstalled OSFBASE` case "$_FORMAT" in single) TOOLDIR=$_KIT_TOP/kit [ -d $_KIT_TOP/patch_tools ] && TOOLDIR=$_KIT_TOP/patch_tools ;; multi) TOOLDIR=$_KIT_TOP/patch_tools ;; esac NEWSUB=`(cd $TOOLDIR; ls -1 OSFPAT?${_TOOLSUB}*${SYSVER} 2>/dev/null | tail -1)` [ "$NEWSUB" ] || { P_Error " This patch distribution does not contain the required patch tools subset. " return 1 } CURSUB=`(cd $_SMDB; ls -1 OSFPAT?${_TOOLSUB}*${SYSVER}.lk 2>/dev/null |\ tail -1 | sed 's/\.lk//')` [ "$CURSUB" ] && { NEWREV=`expr "$NEWSUB" : '.*\([0-9][0-9]\)...'` CURREV=`expr "$CURSUB" : '.*\([0-9][0-9]\)...'` [ $CURREV -gt $NEWREV ] && return 0 [ $CURREV -eq $NEWREV -a ! "$UPDATE_DUPATCH" ] && return 0 [ "$PATCH_DEBUG" ] && echo "\n=== utility update NEW: $NEWREV CUR: $CURREV" } [ `id -u` -ne "0" ] && { echo " Patch tools need to be installed or updated on your system. Please invoke the command as the super-user (root) first. " | tee -a $_SLOG return 1 } STR1="." STR2="" [ $_ROOT = / ] || { STR1=" relative to $_ROOT." STR2="$_ROOT" } echo " * A new version of patch tools required for patch management is now being installed on your system$STR1" | tee -a $_SLOG SETLD_LOC=/usr/sbin [ -f $_KIT_TOP/patch_tools/setld ] && SETLD_LOC=$_KIT_TOP/patch_tools [ "$PATCH_DEBUG" ] && { $SETLD_LOC/setld $_ALTROOT -l $TOOLDIR $NEWSUB || P_Ferror 1 "\nFailed to update patch tools." } [ "$PATCH_DEBUG" ] || { $SETLD_LOC/setld $_ALTROOT -l $TOOLDIR $NEWSUB > /dev/null || P_Ferror 1 "\nFailed to update patch tools." } [ -d "$OSKitDir" ] && { cp -pf $TOOLDIR/instctrl/$NEWSUB.* $OSKitDir/ } SETUP_STARTED=/cluster/admin/clu_upgrade/setup.started [ -f $SETUP_STARTED ] && { TAG_FILE_LIST=/cluster/admin/clu_upgrade/tag_files.list TEMP_TAG_LIST=$_DUPATCH_TMP/tag_files.list TEMP_PATCHTOOLS=$_DUPATCH_TMP/ToolsInv [ -f ${TAG_FILE_LIST}.ORIG ] || cp $TAG_FILE_LIST ${TAG_FILE_LIST}.ORIG cut -f 10 $_SMDB/${NEWSUB}.inv | sed 's/^\.//' > $TEMP_PATCHTOOLS grep -v -f $TEMP_PATCHTOOLS $TAG_FILE_LIST > $TEMP_TAG_LIST [ -s $TEMP_TAG_LIST ] && mv $TEMP_TAG_LIST $TAG_FILE_LIST rm -f $TEMP_TAG_LIST $TEMP_PATCHTOOLS } echo " * Tools updated, invoking the updated Patch Utility... " | tee -a $_SLOG _TOOLS_UPDATED=1; export _TOOLS_UPDATED _DUPATCH_EXEC=Y; export _DUPATCH_EXEC exec $STR2/usr/sbin/$_PROG $_ALLARGS return $? } P_Usage () { case $1 in DELETE) echo "\nThe following is a description of the command line interface:" echo "\n$DELETE_USAGE" ;; HELP) [ "$_SW_DATA_FILE" ] && echo "$DATA_FILE_USAGE" [ "$_SW_PATCH_ID" ] && P_ArgsPidMsg PATCH ALL [ "$_SW_PRODUCT_ID" ] && P_ArgsPidMsg PRODUCT ALL [ "$_SW_REV" ] && echo $_DUPATCH_REV [ "$_SW_ROOT_PATH" ] && echo "$ROOT_PATH_USAGE" [ ! "$_SW_DATA_FILE" -a \ ! "$_SW_PATCH_ID" -a \ ! "$_SW_PRODUCT_ID" -a \ ! "$_SW_REV" -a \ ! "$_SW_ROOT_PATH" ] && { TMP=$_DUPATCH_TMP/$_PROG.help unlink $TMP 2>/dev/null > $TMP || exit 1 echo "$REV_USAGE" >> $TMP echo "$ALL_USAGE" >> $TMP echo "$DATA_FILE_USAGE" >> $TMP P_ArgsPidMsg PATCH ALL >> $TMP P_ArgsPidMsg PRODUCT ALL >> $TMP echo "$ROOT_PATH_USAGE" >> $TMP if [ "$_DISPLAY" ]; then $_DISPLAY $TMP else cat $TMP fi rm -f $TMP } ;; INSTALL) echo "\nThe following is a description of the command line interface:" echo "\n$INSTALL_USAGE" ;; TRACK) echo "\nThe following is a description of the command line interface:" echo "\n$TRACK_USAGE" ;; *) echo "\n$ALL_USAGE" esac return 0 } P_ValidProd () { _VALIDPROD= [ "$_TYPE" = DELETE ] && { P_PatchesAvailable lk $_SMDB VP_SUBS MSG || return 1 P_SelSysProds lk N $VP_SUBS } for PV in $_PVS { eval PROD=\$_PNAME$PV _VALIDPROD="$_VALIDPROD $PROD" } [ "$_VALIDPROD" ] || { ERROR=1 P_Error " There are no patches available for this operation." return 1 } return 0 } # @(#)$RCSfile: share.sh,v $ $Revision: 1.1.2.5 $ (DEC) $Date: 2004/02/26 15:23:29 $ GetSubDesc () { SDESC= case $3 in Y) SDESC=`S_GetSubDesc $1 $2 STRIP_CAT STRIP_TEXT` ;; *) SDESC=`S_GetSubDesc $1 $2 KEEP_CAT KEEP_TEXT` ;; esac echo "$SDESC" return 0 } S_ApplicableDeps () { LIST=$* DLIST= for K in $LIST { SUBS=`echo $K | sed 's/:/ /g'` for S in $SUBS { P=`expr "$S" : '^\(...\).*'` V=`expr "$S" : '.*\(...\)$'` ls ./usr/.smdb./$P*$V.lk > /dev/null 2>&1 && { DLIST="$DLIST $S" break } } } echo $DLIST return 0 } S_GetSubDesc () { SUB=$1 LOC=$2 CAT=$3 TEXT=$4 HIST=$5 case $_TYPE in INSTALL|BASELINE) PRODMAP=$_KIT_PRODMAP # install / baseline ;; DOC) PRODMAP=$_DOC_PRODMAP ;; *) PRODMAP=$_SYS_PRODMAP # delete / track ;; esac if [ ${PRODMAP} ]; then ak=1 # do nothing else { if [ ${_PATCHDIR} ]; then { PRODMAP="$_PATCHDIR/product_map" } else { if [ ${_ROOT} ]; then PRODMAP="$_ROOT/var/adm/patch/product_map" else PRODMAP="/var/adm/patch/product_map" fi } fi } fi SDESC= if [ -f $LOC/$SUB.ctrl ]; then { eval `grep DESC= $LOC/$SUB.ctrl` SDESC=$DESC [ "$CAT" = STRIP_CAT ] && SDESC=`echo "$DESC" | sed 's/%.*//' | sed 's/ $//'` } # new - ask 10/6/98 else { TEXT=STRIP_TEXT } fi # end new case "$SUB" in ???PAT?[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) PCODE=`expr $SUB : '^\(...\).*$'` # product code VCODE=`expr "$SUB" : '^.*\(...\)$'` # version code BASE=`expr "$SUB" : '^...\(.*\)...$'` # w/o p/vcode PID=`echo $BASE | cut -b 5-9'` # id PREV=`echo $BASE | cut -b 10-11'` # rev case "$SUB" in ???PAT${_CSPC}[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) PID="$_CSPC $PID" ;; *) PID=" $PID" ;; esac if [ \( "$TEXT" = STRIP_TEXT \) -o \( "$HIST" = hist \) ]; then SDESC="Patch $PID.$PREV" else SDESC=`echo "$SDESC" | sed 's/^Patch:/Patch '"$PID"'.'$PREV' -/'` fi PNAME= [ "$PRODMAP" -a -f $PRODMAP ] && PNAME=`S_ProdmapGet name $PRODMAP $PCODE $VCODE` [ "$PNAME" ] || { [ "$SDESC" ] || SDESC="$SUB" echo "$SDESC" return 0 } [ "$HIST" = hist ] || { if [ "$CAT" = STRIP_CAT ]; then { SDESC="$PNAME $SDESC" } else { if `echo $SDESC | egrep -q %`; then SDESC=`echo $SDESC | sed "s=%=%$PNAME / ="` else SDESC=`echo $SDESC | sed "s/$/%$PNAME/"` fi } fi } ;; *) [ "$SDESC" ] || { PCODE=`expr $SUB : '^\(...\).*$'` # product code VCODE=`expr "$SUB" : '^.*\(...\)$'` # version code PNAME= [ "$PRODMAP" -a -f $PRODMAP ] && PNAME=`S_ProdmapGet name $PRODMAP $PCODE $VCODE` [ "$PNAME" ] && SDESC="$PNAME"" - subset: $SUB" } ;; esac [ "$SDESC" ] || SDESC="$SUB" echo "$SDESC" return 0 } S_ListPatches () {( SUBS=$* LTMP1=$_DUPATCH_TMP/listpatches.tmp1 LTMP2=$_DUPATCH_TMP/listpatches.tmp2 >$LTMP1 S_Order other $SUBS for PV in $PVS { case "$_TYPE" in INSTALL|BASELINE) eval LOC=\$_INSTDIR$PV ;; DOC) LOC=$_DOC_INSTDIR ;; *) # delete / track LOC=$_SMDB ;; esac eval SLIST=\$SUBS$PV for S in $SLIST { DESC=`S_GetSubDesc $S $LOC KEEP_CAT KEEP_TEXT` echo "$DESC@$S" >> $LTMP1 } } if [ `Length $SUBS` = 1 ]; then { cp $LTMP1 $LTMP2 } else { >$LTMP2 S_MenuSort $LTMP1 $LTMP2 rm -f $LTMP1 } fi _EXTRA_OPERATION=list; export _EXTRA_OPERATION NO_LINECNT= [ "$_CMDLINE" ] && NO_LINECNT="-n" if [ -z "${TRIM}" ]; then ./usr/lbin/patmenu -l $NO_LINECNT -s display $LTMP2 else { echo "" AK=`cat $LTMP2 | awk -F@ '{print $1}'` AK1=`echo $AK | awk -F% '{print $2}'` AK2=`echo $AK | awk -F% '{print $1}'` echo " - $AK1" echo " $AK2" echo "" } fi rm -f $LTMP1 $LTMP2 return 0 )} S_MenuSort () {( IN=$1 OUT=$2 >$OUT # make sure OUT is empty... [ -s $IN ] || return 0 grep % $IN | sort -t% +1 -2 > $OUT grep -v % $IN | sort >> $OUT return 0 )} S_Order () { OP=$1; shift O_SUBS=$* [ `Length $O_SUBS` = 1 ] && { PV=`echo $O_SUBS | sed 's/^\(...\).*\(...\)$/\1\2/'` case $OP in install | delete) _PVS=$PV eval _SLIST$PV='$O_SUBS' ;; other) PVS=$PV eval SUBS$PV='$O_SUBS' ;; esac return 0 } LTMP1=$_DUPATCH_TMP/order.tmp1 >$LTMP1 for S in $O_SUBS { echo $S >> $LTMP1 } PVS=`cat $LTMP1 | sed 's/^\(...\).*\(...\)$/\1\2/' | sort -u` OSFLIST= TCRLIST= IOSLIST= UNKLIST= for K in $PVS do case "$K" in OSF* ) OSFLIST="$OSFLIST $K" ;; TCR* ) TCRLIST="$TCRLIST $K" ;; IOS* ) IOSLIST="$IOSLIST $K" ;; * ) UNKLIST="$UNKLIST $K" ;; esac done PVS="$OSFLIST $TCRLIST $IOSLIST $UNKLIST" for PV in $PVS { [ `Length $PVS` -eq 0 ] || { P=`expr "$PV" : '^\(...\)'` V=`expr "$PV" : '.*\(...\)$'` O_SUBS=`egrep '^'$P'.+'$V'$' $LTMP1` } case $OP in install) eval INSTCTRL=\$_INSTDIR$PV O_SUBS=`(cd $INSTCTRL; $_ROOT/usr/lbin/depord $O_SUBS)` eval _SLIST$PV='$O_SUBS' ;; delete) O_SUBS=`GetDeleteOrder $O_SUBS` RC=$? [ $RC != 0 ] && { echo "An error occurred in examining patches for deletion. Please contact your Customer" echo "Service Representative for assistance." echo "Patches will not be removed. dupatch terminating." P_Exit 1 } eval _SLIST$PV='$O_SUBS' ;; other) eval SUBS$PV='$O_SUBS' ;; esac } rm -f $LTMP1 [ "$OP" = other ] && return 0 _PVS=$PVS return 0 } S_ProdmapGet () {( TYPE=$1 PRODMAP=$2 [ -s "$PRODMAP" ] || { echo "product_map does not exist or is empty, can not continue." exit 1 } case $TYPE in whole | name | desc) P=$3 V=$4 ENTRY=`egrep "%$P%$V%" $PRODMAP| head -1` ;; pvcode) NAME=$3 ENTRY=`egrep -i "^$NAME%" $PRODMAP| head -1` ;; esac case $TYPE in whole) echo $ENTRY ;; name) echo $ENTRY | awk -F% '{print $1}' ;; desc) echo $ENTRY | awk -F% '{print $4}' | sed 's/\"//g' ;; pvcode) echo $ENTRY | awk -F% '{print $2$3}' esac case $TYPE in vname) echo $ENTRY | awk -F% '{print $5}' ;; svname) echo $ENTRY | awk -F% '{print $6}' ;; kitpre) echo $ENTRY | awk -F% '{print $7}' ;; esac return 0 )} S_ShellArgLimit () { case "$1" in on ) [ "$SH_ARG_LIMIT" ] && { /sbin/sysconfig -r proc exec_disable_arg_limit=$SH_ARG_LIMIT \ >/dev/null 2>&1 } ;; off ) set -- `/sbin/sysconfig -q proc | grep exec_disable_arg_limit` [ "$3" = "0" ] && { SH_ARG_LIMIT="$3" /sbin/sysconfig -r proc exec_disable_arg_limit=1 \ >/dev/null 2>&1 } ;; esac } [ "$CHECK_SYNTAX" ] || Main $@