#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos72Q src/bos/usr/lib/nim/methods/c_cust_lku.sh 1.19 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2014,2019 
# 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 
# @(#)64        1.19  src/bos/usr/lib/nim/methods/c_cust_lku.sh, cmdnim, bos72Q, q2019_29B5  7/9/19  14:29:30
#   COMPONENT_NAME: CMDNIM
#
#   FUNCTIONS: ./usr/lib/nim/methods/c_cust_lku.sh
#		
#   ORIGINS: 27
#
#   (C) COPYRIGHT International Business Machines Corp. 2014
#   All Rights Reserved
#   Licensed Materials - Property of IBM
#   US Government Users Restricted Rights - Use, duplication or
#   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

# include common NIM shell defines/functions
NIMPATH=${0%/*}
NIMPATH=${NIMPATH%/*}
[[ ${NIMPATH} = ${0} ]] && NIMPATH=/usr/lpp/bos.sysmgt/nim
NIM_METHODS="${NIMPATH}/methods"
. ${NIM_METHODS}/c_sh_lib

#---------------------------- local defines ------------------------------------

#---------------------------- module globals -----------------------------------
REQUIRED_ATTRS="live_update"
OPTIONAL_ATTRS="lpp_source installp_flags filesets installp_bundle boot_env fix_bundle fixes async show_progress live_update_data script debug"
PROGRAM_NAME="c_cust_lku"
lpp_source=""
installp_flags=""
filesets=""
installp_bundle=""
fileset_list=""
show_progress=""
script=""
geninstall_cmd=""
lvdata="/var/adm/ras/liveupdate/lvupdate.data"
back_lvdata=""
pvc=""
hmc=""
user=""
project=""

NIM_OUT=""
VERBOSE=""

#---------------------------- prep_dir         --------------------------------
#
# NAME: prep_dir
#
# FUNCTION:
#		prepares environment to use a directory as the source for install images
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#			1				= local mount point
#		global:
#			src_access			= local access point for the source device
#			access_pnt			= local access point returned from nim_mount
#
# RETURNS: (int)
#		0					= success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function prep_dir {

	typeset lpp_access_dir=${1}
	typeset rc=1

	# NOTE: As part of the http availability feature -
	#       the initial call will include a check for
	#       web download service.
	#
	if [[ ${lpp_access_dir} = ?*:/?* ]]
	then
		# c_cust_lku should attempt to locate the file
		# using the nimtthp servicing option
		# Preference for ssl ..

		download_srvr=`echo ${lpp_access_dir} | ${SED} 's/\:.*$//'`
		download_loc=`echo ${lpp_access_dir} | ${SED} 's/.*://'`
		${MKDIR} -p ${TMPDIR}/$download_loc
		${NIMHTTP} -i $download_srvr -f $download_loc -o dest=${TMPDIR} -s >/dev/null 2>&1 ||
		${NIMHTTP} -i $download_srvr -f $download_loc -o dest=${TMPDIR} >/dev/null 2>&1
		rc=$?

		if [[ $rc -eq 0 ]]; then
			mget_http_content $lpp_access_dir ${TMPDIR} >/dev/null 2>&1
			rc=$?

			# set new access point
			if [[ $rc -eq 0 ]]; then
				access_pnt="${TMPDIR}/${download_loc}"
			fi
		fi
		# end of HTTP
	fi

	if [[ $rc -ne 0 ]]
	then
		# NFS Method

		# mount images at a specific offset
		nim_mount ${lpp_access_dir}
		rc=$?

		# end of NFS
	fi

	return $rc

} # end of prep_dir

#---------------------------- prep_lpp_source ----------------------------------
#
# NAME: prep_lpp_source
#
# FUNCTION:	prepares the specified LPP source device for use
#
# EXECUTION ENVIRONMENT:
#
# NOTES:	calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#			lpp_source	= source device name
#
# RETURNS: (int)
#		0			= success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function prep_lpp_source {

	typeset rc=1

	prep_dir `get_res_mnt "lpp_source" $lpp_source`

	rc=$?
	if [[ $rc -eq 0 ]]; then
		# Change the lpp_source name
		lpp_source="-d ${access_pnt}"
	fi

	return $rc

} # end of prep_lpp_source

#---------------------------- prep_bnd -----------------------------------------
#
# NAME: prep_bnd
#
# FUNCTION:	prepares the specified NIM installp bundle source for use
#               get its attributes to build up the access location before calling
#               c_sh_lib -> prep_bundle to be mounted
#
# EXECUTION ENVIRONMENT:
#
# NOTES:	calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#               parameters:
#               global:
#                       installp_bundle = source installp bundle name
#
# RETURNS: (int)
#               0                       = success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function prep_bnd {

	typeset bndtype=$1
	typeset bndname=$2
	typeset rc=1

	if [[ -n $bndname ]]; then

		# Change the installp_bundle name, prep_bundle requires it
		installp_bundle=`get_res_mnt $bndtype $bndname`

		prep_bundle $installp_bundle
		rc=$?
	fi

	return $rc

} # end of prep_bnd

#---------------------------- prep_live_update_data ----------------------------
#
# NAME: prep_live_update_data
#
# FUNCTION:	prepares the specified NIM live_update_data source for use
#               get its attributes to build up the access location
#
# EXECUTION ENVIRONMENT:
#
# NOTES:	calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#               parameters:
#               global:
#                       installp_bundle = source installp bundle name
#
# RETURNS: (int)
#               0                       = success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function prep_live_update_data {

	typeset rc=0

	# Backup the original /var/adm/ras/liveupdate/lvupdate.data file on the client if it exists
	if [[ -s $lvdata ]]; then
		back_lvdata=${lvdata}.$$
		$CP $lvdata $back_lvdata
		if [[ $? -ne 0 ]]; then
			#
			# 0042-175 <c_cust_lku>: An unexpected result was returned by the
			#       "</usr/bin/cp>" command:
			#       <$CP $lvdata $back_lvdata>
			error ${ERR_CMD} "$CP" "$CP $lvdata $back_lvdata"
		fi
	fi

	# Access the live_update_data resource
	# NOTE: As part of the http availability feature -
	#       the initial call will include a check for
	#       web download service.
	#
	if [[ -n $live_update_data ]]; then
		# Attempt to locate the file
		# using the nimtthp servicing option
		# Preference for ssl ..  
		location=`get_res_mnt "live_update_data" $live_update_data`
		download_srvr=`echo ${location} | ${SED} 's/\:.*$//'`
		download_loc=`echo ${location} | ${SED} 's/.*://'`
		${NIMHTTP} -i $download_srvr -f $download_loc -o dest=${TMPDIR} -s >/dev/null 2>&1 ||
		${NIMHTTP} -i $download_srvr -f $download_loc -o dest=${TMPDIR} >/dev/null 2>&1
		rc=$?

		if [[ $rc -eq 0 ]]; then
			${MV} ${TMPDIR}/$download_loc $lvdata >/dev/null 2>&1
			rc=$?
		fi
		# end of HTTP
		
		if [[ $rc -ne 0 ]]; then
			nim_mount $location
			lv_access=${access_pnt}
			
			# Copy the mounted live_update_data NIM resource to /var/adm/ras/liveupdate/lvupdate.data
			if [[ -n $lv_access ]]; then
				$CP $lv_access $lvdata 2>${ERR} || \
				       	error ${ERR_CMD} "$CP" "$CP $lv_access $lvdata"
					# 0042-175 <c_cust_lku>: An unexpected result was returned by the
					# 	"</usr/bin/cp>" command:
					#	<$CP $lv_access $lvdata>

				#unmount
				nim_unmount $lv_access
				rc=0
				# end of NFS
			fi
		fi
	else
		#
		# warning: This operation requires a resource of type <live_update_data>.
                # Since the resource is not specified, the file residing on the
                # client at location </var/adm/ras/liveupdate/lvupdate.data> will be used.
		#
		${DSPMSG} -s ${MSG_SET} cmdnim.cat ${MSG_WARN_RESOURCE} 'warning: This operation requires a resource of type %1$s.\nSince the resource is not specified, the file residing on the\nclient at location %2$s will be used.\n' "live_update_data" "$lvdata"
	fi


	# P_FLAG is preview set by c_sh_lib->set_geninst()
	# FOR PREVIEW, WE DON'T NEED TO UPDATE
	if [[ -n $P_FLAG ]]; then
		return $rc
	fi

	# Update managed information to the file
	update_live_update_data

	return $rc

} # end of prep_live_update_data

#---------------------------- update_live_update_data ----------------------------
#
# NAME: update_live_update_data
#
# FUNCTION:	update the /var/adm/ras/liveupdate/lvupdate.data file with managed
#               information before calling geninstall
#
# EXECUTION ENVIRONMENT:
#
# NOTES:	calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#               parameters:
#               global:
#
# RETURNS: (int)
#               0                       = success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function update_live_update_data {

	# set hmc/powervc variable
	get_mgmt_info

	# Update the data file $lvdata with managed console information
	if [[ -n $pvc ]]; then

		# define powervc in the lvupdate.data file
		# See if pvc field is present
		if [[ $( ${CAT} $lvdata 2>/dev/null | ${GREP} -v "^#" | ${GREP} "^pvc:" >/dev/null 2>&1; echo $? ) -eq 0 ]]; then

			# Update the management_console field
			if $AWK '/^[^#](.*)management_console(.*)=/ {sub(/(.*)management_console(.*)=(.*)/, \
				 "\tmanagement_console = '$pvc'")} {print}' $lvdata >$TMPDIR/lvupdate.data; then
				$CAT $TMPDIR/lvupdate.data >$lvdata || warning_from_cmd $CAT
			fi

			# Update the user field
			if $AWK '/^[^#](.*)user(.*)=/ {sub(/(.*)user(.*)=(.*)/, \
				 "\tuser = '$user'")} {print}' $lvdata >$TMPDIR/lvupdate.data; then
				$CAT $TMPDIR/lvupdate.data >$lvdata || warning_from_cmd $CAT
			fi

			# Update the project field
			if $AWK '/^[^#](.*)project(.*)=/ {sub(/(.*)project(.*)=(.*)/, \
				 "\tproject = '$project'")} {print}' $lvdata >$TMPDIR/lvupdate.data; then
				$CAT $TMPDIR/lvupdate.data >$lvdata || warning_from_cmd $CAT
			fi
		else
			# pvc field is not present, add the pvc name field
			echo "pvc:"                     >> $lvdata
			echo "\tmanagement_console = $pvc" >> $lvdata
			echo "\tuser = $user" >> $lvdata
			echo "\tproject = $project" >> $lvdata
		fi
	else

		# define hmc in the lvupdate.data file
		# See if hmc field is present
		if [[ $( ${CAT} $lvdata 2>/dev/null | ${GREP} -v "^#" | ${GREP} "^hmc:" >/dev/null 2>&1; echo $? ) -eq 0 ]]; then

			# Update the management_console field
			if $AWK '/^[^#](.*)management_console(.*)=/ {sub(/(.*)management_console(.*)=(.*)/, \
				 "\tmanagement_console = '$hmc'")} {print}' $lvdata >$TMPDIR/lvupdate.data; then
				$CAT $TMPDIR/lvupdate.data >$lvdata || warning_from_cmd $CAT
			fi
		else
			# hmc field is not present, add the hmc name field
			echo "hmc:"                     >> $lvdata
			echo "\tmanagement_console = $hmc" >> $lvdata
		fi

	fi

	return 0

} # end of update_live_update_data

#---------------------------- get_mgmt_info ----------------------------
#
# NAME: get_mgmt_info
#
# FUNCTION:     get the management information for the client
#		This function will set one of the (two) gloabal variables:
#		pvc  = PowerVC IP for the client
#		hmc  = HMC IP for the client
#
# EXECUTION ENVIRONMENT:
#
# NOTES:        calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#               parameters:
#               global:		pvc / hmc
#
# RETURNS: (int)
#               0                       = success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function get_mgmt_info {

	mgmt_ip=""
	# Get the management information from the nimclient (NIM DB) output
	NIM_OUT=`$NIMCLIENT -l -Fl $NIM_NAME 2>/dev/null`

	# Obtain the management server attributes 
	# -- (used by update_live_update_data)
	typeset mgmt_object=`echo "${NIM_OUT}" | $GREP "mgmt_profile1 " | $AWK '{print $3}'`

	# Sample output:
	# type=hmc,ip=9.3.78.106,passwd_file=<path/to/file>:type=lpar,identity=5:type=cec,serial=9117-570*103061E:
	typeset output=`echo "${NIM_OUT}" | $GREP "default_profile " | $AWK '{print $3}'`

	mgmt_ip=`echo $output | $CUT -d, -f2 | $CUT -d= -f2`
	if [[ -z $mgmt_ip ]]; then
		#
		# 0042-051 <c_cust_lku>: unable to resolve "<$NIM_NAME>"
		# 	to an <hmc>
		#
		error ${ERR_IP_RESOLVE} $NIM_NAME "hmc"
	fi

	# if we get this far, then determine the management type
	# set the global variables (as necessary)
	if [[ $( echo $output | ${GREP} "type=powervc" >/dev/null 2>&1; echo $? ) -eq 0 ]]; then
		pvc=$mgmt_ip
		user=`$NIMCLIENT -l -a login $mgmt_object | $AWK '(NR==2) {print $3}'`
		project=`$NIMCLIENT -l -a project $mgmt_object | $AWK '(NR==2) {print $3}'`
	else
		hmc=$mgmt_ip
	fi

	return 0
}

#---------------------------- get_res_mnt ----------------------------
#
# NAME: get_res_mnt
#
# FUNCTION:	Get the resource attributes (for passing to nimhttp or nim_mount)
#            
#
# EXECUTION ENVIRONMENT:
#
# NOTES:	calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#       parameters:
#       global:
#
# RETURNS:
#
# OUTPUT:
#-------------------------------------------------------------------------------
function get_res_mnt {

	typeset restype=$1
	typeset resname=$2
	typeset return_val=""

	if [[ -n $restype ]] && [[ -n $resname ]]; then
		nim_server=`${NIMCLIENT}   -l -a server   $resname    2>/dev/null | ${AWK} '/server = / {print $3}'`
		nim_location=`${NIMCLIENT} -l -a location $resname    2>/dev/null | ${AWK} '/location = / {print $3}'`
		if [[ $nim_server == "master" ]]; then
			nim_hostname=$NIM_MASTER_HOSTNAME
		else
			nim_hostname=`${NIMCLIENT} -l -a if1  $nim_server 2>/dev/null | ${AWK} '{if (NR!=1) print $4}'`
		fi

		[[ -n $nim_hostname ]] && [[ -n nim_location ]] && \
			return_val="${nim_hostname}:${nim_location}"
	fi

	echo $return_val

} # end get_res_mnt

#---------------------------- cleanup_lku ----------------------------
#
# NAME: cleanup_lku
#
# FUNCTION:	Restore back_lvdata before the call to the generic cleanup
#		function to make sure everything gets unmounted.
#
# EXECUTION ENVIRONMENT:
#
# NOTES:	calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#       parameters:
#       global:
#
# RETURNS:
#
# OUTPUT:
#-------------------------------------------------------------------------------
function cleanup_lku {

	# restore back_lvdata created in prep_live_update_data
	if [[ -n ${back_lvdata} ]]; then
		${MV} $back_lvdata $lvdata 2>${ERR} || warning_from_cmd "${MV} $back_lvdata $lvdata"
	fi

	# Call c_sh_lib cleanup
	cleanup

} # end cleanup_lku

#---------------------------- get_alloc_res ----------------------------
#
# NAME: get_alloc_res
#
# FUNCTION:     Get the name of the NIM resource type allocated to the NIM client
#
# EXECUTION ENVIRONMENT:
#
# NOTES: 
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#               parameters:
#			restype = the NIM resource type
#               global:
#
# RETURNS: (string)
#               NIM resource or empty string
#
# OUTPUT:
#-------------------------------------------------------------------------------
function get_alloc_res {

	typeset restype=$1

	$NIMCLIENT -l -a $restype $NIM_NAME 2>/dev/null | $GREP "$restype =" | $AWK '{print $3}'
}

#---------------------------- validate_res ----------------------------
#
# NAME: validate_res
#
# FUNCTION:     Check resource to ensure one resource type can only be allocated
#
# EXECUTION ENVIRONMENT:
#
# NOTES:	calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#               parameters:
#			res_type  = the NIM resource type
#			res_cmd   = the resource passed in with the command line
#			res_alloc = the resource allocated to the client (get_alloc_res)
#               global:
#
# RETURNS: (string)
#               0       = NIM resource or empty string
#
# OUTPUT:
#-------------------------------------------------------------------------------
function validate_res {

	typeset res_type="${1}"
        typeset res_cmd="${2}"
	typeset res_alloc="${3}"

        if [[ -n $res_alloc ]] && 
	   [[ -n $res_cmd   ]] &&
	   [[ "${res_alloc}" != "${res_cmd}" ]]; then
		#
                # 0042-271 <c_cust_lku>:  A resource matching the type of "<$res_type>"
                #       is already allocated to "<$NIM_NAME>".  You cannot allocate
                #       more than one resource of this type to a machine.
		#
                error ${ERR_ONLY_1_RES_OF_THIS_TYPE} $res_type $NIM_NAME
        fi

	return 0
}

#---------------------------- ck_attrs ----------------------------
#
# NAME: ck_attrs
#
# FUNCTION: Check attributes
#
# EXECUTION ENVIRONMENT:
#
# NOTES:	calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#               parameters:
#               global:
#                       lpp_source      = source device name
#
# RETURNS: (int)
#               0                       = success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function ck_attrs {

	# Can only execute on NIM standalone
	if [[ $NIM_CONFIGURATION != "standalone" ]]; then
		#
		# 0042-025 <c_cust_lku>: the "<live_update>" operation cannot be applied to
		#	"<$NIM_CONFIGURATION>" types
		#
		error ${ERR_OP_NOT_ALLOWED} "live_update" $NIM_CONFIGURATION
	fi

	# See if the client was allocated NIM resources
	typeset temp_lpp=`get_alloc_res "lpp_source"`
	typeset temp_ibd=`get_alloc_res "installp_bundle"`
	typeset temp_fbd=`get_alloc_res "fix_bundle"`
	typeset temp_lvu=`get_alloc_res "live_update_data"`
	typeset temp_scr=`get_alloc_res "script"`

	# Make sure we don't get more than one resource of the same type
	validate_res "lpp_source"       "${lpp_source}"       "${temp_lpp}"
	validate_res "installp_bundle"  "${installp_bundle}"  "${temp_ibd}"
	validate_res "fix_bundle"       "${fix_bundle}"       "${temp_fbd}"
	validate_res "live_update_data" "${live_update_data}" "${temp_lvu}"
	validate_res "script"           "${script}"           "${temp_scr}"

	[[ -z $lpp_source       ]] && lpp_source=$temp_lpp
	[[ -z $installp_bundle  ]] && installp_bundle=$temp_ibd
	[[ -z $fix_bundle       ]] && fix_bundle=$temp_fbd
	[[ -z $live_update_data ]] && live_update_data=$temp_lvu
	[[ -z $script           ]] && script=$temp_scr

	# resources are not needed with preview flag
	if [[ -z $P_FLAG ]] && [[ -z $lpp_source ]]; then
		#
		# 0042-021 <c_cust_lku: the "<lpp_source>" attribute is required for this
		# 	operation
		#
		error ${ERR_MISSING_ATTR} "lpp_source"
	fi

} # end of ck_attrs

#
# This function returns a string delimited by "|" for the
# if attribute for a NIM client.
# example output:
#      <if_name>|<netname>|<hostname>|<macaddr>|<adapter>
#      if2|ent-Network4|apu02_priv|5E150A4EE002|ent0
#
function get_nim_if_output {
	typeset client=$1

	for j in `$NIMCLIENT -l -a if $client 2>/dev/null | $AWK '{if (NR > 1) {print $1"|"$3"|"$4"|"$5"|"$6}}'`; do
		if_name=`echo $j | $CUT -d'|' -f1`
		netname=`echo $j | $CUT -d'|' -f2`
		hostval=`echo $j | $CUT -d'|' -f3`
		macaddr=`echo $j | $CUT -d'|' -f4 | $TR '[:lower:]' '[:upper:]'`
		adapter=`echo $j | $CUT -d'|' -f5`
		if [[ $macaddr != "0" ]]; then
			echo "$if_name|$netname|$hostval|$macaddr|$adapter"
		fi
	done
}

#
# This function returns a string delimited by "|" for the
# network adapter and its IP information from parsing the
# "netstat -in" output.
# example output:
#      en0|5e.15.a.4e.e0.2|9.3.78.35
#      en1|5e.15.a.4e.e0.4|10.0.0.35
#
function get_netstat_in {
	set -A idevices
	for line in `/usr/bin/netstat -in | \
		$AWK 'BEGIN { contvar=0 }
		     { if (NR > 0) {
			if (contvar == 1 && match($1, interface)) {
				ipaddr=$4
				print interface "|" macaddr "|" ipaddr;
				contvar=0
				continue
			}

			if ( match($1, /en[0-9]/) ) {
				interface=$1;
				if (match($4, /[a-z0-9]{1,2}\.[a-z0-9]{1,2}\.[a-z0-9]{1,2}\.[a-z0-9]{1,2}/)) {
					macaddr=$4;
					contvar=1
				} else if (contvar == 0 && match($3, /::/)) {
					macaddr=$3
					print interface "|" macaddr "|" macaddr;
				}
			}
		     } }'`; do
		echo "$line"
	done
}

#
# This function converts a colon separated mac address to
# a form where the colons are removed. Single value in the
# colon separted field will be appended with a 0.  The
# mac address will be returned uppercase.
#
# example:
# "5e.15.5.45.ea.2" => 5E150545EA02
#
function convert_mac {
	typeset macaddr=$1
	typeset version=$2
	typeset newmac=""

	if [[ $version = "ipv6" ]]; then
		newmac=$macaddr
	else
		for i in $(echo $macaddr | $SED "s/\./ /g"); do
			if [[ ${#i} -eq 1 ]]; then
				newmac="${newmac}0${i}"
			else
				newmac=${newmac}${i}
			fi
		done
	fi
	echo $newmac | $TR '[:lower:]' '[:upper:]'
}

#
# This function calls get_nim_if_output to get its output for a NIM client.
# The function then calls get_netstat_in to get its output for the client's.
# The two outputs are compared for matching hostname and the mac address
# for the NIM client would be updated to match the mac address from get_netstat_in
#
function change_mac {
	typeset client=$1
	typeset nim_out=`get_nim_if_output $client`
	typeset net_out=`get_netstat_in`

	# Parse the "if" attribute for the NIM client
	for line in `echo ${nim_out}`; do
		# get the host name from the if output
		if_name=`echo $line | $CUT -d"|" -f1`
		netname=`echo $line | $CUT -d"|" -f2`
		hostval=`echo $line | $CUT -d"|" -f3`
		macaddr=`echo $line | $CUT -d"|" -f4`
		adapter=`echo $line | $CUT -d"|" -f5`

		# Get the IP from hostval
		hostip=`/usr/bin/host $hostval 2>/dev/null | $AWK '{print $3}' | $SED 's/,//g'`
		[[ -z $hostip ]] && continue

		# Find the line from net_out that matches the hostip
		newline=`echo "${net_out}" | $GREP $hostip`

		# Get the mac address matching the hostip
		mac=`echo $newline | $CUT -d"|" -f2`
		[[ -z $mac ]] && continue
		mac=`convert_mac $mac`

		change_val="${netname} ${hostval} ${mac}"
		if [[ -n $adapter ]]; then
			change_val="${change_val} ${adapter}"
		fi

		if [[ $macaddr != $mac ]]; then
			$NIMCLIENT -o change -a ${if_name}="${change_val}" 2>/dev/null
		fi
	done
}

#*---------------------------- c_cust_lku ----------------------------
#
# NAME: c_cust_lku
#
# FUNCTION:
#		mount remote resources, then calls geninstall for live update
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#
# RETURNS: (int)
#		0	= no errors
#		>0	= failure
#
# OUTPUT:
#-----------------------------------------------------------------------------*/

# global setting for error handling
export CALLED_FROM_NIMCLIENT_LKU=yes

# signal processing
trap cleanup_lku 0 1 2 11 15
trap err_signal 1 2 11 15

# NIM initialization
nim_init

# initialize local variables
typeset c=""

# set parameters from command line
while getopts :a:qv c; do
	case ${c} in
		a)	# parse the arguments
			# is it in the correct format (<var>=<value>)?
			if [[ "${OPTARG}" != +(?)=+(?) ]]; then
				#
				# 0042-023 <c_cust_lku>: "<$1>" is not a valid <attribute assignment>
				#
				error ${ERR_VALUE} "${1}" "attribute assignment"
			fi

			# separate variable from value
			# NOTE that we must be careful here as the "value" may have "=" chars in it
			variable=${OPTARG%%=*}
			value=${OPTARG#*=}

			# include the assignment for use in this environment
			eval ${variable}=\"${value}\" || error "unable to make assignment for: ${OPTARG}"
			;;

		q)	# show attr info
			cmd_what
			exit 0
			;;

		v)	# verbose mode (for debugging)
			VERBOSE=-v
			set -x
			for i in $(typeset +f); do
				typeset -ft $i
			done
			;;

		\?)	# unknown option
			#
			# 0042-016 <c_cust_lku>: "-<$c>" is not a valid option for this
			# operation
			# 	<$OPTARG>
			#
			error ${ERR_BAD_OPT} ${OPTARG}
			;;
	esac
