#!/bin/sh

. /usr/lib/nimol_lib

#------------------------------ local defines ---------------------------------
NIMOL_SERVER=
NIMOL_SERVER_IP=
NIMOL_SYSLOG_FACILITY=
SOURCE_DIR=
NIMINFO_FILE=
CSCRIPT=
NIM_MOUNTS=
MKSYSB_EXISTS=
BIDATA_EXISTS=
LPPSRC_EXISTS=
IMDATA_EXISTS=
CUSTSC_EXISTS=
CUST_SCRIPT_LOC1=
CUST_SCRIPT_LOC2=
nimol_br_en=

# variables set based on the parameters
CHOSTNAME=
MAC_ADDR=
CGATEWAY_IP=
LIST=
LABEL=
REMAIN_CLIENT=
REMOVE=
SUBNET_MASK=
IP_ADDR=

# Variables for undo function
EDIT_CONF_SUCCESS=
EDIT_HOSTS_SUCCESS=
EDIT_DHCPD_SUCCESS=
LINK_BOOTI_SUCCESS=
ADD_ARP_SUCCESS=
NFS_EXPORT_SUCCESS=
K_NIMINFO_SUCCESS=
MK_CSCRIPT_SUCCESS=
IPTABLES_SUCCESS=
STARTED_BOOTREPLYD=
EDITED_BOOTREPLY_CONF=


################################################################################
#
#  undo - undo changes made
#
#  parameters:
#
################################################################################
function undo {

if [[ -n $EDIT_CONF_SUCCESS ]]; then
    ${AWK} '{if ( !($1 == "CLIENT" && $2 == host)) print $0;}' host="${CHOSTNAME}" \
	$NIMOL_CONF >${TMPDIR}/nimol.conf.tmp && ${MV} ${TMPDIR}/nimol.conf.tmp $NIMOL_CONF
    msg "Removed \"%s\" from the file \"%s\"\n" "CLIENT ${CHOSTNAME}" "$NIMOL_CONF"
fi

if [[ -n $EDIT_HOSTS_SUCCESS ]]; then
    ${AWK} '{if ( !($1 == ip && $2 == host)) print $0;}' ip=${IP_ADDR} host="${CHOSTNAME}" \
	/etc/hosts >${TMPDIR}/hosts.tmp && ${MV} ${TMPDIR}/hosts.tmp /etc/hosts
    msg "Removed \"%s\" from the file \"%s\"\n" "${IP_ADDR} ${CHOSTNAME}" "/etc/hosts"
fi

if [[ -n $EDIT_DHCPD_SUCCESS ]]; then
    ${AWK} 'BEGIN { RS = "\n\n" } {if ( !( $1 == "host" && $2 == hn)) print $0 "\n";}' hn="${CHOSTNAME}" \
	/etc/dhcpd.conf >${TMPDIR}/dhcpd.conf.tmp && ${MV} ${TMPDIR}/dhcpd.conf.tmp /etc/dhcpd.conf

    msg "Removed \"%s\" from the file \"%s\"\n" "host ${CHOSTNAME}" "/etc/dhcpd.conf"

    ${DHCPD} restart || warn "Failed to restart %s.\n" "${DHCPD}"
fi

if [[ $EDITED_BOOTREPLY_CONF = "yes" ]]
then
	#remove entry, rehash server
	if $SED "/^$CHOSTNAME:.*/d" $NIMOL_BOOTREPLYD_CONF > $TMPDIR/nbrconf.$$ 
	then
		line=$( $GREP "$CHOSTNAME:" $NIMOL_BOOTREPLYD_CONF )
		[[ -n $line ]] && msg "Removed \"%s\" from the file \"%s\"\n" "$line" "$NIMOL_BOOTREPLYD_CONF"
		$MV $TMPDIR/nbrconf.$$ $NIMOL_BOOTREPLYD_CONF
	else
		err 1 "error from command %s\n" "$SED \"/^$CHOSTNAME:.*/d\" $NIMOL_BOOTREPLYD_CONF > $TMPDIR/nbrconf.$$"
	fi

	if [[ -s $NIMOL_BOOTREPLYD_PID ]]
	then
		file_pid=$( $CAT $NIMOL_BOOTREPLYD_PID )
		running_pid=$( $PS | $SED 1d | $AWK -vpid=$file_pid '$2 == pid {print $2}' )
	fi

	if [[ -n $running_pid ]]
	then
		[[ -s $NIMOL_BOOTREPLYD_PID ]] && pid=$($CAT $NIMOL_BOOTREPLYD_PID) 
		kill -HUP $pid || warn "Failed to restart %s.\n" "nimol_bootreplyd" #send HUP signal to rehash
		msg "Executed %s.\n" "kill -HUP $pid"
	else
		#start nimol_bootreplyd
		[[ -s $NIMOL_BOOTREPLYD_CONF ]] || >$NIMOL_BOOTREPLYD_CONF
		$NIMOL_BOOTREPLYD_START || warn "Failed to start %s.\n" "nimol_bootreplyd"
		msg "Executed %s.\n" "$NIMOL_BOOTREPLYD_START"
	fi
fi

if [[ $STARTED_BOOTREPLY = "yes" ]]
then
	if [[ -s $NIMOL_BOOTREPLYD_PID ]] 
	then
		pid=$($CAT $NIMOL_BOOTREPLYD_PID) 
		kill $pid || warn "Failed to stop %s.\n" "nimol_bootreplyd"
		msg "Executed %s.\n" "kill $pid"
	fi
fi

if [[ -n $LINK_BOOTI_SUCCESS ]]; then
    ${RM} -f ${TFTPBOOT}/${CHOSTNAME}
    msg "Removed %s.\n" "${TFTPBOOT}/${CHOSTNAME}"
fi

if [[ -n $ADD_ARP_SUCCESS ]]; then
    ${ARP} -d $CHOSTNAME
    msg "Executed %s.\n" "${ARP} -d $CHOSTNAME"
fi

if [[ -n $IPTABLES_SUCCESS ]]; then
    ${IPTABLES} -D INPUT -s $CHOSTNAME -j ACCEPT
    msg "Executed %s.\n" "${IPTABLES} -D INPUT -s $CHOSTNAME -j ACCEPT"
fi

if [[ -n $NFS_EXPORT_SUCCESS ]]; then
    ${EXPORTFS} -u ${CHOSTNAME}:${SOURCE_DIR} 2>$ERR || \
	cmd_warn "${EXPORTFS} -u ${CHOSTNAME}:${SOURCE_DIR}"
    msg "Executed %s.\n" "${EXPORTFS} -u ${CHOSTNAME}:${SOURCE_DIR}"
fi

if [[ -n $MK_NIMINFO_SUCCESS ]]; then
    ${RM} -f ${NIMINFO_FILE}
    msg "Removed %s.\n" "${NIMINFO_FILE}"
fi

if [[ -n $MK_CSCRIPT_SUCCESS ]]; then
    ${RM} -f ${CSCRIPT}
    msg "Removed %s.\n" "${CSCRIPT}"
fi

return
}


