#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/lib/nim/methods/c_cfgadptrs.sh 1.17 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2002,2009 
# 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 
# @(#)71 1.17 src/bos/usr/lib/nim/methods/c_cfgadptrs.sh, cmdnim, bos720 3/19/09 13:38:13

#   COMPONENT_NAME: CMDNIM
#
#   FUNCTIONS: ./usr/lib/nim/methods/c_cfgadptrs.sh, mktcpip2.sh
#		
#
#   ORIGINS: 27
#
#


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

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

#---------------------------- module globals    --------------------------------
REQUIRED_ATTRS="location"
OPTIONAL_ATTRS="name"
location=""
name=""

# 
# FUNCTION: mktcpip2
#
# FUNCTION DESCRIPTION: High-level shell command for performing minimal
#   configuration of a secondary network adapter
#
#   Basic functions performed are:
#   1)  If the optional hostname is entered, it is set in /etc/hosts
#   2)  the IP address of the interface is set in the config database.
#   3)  /etc/hosts entries made for hostname and IP address
#   removed 4)  the IP address of the nameserver and domain name are set
#   5)  the subnet mask is set
#   removed 6)  destination and gateway routes are set
#   removed 7)  TCP/IP deamons started
#       or
#   8)  Retrieve the above information for SMIT display 
#   9)  the cable type (N/A, bnc, dix or tp) is set in database
#  10)  the media_speed (e.g. Auto_Negotiation or 1000_Full_Duplex) is set in database
#  11)  Apply the attributes parameter, if any
#
#   See Usage message for explanation of parms
#
#
# RETURN VALUE DESCRIPTION: 
#                             0         Successful
#                             non-zero  Unsuccessful
# 
#
# EXTERNAL PROCEDURES CALLED: chdev, hostent, lsdev, mkdev
#
#
# GLOBAL VARIABLES: none
#

################################# usage #######################################
#
# NAME: mktcpip2_usage()
#
# DESCRIPTION: Issue "usage" message and return.
#
# INPUT: 
#        None
#
# OUTPUT:
#        Error messages (Standard Error)
#
# RETURN VALUE DESCRIPTION:
#                           2
#
# NOTE: This function will not return (i.e., it will return the entire
#       script with status of 2).
#

mktcpip2_usage(){
   msg=`/usr/bin/dspcat mktcpip.cat 1 1 2>/dev/null`
   /usr/bin/cat <<- HERE >&2
   Usage:  $NAME {-S interface | -a address -i interface
               [-h hostname ]
               [-m subnet_mask] 
               [-t cable_type] [-r ring_speed]
	       [-A attrbutes 
               [-x media_speed]}

   -h hostname            optional hostname for secondary IP address
   -a address             IP address of the interface specified by -i
                          (must be in dotted decimal notation)
   -i interface           Interface to associate with the -a IP address
   -m subnet_mask         Subnetwork mask (dotted decimal or 0x notation)
                          (dotted decimal or symbolic name)
   -t cable_type	  Cable type for ethernet, either 'bnc', 'dix', 'tp'
                          or 'N/A'
   -r ring_speed          Ring speed for token ring adapter, either 4 or 16
   -S interface           Retrieve information for SMIT display
   -A attributes	  list of attributes for ethernet or multilink
   -x media_speed         media_speed for ethernet (e.g. Auto_Negotiation or
                          1000_Full_Duplex)

   Example: $NAME -h fred.austin.ibm.com -a 192.9.200.9 -i en1 

HERE
   return 2			# don't return
}

############################# mandatory #######################################
#
# NAME: mktcpip2_mandatory()
#
# DESCRIPTION: Issue "mandatory" message and invoke "usage" function.
#
# INPUT: 
#        None
#
# OUTPUT:
#        Error messages (Standard Error)
#
# RETURN VALUE DESCRIPTION:
#                           None
#
mktcpip2_mandatory(){
   msg=`/usr/bin/dspcat mktcpip.cat 1 2 2>/dev/null`
   if [ -n "$msg" ]
   then
       /usr/bin/dspcat mktcpip.cat 1 2 >&2
   else
       echo "$NAME: Mandatory flag(s) missing" >&2
   fi
   mktcpip2_usage			# issue msg and don't return
   return 2
}

############################## problem ########################################
#
# NAME: mktcpip2_problem()
#
# DESCRIPTION: Issue "problem" message and return
#
# INPUT: 
#        $RTNCODE
#        $1		Name of command that encountered an error
#
# OUTPUT:
#        Error messages (Standard Error)
#
# RETURN VALUE DESCRIPTION:
#                           $RTNCODE
#
#
problem(){
   msg=`/usr/bin/dspcat mktcpip.cat 1 3 2>/dev/null`
   if [ -n "$msg" ]
   then
       /usr/bin/dspcat mktcpip.cat 1 3 >&2
       echo $1
       /usr/bin/dspcat mktcpip.cat 1 4 >&2
       echo $RTNCODE
   else
       echo "$NAME: Problem with command: $1, return code = $RTNCODE" >&2
   fi
   return $RTNCODE			# don't return
}

############################### dotted ########################################
#
# NAME: dotted()
#
# DESCRIPTION: Perform rudimentary check of IP address to see if composed
#              of dots and numbers.  Will issue error message and invoke
#              usage function if error detected.
#
# INPUT: 
#        $1, IP Address
#
# OUTPUT:
#        Error messages (Standard Error).  If error detected.
#
# RETURN VALUE DESCRIPTION:
#                           0     (Successful)
#                           None  (Will invoke usage function if error)
#
mktcpip2_dotted(){
# compare number chars to number of "decimal and 0-9" characters
if [ "`${EXPR} $1 : '.*'`" -ne "`${EXPR} $1 : '[.0-9]*'`" ] ; then
   msg=`/usr/bin/dspcat mktcpip.cat 1 5 2>/dev/null`
   if [ -n "$msg" ]
   then
       /usr/bin/dspcat mktcpip.cat 1 5 >&2
       echo $1
   else
       echo "$NAME: IP address not in dotted decimal notation, $i" >&2
   fi
   mktcpip2_usage			# issue message and don't return
   return 2
fi
}

############################## mktcpip2 ############################################

mktcpip2(){

PATH=/bin:/usr/bin:/usr/sbin:/etc:/usr/ucb export PATH

NAME=mktcpip2

# Parse command flags and arguments
set -- `/usr/bin/getopt h:a:i:m:t:r:S:A:x: $*`
if [ $? != 0 ] ; then		# test for syntax error
   mktcpip2_usage			# issue msg and don't return
fi

#if [ $# -lt 3 ] ; then		# test for too few parms
#   mandatory			# issue msg and don't return
#fi

HOSTNAME= IPADDRESS= INTERFACE= SUBNETMASK= NETMASK= SHOW= TYPE= RING= MEDIASPEED=

while [ "$1" != "--" ]
do
   case $1 in
      -h)
	 unset HOSTNAME
	 HOSTNAME=$2 shift 2
      ;;
      -a)
	 unset IPADDRESS
	 IPADDRESS=$2 shift 2
      ;;
      -i)
	 unset INTERFACE
	 INTERFACE=$2 shift 2
	 echo "$INTERFACE"
      ;;
      -m)
	 unset SUBNETMASK
	 SUBNETMASK=" -a netmask=$2"
	 NETMASK=$2 shift 2
      ;;
      -t)
	 unset TYPE
	 TYPE=$2 shift 2
      ;;
      -r)
	 unset RING
	 RING=$2 shift 2
      ;;
      -S)
	 unset SHOW
	 SHOW=$2 shift 2
      ;;
      -A)
	 unset ATTRIBUTES
	 ATTRIBUTES=$2 shift 2
      ;;
      -x)
         unset MEDIASPEED 
         MEDIASPEED=$2 shift 2
      ;;
      *)
	 mktcpip2_usage				# shouldn't ever hit this
      ;;
   esac
done