done

ck_attrs

# The following information is passed as attributes
[[ ${show_progress} = yes ]] && export NIM_SHOW_PROGRESS=yes

# set defaults
[[ -n ${installp_flags} ]] && installp_flags=$( ck_installp_flags "${installp_flags}" )

# set geninstall_cmd for live update "-k"
set_geninst ${installp_flags}
geninstall_cmd="${geninstall_cmd} ${VERBOSE:+-D} -k -Y"

# The -e flag (for specifying an alternate log file)
E_FLAG="-e ${INSTALLP_LOG}"

# mount lpp_source
prep_lpp_source

# mount, update live_update_data
prep_live_update_data

# mount installp_bundle
prep_bnd "installp_bundle" $installp_bundle  && filesets="-f ${bundle_access}"

# use fix_bundle? 
if [[ -z $filesets ]]; then

	if [[ "${fixes}" = "update_all" ]]; then
		# pass update_all keyword as the install list (live_update)
		filesets="${fixes}"
	else
		prep_bnd "fix_bundle" "$fix_bundle"

		if [[ $? -eq 0 ]]; then
			# convert list of fix keywords to list of filesets
			prep_instfix_lst "client" "bun" "${bundle_access}" "${lpp_source}"
			if [[ $? -ne 0 ]]; then
				#
				# 0042-450 <c_cust_lku>: The command "instfix" failed (rc=$rc).
			       	#
				error ${ERR_OVF_RUNCMD} "instfix" "$rc"
			fi
			filesets="-f ${fileset_list}"
		fi
	fi