################################################################################
#
#  cleanup - standard cleanup 
#
#  parameters:
#
################################################################################
function cleanup {

    trap "" 

    ${RM} -rf $TMPDIR

    ${RM} -rf $ERR

} # end of cleanup 


# ----------------------------------- MAIN ------------------------------------
#
#
#
#
# -----------------------------------------------------------------------------

# set parameters from command line
while getopts :c:Dg:lL:m:np:rs: c
do
	case ${c} in

        c)		# client hostname
				CHOSTNAME=$OPTARG
				;;

        D)		# debug output
				set -x
				;;
				
        g)		# client gateway
				CGATEWAY_IP=$OPTARG
				;;

        l)		# list clients that are defined for an install
				LIST="yes"
				;;

        L)		# the label for the AIX install resources to use
				LABEL=$OPTARG
				;;

        m)		# client MAC address
				MAC_ADDR=$OPTARG
				;;

        n)		# do not remain a NIM client
				REMAIN_CLIENT="no"
				;;

        p)		# client ip address - used if not in /etc/hosts 
				IP_ADDR=$OPTARG
				;;

        r)		# remove client 
				REMOVE="yes"
				;;

        s)		# client subnet mask
				SUBNET_MASK=$OPTARG
				;;

		\?)		# unknown option
				usage "\nUsage nimol_install: Setup client for AIX installation.\n      nimol_install       -c <client hostname> | -l\n                         [-g <client gateway>]\n                         [-m <client MAC address>]\n                         [-p <client ip address>]\n                         [-s <client subnet mask>]\n                         [-L <install resources label>] [-n] [-r] [-D]\n\nExamples:\n  nimol_install -c client1 -g 192.168.1.1 -m 00:60:08:3F:E8:DF\n    -s 255.255.255.0 -L aix530   # setup client1 for an install\n  nimol_install -l               # list clients ready for an install\n  nimol_install -c client1 -r    # remove client1\n\ndefaults:\n\t-L    default\n"

				;;
	esac
done

trap err_signal 1 2 11 15
trap cleanup 0

# tmp directory
${MKDIR} ${TMPDIR} 2>$ERR || cmd_err 1 "${MKDIR} ${TMPDIR}"

#are we using nimol_bootreply or dhcp? 
nimol_br_en=$( ${AWK} '{if ($1 == "NIMOL_BOOTREPLYD" ) print $2;}' $NIMOL_CONF 2>$ERR )
[[ $? != 0 ]] && cmd_warn "${AWK}"

####################################################
#
# LIST CLIENTS READY FOR AN INSTALL
#
####################################################
if [[ -n $LIST ]]
then

    [[ ! -s $NIMOL_CONF ]] && err 1 "The file %s does not exist.\n" "${NIMOL_CONF}"

    client_listing=$( ${AWK} '{if ( $1 == "CLIENT" ) print $0;}' $NIMOL_CONF )
    if [[ -z $client_listing ]]; then
	msg "No clients are defined for an install.\n"
    else
	msg "The following clients are defined for an install:\n%s\n" "$client_listing"
    fi 

    exit 0
fi


#
# Specify the default values.
#
if [[ -z $CHOSTNAME ]]
then
	err 1 "A hostname must be specified.\n"
fi