if [ $# -gt 1 ] ; then			# see if extra parms specified
   msg=`/usr/bin/dspcat mktcpip.cat 1 6 2>/dev/null`
   if [ -n "$msg" ]
   then
       /usr/bin/dspcat mktcpip.cat 1 6 >&2
   else
       echo "$NAME: Too many flags" >&2
   fi
   mktcpip2_usage				# issue msg and don't return
fi

if [ "$SHOW" != "" ] ; then
   # Find whether the interface is for Ethernet, Token ring or else ..
   SHW=`echo $SHOW | ${CUT} -c1-2`
   # get the hostname
   HOST=`/usr/bin/hostname`
   # get the IPaddr and the subnetmask
   ADDR=`${LSATTR} -E -l $SHOW -F "value" -a netaddr`
	
# Comment out the channel adapter stuff
   # Channel adapter needs netmask for real world
   #if [ "$SHW" != ca ]; then
       # no netmask for 370 channel
       MASK=`${LSATTR} -E -l $SHOW -F "value" -a netmask`
   #fi

   # we don't want rc.tcpip started again accidentally
   START="no"
   if [ "$SHW" = tr ]; then
        INT=`echo $SHOW | ${CUT} -c3-4`
        SPEED=`${LSATTR} -E -l tok$INT -F "value" -a ring_speed`
        # print all of the requested information in command to discover format
        echo "#host:addr:mask:_rawname:speed" >&2
        echo "$HOST:$ADDR:$MASK:$SHOW:$SPEED" >&2
        return 0
   fi
   if [ "$SHW" = en -o "$SHW" = et ]; then
   	# get the value of 'bnc_select' attribute
   	INT=`echo $SHOW | ${CUT} -c3-4`       
   	${LSATTR} -E -l ent$INT | ${GREP} bnc_select > /dev/null 2>&1
	RTNCODE=$?
  	if [ $RTNCODE -ne 0 ]; then
		CABLE="N/A"
	else
		CABLE=`${LSATTR} -E -l ent$INT -F "value" -a bnc_select` 
	fi
   	${LSATTR} -E -l ent$INT | ${GREP} media_speed > /dev/null 2>&1
	RTNCODE=$?
  	if [ $RTNCODE -ne 0 ]; then
		MEDIASPEED=
	else
		MEDIASPEED=`${LSATTR} -E -l ent$INT -F "value" -a media_speed` 
	fi
        # print all of the requested information in command to discover format
        echo "#host:addr:mask:_rawname:type:media_speed" >&2
        echo "$HOST:$ADDR:$MASK:$SHOW:$CABLE:$MEDIASPEED" >&2
        return 0
   fi
   if [ "$SHW" = ml ]; then
   	INT=`echo $SHOW | ${CUT} -c3-4`       
        # print all of the requested information in command to discover format
        echo "#host:addr:mask:_rawname" >&2
        echo "$HOST:$ADDR:$MASK:$SHOW" >&2
	return 0
   fi
   # print all of the requested information in command to discover format
   echo "#host:addr:mask:_rawname" >&2
   echo "$HOST:$ADDR:$MASK:$SHOW" >&2
   return 0
fi

SHW=`echo $INTERFACE | ${CUT} -c1-2`	#to get first two letters, ex. en, et..
INT=`echo $INTERFACE | ${CUT} -c3-4`	#to get last digits in interface.

# See if mandatory parms were specified
# Comment out required hostname
#if [ "$HOSTNAME" = "" -o "$IPADDRESS" = "" -o "$INTERFACE" = "" ] ; then
if [ "$IPADDRESS" = "" -o "$INTERFACE" = "" ] ; then
   mktcpip2_mandatory
   return 2
fi

# REMOVE channel adapter stuff

# REMOVE gateway stuff

mktcpip2_dotted $IPADDRESS		# rudimentary check on address
rc=$?
if [[ $rc -ne 0 ]]; then
    return 2
fi

# REMOVE DOMAIN AND NAMESERVER checks

# Save off current umask and set it to 022 so that any creation
# of the files /etc/resolv.conf or /etc/hosts by namerslv or hostent
# will have the correct 644 permissions.
UMASKSAVE=`umask`
umask 022

# If there is a new HOSTNAME try to put it in /etc/hosts.  Otherwise,
# do not touch /etc/hosts
if [[ -n $HOSTNAME ]]; then
	# Make entry in local /etc/hosts
	# Make sure that /etc/hosts exists
	if [ ! -f /etc/hosts ]; then
		/usr/bin/touch /etc/hosts
	fi
	# Make sure that the address isn't commented out
	${GREP} -F -w "$IPADDRESS" /etc/hosts | ${GREP} -v ".*#.*$IPADDRESS" > /dev/null 2>&1
	RTNCODE=$?
	# If new IP address is in /etc/hosts file then add the new hostname as an alias
	# Else enter the IP address and hostname as new entry in /etc/hosts file.
	if [ $RTNCODE -eq 0 ]; then
        	ONAMES=`${GREP} -F -w "$IPADDRESS" /etc/hosts | \
               		${GREP} -v ".*#.*$IPADDRESS" | \
               		${AWK} '{for(i=2;i<=NF;i++)
                         if(substr($i,1,1)=="#")
                           break;
                         else
                           printf("%s ",$i) }'`
        	# if new hostname is anywhere on old entry, don't add it
        	DONTADD=0
        	for i in $ONAMES
          	do
            		if [ $HOSTNAME = $i ]; then
              			DONTADD=1
            		fi
          	done
        	if [ $DONTADD -eq 0 ]; then
                	/usr/bin/hostent -c "$IPADDRESS" -h "$ONAMES $HOSTNAME"
			RTNCODE=$?
                        if [ $RTNCODE -ne 0 ]; then
	                    problem chdev
	                    return 2
                        fi
		fi
	else
		/usr/bin/hostent -a "$IPADDRESS" -h "$HOSTNAME"
		RTNCODE=$?
                if [ $RTNCODE -ne 0 ]; then
	            problem chdev
	            return 2
                fi
	fi
fi
# REMOVE Set hostname in the running system

# REMOVE Set hostid  of  the running system

# REMOVE Set uname of the running system

# REMOVE Set hostname and IP addr in config DB

# REMOVE token-ring support for Ring Speed

# Support Attributes field.  Do not set attribute if the requested value is equal
# to the current value.
set_attrs=
# Is there an input attributes field?
if [ -n "$ATTRIBUTES" ]; then
	ATTRIBUTES=$( echo $ATTRIBUTES | ${CUT} -f2 -d'"' )
	ATTRIBUTES=$( echo $ATTRIBUTES | ${SED} 's/|/ /g' )
	ATTRIBUTES=$( echo $ATTRIBUTES | ${SED} s/-a//g )
	while [[ -n $ATTRIBUTES ]]
	do
		ATTR=
		VALUE=
		ATTR=$( echo $ATTRIBUTES | ${CUT} -f1 -d'=' )
		ATTRIBUTES=${ATTRIBUTES#*=}
		if [[ -n $ATTRIBUTES ]]; then
			VALUE=$( echo $ATTRIBUTES | ${CUT} -f1 -d' ' )
		fi
		[[ $VALUE = $ATTRIBUTES ]] && ATTRIBUTES= \
			|| ATTRIBUTES=${ATTRIBUTES#*[ ]}
		if [[ -n $ATTR ]]; then
			CUR_VALUE=$( ${LSATTR} -E -a $ATTR -F value -l $INTERFACE 2>/dev/null )
			rc="$?"
			if [[ $rc -eq 0 ]]; then
				if [[ $VALUE != $CUR_VALUE ]]; then
					set_attrs="$set_attrs -a $ATTR=$VALUE"
				fi
			else
				if [[ $SHW = 'sn' ]]; then
					set_attrs="$set_attrs -a $ATTR=$VALUE"
				fi
			fi
		fi
	done
fi

# Handle Ethernet case
if [ "$SHW" = en -o "$SHW" = et ]; then
	set_media_speed= set_bnc_select=
	# Is there an input media_speed?
	if [ -n "$MEDIASPEED" ]; then
		# If so, is it different from the current setting?
   		${LSATTR} -E -l ent$INT | ${GREP} media_speed > /dev/null 2>&1
		RTNCODE=$?
  		if [ $RTNCODE -eq 0 ]; then
			curspeed=$( ${LSATTR} -E -l ent$INT -a media_speed -F value )         
			if [ "$curspeed" != "$MEDIASPEED" ]; then
				# Is the input media_speed valid for this adapter?
				export ODMDIR=/etc/objrepos
				UTYPE=$( ${ODMGET} -q"name=ent$INT" CuDv | ${GREP} '^[ 	]*PdDvLn' )	
				UTYPE=$( echo ${UTYPE#*=} | ${CUT} -f2 -d\" )
				VALID_LIST=$( ${ODMGET} -q"attribute='media_speed' AND uniquetype=$UTYPE" PdAt | ${GREP} '^[ 	]*values' )
				VALID=$( echo ${VALID_LIST#*=} | ${CUT} -f2 -d\" | ${GREP} "$MEDIASPEED" 2>/dev/null )
				if [ -n  "$VALID" ]; then
					set_media_speed="-a media_speed=$MEDIASPEED"
				else
					#echo "media_speed=$MEDIASPEED is not valid for ent$INT\n"
					${C_ERRMSG} ${ERR_ADAPTER_INVALID_VALUE} \
						${C_ERRMSG_ERR} "${PROGNAME}" "media_speed" "$MEDIASPEED" "ent$INT"
				fi
			fi
		fi
	fi
# For Ethernet, set the Cable Type except integrated ethernet adapter
   	${LSATTR} -E -l ent$INT | ${GREP} bnc_select > /dev/null 2>&1
	RTNCODE=$?
  	if [ $RTNCODE -ne 0 ]; then
          ${LSATTR} -E -l ent$INT | ${GREP} bnc_dix_jumper > /dev/null 2>&1
          RTNCODE=$?
          if [ $RTNCODE -eq 0 ]; then
             JUMPER=no
             JUMPER=`${LSATTR} -E -l ent$INT -a bnc_dix_jumper -F value`
             if [ "$JUMPER" = "yes" ]; then
                  if [ "$TYPE" = "dix" -o "$TYPE" = "bnc" ]; then
                      msg=`/usr/bin/dspcat mktcpip.cat 1 10 2>/dev/null`
                      if [ -n "$msg" ]
                      then
                          /usr/bin/dspcat mktcpip.cat 1 10
                      else
                  echo "To select bnc or dix on the integrated ethernet adapter,
                  please change the jumper on the adapter."
		      fi
                  fi
             fi
	  fi
        else 
	  if [ "$TYPE" = "dix" -o "$TYPE" = "bnc" -o "$TYPE" = "tp" ]; then
		curbnc=`${LSATTR} -E -l ent$INT -a bnc_select -F value`
		if [ $curbnc != $TYPE ]
		then
			set_bnd_select="-a bnc_select=$TYPE"
		fi
	  else
                msg=`/usr/bin/dspcat mktcpip.cat 1 12 2>/dev/null`
                if [ -n "$msg" ]
                then
                    /usr/bin/dspcat mktcpip.cat 1 12
                else
		    echo "Select either 'bnc', 'dix' or 'tp'"
		fi
	  fi
	fi
	if [ -n "$set_media_speed" -o -n "$set_bnc_select" ]; then
		${CHDEV} -l $INTERFACE -a state=detach > /dev/null 2>&1
		/usr/sbin/rmdev -l ent$INT > /dev/null 2>&1
		eval ${CHDEV} -l ent"$INT" "$set_media_speed" "$set_bnc_select" > /dev/null 2>&1
		if [ $? != 0 ] ; then
			eval ${CHDEV} -P -l ent"$INT" "$set_media_speed" "$set_bnc_select" > /dev/null 2>&1
   	        msg=`/usr/bin/dspcat mktcpip.cat 1 11 2>/dev/null`
   	        if [ -n "$msg" ]
   	        then
   	    	    /usr/bin/dspcat mktcpip.cat 1 11
   	        else
		      	echo "Warning: Ethernet device busy. Changing ent$INT"
		       	echo "         will take effect on the next reboot."
			fi
		fi
		/usr/sbin/mkdev -l ent$INT > /dev/null 2>&1
	fi
fi

###############################################################################
# If configuring multilink or a switch adapter, use the tunchange or vmo
# command to request kernel large page space function
###############################################################################
if [[ "$SHW" = 'ml' || "$SHW" = 'sn' ]]; then
	BOSBOOT_RESPONSE=y
	LGPG_SIZE=16777216
	LGPG_REGIONS=32

	# Check to see if the vmo and tunchange commands exist
	if [[ ! -x ${VMO} ]]; then
		#echo "The vmo command is not available"
		${C_ERRMSG} ${ERR_ADAPTER_NO_CMD} \
			${C_ERRMSG_ERR} "${PROGNAME}" "${VMO}" "" ""
		return 2
	fi

	if [[ ! -x ${TUNCHANGE} ]]; then
		#echo "The tunchange command is not available"
		${C_ERRMSG} ${ERR_ADAPTER_NO_CMD} \
			${C_ERRMSG_ERR} "${PROGNAME}" "${TUNCHANGE}" "" ""
		return 2
	fi

	# Make sure pre520tune (pre-5.2 compatibility mode) is disabled
	PRE520=$( ${LSATTR} -E -l sys0 | ${GREP} pre520tune | ${AWK} '{ print $2 }' )
	if [[ $PRE520 = 'enable' ]]; then
		${CHDEV} -l sys0 -a pre520tune=disable
	fi

	# If we are doing a BOS Install, use tunchange command to tune variables
	if [[ -n "$INUBOSTYPE" ]]; then
		# Need to set phase variable between bos.perf.tune install and tunrestore in
		# inittab
		/usr/lib/perf/set_phase 1
                if [[ -n $bos_preconfig ]]; then
			SET_TUNABLE=yes
			bos_preconfig=`echo ${bos_preconfig} | ${AWK} '{sub(/^"/, "", $0); sub(/"$/, "", $0); print;}'`
                        ${bos_preconfig}
                elif [[ $SET_TUNABLE != "yes" ]]; then
			${TUNCHANGE} -f nextboot -t vmo -o v_pinshm=1 -o lgpg_size=$LGPG_SIZE \
				-o lgpg_regions=$LGPG_REGIONS
                fi
	else	
                if [[ -n $cust_preconfig ]]; then
			RUN_BOSBOOT=yes
			cust_preconfig=`echo ${cust_preconfig} | ${AWK} '{sub(/^"/, "", $0); sub(/"$/, "", $0); print;}'`
                        echo $BOSBOOT_RESPONSE | ${cust_preconfig}
			${C_ERRMSG} ${MSG_ADAPTER_REBOOT}  ${C_ERRMSG_MSG} "" "" ""
                else
			# Check for vmo change required.
			CUR_V_PINSHM=$( ${VMO} -r -a | ${GREP} v_pinshm | ${AWK} '{ print $3 }' )
			CUR_LGPG_SIZE=$( ${VMO} -r -a | ${GREP} lgpg_size | ${AWK} '{ print $3 }' )
			CUR_LGPG_REGIONS=$( ${VMO} -r -a | ${GREP} lgpg_regions | ${AWK} '{ print $3 }' )
			if [[ $CUR_V_PINSHM != 1 || $CUR_LGPG_SIZE != $LGPG_SIZE || $CUR_LGPG_REGIONS = 0 ]]; then
	
				echo $BOSBOOT_RESPONSE | ${VMO} -r -o v_pinshm=1 -o lgpg_size=$LGPG_SIZE -o lgpg_regions=$LGPG_REGIONS
				#echo "These changes will not fully take effect until after a system reboot."
				${C_ERRMSG} ${MSG_ADAPTER_REBOOT} \
					${C_ERRMSG_MSG} "" "" ""
			fi
		fi
	fi

	# Check to see if switch support is currently installed on the system
	${LSLPP} -l devices.chrp.IBM.HPS.rte >/dev/null 2>&1
	rc="$?"
	${LSLPP} -l devices.common.IBM.sni.rte >/dev/null 2>&1	
	rc2="$?"
	if [[ $rc -ne 0 || $rc2 -ne 0  ]]; then
		#echo "Switch device support is not available"
		${C_ERRMSG} ${ERR_ADAPTER_DEV_SUPPORT} \
			${C_ERRMSG_ERR} "${PROGNAME}" "switch" "" ""
		return 2
	fi
fi

CREATE_FIRSTBOOT=""
if [[ "$SHW" = ml || "$SHW" = sn ]] && [[ $CREATE_FIRSTBOOT != "yes" ]] && [[ -n "$INUBOSTYPE" ]]; then
	filename="/var/adm/ras/nim_cfgadptrs"
	/usr/bin/touch $filename
	/usr/bin/chmod +x $filename
	print "echo \"$filename 2>&1 | tee $filename.log &\" | /usr/bin/at now >/dev/null 2>&1" >> /etc/firstboot

	if [[ ${NIM_SHOW_PROGRESS} = yes ]]; then
		print "#!/usr/bin/ksh"          >> $filename
		print "set -x"                  >> $filename
		print "for i in \$(typeset +f)" >> $filename
		print "do"                      >> $filename
		print "    typeset -ft \$i"     >> $filename
		print "done"                    >> $filename
	fi

	CREATE_FIRSTBOOT="yes"
fi

# multilink
if [ "$SHW" = ml ]; then
	if [[ -n "$INUBOSTYPE" ]]; then
		print "count=0"                 >> $filename
		print "while true; do"          >> $filename
		print "    if [[ \`ODMDIR=/etc/objrepos odmget -q \"name=$INTERFACE\" CuDv | grep \"name = \\\"$INTERFACE\\\"\" >/dev/null 2>&1; echo \$?\` -eq 0 ]] || [[ \$count -gt 30 ]]; then" >> $filename
		print "        eval chdev -l \"$INTERFACE\" -a netaddr=\"$IPADDRESS\" -a netmask=\"$NETMASK\" -a state=up \"$set_attrs\" 2>&1 >/var/adm/ras/${INTERFACE}.out" >> $filename
		print "        break"           >> $filename
		print "    fi"                  >> $filename
		print "    ((count=count+1))"   >> $filename
		print "    sleep 1"             >> $filename
		print "done"                    >> $filename
	else
		print "eval chdev -l \"$INTERFACE\" -a netaddr=\"$IPADDRESS\" -a netmask=\"$NETMASK\" -a state=up \"$set_attrs\" 2>&1 >/var/adm/ras/${INTERFACE}.out" >> /etc/firstboot
	fi
# switch adapter interface
elif [ "$SHW" = sn ]; then
	if [[ -n "$INUBOSTYPE" ]]; then
		print "    eval chdev -l \"$INTERFACE\" -a netaddr=\"$IPADDRESS\" -a netmask=\"$NETMASK\" -a state=up \"$set_attrs\" 2>&1 >/var/adm/ras/${INTERFACE}.out" >> $filename
	else
		print "eval chdev -l \"$INTERFACE\" -a netaddr=\"$IPADDRESS\" -a netmask=\"$NETMASK\" -a state=up \"$set_attrs\" 2>&1 >/var/adm/ras/${INTERFACE}.out" >> /etc/firstboot
	fi
# Any other interface
else
   	eval ${CHDEV} -l "$INTERFACE" -a netaddr="$IPADDRESS" "$SUBNETMASK" -a state=up "$set_attrs"
   	RTNCODE=$?
   	if [ $RTNCODE -ne 0 ]; then
		problem chdev
   	fi
fi
	

# REMOVE Change nameserver and domain entries,

# REMOVE changing inet0 routes

# Set the umask back to the original value.
umask $UMASKSAVE

# REMOVE -- Start TCP/IP if need be
return 0

}

#####  Get Stanza Data from data file

function get_stanza_data
{
    FILENAME=$1  ## Name of stanza file
    STANZA=$2    ## Stanza Name
    ATTR="$3"    ## Field Name=
    VAL=$4       ##      Unique Field Name Value (may be null)
    RECORD=$5    ## Field Name for stanza line you seek the data from.

    if [ "$VAL" = "" ]
    then
        VAL1="$VAL"
        ${SED} '/:$/i\
' ${FILENAME} | ${GREP} -p "^"$STANZA: | \
        ${EGREP} -p "^[ 	]+$ATTR[ 	]*=[ 	]*$VAL1" |  \
        ${EGREP} "^[ 	]+$RECORD[ 	]*" | \
	${SED} -e "s/[	]*=/ =/" -e "s/ =[      ]*/ = /" | \
        ${AWK} '{ for (i = 3; i <= NF; i++)
                        { print $i } }'
    else
        VAL1=$VAL"$"
        ## fgrep added to handle . and _ characters in user data search
	## fields (VAL).
	## First grep searches for stanza types.
	## fgrep eliminates problems with . and _ characters.
	## First egrep ensures that only the specific search criteria is
	## met (eliminates preceding and trailing characters).
        ${SED} '/:$/i\
' $FILENAME | ${GREP} -p "^"$STANZA: | ${FGREP} -p -w $VAL | \
         ${EGREP} -p "^[ 	]+$ATTR[ 	]*=[ 	]*$VAL1" |  \
         ${EGREP} "^[ 	]+$RECORD[ 	]*" | \
         ${SED} -e "s/[ 	]*=/ =/" -e "s/ =[ 	]*/ = /" | \
				${AWK} 'BEGIN { ORS = "" }
					NF == 3 { print $3 }
					NF > 3  { if ($1 == "bos_preconfig" || $1=="cust_preconfig" || $1 == "route") { 
                                                     print $3
                                                     for (i = 4; i <= NF; i++) 
                                                     { printf " %s", $i }
                                                  }
                                                  else { 
                                                     print $3
						     for (i = 4; i <= NF; i++) 
						     { printf "|%s", $i }
                                                  }
                                                }'

	fi
	return 0
}

#*---------------------------- set_adapter_attrs    ----------------------------
#
# NAME: set_adapter_attrs
#
# FUNCTION:
#		sets the adapter_attributes of an adapter if they are different
#       than the current setting
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters: adapter, interface_name, adapter_attributes
#		global:
#
# RETURNS: (int)
#		0							= no errors
#		>0							= failure
#
# OUTPUT:
#-----------------------------------------------------------------------------*/
function set_adapter_attrs
{
    adapter=$1              ## Name of physical adapter
    interface_name=$2       ## Name of interface
	adapter_attributes="$3" ## List of attributes for the adapter
	set_attrs=              ## Attributes to set

	adapter_attributes=$( echo $adapter_attributes | ${CUT} -f2 -d'"' )
	adapter_attributes=$( echo $adapter_attributes | ${SED} 's/|/ /g' )
	adapter_attributes=$( echo $adapter_attributes | ${SED} s/-a//g )
	adapter_attributes=$( echo $adapter_attributes | ${SED} s/\'//g )

	while [[ -n $adapter_attributes ]]
	do
		ATTR=
		VALUE=
		CUR_VALUE=

		ATTR=$( echo $adapter_attributes | ${CUT} -f1 -d'=' )
		adapter_attributes=${adapter_attributes#*=}
		if [[ -n $adapter_attributes ]]; then
			VALUE=$( echo $adapter_attributes | ${CUT} -f1 -d' ' )
		fi
		[[ $VALUE = $adapter_attributes ]] && adapter_attributes= \
			|| adapter_attributes=${adapter_attributes#*[ ]}
		if [[ -n $ATTR ]]; then
			CUR_VALUE=$( ${LSATTR} -E -a $ATTR -F value -l $adapter 2>/dev/null )
			rc="$?"
			if [[ $rc -eq 0 ]]; then
				if [[ $VALUE != $CUR_VALUE ]]; then
					set_attrs="$set_attrs -a $ATTR=$VALUE"
				fi
			else
				#echo "warning: could not get current value of $ATTR for $adapter."
				#echo "         will attempt to set $ATTR."
				${C_ERRMSG} ${MSG_ADAPTER_GET_ATTR_VAL} \
					${C_ERRMSG_MSG} "$ATTR" "$adapter" "$ATTR" ""
				set_attrs="$set_attrs -a $ATTR=$VALUE"
			fi
		fi
	done

	# set the adapter_attributes before configuring the interface
	if [[ -n "$set_attrs" ]]; then
		${CHDEV} -l $interface_name -a state=detach > /dev/null 2>&1
		/usr/sbin/rmdev -l $adapter > /dev/null 2>&1
		eval ${CHDEV} -l $adapter "$set_attrs" > /dev/null 2>&1
		if [[ $? != 0 ]]; then
			eval ${CHDEV} -P -l $adapter "$set_attrs" > /dev/null 2>&1
			#echo "Warning: Network device busy. Changing $adapter"
			#echo "         will take effect on the next reboot."
			${C_ERRMSG} ${MSG_ADAPTER_DEV_BUSY} \
				${C_ERRMSG_MSG} "$adapter" "" "" ""
		fi

		${MKDEV} -l $adapter > /dev/null 2>&1
	fi

	return
}

#*-------------------------------- set_route ---------------------------------
#
# NAME: set_route
#
# FUNCTION:
#		add route from the route attribute
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters: route
#		global:
#
# RETURNS: (int)
#		0	= no errors
#		>0	= failure
#
# OUTPUT:
#-----------------------------------------------------------------------------*/
function set_route {

	typeset route_string=$1
	typeset route
	typeset destination
	typeset mask
	typeset gateway
	typeset -i numberfield=0
	typeset -i number=1

	numberfield=`echo $route_string | ${AWK} 'BEGIN {FS=","} {print NF}'`
	while (( $number <= $numberfield )); do
		route=`echo $route_string | ${CUT} -d, -f$number | ${SED} 's/"//g;s/^[ ]*//g;s/[ \t]]*$//g'`
		destination=`echo $route | ${AWK} 'BEGIN {FS="::"} {print $1}'`
		mask=`echo $route | ${AWK} 'BEGIN {FS="::"} {print $2}'`
		gateway=`echo $route | ${AWK} 'BEGIN {FS="::"} {print $3}'`

		if [[ -z $mask ]]; then
			${CHDEV} -l inet0 -a route=net,-hopcount,0,,,,,,$destination,$gateway
		else
			${CHDEV} -l inet0 -a route=net,-hopcount,0,-netmask,$mask,,,,,$destination,$gateway
		fi

		if [[ $? -ne 0 ]]; then
			${C_ERRMSG} ${ERR_ADD_ROUTE2} \
				${C_ERRMSG_ERR} "${PROGNAME}" "" "" ""
		fi				
		((number = $number + 1))
	done

	return 0
}

#*---------------------------- cfgnimadapters       ----------------------------
#
# NAME: cfgnimadapters
#
# FUNCTION:
#		processes the stanza file and configures the secondary adapters
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#
# RETURNS: (int)
#		0							= no errors
#		>0							= failure
#
# OUTPUT:
#-----------------------------------------------------------------------------*/
function cfgnimadapters {
	DEFIF=${SPOT}/lib/methods/defif
	[[ -x ${DEFIF} ]] || DEFIF=/usr/lib/methods/defif

	typeset stanza_file=${1}

	if [[ -z $stanza_file ]]; then
		#echo "Secondary adapter stanza file name is required."
	    ${C_ERRMSG} ${ERR_ADAPTER_MISSING_STANZA_FILE} \
			${C_ERRMSG_ERR} "${PROGNAME}" "" "" ""
		return 1
	fi

	# Next, find the ip address for this hostname from $NIM_HOSTS
	# Blank separated list of netaddr:netname pairs
	nim_ip_addr=
	OIFS="$IFS"
	for host_args in ${NIM_HOSTS}
	do
		IFS=':'
		set -- ${host_args}
		IFS="$OIFS"
		if [[ "${2}" = "$NIM_HOSTNAME" ]]; then
			nim_ip_addr="${1}"
			break
		fi
	done
	if [[ -z $nim_ip_addr ]]; then
		#echo "Could not determine NIM client ip_address"
	    ${C_ERRMSG} ${ERR_ADAPTER_DETERMINE_IP} \
			${C_ERRMSG_ERR} "${PROGNAME}" "" "" ""
		return 1
	fi

	# Get the NIM network interface name based on the ip address
	ODMDIR=/etc/objrepos nim_iname=$( ${ODMGET} -q"attribute=netaddr AND value=$nim_ip_addr" \
		CuAt | ${GREP} '^[ 	]*name' )
	nim_iname=$( echo ${nim_iname#*=} | ${CUT} -f2 -d\" )

	# Get the adapter name and physical location corresponding
	# to the NIM interface name (ethernet case only?)
	echo $nim_iname | ${GREP} -q "^e[nt]"
	if [[ $? -eq 0 ]]; then
		int=$( echo $nim_iname | ${CUT} -c3-4 )
		nim_aname=ent$int
		nim_physloc=$( ${LSDEV} -C -F "physloc" -l $nim_aname )
	else
		#echo "Could not determine NIM network interface and network adapter"
	    ${C_ERRMSG} ${ERR_ADAPTER_DETERMINE_IF} \
			${C_ERRMSG_ERR} "${PROGNAME}" "" "" ""
	fi

	# Sort the list of netaddrs in this order: etherchannel, all others, VIPA
	sorted_netaddrs=
	ethc_list=
	others_list=
	vipa_list=
	get_stanza_data  "$stanza_file" ${NIM_NAME} netaddr "" netaddr \
		| while read netaddr rest1
	do
		machine_type=$( get_stanza_data  $stanza_file $NIM_NAME netaddr $netaddr machine_type )
		network_type=$( get_stanza_data  $stanza_file $NIM_NAME netaddr $netaddr network_type )
		interface_type=$( get_stanza_data  $stanza_file $NIM_NAME netaddr $netaddr interface_type )

		route=$( get_stanza_data  $stanza_file $NIM_NAME netaddr $netaddr route )

		if [[ $machine_type = "etherchannel" ]]
		then
			ethc_list="$ethc_list $netaddr"
		elif [[ $network_type = "vi" || $interface_type = "vi" ]]
		then
			vipa_list="$vipa_list $netaddr"
		else
			others_list="$others_list $netaddr"
		fi
	done

	sorted_netaddrs="$ethc_list $others_list $vipa_list"

	# Find the network ip addresses which should be unique in the file 
	# but in error cases may not be.
	netaddr_list=
	for netaddr in $sorted_netaddrs
	do
		if [[ -z "$netaddr" ]]; then
			#echo "Network address is required."
			${C_ERRMSG} ${ERR_ADAPTER_MISSING_REQ_ATTR} \
				${C_ERRMSG_ERR} "${PROGNAME}" "netaddr" "" ""
			continue
		fi
		if echo "$netaddr_list" | ${GREP} -F -w $netaddr
		then
			#echo "Duplicate network address $netaddr for NIM secondary adapters"
			${C_ERRMSG} ${ERR_ADAPTER_DUP_IPS} \
				${C_ERRMSG_ERR} "${PROGNAME}" "$netaddr" "" ""
			continue
		else
			netaddr_list="$netaddr_list $netaddr"
		fi
		nim_name="$NIM_NAME"
		machine_type= network_type= location= interface_name=
		secondary_hostname= subnet_mask= cable_type= media_speed=
		attributes=
		machine_type=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr machine_type )
		network_type=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr network_type )
		interface_type=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr interface_type )
		interface_name=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr interface_name ) 
		location=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr location )
		secondary_hostname=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr secondary_hostname ) 
		subnet_mask=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr subnet_mask )
		cable_type=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr cable_type )
		media_speed=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr media_speed ) 
		attributes=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr attributes )
		interface_attributes=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr interface_attributes )
		adapter_attributes=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr adapter_attributes )
		multiple_physloc=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr multiple_physloc )
                bos_preconfig=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr bos_preconfig )
		cust_preconfig=$( get_stanza_data  $stanza_file $nim_name netaddr $netaddr cust_preconfig )