# use fixes? 
elif [[ -n "${fixes}" ]]; then
	# "update_all" keyword specified?
	if [[ "${fixes}" = "update_all" ]]; then
		# pass update_all keyword as the install list (live_update)
		filesets="${fixes}"

	else
		# convert list of fix keywords to list of filesets
	        prep_instfix_lst "client" "fixes" "${fixes}" "${lpp_source}"
		if [[ $? -ne 0 ]]; then
			#
			# 0042-450 <c_cust_lku>: The command "instfix" failed (rc=$rc).
			#
			error ${ERR_OVF_RUNCMD} "instfix" "$rc"
		fi

		filesets="-f ${fileset_list}"
	fi
fi

if [[ ${installp_flags} = *u* ]] || [[ ${installp_flags} = *r* ]]; then
	# this is a deinstall operation: filesets must be specified

	#
	# 0042-021 <c_cust_lku>: the "<fileset>" attribute is required for this
	# 	operation
	#
	[[ -z "${filesets}" ]] && error ${ERR_MISSING_ATTR} filesets

elif [[ ${installp_flags} != *C* ]]; then
	# this is an install operation: use default if filesets not specified
	filesets=${filesets:-${DEFAULT_INSTALLP_OPTIONS}}
fi

if [[ -n "${fixes}" ]] || [[ -n "${fix_bundle}" ]]; then
	# if not doing an update_all, add B flag for safety 
	# (so that base levels are not accidently instld via requisites)
	if [[ "${fixes}" != "update_all" ]] && [[ "${installp_flags}" != *B* ]]; then
		installp_flags=${installp_flags}B
	fi