####################################################
#
# REMOVE CLIENT
#
####################################################
if [[ -n $REMOVE ]]
then

    # determine the label
    label=$( ${AWK} '{if ( $1 == "CLIENT" && $2 == host ) print $6;}' host="${CHOSTNAME}" $NIMOL_CONF 2>$ERR )
    [[ $? != 0 ]] && cmd_err 1 "${AWK}"
    [[ -z $label ]] && err 1 "Unable to find the label corresponding to %s in %s\n" "$CHOSTNAME" "$NIMOL_CONF"
    
    # Determine directory
    dir=$( ${AWK} '{if ( $1 == "LABEL" && $2 == label ) print $3;}' label="$label" $NIMOL_CONF 2>$ERR )
    [[ $? != 0 ]] && cmd_err 1 "${AWK}"
    [[ -z $dir ]] && err 1 "Unable to find the directory corresponding to %s in %s\n" "$LABEL" "$NIMOL_CONF"

    # Unexport the directory
    if [[ ! -s /etc/exports ]] || ${AWK} '{if ( $1 == dir && $2 == "*(rw,insecure,no_root_squash)" ) exit 1;}' dir="${dir}" /etc/exports
    then
	${EXPORTFS} -u ${CHOSTNAME}:${dir} 2>$ERR || \
	    cmd_warn "${EXPORTFS} -u ${CHOSTNAME}:${dir}"
	msg "Executed %s.\n" "${EXPORTFS} -u ${CHOSTNAME}:${dir}"
    fi

	#are we using nimol_bootreplyd?  or dhcp?
	if [[ $nimol_br_en = "yes" ]]
	then
		#remove host's entry
		if $SED "/^$CHOSTNAME:.*/d" $NIMOL_BOOTREPLYD_CONF > $TMPDIR/nbrconf.$$ 
		then
			line=$( $EGREP "^$CHOSTNAME:" $NIMOL_BOOTREPLYD_CONF )
			[[ -n $line ]] && msg "Removed \"%s\" from the file \"%s\"\n" "$line" "$NIMOL_BOOTREPLYD_CONF"
			$MV $TMPDIR/nbrconf.$$ $NIMOL_BOOTREPLYD_CONF
		else
			err 1 "error from command %s\n" "$SED \"/^$CHOSTNAME:.*/d\" $NIMOL_BOOTREPLYD_CONF > $TMPDIR/nbrconf.$$"
		fi

		if [[ -s $NIMOL_BOOTREPLYD_PID ]]
		then
			file_pid=$( $CAT $NIMOL_BOOTREPLYD_PID )
			running_pid=$( $PS | $SED 1d | $AWK -vpid=$file_pid '$2 == pid {print $2}' )
		fi

		if [[ -n $running_pid ]]
		then
			[[ -s $NIMOL_BOOTREPLYD_PID ]] && pid=$($CAT $NIMOL_BOOTREPLYD_PID) 
			kill -HUP $pid || warn "Failed to restart %s.\n" "nimol_bootreplyd" #send HUP signal to rehash
			msg "Executed %s.\n" "kill -HUP $pid"
		else
			#start nimol_bootreplyd
			[[ -s $NIMOL_BOOTREPLYD_CONF ]] || >$NIMOL_BOOTREPLYD_CONF
			$NIMOL_BOOTREPLYD_START || warn "Failed to start %s.\n" "nimol_bootreplyd"
			msg "Executed %s.\n" "$NIMOL_BOOTREPLYD_START"
		fi
	else
		# Remove the entry for the host in /etc/dhcpd.conf
		${AWK} 'BEGIN { RS = "\n\n" } {if ( !( $1 == "host" && $2 == hn)) print $0 "\n";}' hn="${CHOSTNAME}" \
		/etc/dhcpd.conf >${TMPDIR}/dhcpd.conf.tmp && ${MV} ${TMPDIR}/dhcpd.conf.tmp /etc/dhcpd.conf
		msg "Removed \"%s\" from the file \"%s\"\n" "host ${CHOSTNAME}" "/etc/dhcpd.conf"

		${DHCPD} restart || warn "Failed to restart %s.\n" "${DHCPD}"
	fi

    # Remove the boot image link
    [[ -s ${TFTPBOOT}/${CHOSTNAME} ]] && ${RM} -f ${TFTPBOOT}/${CHOSTNAME}
    msg "Removed %s.\n" "${TFTPBOOT}/${CHOSTNAME}"

    # Remove the arp entry
    ${ARP} -d $CHOSTNAME 2>$ERR || cmd_warn "${ARP} -d $CHOSTNAME"
    msg "Executed %s.\n" "${ARP} -d $CHOSTNAME"

    # remove the rule from iptables
    ${IPTABLES} -D INPUT -s $CHOSTNAME -j ACCEPT
    msg "Executed %s.\n" "${IPTABLES} -D INPUT -s $CHOSTNAME -j ACCEPT"

    # Remove the niminfo file
    [[ -s ${TFTPBOOT}/${CHOSTNAME}.info ]] && ${RM} -f ${TFTPBOOT}/${CHOSTNAME}.info
    msg "Removed %s.\n" "${TFTPBOOT}/${CHOSTNAME}.info"

    # Remove the cscript file
    [[ -s ${dir}/scripts/${CHOSTNAME}.script ]] && ${RM} -f ${dir}/scripts/${CHOSTNAME}.script
    msg "Removed %s.\n" "${dir}/scripts/${CHOSTNAME}.script"

    # Remove the client from /etc/nimol.conf
    if ${AWK} '{if (!( $1 == "CLIENT" && $2 == host )) print $0;}' host="${CHOSTNAME}" $NIMOL_CONF >${TMPDIR}/nimol.conf.tmp 2>$ERR
    then
	${MV} ${TMPDIR}/nimol.conf.tmp $NIMOL_CONF 2>$ERR || cmd_err 1 "${MV} ${TMPDIR}/nimol.conf.tmp $NIMOL_CONF"
	msg "Removed \"%s\" from the file \"%s\"\n" "CLIENT ${CHOSTNAME}" "$NIMOL_CONF"
    else
	cmd_warn "${AWK}" 1
    fi

	# Remove client's /etc/hosts entry if nimol created one
	if ${AWK} '{if (!($1 == "HOSTS_ENTRY" && $2 == host)) print $0;}' host="${CHOSTNAME}" $NIMOL_CONF >${TMPDIR}/nimol.conf.tmp 2>$ERR
	then
		${MV} ${TMPDIR}/nimol.conf.tmp $NIMOL_CONF 2>$ERR || cmd_err 1 "${MV} ${TMPDIR}/nimol.conf.tmp $NIMOL_CONF"
		if ${AWK} '{if (!($2 == host || $3 == host)) print $0;}' host="${CHOSTNAME}" /etc/hosts >${TMPDIR}/hosts.temp.$$ 2>$ERR
		then
			${MV} ${TMPDIR}/hosts.temp.$$ /etc/hosts
		else
			cmd_warn "${AWK}" 1
		fi
	else
		cmd_warn "${AWK}" 1
	fi

    exit 0