# Debug stuff
echo "nim_name = $nim_name"
echo "machine_type = $machine_type"
echo "interface_type = $interface_type"
echo "network_type = $network_type"             # deprecated - use interface_type
echo "logical_name = $interface_name"
echo "location = $location"
echo "multiple_physloc = $multiple_physloc"
echo "secondary_hostname = $secondary_hostname"
echo "netaddr = $netaddr"
echo "subnet_mask = $subnet_mask"
echo "cable_type = $cable_type"
echo "media_speed = $media_speed"
echo "attributes = $attributes"                 # deprecated - use interface_attributes
echo "interface_attributes = $interface_attributes"
echo "adapter_attributes = $adapter_attributes"
echo "bos_preconfig = $bos_preconfig"
echo "cust_preconfig = $cust_preconfig"
echo "route = $route"

		# Since network_type was replaced with interface_type, copy the value of interface_type
		# to network_type so that the rest of the code works the same as before.  There is
		# an existing variable in this script named "interface_type" which is used for a 
		# different purpose, so the value will be nulled here.
		if [[ -z $network_type && -n $interface_type ]]; then
			network_type=$interface_type
			interface_type=
		fi

		# Since attributes was replaced with interface_attributes, copy the value of 
		# interface_attributes to attributes so that the rest of the code works the same as before.
		if [[ -z $attributes && -n $interface_attributes ]]; then
			attributes=$interface_attributes
		fi

		# Check input parameters
		if [[ $machine_type != secondary ]] && [[ $machine_type != etherchannel ]]; then
			#echo "Invalid machine_type.  Expected machine_type = secondary or etherchannel."
			${C_ERRMSG} ${ERR_ADAPTER_INVALID_ATTR} \
				${C_ERRMSG_ERR} "${PROGNAME}" "machine_type" "$machine_type" ""
			continue
		fi

		# Set up variables for later use
		adapter_type= subclass= interface_type= prefix=
		adapter_name=
		class='if'
		[[ $network_type = 'en' ]] && \
			{ adapter_type='ent'; subclass='EN'; interface_type='en'; prefix='en'; }
		[[ $network_type = 'et' ]] && \
			{ adapter_type='ent'; subclass='EN'; interface_type='ie3'; prefix='et'; }
		[[ $network_type = 'ml' ]] && \
			{ adapter_type='mlt'; subclass='ML'; interface_type='ml'; prefix='ml'; }
		[[ $network_type = 'sn' ]] && \
			{ adapter_type='sni'; subclass='SN'; interface_type='sn'; prefix='sn'; }
		[[ $network_type = 'vi' ]] && \
			{ adapter_type='pseudo'; subclass='VI'; interface_type='vi'; prefix='vi'; }

		#### ETHERCHANNEL #####
		if [[ $machine_type = "etherchannel" ]]
		then
			MK_ETHC=
		    ec_adapter_list=
		    ec_adapter_name=

		    if [[ -n $location ]]
			then
				#echo "Cannot specify the attribute location with an etherchannel adapter"
				${C_ERRMSG} ${ERR_ADAPTER_ATTR_TYPE_MISMATCH} \
					${C_ERRMSG_ERR} "${PROGNAME}" "location" "$machine_type" ""
				continue
		    fi

		    # error if adapter_names was specified in adapter_attributes with multiple_physloc
 		    if [[ -n $adapter_attributes ]] && [[ -n $multiple_physloc ]]
		    then
				if echo $adapter_attributes | ${GREP} "adapter_names" >/dev/null 2>&1
				then
					#echo "cannot specify adapter_names in adapter_attributes and multiple_physloc"
					${C_ERRMSG} ${ERR_ADAPTER_ATTR_VAL_MISMATCH} \
						${C_ERRMSG_ERR} "${PROGNAME}" "adapter_names" \
							"adapter_attributes" "multiple_physloc"
					continue
				fi
		    fi

		    if [[ -n $multiple_physloc ]]
		    then
				ec_err=
				# separate physical location codes based on commas and get each adapter
				multiple_physloc=$( echo $multiple_physloc | ${CUT} -f2 -d'"' )
				loc_list=$( echo $multiple_physloc | ${SED} 's/,/ /g' )
				for loc in $loc_list
				do
					adapter=
					# Loop through the adapters looking for the one at this location
					${LSDEV} -Cc adapter -F "name" | while read adapter rest3
					do
						# If the adapter is not the requested type, skip it
						cu_adapter_type=$( echo $adapter | ${CUT} -c1-3 )
						[[ $adapter_type != $cu_adapter_type ]] && continue
						# If the physical location cannot be retrieved or is not
						# the requested value, skip the adapter
						physloc=$( ${LSDEV} -C -F "physloc" -l $adapter 2>/dev/null )
						[[ $? -ne 0 ]] && continue	
						[[ $loc != $physloc ]] && continue

						# found the corresponding adapter, check it
						cu_adapter_number=$( echo $adapter | ${CUT} -c4-5 )
						if ifconfig -a | ${GREP} e[nt]${cu_adapter_number} >/dev/null 2>&1
						then
							#echo "warning: etherchannel adapter $adapter at location $loc"
							#echo "         appears to be already configured"
							${C_ERRMSG} ${ERR_ADAPTER_ALREADY_CONFIGURED} \
								${C_ERRMSG_ERR} "${PROGNAME}" "$adapter" "$loc" ""
						fi

						if [[ $nim_aname = $adapter ]]; then
							#echo "etherchannel adapter $adapter conflicts with NIM adapter"
							${C_ERRMSG} ${ERR_ADAPTER_NIMIF_CONFLICT} \
								${C_ERRMSG_ERR} "${PROGNAME}" "adapter" "$adapter" "$loc"
							ec_err=1
							break
						fi

						# if there were no errors, then we found it
						ec_adapter_list="${ec_adapter_list}${adapter},"
						break
					done

					# if an error occured, stop looping through location codes
					[[ -n $ec_err ]] && break
				done

				# if an error occured, then continue to the next secondary adapter
				[[ -n $ec_err ]] && continue

			fi # -n multiple_physloc
		    
			# remove the trailing comma from the list of adapters
			if [[ -n $ec_adapter_list ]]; then
				ec_adapter_list=${ec_adapter_list%,}
				echo "adapter_names=${ec_adapter_list}"
			fi
		    
		    # if an interface_name was specified, check if the 
		    # corresponding physical adapter exists
		    if [[ -n $interface_name ]]
		    then
				interface_number=$( echo $interface_name | ${CUT} -c3-4 )
				ec_adapter_name=${adapter_type}${interface_number}

				if ${LSATTR} -El ${ec_adapter_name} >/dev/null 2>&1
				then
					if ${LSATTR} -E -a adapter_names -l ${ec_adapter_name} >/dev/null 2>&1
					then
						# this is an existing etherchannel adapter, set attributes
						if [[ -n $adapter_attributes ]]; then
							#echo "setting adapter_attributes for etherchannel adapter ${ec_adapter_name}."
							${C_ERRMSG} ${MSG_ADAPTER_SET_ATTR} \
								${C_ERRMSG_MSG} "adapter_attributes" "${ec_adapter_name}" "" ""
							set_adapter_attrs $ec_adapter_name $interface_name $adapter_attributes
						fi
					else
						# this is not an etherchannel adapter
						#echo "error: a non-etherchannel adapter already exists at ${ec_adapter_name}."
						${C_ERRMSG} ${ERR_ADAPTER_NON_EC} \
							${C_ERRMSG_ERR} "${PROGNAME}" "${ec_adapter_name}" "" ""
						continue
					fi
				else
					MK_ETHC="yes"
				fi
			else
				#echo "no interface specified, attempting to make etherchannel adapter."
				${C_ERRMSG} ${MSG_ADAPTER_MAKE} \
					${C_ERRMSG_MSG} "etherchannel" "" "" ""
				MK_ETHC="yes"
		    fi

			if [[ $MK_ETHC = "yes" ]]
			then
				# handle adapter_attributes
				if [[ -n $adapter_attributes ]]
				then
					adapter_attributes=$( echo $adapter_attributes | ${CUT} -f2 -d'"' )
					adapter_attributes=$( echo $adapter_attributes | ${SED} 's/|/ /g' )
					adapter_attributes=$( echo $adapter_attributes | ${SED} s/-a//g )
					adapter_attributes=$( echo $adapter_attributes | ${SED} s/\'//g )
					adapter_attributes=$( echo $adapter_attributes | ${SED} 's/ / -a /g' )
					adapter_attributes="-a ${adapter_attributes}"
				fi

				cmd="${MKDEV} -c adapter -s pseudo -t ibm_ech ${adapter_attributes} \
					${ec_adapter_list:+-a adapter_names=${ec_adapter_list}} \
					${ec_adapter_name:+-l ${ec_adapter_name}}"

				# run mkdev to define the etherchannel adapter
				adapter=$( $cmd )

				if [[ $? -ne 0 ]]
				then
					#echo "ERROR: the following command failed to define the etherchannel adapter:"
					#echo "       $cmd\n"
					${C_ERRMSG} ${ERR_ADAPTER_DEF_FAILED} \
						${C_ERRMSG_ERR} "${PROGNAME}" "etherchannel" "$cmd" ""
					continue
				else
					adapter=$( echo $adapter | ${AWK} '{ print $1 }' )
				fi
				
			fi

			# now define the interface
			${DEFIF} >/dev/null
			
			# Construct the interface_name
			if [[ -z ${interface_name} ]]; then
				cu_adapter_number=$( echo $adapter | ${CUT} -c4-5 )
				interface_name=$network_type$cu_adapter_number
			fi
				
			#echo "Secondary adapter and interface do not conflict with NIM"
			# Set up mktcpip2 parameters
			[[ -n $secondary_hostname ]] && host_name="-h $secondary_hostname"
			[[ -n $cable_type ]] && cable_type="-t $cable_type"
			[[ -n $media_speed ]] && media_speed="-x $media_speed"
			[[ -n $attributes ]] && attributes="-A $attributes"
			mktcpip2 -i $interface_name -a $netaddr -m $subnet_mask \
				$host_name $cable_type $media_speed $attributes

			if [[ -n $route ]]; then
				set_route "$route"
			fi
 
        #### END OF ETHERCHANNEL ####

		#### VIPA ####
		elif [[ $network_type = "vi" ]] 
		then
			MK_VIPA=
		    vi_if_list=

		    if [[ -n $location ]]
			then
				#echo "Cannot specify the attribute location with a VIPA interface"
			    ${C_ERRMSG} ${ERR_ADAPTER_ATTR_TYPE_MISMATCH} \
					${C_ERRMSG_ERR} "${PROGNAME}" "location" "$network_type" ""
				continue
		    fi

		    if [[ -n $adapter_attributes ]]
			then
				#echo "Cannot specify the adapter_attributes with a VIPA interface"
			    ${C_ERRMSG} ${ERR_ADAPTER_ATTR_TYPE_MISMATCH} \
					${C_ERRMSG_ERR} "${PROGNAME}" "adapter_attributes" "$network_type" ""
				continue
		    fi

		    # error if interface_names was specified in attributes with multiple_physloc
 		    if [[ -n $attributes ]] && [[ -n $multiple_physloc ]]
		    then
				if echo $attributes | ${GREP} "interface_names" >/dev/null 2>&1
				then
					#echo "cannot specify interface_names in interface attributes and multiple_physloc"
					${C_ERRMSG} ${ERR_ADAPTER_ATTR_VAL_MISMATCH} \
						${C_ERRMSG_ERR} "${PROGNAME}" "interface_names" \
							"interface_attributes" "multiple_physloc"
					continue
				fi
		    fi

		    if [[ -n $multiple_physloc ]]
		    then
				vi_err=
				# separate physical location codes based on commas and get each adapter
				loc_list=$( echo $multiple_physloc | ${SED} 's/,/ /g' )
				for loc in $loc_list
				do
					adapter=
					# Loop through the adapters looking for the one at this location
					${LSDEV} -Cc adapter -F "name" | while read adapter rest3
					do
						cu_adapter_type=$( echo $adapter | ${CUT} -c1-3 )
						# If the physical location cannot be retrieved or is not
						# the requested value, skip the adapter
						physloc=$( ${LSDEV} -C -F "physloc" -l $adapter 2>/dev/null )
						[[ $? -ne 0 ]] && continue	
						[[ $loc != $physloc ]] && continue
						# found the corresponding adapter, check it
						cu_adapter_number=$( echo $adapter | ${CUT} -c4-5 )
						status=$( ${LSDEV} -C -F "status" -l en${cu_adapter_number} 2>/dev/null )
						if  [[ $status = "Available" ]]; then
							vi_if_list="${vi_if_list}${adapter},"
							break
						fi
						status=$( ${LSDEV} -C -F "status" -l et${cu_adapter_number} 2>/dev/null )
						if  [[ $status = "Available" ]]; then
							vi_if_list="${vi_if_list}${adapter},"
							break
						fi

						# did not find an available interface at this location
						#echo "Did not find an available interface at location $loc for VIPA interface"
						${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
							${C_ERRMSG_ERR} "${PROGNAME}" "vi" "" ""
						vi_err=1
				        break
					done

					# if an error occured, stop looping through location codes
					[[ -n $vi_err ]] && break
				done

				# if an error occured, then continue to the next secondary adapter
				[[ -n $vi_err ]] && continue

		    fi # -n multiple_physloc
		    
		    # remove the trailing comma from the list of adapters
		    [[ -n $vi_if_list ]] && vi_if_list=${vi_if_list%,}
		    
		    if [[ $nim_ip_addr = $netaddr ]]; then
				#echo "Secondary interface ip address conflicts with NIM interface"
			    ${C_ERRMSG} ${ERR_ADAPTER_NIMIF_CONFLICT} \
					${C_ERRMSG_ERR} "${PROGNAME}" "netaddr" "$netaddr" "$nim_ip_addr"
				continue
		    fi

		    # if an interface_name was specified, check if the interface exists
		    if [[ -n $interface_name ]]
		    then
				if ! ${LSATTR} -El ${interface_name} >/dev/null 2>&1
				then
					MK_VIPA="yes"
				fi
		    else
				num=0
				while [[ -z $interface_name ]] && [[ $num -ne 99 ]] 
				do
					if ! ${LSATTR} -El ${network_type}${num} >/dev/null 2>&1
					then
						interface_name=${network_type}${num}
					else
					   (( num=num + 1 ))
					fi
		        done
			
				if [[ -z $interface_name ]]; then
					#echo "Cannot find an available interface name for the VIPA adapter."
					${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
						${C_ERRMSG_ERR} "${PROGNAME}" "vi" "" ""
					continue
				else
					#echo "no interface specified, making VIPA interace ${interface_name}."
					${C_ERRMSG} ${MSG_ADAPTER_MAKE} \
						${C_ERRMSG_MSG} "${interface_name}" "" "" ""
				fi
				MK_VIPA="yes"
		    fi

			if [[ -z $vi_if_list && -n $attributes ]]
			then
				tmp_attrs="$attributes"
				attr_list=
				tmp_attrs=$( echo $tmp_attrs | ${CUT} -f2 -d'"' )
				tmp_attrs=$( echo $tmp_attrs | ${SED} 's/|/ /g' )
				tmp_attrs=$( echo $tmp_attrs | ${SED} s/-a//g )

				for attr in $tmp_attrs
				do
					if [[ ${attr%=*} = "interface_names" ]]
					then
						vi_if_list=${attr#*=}
					else
						attr_list="${attr_list} ${attr}"
					fi
				done

				if [[ -z $vi_if_list ]]
				then
					#echo "couldn't find interface_names in attribute list"
					${C_ERRMSG} ${ERR_ADAPTER_FIND_ATTR_VAL} \
						${C_ERRMSG_ERR} "${PROGNAME}" "interface_names" \
							"interface_attributes" ""
					continue
				fi

				if [[ $MK_VIPA = "yes" ]]; then
					attributes=${attr_list}
					attributes=$( echo $attributes | ${SED} 's/ /|/g' )
					echo "new attributes=${attributes}"
				fi
			fi

			echo "interface_names=${vi_if_list}"

			if echo $interface_names | ${GREP} $nim_iname >/dev/null 2>&1
			then
				#echo "warning: VIPA interface is using NIM interface."
				${C_ERRMSG} ${MSG_ADAPTER_USING_NIMIF} \
					${C_ERRMSG_MSG} "VIPA" "$nim_iname" "" ""
			fi

			if [[ $MK_VIPA = "yes" ]]
			then
				cmd="${MKDEV} -c if -s VI -t vi -w $interface_name \
					${vi_if_list:+-a interface_names=${vi_if_list}}"

				# run mkdev to define the VIPA interface
				$cmd

				if [[ $? -ne 0 ]]
				then
					#echo "ERROR: the following command failed to define the VIPA interface:"
					#echo "       $cmd\n"
					${C_ERRMSG} ${ERR_ADAPTER_DEF_FAILED} \
						${C_ERRMSG_ERR} "${PROGNAME}" "VIPA" "$cmd" ""
					continue
				fi
			fi

			#echo "Secondary adapter and interface do not conflict with NIM"
			# Set up mktcpip2 parameters
			[[ -n $secondary_hostname ]] && host_name="-h $secondary_hostname"
			[[ -n $attributes ]] && attributes="-A $attributes"
			mktcpip2 -i $interface_name -a $netaddr -m $subnet_mask \
				$host_name $attributes

			if [[ -n $route ]]; then
				set_route "$route"
			fi

		#### END OF VIPA ####
		else		
		#### ALL OTHER ####

		# Look for the requested interface and adapter in the configuration database
		# If there is no input interface_name...
		if [[ -z $interface_name ]]; then
			# If input network_type is multilink, assume ml0, mlt0, and no physloc
			if [[ $network_type = 'ml' ]]; then
				interface_name=ml0
				adapter=mlt0
				physloc=
			# If there is an input physical location code...
			elif [[ -n $location ]]; then
				adapter=
				# Loop through the adapters looking for the one at this location
				${LSDEV} -Cc adapter -F "name" | while read adapter rest3
				do
					# If the adapter is not the requested type, skip it
					cu_adapter_type=$( echo $adapter | ${CUT} -c1-3 )
					[[ $adapter_type != $cu_adapter_type ]] && continue
					# If the physical location cannot be retrieved or is not
					# the requested value, skip the adapter
					physloc=$( ${LSDEV} -C -F "physloc" -l $adapter 2>/dev/null )
					[[ $? -ne 0 ]] && continue	
					[[ $location != $physloc ]] && continue
					# Construct the interface_name 
					cu_adapter_number=$( echo $adapter | ${CUT} -c4-5 )
					interface_name=$network_type$cu_adapter_number
					break
				done
				if [[ -z $interface_name ]]; then
					#echo "Did not find suitable adapter at $location"
					${C_ERRMSG} ${ERR_ADAPTER_FIND_ADAPTER_LOC} \
						${C_ERRMSG_ERR} "${PROGNAME}" "$location" "" ""
					continue
				fi	
					
			# If there is no input interface_name and no input location...
			else
				defined_flag="-S Defined"
				# Loop through defined network interfaces
				${LSDEV} $defined_flag -Cc if -F "name" | while read I_name rest3
				do
					cu_interface_type=$( echo $I_name | ${CUT} -c1-2 )
					# If this interface is not the requested type, skip it
					[[ $cu_interface_type != $network_type ]] && continue
					# If this is the NIM interface, skip it
					[[ $I_name = $nim_iname ]] && continue
					interface_name="$I_name"
					break
				done
				# If there is no defined interface of the requested type, try defif
				if [[ -z $interface_name ]]; then
					# Only run defif if not BOS Install and either large page regions is set
					# or the interface is not for a switch adapter (does not require large page
					# support)
					if [[ -z $INUBOSTYPE ]]; then
						CUR_LGPG_REGIONS=$( ${VMO} -r -a | ${GREP} lgpg_regions | ${AWK} '{ print $3 }' )
						if [[ ( -n $CUR_LGPG_REGIONS && $CUR_LGPG_REGIONS != 0 ) || \
							$network_type != 'sn' ]]; then
							
							I_name=$( ${DEFIF} -c $class -s $subclass -t $interface_type )
							rc="$?"
							# If the defif was successful, save the interface_name
							if [[ $rc -eq 0 ]]; then	
								interface_name="$I_name"
							else
								#echo "Did not find suitable network interface"
								${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
									${C_ERRMSG_ERR} "${PROGNAME}" "$interface_type" "" ""
								continue
							fi
						fi
					fi
				fi
			fi
		fi

		if [[ -z $interface_name ]]; then
			#echo "Did not find suitable network interface"
			${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
				${C_ERRMSG_ERR} "${PROGNAME}" "$network_type" "" ""
			continue
		fi 
		interface_type=$( echo $interface_name | ${CUT} -c1-2 )
		# If this interface is not the requested type, skip it
		if [[ $interface_type != $network_type ]]; then
			#echo "Did not find suitable interface for $interface_name"
			${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
				${C_ERRMSG_ERR} "${PROGNAME}" "$network_type" "" ""
			continue
		fi 
		# If the interface is not in the configuration database, run defif
		# Only run defif if not BOS Install and either large page regions is set
		# or the interface is not for a switch adapter (does not require large page
		# support)
		if [[ -z $INUBOSTYPE ]]; then
			CUR_LGPG_REGIONS=$( ${VMO} -r -a | ${GREP} lgpg_regions | ${AWK} '{ print $3 }' )
			if [[ ( -n $CUR_LGPG_REGIONS && $CUR_LGPG_REGIONS != 0 ) || \
				$network_type != 'sn' ]]; then
				I_name=
				until ${LSATTR} -E -O -l $interface_name 2>&1 >/dev/null
				do
					I_name=$( ${DEFIF} -c $class -s $subclass -t $interface_type )
					rc="$?"
					[[ $rc -ne 0 ]] && break
				done
				if [[ -n $I_name && $interface_name != $I_name ]]; then
					#echo "Did not find suitable interface for $interface_name"
					${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
						${C_ERRMSG_ERR} "${PROGNAME}" "$network_type" "" ""
					continue
				fi 
			fi
		fi
		
		# Get the adapter name and verify the adapter is at the requested location
		# and configured
		cu_adapter_number=$( echo $interface_name | ${CUT} -c3-4 )
		adapter=$adapter_type$cu_adapter_number
		if [[ $network_type != 'ml' ]]; then
			physloc=$( ${LSDEV} -C -F "physloc" -l $adapter 2>/dev/null )
			if [[ $? -ne 0 ]]; then
				#echo "Did not find suitable adapter for $interface_name"
				${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
					${C_ERRMSG_ERR} "${PROGNAME}" "$interface_name" "" ""
				continue
			fi
			if [[ -n $location && $location != $physloc ]]; then
				#echo "Did not find suitable adapter for $interface_name"
				${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
					${C_ERRMSG_ERR} "${PROGNAME}" "$interface_name" "" ""
				continue
			fi
		fi
		status=$( ${LSDEV} -C -F "status" -l $adapter 2>/dev/null )
		if [[ $? -ne 0 ]]; then
			#echo "Did not find suitable adapter for $interface_name"
			${C_ERRMSG} ${ERR_ADAPTER_FIND_IF} \
				${C_ERRMSG_ERR} "${PROGNAME}" "$interface_name" "" ""
			continue
		fi
		if [[ $status != 'Available' ]]; then
			# Only run cfgmgr if not BOS Install and either large page regions is set
			# or the interface is not for a switch adapter (does not require large page
			# support)
			if [[ -z $INUBOSTYPE ]]; then
				CUR_LGPG_REGIONS=$( ${VMO} -r -a | ${GREP} lgpg_regions | ${AWK} '{ print $3 }' )
				if [[ ( -n $CUR_LGPG_REGIONS && $CUR_LGPG_REGIONS != 0 ) || \
					network_type != 'sn' ]]; then

					/usr/sbin/cfgmgr -l $adapter
				fi
			fi
		fi

		# Check the requested secondary adapter/interface against the NIM
		# adapter/interface
		if [[ $nim_aname = $adapter ]]; then
			#echo "Secondary adapter name conflicts with NIM adapter"
			${C_ERRMSG} ${ERR_ADAPTER_NIMIF_CONFLICT} \
				${C_ERRMSG_ERR} "${PROGNAME}" "adapter" "$adapter" "$nim_aname"
			continue
		elif [[ $nim_physloc = $physloc ]]; then
			#echo "Secondary adapter physical location conflicts with NIM adapter"
			${C_ERRMSG} ${ERR_ADAPTER_NIMIF_CONFLICT} \
				${C_ERRMSG_ERR} "${PROGNAME}" "location" "$physloc" "$nim_physloc"
			continue
		elif [[ $nim_iname = $interface_name ]]; then
			#echo "Secondary interface name conflicts with NIM interface"
			${C_ERRMSG} ${ERR_ADAPTER_NIMIF_CONFLICT} \
				${C_ERRMSG_ERR} "${PROGNAME}" "interface_name" "$interface_name" "$nim_iname"
			continue
		elif [[ $nim_ip_addr = $netaddr ]]; then
			#echo "Secondary interface ip address conflicts with NIM interface"
			${C_ERRMSG} ${ERR_ADAPTER_NIMIF_CONFLICT} \
				${C_ERRMSG_ERR} "${PROGNAME}" "netaddr" "$netaddr" "$nim_ip_addr"
			continue
		elif [[ -n $secondary_hostname && $NIM_HOSTNAME = $secondary_hostname ]]; then
			#echo "Secondary interface netname conflicts with NIM interface"
			${C_ERRMSG} ${ERR_ADAPTER_NIMIF_CONFLICT} \
				${C_ERRMSG_ERR} "${PROGNAME}" "secondary_hostname" \
					"$secondary_hostname" "$NIM_HOSTNAME"
			continue
		else
			if [[ -n $adapter_attributes ]]; then
				set_adapter_attrs "$adapter" "$interface_name" "$adapter_attributes"
			fi
			
			#echo "Secondary adapter and interface do not conflict with NIM"
			# Set up mktcpip2 parameters
			[[ -n $secondary_hostname ]] && host_name="-h $secondary_hostname"
			[[ -n $cable_type ]] && cable_type="-t $cable_type"
			[[ -n $media_speed ]] && media_speed="-x $media_speed"
			[[ -n $attributes ]] && attributes="-A $attributes"
			mktcpip2 -i $interface_name -a $netaddr -m $subnet_mask \
				$host_name $cable_type $media_speed $attributes
		fi

		if [[ -n $route ]]; then
			set_route "$route"
		fi

		#### END OF ALL OTHER ####
		fi
	done
}


#*---------------------------- setup_and_exec       ----------------------------
#
# NAME: setup_and_exec
#
# FUNCTION:
#		mounts the stanza file and processes it
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		this function is used so that we can log the output
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#
# RETURNS: (int)
#		0							= no errors
#		>0							= failure
#
# OUTPUT:
#-----------------------------------------------------------------------------*/
function setup_and_exec {

	# ensure local access to the script (local path returned via access_pnt)
	nim_mount ${location}

	# attempt to copy it
	if ${CP} ${access_pnt} ${TMPDIR}/adapters >/dev/null 2>&1
	then

		# unmount the source and use local copy
		nim_unmount ${access_pnt}

		# set new access point
		access_pnt="${TMPDIR}/adapters"

	fi

	#
	# call the method to configure the adapters with the stanza file
	#
	cfgnimadapters ${access_pnt} || return 1

	#
	# In 53, vmo tunable parameters are made dynamic so prompt for
	# bosboot are no longer asked.  This script will now call bosboot
	# as a workaround.
	#
	if [[ $RUN_BOSBOOT = "yes" ]]; then
		/usr/sbin/bosboot -ad /dev/ipldevice
		if [[ $? -ne 0 ]]; then
			return 1
		fi
	fi

	return 0
}



#*---------------------------- c_cfgadptrs         ----------------------------
#
# NAME: c_cfgadptrs
#
# FUNCTION:
#		executes the command to configure the secondary adapter stanza file
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#
# RETURNS: (int)
#		0							= no errors
#		>0							= failure
#
# OUTPUT:
#-----------------------------------------------------------------------------*/

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

# initialize local variables
source=
rc=

# set parameters from command line
while getopts :a:qv c
do
	case ${c} in

		a)		# validate the attr ass
				parse_attr_ass "${OPTARG}"

				# include the assignment for use in this environment
				eval ${variable}=\"${value}\"
		;;

		q)		# show attr info
				cmd_what
				exit 0
		;;

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

		\?)	# unknown option
				error ${ERR_BAD_OPT} ${OPTARG}
		;;
esac
done

# check for missing attrs
ck_attrs

if [[ -z $name ]]; then
	# NIM initialization
	nim_init
else
	TMPDIR=/tmp/c_cfgadptrs_$name_$$
	/usr/bin/mkdir $TMPDIR
	if [[ $? -ne 0 ]]; then
		/usr/bin/dspmsg -s ${ERR_SET} cmdnim.cat ${ERR_CREATE_DIR} \
			'%1$s: Unable to create %2$s directory.\n' "${PROGNAME}" "${TMPDIR}"
		exit 1
	fi
	SCRIPT_LOG=$TMPDIR/c_cfgadptrs_$name_$$.log
	ERR=$TMPDIR/c_cfgadptrs_$name_$$.err
	clienthostname=`/usr/bin/hostname`
	hostip=`/usr/bin/cat /etc/hosts | /usr/bin/grep -v "^#" | /usr/bin/grep $clienthostname | /usr/bin/awk '{print $1}'`
	if [[ -z $hostip ]]; then
		/usr/bin/dspmsg -s ${ERR_SET} cmdnim.cat ${ERR_INVALID_HOSTNAME} \
			'%1$s: Host %2$s is not resolvable.\n' "${PROGNAME}" "${clienthostname}"
		exit 1
	fi
	NIM_NAME=$name
	NIM_HOSTS="$hostip:$name"
	NIM_HOSTNAME=$name
fi

${C_TIME_STAMP} >> ${SCRIPT_LOG}
if [[ ${NIM_SHOW_PROGRESS} = yes ]]
then
	# run the function 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.
	(
	( setup_and_exec )
	echo $? > ${TMPDIR}/_script.rc 
	) 2>&1 | ${TEE} -a ${SCRIPT_LOG}
	rc=`${CAT} ${TMPDIR}/_script.rc`
	${RM} ${TMPDIR}/_script.rc
else
	( setup_and_exec  ) >> ${SCRIPT_LOG} 2>&1
	rc=$?
fi
${C_TIME_STAMP} -e >> ${SCRIPT_LOG}

# If an error occurred, it was logged.  Print a message
# referring the user to the log for information.
if [[ $rc -ne 0 ]]; then
	if [[ -z $name ]]; then
		${C_ERRMSG} ${MSG_SEE_LOG_FILE} \
					${C_ERRMSG_MSG} "${SCRIPT_LOG}" \
					"" "" "" >${ERR} 2>&1
		err_from_cmd "c_cfgadptrs"
	else
		/usr/bin/dspmsg -s ${ERR_SET} cmdnim.cat ${ERR_ERROR_CAUSE} \
			'%1$s: An error has occured.  The following is the cause of the error:\n' "${PROGNAME}"
		/usr/bin/cat ${ERR}
	fi
fi

# success
exit $rc