fi

# Execute the live update script, with the request to show output, 
# execute the script appropriately.
${C_TIME_STAMP} >> ${SCRIPT_LOG}

if [[ ${NIM_SHOW_PROGRESS} = yes ]]
then
	# run the command sending all output to log AND to
	# screen (stdout)
	# NOTE: Since we are piping output to "tee", we
	#       resort to sending the return code from the
	#       command to a file in a sub-shell then
	#       retrieving it for use later on.
	# run the live update operation
	(
	${geninstall_cmd} ${installp_flags:+-I "$installp_flags"} $E_FLAG \
			  ${lpp_source} ${filesets}
	echo $? > ${TMPDIR}/_luscript.rc
	) 2>&1 | ${TEE} -a ${SCRIPT_LOG}
	rc=`${CAT} ${TMPDIR}/_luscript.rc`
	${RM} ${TMPDIR}/_luscript.rc
else
	${geninstall_cmd} ${installp_flags:+-I "$installp_flags"} $E_FLAG \
			  ${lpp_source} ${filesets} >> ${SCRIPT_LOG} 2>&1
	rc=$?
fi
${C_TIME_STAMP} -e >> ${SCRIPT_LOG}

# set variable so that errors are appended to err_info attribute on the client object.
export UPDT_CL_ERR_INFO=yes