fi

####################################################
#
# DEFINE CLIENT FOR INSTALL
#
####################################################

if [[ -z $SUBNET_MASK ]]
then
	err 1 "A subnet mask must be specified.\n"
fi

[[ ! -s $NIMOL_CONF ]] && err 1 "The file %s does not exist.\n" "${NIMOL_CONF}"
NIMOL_SUBNET=$( ${AWK} '{if ( $1 == "NIMOL_SUBNET" ) print $2;}' $NIMOL_CONF )
[[ -z $NIMOL_SUBNET ]] && err 1 "Unable to find %s in %s\n" "NIMOL_SUBNET" "$NIMOL_CONF"
[[ -n $IP_ADDR ]] && get_subnet $IP_ADDR $SUBNET_MASK

#mac address is not required to answer directed boot requests with nimol_bootreplyd except when installing
#from the same subnet (static ARP entry is needed within same subnet for tftp boot image transfer)
if [[ -z $MAC_ADDR && $nimol_br_en != "yes" ]] || [[ -z $MAC_ADDR && $NIMOL_SUBNET = $SUBNET ]]
then
	err 1 "A MAC address must be specified.\n"
fi

[[ -z $MAC_ADDR ]] && MAC_ADDR="none"

if [[ -z $LABEL ]]
then
	msg "No label specified.  Using \"%s\".\n" "default"
	LABEL=default
fi

#
# Start nfs - do this incase the machine was rebooted.
#

# first, make sure that portmap is running
${PORTMAP} status >/dev/null
if [[ $? -ne 0 ]]
then
    ${PORTMAP} start 2>$ERR || cmd_err 1 "${PORTMAP} start"
fi

#
# On the HMC, call nfsserver.  On Redhat, call nfs
#
if [[ -s ${NFSSERVER} ]]
then
    # now start the nfssever
    ${NFSSERVER} status >/dev/null
    if [[ $? -ne 0 ]]
    then
	${NFSSERVER} start 2>$ERR || cmd_err 1 "${NFSSERVER} start"
    fi
else
    # the status for nfs does not return a non-zero value if stopped
    ${NFS} status >${TMPDIR}/nfs.status 2>$ERR || cmd_warn "${NFS} status"
    if [[ -s ${TMPDIR}/nfs.status ]]
    then
	if ${GREP} "stopped" ${TMPDIR}/nfs.status >/dev/null 2>/dev/null
	then
	    ${NFS} start || err 1 "Failed to start %s.\n" "nfs"
	fi
    fi
fi

#
# Determine the hostname of the NIMOL server
#
[[ ! -s $NIMOL_CONF ]] && err 1 "The file %s does not exist.\n" "${NIMOL_CONF}"
NIMOL_SERVER=$( ${AWK} '{if ( $1 == "NIMOL_SERVER" ) print $2;}' $NIMOL_CONF )
[[ -z $NIMOL_SERVER ]] && err 1 "Unable to determine the hostname of the NIMOL server.\n"

#
# Determine IP address of the NIMOL server
#
get_ipaddr_from_hostname ${NIMOL_SERVER}
[[ -z $IP_OUT ]] && err 1 "Unable to determine IP address for hostname \"%s\".  Please update /etc/hosts or dns.\n" "${NIMOL_SERVER}"
NIMOL_SERVER_IP=${IP_OUT}


# Determine NIMOL_SYSLOG_FACILITY
NIMOL_SYSLOG_FACILITY=$( ${AWK} '{if ( $1 == "NIMOL_SYSLOG_FACILITY" ) print $2;}' $NIMOL_CONF 2>$ERR )
[[ $? != 0 ]] && cmd_err 1 "${AWK}"
[[ -z $NIMOL_SYSLOG_FACILITY ]] && err 1 "Unable to find %s in %s\n" "NIMOL_SYSLOG_FACILITY" "$NIMOL_CONF"

#
# Determine the tftpboot directory 
#
[[ ! -s $NIMOL_CONF ]] && err 1 "The file %s does not exist.\n" "${NIMOL_CONF}"
NIMOL_TFTPBOOT=$( ${AWK} '{if ( $1 == "NIMOL_TFTPBOOT" ) print $2;}' $NIMOL_CONF )

#
# If an ip address is associated with a hostname, then use that ip address
# Otherwise, add the specified ip address and hostname to /etc/hosts
#
get_ipaddr_from_hostname ${CHOSTNAME}

if [[ -z ${IP_OUT} ]]
then
    # An ip address wasn't found for the hostname, was an ip address passed
    # as a parameter
    if [[ -z $IP_ADDR ]]; then
	err 1 "Unable to resolve hostname \"%s\".  Please specify an IP address.\n" "${CHOSTNAME}"
    else
	# add an entry into /etc/hosts
	$ECHO "$IP_ADDR $CHOSTNAME" >>/etc/hosts
	EDIT_HOSTS_SUCCESS=yes
	msg "Added \"%s\" to the file \"%s\"\n" "$IP_ADDR $CHOSTNAME" "/etc/hosts"

	if [[ -s $NIMOL_CONF ]]
	then
		echo "HOSTS_ENTRY $CHOSTNAME" >> $NIMOL_CONF
	else
		err 1 "The file %s does not exist.\n" $NIMOL_CONF
	fi
    fi
