#!/usr/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos72X src/bos/usr/sbin/install/efixtools/elib.sh 1.60.9.1 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2003,2022 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#)31 1.60.9.1 src/bos/usr/sbin/install/efixtools/elib.sh, cmdefix, bos72X, x2022_07A4 1/13/22 14:40:19 ############################################################# ## The following functions are included in this file and ## are listed in alphabetical order: ## ## abort_function() ## abspath() ## add_to_cleanup() ## aclcomp() ## aclget() ## aclput() ## add_emgr_bit() ## addbuf() ## all_files_new() ## btoi() ## check4debug() ## check_dir() ## check_dup_targets() ## check_fdup_space() ## check_file() ## check_file_full() ## check_kernel_link() ## check_node() ## check_overlaid_targets() ## check_reboot_conflict() ## check_root() ## chmod() ## chown() ## ck_exp_fs() ## ck_overwrite_bit() ## clevels() ## conv_einstaller() ## conv_etype() ## conv_ifile_to_target() ## conv_val_to_field() ## dec() ## does_ar_mem_exist() ## emount() ## eumount() ## extract_ar_member() ## get_ar_msize() ## get_ar_sum() ## get_byte_fsize() ## get_common_cvars() ## get_efile_vars() ## get_global_warning() ## get_inode() ## get_installp_links() ## get_lcount() ## get_lpp_level() ## get_md5_fsum() ## get_parent_dir() ## get_wouldbe_fs() ## getecvar() ## getfsfree() ## getfsize() ## getfsum() ## inc() ## inc_global_warning() ## initQs() ## init_pos_cmds() ## init_sys_vars() ## init_vars() ## isbitset() ## isYorN() ## is_ar_member() ## is_emgr_bit_on() ## is_file_new() ## is_hlinked() ## is_slinked() ## is_text_file() ## isemounted() ## isfopen() ## isin() ## isnum() ## more_same_target() ## odm_get_cp_flag() ## odm_set_emgr_bit() ## pcerror() ## perror() ## pmerror() ## print_cfgfile() ## print_ecfile() ## print_line() ## print_msg() ## print_uniq_iname() ## process_new_options() ## read_ecfile() ## remove_emgr_bit() ## setcmd() ## set_emgrdata_vars() ## set_md5_cmd() ## setup_global_warning() ## shiftbit() ## sigtrap() ## slibclean() ## subshrc() ## strcat() ## sync() ## tcb_delete() ## tcb_get_attr() ## tcb_get_sz() ## tcb_set_state() ## tcb_restore() ## tcb_update() ## timestamp() ## toupper() ## verify_apar_info() ## verify_pkglocks_file() ## verify_prereq_file() ## verify_supersede_file() ## verifysum() ## vstr() ## vstrDS() ## which_lpp() ## which_rpm() ## whichfs() ############################################################# ######################################################################## ## Function: is_text_file() ## Parameters: ## Returns: 0 = yes, is text file, 1 = not text file, 2 = error ######################################################################## is_text_file() { typeset ERROR='eval pmerror "is_text_file()"; return 2' typeset ISTEXTF='eval return 0' typeset NOTEXTF='eval perror 381 "$NODE"; return 1' typeset AWKERROR='eval pmerror "$AWK"; $ERROR' typeset BUF="" typeset NODE="$1" # Check for internal error [[ -z $NODE ]] && $ERROR # If it is not a file, then it can't be a text file. check_file $NODE || $NOTEXTF ######################################################################## ## awk will read the first line of the given file and compare all of ## the characters in that first line against the ASCII character set ## based on the POSIX locale. This function expects ony POSIX ascii ## characters to be in a text file.. so this is not a good routine to ## execute against a file that may contain non-POSIX characters. ######################################################################## BUF=$(LC_ALL=C LANG=C awk '{ if($0 ~ "^[\b-\~]*$" ) exit(0); print "1"; exit(0) }' $NODE) || $AWKERROR # Sanity check.. [[ -n "$BUF" && "$BUF" != "1" ]] && $ERROR # If BUF empty, then this is a text file, otherwise it is not. [[ -z $BUF ]] && $ISTEXTF || $NOTEXTF # Should never get here. $ERROR } # end of is_text_file() ######################################################################## ## Function: btoi() Changes boolean variable (y or no, etc) to int ## Parameters: ## Returns: 0 = OK, !0 = ERROR ## Note: Changes to 0 = no/false, 1 = yes/true ######################################################################## btoi() { typeset ERROR='eval pmerror "btoi()" ; return 1' typeset VAR=$1 typeset VAL typeset RC [[ -z $VAR ]] && $ERROR eval VAL="$"$VAR isYorN "$VAL"; RC=$? [[ $RC -ne 0 && $RC -ne 1 ]] && $ERROR eval $VAR=$RC return 0 } # end of btoi() ######################################################################## ## Function: check_reboot_conflict() Checks if the A_EREBOOT and ## A_BUILD_BOOT_IMAGE variables ## conflict. ## Parameters: None ## Returns: 0 = ok, !0 = error ######################################################################## check_reboot_conflict() { typeset ERROR='eval pmerror "check_reboot_conflict()"; return 1' typeset REBOOT=$A_EREBOOT typeset BUILDBOOT=$A_BUILD_BOOT_IMAGE # We now support A_EREBOOT= no and A_BUILD_BOOT_IMAGE = yes return 0 btoi REBOOT || $ERROR btoi BUILDBOOT || $ERROR if [[ $REBOOT -eq 0 && $BUILDBOOT -eq 1 ]]; then perror 357 return 1 fi return 0 } # end of check_reboot_conflict() ######################################################################## ## Function: conv_ifile_to_target() Converts IFILE to EDIR target. ## Parameters: ## Returns: 0 = ok, !0 = error ## Output: EDIR target associated with ifile ######################################################################## conv_ifile_to_target() { typeset ERROR='eval pmerror "conv_ifile_to_target()"; return 1' typeset IFILE=$1 typeset TARGET [[ -z $IFILE ]] && $ERROR # Name the target based on install script type case $IFILE in A_PREI) TARGET=pre_install;; A_POSTI) TARGET=post_install;; A_PRER) TARGET=pre_remove;; A_POSTR) TARGET=post_remove;; A_PREREQ) TARGET=prereq;; A_EDESC) TARGET=description;; A_PKGLOCKS) TARGET=pkglocks;; A_SUPERSEDE) TARGET=supersede;; A_E2E_PREREQ) TARGET=e2e_prereq;; A_APARREF) TARGET=aparref;; *) $ERROR;; esac [[ -n $TARGET ]] && echo "$TARGET" || $ERROR return 0 } # end of conv_ifile_to_target() ######################################################################## ## Function: check_kernel_link() ## Parameters: NONE ## Returns: Issues an ATTENTION message if there is a possible ## kernel file being delivered as an efix but the ## kernel link does not point to that file or an ERROR ## is displayed if the kernel link is invalid ######################################################################## check_kernel_link() { typeset ERROR='eval pmerror "check_kernel_link()"; return 1' typeset KER_ATT='eval $PB; perror "349" "$TARGET" "$KLINK1" "$KLINK2"; continue' typeset KER_NBB='eval $PB; perror 358 "$TARGET"' typeset KERNEL_PREFIX="/usr/lib/boot/unix_" typeset KLINK1="/unix" # kernel symbolic link typeset KLINK2="/usr/lib/boot/unix" # kernel symbolic or hard link typeset EFCOUNT=0 typeset LOOPSAFE=0 typeset TARGET="" # If no efix files, then return clean [[ $GENUM -lt 1 ]] && return 0 # Loop through efix files searching for # possible kernels and check links while [[ $EFCOUNT -lt $GENUM ]] do # Increase loop counter and error if # we are looping out of control inc LOOPSAFE [[ $LOOPSAFE -gt $MAXEFILES ]] && $ERROR inc EFCOUNT # Set TARGET to be an efix file TARGET=${A_ETARGET[$EFCOUNT]} # Check if target is a possible kernel [[ $TARGET != "$KERNEL_PREFIX"* ]] && continue # Make sure A_BUILD_BOOT_IMAGE flag is set btoi A_BUILD_BOOT_IMAGE [[ $A_BUILD_BOOT_IMAGE -ne 1 ]] && $KER_NBB # If this is epkg, then we are done with this file. [[ $EPKG -eq 1 ]] && continue # Now check if /unix exists check_node "$KLINK1" if [[ $? -eq 0 ]]; then # It exists, now check if it is linked # to what our efix file replaces is_slinked "$KLINK1" "$TARGET" || $KER_ATT else # If we got here it means there is no /unix # now check /usr/lib/boot/unix check_node "$KLINK2" || $KER_ATT # It is there, now check if it is # a symlink or a hard link to our target is_slinked "$KLINK2" "$TARGET" || \ is_hlinked "$KLINK2" "$TARGET" || $KER_ATT fi done return 0 } # end of check_kernel_link() ######################################################################## ## Function: process_new_options() ## Parameters: ## Note: This functions will process the additional features that were ## added in version 3 and above of Efix Management. If the field ## is not set, a default value will be assigned. ## = opt field name ## = variable that currently holds or ## should be set after evaluation is complete. ## This function will upvar the value into this ## variable. ## = current value of ######################################################################## process_new_options() { typeset FIELD="$1" typeset VALUE_VAR="$2" typeset VALUE="$3" typeset ERROR='eval pmerror "process_new_options()"; return 1' [[ -z $FIELD || -z $VALUE_VAR ]] && $ERROR # If this value is set to anything, then we are done. [[ -n $VALUE ]] && return 0 case $FIELD in PKGLOCKS|SUPERSEDE|E2E_PREREQ|APARREF) eval A_$FIELD="$NONE" # upvar the new value eval $VALUE_VAR="$"A_$FIELD ;; *VERSION) [[ $EMGR -eq 0 ]] && return 0 EPKG_VERSION=0 # upvar the new value eval $VALUE_VAR=$EPKG_VERSION ;; BUILD_BOOT_IMAGE) # If this is epkg, and BUILD_BOOT_IMAGE is null, then set # to the value of A_EREBOOT (which should have been processed # by now. # If A_REBOOT is not set yet, then we are done [[ -z $A_EREBOOT ]] && return 0 A_BUILD_BOOT_IMAGE=$A_EREBOOT # upvar the new value eval $VALUE_VAR=$A_BUILD_BOOT_IMAGE ;; FIXTESTED) eval A_${FIELD}=0 # upvar the new value eval $VALUE_VAR="$"A_$FIELD ;; CU_VR) eval $VALUE_VAR="." ;; LKU_CAPABLE) A_LKU_CAPABLE=$NO eval $VALUE_VAR=$A_LKU_CAPABLE ;; esac return 0 } # end of process_new_options() ######################################################################## ## Function: all_files_new() ## Parameters: ## Returns: 0 = all files are new, !0 not all files are new or error ######################################################################## all_files_new() { typeset ERROR='eval pmerror "all_files_new()"; return 1' typeset EFCOUNT=0 # local EFIX file counter isnum $GENUM || $ERROR while [[ $EFCOUNT -lt $GENUM ]]; do inc EFCOUNT # Safety valve for this loop if [[ $EFCOUNT -gt $MAXEFILES ]]; then $ERROR fi # If file is not NEW, then return 1 is_file_new $EFCOUNT || return 1 done return 0 } # end of all_files_new() ######################################################################## ## Function: print_uniq_iname() ## Parameters: ## Returns: outputs uniq file/dir name in same directory. If the file ## or dir exists, will add a .integer sufix. ######################################################################## print_uniq_iname() { typeset ERROR='eval pmerror "print_uniq_iname()"; return 1' typeset NODE="$1" typeset UNODE # uniq node typeset c=0 # local counter typeset SUM [[ -z $NODE ]] && $ERROR # If the file/dir does not exist, return its name as uniq. if [[ ! -f $NODE && ! -d $NODE ]]; then echo "$NODE" return 0 fi NODE=$(abspath $NODE) || $ERROR UNODE=$NODE while [[ -f $UNODE || -d $UNODE ]]; do inc c # loop safety [[ $c -gt $MAXEFILES ]] && $ERROR UNODE="${NODE}.${c}" done echo "$UNODE" return 0 } # end of print_uniq_iname() ######################################################################## ## Function: isemounted() ## Parameters: ## Output Returns: emounted = 1, NOT emounted = 0 ######################################################################## isemounted() { typeset ERROR='eval pmerror "isemounted()"; return 1' typeset TARGET="$1" typeset BUF typeset MOUNTED='eval echo 1; return 0' typeset NOT_MOUNTED='eval echo 0; return 0' [[ -z $TARGET ]] && $ERROR # If target does not exist, then it is not mounted. [[ ! -f $TARGET && ! -d $TARGET ]] && $NOT_MOUNTED # Get the abspath TARGET=$(abspath $TARGET) || $ERROR # Get the df buf BUF=$($DF "$TARGET/" 2>/dev/null | \ $AWK '{ if (NR==1) next; print $6; exit(0)}') || $ERROR [[ "$BUF" = "$TARGET" ]] && $MOUNTED # If we got here, then it is not emounted. $NOT_MOUNTED } # end of isemounted() ######################################################################## ## Function: eumount() ## Parameters: ######################################################################## eumount() { typeset ERROR='eval pmerror "eumount()"; return 1' typeset TARGET="$1" typeset c=0 # local counter typeset RC [[ -z $TARGET ]] && $ERROR # If target is alread unmounted, we are done. RC=$(isemounted $TARGET) || $ERROR [[ "$RC" = "0" ]] && return 0 # Set abspath just in case. TARGET=$(abspath $TARGET) || $ERROR # We make 10 unemount attempts before giving up. while [[ $c -lt 10 ]]; do inc c $UMOUNT $TARGET > /dev/null 2<&1 RC=$(isemounted $TARGET) || $ERROR [[ "$RC" = "0" ]] && return 0 done # Still not unmounted ?! Lets try one more time, and lets let # the user see stderr/stdout $UMOUNT $TARGET || $ERROR RC=$(isemounted $TARGET) || $ERROR [[ $RC = "0" ]] && return 0 # should never get here. $ERROR } # end of eumount() ######################################################################## ## Function: emount() ## Parameters: ######################################################################## emount() { typeset ERROR='eval pmerror "emount()"; return 1' typeset SOURCE="$1" typeset TARGET="$2" typeset ISDIR=0 [[ -z $SOURCE || -z $TARGET ]] && $ERROR check_file $TARGET || $ERROR check_file $SOURCE || $ERROR TARGET=$(abspath $TARGET) || $ERROR SOURCE=$(abspath $SOURCE) || $ERROR $MOUNT $SOURCE $TARGET || $ERROR return 0 } # end of emount() ######################################################################## ## Function: does_ar_mem_exist() ## Parameters: ## Output: 1 = yes, 0 = no ######################################################################## does_ar_mem_exist() { typeset ERROR='eval pmerror "does_ar_mem_exist()"; return 1' typeset AFILE=$1 typeset MEMBER=$2 typeset RC=$? # Check the input [[ -z $AFILE ]] && $ERROR check_file $AFILE [[ $? -ne 0 || -z $MEMBER ]] && $ERROR $AR -X 32_64 -t $AFILE $MEMBER > /dev/null 2>&1 RC=$? [[ $RC -eq 0 ]] && echo 1 || echo 0 return 0 } # end of does_ar_mem_exist() ######################################################################## ## Function: get_ar_sum() ## Parameters: ######################################################################## get_ar_sum() { typeset ERROR='eval perror 242; return 1' typeset AFILE=$1 typeset MEMBER=$2 typeset EAR='eval pmerror $AR; $ERROR' typeset CKSUM=0 # Check the input check_file $AFILE [[ $? -ne 0 || -z $MEMBER ]] && $ERROR # Set actual member location $RM -f $MEMBER # just in case # Extract the member into WORKDIR. extract_ar_member "$AFILE" "$MEMBER" "$WORKDIR" || $ERROR # Set the full location for member.. MEMBER=$WORKDIR/$MEMBER # Get the sum. CKSUM=$(getfsum "$MEMBER") || $ERROR # Remove member $RM -f $MEMBER echo "$CKSUM" return 0 } # end of get_ar_sum() ######################################################################## ## Function: chmod ## Parameters: ######################################################################## chmod() { typeset MODE=$1 typeset FILE=$2 typeset ERROR='eval pmerror "chmod()"; return 1' check_file $FILE [[ $? -ne 0 || -z $MODE ]] && $ERROR $CHMOD "$MODE" "$FILE" || $ERROR return 0 } # end of chmod() ######################################################################## ## Function: chown ## Parameters: ######################################################################## chown() { typeset OWNSTR=$1 typeset FILE=$2 typeset ERROR='eval pmerror "chown()"; return 1' check_file $FILE [[ $? -ne 0 || -z $OWNSTR ]] && $ERROR $CHOWN "$OWNSTR" "$FILE" || $ERROR return 0 } # end of chown() ######################################################################## ## Function: extract_ar_member() ## Parameters: ######################################################################## extract_ar_member() { typeset ERROR='eval perror 240; return 1' typeset AFILE=$1 typeset MEMBER=$2 typeset TDIR=$3 typeset EAR='eval pmerror $AR; $ERROR' typeset SIZE=0 typeset RC=0 typeset EXTMEM typeset BUF # Check the input check_file $AFILE [[ $? -ne 0 || -z $MEMBER ]] && $ERROR check_dir $TDIR || $ERROR AFILE=$(abspath $AFILE) || ERROR cd $TDIR || $ERROR [[ "$TDIR" != "$PWD" ]] && $ERROR # Make sure we have space.. SIZE=$(get_ar_msize $AFILE $MEMBER) || $ERROR addbuf SIZE 14 64 ck_exp_fs $PWD $SIZE # Ok, lets get our ar member $AR -X 32_64 -lx $AFILE $MEMBER ; RC=$? EXTMEM=$PWD/$MEMBER ERROR='eval $RM -f $EXTMEM; perror 240; return 1' cd $OLDPWD [[ $RC -ne 0 ]] && $EAR check_file "$EXTMEM" || $ERROR # One more task.. we need to reset the ownership to # what is in the previous archive. Get the archive string. BUF=$($AR -X 32_64 -tv $AFILE $MEMBER) [[ $? -ne 0 || -z $BUF ]] && $EAR # Parse out for ownership. Replace "/" with ":" BUF=$(echo "$BUF" | $AWK '{gsub("/",":",$2); print $2 }') [[ $? -ne 0 || -z $BUF ]] && $ERROR # Set the right ownership.. chown "$BUF" "$EXTMEM" || $ERROR return 0 } # end of extract_ar_member() ######################################################################## ## Function: get_ar_msize() ## Parameters: ######################################################################## get_ar_msize() { typeset ERROR='eval perror 239; return 1' typeset AFILE=$1 typeset MEMBER=$2 typeset EAR='eval pmerror $AR; $ERROR' typeset BUF # Check the input check_file $AFILE [[ $? -ne 0 || -z $MEMBER ]] && $ERROR # Get line of output as buffer BUF=$($AR -X 32_64 -tv $AFILE $MEMBER) [[ $? -ne 0 || -z $BUF ]] && $EAR # Parse the line out for size BUF=$(echo "$BUF" | $AWK '{print $3}') || $ERROR # Check that the buf is good. isnum $BUF || $ERROR # Convert this into 512 bb. We also add a small buffer. addbuf BUF 5 512 (( BUF = $BUF / 512 )) echo "$BUF" return 0 } # end of get_ar_msize() ######################################################################## ## Function: is_ar_member() ## Parameters: ## Returns: 0 = yes, 1 = no, 2 = ERROR ######################################################################## is_ar_member() { typeset ERROR='eval pmerror "is_ar_member()"; return 1' typeset AFILE=$1 typeset MEMBER=$2 # Check the input check_file $AFILE [[ $? -ne 0 || -z $MEMBER ]] && $ERROR # Do the check eval $AR -X 32_64 -t $AFILE $MEMBER > /dev/null 2>&1 # Return the output return $? } # end of is_ar_member() ######################################################################## ## Function: get_parent_dir() ######################################################################## get_parent_dir() { typeset ERROR='eval pmerror "get_parent_dir()"; return 1' typeset NODE=$1 [[ -z $NODE ]] && $ERROR NODE=$(abspath $NODE) || $ERROR if [[ -d $NODE ]]; then echo "$NODE" return 0 elif [[ -f $NODE ]]; then # remove initial "/" NODE=${NODE#/} # remove file if still has slashes [[ "$NODE" != ${NODE%/*} ]] && NODE=${NODE%/*} || NODE="" # add slash back in NODE="/${NODE}" # check results check_dir $NODE || $ERROR # print results echo "$NODE" return 0 fi # If we got here, something went wrong. $ERROR } # end of get_parent_dir() ######################################################################## ## Function: odm_set_emgr_bit() ## Parameters: ######################################################################## odm_set_emgr_bit() { typeset ERROR='eval perror 206; return 2' typeset EODMCHANGE='eval pmerror $ODMCHANGE; $ERROR' typeset EODMGET='eval pmerror $ODMGET; $ERROR' typeset ELPPDATA='eval perror 205 $LPP; $ERROR' typeset LPP=$1 typeset ODMDIR=$2 typeset OP=$3 typeset LPPODM=$ODMDIR/lpp typeset CMD typeset CPFLAG=$4 typeset BUF="" typeset RC=0 # Do a few checks upfront. [[ "$PLATFORM" != "AIX" || -z $ODMDIR || -z $LPP ]] && $ERROR [[ "$OP" != "ADD" && "$OP" != "REMOVE" ]] && $ERROR check_dir $ODMDIR || $ERROR check_file $LPPODM || $ERROR # Get the cp_flag if we do not have a valid one isnum $CPFLAG if [[ $? -ne 0 ]]; then CPFLAG=$(odm_get_cp_flag $LPP $ODMDIR) || $ERROR fi # If the emgr bit is already set, our work is done. is_emgr_bit_on $CPFLAG RC=$? if [[ $RC -eq 1 && "$OP" = "ADD" ]]; then return 0 elif [[ $RC -eq 0 && "$OP" = "REMOVE" ]]; then return 0 fi [[ $RC -ne 0 && $RC -ne 1 ]] && $ERROR # Flip emgr bit in CPFLAG if [[ "$OP" = "ADD" ]]; then add_emgr_bit CPFLAG || $ERROR else remove_emgr_bit CPFLAG || $ERROR fi # Get the odm entry BUF=$(ODMDIR=$ODMDIR $ODMGET -q name=$LPP lpp) || $EODMGET [[ -z $BUF ]] && $ELPPDATA # Set the new cp_flag in buf BUF=$(echo "$BUF" | $AWK -v cpflag=$CPFLAG '{ if ($1 == "cp_flag") sub($3,cpflag); print $0 }') [[ $? -ne 0 || -z $BUF ]] && $ERROR # Do the odmchange in lpp. echo "$BUF" | ODMDIR=$ODMDIR $ODMCHANGE -q name=$LPP -o lpp || $EODMCHANGE return 0 } # end of odm_set_emgr_bit() ######################################################################## ## Function: remove_emgr_bit (removes emgr bit to variable) ## Parameters: ######################################################################## remove_emgr_bit() { typeset ERROR='eval pmerror "remove_emgr_bit()"; return 1' typeset VARNAME=$1 typeset VALUE=0 typeset NEW_BIT=0 # A few checks.. [[ -z $VARNAME ]] && $ERROR eval VALUE="$"$VARNAME isnum $VALUE || $ERROR # Get the resulting bit (invert and bitwise and) (( NEW_BIT = $VALUE & ~$EMGRBIT )) [[ $? -ne 0 ]] && $ERROR # Upvar the new bit value eval $VARNAME=$NEW_BIT eval VALUE="$"$VARNAME [[ -z $VALUE ]] && $ERROR return 0 } # end of remove_emgr_bit() ######################################################################## ## Function: is_emgr_bit_on (checks if bit set in value) ## Parameters: ## Returns: 1 = is set, 0 = not set, 2 = ERROR ######################################################################## is_emgr_bit_on() { typeset ERROR='eval pmerror "is_emgr_bit_on()"; return 2' typeset VALUE=$1 typeset RC=0 # A few checks.. [[ -z $VALUE ]] && $ERROR isnum $VALUE || $ERROR # Is the bit set ? (bitwise and) (( RC = $VALUE & $EMGRBIT )) [[ -z $RC ]] && $ERROR # Return the results [[ $RC -eq 0 ]] && return 0 || return 1 # Can't get here.. should not anyway. $ERROR } # end of is_emgr_bit_on() ######################################################################## ## Function: add_emgr_bit (adds emgr bit to variable) ## Parameters: ######################################################################## add_emgr_bit() { typeset ERROR='eval pmerror "add_emgr_bit()"; return 1' typeset VARNAME=$1 typeset VALUE=0 typeset NEW_BIT=0 # A few checks.. [[ -z $VARNAME ]] && $ERROR eval VALUE="$"$VARNAME isnum $VALUE || $ERROR # Get the resulting bit (bitwise or) (( NEW_BIT = $VALUE | $EMGRBIT )) [[ $? -ne 0 ]] && $ERROR # Upvar the new bit value eval $VARNAME=$NEW_BIT eval VALUE="$"$VARNAME [[ -z $VALUE ]] && $ERROR return 0 } # end of add_emgr_bit() ######################################################################## ## Function: odm_get_cp_flag (gets cp flag for lpp) ## Parameters: ######################################################################## odm_get_cp_flag() { typeset ERROR='eval pmerror "odm_get_cp_flag()"; return 1' typeset EODMGET='eval pmerror $ODMGET; $ERROR' typeset ELPPDATA='eval perror 205 $LPP; $ERROR' typeset ODMDIR=$2 typeset LPPODM=$ODMDIR/lpp typeset LPP=$1 typeset BUF="" # Do a few checks upfront. [[ "$PLATFORM" != "AIX" || -z $ODMDIR || -z $LPP ]] && $ERROR check_dir $ODMDIR || $ERROR check_file $LPPODM || $ERROR ########################################################### ## Ok, lets do the odmget. ########################################################### BUF=$(ODMDIR=$ODMDIR $ODMGET -q name=$LPP lpp) || $EODMGET ########################################################### ## Make sure we got data. If not, we have to stop. ########################################################### [[ -z $BUF ]] && $ELPPDATA ########################################################### ## Parse and print out the cp_flag ########################################################### BUF=$(echo "$BUF" | $AWK '{ if ($1 == "cp_flag") {print $3; exit(0)} }') [[ $? -ne 0 || -z $BUF ]] && $ERROR isnum $BUF || $ERROR echo "$BUF" return $? } # end of odm_get_cp_flag() ######################################################################## ## Function: ACLGET (Wrapper to not use aclget command) ## Parameters: -o ######################################################################## ACLGET() { typeset PLACE=$1 typeset ACL_OUTPUT=$2 typeset ACL_INPUT=$3 LANG=C istat $ACL_INPUT|grep "^Protection: "|read PLACE permissions typeset -i RC=$? LANG=C istat $ACL_INPUT|grep "^Owner: "|read PLACE User PLACE Group RC=RC+$? echo $permissions|awk '{print substr($0,1,3)" "substr($0,4,3)" "substr ($0,7,3)}'|read oowner ogroup oother User=${User##*\(} User=${User%%\)} Group=${Group##*\(} Group=${Group%%\)} cat << END > $ACL_OUTPUT * * ACL_type AIXC * attributes: base permissions owner($User): $oowner group($Group): $ogroup others: $oother extended permissions disabled END RC=RC+$? return $RC } # end of ACLGET() ######################################################################## ## Function: ACLPUT() (Wrapper to not use aclget command) ## Parameters: -i ######################################################################## ACLPUT() { typeset PLACE=$1 typeset ACL_INPUT=$2 typeset ACL_OUTPUT=$3 grep "owner(" $ACL_INPUT|read User oowner grep "group(" $ACL_INPUT|read Group ogroup grep "others:" $ACL_INPUT|read SPACE oother User=${User##*\(} User=${User%%\)*} Group=${Group##*\(} Group=${Group%%\)*} chown $User:$Group $ACL_OUTPUT typeset -i RC=$? oowner=`echo $oowner|tr -d '-'` ogroup=`echo $ogroup|tr -d '-'` oother=`echo $oother|tr -d '-'` chmod u=$oowner,g=$ogroup,o=$oother $ACL_OUTPUT RC=RC+$? return $RC } # end of ACLPUT() ######################################################################## ## Function: aclcomp() (Compares two sets of ACL output) ## Parameters: ######################################################################## aclcomp() { typeset ERROR='eval pmerror "aclcomp()"; return 2' typeset NOMATCH='eval return 1' typeset MATCH='eval return 0' typeset TARGET=$1 typeset EXPECTED=$2 typeset ACLOUT=$MSG_BUF typeset MSG_EXPECTED typeset MSG_ACTUAL typeset RC=0 typeset LINE="===========================" [[ -z $TARGET || -z $EXPECTED ]] && $ERROR check_file $TARGET || $ERROR check_file $EXPECTED || $ERROR $RM -f $MSG_BUF # just in case ########################################################### ## First, get the new ACL attributes. ########################################################### aclget $TARGET $ACLOUT || $ERROR ########################################################### ## Now, compare them to the EXPECTED. ########################################################### LC_ALL=C LANG=C $DIFF $EXPECTED $ACLOUT > /dev/null 2>&1 RC=$? if [[ $RC -eq 2 ]]; then # An error from diff pmerror $DIFF $ERROR elif [[ $RC -eq 1 ]]; then # There are differences.. perror 195 $TARGET elif [[ $RC -eq 0 ]]; then $MATCH else # An unknown error $ERROR fi ########################################################### ## If we got here, then there is a mismatch. ########################################################### if [[ "$PLATFORM" = "AIX" ]]; then $PB print_msg 196 echo "$LINE" | $LOGIT $CAT $EXPECTED | $LOGIT $PB print_msg 197 echo "$LINE" | $LOGIT $CAT $ACLOUT | $LOGIT $NOMATCH fi $ERROR } # end of aclcomp() ######################################################################## ## Function: aclput() ## Parameters: ######################################################################## aclput() { typeset ERROR='eval pmerror "aclput()"; return 1' [[ $EMGR_IGNORE_ACLERR = "1" ]] && ERROR='eval pmerror "aclput()"' typeset TARGET="$1" typeset ACLIN="$2" typeset OWNER typeset GROUP [[ -z $TARGET || -z $ACLIN ]] && $ERROR check_file $TARGET || $ERROR check_file $ACLIN || $ERROR if [[ "$PLATFORM" = "AIX" ]]; then # Exec aclput ACL_ERROR=`LC_ALL=C LANG=C $ACLPUT -i $ACLIN $TARGET 2>&1` RC=$? if [[ $RC -ne 0 ]] then if [[ $RC -eq 109 ]] then # Use ACLPUT() wrapper function since aclput not supported ACLPUT -o $ACLIN $TARGET || $ERROR else print $ACL_ERROR >&2 $ERROR fi else ERROR='eval pmerror $AWK; pmerror "aclput()"; return 1' # Get the OWNER and GROUP from ACLIN. OWNER=$($AWK '/ owner\(.*\):/ { sub("^.*owner\\(","",$0); sub("\\):.*$","",$0); print $0; exit(0);}' $ACLIN) [[ $? -ne 0 || -z $OWNER ]] && $ERROR GROUP=$($AWK '/ group\(.*\):/ { sub("^.*group\\(","",$0); sub("\\):.*$","",$0); print $0; exit(0);}' $ACLIN) [[ $? -ne 0 || -z $GROUP ]] && $ERROR ERROR='eval pmerror "aclput()"; return 1' chown "$OWNER:$GROUP" "$TARGET" || $ERROR fi return 0 fi $ERROR } # end of aclput() ######################################################################## ## Function: aclget() ## Parameters: ######################################################################## aclget() { typeset ERROR='eval pmerror "aclget()"; return 1' [[ $EMGR_IGNORE_ACLERR = "1" ]] && ERROR='eval pmerror "aclget()"' typeset TARGET="$1" typeset ACLOUT="$2" [[ -z $TARGET || -z $ACLOUT ]] && $ERROR check_file $TARGET || $ERROR if [[ "$PLATFORM" = "AIX" ]]; then # Exec aclget ACL_ERROR=`LC_ALL=C LANG=C $ACLGET -o $ACLOUT $TARGET 2>&1` RC=$? if [[ $RC -ne 0 ]] then if [[ $RC -eq 109 ]] then # Use ACLGET() wrapper function since aclget not supported ACLGET -o $ACLOUT $TARGET || $ERROR else print $ACL_ERROR >&2 $ERROR fi fi check_file $ACLOUT || $ERROR return 0 fi $ERROR } # end of aclget() ######################################################################## ## Function: toupper ######################################################################## toupper() { typeset ERROR='eval pmerror "toupper()"; return 1' typeset -u STR=$1 [[ -z $STR ]] && $ERROR echo "$STR" return 0 } # end of toupper() ######################################################################## ## Function: check_fdup_space (Check that we have space to dup a file ## within its own filesystems). ## Parameters: [ ] [ ] ######################################################################## check_fdup_space() { typeset ERROR='eval pmerror "check_fdup_space()"; return 1' typeset NEEDSIZE typeset FILE="$1" typeset BUF=$2 typeset FS="$3" [[ -z $FILE ]] && $ERROR # Make sure that we have enough space to write out the file copy # Note.. the file must exist ! NEEDSIZE=$(getfsize $FILE) || $ERROR if [[ -n $FS ]]; then FS=$(whichfs $FS) else # default FS=$(whichfs $FILE) || $ERROR fi # Add buffer if needed.. if [[ -n $BUF ]]; then addbuf NEEDSIZE $BUF || $ERROR [[ $NEEDSIZE -lt 32 ]] && NEEDSIZE=32 fi # Do the check-expand. ck_exp_fs $FS $NEEDSIZE || $ERROR # Done ! return 0 } # end of check_fdup_space() ######################################################################## ## Function: slibclean (Executes slibclean) ######################################################################## slibclean() { typeset ERROR='eval pmerror "slibclean()"; return 1' if [[ "$PLATFORM" = "AIX" && -z $INUCLIENTS ]]; then # Set slibclean setcmd slibclean || $ERROR # Exec slibclean $SLIBCLEAN || $ERROR fi return 0 } # end of slibclean() ######################################################################## ## Function: Verify that string does not contain $DS (database ## field separator). ######################################################################## vstrDS() { # We could use EGREP here, but that would mean spawning another # process (yuck !). So we use some ksh trickery. TESTSTR="${1}" # test string [[ -z $TESTSTR ]] && return 0 BUF="${TESTSTR%%$DS*}" BUF="${TESTSTR##*$DS}" # There is a bug in ksh that forces us to use a case statement # here instead of an if-then conditional case "$BUF" in "$TESTSTR") return 0 ;; *) : ;; esac perror 44 "$TESTSTR" "$DS" return 1 } # end of vstrDS() ######################################################################## ## Function: dec() (decrement variable by 1) ######################################################################## dec() { # decrement variable by 1 typeset -i CUR_VALUE=0 typeset -i NEW_VALUE=0 typeset ERROR='eval pmerror "dec()" ; return 1' eval isnum "$"$1 || $ERROR eval CUR_VALUE="$"$1 (( NEW_VALUE = $CUR_VALUE - 1 )) eval $1=$NEW_VALUE return 0 } # end of dec() ######################################################################## ## Function: is_file_new() Is this file new ## Parms: Efix number, [ ITYPE ] ## Returns: 0 = "yes", 1 = "no" ######################################################################## is_file_new() { typeset ERROR='eval pmerror "is_file_new()"; return 1' typeset ENUM="$1" typeset ITYPE="$2" isnum $ENUM || $ERROR # If we did not get an ITYPE then try to get it. [[ -z $ITYPE ]] && ITYPE=${A_EINST[$ENUM]} [[ -n $ITYPE ]] || $ERROR case $ITYPE in $ETNEWI|$ETNEWR|$ETNEWISMP|$ETNEWOTH|$ETNEWNONE) return 0 ;; esac # not new return 1 } # is_file_new() ######################################################################## ## Function: which_lpp() Which LPP owns this file ? ######################################################################## which_lpp() { typeset ERROR='eval perror 99; perror 131 $FILE; return 1' typeset BUF typeset FILE="$1" typeset FILESET="" ########################################################### ## Check that we are at least in the right neighborhood. ########################################################### [[ "$PLATFORM" != "AIX" || -z $FILE ]] && $ERROR ########################################################### ## Is the fileset installed ? If yes, get the data. ########################################################### BUF=$(LC_ALL=C LANG=C $LSLPP -qwc $FILE) if [[ $? -ne 0 ]]; then pmerror $LSLPP $ERROR fi [[ -z $BUF ]] && $ERROR FILESET=$(echo $BUF | $AWK -F":" '{ print $2 }') [[ $? -ne 0 || -z $FILESET ]] && $ERROR echo "$FILESET" return 0 } # end of which_lpp() ######################################################################## ## Function: addbuf() (Add Buffer to Variable) ## Parameters: (note: this ## is approximate) ######################################################################## addbuf() { # increment variable by 1 typeset -i CUR_VALUE=0 typeset -i NEW_VALUE=0 typeset BUF_PERCENT=$2 typeset FLATADD=$3 typeset DIVISOR=100 typeset ERROR='eval pmerror "addbuf()" ; return 1' [[ -z $FLATADD ]] && FLATADD=0 # Make sure the input is valid isnum $FLATADD || $ERROR eval isnum "$"$1 || $ERROR isnum $BUF_PERCENT || $ERROR [[ $BUF_PERCENT -eq 0 ]] && return 0 [[ $BUF_PERCENT -lt 0 || $BUF_PERCENT -gt 100 ]] && $ERROR # Calculate the divisor (( DIVISOR = 100 / $BUF_PERCENT )) [[ $DIVISOR -eq 0 ]] && $ERROR eval CUR_VALUE="$"$1 (( NEW_VALUE = $CUR_VALUE + ($CUR_VALUE / $DIVISOR) )) [[ $NEW_VALUE -eq $CUR_VALUE ]] && (( NEW_VALUE = $NEW_VALUE +1 )) # Finally, add the flat. (( NEW_VALUE = $NEW_VALUE + $FLATADD )) # Upvar the results. eval $1=$NEW_VALUE return 0 } # end of addbuf() ######################################################################## ## Function: get_lpp_level() ## Returns: 0 = OK, !0 = Error ## Output: LPP level if fileset is installed. If fileset is not ## installed, then NULL is returned. ######################################################################## get_lpp_level() { typeset ERROR='eval perror 99; return 1' typeset BUF typeset FILESET="$1" typeset STATE typeset LEVEL typeset JUNK ########################################################### ## Check that we are at least in the right neighborhood. ########################################################### [[ "$PLATFORM" != "AIX" || -z $FILESET ]] && $ERROR ########################################################### ## Is the fileset installed ? If yes, get the data. ########################################################### LC_ALL=C LANG=C $LSLPP -qLc > $MSG_BUF if [[ $? -ne 0 ]]; then $RM -f $MSG_BUF pmerror $LSLPP $ERROR fi BUF=$($AWK -v F=$FILESET -F: '{if ($2 == F) {print $3" "$6 ; exit(0)}}' $MSG_BUF) || $ERROR $RM -f $MSG_BUF ########################################################### ## If BUF is null, then the fileset is not installed, ## just return with 0 return code. ########################################################### [[ -z $BUF ]] && return 0 ########################################################### ## Read in STATE and LEVEL ########################################################### echo "$BUF" | read LEVEL STATE JUNK [[ -z $LEVEL || -z $STATE || -n $JUNK ]] && $ERROR ########################################################### ## Make sure that the fileset is Applied or Committed. ########################################################### [[ $STATE != "C" && $STATE != "A" ]] && perror 100 "$FILESET" echo "$LEVEL" return 0 } # end of get_lpp_level() ######################################################################## ## Function: clevels() (Compare levels in VRMF format) ## Parameters LEV1, LEV2, CONDITIONAL ## CONDITIONAL: LT,GT,EQ,LE,GE,VONLY(verify only) ## Returns: 0 = Condition true, 1 = Condition false, 2 = Error ######################################################################## clevels() { typeset ERROR='eval pmerror "clevels()"; return 2' typeset T='eval return 0' # return true typeset F='eval return 1' # return false typeset LEV1[3] # array to hold level typeset LEV2[3] # array to hold level typeset OP="$3" typeset VRMF="1 2 3 4" typeset TOK typeset REL="" [[ -z $1 || -z $2 || -z $OP ]] && $ERROR case $OP in LT|GT|EQ|LE|GE|VONLY) : ;; *) $ERROR ;; esac ########################################################## ## Break the level fields into tokens and load into arrays. ########################################################### IFS="." # Set break point to "." i=0; for TOK in $1; do inc i || $ERROR; LEV1[$i]=$TOK; done i=0; for TOK in $2; do inc i || $ERROR; LEV2[$i]=$TOK; done ########################################################## ## Check that we did not get an invalid level. ########################################################## unset IFS for TOK in $VRMF; do isnum ${LEV1[$TOK]} || { perror 98 "$1"; $ERROR } isnum ${LEV2[$TOK]} || { perror 98 "$2"; $ERROR } done ########################################################## ## If this is a verify only, then we are done.. ########################################################## [[ $OP = "VONLY" ]] && return 0 ########################################################## ## Get the relationship ("REL"): ## E = equal ## G = greater then ## L = less then ########################################################## for TOK in $VRMF; do if [[ ${LEV1[$TOK]} -gt ${LEV2[$TOK]} ]]; then REL=G break elif [[ ${LEV1[$TOK]} -lt ${LEV2[$TOK]} ]]; then REL=L break fi done # if we get here then they are equal [[ -z $REL ]] && REL="E" ########################################################## ## Figure out the return. ########################################################## case $OP in LE) [[ $REL = "L" || $REL = "E" ]] && $T || $F ;; GE) [[ $REL = "G" || $REL = "E" ]] && $T || $F ;; GT) [[ $REL = "G" ]] && $T || $F ;; LT) [[ $REL = "L" ]] && $T || $F ;; EQ) [[ $REL = "E" ]] && $T || $F ;; *) $ERROR esac # If we got here, we suffered some sort of error $ERROR } # end of clevels() ######################################################################## ## Function: isfopen() (Is the file open ?) ## Parameters: FILE ## Returns: 1 = open, 0 = closed, 2 = ERROR ######################################################################## isfopen() { typeset ERROR='eval pmerror "isfopen()"; return 2' typeset OPEN='eval return 1' typeset CLOSED='eval return 0' typeset FILE="$1" typeset FUSER_CMD typeset BUF typeset WAITPID [[ -z $FILE ]] && $ERROR check_file $FILE || $ERROR # If this is alt-root, then nothing should be running there.. # lets hope. [[ -n $INUCLIENTS ]] && return 0 [[ "$PLATFORM" = "AIX" ]] && FUSER_CMD="$FUSER -xf" || FUSER_CMD="$FUSER" # Run a process to trigger any dormant libraries. This is mainly # done for libc.a $SLEEP 5 > /dev/null 2>&1 & WAITPID=$! BUF=$(eval $FUSER_CMD "$"FILE 2> $MSG_BUF) if [ $? -ne 0 ]; then $CAT $MSG_BUF >&2 pmerror "$FUSER_CMD" $ERROR fi kill -TERM $WAITPID > /dev/null 2>&1 # If BUF is full return "open", if not return closed. [[ -n $BUF ]] && $OPEN || $CLOSED # If we got here, there is a problem. $ERROR } # end of isfopen() ######################################################################## ## Function: conv_einstaller Convert EFIX installer ## Takes installer number and converts to user language. ######################################################################## conv_einstaller() { typeset TYPE="$1" typeset ERROR='eval pmerror "conv_einstaller()"; return 1' typeset MSG=0 case $TYPE in $ETINSTALLP) MSG="installp";; $ETNEWI) MSG="installp (new)";; $ETRPM) MSG="RPM";; $ETNEWR) MSG="RPM (new)";; $ETISMP) MSG="ISMP";; $ETNEWISMP) MSG="ISMP (new)";; $ETNEWNONE) MSG=$(EMGRLOG=0 print_msg 95);; # none $ETOTHER) MSG=$(EMGRLOG=0 print_msg 11);; # other $ETNEWOTH) MSG="Other (new)";; *) $ERROR;; # Error esac [[ -n $MSG ]] && echo "$MSG" || $ERROR return 0 } # end of conv_einstaller() ######################################################################## ## Function: conv_etype() Convert EFIX file type ## Takes TYPE number and converts to user language. ######################################################################## conv_etype() { typeset TYPE="$1" typeset ERROR='eval pmerror "conv_etype()"; return 1' typeset MSG=0 case $TYPE in $FSTAND) MSG=9 ;; # standard flat file or binary $FLIBM) MSG=10 ;; # Library Member $FCU) MSG=427 ;; # Concurrent Update *) $ERROR ;; # Error esac EMGRLOG=0 print_msg $MSG || $ERROR return 0 } # end of conv_etype() ######################################################################## ## Function: print_line() ######################################################################## print_line() { typeset LINEOPT="$1" typeset LINEOUT="" [[ -z $LINEOPT ]] && return 1 case "$LINEOPT" in "dashes") LINEOUT="+-------------------------------------" LINEOUT="$LINEOUT----------------------------------------+";; "stars" ) LINEOUT="**************************************" LINEOUT="$LINEOUT*****************************************";; "equals" ) LINEOUT="======================================" LINEOUT="$LINEOUT=========================================";; *) return 1;; esac [[ $EMGRLOG -eq 1 ]] && echo "$LINEOUT" >> $LOG [[ $QUIET -eq 0 ]] && echo "$LINEOUT" return 0 } # end of print_line() ######################################################################## ## Function: inc() (increment variable by 1) ######################################################################## inc() { # increment variable by 1 typeset -i CUR_VALUE=0 typeset -i NEW_VALUE=0 typeset ERROR='eval pmerror "inc()" ; return 1' eval isnum "$"$1 || $ERROR eval CUR_VALUE="$"$1 (( NEW_VALUE = $CUR_VALUE + 1 )) eval $1=$NEW_VALUE return 0 } # end of inc() ######################################################################## ## Function: get_wouldbe_fs() ######################################################################## get_wouldbe_fs() { typeset ERROR='eval pmerror "get_wouldbe_fs()"; return 1' typeset FLOC="$1" # future location typeset FOUND=0 # is it found ? typeset FS="" # future file system [[ -z $FLOC ]] && $ERROR ########################################################### ## This function loops until it finds a filesystem that ## would host a file that is TO BE delivered. It returns ## that filesystem. ########################################################### while [[ ! -d $FLOC && ! -f $FLOC ]]; do FLOC=${FLOC%/*} [[ -z $FLOC ]] && FLOC="/" done FS=$(whichfs "$FLOC") || $ERROR [[ -z $FS ]] && $ERROR echo "$FS" } # end of get_wouldbe_fs() ######################################################################## ## Function: check_root (is root ? returns 9 if yes, 1 if no) ######################################################################## check_root() { isnum "$UID" if [[ $? -ne 0 ]]; then pmerror "check_root()" return 1 fi if [[ $UID -ne 0 ]]; then perror 86 return 1 fi return 0 } # end of check_root() ######################################################################## ## Function: print_ecfile ######################################################################## print_ecfile() { typeset BUF # local buffer typeset EFCOUNT=0 # local EFIX file counter typeset FILEVAR # local EFIX file variable typeset Q # local common question variable typeset FIELD VALUE # local question/answer pairs typeset ERROR='eval pmerror "print_ecfile()"; return 1' # Set TENUM #TENUM=${#A_ESHIP[*]} # array count typeset TENUM=$GENUM ########################################################### ## Print the current date. ########################################################### echo "*DATE=$($DATE)" || $ERROR ########################################################### ## Print COMMON info (applies to entire EFIX). ########################################################### for Q in $CVARS; do echo "$Q" | IFS=: read FIELD VALUE ### *** Skip these fields.. *** ### ### *** Make sure to update: *** ### ### *** read_ecfile() *** ### case $FIELD in *QNEXT|*QORDER|TIMESTAMP|STATE) continue;; esac eval echo $FIELD="$"$VALUE done size=$(getfsum $EDIR/secfile.sec) echo CKSUM_SEC=$size # print blank $PB ########################################################### ## Print out EFIX file info. One stanza per file. ########################################################### while [[ $EFCOUNT -lt $TENUM ]]; do # Safety valve for this loop if [[ $EFCOUNT -gt $MAXEFILES ]]; then $ERROR fi # Increment EFCOUNT (( EFCOUNT = $EFCOUNT + 1 )) # Check if this is a blank file [[ -z ${A_ESHIP[$EFCOUNT]} ]] && continue ########################################################### ## Print stanza header ########################################################### echo "EFIX_FILE:" ########################################################### ## Print EFIX file numer ########################################################### echo "\tEFIX_FILE_NUM=$EFCOUNT" ########################################################### ## Print out all file info specific to this file. ########################################################### for FILEVAR in $EFILE_VARS; do echo "$FILEVAR" | IFS=: read FIELD VALUE ### *** Skip these fields.. *** ### ### *** Make sure to update: *** ### ### *** read_ecfile() *** ### case $FIELD in "PACKAGE"|"MOUNTS") continue;; CU_OBJECT|CU_LDR_NAME|SANDBOX_BINARIES|CU_TIMESTAMP|TARGET_TIMESTAMPS|CU_MODULE_MEMBER_NAME) eval VAL="\${$VALUE[\$EFCOUNT]}" [[ -n $VAL ]] || continue ;; esac echo "\t\c" eval echo "$"FIELD="$"{$VALUE["$"EFCOUNT]} done # print blank $PB done ########################################################### ## Print the internal field separator, the next question, ## and qorder. ########################################################### $PB echo "# Internal navigation variables" echo "*QNEXT=$GQTYPE" echo "*QORDER=$QORDER" return 0 } # end of print_ecfile() ######################################################################## ## Function: get_common_cvars() ## Retrieves the value of a all the common (file independant) variables. ######################################################################## get_common_cvars() { typeset FIELD VARNAME VAR typeset ERROR='eval pmerror "get_common_cvars()"; return 1' typeset RC=0 # Set LANG to "C" so locale is predictable typeset OLD_LANG=$LANG export LC_ALL=C LANG=C # Make sure ECFILE is there.. check_file $ECFILE || $ERROR CPAIRS="" for VAR in $CVARS; do echo "$VAR" | IFS=: read FIELD VARNAME; if [[ -n $CPAIRS ]]; then CPAIRS="$CPAIRS\n$FIELD $VARNAME" else CPAIRS="$FIELD $VARNAME" fi done ########################################################### ## Export CPAIRS so awk can use it. Init MSG_BUF just in ## case. ########################################################### export CPAIRS $RM -f $MSG_BUF ########################################################### ## Read $ECFILE and print out CPAIRS in the following ## format: ## export $VARNAME=$VALUE ## This way we can just . exec the output file. ########################################################### $AWK ' BEGIN { while ("echo \"$CPAIRS\"" | getline) { if ( $1 ~ "\\*" ) VAR="\\"$1; else VAR=$1; fields[VAR]=$2; } # end of while loop } # end of BEGIN { # start of MAIN for (VAR in fields) { if ( $0 ~ "^[ |\t]*"VAR"=" ) { i=index($0,"="); OUT=substr($0,i+1); # remove leading and ending tabs and spaces gsub("(^[ |\t]*|[ |\t]*$)","",OUT); # escape single quotes , \47 = escaped single quote gsub("\47","\47\\\47\47",OUT); print "export "fields[VAR]"=\47"OUT"\47"; } # end of if } # end for loop }' $ECFILE > $MSG_BUF RC=$? [[ $DEBUG -eq 1 ]] && $CAT $MSG_BUF if [[ $RC -ne 0 ]]; then $RM -f $MSG_BUF $ERROR fi . $MSG_BUF || $ERROR ########################################################### ## Cleanup. ########################################################### # reset LANG unset LC_ALL export LANG=$OLD_LANG $RM -f $MSG_BUF unset CPAIRS return 0 } # end of get_common_cvars() ######################################################################## ## Function: get_efile_vars() ## Retrieves the value of a all the common (file independant) variables. ######################################################################## get_efile_vars() { typeset FIELD VARNAME VAR typeset RC=0 typeset ERROR='eval pmerror "get_efile_vars()"; return 1' # Set LANG to "C" so locale is predictable typeset OLD_LANG=$LANG export LC_ALL=C LANG=C # Make sure ECFILE is there.. check_file $ECFILE || $ERROR EPAIRS="" for VAR in $EFILE_VARS; do echo "$VAR" | IFS=: read FIELD VARNAME; if [[ -n $EPAIRS ]]; then EPAIRS="$EPAIRS\n$FIELD=$VARNAME" else EPAIRS="$FIELD=$VARNAME" fi done ########################################################### ## Export EPAIRS so awk can use it. Init MSG_BUF just in ## case. ########################################################### export EPAIRS $RM -f $MSG_BUF [[ -z $GENUM ]] && GENUM=0 ########################################################### ## Read $ECFILE and print out EPAIRS in the following ## format: ## export $VARNAME=$VALUE ## This way we can just . exec the output file. ########################################################### $AWK -F"=" 'BEGIN { while ("echo \"$EPAIRS\"" | getline) { if ( $1 ~ "\\*" ) VAR="\\"$1; else VAR=$1; fields[VAR]=$2; loopsafe=0; } # end of while loop } # end of BEGIN { # start of MAIN if ( GENUM == 0 ) exit 0; if ( $0 ~ "^[ |\t]*EFIX_FILE_NUM=" ) EFCOUNT=$2; if ( GENUM < EFCOUNT ) exit 4; for (VAR in fields) { if ( $0 ~ "^[ |\t]*"VAR"=" ) { i=index($0,"="); OUT=substr($0,i+1); # remove leading and ending tabs and spaces gsub("(^[ |\t]*|[ |\t]*$)","",OUT); # escape single quotes , \47 = escaped single quote gsub("\47","\47\\\47\47",OUT); print "export "fields[VAR]"["EFCOUNT"]=\47"OUT"\47"; next; } # end of if } # end for loop }' GENUM=$GENUM $ECFILE > $MSG_BUF RC=$? # set return code [[ $DEBUG -eq 1 ]] && $CAT $MSG_BUF [[ $RC -ne 0 ]] && $ERROR . $MSG_BUF || $ERROR ########################################################### ## Cleanup. ########################################################### # reset LANG unset LC_ALL export LANG=$OLD_LANG $RM -f $MSG_BUF unset EPAIRS return 0 } # end of get_efile_vars() ######################################################################## ## Function: isin() (Is in ?) isin [ ] ## Returns: 0 = ok, !0 = error ## Output: 1 = TRUE, 0 = false, (if COUNT="G" = number of times) ######################################################################## isin() { eval $SIGTRAP typeset ERROR='eval pmerror "isin()"; return 1' typeset VAR="$1" typeset LIST="$2" typeset COUNT="$3" typeset MAXLOOP=15000 typeset C=0 # counter typeset OUTPUTC='eval echo "$C"; return 0' typeset E # element index typeset GETCOUNT=0 ########################################################### ## Check if VAR is in LIST. For example, if VAR="a" and ## LIST="a b c", then isin() returns true (i.e. 1). If the ## COUNT flag is set, then we return true if VAR occurs ## in LIST $COUNT times or more. If COUNT = "G", ## then we return the number of times VAR is in LIST with ## a MAXLOOP of 15000. ########################################################### [[ -z $VAR ]] && $ERROR [[ -z $LIST ]] && $OUTPUTC if [[ $COUNT = "G" ]]; then GETCOUNT=1 elif [[ -n $COUNT ]]; then isnum "$COUNT" || $ERROR [[ $COUNT -eq 0 ]] && $ERROR fi for E in $LIST; do [[ $E != $VAR ]] && continue (( C = $C + 1 )) # If COUNT is blank, then we are done. [[ -z $COUNT ]] && break # If we need to get the total cout, keep going ! [[ $GETCOUNT -eq 1 ]] && continue # If we need to check for a certain count, then lets # check if we got there yet. [[ $C -ge $COUNT ]] && break # If something went terribly wrong.. [[ $C -gt $MAXLOOP ]] && $ERROR done # Check if we go the right min count Set C to # true if yes and false if no if [[ $GETCOUNT -eq 0 && -n $COUNT ]]; then [[ $C -eq $COUNT ]] && C=1 || C=0 fi $OUTPUTC # Should never get here. $ERROR } # end of isin() ######################################################################## ## Function: Verify Efix Control File ######################################################################## read_ecfile() { eval $SIGTRAP # set function error typeset ERROR='eval perror 70; return 1' typeset VAR # local var index typeset FIELD # ec field typeset VALUE # ec value typeset OUT # output buffer from getecvar typeset RC=0 # local return code typeset COMMON=53 # command variable error num typeset EFIXF=21 # efix file variable error num typeset TENUM=0 # total efix files typeset EFCOUNT=0 # local efix file count typeset TARGET # local target var # reboot incompatibility tracker typeset REEBOOT_INCOMPAT=0 ck_overwrite_bit "read_ecfile" && ERROR=":" check_file $ECFILE || $ERROR [[ ! -s $ECFILE ]] && $ERROR # Verifying efix control file.. print_msg 71 ########################################################### ## Check COMMON info (applies to entire EFIX). ########################################################### get_common_cvars || $ERROR for VAR in $CVARS; do echo "$VAR" | IFS=: read FIELD VALUE eval OUT="$"$VALUE vstrDS "$OUT" || { perror $COMMON $FIELD $ERROR } if [[ -z "$OUT" ]]; then process_new_options "$FIELD" "OUT" "$OUT" || $ERROR fi # Specific field checks case $FIELD in A_ELABEL) if [[ ${#OUT} -gt $LABELMAX ]]; then perror 20 "$LABELMAX" perror $COMMON $FIELD $ERROR fi ;; TIMESTAMP|STATE) # Ignore these for ecfile (see print_ecfile()) continue ;; ABSTRACT) if [[ ${#OUT} -gt $ABSTRACTMAX ]] || [[ ${#OUT} -eq 0 ]]; then perror $COMMON $FIELD $ERROR fi ;; REBOOT|BUILD_BOOT_IMAGE|FIXTESTED|LKU_CAPABLE) isYorN $OUT; RC=$? if [[ $RC -ne 1 && $RC -ne 0 ]]; then perror $COMMON $FIELD $ERROR fi ;; *INSTWORK|*VERSION) isnum "$OUT" || { perror $COMMON $FIELD $ERROR } ;; *) if [[ -z $OUT ]]; then perror $COMMON $FIELD $ERROR fi ;; esac done ########################################################### ## Verify that we do not have any incompatible ecfile ## attributes. ########################################################### check_reboot_conflict || $ERROR ########################################################### ## Get the total number of EFIX files. ########################################################### isnum $GENUM if [[ $? -ne 0 ]]; then perror $COMMON EFIX_FILES $ERROR fi ########################################################### ## Verify file specific info.. ########################################################### get_efile_vars || $ERROR while [[ $EFCOUNT -lt $GENUM ]]; do # Safety valve for this loop if [[ $EFCOUNT -gt $MAXEFILES ]]; then pmerror "read_ecfile()" $ERROR fi # Increment EFCOUNT (( EFCOUNT = $EFCOUNT +1 )) for VAR in $EFILE_VARS; do echo "$VAR" | IFS=: read FIELD VALUE eval OUT="$"{$VALUE[$EFCOUNT]} typeset EFILE_ERROR='eval perror "$EFIXF" "$FIELD" "$EFCOUNT"; $ERROR' ck_overwrite_bit "read_ecfile" && ERROR=":" vstrDS "$OUT" || $EFILE_ERROR # If this is not a mounti operation, set MOUNTS to NONE [[ $MOUNTI -eq 0 ]] && MOUNTS[$EFCOUNT]=$NONE case $FIELD in # ** Ignore these for ecfile.. see print_ecfile() ** PACKAGE|MOUNTS|CU_TIMESTAMP|TARGET_TIMESTAMPS|CU_MODULE_MEMBER_NAME) continue ;; EFIX_FILE_NUM|*CKSUM|*SIZE) isnum $OUT || $EFILE_ERROR ;; SHIP_FILE|TARGET_FILE) [[ -z $OUT || $OUT != "/"* ]] && $EFILE_ERROR ;; CU_OBJECT|CU_LDR_NAME|SANDBOX_BINARIES) [[ -n $OUT && $OUT != "/"* ]] && $EFILE_ERROR ;; TYPE) isnum $OUT || $EFILE_ERROR [[ $OUT -ge 1 && $OUT -le $ETYPEMAX ]] || $EFILE_ERROR ;; INSTALLER) isnum $OUT || $EFILE_ERROR [[ $OUT -ge 1 && $OUT -le $EINSTMAX ]] || $EFILE_ERROR ;; ACL) is_file_new $EFCOUNT if [[ $? -eq 0 && $OUT = "DEFAULT" ]]; then perror 136 perror "$EFIXF" "ACL or INSTALLER" "$EFCOUNT" perror 70; return 1 fi [[ $OUT = "DEFAULT" ]] && continue typeset a1 a2 a3 echo "$OUT" | IFS=":" read a1 a2 a3 unset IFS if [[ -n $a1 && -n $a2 && -n $a3 ]]; then isnum $a3 && continue fi $EFILE_ERROR ;; *) if [[ -z $OUT ]]; then perror $COMMON $FIELD $ERROR fi ;; esac done # end of for VAR in $EFIL_VARS for loop ########################################################### ## Verify that we do not have more then one TARGET_FILE ########################################################### check_dup_targets "${A_ETARGET[$EFCOUNT]}" "${A_AR_MEM[$EFCOUNT]}" \ "1" "$EFCOUNT" || $ERROR ############################################################### ## Transform any overlaid files from within a versioned WPAR ############################################################### if [[ $EMGR -eq 1 ]]; then check_overlaid_targets || $ERROR fi continue done # end of file specific info.. return 0 } # end of read_ecfile() ######################################################################## ## Function: perror (Print Error) ######################################################################## perror() { ISERROR=1 print_msg "$@" >&2 ISERROR=0 # If warning has been supressed, we are done. [[ $NOWARN -eq 1 ]] && return 0 # Check if this is a warning and update the GLOBAL_WARNING # variable if it is. [[ -z $GLOBAL_WARNING ]] && export GLOBAL_WARNING=0 case "$1" in 26|89|123|152|155|171|178|199|220| \ 230|245|269|300|341|342|381|343| \ 345|346|347|349|245|358|373|100| \ 403|405|409|91|235|299|327|418|419) inc_global_warning ;; esac return 0 } # end of perror() ######################################################################## ## Function: sigtrap() ######################################################################## sigtrap() { trap '' 1 2 3 11 15 [[ $EMGR -eq 1 ]] && set_sum_stats 1 perror 65 FAIL } # end of sigtrap() ######################################################################## ## Function: whichfs ("Which FS", prints the FS for a given file or ## directory) ## Input Parameters: Node (file or directory or link to file/directory) ######################################################################## whichfs() { typeset NODE="$1" typeset BUF="" typeset ERROR='eval pmerror "whichfs()"; return 1' typeset DEV typeset FS typeset ISDEV=0 # Is device or special case file system typeset LOOPMAXHARD=256 # max number of loops allowed typeset LOOPMAXSOFT=128 # max number of attempts we will make before # giving an answer typeset LOOPC=0 # loop count [[ -z $NODE ]] && $ERROR if [[ -d $NODE ]]; then check_dir $NODE || $ERROR elif [[ -f $NODE ]]; then check_file $NODE || $ERROR else $ERROR # not a file or dir and not a link to a file or a dir # what the heck is it then ? Hopefully not a block or # char device. fi while : ; do # Loop safety inc LOOPC [[ $LOOPC -gt $LOOPMAXHARD ]] && $ERROR # Get df output into BUF # If NODE is a special file (e.g. /dev), remove trailing / if [[ -b $NODE || -c $NODE ]]; then BUF=$(LC_ALL=C LANG=C $DF $NODE) || $ERROR else BUF=$(LC_ALL=C LANG=C $DF $NODE/) || $ERROR fi # Drop header within BUF BUF=$(echo "$BUF" | $AWK '{if (NR>1) {print $0; exit(0)}}') || $ERROR # Set the device DEV=$(echo "$BUF" | $AWK1 ) [[ $? -ne 0 || -z $DEV ]] && $ERROR ####################################################################### ## Is DEV a device ? If yes, then we set FS and return it. If it is ## not a device, then we set DEV as the new NODE and start again. ## Note: If we have looped more then LOOPMAXSOFT, then this seems to ## not be getting anywhere. Lets give a warning and return whatever ## we have at the time. If the INUCLIENTS variable is set, then we are ## in a chrooted environment and (where mount install is not allowed) ## and will take the first FS NODE we get back ####################################################################### # If DEV is a device or a "special case" file system device, then # set ISDEV to true. [[ -b $DEV || -c $DEV || "$DEV" != "/"* ]] && ISDEV=1; if [[ $ISDEV -eq 1 || $LOOPC -gt $LOOPMAXSOFT || -n $INUCLIENTS ]] then [[ $LOOPC -gt $LOOPMAXSOFT ]] && pmerror "whichfs()" # Get the FS FS=$(echo "$BUF" | $AWK '{ print $NF }') || $ERROR # We are done ! break else # Set DEV as new search NODE NODE=$DEV fi done # end of loop if [[ -n $FS ]]; then echo "$FS" return 0 fi # If we got here, then there is a problem. $ERROR } # end of whichfs() ######################################################################## ## Function: subshrc (Sub-shell Return Codes) ######################################################################## subshrc() { ############################################################ ## Since ksh is not very good about communicating return ## codes between subshells (without getting very complex), ## We have deviced our own simple method of leving and ## checking for ERROR tokens.. This function supports ## two operations: ## "PUTRC" -> Gets the RC from the previous command. ## If RC != 0, then a token file is generated. ## "GETRC" -> Prints the RC as recorded by the last PUTRC ## call. Note, if there is no token file, then ## RC=0. ############################################################ ############################################################ ## Set the return code form the command that ran previous to ## this function.. ############################################################ typeset PRC=$? typeset RETRC=0 ############################################################ ## Setup Operation and ERROR. ############################################################ typeset OP="$1" # operation typeset ERROR='eval pmerror "subshrc()"; return 1' if [[ $OP = "PUTRC" ]]; then # Check PRC, this is a little paranoid, but better safe then sorry isnum $PRC || $ERROR $RM -f $ERRTOKEN [[ $PRC -eq 0 ]] && return 0 echo "$PRC" > $ERRTOKEN || $ERROR return 0 fi if [[ $OP = "GETRC" ]]; then if [[ ! -s $ERRTOKEN ]]; then echo "0" return 0 fi RETRC=$($CAT $ERRTOKEN) $RM -f $ERRTOKEN isnum $RETRC || $ERROR echo "$RETRC" return 0 fi # If we get here, then there is a problem. $ERROR } # end of subshrc() ######################################################################## ## Function: verifysum (Verify Sum) ## Parameters: ######################################################################## verifysum() { typeset FILE="$1" # File to check typeset ESUM=$2 # Expected sum typeset ASUM=0 # Actual sum typeset MEMBER=$4 typeset ERROR='eval pmerror "verifysum()"; return 1' ############################################################ ## Make sure the parameters are valid. ############################################################ isnum $ESUM if [[ $? -ne 0 ]]; then $ERROR fi check_file $FILE || return 1 ############################################################ ## If ESUM is volitile (i.e. 0), then we are done. ############################################################ [[ $ESUM -eq 0 ]] && return 0 ############################################################ ## Get the actual sum on FILE.. ############################################################ ASUM=$(getfsum $FILE) || $ERROR ############################################################ ## Compare the actual sum to the expected sum. ############################################################ if [[ $ASUM -ne $ESUM ]]; then perror 54 $FILE perror 58 "$ESUM" "$ASUM" return 1 fi # OK ! return 0 } # end of verifysum() ######################################################################## ## Function: pmerror (Print Module Error) ######################################################################## pmerror() { perror 26 "$1" return 0 } # end of pmerror() ######################################################################## ## Function: pcerror (Print Common Error) ######################################################################## pcerror() { perror 22 } # end of pcerror ######################################################################## ## Function: init_pos_cmds (Initialize POSIX Commands) ######################################################################## init_pos_cmds() { typeset CMDS # Posix commands typeset ERROR='eval return 1' [[ -n "$EMGR_IGNORE_CMDNOFIND" ]] && ERROR='eval continue' ############################################################ ## Setup simple commands ############################################################ CMDS="awk du sum wc egrep rm mv mkdir rmdir date tail sed sort df uname" CMDS="$CMDS printf fuser id compress ln tar cp vi cat touch zcat chmod" CMDS="$CMDS chown sleep tee diff ar mount umount ps ls sync tr od" ############################################################ ## Loop through $CMDS and $PATHS to find the correct ## location for this system. If we do not find the given ## command in any of the paths, then report an error and ## return. ############################################################ for CMD in $CMDS; do setcmd "$CMD" || $ERROR done # end of CMDS ############################################################ ## Setup complex commands. ############################################################ export AWK1="eval $AWK '{ print \$1 }'" export AWK2="eval $AWK '{ print \$2 }'" export DBAWK="$AWK -F $DS" export DF="$DF -P" ############################################################ ## That is it ! ############################################################\ return 0 } # end of init_pos_cmds() ######################################################################## ## Function: check_file ######################################################################## check_dir() { typeset DIR="$1" [[ -z $DIR ]] && DIR="" if [[ ! -d $DIR || ! -x $DIR ]]; then perror 56 "$DIR" return 1 fi return 0 } # check_dir ######################################################################## # Function: abspath() ######################################################################## abspath() { typeset RELPATH="$1" # local relative path (input) typeset ABSPATH="" # absolute path (return) typeset ISFILE=0 # Is it a file ? typeset ISDIR=0 # Is it a directory ? typeset RC=0 # Local RC typeset FILEDIR # directory that contains the file typeset FILE # The name of the actual file if [[ -z $RELPATH ]]; then # No input.. ouch. perror 55 "" return 1 fi # Is this a file [[ -f $RELPATH ]] && ISFILE=1 [[ -d $RELPATH ]] && ISDIR=1 if [[ $ISFILE -eq 0 && $ISDIR -eq 0 ]]; then # If this is not a file or a directory, then we are done. perror 55 "$RELPATH" return 1 elif [[ $ISFILE -eq 1 && $ISDIR -eq 1 ]]; then # If this is both a file and a directory, then we have a big problem. perror 55 "$RELPATH" pmerror "abspath()" fi ############################################################ ## If this is a directory, then just check it and cd into ## the path. ############################################################ if [[ $ISDIR -eq 1 ]]; then check_dir $RELPATH || return 1 cd $RELPATH if [[ $? -ne 0 ]]; then perror 55 "$RELPATH" return 1 fi ABSPATH=$PWD cd $OLDPWD fi ############################################################ ## If this is a file, then it is a little more complicated. ## We have to get the directory the file is in, check it ## and cd into it to get the absolute path. ############################################################ if [[ $ISFILE -eq 1 ]]; then # First, check that the file is valid and accessible check_file $RELPATH || return 1 # Parse dir from file FILEDIR=${RELPATH%/*} FILE=${RELPATH##*/} ############################################################ ## Lets interprate the output a little: ## 1. If FILEDIR equals FILE, then we have a RELPATH ## with no slashes. This means that FILEDIR is the ## current directory. ## 2. If FILE is set, but FILEDIR is not, that means ## FILE was in "/" ############################################################ [[ $FILEDIR = $FILE ]] && FILEDIR=$PWD [[ -n $FILE && -z $FILEDIR ]] && FILEDIR="/" ############################################################ ## Check that the DIR we got is valid, we make a recursive ## call to get the absolute path of FILEDIR ############################################################ check_dir $FILEDIR || return 1 ABSPATH=$(abspath $FILEDIR) || return 1 # Tack on the file name (we avoid the "//" prEFIX) if [[ $ABSPATH != "/" ]]; then ABSPATH=$ABSPATH/$FILE else ABSPATH=/$FILE fi fi ############################################################ ## Lets check if our output is valid. ############################################################ if [[ $ISDIR -eq 1 ]]; then check_dir $ABSPATH || return 1 else check_file $ABSPATH || return 1 fi # Output absolute path.. echo "$ABSPATH" return 0 } # end of abspath ######################################################################## # Function: ck_exp_fs() ######################################################################## ck_exp_fs() { typeset FREESPACE # space available in local filesystem typeset FS="$1" # local filesystem typeset FREE_SPACE_REQ="$2" # free space required in 512bb typeset ADDSPACE # You guessed it ! Space we need to add # to FREESPACE to get FREE_SPACE_REQ typeset CANEXPAND=0 typeset ERROR='eval pmerror "ck_exp_fs()"; return 1' typeset EXPAND_MAX_MEG=128 # 128 megabytes typeset EXPAND_MAX_512 # 128 megs in 512BB typeset ERROR='eval pmerror "ck_exp_fs()"; return 1' [[ -z $FS || -z $FREE_SPACE_REQ ]] && $ERROR # Did the user set a variable to ignore space requirements ? isYorN $EPKG_IGNORE_SPREQ [[ $? -eq 1 ]] && return 0 # Ignore -X on a thin server if [[ $THINSERVER -eq 1 && $EXP_REQUESTED -eq 1 ]]; then if [[ $PRINTED_IGNORE_X -eq 0 ]]; then print_msg 469 "-X" $PB export PRINTED_IGNORE_X=1 fi fi # Get the formal FS name FS=$(whichfs $FS) || $ERROR # Get free space FREE_SPACE=$(getfsfree $FS) || return 1 # Make sure FREE_SPACE_REQ is valid isnum "$FREE_SPACE_REQ" || $ERROR ############################################################ ## Ok, lets do the math. Note, all buffering should be done ## before this call is made. ############################################################ if [[ $FREE_SPACE -lt $FREE_SPACE_REQ ]]; then (( ADD_SPACE = $FREE_SPACE_REQ - $FREE_SPACE )) else return 0 fi ############################################################ ## Determine if expansion is possible, allowed, and ## requisted.. ############################################################ [[ -z $EXP_REQUESTED ]] && EXP_REQUESTED=0 # Don't allow CANEXPAND to be set on thin server if [[ $THINSERVER -eq 1 && $EXP_REQUESTED -eq 1 ]]; then EXP_REQUESTED=0 fi # Cannot expand filesystem inside WPAR if [[ $($IN_WPAR) -eq 1 && $EXP_REQUESTED -eq 1 ]]; then EXP_REQUESTED=0 fi if [[ "$PLATFORM" = "AIX" && $EXP_REQUESTED -eq 1 ]]; then CANEXPAND=1 print_msg 49 $FS else perror 50 "$FS" "$ADD_SPACE" return 1 fi ############################################################ ## Check to make sure we did not pass EXPAND_MAX ############################################################ (( EXPAND_MAX_512 = $EXPAND_MAX_MEG * 2048 )) if [[ $ADD_SPACE -gt $EXPAND_MAX_512 && $FORCE -ne 1 ]]; then # We have to stop. We calculate some values to give them # a good error message. # Put ADD_SPACE int megs (( ADD_SPACE = $ADD_SPACE / 2048 )) [[ $ADD_SPACE -eq $EXPAND_MAX_MEG ]] && inc ADD_SPACE perror 89 "$EXPAND_MAX_MEG" "$FS" "$ADD_SPACE" return 1 fi ############################################################ ## Do the expansion. ############################################################ /usr/sbin/chfs -a size=+$ADD_SPACE $FS if [[ $? -ne 0 ]]; then perror 51 return 1 fi return 0 } # end of ck_exp_fs() ######################################################################## # Function: getfsfree() (Get filesystem free space) ######################################################################## getfsfree() { typeset FS="$1" # File system typeset SUMBUF # Local buffer typeset RC # Local return code FS=$(whichfs $FS) if [[ $? -ne 0 ]]; then perror 48 "$1" return 1 fi BUF=$(LC_ALL=C LANG=C $DF $FS/) if [[ $? -ne 0 || -z $BUF ]]; then perror 48 "$FS" return 1 fi BUF=$(echo "$BUF" | $AWK '{getline; print $4}') RC=$? isnum "$BUF" || RC=1 if [[ $RC -ne 0 || -z $BUF ]]; then perror 48 "$FS" return 1 fi echo "$BUF" return 0 } # end of getfsfree ######################################################################## ## Function: vstr() (Verify String) ######################################################################## vstr() { typeset STR # local var for string typeset BADC="" # bad char typeset DISP="" eval STR="$"$# [[ -z $STR ]] && return 0 while getopts "cesa:" OPTION; do case $OPTION in c) BADC="$BADC:";; # check for : e) BADC="$BADC=";; # check for "=" s) BADC="$BADC[:space:]";; # check for whitespace a) BADC="$BADC:=[:space:]";; # check for ALL esac done # Surround bad characters with brakets BADC="[$BADC]" # Execute egrep echo "$STR" | LC_ALL=C LANG=C $EGREP -q "$BADC" > /dev/null 2>&1 # Check return code if [[ $? -ne 0 ]]; then return 0 else perror 44 "$STR" "$BADC" return 1 fi } # end of vstr() ######################################################################## ## Function: getecvar ## Retrieves the value of a specific ecvar. ######################################################################## getecvar() { typeset VAR=$1 typeset RC=0 typeset ENUM="$2" typeset BUF # local buf # Set LANG to "C" so locale is predictable typeset OLD_LANG=$LANG export LC_ALL=C LANG=C # Make sure ECFILE is there.. check_file $ECFILE || return 1 # If ENUM, not set, then this is a straight fetch [[ -z $ENUM ]] && ENUM=0 ########################################################### ## If ENUM is set then we need to look in the EFIX_FILE ## stanza that matches ENUM, otherwise we do a straight ## forward fetch. ########################################################### BUF=$($AWK -F"=" 'BEGIN { AUTO=0; } { # If this is an AUTOVAR (starts with "*"), then # add "//" to the front, so that the "*" is # not treated as a metacharcter. if ( AUTO == 0 && VAR ~ "\\*" ) { VAR="\\"VAR; AUTO=1; } # Go to the correct ENUM if ( ENUM != 0 ) { loopsafe=0; #go to the correct stanza while ( !($0 ~ "^[ |\t]*EFIX_FILE_NUM=" && $2 == ENUM) ) {getline; ++loopsafe; if (loopsafe > 1800) break;} ENUM=0; next; } if ( $0 ~ "^[ |\t]*"VAR"=" ) { i=index($0,"="); OUT=substr($0,i+1); # remove leading and ending tabs and spaces gsub("(^[ |\t]*|[ |\t]*$)","",OUT); print OUT; exit 0 } }' VAR="$VAR" ENUM=$ENUM $ECFILE # end of awk) RC=$? # reset LANG unset LC_ALL export LANG=$OLD_LANG # Print the buffer [[ -n $BUF ]] && echo "$BUF" return $RC } # end of getecvar() ######################################################################## ## Function: timestamp ######################################################################## timestamp() { typeset OUT # local ouput typeset FORMAT="$1" # timestamp format typeset ERROR='eval pmerror "timestamp()"; return 1' typeset STRINGS="" typeset M="%" # Magic (this is done because the cmvc checkin # process can misinterprate some of the symbols meant # for dater).. [[ -z $FORMAT ]] && $ERROR case $FORMAT in FULL) # Month Month-day hour minutes seconds century OUT=$($DATE +m%md%dt%H:%m:%Sy%y) ;; MDY) # Month - day OUT=$($DATE +%y%m%d);; RAW) OUT=$($DATE +"$M"m"$M"d"$M"H"$M"m"$M"S"$M"y) ;; DT) OUT=$($DATE +"%D %T") ;; esac [[ $? -ne 0 || -z "$OUT" ]] && $ERROR echo "$OUT" return 0 } # end of timestamp() ######################################################################## ## Function: initQs ######################################################################## initQs() { typeset Q FIELD VALUE CSUM ######################################################################## ## ABSTRACT = Enter EFIX abstract [35 bytes maximum]: ## QFILES = Does this EFIX deliver one or more files ? (yes/no): ## PREI = Enter the local location for the pre-install script ## POSTI = Enter the local location for the post-install script ## ESHIP = Enter the ship location for EFIX file number : ## ETARGET = Enter target location for EFIX file number : ## ETYPE = Select file type for EFIX file number : ## EINST = Select the installer which tracks the file that is.. ## EMORE = Are there more EFIX files ? (yes/no): ## EREBOOT = Is a reboot required after installing thi.. ## EDESC = Enter the EFIX description. Please include the symptoms that a ## POSTR = Enter the local location for the post-remove script. ## PRER = Enter the local location for the pre-remove script. ######################################################################## # Initialize answers to all known questions for Q in $CVARS; do echo "$Q" | IFS=: read FIELD VALUE eval unset $VALUE > /dev/null 2>&1 done # Set control script sums to $NONE for CSUM in PREISUM PRERSUM POSTISUM POSTRSUM; do eval $CSUM="$"NONE done # Set the QORDER global variabel that tracks the question order [[ $EPKG -eq 1 ]] && Qorder -q -o RESET # The next question (global) export QNEXT="" # Efix file number (global) export GENUM=0 # Init global PA (Previous Answer) PA="" # Init global ASKAGAIN (ask again) ASKAGAIN=0 # Init global QTYPE GQTYPE="" # Init all FILE data. for VAR in $EFILE_VARS; do echo "$VAR" | IFS=: read FIELD VALUE eval unset $VALUE > /dev/null 2>&1 done return 0 } # end of initQs ######################################################################## ## Function: check_file_full (Check that the file is not empty). ######################################################################## check_file_full() { typeset FILE="$1" check_file "$FILE" || return 1 if [[ ! -s $FILE ]]; then perror 83 "$FILE" return 1 fi } # end of check_file_full() ######################################################################## ## Function: check_file ######################################################################## check_file() { typeset FILE="$1" [[ -z $FILE ]] && FILE="" if [[ ! -f $FILE || ! -r $FILE ]]; then perror 28 "$FILE" return 1 fi return 0 } # check_file ######################################################################## ## Function: isYorN ## Return Status: 1 = "yes", 0 = "no", 2 = failure ######################################################################## isYorN() { typeset ANS="$1" # local answer typeset YESSTR typeset NOSTR typeset STR [[ -z $ANS ]] && return 2 if [ -x /usr/bin/locale ]; then # We should be able to use yes/no strings. YESSTR=$(/bin/locale yesstr 2> /dev/null) || YESSTR="yes:y:Y:YES:Yes" NOSTR=$(/bin/locale nostr 2> /dev/null) || NOSTR="no:n:N:NO:No" YESSTR="$YESSTR:YES:Yes" NOSTR="$NOSTR:NO:No" else YESSTR="yes:y:Y:YES:Yes" NOSTR="no:n:N:NO:No" fi YESSTR="$YESSTR:1" NOSTR="$NOSTR:0" # Set the Internal Field Separator (IFS) to ":" typeset IFS=: for STR in $YESSTR; do if [[ "$ANS" = "$STR" ]]; then return 1 fi done for STR in $NOSTR; do if [[ "$ANS" = "$STR" ]]; then return 0 fi done # If we go here, then something went wrong return 2 } # end of isYorN() ######################################################################## ## Function: isnum ## Returns: 0 = STR is all digits 0-9, 1 = STR is not all digits ######################################################################## isnum() { typeset STR="$1" typeset ERROR='eval pmerror "isnum()"; return 1' typeset COUNT=0 STR=${STR#-} # remove negative [[ -z "$STR" ]] && return 1 while [[ -n "$STR" ]]; do [[ "$STR" = "${STR%[0-9]}" ]] && return 1 STR=${STR%[0-9]} # loop safety (( COUNT = $COUNT + 1 )) [[ $COUNT -gt 40000 ]] && $ERROR done return 0 } # end of isnum() ######################################################################## ## Function: getfsum ######################################################################## getfsum() { typeset FILE="$1" typeset FSUM typeset RC=0 typeset ERROR='eval perror 24 $FILE; return 1' if [[ -z "$FILE" ]]; then perror 24 "" return 1 fi check_file $FILE || $ERROR FSUM=$($SUM $FILE/) || $ERROR FSUM=$(echo "$FSUM" | $AWK1) || $ERROR isnum "$FSUM" || $ERROR echo "$FSUM" return 0 } # end of getfsum() ######################################################################## ## Function: getfsize ######################################################################## getfsize() { typeset FILE="$1" typeset FSIZE typeset RC=0 typeset ERROR='eval perror 23 "$FILE"; return 1' if [[ -z "$FILE" ]]; then perror 23 "" return 1 fi check_file $FILE || $ERROR FSIZE=$($DU -s $FILE/) || $ERROR FSIZE=$(echo "$FSIZE" | $AWK1) || $ERROR isnum "$FSIZE" || $ERROR echo "$FSIZE" return 0 } # end of getfsize() ######################################################################## ## Function: init_vars() (Initialize Variables) ######################################################################## init_vars() { # Init execute vars export PATH="/bin:/usr/bin:/sbin:/usr/sbin:$PATH" umask 077 export POSIXLY_CORRECT=1 export MAXEFILES=400 # MAX number of efix files per package export NONE="." export PB="echo" # print blank export SIGTRAP="trap 'sigtrap' 1 2 3 11 15" export ISERROR=0 export DEBUG=0 export ECFILE="" export STARTDIR=$PWD export DS="|:|" # database separator, we try to make this # somewhat uniq export PRINTED_IGNORE_X=0 # Only print warning once # Set THINSERVER=1 if /usr is an nfs file system # to indicate emgr/epkg is being run on a NIM thin server # Also determine if nimadm using cache or not so we can # remove old IFIXs from /usr directory. /usr/sysv/bin/df -n /usr | cut -d: -f2 | grep nfs >/dev/null if [[ $? -eq 0 && "$NIMADMCACHE" != "0" ]]; then export THINSERVER=1 else export THINSERVER=0 fi ########################################################### ## Only emgr needs these variables. ########################################################### if [[ $EMGR -eq 1 ]]; then # Directory that contains all emgr data if [[ $THINSERVER -eq 0 ]]; then export EMGRDIR="/usr/emgrdata" else export EMGRDIR="/var/emgrdata" fi set_emgrdata_vars || return 1 # States export INSTALLING="I" export REMOVING="R" export BROKEN="B" export STABLE="S" export PATCHED="P" export STABLE_PATCHED="SP" export BI_MODIFIED="QP" export STATES="S B R I N M U Q P SP QP SN QN RQ" # State suffix export TESTED="T" # applies to stable, mounted, unmounted, reboot req # Misc variables export NOSUMMARY=1 export CANCELLED_RC=999 # this is just a random unique RC export EPKG_VERSION=0 # version of this epkg image (installed # or being installed ########################################################### ## Y or N efix variables. Note, only epkg cares about ## the actual file path, etc. emgr just needs to know if ## it is set or not. ########################################################### export EYNVARS="A_PREREQ A_PREI A_POSTI A_PRER A_POSTR A_APARREF" EYNVARS="$EYNVARS A_EREBOOT A_BUILD_BOOT_IMAGE A_PKGLOCKS" EYNVARS="$EYNVARS A_SUPERSEDE A_E2E_PREREQ A_FIXTESTED A_LKU_CAPABLE" # Set global superseded variable export GSUPS="" # Set global efix requisites variables (prereq and xreq) export GE2EPREREQS="" export GE2EXREQS="" ########################################################### ## The magic bit number.. i.e. BIT(19) ########################################################### export EMGRBIT=524288 ########################################################### ## bosboot space in /tmp ########################################################### export BOSBOOT_TMP_SPACE=57344 fi # end of if EMGR -eq 1 ########################################################### ## Only epkg needs these variables. ########################################################### if [[ $EPKG -eq 1 ]]; then # Define REBOOT types export NOREBOOT=1 # reboot not required export REBOOT_BBI=2 # reboot required, rebuilt boot image export REBOOT_NO_BBI=3 # reboot, but do NOT rebuild boot image export BBI_NO_REBOOT=4 # build boot image, but no reboot export MAXREBOOT=4 # max reboot options fi ########################################################### ## Set the version of this emgr/epkg utility. We update the ## version each time a possibly incompatible change is ## introduced between different levels of epkg/emgr. ########################################################### # # # Version 0 = Original ship # # Version 1 = Added version control (d 418968) # # Version 2 = Change install type options (d 418781) # # Version 3 = Added e2e,md5,supersedes, pkg display # # Version 4 = Added addition package locks, reboot opts # # Version 5 = Added "TESTED FIX" # # Version 6 = Added Concurrent Update Functionality # # Version 7 = Added APARREF and CU Stacking functions # # # export EVERSION=7 # The current version. # # ########################################################### export EMGRLOG=0 export EPKGEXT="epkg.Z" export EXP_REQUESTED=0 export YES="yes" export NO="no" export DESCMAX=128 # 128 512 bb (or 64k) export LISTFILEMAX=128 # 128 512 bb (or 64k) export ABSTRACTMAX=38 # 38 bytes export PREREQMAX=32 # Max number of requisites export PKGLOCKMAX=32 # Max number of additional package locks export SUPERSMAX=32 # Max number of supersede entries export E2EMAX=32 # Max number of E2E prerequisites export LABELMAX=10 # Max number of chars in label name export LOCPRINT=0 # Local message printing ? # Valid REQTYPES export REQTYPES="PREREQ IFREQ XREQ" # Define EFIX file types (see conv_etype() for more info) export FSTAND=1 # standard flat file or binary export FLIBM=2 # Library Member export FCU=3 # standard + concurrent update export ETYPEMAX=3 # Max number of choices # Default work directory export WORKDIR=$HOME/epkgwork [[ $EMGR -eq 1 ]] && WORKDIR=/tmp # Define EFIX installer types export ETINSTALLP=1 # Currently tracked by installp. export ETRPM=2 # Currently tracked by RPM. export ETISMP=3 # Currently tracked by ISMP. export ETOTHER=4 # Currently tracked by another installer. export ETNEWI=5 # NEW file that will be tracked by installp export ETNEWR=6 # NEW file that will be tracked by RPM. export ETNEWISMP=7 # NEW file that will be tracked by ISMP. export ETNEWOTH=8 # NEW file that will be tracked by another installer. export ETNEWNONE=9 # NEW file that will never be tracked (temporary file) export EINSTMAX=9 # Max number of choices # Setup common vars CVARS="*EFIX_LABEL:A_ELABEL" # EFIX label" CVARS="$CVARS ABSTRACT:A_ABSTRACT" # EFIX abstract CVARS="$CVARS PRE_INSTALL:A_PREI" # pre-install script CVARS="$CVARS POST_INSTALL:A_POSTI" # post-install script CVARS="$CVARS PRE_REMOVE:A_PRER" # pre-remove script CVARS="$CVARS POST_REMOVE:A_POSTR" # post-remove script CVARS="$CVARS REBOOT:A_EREBOOT" # reboot required CVARS="$CVARS PREREQ:A_PREREQ" # prepreq file CVARS="$CVARS DESCRIPTION:A_EDESC" # description file CVARS="$CVARS *INSTWORK:A_INSTWORK" # install size CVARS="$CVARS *VUID:A_VUID" # Virtually unique ID CVARS="$CVARS EFIX_FILES:GENUM" # Efix files and genum CVARS="$CVARS *QNEXT:QNEXT" # Qnext CVARS="$CVARS *QORDER:QORDER" # Qorder CVARS="$CVARS TIMESTAMP:GTS" # Timestamp CVARS="$CVARS STATE:A_STATE" # State CVARS="$CVARS BUILD_BOOT_IMAGE:A_BUILD_BOOT_IMAGE" # build boot image CVARS="$CVARS *VERSION:EPKG_VERSION" # Version CVARS="$CVARS PKGLOCKS:A_PKGLOCKS" # Additional package locks CVARS="$CVARS SUPERSEDE:A_SUPERSEDE" # Superseded list CVARS="$CVARS E2E_PREREQ:A_E2E_PREREQ" # Efix to efix prereq CVARS="$CVARS FIXTESTED:A_FIXTESTED" # Tested fix (yes/no) CVARS="$CVARS CU_VR:A_CUVR" # Concurrent Update- patching vmm? (yes/no) CVARS="$CVARS APARREF:A_APARREF" # APAR reference file CVARS="$CVARS LKU_CAPABLE:A_LKU_CAPABLE" # Compatable with live update? (yes/no) export CVARS # Setup file specific vars EFILE_VARS="SHIP_FILE:A_ESHIP" # Ship file EFILE_VARS="$EFILE_VARS TARGET_FILE:A_ETARGET" # Target file EFILE_VARS="$EFILE_VARS TYPE:A_ETYPE" # File type EFILE_VARS="$EFILE_VARS INSTALLER:A_EINST" # Installer type EFILE_VARS="$EFILE_VARS *CKSUM:CKSUM" # File checksum EFILE_VARS="$EFILE_VARS *SIZE:SZ" # File size in 512bb EFILE_VARS="$EFILE_VARS ACL:A_ACL" # ACL for file EFILE_VARS="$EFILE_VARS PACKAGE:PACKAGE" # Package EFILE_VARS="$EFILE_VARS AR_MEM:A_AR_MEM" # Archive member EFILE_VARS="$EFILE_VARS MOUNTS:MOUNTS" # Mount source EFILE_VARS="$EFILE_VARS CU_OBJECT:CU_MODULE" # Concurrent Update- relocatable module EFILE_VARS="$EFILE_VARS CU_LDR_NAME:LDR_NAME" # Concurrent Update- loader name EFILE_VARS="$EFILE_VARS CU_TIMESTAMP:TSTAMP" # Concurrent Update- module timestamp EFILE_VARS="$EFILE_VARS SANDBOX_BINARIES:SB_BIN" # Concurrent Update- backing tree binaries EFILE_VARS="$EFILE_VARS TARGET_TIMESTAMPS:TGT_TS" # Concurrent Update- backing tree binary timestamps EFILE_VARS="$EFILE_VARS CU_MODULE_MEMBER_NAME:CU_MBR" # Concurrent Update- kext archive member to patch export EFILE_VARS # Setup IFILES (Install Files or common files), not counting ecfile # Also, see conv_ifile_to_target() IFILES="A_EDESC A_POSTI A_PRER A_POSTR A_PREI A_PREREQ A_PKGLOCKS" IFILES="$IFILES A_SUPERSEDE A_E2E_PREREQ A_APARREF" export IFILES # Initialize add_to_cleanup() vars export ADD_CLEAN_FILE="" # holder for dynamic files export ADD_CLEAN_DIR="" # holder for dynamic dirs # Reset all Qs initQs } # end of init_vars() ######################################################################## ## Function: init_sys_vars (Initialize System Variables) ######################################################################## init_sys_vars() { typeset ERROR='eval perror 62; return 1' typeset VAR VARS typeset CMD ############################################################ ## We track all system variables in the VARS local variable. ############################################################ VARS="UID PLATFORM AIX_VERSION" ############################################################ ## Get values for the different variables.. Note we do not ## use "export" in the original assignments so we can check ## the return codes from commands within the assignments. ############################################################ UID=$($ID -u) || $ERROR PLATFORM=$($UNAME) || $ERROR if [[ $PLATFORM = "AIX" ]]; then AIX_VERSION=$($UNAME -v) || $ERROR else AIX_VERSION=0 fi for VAR in $VARS; do eval export $VAR="$"$VAR done ############################################################ ## Now, that we have the platform, go ahead and set platform ## specific commands that will be used more than once by ## emgr (not for epkg). ############################################################ if [[ $PLATFORM = "AIX" && $EMGR -eq 1 ]]; then for CMD in lslpp odmget odmchange aclput aclget; do setcmd $CMD || $ERROR done fi ############################################################ ## Version 6 uses the kpatch command (emgr only, not epkg) ## in AIX for CU ############################################################ if [[ $PLATFORM = "AIX" && $EMGR -eq 1 ]]; then export KPATCH="/usr/lib/instl/kpatch" [[ -x $KPATCH ]] || $ERROR fi ############################################################ ## Set the correct message printer based on current locale. ############################################################ if [[ $PLATFORM = "AIX" && "$LANG" != "C" && "$LANG" != "en_US" ]] || [[ $EMGR_FORCE_LOCPRINT = 1 ]] then setcmd inuumsg || $ERROR LOCPRINT=1 fi return 0 } # end of init_sys_vars() ######################################################################## ## Function: check4debug() ######################################################################## check4debug() { ######################################################## ## Check up-front for the debug flag. ######################################################## typeset OPT typeset i for OPT in $@; do if [ "$OPT" = "-D" ]; then set -x for i in $(typeset +f); do typeset -ft $i; done export DEBUG=1 return 0 fi done return 1 } # end of check4debug() ######################################################################## ## Function: verify_prereq_file() ######################################################################## verify_prereq_file() { typeset ERROR='eval perror 105; return 1' typeset SERROR='eval perror 112 ">> $LINE <<"; RC=1; continue' typeset PFILE="$1" typeset -i LINES=0 typeset FILESET typeset LLEV # low level typeset HLEV # high level typeset TYPE typeset NOLEV="0.0.0.0" # no level or "NONE" typeset RC=0 typeset VALID_RTYPE typeset LINE print_msg 103 check_file_full $PFILE || $ERROR ########################################################### ## Check that the number of requisites has not exceeded ## PREREQMAX. ########################################################### LINES=$(print_cfgfile "$PFILE" | $WC -l) (( RC = $? + $(subshrc GETRC) )) [[ $RC -ne 0 ]] && $ERROR isnum $LINES || $ERROR if [[ $LINES -le 0 ]]; then perror 113 $ERROR fi if [[ $LINES -gt $PREREQMAX ]]; then perror 362 $PREREQMAX $ERROR fi ########################################################### ## Loop through the prereq file and process each entry. ########################################################### print_cfgfile $PFILE | while read LINE ; do echo "$LINE" | read FILESET LLEV HLEV TYPE JUNK [[ -z $FILESET || -z $LLEV || -z $HLEV ]] && $SERROR [[ -n $JUNK && "$JUNK" != "#"* ]] && $SERROR # Check the levels [[ $LLEV = "NONE" || $LLEV = "NULL" ]] && LLEV=$NOLEV [[ $HLEV = "NONE" || $HLEV = "NULL" ]] && HLEV=$NOLEV [[ -z $TYPE || "$TYPE" = "#"* ]] && TYPE="PREREQ" clevels "$LLEV" "$HLEV" VONLY || $SERROR # Make sure HLEV is not lower then LLEV if [[ $LLEV != $NOLEV && $HLEV != $NOLEV ]]; then clevels "$LLEV" "$HLEV" LE if [[ $? -ne 0 ]]; then perror 109 perror 112 ">> $LINE <<" RC=1 fi fi # Check if the requisite type is valid for VALID_RTYPE in $REQTYPES; do [[ "$VALID_RTYPE" = "$TYPE" ]] && continue 2 done # If we got here, then we have an error. $SERROR continue done (( RC = $RC + $? + $(subshrc GETRC) )) [[ $RC -ne 0 ]] && $ERROR return 0 } # end of verify_prereq_file() ######################################################################## ## Function: print_msg ######################################################################## print_msg() { [ "$ELIB_PRINT_MSG_DBG" -ne 1 ] && set +x typeset msg # local temp message var typeset tmsg # translated message typeset MSG_OPTION="$1" # local message number typeset CMD="epkg:" typeset C=0 typeset ERROR='eval echo "Error in print_msg()"; return 1' [ -z "$MSG_OPTION" ] && return 1 [[ $EMGR -eq 1 ]] && CMD="emgr:" case "$MSG_OPTION" in 1) msg="Initializing epkg..\n";; 2) msg="Enter efix abstract [$2 bytes maximum]:\n";; 3) msg="Does this efix deliver one or more files ? (yes/no):";; 4) msg="Enter the location for the pre-install script or \".\" to skip.\n";; 5) msg="Enter the location for the post-install script or \".\" to skip.\n";; 6) msg="Enter the ship file location for efix file number $2:\n";; 7) msg="Enter target file location or archive for efix file number $2:\n";; 8) msg="Select file type for efix file number $2:\n";; 9) msg="Standard (file or executable)\n";; 10) msg="Archive/Library Member\n";; 11) msg="Other\n";; 12) msg="Select the installer which tracks the file that is being fixed by efix\nfile number $2:\n";; 13) msg="Currently tracked by installp.\n";; 14) msg="Currently tracked by RPM.\n";; 15) msg="Currently tracked by ISMP.\n";; 16) msg="Currently NOT tracked -OR- tracked by another installer.\n";; 17) msg="NEW file that will NOT be tracked.\n";; 18) msg="Are there more efix files ? (yes/no):";; 19) msg="Is a reboot required after installing this efix ? (yes/no):";; 20) C=1; msg="$CMD 0645-001 The efix label cannot exceed $2 characters.\n";; 21) C=1; msg="$CMD 0645-002 Invalid file attribute value: attribute=$2, file=$3.\n";; 22) C=1; msg="$CMD 0645-003 Error.\n";; 23) C=1; msg="$CMD 0645-004 Error getting file size of $2.\n";; 24) C=1; msg="$CMD 0645-005 Error getting file checksum for $2.\n";; 25) C=1; msg="$CMD 0645-006 Failed to create efix package.\n";; 26) C=1; msg="$CMD 0645-007 ATTENTION: $2 returned an unexpected result.\n";; 27) C=1; msg="$CMD 0645-008 Input byte limit exceeded, please try again.\n";; 28) C=1; msg="$CMD 0645-009 Unable to locate or access file $2\n";; 29) C=1; msg="$CMD 0645-010 Target file location must be an absolute path.\n";; 30) C=1; msg="$CMD 0645-011 Invalid selection.\n";; 31) msg="NEW file that will be tracked by installp.\n";; 32) msg="NEW file that will be tracked by RPM.\n";; 33) msg="NEW file that will be tracked by ISMP.\n";; 34) msg="NEW file that will be tracked by another installer.\n";; 35) msg="Enter the installp fileset that will track this file:\n";; 36) C=1; msg="$CMD 0645-012 Error writing file information to efix control file.\n";; 37) msg="Located existing efix directory $2\n";; 38) msg="Creating efix directory $2.\n";; 39) msg="epkg has located existing efix control file $2.\nShould epkg use this control file instead of creating a new one ? (yes/no):\n";; 40) msg="[Previous Answer: \"$2\", "Enter" to accept.]\n";; 41) C=1; msg="$CMD 0645-013 Error setting up working directory. $2 is a file.\nPlease specify alternate work directory.\n";; 42) msg="Enter the location for the pre-remove script or \".\" to skip.\n";; 43) msg="Enter the location for the post-remove script or \".\" to skip.\n";; 44) C=1; msg="$CMD 0645-014 String \"$2\" contains invalid character group \"$3\".\n";; 45) C=1; msg="$CMD 0645-015 Error processing efix control file information.\n";; 46) C=1; msg="$CMD 0645-016 Unable to read file information for efix number $2.\n";; 47) msg="Processing efix control file ...\n";; 48) C=1; msg="$CMD 0645-017 Error getting file system size for $2.\n";; 49) msg="Expanding $2 file system ...\n";; 50) C=1; msg="$CMD 0645-018 $2 requires an additional $3 512-bb of free space.\n";; 51) C=1; msg="$CMD 0645-019 Error expanding file system.\n";; 52) C=1; msg="$CMD 0645-020 Error populating efix package directory.\n";; 53) C=1; msg="$CMD 0645-021 Invalid value for efix attribute $2.\n";; 54) C=1; msg="$CMD 0645-022 Checksum mismatch for file $2.\n";; 55) C=1; msg="$CMD 0645-023 Error resolving absolute path for $2.\n";; 56) C=1; msg="$CMD 0645-024 Unable to access directory $2\n";; 57) C=1; msg="$CMD 0645-025 Unable to locate command module $2.\n";; 58) msg=" Expected sum=$2, Actual sum=$3.\n";; 59) C=1; msg="$CMD 0645-026 Error creating efix package file.\n";; 60) msg="Packing efix package file ...\n";; 61) msg="Package file is: $2\n";; 62) C=1; msg="$CMD 0645-027 Error initializing system variables.\n";; 63) msg="Are you sure you want to quit this epkg session ? (yes/no):\n";; 64) msg="Populating efix directory ...\n";; 65) C=1; msg="$CMD 0645-028 Signal received, cleaning up.\n";; 66) msg="Enter the location for the efix description file or \".\" to compose it\nin an editor:\n";; 67) C=1; msg="\n$CMD 0645-029 Error editing description file.\n";; 68) msg="Enter the location for the installp prerequisite file or \".\" to skip.\n";; 69) C=1; msg="$CMD 0645-030 Error calculating install work size.\n";; 70) C=1; msg="$CMD 0645-031 Error verifying efix control file.\n";; 71) msg="Verifying efix control file ...\n";; 72) C=1; msg="$CMD 0645-032 Duplicate target locations for $2.\n";; 73) msg="Total number of efix files removed is $2.\n";; 74) msg="Return Status: FAILURE\n";; 75) C=1; msg="$CMD 0645-033 Error installing efix package.\n";; 76) C=1; msg="$CMD 0645-034 Error setting up work directory.\n";; 77) msg="Efix Manager Initialization\n";; 78) msg="Accessing efix metadata ...\n";; 79) C=1; msg="$CMD 0645-035 Efix package did not pass all preview checks.\n";; 80) msg="Return Status = SUCCESS\n";; 81) msg="Unpacking efix package file ...\n";; 82) C=1; msg="$CMD 0645-108 Error processing extraction space requirements.\n";; 83) C=1; msg="$CMD 0645-036 The file $2 is zero length.\n";; 84) C=1; msg="$CMD 0645-037 Error extracting efix metadata.\n";; 85) C=1; msg="$CMD 0645-038 Error unpacking efix package.\n";; 86) C=1; msg="$CMD 0645-039 You must have root user authority to execute this function.\n";; 87) C=1; msg="$CMD 0645-040 Error processing space requirements.\n";; 88) msg="Checking space requirements ...\n";; 89) C=1; msg="$CMD 0645-041 ATTENTION: this operation is attempting to expand a file system by more then $2 megabytes. If this is correct, please retry this operation with the force flag (\"-F\").\nFile system=$3, Space Needed=$4 megabytes.\n";; 90) msg="File system: $2, Free: $3, Required: $4, Deficit: $5.\n";; 91) msg="ATTENTION: expansion will be required for file system $2.\n";; 92) msg="Space Requirements\n";; 93) msg="Efix Description\n";; 94) msg="Efix Attributes\n";; 95) msg="None\n";; 96) C=1; msg="$CMD 0645-042 Description file size cannot exceed $2 512 byte-blocks.\n";; 97) msg="\nSpace statistics (in 512 byte-blocks):\n";; 98) C=1; msg="$CMD 0645-043 Error processing VRMF level $2\n";; 99) C=1; msg="$CMD 0645-044 Error processing installp fileset data.\n";; 100) C=1; msg="$CMD 0645-045 ATTENTION: Fileset $2 is in an unknown state.\n";; 101) C=1; msg="$CMD 0645-046 Error processing installp prerequisites.\n";; 102) msg="Installp Prerequisite Verification\n";; 103) msg="Verifying prerequisite file ...\n";; 104) msg="No prerequisites specified.\n";; 105) C=1; msg="$CMD 0645-047 Error verifying prerequisite file.\n";; 106) C=1; msg="$CMD 0645-048 The prerequisite file is currently limited to $2 entries.\n";; 107) msg="Prerequisite Number: $2\n Fileset: $3\n Minimal Level: $4\n" msg=""$msg" Maximum Level: $5\n Actual Level: $6\n" msg=""$msg" Type: $7\n Requisite Met: $8\n";; 108) msg="Checking prerequisites ...\n";; 109) C=1; msg="$CMD 0645-049 Upper prerequisite level is higher than lower limit.\n";; 110) C=1; msg="$CMD 0645-050 Prerequisite number $2 did not pass all checks. Please see\ndetails above.\n" ;; 111) msg="All prerequisites have been met.\n";; 112) C=1; msg="$CMD 0645-051 Syntax or content error in configuration file:\n$2\n";; 113) C=1; msg="$CMD 0645-052 Unable to locate any valid configuration file entries.\n";; 114) msg="Installing efix file #$2 (File: $3) ...\n";; 115) C=1; msg="$CMD 0645-053 Error installing efix file number $2.\n";; 116) msg="Removing efix file #$2 (File: $3) ...\n";; 117) C=1; msg="$CMD 0645-054 Error removing efix file number $2.\n";; 118) msg="Saving all files that will be replaced ...\n";; 119) C=1; msg="$CMD 0645-055 Error saving efixed files.\n";; 120) msg="Efix Installation Setup\n";; 121) msg="Initializing efix installation ...\n";; 122) C=1; msg="$CMD 0645-056 Error setting up for efix installation.\n";; 123) C=1; msg="$CMD 0645-057 ATTENTION: existing directory $2 will be renamed $3\n";; 124) msg="Installing all efix files:\n";; 125) msg="Total number of efix files installed is $2.\nAll efix files installed successfully.\n";; 126) msg="Efix File Removal\n";; 127) msg="Removing all efix files (in reverse order of installation):\n";; 128) C=1; msg="$CMD 0645-058 Removal of efix has failed.\n";; 129) C=1; msg="$CMD 0645-059 The save directory is incomplete.\n";; 130) msg="Setting up for removal of efix files ...\n";; 131) C=1; msg="$CMD 0645-060 Unable to determine owning fileset for $2.\n";; 132) msg="Building file-to-package list ...\n";; 133) msg="Enter access attributes for file $2 in the following format:\n::\nFor example to make the user=\"root\", the group=\"system\", and the modes \"444\",\nyou would enter root:system:444. Enter \".\" if you want to keep the default\n(i.e. current) permissions on the existing target file.\n";; 134) C=1; msg="$CMD 0645-061 Invalid format for access attributes string.\n" ;; 135) msg="Enter access attributes for file $2 in the following format:\n::\nFor example to make the user=\"root\",the group=\"system\", and the modes \"444\",\nyou would enter root:system:444.\n";; 136) C=1; msg="$CMD 0645-062 You must specify specific permissions for NEW files.\n";; 137) C=1; msg="$CMD 0645-063 Error writing to efix database.\n";; 138) C=1; msg="$CMD 0645-064 Error processing efix database.\n";; 139) C=1; msg="$CMD 0645-065 An efix with label \"$2\" is already installed.\n";; 140) C=1; msg="$CMD 0645-066 Unable to locate label \"$2\" in efix database.\n";; 141) C=1; msg="$CMD 0645-067 Error writing efix data for file $2.\n";; 142) C=1; msg="$CMD 0645-068 File entry already exists.\nLabel=\"$2\", File=\"$3\".\n";; 143) C=1; msg="$CMD 0645-069 Error deleting file from efix database.\nLabel=\"$2\", File=\"$3\".\n";; 144) C=1; msg="$CMD 0645-070 Target file $2 is locked by efix label \"$3\".\n";; 145) msg="Efix Lock Management\n";; 146) C=1; msg="$CMD 0645-109 Error processing efix lock data.\n";; 147) msg="Checking locks for file $2 ...\n";; 148) msg="All files have passed lock checks.\n";; 149) C=1; msg="$CMD 0645-071 The following target files have failed lock checks:\n";; 150) msg="EFIX MANAGER PREVIEW START\n";; 151) msg="EFIX MANAGER PREVIEW END\n";; 152) C=1; msg="$CMD 0645-072 ATTENTION: missing install data for file $2. File will be skipped.\n";; 153) C=1; msg="$CMD 0645-073 Error reading efix database.\n";; 154) C=1; msg="$CMD 0645-074 Error reading efix file database.\n";; 155) C=1; msg="$CMD 0645-075 ATTENTION: efix data states that the number of files should be $2,\nbut the number of files emgr was able to locate is $3.\n";; 156) C=1; msg="$CMD 0645-110 Error executing packaging script.\n";; 157) msg="pre-install";; 158) msg="post-install";; 159) msg="pre-remove";; 160) msg="post-remove";; 161) C=1; msg="$CMD 0645-076 The $2 script has returned an error.\n";; 162) msg="Executing $2 script ...\n";; 163) msg="Efix File Installation\n";; 164) msg="Pre-Install Script\n";; 165) msg="Post-Install Script\n";; 166) msg="Pre-Remove Script\n";; 167) msg="Post-Remove Script\n";; 168) msg="Return code from $2 script is: $3\n";; 169) msg="Install Failure Cleanup\n";; 170) msg="Initializing failed efix install cleanup ...\n";; 171) C=1; msg="$CMD 0645-077 ATTENTION: cleanup did not succeed.\n";; 172) msg="Successfully cleaned up failed install.\n";; 173) msg="INSTALLING\n";; 174) msg="REMOVING\n" ;; 175) msg="BROKEN\n" ;; 176) msg="STABLE\n" ;; 177) msg="NONE\n" ;; 178) C=1; msg="$CMD 0645-078 ATTENTION: efix \"$2\" has the state of \"$3\".\n";; 179) C=1; msg="$CMD 0645-079 Error changing efix state.\n";; 180) msg="Setting efix state to: $2\n";; 181) msg="Efix State\n";; 182) msg="There is no efix data on this system.\n";; 183) msg="Initializing log $2 ...\n";; 184) msg="STATE codes:\n S = STABLE\n M = MOUNTED\n U = UNMOUNTED\n Q = REBOOT REQUIRED\n B = BROKEN\n I = INSTALLING\n R = REMOVING\n";; 185) C=1; msg="$CMD 0645-080 Efix did not pass all remove preview checks.\n";; 186) C=1; msg="$CMD 0645-081 Unable to locate efix with id number $2.\n";; 187) C=1; msg="$CMD 0645-082 Unale to locate efix with VUID \"$2\".\n";; 188) C=1; msg="$CMD 0645-083 Label name \"$2\" is reserved or invalid.\n";; 189) C=1; msg="$CMD 0645-084 Error writing to efix prerequisite database.\n";; 190) C=1; msg="$CMD 0645-085 Error checking efix status.\n";; 191) C=1; msg="$CMD 0645-086 Error checking efix with label \"$2\"\n";; 192) msg="Checking file number $2: $3 ...\n";; 193) msg="Efix passed all level $2 checks.\n";; 194) msg="EFIX ID: $2\nEFIX LABEL: $3\n";; 195) C=1; msg="$CMD 0645-087 Access attributes mismatch for file $2\n";; 196) msg="Expected access attributes:\n";; 197) msg="Actual access attributes:\n";; 198) msg="Checking access attributes for $2 ...\n";; 199) C=1; msg="$CMD 0645-088 ATTENTION: file $2 will not be removed.\n*** This new file was installed by emgr. During the install, emgr could ***\n*** not determine or lock the owning package. If you have not installed ***\n*** the permanent version of this file, you can safely remove it. ***\n" ;; 200) C=1; msg="$CMD 0645-089 Efix \"$2\" no longer meets the following prerequisites:\n";; 201) msg=" Level at Install: $2\n";; 202) msg="Check level is $2.\n";; 203) C=1; msg="$CMD 0645-090 Invalid level for verbose flag. Valid levels are $2.\n";; 204) C=1; msg="$CMD 0645-091 Error processing ODM database.\n";; 205) C=1; msg="$CMD 0645-092 No ODM data available for fileset $2.\n";; 206) C=1; msg="$CMD 0645-093 Error changing emgr bit in ODM.\n";; 207) msg="$2: installp fileset $3 is already locked by emgr.\n";; 208) msg="$2: locking installp fileset $3.\n";; 209) C=1; msg="$CMD 0645-094 Error locking package $2.\n";; 210) C=1; msg="$CMD 0645-095 Error unlocking package $2.\n";; 211) msg="$2: unlocking installp fileset $3.\n";; 212) msg="$2: installp fileset $3 is already unlocked.\n";; 213) msg="$2: no lockable package for this file.\n";; 214) C=1; msg="$CMD 0645-096 Error processing package locks.\n";; 215) C=1; msg="$CMD 0645-097 Error processing inventory data for file number $2.\n";; 216) msg="Processing package locking for all files.\n";; 217) msg="All package locks processed successfully.\n";; 218) msg="Package Locking\n";; 219) msg="Initializing emgr manual maintenance tools.\n";; 220) C=1; msg="$CMD 0645-098 ATTENTION: File number $2 will be replaced by an efix file that\nhas been designated as \"new\" by the package. The replaced file has been saved\nin $3.\n* Original File: $4\n* Saved File: $5\n";; 221) msg="Processing package unlocking for all files.\n";; 222) msg="$2: installp fileset $3 is locked by another label.\n";; 223) C=1; msg="$CMD 0645-099 Error writing to pkglock database.\n";; 224) msg="Operation Summary\n";; 225) C=1; msg="$CMD 0645-100 Error listing package locks.\n";; 226) msg="No locks for the specified packages.\n";; 227) msg="Reboot Processing\n";; 228) msg="Reboot is not required by this efix package.\n";; 229) msg="\n*** NOTICE ***\nThis efix package requires the target system to be rebooted after the current\noperation is complete. It is recommended that you reboot the target system as\nsoon as possible after installation to avoid disruption of current functionality.\n";; 230) msg="\n*** NOTICE ***\nemgr has detected that this operation is executing in an alternate root\nenvironment (such as NIM SPOT or alt_disk_install). The efix package being\ninstalled has specified that a reboot is required. Be sure that the boot\nimage is rebuilt before booting from the target alternate root environment.\n";; 231) C=1; msg="$CMD 0645-101 Error during reboot processing.\n";; 232) msg="Rebuilding boot image ...\n";; 233) C=1; msg="$CMD 0645-102 Error rebuilding boot image.\n";; 234) msg="Successfully rebuilt boot image.\n";; 235) msg="ATTENTION: boot image rebuilding aborted by user.\n";; 236) C=1; msg="$CMD 0645-103 Error installing archive member.\n";; 237) msg="Enter the file name of the target archive member for efix file number $2.\nThis should be the name of the archive member that will be installed or\nreplaced in the target archive $3.\n";; 238) C=1; msg="$CMD 0645-104 Error initializing efix database.\n";; 239) C=1; msg="$CMD 0645-105 Error getting archive member size.\n";; 240) C=1; msg="$CMD 0645-106 Error extracting archive member.\n";; 241) msg="Archiving member $2 ...\n";; 242) C=1; msg="$CMD 0645-107 Error getting archive member checksum.\n";; 243) msg="Force removing efix with label \"$2\"...\n";; 244) msg="Efix Force Removal\n";; 245) C=1; msg="$CMD 0645-148 ATTENTION: efix label \"$2\" is selected for force removal.\nThe recommended method for removing an installed efix is to use the standard\nremoval process (-r flag). The force remove option will not delete any of the\nefix files, saved data, or execute remove scripts. This option should only\nbe used if the standard remove process cannot be accomplished.\n";; 246) C=1; msg="$CMD 0645-111 This operation requires that you confirm it with the FORCE\nflag (-F flag).\n";; 247) C=1; msg="$CMD 0645-112 Error initializing log $2\n";; 248) msg="Efix package file is: $2\n";; 249) msg="Processing Efix Package $2 of $3.\n";; 250) msg="Processing Efix Selection $2 of $3.\n";; 251) C=1; msg="$CMD 0645-113 No valid entries to process in bundle file $2.\n";; 252) C=1; msg="$CMD 0645-114 Error processing label variable.\n";; 253) msg="Initializing check operation ...\n";; 254) msg="INSTALL";; 255) msg="REMOVE";; 256) msg="CHECK";; 257) msg="FORCE REMOVE";; 258) msg="FAILURE CLEANUP";; 259) msg="FAILURE";; 260) msg="SUCCESS";; 261) msg="Unknown";; 262) msg="EFIX NUMBER";; 263) msg="EPKG NUMBER";; 264) msg="INSTALL PREVIEW";; 265) msg="REMOVE PREVIEW";; 266) msg="Cumulative Space Requirements\n";; 267) C=1; msg="$CMD 0645-115 Error processing cumulative space requirements.\n";; 268) msg="Processing space requirements for all successful operations ...\n";; 269) C=1; msg="$CMD 0645-116 ATTENTION: label \"$2\" has already been processed.\n";; 270) C=1; msg="$CMD 0645-117 Target file $2 will be locked by efix label \"$3\".\n";; 271) msg="Efix label \"$2\" was mount installed.\n";; 272) msg="Unmounting efix file $2 ...\n";; 273) msg="Efix Mounts\n";; 274) C=1; msg="$CMD 0645-118 Error removing efix mounts.\n";; 275) msg="MOUNTED\n";; 276) msg="UNMOUNTED\n";; 277) C=1; msg="$CMD 0645-119 file $2 is not mounted.\n";; 278) C=1; msg="$CMD 0645-120 Error mounting efix files.\n";; 279) C=1; msg="$CMD 0645-121 Efix with label \"$2\" is not mount installed.\n";; 280) msg="EFIX MOUNT";; 281) msg="EFIX UNMOUNT";; 282) msg="Mounting efix label \"$2\".\n";; 283) msg="File $2: $3 is already mounted.\n";; 284) msg="File $2: $3 is NOT mounted. Mounting ...\n";; 285) msg="All files successfully mounted.\n";; 286) C=1; msg="$CMD 0645-122 Error unmounting efix files.\n";; 287) msg="All files successfully unmounted.\n";; 288) msg="Unmounting efix label \"$2\".\n";; 289) msg="File $2: $3 is already unmounted.\n";; 290) msg="File $2: $3 is mounted. Unmounting ...\n";; 291) C=1; msg="$CMD 0645-123 There are no mount installed efix files on this system.\n";; 292) C=1; msg="$CMD 0645-124 Efix package file name must end in the \"$2\" extension.\n";; 293) C=1; msg="$CMD 0645-125 Error processing emgr locks.\n";; 294) C=1; msg="$CMD 0645-126 emgr is currently locked by process $2. If you believe\nthis lock is in error, use the -K flag to force unlock.\n";; 295) C=1; msg="$CMD 0645-127 Error processing TCB state.\n";; 296) C=1; msg="$CMD 0645-128 Error processing TCB data.\n";; 297) C=1; msg="$CMD 0645-129 Efix file number $2 cannot be mount installed because it is\ndesignated as \"new\".\n";; 298) C=1; msg="$CMD 0645-130 Mount install is not supported on TCB enabled systems.\n";; 299) msg="ATTENTION: This file may still be tracked in the TCB database. If the file is\nreplaced with a non-TCB file, you should unregister it from TCB with the\nfollowing command: /usr/bin/tcbck -d $2.\n";; 300) C=1; msg="$CMD 0645-131 ATTENTION: efix file number $2 will not be removed because\nit was designated as new and has been replaced by a tracked file.\n";; 301) C=1; msg="$CMD 0645-132 Efix file number $2 has been designated as new by the package,\nbut it is tracked by one or more installers on this system.\n";; 302) return 0;; # held for emgr usage 303) return 0;; # held for epkg usage 304) msg="Log file is $2\n";; 305) msg="** For help, enter \"h!\" at any question prompt. **\n";; 306) msg="epkg subcommands ================ b! Return to the previous question (i.e. "back"). h! Display help information for the current question. q! Quit without saving the input for this session. s! Show the current input for this session. sq! Save existing input for this session and quit. sh! Shell escape.\n" ;; 307) msg="Briefly describe the efix package. The abstract is limited to 38 bytes.\n";; 308) msg="An efix package may or may not deliver efix files. If this efix package\ndelivers one or more efix files enter \"yes\". Otherwise, enter \"no\".\n";; 309) msg="Enter the absolute or relative path of the efix file that will be archived\nand shipped with this efix package. This is the file that contains the efix\ncode. Please note that the name of this file is immaterial to the efix install\ntools (emgr) and only the efix package target information will be used for\ninstallation purposes.\n";; 310) msg="Enter the absolute path of the file or archive (i.e. library) that is targeted\nby this efix file. This is the location that will be the install target when\nthis efix file is installed. If this file is tracked by an installer (e.g.\ninstallp, RPM, ISMP, etc), enter the exact tracked location.\n";; 311) msg="Select the corresponding type for this efix file. For example:\n/usr/bin/ls would be \"Standard file or executable\" and shr.o (as a member of a\nlibrary) would be \"Archive/Library Member\". Note: this description applies to\nthe ship file. If the ship file will be shr.o as an archive member of target\nfile /usr/ccs/lib/libc.a, you would select \"Archive/Library Member\".\"\n";; 312) msg="Example: If the ship file will be shr.o as an archive member of target file\n/usr/ccs/lib/libc.a, you would enter \"shr.o\".\n";; 313) msg="Select the installer (if any) that tracks the target file. If the target file\nis new (i.e. it does not exist on the target system), then be sure to\ndesignate it as \"NEW\". If it is not new, be sure to select its tracked status.\n";; 314) msg="For a full explanation of octal modes see the chmod man page and\ndocumentation. For a full explanation of file owner and group designations,\nsee the chown man page and documentation. Note: If the ship file is an archive\nmember, the permissions will apply to the member and not the archive or\nlibrary.\n" ;; 315) msg="This is the script that will be executed by emgr before any efix files are\ninstalled and before the post-install script. A failure in this script will\nabort the installation.\n" ;; 316) msg="This is the script that will be executed by emgr after all efix files are\ninstalled and after the pre-install script is executed. A failure in this\nscript will cause the installation to fail and clean up.\n" ;; 317) msg="This is the script that will be executed by emgr before any efix files are\nremoved and before the post-remove script. A failure in this script will fail\nthe remove operation.\n" ;; 318) msg="This is the script that will be executed by emgr after all efix files are\nremoved and after the pre-remove script is executed. A failure in this\nscript will fail the remove operation.\n" ;; 319) msg="If the proper integration of this efix requires a reboot, enter \"yes\". This\nwill cause emgr to rebuild the boot image and issue a reboot requirement\nstatement to the user.\n";; 320) msg="Enter the absolute or relative path of the prerequisite file. This is a file\nthat contains prerequisite information for AIX installp filesets. If the\ntarget system does not meet all specified prerequisites, emgr will block the\ninstallation. Please see epkg documentation for a full explanation of\nprerequisite files.\n";; 321) msg="Enter the absolute or relative path of the description file OR enter \".\" to\ncompose the description in an editor. You can specify which editor to use by\nsetting the EDITOR global environment variable. The default editor is vi.\nIf epkg finds an epkg.desc.tpl file in $HOME, it will use that file as\nthe template.\n";; 322) msg="Selecting \"yes\" will resume the previously saved epkg session. Selecting\n\"no\" will start a new epkg session from the beginning.\n";; 323) msg="Selecting \"yes\" will save and end this epkg session. Selecting \"no\" will resume\nthe current session.\n";; 324) msg="CANCELED";; 325) msg="Overwrite install option selected. Removing currently installed\nefix \"$2\".\n";; 326) msg="Overwrite Processing\n";; 327) msg="ATTENTION: overwrite option selected. Actual install will remove currently\ninstalled efix \"$2\" before installing the current efix package.\n";; 328) msg="Previously installed efix removed successfully.\nInstalling current efix package ...\n";; 329) C=1; msg="$CMD 0645-133 Previously installed efix could not be successfully removed.\nCanceling installation of current efix package.\n";; 330) msg="EMGR RCBOOT";; 331) msg="REBOOT REQUIRED";; 332) msg="Boot Image Processing\n";; 333) C=1; msg="$CMD 0645-134 ATTENTION: boot image processing has failed.\n";; 334) msg="ATTENTION: system reboot is required. Please see the \"Reboot Processing\"\nsections in the output above or in the $2 file.\n";; 335) C=1; msg="$CMD 0645-135 Mount install is not supported for efix packages with install or\nremove scripts.\n";; 336) C=1; msg="$CMD 0645-136 Mount install is not supported for efix packages without files.\n";; 337) C=1; msg="$CMD 0645-137 Mount install is not supported for efix packages that require\nrebooting.\n";; 338) msg="Save directory is: $2\n";; 339) msg="File $2: Saving $3 as $4 ...\n";; 340) msg="File Archiving\n";; 341) C=1; msg="$CMD 0645-144 ATTENTION: function $2 aborted or altered by user.\n";; 342) C=1; msg="$CMD 0645-138 ATTENTION: the level of emgr being executed is lower than the\nlevel of the epkg command used to create this efix package.\n";; 343) C=1; msg="$CMD 0645-139 ATTENTION: the level of emgr being executed is higher than the\nlevel of the epkg command used to create this efix package.\n";; 344) C=1; msg="$CMD 0645-140 ATTENTION: emgr has issued $2 attention notice(s).\nSuch notices may not indicate an immediate failure, but may require\nfurther attention. Please see the output above or the log for more details.\n";; 345) C=1; msg="$CMD 0645-141 ATTENTION: An error occurred processing installp ODM inventory\ndata. Object data in error is: $2.\n" ;; 346) C=1; msg="$CMD 0645-142 ATTENTION: An error occurred processing hard links for target\nfile $2.\n" ;; 347) C=1; msg="$CMD 0645-143 ATTENTION: An error occurred resetting hard links for target\nfile $2.\n" ;; 348) msg="Resetting hard link from $2 to $3\n";; 349) C=1; msg="$CMD 0645-145 ATTENTION: The target file $2 appears to be\na kernel module. emgr was not able to locate a link to this module from $3\nor from $4. This kernel module may not be integrated into the\nboot image.\n";; 350) C=1; msg="$CMD 0645-146 Unable to locate SHIP_FILE attribute for file number $2.\n" ;; 351) C=1; msg="$CMD 0645-147 The EFIX_FILES attribute specified a total of $2 ship file(s),\nbut epkg was able to locate ship file data for a total of only $3 file(s).\n";; 352) msg="Not Installed" ;; # NOTE: 0645-148 used by 245 353) msg="Select reboot policy for this efix package:\n" ;; 354) msg="Reboot is NOT required.\n" ;; 355) msg="Reboot is required. The boot image will be rebuilt.\n" ;; 356) msg="Reboot is required. The boot image will NOT be rebuilt.\n" ;; 357) C=1; msg="$CMD 0645-149 The BUILD_BOOT_IMAGE attribute cannot be set to \"yes\" if the\nREBOOT attribute is set to \"no\".\n" ;; 358) C=1; msg="$CMD 0645-150 ATTENTION: The target file $2 appears to be\na kernel module, but the BUILD_BOOT_IMAGE attribute is set to \"no\". This kernel module may not be integrated into the boot image.\n";; 359) msg="Enter the location for the additional package locks file or \".\" to skip.\n";; 360) C=1; msg="$CMD 0645-151 Error verifying additional package locks file.\n";; 361) msg="Verifying additional package locks file ...\n" ;; 362) C=1; msg="$CMD 0645-152 This configuration file is currently limited to $2 entries.\n";; 363) C=1; msg="$CMD 0645-153 Package locking for $2 packages is not currently supported.\n";; 364) C=1; msg="$CMD 0645-154 Error processing additional package locks.\n" ;; 365) msg="Processing additional package locks ...\n";; 366) C=1; msg="$CMD 0645-155 Package $2 is not installed.\n" ;; 367) msg="File $2";; 368) msg="Explicit Lock";; 369) msg="Enter the location for the efix supersede file or "." to skip.\n";; 370) C=1; msg="$CMD 0645-156 Error verifying supersede file.\n" ;; 371) C=1; msg="Verifying efix supersede file ...\n" ;; 372) msg="Removing superseded efix package \"$2\" ...\n";; 373) msg="ATTENTION: the currently selected efix package supersedes efix \"$2\".\nemgr will remove efix package \"$3\" before performing installation of\nthe current efix package.\n" ;; 374) C=1; msg="$CMD 0645-157 Error processing supersedes.\n" ;; 375) C=1; msg="Supersede Processing\n" ;; 376) msg="No superseded efix labels are installed.\n" ;; 377) msg="All superseded efixes removed successfully.\nInstalling current efix package ...\n";; 378) C=1; msg="$CMD 0645-158 Efix name entry matches current label.\n";; 379) msg="OVERWRITE REMOVE";; 380) msg="SUPERSEDE REMOVE";; 381) C=1; msg="$CMD 0645-159 ATTENTION: $2 is not a text file.\n";; 382) C=1; msg="$CMD 0645-160 Error verifying efix to efix prerequisite file.\n" ;; 383) C=1; msg="Verifying efix to efix prerequisite file ...\n" ;; 384) C=1; msg="$CMD 0645-161 Error processing efix to efix prerequisites.\n" ;; 385) C=1; msg="$CMD 0645-162 This \"$2\" entry was previously designated as \"$3\".\n" ;; 386) C=1; msg="$CMD 0645-163 The efix entry \"$2\" is listed in both the supersede file\nand as a PREREQ in the efix to efix prerequisite file.\n";; 387) msg="Entering shell! Exit to resume $2 session.\n";; 388) msg="Enter the location for the efix to efix prerequisite file or "." to skip.\n";; 389) C=1; msg="$CMD 0645-164 The efix PREREQ \"$2\" is required to be installed.\n";; 390) C=1; msg="$CMD 0645-165 The efix XREQ \"$2\" is required to NOT be installed.\n";; 391) msg="Efix to Efix Requisite Number: $2\n Efix Label: $3\n Type: $4\n Install Status: $5\n Requisite Met: $6\n";; 392) msg="Installed\n";; 393) msg="Efix to Efix Prerequisite Verification\n";; 394) msg="All efix to efix prerequisites successfully processed.\n";; 395) msg="Superseded\n";; 396) C=1; msg="$CMD 0645-166 The following previously installed efixes list this efix\npackage as an XREQ:\n";; 397) C=1; msg="$CMD 0645-167 The following previously installed efixes list efix \"$2\"\nas a PREREQ:\n";; 398) C=1; msg="$CMD 0645-168 Error displaying efix package.\n";; 399) msg="DISPLAY";; 400) C=1; msg="$CMD 0645-069 List file size cannot exceed $2 512 byte-blocks.\n";; 401) C=1; msg="Install Scripts:\n";; 402) C=1; msg="$CMD 0645-170 Error displaying configuration file.\n";; 403) C=1; msg="$CMD 0645-171 ATTENTION: Unable to display configuration file \"$2\"\nbecause it is not a text file.\n";; 404) msg="Displaying Configuration File \"$2\"\n";; 405) C=1; msg="$CMD 0645-172 ATTENTION: Error generating MD5 checksum.\n";; 406) msg="MD5 generating command is $2\n";; 407) msg="MD5 checksum is $2\n";; 408) msg="ATTENTION: system reboot will be required by the actual (not preview) operation.\nPlease see the \"Reboot Processing\" sections in the output above or in the\n$2 file.\n";; 409) C=1; msg="$CMD 0645-173 ATTENTION: label \"$2\" has been marked as \"$3\" by a\npreviously processed label during this preview operation.\n";; 410) msg="To be Installed\n" ;; 411) msg="To be Removed\n" ;; 412) msg="Processing efix label \"$2\" ...\n" ;; 414) C=1; msg="$CMD 0645-174 Error processing description file.\n";; # Version 5 messages 415) msg="STATE codes:\n S = STABLE\n M = MOUNTED\n U = UNMOUNTED\n Q = REBOOT REQUIRED\n B = BROKEN\n I = INSTALLING\n R = REMOVING\n T = TESTED\n";; 416) msg="Reboot is NOT required. The boot image will be rebuilt.\n" ;; 417) msg="ATTENTION: changing package label to user specified label \"$2\".\n";; 418) C=1; msg="$CMD 0645-175 ATTENTION: reboot and boot image processing skipped in\nalternate install location.\n";; 419) C=1; msg="$CMD 0645-176 ATTENTION: installp prerequisite processing skipped in\nalternate install location.\n";; 420) msg="ALTERNATE INSTALL PATH: $2\n";; 421) msg="Enter the absolute or relative path of the prerequisite file. This is a file\nthat contains prerequisite information for installp filesets. If the\ntarget system does not meet all specified prerequisites, emgr will block the\ninstallation. Please see epkg documentation for a full explanation of\nprerequisite files.\n";; # Version 6 messages (Concurrent Update Enablement) 422) msg="PATCHED";; 423) msg="STABLE + PATCHED";; 424) msg="BOOT IMAGE MODIFIED + PATCHED";; 425) msg="STATE codes:\n S = STABLE\n M = MOUNTED\n U = UNMOUNTED\n Q = REBOOT REQUIRED\n B = BROKEN\n I = INSTALLING\n R = REMOVING\n T = TESTED\n P = PATCHED\n N = NOT PATCHED\n SP = STABLE + PATCHED\n SN = STABLE + NOT PATCHED\n QP = BOOT IMAGE MODIFIED + PATCHED\n QN = BOOT IMAGE MODIFIED + NOT PATCHED\n RQ = REMOVING + REBOOT REQUIRED\n";; 426) C=1; msg="$CMD 0645-177 Error patching a concurrent update to memory.\n" ;; 427) msg="Concurrent Update" ;; 428) msg="NOT PATCHED" ;; 429) msg="STABLE + NOT PATCHED" ;; 430) msg="BOOT IMAGE MODIFIED + NOT PATCHED" ;; 431) C=1; msg="$CMD 0645-178 Error committing a concurrent update to disk.\n" ;; 432) C=1; msg="$CMD 0645-179 Error creating concurrent update description file\n" ;; 433) C=1; msg="$CMD 0645-180 Error verifying concurrent update with the kernel\n" ;; 434) msg="COMMIT" ;; 435) msg="REMOVING + REBOOT REQUIRED" ;; 436) msg="ATTENTION: This interim fix has patched and commited a fix onto a kernel\nextension. A system reboot is needed to completely remove this interim fix.\n" ;; 437) C=1; msg="$CMD 0645-181 Error listing active concurrent update data on this system\n" ;; 438) C=1; msg="$CMD 0645-182 ATTENTION: This fix is not enabled for concurrent update, and cannot be applied with -i\n" ;; # Version 7 messages (installp/ifix messages) 439) msg="Enter the location for the APAR reference file.\n";; 440) msg="Enter the absolute or relative path of the APAR reference file. This is a file\nthat lists the APAR(s) in this interim fix package.\nPlease see epkg documentation for a full explanation of\nAPAR reference files.\n";; 441) msg="No APAR references specified.\n";; 442) msg="Processing APAR reference file\n" ;; 443) C=1; msg="$CMD 0645-183 Error processing APAR reference file.\n";; 444) C=1; msg="$CMD 0645-184 emgr is currently locked by process $2.\n";; 445) C=1; msg="$CMD 0645-185 Lock file contains the inactive process id $2. Verify that\nthis process is not running and remove the lock file $3\n";; # Version 7 messages (Concurrent Update stacking enablement) 449) msg="Concurrent Update Efix Validation\n";; 450) C=1; msg="$CMD 0645-193 \"$2\" does not contain the same files as \"$3\".\n";; 451) msg="Efix label \"$2\" is a follow-on patch to efix label \"$3\".\n";; 452) C=1; msg="$CMD 0645-194 Can not commit an efix that has a follow-on.\n" ;; 453) msg="Efix is a follow-on. Linking save directory $2\nto $3.\n";; 454) msg="Efix has passed target validation.\n";; 455) msg="Removing Efix as a result of Commit\n";; 456) msg="Removing efix label \"$2\" ...\n" ;; 457) C=1; msg="$CMD 0645-195 Efix has failed target validation.\n" ;; 458) msg="Concurrent update efix contains multiple files.\n";; 459) C=1; msg="$CMD 0645-196 Can not remove an efix that has a follow-on.\n" ;; 460) msg="Patch Removal from Memory\n";; 461) msg="Successfully removed patch id $2.\n";; 462) C=1; msg="$CMD $2 Error creating file.\n" ;; 463) C=1; msg="$CMD 0645-197 Can not install follow-on to patch in state \"$2\".\n" ;; 464) msg="Patch Removal from Memory finished.\n";; 465) msg="\"$2\" has not been committed to disk. Skipping checksum validation.\n";; # Additional messages 466) msg="ATTENTION: Interim fix is enabled for automatic removal by installp.\n";; 467) msg="APAR reference set to NONE. Interim fix is not enabled for automatic removal.\n";; 468) C=1; msg="$CMD 0645-198 The $2 flag is not valid on a Thin Server.\n" ;; 469) C=1; msg="$CMD Warning. The $2 flag is not valid on a Thin Server and has been ignored.\n" ;; 470) C=1; msg="$CMD The \"$2\" operation is not valid on a Thin Server. The $3 flag\nhas been passed by default.\n" ;; 471) msg="File is in \"$2\". Skipping checksum validation.\n";; 472) msg="Running customization scripts is disabled in alternate BOS environments.\nExport FORCE_SCRIPTS=yes to bypass this check. Use with caution.\n";; 473) msg="Efix is a follow-on. Copying save directory $2\nto $3.\n";; 474) C=1; msg="$CMD 0645-199 A live update operation has been initiated by a geninstall command.\nAll other install operations are locked until it is complete.\nPlease see /var/adm/ras/liveupdate/logs/lvupdlog for details.\n";; 475) msg="Is this efix suitable for a live update operation ? (yes/no):\n";; 476) msg="Generally, only efixes containing the kernel and kernel extensions are safe\nfor live update operations. If unsure, please answer \"no\". See\ngeninstall and live update documentation for more information.\n";; 477) msg="Please Note:\nAll efixes should be marked Live Update capable. This is needed for installing\nefixes as a group. If there is a reason an efix is not suitable for a live\nupdate operation, then answer \"no\" but most efixes should be marked \"yes\".\n";; 478) msg="LABEL";; 479) msg="OPERATION";; 480) msg="RESULT";; # tar and signature/cert verification 481) msg="Verying signature of ifix\n";; 482) msg="ifix: $2\n";; 483) msg="ifix $2 does not exist\n";; 484) msg="Please download $2 and try to install again\n";; 485) msg="Signature file is $2\n";; 486) msg="ERROR: Signature file $2 does not exist.\nPlease download ifix and try again\n";; 487) msg="Signature verification passed for $2 ...\nInstalling ifix $2 ...\n";; 488) msg="ERROR: Installation failed, Please check the emgr display.\n";; 489) msg="ERROR: Signature verification failed on $2\n$2 not installed ...\n";; 490) msg="Certificate file is $2\n";; 491) msg="ERROR: Certificate file $2 does not exist.\nPlease ensure that $2 is installed\n";; 492) msg="Downloaded Tar file name is: $2\n";; 493) msg="TAR file $2 does not exist.\nPlease download $2 and try to install again\n";; 494) msg="Extracting Contents of $2\n";; 495) msg="Directory name: $2\n";; 496) msg="No files";; 497) msg="Checking System Level Prerequisites\n";; 498) msg="calling emgr -p -e $2\n";; 499) msg="Found the ifix $2 for the current system level, checking signature ...\n";; 500) msg="Skipping ifix\nSee /var/adm/ras/emgr.log for more details\n";; 501) msg="Usage: $2 TAR_FILE\n";; 502) msg="Usage: $2 IFIX_FILE_NAME.Z\n";; 503) msg="Verifying contents of $2\n";; 504) msg="ERROR: verifification of tar content failed\n";; 505) msg="ERROR: $2 is not found in the tar file\n";; 506) msg="ERROR: $2.sig is not found in the tar file\n";; 507) msg="ERROR: failled to extract $2.sig, check the file system space\n";; 508) msg="ERROR: failed to extract $2, check the file system space\n";; 509) msg="Verifying integrity of Advisory.asc\n";; 510) msg="ERROR: $2 integrity verification failed\n";; 511) msg="$2 integrity verification passed\n";; 512) msg="ERROR: $2 hash doesn't match that in $3\n";; 513) msg="$2 is already installed\n";; 514) msg="Verifying the interity of $2\n";; 515) msg="ERROR: $2 hash doesn't match that in $3\n";; 516) msg="ERROR: gunzip $2 failed, check the file system space\n";; 517) msg="$2 installed, extract the udpate ...\n";; 518) msg="Install $2 updates ...\n";; 519) msg="ERROR: $2 failed, check the update log $3\n";; *) $ERROR;; esac ############################################################ ## See if we need to print out a message in the local ## locale.. i.e. other than English. Right now, we only ## support AIX's install message catalog. ############################################################ if [[ $LOCPRINT -eq 1 ]]; then # Make adjustments for catalog order if [[ $MSG_OPTION -le 337 ]]; then (( MSG_OPTION = $MSG_OPTION + 305 )) elif [[ $MSG_OPTION -le 414 ]]; then (( MSG_OPTION = $MSG_OPTION + 309 )) elif [[ $MSG_OPTION -le 420 ]]; then (( MSG_OPTION = $MSG_OPTION + 336 )) elif [[ $MSG_OPTION -le 470 ]]; then (( MSG_OPTION = $MSG_OPTION + 359 )) elif [[ $MSG_OPTION -le 471 ]]; then (( MSG_OPTION = $MSG_OPTION + 393 )) elif [[ $MSG_OPTION -eq 477 ]]; then (( MSG_OPTION = $MSG_OPTION + 419 )) elif [[ $MSG_OPTION -le 480 ]]; then (( MSG_OPTION = $MSG_OPTION + 434 )) elif [[ $MSG_OPTION -le 502 ]]; then (( MSG_OPTION = $MSG_OPTION + 440 )) elif [[ $MSG_OPTION -le 519 ]]; then (( MSG_OPTION = $MSG_OPTION + 445 )) else (( MSG_OPTION = $MSG_OPTION + 416 )) fi [[ $C -ne 1 ]] && CMD="" tmsg=$($INUUMSG $MSG_OPTION $CMD "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" 2>&1) if [[ $? -eq 0 ]]; then # If inuumsg succeeded, issue the translated message; else # issue the untranslated message. msg="${tmsg}\n" fi fi # end of LOCPRINT=1 if [[ $EMGRLOG -eq 1 ]]; then echo "$msg\c" 2>&1 >> $LOG [[ $QUIET -eq 1 && $ISERROR -eq 0 ]] && return 0 fi echo "$msg\c" 2>&1 } # end of print_msg() ######################################################################## ## Function: setcmd ######################################################################## setcmd() { typeset ERROR='eval perror 57 "$CMD"; return 1' typeset IERROR='eval pmerror "setcmd()"; return 1' typeset PATHS # All known common paths typeset -u UCMD # Posix commands in uppercase (for variable assignments) typeset P # PATH index typeset CMD="$1" # command [[ -z $CMD ]] && $IERROR ############################################################ ## Setup known PATHS ############################################################ PATHS="$EMGRBIN /usr/bin /usr/sbin /bin /sbin /usr/local/bin /usr/local/sbin" ############################################################ ## Loop through $PATHS to find the correct location for this ## system. If we do not find the given command in any of the ## paths, then report an error and return. ############################################################ for P in $PATHS; do if [[ -x $P/$CMD ]]; then UCMD=$(echo $CMD | /usr/bin/tr -A '[:lower:]' '[:upper:]') eval export $UCMD=$P/$CMD return 0 fi done # If we got here, then we did not find the command $ERROR } # end of setcmd() ######################################################################## ## Function: get_byte_fsize ######################################################################## get_byte_fsize() { typeset FILE="$1" typeset FSIZE=0 typeset ERROR='eval perror 23 "$FILE"; return 1' if [[ -z "$FILE" ]]; then perror 23 "" return 1 fi check_file $FILE || $ERROR FSIZE=$($LS -l $FILE) || $ERROR FSIZE=$(echo "$FSIZE" | $AWK '{print $5}') || $ERROR isnum $FSIZE || $ERROR echo "$FSIZE" return 0 } # end of get_byte_fsize() ######################################################################## ## Function: tcb_get_type ## Parameters: ######################################################################## tcb_get_attr() { typeset ERROR='eval pmerror "tcb_get_type()"; perror 296; return 1' typeset SF=/etc/security/sysck.cfg typeset TARGET=$1 typeset ATTR=$2 typeset BUF="" [[ $TCBSTATE -eq 0 ]] && return 0 [[ -z $TARGET || -z $ATTR ]] && $ERROR BUF=$( $AWK -v file="$TARGET" -v attr=$ATTR '{ if ( $1 !~ "^"file":$" ) next; getline; while ( $0 ~ "=" && $0 !~ ":$") { if ( $1 == attr ) {sub("^.*[ ]=[ ]",""); print $0; exit(0)} getline; } exit(0); }' $SF) || $ERROR echo "$BUF" return 0 } # end of tcb_get_attr() ######################################################################## ## Function: tcb_set_state ######################################################################## tcb_set_state() { typeset ERROR='eval perror 295; return 1' typeset BUF="" [[ "$PLATFORM" != "AIX" || -n $EMGR_IGNORE_TCB ]] && return 0 # Check PdAt ODM to see if TCB is enabled. BUF=$(ODMDIR=/usr/lib/objrepos $ODMGET -q attribute=TCB_STATE PdAt) [[ $? -ne 0 || -z $BUF ]] && $ERROR BUF=$(echo "$BUF" | $AWK '{ if ($1 != "deflt") next; gsub("\"","",$3); # remove quotes if ($3 == "tcb_enabled" || $3 == "CC_EVAL" || $3 == "IBM_C2" ) print "1" ; else { if ($3 == "tcb_disabled") print "0"; else print "2"; exit(0) }} ') || $ERROR isnum $BUF || $ERROR if [[ $BUF -eq 1 ]]; then export TCBSTATE=1 setcmd tcbck || $ERROR elif [[ $BUF -eq 0 ]]; then export TCBSTATE=0 else $ERROR fi return 0 } # end of tcb_set_state() ######################################################################## ## Function: tcb_get_sz ## Parameters: ######################################################################## tcb_get_sz() { typeset ERROR='eval pmerror "tcb_get_sz()"; perror 296; return 1' typeset SF=/etc/security/sysck.cfg typeset FILE=$1 typeset TARGET=$2 typeset BUF="" [[ $TCBSTATE -eq 0 ]] && return 0 [[ -z $FILE || -z $TARGET ]] && $ERROR check_file_full $SF || $ERROR BUF=$( $AWK -v file="$FILE" '{ if ( $1 !~ "^"file":$" ) next; print $0; getline; while ( $0 ~ "=" && $0 !~ ":$") { print $0; getline; } exit(0); }' $SF) || $ERROR if [[ -n $BUF ]]; then BUF="$BUF\n" echo "$BUF" > $TARGET || $ERROR else > $TARGET || $ERROR fi return 0 } # end of tcb_get_sz() ######################################################################## ## Function: tcb_restore ## Parameter: ######################################################################## tcb_restore() { typeset ERROR='eval pmerror "tcb_restore()"; perror 296; return 1' typeset TARGET=$1 typeset INPUT=$2 [[ $TCBSTATE -eq 0 ]] && return 0 [[ -z $INPUT || -z $TARGET ]] && $ERROR check_file $INPUT || $ERROR if [[ ! -s $INPUT ]]; then NOWARN=1 EMGRLOG=0 tcb_delete $TARGET > /dev/null 2>&1 else $TCBCK -a -f $INPUT || $ERROR LC_MESSAGES=C $EGREP TCB $INPUT > /dev/null 2>&1 if [ "$?" -eq 0 ] then $CHTCB on $TARGET fi fi return 0 } # end of tcb_restore() ######################################################################## ## Function: tcb_delete ## Parameter: ######################################################################## tcb_delete() { typeset ERROR='eval pmerror "tcb_delete()"; perror 296; return 1' typeset TARGET=$1 [[ $TCBSTATE -eq 0 ]] && return 0 [[ -z $TARGET ]] && $ERROR $TCBCK -d $TARGET || $ERROR return 0 } # end of tcb_delete() ######################################################################## ## Function: tcb_update ## Parameter: ######################################################################## tcb_update() { typeset ERROR='eval pmerror "tcb_update()"; perror 296; return 1' typeset TARGET=$1 typeset CHTCB_SET=$2 typeset TYPE="" typeset CLASS="" typeset MODE="" [[ $TCBSTATE -eq 0 ]] && return 0 [[ -z $TARGET ]] && $ERROR # Get the current class before we delete the entry CLASS=$(tcb_get_attr $TARGET class) || $ERROR # Get the current mode before we delete the entry MODE=$(tcb_get_attr $TARGET mode) || $ERROR [[ -z $MODE ]] && return 0 # Delete the entry just in case NOWARN=1 EMGRLOG=0 tcb_delete "$TARGET" > /dev/null 2>&1 # Create the TCB entry $TCBCK -l $TARGET || $ERROR # If the entry is a file, add size and checksum TYPE=$(tcb_get_attr $TARGET type) || $ERROR if [[ "$TYPE" = "FILE" ]]; then # Add the size and checksum .. $TCBCK -a $TARGET size checksum || $ERROR fi # If class is not specified (i.e. this is a new file), then we are done. [[ -z $CLASS ]] && return 0 # Add in class $TCBCK -a $TARGET class="$CLASS" || $ERROR # Set TCB bit if [[ "$CHTCB_SET" = "on" ]]; then $CHTCB on $TARGET fi # Add in mode if [[ -z $(tcb_get_attr $TARGET mode) ]]; then $TCBCK -a $TARGET mode="$MODE" || $ERROR fi return 0 } # end of tcb_update() ######################################################################## ## Function: is_tfile_installed # Is tracked file installed. ## Parameters: ## Output: 1 = installed, 0 = not installed ## Returns: 0 = OK, not 0 = ERROR ######################################################################## is_tfile_installed() { typeset ERROR='eval perror "is_tfile_installed()"; return 1' typeset INSTALLED='eval echo 1; return 0' typeset NOT_INSTALLED='eval echo 0; return 0' typeset TARGET=$1 [[ -z $TARGET ]] && $ERROR ########################################################### ## First, see of the file is tracked by installp ########################################################### if [[ "$PLATFORM" = "AIX" ]]; then NOWARN=1 EMGRLOG=0 which_lpp $TARGET > /dev/null 2>&1 [[ $? -eq 0 ]] && $INSTALLED fi ########################################################### ## Second, check if the file is tracked by rpm ########################################################### NOWARN=1 EMGRLOG=0 which_rpm $TARGET > /dev/null 2>&1 [[ $? -eq 0 ]] && $INSTALLED # If we got here, then it is unknown to any of our installers. $NOT_INSTALLED # Should never get here.. $ERROR } # end of is_tfile_installed() ######################################################################## ## Function: which_rpm() ## Parameter: rpm file ## Output: owning rpm package ## Returns: 0 = OK, not 0 = ERROR ######################################################################## which_rpm() { typeset ERROR='eval pmerror "which_rpm()"; return 1' typeset BUF="" typeset FILE=$1 [[ -z $FILE ]] && $ERROR setcmd rpm || $ERROR ########################################################### ## Execute rpm command to determine the owning package. ## Strip of the release value, etc. ########################################################### BUF=$($RPM -qf --queryformat '%{NAME}\n' $FILE) [[ $? -ne 0 || -z $BUF ]] && $ERROR echo "$BUF" return 0 } # end of which_rpm() ######################################################################## ## Function: check_dup_targets (Check duplicate targets) ## Parameters: ######################################################################## check_dup_targets() { typeset ERROR='eval pmerror "check_dup_targets()"; return 1' typeset TARGET="$1" typeset TFILE="$1" typeset ARMEM="$2" typeset CK_AR_CONF="$3" # check ar conflict typeset CKNUM="$4" # the number of the efix we are checking typeset DUP='eval perror 72 $TARGET; return 1' typeset OK='eval return 0' typeset EFCOUNT=1 typeset PREV_TARGET="" typeset PREV_ARMEM="" typeset PREV_TFILE="" typeset RC=0 [[ -z $TARGET ]] && $ERROR [[ -z $ARMEM ]] && ARMEM=$NONE [[ "$ARMEM" != "$NONE" ]] && TARGET="$TARGET[$ARMEM]" isnum $CKNUM || CKNUM=0 if [[ -z $CK_AR_CONF ]]; then CK_AR_CONF=0 else isYorN $CK_AR_CONF CK_AR_CONF=$? fi # If this is the first and only file, then we do not need to # perform a check [[ $GENUM -eq 1 ]] && $OK # Loop through all of the targets looking for a duplicate match. # If we find one, then there is a problem. while [[ $EFCOUNT -lt $GENUM ]]; do # loop safety [[ $EFCOUNT -gt $MAXEFILES ]] && $ERROR # never compare an efix file against itself ! if [[ $EFCOUNT -eq $CKNUM ]]; then inc EFCOUNT continue fi # Set previous target variables PREV_TARGET=${A_ETARGET[$EFCOUNT]} PREV_ARMEM=${A_AR_MEM[$EFCOUNT]} PREV_TFILE=$PREV_TARGET [[ -z $PREV_ARMEM ]] && PREV_ARMEM="$NONE" if [[ "$PREV_ARMEM" != "$NONE" ]]; then PREV_TARGET="$PREV_TARGET[$PREV_ARMEM]" fi # Do the dup check [[ "$PREV_TARGET" = "$TARGET" ]] && $DUP # If CK_AR_CONF (check ar conflict) then do it now if [[ $CK_AR_CONF -eq 1 ]]; then if [[ "$TFILE" = "$PREV_TFILE" ]]; then [[ "$ARMEM" = "$NONE" || "$PREV_ARMEM" = "$NONE" ]] && $DUP fi fi # end of CK_AR_CONF check inc EFCOUNT || $ERROR done $OK } # end of check_dup_targets() ######################################################################## ## Function: check_overlaid_targets (renames overlaid target files) ## Parameters: None ######################################################################## check_overlaid_targets() { typeset ERROR='eval pmerror "check_overlaid_targets()"; return 1' typeset EFCOUNT=1 typeset OVSUFFIX="__O_v_" typeset OK='eval return 0' # Check to see if we are operating within a versioned WPAR. # If not, there is nothing to check. if [[ -z $(/usr/lib/wpars/manage_file_overlays -l -A | /usr/bin/head -1) ]]; then $OK fi # Loop through all of the targets looking for a files which # are overlaid. If we find one, transform the name to match # the renamed file replaced by the overlay. while [[ $EFCOUNT -le $GENUM ]]; do # loop safety [[ $EFCOUNT -gt $MAXEFILES ]] && $ERROR # If the target file exists on the system as a # symbolic link, then check to see if it is an overlaid file. # If it is, reflect the renaming of the original file in the # target. This could be cached for efficiency, but the # number of situations like are expected to be small. # if [[ -L ${A_ETARGET[$EFCOUNT]} ]]; then ovchk=`ODMDIR=/usr/lib/objrepos /usr/bin/odmget -q "path=${A_ETARGET[$EFCOUNT]}" file_overlay` if [[ -n "$ovchk" ]]; then A_ETARGET[$EFCOUNT]="${A_ETARGET[$EFCOUNT]}${OVSUFFIX}" fi fi (( EFCOUNT = EFCOUNT + 1 )) done $OK } # end of check_overlaid_targets() ######################################################################## ## Function: Disable function. ## Paramenters: Function name ## Output: None ######################################################################## abort_function() { typeset ERROR='eval $RM -f $BUF; pmerror "abort_function"; return 1' typeset FUNCTION=$1 typeset BUF=/tmp/.emgr.abort_function.$$ [[ -z $FUNCTION ]] && return 0 [[ "$FUNCTION" = "abort_function()" ]] && $ERROR setcmd rm || $ERROR $RM -f $BUF typeset -f "$FUNCTION" > /dev/null 2>&1 || $ERROR # Create the function echo "#!/usr/bin/ksh\n$FUNCTION()\n{\nreturn 0\n}\n" > $BUF || $ERROR # Reload the function . $BUF || $ERROR perror 341 "$FUNCTION()" rm -f $BUF return 0 } # end of abort_function() ######################################################################## ## Function: more_same_target (More targets with the same loc ?) ## Paramenters: ## Output: 0 = NO more targets, 1 = More targets ######################################################################## more_same_target() { typeset ERROR='eval pmerror "more_same_target"; return 1' typeset TARGET="$1" typeset EFCOUNT="$2" typeset MORE=1 typeset NO_MORE=0 # Set RC to no more. typeset RC=$NO_MORE [[ -z $TARGET ]] && $ERROR isnum $EFCOUNT || $ERROR while [[ $EFCOUNT -lt $GENUM ]]; do inc EFCOUNT # loop safety [[ $EFCOUNT -gt $MAXEFILES ]] && $ERROR if [[ ${A_ETARGET[$EFCOUNT]} = $TARGET ]]; then RC=$MORE break fi done # output the return echo "$RC" return 0 } # end of more_same_target() ######################################################################## ## Function: shiftbit() (Shifts $START by $NUM in direction $DIRECTION) ## Parameters: START number, NUM to shift, DIRECTION of shift (L or R) ## Returns: 0 = ok, != 0 = fail ## Output Returns: New value after shift. ######################################################################## shiftbit() { typeset START=$1 typeset NUM=$2 typeset DIRECTION=$3 typeset NEW=0 typeset ERROR='eval pmerror "shiftbit()"; return 1' # Validate arguments isnum $START || $ERROR isnum $NUM || $ERROR [[ "$DIRECTION" != "L" && "$DIRECTION" != "R" ]] && $ERROR # Do the shift based on direction if [[ "$DIRECTION" = "L" ]]; then (( NEW = $START << $NUM )) else (( NEW = $START >> $NUM )) fi # Validate and output return isnum $NEW && echo "$NEW" || $ERROR return 0 } # end of shiftbit() ######################################################################## ## Function: isbitset() (Is bit $BIT set in $VALUE) ## Parameters: VALUE, BIT ## Returns: 0 = is set, 1 = fail, 2 = not set ######################################################################## isbitset() { typeset VALUE=$1 typeset BIT=$2 typeset ERROR='eval pmerror "isbitset()"; return 1' typeset SET='eval return 0' typeset NOT_SET='eval return 2' # Validate arguments isnum $VALUE || $ERROR isnum $BIT || $ERROR (( $VALUE & $BIT )) && $SET || $NOT_SET } # end of isbitset() ######################################################################## ## Function: ck_overwrite_bit (check overwrite bit) ## Parameters: FUNC (name of function to overwrite) ## Returns: 0 = is set, 1 = fail, 2 = not set ######################################################################## ck_overwrite_bit() { typeset ERROR='eval pmerror "ck_overwrite_bit()"; return 1' typeset NOT_SET='eval return 2' typeset SET='eval perror 341 $FORMATED_FUNC; return 0' typeset BIT=-1 typeset SHIFT=-1 # If the global variable EMGR_OVERWRITE_BITS is not set, the # we are done [[ -z $EMGR_OVERWRITE_BITS ]] && $NOT_SET # Validate arguments typeset FUNC=$1 typeset FORMATED_FUNC FORMATED_FUNC="${FUNC%% *}()" [[ -z $FUNC ]] && $ERROR isnum $EMGR_OVERWRITE_BITS || $NOT_SET # Find the right bit to check based on FUNC case $FUNC in "check_epkg_prereq") SHIFT=0 ;; # 1 - Skip prereq check "set_pkg_list" ) SHIFT=1 ;; # 2 - Skip pkg to file map "check_exp_req_ispace") SHIFT=2 ;; # 4 - Skip install space check "check_exp_req_rspace") SHIFT=3 ;; # 8 - Skip remove space check "check_mounti_option") SHIFT=4 ;; # 16 - Skip mounti checks "db_change_state") SHIFT=5 ;; # 32 - Do not change state "db_is_target_locked") SHIFT=6 ;; # 64 - Skip target lock check "exec_epkg_script") SHIFT=7 ;; # 128 - Skip all pkg scripts "exec_epkg_script PREI") SHIFT=8 ;; # 256 - Skip prei pkg script "exec_epkg_script POSTI") SHIFT=9 ;; # 512 - Skip posti pkg script "exec_epkg_script PRER") SHIFT=10 ;; # 1024 - Skip prer pkg script "exec_epkg_script POSTR") SHIFT=11 ;; # 2048 - Skip postr pkg script "lock_packages") SHIFT=12 ;; # 4096 - Skip locking packages "unlock_packages") SHIFT=13 ;; # 8192 - Skip unlocking packages "check_efix_locks") SHIFT=14 ;; # 16384 - Skip chking all efix lcks "read_ecfile") SHIFT=15 ;; # 32768 - Disable error in reading # the ecfile "install_epkg") SHIFT=16 ;; # 65536 - Ignore epkg name check "check_e2e_requisites") SHIFT=17 ;; # 131072 - skip e2e requisites "remove_sup_efixes") SHIFT=18 ;; # 262144 - skip efix supersede "check_e2e_pprereqs") SHIFT=19 ;; # 524288 - skip e2e prereq check *) $ERROR esac # end of case statement [[ $SHIFT -lt 0 ]] && $NOT_SET # Do the bit shift BIT=$(shiftbit 1 $SHIFT L) || $ERROR # Is the BIT set ? isbitset $EMGR_OVERWRITE_BITS $BIT && $SET || $NOT_SET return 0 } # end of ck_overwrite_bit() ####################################################################### ## Function: is_hlinked() Is node1 a link to done2. ## Parameters: ## Returns: 0 = linked, 1 = not linked >1 = failure ####################################################################### is_hlinked() { typeset ERROR='eval pmerror "is_hlinked()"; return 2' typeset N1=$1 # node1 typeset N2=$2 # node2 typeset LINKED='eval return 0' typeset NOT_LINKED='eval return 1' typeset B1 B2 # buffer 1 and 2 [[ -z $N1 || -z $N2 ]] && $ERROR [[ -f $N1 && -f $N2 ]] || $NOT_LINKED [[ -L $N1 || -L $N2 ]] && $NOT_LINKED # Compare the node numbers B1=$(get_inode -f $N1) || $ERROR B2=$(get_inode -f $N2) || $ERROR [[ $B1 -ne $B2 ]] && $NOT_LINKED # Make sure both nodes are in the same file system B1=$(whichfs $N1) || $ERROR B2=$(whichfs $N2) || $ERROR [[ "$B1" != "$B2" ]] && $NOT_LINKED # get the abspath for N1 and N2 and make sure N1 and N2 are # not the same path ! N1=$(abspath $N1) || $ERROR N2=$(abspath $N2) || $ERROR [[ "$N1" = "$N2" ]] && $NOT_LINKED $LINKED } # end of is_hlinked() ######################################################################## ## Function: get_installp_links() Gets installp link list from ## the inventory ODM database ## Parameters: [] ## Output: comma separated link list, if there is one ## Returns: 0 = ok, !0 = failure ######################################################################## get_installp_links() { typeset ERROR='eval perror 345 "links"; return 1' typeset TARGET="$1" typeset LPP="$2" typeset BUF="" # check args, etc [[ $PLATFORM != "AIX" ]] && return 0 [[ -z $TARGET ]] && $ERROR # Get the lpp/fileset that owns this link if it has not been # provided. if [[ -z $LPP ]]; then LPP=$(which_lpp $TARGET) || $ERROR fi # Get the list of files associated with this fileset BUF=$($LSLPP -cf $LPP) || $ERROR # Parse out all links BUF=$(echo "$BUF" | $AWK -v TARGET=$TARGET -F: '{ if ($3!~"->") next; split($3,split_array," -> "); link_array[split_array[1]]=split_array[2]; } END { anchor="" # find the anchor for (link in link_array) { if (link==TARGET) { anchor=link_array[link]; break; } if (link_array[link]==TARGET) { anchor=TARGET; break; } } # if anchoer is null, then we are done if(anchor==NULL) exit(0); # print out all links connected to the anchor (except the TARGET) for (link in link_array) if (link_array[link] == anchor && link != TARGET ) print link; if (anchor != TARGET ) print anchor; exit(0); }') || $ERROR [[ -n $BUF ]] && echo "$BUF" return 0 } # end of get_installp_links() ######################################################################## ## Function: get_inode() ## Parameters: ## [-L = follow sym links>] ## [-f = file or a link to a file ] ## [-d = directory or a link to a directory ] ## [-b = file or directory or a link to either ] ## [-z = anything that has an inode number ] ## ## Output: inode number ## Returns: 0 = ok, !0 = failure ######################################################################## get_inode() { typeset ERROR='eval pmerror "get_inode()"; return 1' typeset BUF typeset OPTION typeset Lflag typeset FILE typeset DIR typeset TARGET # node status typeset ISFILE=0 # is file typeset ISDIR=0 # is directory typeset ISDF=0 # is file or directory typeset ISLINK=0 # is link # set inode reference types typeset BNODE=0 typeset ZNODE=0 while getopts ":f:d:z:b:L" OPTION; do case $OPTION in L) Lflag="-L" ;; # get inode of file link points to # (not inode of link) f) FILE=$OPTARG ;; # must be a file or a link to a file d) DIR=$OPTARG ;; # must be a dir or a link to a dir b) TARGET=$OPTARG # can be a file or a dir or a link to either BNODE=1 ;; z) TARGET=$OPTARG # can be anything that has an inode number ZNODE=1 ;; *) $ERROR ;; esac done # Check syntax [[ -n $FILE ]] && TARGET=$FILE [[ -n $DIR ]] && TARGET=$DIR [[ -z $TARGET ]] && $ERROR # Set node description variables [[ -f $TARGET ]] && ISFILE=1 [[ -d $TARGET ]] && ISDIR=1 [[ -L $TARGET ]] && ISLINK=1 (( ISDF = $ISDIR + $ISFILE )) # Check internal consistency [[ $ISDF -gt 1 ]] && $ERROR (( $ISFILE + $ISDIR + $ISLINK < 1 )) && $ERROR # Check if this is the correct reference type [[ -n $FILE && $ISFILE -eq 0 ]] && $ERROR [[ -n $DIR && $ISDIR -eq 0 ]] && $ERROR [[ $BNODE -eq 1 && $ISDF -eq 0 ]] && $ERROR [[ $ZNODE -eq 1 && $ISDF -eq 0 && $ISLINK -eq 0 ]] && $ERROR # If ZNODE is set, and this is a broken link, just get the # inode of the link. [[ $ZNODE -eq 1 && $ISDF -eq 0 ]] && Lflag="" BUF=$($LS $Lflag -di $TARGET) || $ERROR BUF=$(echo "$BUF" | $AWK1) || $ERROR isnum "$BUF" || $ERROR echo "$BUF" return 0 } # end of get_inode() ######################################################################## ## Function: get_lcount() # get hard link count ## Parameters: $TARGET ## Output: link count ## Returns: 0 = ok, !0 = failure ######################################################################## get_lcount() { typeset ERROR='eval pmerror "get_lcount()"; return 1' typeset BUF typeset TARGET=$1 [[ -f $TARGET || -d $TARGET || -c $TARGET || -b $TARGET ]] || $ERROR BUF=$($LS -l $TARGET) || $ERROR BUF=$(echo "$BUF" | $AWK2) || $ERROR isnum "$BUF" || $ERROR echo "$BUF" return 0 } # end of get_lcount() ######################################################################## ## Function: check_node ## Parameters: ## Returns: 0 = node exists, 1 = node does not exist or error ######################################################################## check_node() { typeset FILE="$1" typeset ERROR='eval pmerror "check_node()" ; return 1' [[ -z $FILE ]] && $ERROR [[ ! -L $FILE && ! -r $FILE ]] && return 1 return 0 } # end of check_node() ####################################################################### ## Function: is_slinked() Is the symlink pointing to target? ## Parameters: ## Returns: 0 = linked, 1 = not linked >1 = failure ####################################################################### is_slinked() { typeset ERROR='eval pmerror "is_slinked()"; return 2' typeset LINK=$1 typeset TARGET=$2 typeset LINKED='eval return 0' typeset NOT_LINKED='eval return 1' typeset LN TN # inodes typeset LFS TFS # link fs and target fs [[ -z $LINK || -z $TARGET ]] && $ERROR [[ ! -L $LINK || -L $TARGET ]] && $NOT_LINKED # Compare the inode numbers LN=$(get_inode -Lz $LINK) || $ERROR TN=$(get_inode -b $TARGET) || $ERROR [[ $LN -ne $TN ]] && $NOT_LINKED # Get the target file systems for LINK and TARGET. Make sure they # are the same. LFS=$(whichfs $LINK 2> /dev/null ) || $NOT_LINKED TFS=$(whichfs $TARGET 2> /dev/null ) || $NOT_LINKED [[ "$LFS" != "$TFS" ]] && $NOT_LINKED $LINKED } # end of is_slinked() ######################################################################## ## Function: add_to_cleanup < FILE | DIR > ######################################################################## add_to_cleanup() { eval $SIGTRAP typeset ERROR='eval pmerror "add_to_cleanup()"; return 1' typeset NODE=$1 typeset TYPE=$2 [[ -z $NODE || -z $TYPE ]] && $ERROR case $TYPE in FILE) strcat -v ADD_CLEAN_FILE -s "$NODE" || $ERROR ;; DIR) strcat -v ADD_CLEAN_DIR -s "$NODE" || $ERROR ;; *) # Invalid TYPE $ERROR esac return 0 } # end of add_to_cleanup() ######################################################################## ## Function: strcat [-au ] [-f ] -v -s ######################################################################## strcat() { eval $SIGTRAP typeset ERROR='eval pmerror "strcat()"; return 1' typeset VAR_NAME="" # variable to alter typeset CURR_VAL="" # current value holder typeset STRING="" # string to concatenate typeset DEL="" # delimiter typeset ALWAYS=0 # create always typeset SP=" " # blank space (default delimiter) DEL="$SP" # set default delimiter while getopts ":f:v:s:a" OPTION; do case "$OPTION" in f) DEL="$OPTARG";; a) ALWAYS=1;; s) STRING="$OPTARG";; v) VAR_NAME="$OPTARG";; *) $ERROR esac done # Check for required args [[ -z $VAR_NAME ]] && $ERROR # Store the current value eval CURR_VAL="$"$VAR_NAME # Check if empty and initialize if [[ -z $CURR_VAL ]]; then eval $VAR_NAME='$STRING' return 0 fi # If $STRING is null, check if the add ALWAYS flag is on [[ -z $STRING && $ALWAYS -eq 0 ]] && return 0 # Concatenate with new string eval $VAR_NAME='$CURR_VAL$DEL$STRING' return 0 } # end of strcat() ######################################################################## ## Function: print_cfgfile() Streams the output of a configuration file ## removing any white space and comment lines. Also, sets ## the subshrc error token if there is an error. ## Parameters: ## Returns: 0 = ok, 1 = failure (also sets subshrc error token) ######################################################################## print_cfgfile() { typeset METOK='eval echo 2 > $ERRTOKEN' # mark error token typeset ERROR='eval $METOK; pmerror "print_cfgfile()"; return 1' typeset CFGFILE=$1 [[ -z $CFGFILE ]] && $ERROR check_file $CFGFILE || $ERROR is_text_file $CFGFILE || $ERROR $AWK ' { if ($0~"^[\t| ]*#|^$|^[\t| ]*$") next; str=$0; gsub("^[\t| ]*","",str) ; # remove leading whitespace gsub("[\t| ]*$","",str) ; # remove ending whitespace rc=is_printed(str); if (rc == 0 ) next; print str; strarray[str]=1; } # end of MAIN function is_printed(STR) { for (istr in strarray) if (istr == STR) return(0); # found a matching str already printed return(1); # did not find a matching str already printed }' $CFGFILE || $ERROR subshrc PUTRC || $ERROR return 0 } # end of print_cfgfile() ######################################################################## ## Function: verify_pkglocks_file() Verfies the format of the pkglocks ## file ## Parameters: ## Returns: 0 = ok, !0 = error ######################################################################## verify_pkglocks_file() { typeset ERROR='eval perror 360; return 1' # syntax error in pkglock file: typeset SERROR='eval perror 112 ">> $LINE <<"; RC=1; continue' typeset PFILE="$1" typeset -i LINES=0 typeset RC=0 typeset PNAME # package name typeset PACT # package action typeset PTYPE # package type typeset LINE typeset JUNK [[ -z $PFILE ]] && $ERROR print_msg 361 check_file_full $PFILE || $ERROR ########################################################### ## Check that the number of entries has not exceeded ## PKGLOCKMAX. ########################################################### LINES=$(print_cfgfile "$PFILE" | $WC -l) (( RC = $? + $(subshrc GETRC) )) [[ $RC -ne 0 ]] && $ERROR isnum $LINES || $ERROR if [[ $LINES -le 0 ]]; then perror 113 $ERROR fi if [[ $LINES -gt $PKGLOCKMAX ]]; then perror 362 $PKGLOCKMAX $ERROR fi ########################################################### ## Loop through the pkglock file and process each entry. ########################################################### print_cfgfile $PFILE | while read LINE; do echo "$LINE" | read PNAME PACT PTYPE JUNK # Check that we have required fields [[ -z $PNAME || -z $PACT ]] && $SERROR [[ -n $JUNK && "$JUNK" != "#"* ]] && $SERROR # Check PACT PACT=$(toupper $PACT) || $ERROR case "$PACT" in ALWAYS|IFINST) : ;; # ok *) $SERROR ;; # error esac [[ $PACT != "ALWAYS" && $PACT != "IFINST" ]] && $SERROR # Check PTYPE (if needed) if [[ -n "$PTYPE" && "$PTYPE" != "#"* ]]; then PTYPE=$(toupper $PTYPE) || $ERROR case "$PTYPE" in INSTALLP) : ;; # ok ISMP|RPM) perror 363 $PTYPE; RC=1 ;; # not supported yet *) $SERROR ;; # error esac fi continue done (( RC = $? + $RC + $(subshrc GETRC) )) [[ $RC -ne 0 ]] && $ERROR return 0 } # end of verify_pkglocks_file() ######################################################################## ## Function: verify_supersede_file() Verfies the format of the pkglocks ## file ## Parameters: ## Returns: 0 = ok, !0 = error ######################################################################## verify_supersede_file() { typeset ERROR='eval perror 370; return 1' # syntax error in pkglock file: typeset SERROR='eval perror 112 ">> $LINE <<"; RC=1; continue' typeset SFILE="$1" typeset SUP # Supersede index typeset -i LINES=0 typeset RC=0 typeset EFIX JUNK typeset LINE [[ -z $SFILE ]] && $ERROR print_msg 371 check_file_full $SFILE || $ERROR ########################################################### ## Check that the number of entries has not exceeded ## SUPERSMAX. ########################################################### LINES=$(print_cfgfile "$SFILE" | $WC -l) (( RC = $? + $(subshrc GETRC) )) [[ $RC -ne 0 ]] && $ERROR isnum $LINES || $ERROR if [[ $LINES -le 0 ]]; then perror 113 $ERROR fi if [[ $LINES -gt $SUPERSMAX ]]; then perror 362 $SUPERSMAX $ERROR fi ########################################################### ## Loop through the pkglock file and process each entry. ########################################################### print_cfgfile $SFILE | while read LINE; do echo "$LINE" | read EFIX JUNK # Check that we have required fields [[ -z $EFIX ]] && $ERROR if [[ ${#EFIX} -gt $LABELMAX ]]; then perror 20 "$LABELMAX" $SERROR fi if [[ "$EFIX" = "$A_ELABEL" ]]; then perror 378 $SERROR fi # Make sure we have not worked this SUP already for SUP in $GSUPS; do [[ "$EFIX" = "$SUP" ]] && continue 2 done strcat -v GSUPS -s "$EFIX" || $ERROR continue done (( RC = $? + $RC + $(subshrc GETRC) )) [[ $RC -ne 0 ]] && $ERROR return 0 } # end of verify_supersede_file() ######################################################################## ## Function: verify_e2eprereq_file() Verifies the format of the e2e ## prereq file. ## Parameters: ## Returns: 0 = ok, !0 = error ######################################################################## verify_e2eprereq_file() { typeset ERROR='eval perror 382; return 1' typeset SERROR='eval perror 112 ">> $LINE <<"; RC=1; continue' typeset E2EPFILE="$1" typeset -i LINES=0 typeset RC=0 typeset EREQ # efix requisite name typeset RTYPE # requisite type typeset LINE typeset JUNK typeset RET=0 [[ -z $E2EPFILE ]] && $ERROR print_msg 383 check_file_full $E2EPFILE || $ERROR ########################################################### ## Check that the number of entries has not exceeded ## E2EMAX. ########################################################### LINES=$(print_cfgfile "$E2EPFILE" | $WC -l) (( RC = $? + $(subshrc GETRC) )) [[ $RC -ne 0 ]] && $ERROR isnum $LINES || $ERROR if [[ $LINES -le 0 ]]; then perror 113 $ERROR fi if [[ $LINES -gt $E2EMAX ]]; then perror 362 $E2EMAX $ERROR fi ########################################################### ## Loop through the pkglock file and process each entry. ########################################################### print_cfgfile $E2EPFILE | while read LINE; do echo "$LINE" | read EREQ RTYPE JUNK [[ -z $EREQ || -z $RTYPE ]] && $SERROR if [[ ${#EREQ} -gt $LABELMAX ]]; then perror 20 "$LABELMAX" $SERROR fi if [[ "$EREQ" = "$A_ELABEL" ]]; then perror 378 $SERROR fi # Make sure RTYPE is valid RTYPE=$(toupper $RTYPE) || $ERROR # Verify RTYPE case $RTYPE in PREREQ) RET=$(isin "$EREQ" "$GE2EXREQS") || $SERROR if [[ $RET -eq 1 ]]; then perror 385 "$RTYPE" "XREQ" $SERROR fi strcat -v GE2EPREREQS -s "$EREQ" || $ERROR ;; XREQ) RET=$(isin "$EREQ" "$GE2EPREREQS") || $SERROR if [[ $RET -eq 1 ]]; then perror 385 "$RTYPE" "PREREQ" $SERROR fi strcat -v GE2EXREQS -s "$EREQ" || $ERROR ;; *) $SERROR ;; esac continue done (( RC = $? + $RC + $(subshrc GETRC) )) [[ $RC -ne 0 ]] && $ERROR return 0 } # end of verify_e2eprereq_file() ######################################################################## ## Function: check_e2e_sup_conflict() Check for conflicts between ## efix superseded and e2e prereqs. ## Parameters: ## Returns: 0 = ok, !0 = error ######################################################################## check_e2e_sup_conflict() { typeset RC=0 typeset BUF typeset ENTRY typeset ERROR='eval perror 386 "$ENTRY"; RC=1' [[ -z $GSUPS || -z $GE2EPREREQS ]] && return 0 ########################################################### ## Check if the ENTRY in the supersed data is also present ## in the e2e prereq data. This would mean that we have ## asked to remove an efix that is a prereq ! ## ## NOTE: ## GSUPS is populated by verify_supersede_file() ## GE2EPREREQS is populated by verify_e2eprereq_file() ## ########################################################### for ENTRY in $GSUPS; do BUF=$(isin "$ENTRY" "$GE2EPREREQS") || continue [[ $BUF -eq 1 ]] && $ERROR done return $RC } # end of check_e2e_sup_conflict() ######################################################################## ## Function: inc_global_warning() Increments the global warning number. ## ## Parameters: None. ## Returns: 0 = ok, 1 = fail ## Note: The global warning file is maintained to allow subshells to ## increment the global_warning number. ######################################################################## inc_global_warning() { typeset ERROR='eval print_msg 26 "inc_global_warning()" >&2; return 1' typeset GWNUM=0 # global warning number if [[ -z $GLOBAL_WARNING_FILE ]]; then inc GLOBAL_WARNING return 0 fi ########################################################### ## Get the current GWNUM from GLOBAL_WARNING_FILE ########################################################### GWNUM=$(get_global_warning) || $ERROR isnum $GWNUM || $ERROR ########################################################### ## Increment GWNUM and output it to the GLOBAL_WARNING_FILE ########################################################### inc GWNUM echo "$GWNUM" > $GLOBAL_WARNING_FILE || $ERROR return 0 } # end of inc_global_warning() ######################################################################## ## Function: get_global_warning() Retrives the the the current ## global warning number. ## Parameters: None. ## Returns: 0 = ok, 1 = fail ## Output: Current global warning number. ## Note: The global warning file is maintained to allow subshells to ## increment the global_warning number. ######################################################################## get_global_warning() { typeset ERROR='eval print_msg 26 "get_global_warning()" >&2; return 1' typeset GWNUM=0 # global warning number [[ -z $GLOBAL_WARNING_FILE ]] && return 0 ########################################################### ## If the GLOBAL_WARNING_FILE file does not exist or is ## empty, then return 0 as the GWNUM ########################################################### if [[ ! -s $GLOBAL_WARNING_FILE ]]; then echo "0" return 0 fi ########################################################### ## Cat the GLOBAL_WARNING_FILE to get the current GWNUM ########################################################### read GWNUM < $GLOBAL_WARNING_FILE isnum $GWNUM || $ERROR echo "$GWNUM" return 0 } # end of get_global_warning() ######################################################################## ## Function: setup_global_warning() Sets up global warning file. ## Parameters: None. ## Returns: 0 = ok, 1 = fail ## Note: The global warning file is maintained to allow subshells to ## increment the global_warning number. ######################################################################## setup_global_warning() { typeset ERROR='eval print_msg 26 "setup_global_warning()" >&2; return 1' # Export the GLOBAL_WARNING_FILE variable [[ -z $WORKDIR || -z $ERR_BUF ]] && $ERROR export GLOBAL_WARNING_FILE=$WORKDIR/.global.warning.$$ # Write in the curren global warning number. echo $GLOBAL_WARNING > $GLOBAL_WARNING_FILE if [[ $? -ne 0 ]]; then $RM -f $GLOBAL_WARNING_FILE unset GLOBAL_WARNING_FILE $ERROR fi # Reset GLOBAL_WARNING GLOBAL_WARNING=0 return 0 } # end of setup_global_warning() ######################################################################## ## Function: conv_val_to_field() Converts FIELD to VALUE for CVARS ## Parameters: ## Output: FIELD variable associated with VALUE variable ## Returns: 0 = ok, 1 = fail ######################################################################## conv_val_to_field() { typeset ERROR='eval pmerror "conv_val_to_field()"; return 1' typeset VAR typeset FIELD typeset VAL typeset VALUE=$1 [[ -z $VALUE ]] && $ERROR for VAR in $CVARS; do echo "$VAR" | IFS=":" read FIELD VAL if [[ "$VALUE" = "$VAL" ]]; then echo "$FIELD" return 0 fi done # If we get here, then something went wrong $ERROR } # end of conv_val_to_field() ######################################################################## ## Function: set_md5_cmd() Sets the the MD5 command to be used on the ## system. ## Parameters: NONE ## Returns: 0 = found md5 command, 1 = did not find md5 command ######################################################################## set_md5_cmd() { typeset FILE="$1" typeset CSUM=/usr/bin/csum typeset FOUND='eval return 0' typeset NOT_FOUND='eval return 1' ############################################################ ## First check if EMGR_MD5_CMD is set by the user, if it is ## than we use it. ############################################################ [[ -n $EMGR_MD5_CMD ]] && $FOUND ############################################################ ## Check if /usr/bin/csum is available. ############################################################ if [[ -x $CSUM ]]; then export EMGR_MD5_CMD=$CSUM $FOUND fi unset EMGR_MD5_CMD $NOT_FOUND } # end of set_md5_cmd() ######################################################################## ## Function: get_md5_fsum() Gets MD5 checksum. ## Parameters: ## Output: MD5 checksum ## Returns: 0 = ok, 1 = fail ######################################################################## get_md5_fsum() { typeset FILE="$1" typeset ERROR='eval perror 405 $FILE; return 1' typeset MD5SUM="" [[ -z "$FILE" || -z $EMGR_MD5_CMD ]] && $ERROR check_file $FILE || $ERROR if [[ ! -r $EMGR_MD5_CMD ]]; then perror 57 $EMGR_MD5_CMD $ERROR fi MD5SUM=$($EMGR_MD5_CMD $FILE/) || $ERROR MD5SUM=$(echo "$MD5SUM" | $AWK1) || $ERROR [[ ${#MD5SUM} -eq 32 ]] || $ERROR echo "$MD5SUM" } # end of get_md5_fsum() ######################################################################## ## Function: sync() syncs data to disk ## Parameters: [] ## Output: None ## Returns: 0 = ok, 1 = fail ######################################################################## sync() { typeset BACKGROUND=$1 if [[ -n $BACKGROUND ]]; then $SYNC & return 0 else $SYNC && return 0 || pmerror $SYNC fi #If we got here, then there is an error. return 1 } # end of sync() ######################################################################## ## Function: set_emgrdata_vars() (Initialize Variables) ######################################################################## set_emgrdata_vars() { [[ -z $EMGRDIR ]] && return 1 # Database variables export EMGRDBDIR=$EMGRDIR/DBS export NEW_REPLACED_DIR=$EMGRDIR/new_replaced export EDB=$EMGRDBDIR/efix.db export EFDB=$EMGRDBDIR/files.db export PRQEDB=$EMGRDBDIR/prereq.db export PLCKDB=$EMGRDBDIR/pkglck.db export E2EPDB=$EMGRDBDIR/e2eprereq.db export APARDB=$EMGRDBDIR/aparref.db export TMP_EDB=$EMGRDBDIR/tefix.db.$$ export TMP_EFDB=$EMGRDBDIR/tfiles.db.$$ export TMP_PRQEDB=$EMGRDBDIR/tprereq.db.$$ export TMP_PLCKDB=$EMGRDBDIR/tpkglck.db.$$ export TMP_E2EPDB=$EMGRDBDIR/te2eprereq.db.$$ export TMP_APARDB=$EMGRDBDIR/taparref.db.$$ export EMGRLOCK=/var/locks/emgr.lock export EMGRBIN=$EMGRDIR/bin # All tracked DBs export ALLDBS="$EDB $EFDB $PRQEDB $PLCKDB $E2EPDB $CUDB $APARDB" # Efix data directory variables export EFIXDATADIR=$EMGRDIR/efixdata export ACLS="ACL.SAVE" export TCBS="TCB.SAVE" export TSDS="TSD.SAVE" export ACLN="ACL.NEW" export ESAVE="save" export EFSAVE="EFSAVE" return 0 } # end of set_emgrdata_vars() ######################################################################## ## Function: verify_apar_info() checks for valid fields in APARREF file ## Parameters: APARREF file path ## Returns: 0 = ok, 1 = sibling id of "none" found, 2 = fail ######################################################################## verify_apar_info() { typeset APARREF_FILE=$1 [[ -z $APARREF_FILE ]] && return 1 $AWK -F '|:|' ' BEGIN { rc=0 } { if (NF > 3) { rc=2; exit } for(i=1;i<=NF;i++) { if (i == 1) { if (tolower($i) == "none") { rc=1; continue } if ($i !~ /^[0-9]+$/) { rc=2; exit } } if (i == 2) { if (tolower($i) == "none") { continue } if ($i !~ /^[A-Z]{2}[0-9]{5}$/) { rc=2; exit } } } } END { exit rc }' $APARREF_FILE 2>/dev/null return $? } # end of verify_apar_info()