if [[ ${async} = yes ]]; then
        # Processing the target asynchronously.

        # Inform the waiting master we've kicked
        # off the geninstall operation.
        if [[ $rc -ne 0 ]]; then
                ${NIMCLIENT} -R failure

                # used by error function
                instp_err_log=${INSTALLP_LOG}
                err_from_cmd ${INSTALLP}
        fi
        ${NIMCLIENT} -R success
fi

# perform a script customization (if required)
if [[ $rc -eq 0 ]] && [[ -n ${script} ]]; then
	script_location=`get_res_mnt "script" $script` 
	${C_SCRIPT} ${VERBOSE} \
		-a location=${script_location} 2>&1
	rc=$?
fi

if [[ $rc -ne 0 ]]; then
	${NIMCLIENT} -R failure

	# used by error function 
	instp_err_log=${INSTALLP_LOG}
	err_from_cmd ${INSTALLP}	
fi

# update state on master if necessary
${NIMCLIENT} -R success

if [[ $rc -eq 0 ]] && [[ -n $NIM_OUT ]]; then
	mgmt_profile=`echo "${NIM_OUT}" | $GREP mgmt_profile1 | $AWK -F' = ' '{print $2}'`
	lpar_id=`$UNAME -Ls | $AWK '{print $2}'`
	mgmt_profile_new=`echo "$mgmt_profile" | $AWK -v lpar_id=$lpar_id '{$2=lpar_id; print}'`
	$NIMCLIENT -o change -a mgmt_profile1="$mgmt_profile_new" 2>/dev/null

	change_mac $NIM_NAME
fi

# success
exit 0