fi


#
# if an ip address was specified, make sure it matches the one found
#
if [[ -n ${IP_OUT} ]]
then
    if [[ -n $IP_ADDR ]]
    then
	if [[ $IP_ADDR != $IP_OUT ]]; then
	    err 1 "The specified ip address \"%s\" does not match the one found \"%s\".\n" $IP_ADDR $IP_OUT
        fi
    else
	IP_ADDR=$IP_OUT
    fi
fi
	
ping -w 10 -c 1 $CHOSTNAME >/dev/null 2>$ERR
rc=$?
if [[ $rc -eq 0 ]]
then
	warn "The hostname \"%s\" is in use.\n" "$CHOSTNAME"
elif [[ $rc -eq 2 ]]
then
	# another error may exist, but most likely the hostname is unresolveable
	cmd_err 1 "ping -w 10 -c 1 $CHOSTNAME"
else
	# rc -eq 1
	msg "The hostname \"%s\" will be used.\n" "$CHOSTNAME"
fi

#
# Edit the /etc/nimol.conf file with the client being installed
#
if [[ -s $NIMOL_CONF ]]
then
	if ! ${AWK} '{if ( $1 == "CLIENT" && $2 == hostname ) exit 1;}' hostname="$CHOSTNAME" $NIMOL_CONF
	then
		# the client already exists, exit
		err 1 "The client \"%s\" already exists.\n" "${CHOSTNAME}"
	else
	    $ECHO "CLIENT $CHOSTNAME $MAC_ADDR $IP_ADDR $SUBNET_MASK $LABEL installing" >>$NIMOL_CONF
	    EDIT_CONF_SUCCESS=yes
	    msg "Added \"%s\" to the file \"%s\"\n" "CLIENT $CHOSTNAME" "$NIMOL_CONF"
	fi	
else
    err 1 "The file %s does not exist.\n" $NIMOL_CONF
fi


#
# determine the location of the AIX install resources
#
[[ ! -s $NIMOL_CONF ]] && err 1 "The file %s does not exist.\n" $NIMOL_CONF

SOURCE_DIR=$( ${AWK} '{if ( $1 == "LABEL" && $2 == label ) print $3;}' label="$LABEL" $NIMOL_CONF )
if [[ -z $SOURCE_DIR ]]
then
	# the label does not exist, print the valid labels and exit
        VALID_LABELS=$( ${AWK} '{if ( $1 == "LABEL" ) print $2;}' $NIMOL_CONF )
	err 1 "The label \"%s\" does not exist. Valid labels are:\n%s\n" "$LABEL" "$VALID_LABELS"
fi

#
# export the target directory if the directory is not globally exported
#
if [[ ! -s /etc/exports ]] || ${AWK} '{if ( $1 == dir && $2 == "*(rw,insecure,no_root_squash)" ) exit 1;}' dir="${SOURCE_DIR}" /etc/exports
then
    ${EXPORTFS} -i -o rw,insecure,no_root_squash ${CHOSTNAME}:${SOURCE_DIR} 2>$ERR || \
	cmd_err 1 "${EXPORTFS} -i -o rw,insecure,no_root_squash ${CHOSTNAME}:${SOURCE_DIR}"
    NFS_EXPORT_SUCCESS=yes
    msg "Executed %s.\n" "${EXPORTFS} -i -o rw,insecure,no_root_squash ${CHOSTNAME}:${SOURCE_DIR}"
fi

#are we using nimol_bootreplyd?  or dhcp?
if [[ $nimol_br_en = "yes" ]]
then
	#get the following elements for the config file:
	#  hostname, ip addr, subnet mask, mac addr, gateway, boot image
	[[ $MAC_ADDR != "none" ]] && ha=$($ECHO $MAC_ADDR | $SED 's/://g')

	if [[ -n ${NIMOL_TFTPBOOT} ]]; then
		# if tftpd is passed "-s /tftpboot", then don't specify full path
		bf=$CHOSTNAME
	else
		bf="${TFTPBOOT}/$CHOSTNAME"
	fi

	#here, check if there's already an entry for this client and remove it if so
	if $SED "s/^.*ip=$IP_ADDR.*$//g" $NIMOL_BOOTREPLYD_CONF > $TMPDIR/nbrconf.$$ 
	then
		line=$( $GREP "ip=$IP_ADDR" $NIMOL_BOOTREPLYD_CONF )
		[[ -n $line ]] && msg "Removed \"%s\" from the file \"%s\"\n" "$line" "$NIMOL_BOOTREPLYD_CONF"
		$MV $TMPDIR/nbrconf.$$ $NIMOL_BOOTREPLYD_CONF
	fi

	ENTRY="$CHOSTNAME:ip=$IP_ADDR:ht=ethernet:gw=$CGATEWAY_IP:sm=$SUBNET_MASK:bf=$bf:sa=$NIMOL_SERVER_IP"
	[[ $MAC_ADDR != "none" ]] && ENTRY=$ENTRY":ha=$ha"

	echo $ENTRY >> $NIMOL_BOOTREPLYD_CONF || err 1 "The file %s does not exist.\n" $NIMOL_BOOTREPLYD_CONF
	EDITED_BOOTREPLY_CONF="yes"
	msg "Added \"%s\" to the file \"%s\"\n" "$ENTRY" "$NIMOL_BOOTREPLYD_CONF"

	if [[ -s $NIMOL_BOOTREPLYD_PID ]]
	then
		file_pid=$( $CAT $NIMOL_BOOTREPLYD_PID )
		running_pid=$( $PS | $SED 1d | $AWK -vpid=$file_pid '$2 == pid {print $2}' )
	fi

	if [[ -n $running_pid ]]
	then
		[[ -s $NIMOL_BOOTREPLYD_PID ]] && pid=$($CAT $NIMOL_BOOTREPLYD_PID) 
		kill -HUP $pid || warn "Failed to restart %s.\n" "nimol_bootreplyd" #send HUP signal to rehash
		msg "Executed %s.\n" "kill -HUP $pid"
	else
		#start nimol_bootreplyd
		[[ -f $NIMOL_BOOTREPLYD_CONF ]] || >$NIMOL_BOOTREPLYD_CONF
		$NIMOL_BOOTREPLYD_START || err 1 "Failed to start %s.\n" "nimol_bootreplyd"
		msg "Executed %s.\n" "$NIMOL_BOOTREPLYD_START"
		STARTED_BOOTREPLY="yes"
	fi
else
	#
	# Add the client to the /etc/dhcpd.conf file
	#
	[[ ! -s /etc/dhcpd.conf ]] && err 1 "The file %s does not exist.\n" /etc/dhcpd.conf

	# determine the client's subnet
	get_subnet ${IP_ADDR} ${SUBNET_MASK}
	[[ -z ${SUBNET} ]] && cmd_err 1 "Unable to determine the \"%s\" for \"%s\".\n" "subnet" ${IP_ADDR}

	# add the client's subnet to /etc/dhcpd.conf if it does not exist
	if ! ${GREP} -e "subnet[[:space:]*]*${SUBNET}" /etc/dhcpd.conf >/dev/null 2>/dev/null
	then
		# add "subnet $SUBNET" to the end of the file
		$ECHO "\nsubnet $SUBNET netmask $SUBNET_MASK { # nimol" >>/etc/dhcpd.conf
		$ECHO "}\n" >>/etc/dhcpd.conf

		$ECHO "DHCP_SUBNET_ADDED ${SUBNET}" >>$NIMOL_CONF
		msg "Added \"%s\" to the file \"%s\"\n" "subnet $SUBNET netmask $SUBNET_MASK" "/etc/dhcpd.conf"
	fi

	if ${GREP} -e "^[[:space:]*]*host[[:space:]*]*$CHOSTNAME" /etc/dhcpd.conf >/dev/null 2>/dev/null
	then
		err 1 "A host with the hostname \"%s\" already exists\nin %s.  Remove the stanza before continuing.\n" "$CHOSTNAME" "/etc/dhcpd.conf"
	elif ${GREP} -e "^[[:space:]*]*[^#].*$MAC_ADDR" /etc/dhcpd.conf >/dev/null 2>/dev/null
	then
		err 1 "A host with the MAC address \"%s\" already exists\nin %s.  Remove the stanza before continuing.\n" "$MAC_ADDR" "/etc/dhcpd.conf"
	else
		# add the stanza for the client
		$ECHO "\nhost $CHOSTNAME {  # nimol client" >> /etc/dhcpd.conf
		$ECHO "\thardware ethernet $MAC_ADDR;" >> /etc/dhcpd.conf
		$ECHO "\tfixed-address $IP_ADDR;" >> /etc/dhcpd.conf
		$ECHO "\tnext-server $NIMOL_SERVER_IP;" >> /etc/dhcpd.conf
		if [[ -n ${NIMOL_TFTPBOOT} ]]; then
			# if tftpd is passed "-s /tftpboot", then don't specify full path
			$ECHO "\tfilename \"$CHOSTNAME\";" >> /etc/dhcpd.conf
		else
			$ECHO "\tfilename \"${TFTPBOOT}/$CHOSTNAME\";" >> /etc/dhcpd.conf
		fi
		$ECHO "} # nimol $CHOSTNAME\n" >> /etc/dhcpd.conf

		EDIT_DHCPD_SUCCESS=yes
		msg "Added \"%s\" to the file \"%s\"\n" "host $CHOSTNAME" "/etc/dhcpd.conf"

		${DHCPD} restart || err 1 "Failed to restart %s.\n" "${DHCPD}"
	fi
fi

#
# symbolically link the boot image
#
[[ ! -s ${TFTPBOOT}/${LABEL}.chrp.mp.ent ]] && \
    err 1 "The file %s does not exist.\n" "${TFTPBOOT}/${LABEL}.chrp.mp.ent"

#
# if tftpd is passed "-s /tftpboot", then don't link the full path
#
if [[ -n ${NIMOL_TFTPBOOT} ]]; then
    cd ${NIMOL_TFTPBOOT} || \
	cmd_err 1 "cd ${NIMOL_TFTPBOOT}"
    ${LN} -s ${LABEL}.chrp.mp.ent $CHOSTNAME 2>$ERR || \
	cmd_err 1 "${LN} -s ${LABEL}.chrp.mp.ent $CHOSTNAME"
else
    ${LN} -s ${TFTPBOOT}/${LABEL}.chrp.mp.ent ${TFTPBOOT}/$CHOSTNAME 2>$ERR || \
	cmd_err 1 "${LN} -s ${TFTPBOOT}/${LABEL}.chrp.mp.ent ${TFTPBOOT}/$CHOSTNAME"
fi

LINK_BOOTI_SUCCESS=yes 
msg "Created %s.\n" "${TFTPBOOT}/$CHOSTNAME"

#
# create the static ARP entry for the client if on the same subnet as the nimol server
#
if [[ $NIMOL_SUBNET = $SUBNET ]]
then
    ${ARP} -s $CHOSTNAME $MAC_ADDR -t ether 2>$ERR || \
	cmd_err 1 "${ARP} -s $CHOSTNAME $MAC_ADDR -t ether"
    ADD_ARP_SUCCESS=yes
    msg "Executed %s.\n" "${ARP} -s $CHOSTNAME $MAC_ADDR -t ether"
fi

#
# Modify the firewall
#
if [[ -s ${IPTABLES} ]]
then
    # accept all packets from the host
    ${IPTABLES} -I INPUT 1 -s $CHOSTNAME -j ACCEPT
    IPTABLES_SUCCESS="yes"
    msg "Executed %s.\n" "${IPTABLES} -I INPUT 1 -s $CHOSTNAME -j ACCEPT"
fi

#
# Check that the required resources exist and see which
# optional resources exist
#
[[ ! -s ${SOURCE_DIR}/$SPOT ]] && \
    err 1 "The file %s does not exist.\n" "${SOURCE_DIR}/$SPOT"

if [[ -s ${SOURCE_DIR}/${MKSYSB} ]]; then
    NIM_MOUNTS="${NIM_MOUNTS} ${NIMOL_SERVER}:${SOURCE_DIR}/${MKSYSB}:/NIM_BOS_IMAGE:file"
    MKSYSB_EXISTS="yes"
fi

if [[ -s ${SOURCE_DIR}/${BOSINST_DATA} ]]; then
    NIM_MOUNTS="${NIM_MOUNTS} ${NIMOL_SERVER}:${SOURCE_DIR}/${BOSINST_DATA}:/NIM_BOSINST_DATA:file"
    BIDATA_EXISTS="yes"
fi

if [[ -s ${SOURCE_DIR}/${LPP_SOURCE} ]]; then
    NIM_MOUNTS="${NIM_MOUNTS} ${NIMOL_SERVER}:${SOURCE_DIR}/${LPP_SOURCE}:/SPOT/usr/sys/inst.images:dir"
    LPPSRC_EXISTS="yes"
fi

if [[ -s ${SOURCE_DIR}/${IMAGE_DATA} ]]; then
    NIM_MOUNTS="${NIM_MOUNTS} ${NIMOL_SERVER}:${SOURCE_DIR}/${IMAGE_DATA}:/NIM_IMAGE_DATA:file"
    IMDATA_EXISTS="yes"
fi

[[ -s ${SOURCE_DIR}/${RESOLV_CONF} ]]  && RESOLV_EXISTS="yes"

if [[ -s ${SOURCE_DIR}/${CHOSTNAME}.script ]]; then
    CUST_SCRIPT_LOC1="${SOURCE_DIR}/${CHOSTNAME}.script"
    CUSTSC_EXISTS="yes"
    if [[ ! -x ${SOURCE_DIR}/${CHOSTNAME}.script ]]
    then
	${CHMOD} +x ${SOURCE_DIR}/${CHOSTNAME}.script || \
	    cmd_warn "${CHMOD} +x ${SOURCE_DIR}/${CHOSTNAME}.script"
    fi
fi
if [[ -s ${SOURCE_DIR}/${CUST_SCRIPT} ]]; then
    CUST_SCRIPT_LOC2="${SOURCE_DIR}/${CUST_SCRIPT}"
    CUSTSC_EXISTS="yes"
    if [[ ! -x ${SOURCE_DIR}/${CUST_SCRIPT} ]]
    then
	${CHMOD} +x ${SOURCE_DIR}/${CUST_SCRIPT} || \
	    cmd_warn "${CHMOD} +x ${SOURCE_DIR}/${CUST_SCRIPT}"
    fi
fi

[[ -z $MKSYSB_EXISTS && -z $LPPSRC_EXISTS ]] && \
    err 1 "The directory \"%s\" must have a mksysb or a lpp_source.\n"
#
# create the script
#
CSCRIPT="${SOURCE_DIR}/scripts/${CHOSTNAME}.script"

$ECHO "#!/bin/ksh\n" > ${CSCRIPT}
$ECHO "# nim_script for ${CHOSTNAME}" >> ${CSCRIPT}
$ECHO "result=success\n" >> ${CSCRIPT}
$ECHO "export NIM_NON_41_MASTER=yes" >> ${CSCRIPT}
$ECHO "export NIM_SCRIPT=yes" >> ${CSCRIPT}
if [[ $REMAIN_CLIENT != "no" ]]; then
    $ECHO "# NIM client initialization" >> ${CSCRIPT}
    $ECHO "/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_mk_nimclient \${VERBOSE} \\" >> ${CSCRIPT}
    $ECHO "\t-ahostname=${CHOSTNAME} \\" >> ${CSCRIPT}
    $ECHO "\t-aip=${IP_ADDR} \\" >> ${CSCRIPT}
    $ECHO "\t-acable_type=N/A \\" >> ${CSCRIPT}
    $ECHO "\t-asnm=${SUBNET_MASK}" >> ${CSCRIPT}
    $ECHO "[[ \$? != 0 ]] && result=failure\n" >> ${CSCRIPT}
fi
if [[ $RESOLV_EXISTS ]]; then
    $ECHO "# /etc/resolv.conf " >> ${CSCRIPT}
    $ECHO "/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_cp_resolv \${VERBOSE} \\" >> ${CSCRIPT}
    $ECHO "\t-a location=${NIMOL_SERVER}:${SOURCE_DIR}/${RESOLV_CONF}\n" >> ${CSCRIPT}
fi
if [[ $CUSTSC_EXISTS ]]; then
    if [[ -n ${CUST_SCRIPT_LOC1} ]]
    then
	$ECHO "/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_script \${VERBOSE} \\" >> ${CSCRIPT}
	$ECHO "\t-alocation=\"${NIMOL_SERVER}:${CUST_SCRIPT_LOC1}\"" >> ${CSCRIPT}
	$ECHO "script_rc=\$?" >> ${CSCRIPT}
	$ECHO "[[ \${script_rc} != 0 ]] && result=failure\n" >> ${CSCRIPT}
    fi

    if [[ -n ${CUST_SCRIPT_LOC2} ]]
    then
	$ECHO "/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_script \${VERBOSE} \\" >> ${CSCRIPT}
	$ECHO "\t-alocation=\"${NIMOL_SERVER}:${CUST_SCRIPT_LOC2}\"" >> ${CSCRIPT}
	$ECHO "script_rc=\$?" >> ${CSCRIPT}
	$ECHO "[[ \${script_rc} != 0 ]] && result=failure\n" >> ${CSCRIPT}
    fi
fi
$ECHO "[[ \${result} = success ]] && exit 0 || exit 1" >> ${CSCRIPT}

${CHMOD} 755 ${CSCRIPT} 2>$ERR || cmd_warn "${CHMOD} 755 ${CSCRIPT}"
MK_CSCRIPT_SUCCESS=yes
msg "Created %s.\n" "${CSCRIPT}"

#
# create the niminfo file
NIMINFO_FILE=${TFTPBOOT}/${CHOSTNAME}.info

$ECHO "#------------------ Network Install Manager ---------------" > ${NIMINFO_FILE}
$ECHO "# warning - this file contains NIM configuration information" >> ${NIMINFO_FILE}
$ECHO "#       and should only be updated by NIM" >> ${NIMINFO_FILE}
$ECHO "export NIM_SERVER_TYPE=linux" >> ${NIMINFO_FILE}
$ECHO "export NIM_SYSLOG_PORT=514" >> ${NIMINFO_FILE}
$ECHO "export NIM_SYSLOG_FACILITY=${NIMOL_SYSLOG_FACILITY}" >> ${NIMINFO_FILE}
$ECHO "export NIM_NAME=$CHOSTNAME" >> ${NIMINFO_FILE}
$ECHO "export NIM_HOSTNAME=$CHOSTNAME" >> ${NIMINFO_FILE}
$ECHO "export NIM_CONFIGURATION=standalone" >> ${NIMINFO_FILE}
$ECHO "export NIM_MASTER_HOSTNAME=$NIMOL_SERVER" >> ${NIMINFO_FILE}
if [[ $REMAIN_CLIENT = "no" ]]; then
    $ECHO "export REMAIN_NIM_CLIENT=no" >> ${NIMINFO_FILE}
else
    $ECHO "export REMAIN_NIM_CLIENT=yes" >> ${NIMINFO_FILE}
fi
$ECHO "export RC_CONFIG=rc.bos_inst" >> ${NIMINFO_FILE}
$ECHO "export NIM_BOSINST_ENV=\"/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_bosinst_env\"" >> ${NIMINFO_FILE}
$ECHO "export NIM_BOSINST_RECOVER=\"/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_bosinst_env -a hostname=$CHOSTNAME\"" >> ${NIMINFO_FILE}
[[ -n $IMDATA_EXISTS ]] && \
    $ECHO "export NIM_IMAGE_DATA=/NIM_IMAGE_DATA" >> ${NIMINFO_FILE}
[[ -n $BIDATA_EXISTS ]] && \
    $ECHO "export NIM_BOSINST_DATA=/NIM_BOSINST_DATA" >> ${NIMINFO_FILE}
$ECHO "export SPOT=${NIMOL_SERVER}:${SOURCE_DIR}/SPOT/usr" >> ${NIMINFO_FILE}
#[[ -n $CUSTSC_EXISTS || -n $RESOLV_EXISTS || $REMAIN_CLIENT = "no" ]] && \
    $ECHO "export NIM_CUSTOM=\"/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_script -a location=${NIMOL_SERVER}:${CSCRIPT}\"" >> ${NIMINFO_FILE}
if [[ -n $MKSYSB_EXISTS ]]; then
    $ECHO "export NIM_BOS_IMAGE=/NIM_BOS_IMAGE" >> ${NIMINFO_FILE}
    $ECHO "export NIM_BOS_FORMAT=mksysb" >> ${NIMINFO_FILE}
else
    $ECHO "export NIM_BOS_IMAGE=/SPOT/usr/sys/inst.images/installp/ppc/bos" >> ${NIMINFO_FILE}
    $ECHO "export NIM_BOS_FORMAT=rte" >> ${NIMINFO_FILE}
fi
$ECHO "export NIM_HOSTS=\" ${IP_ADDR}:${CHOSTNAME} ${NIMOL_SERVER_IP}:${NIMOL_SERVER}\"" >> ${NIMINFO_FILE}
$ECHO "export NIM_MOUNTS=\"${NIM_MOUNTS}\"" >> ${NIMINFO_FILE}
if [[ -n ${CGATEWAY_IP} ]]
then
    $ECHO "export ROUTES=\" default:0:${CGATEWAY_IP} \"\n" >> ${NIMINFO_FILE}
else
    $ECHO "\n" >> ${NIMINFO_FILE}
fi

MK_NIMINFO_SUCCESS=yes
msg "Created %s.\n" "${NIMINFO_FILE}"

msg "Successfully setup %s for a NIMOL install\n" "${CHOSTNAME}"
exit 0
