#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos72Q src/bos/usr/lib/nim/methods/c_mkbooti.sh 1.22.3.2 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1993,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 

# @(#)45	1.22.3.2  src/bos/usr/lib/nim/methods/c_mkbooti.sh, cmdnim, bos72Q, q2019_26A2 6/21/19 14:05:01 

#   COMPONENT_NAME: CMDNIM
#
#   FUNCTIONS: ./usr/lib/nim/methods/c_mkbooti.sh
#		
#
#   ORIGINS: 27
#
#
#   (C) COPYRIGHT International Business Machines Corp. 1993, 1996
#   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     --------------------------------
IF_SUPPORTED="if_supported"
NETDIR="lib/boot/network"
KERNELDIR='lib/boot'
PROTODIR='lib/boot/network'
PROTO='lib/boot/network/*.proto'
RS6K_PROTO='lib/boot/network/rs6k.*.proto'
RS6KSMP_PROTO='lib/boot/network/rs6ksmp.*.proto'
CHRP_PROTO='lib/boot/network/chrp.*.proto'
CHRPSMP_PROTO='lib/boot/network/chrpsmp.*.proto'
PROTOEXT='lib/boot/protoext'

#---------------------------- module globals    --------------------------------
REQUIRED_ATTRS="location name"
OPTIONAL_ATTRS="platform debug if_defined if_remove"
location=""
name=""
debug=""
preview=""
typeset proto_files=""
typeset boot_image_created=""
cmd="${BOSBOOT} -a"
typeset -i tmp_needed=0
typeset -i tftpboot_needed=0
typeset -i num_booti=0
enter_dbg_mp=""
enter_dbg_up=""
enter_dbg_64=""
typeset boot_kernel=""
typeset boot_platform=""
typeset boot_network=""

#---------------------------- mkboot_images_41 --------------------------------
#
# NAME: mkbooti_images_41
#
# FUNCTION:
#      This function builds boot images for 4.1 SPOTs.	
#      It creates a boot image for each file in
#      /usr/lib/boot/network/*.proto in the SPOT that
#      contains a valid platform type.  The platform
#      type must be one of the valid platforms passed in
#      from C_CKSPOT.  Boot images created by this routine
#      use the following naming convention:
#          <spot_name>.<platform>.<if_type> 
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#			cmd
#
# RETURNS: (int)
#		0							= success
#
# OUTPUT:
#		writes IF_SUPPORTED attr assignments to stdout
#       in the form: if_supported = <platform> <if_type>
#-------------------------------------------------------------------------------
function mkboot_images_41 {

typeset types=""
typeset platform_type=""
typeset print_platform=""
typeset if_type=""
typeset supported_platform=""
typeset kernel=""
typeset bi_name=""
typeset pf=""
typeset	rs6k_proto_files=""
typeset remove_rs6ksmp=""
typeset remove_chrpsmp=""

	# the NIM master is at 4.1 -- so create 4.1 boot images
	# for this 4.2 SPOT -- build the rs6ksmp boot images if
	# rs6k platform is supported using the rs6k proto files 
	# chrp proto files will also be used to build the chrpsmp
	# boot images.
    if (( (( (( ${spot_version} == 4 )) && (( ${spot_release} >= 2 )) )) || (( ${spot_version} > 4 )) ))
	then
		# get list of all rs6k proto files
		rs6k_proto_files="${location}/${RS6K_PROTO}"

		# get list of all chrp proto files
		chrp_proto_files="${location}/${CHRP_PROTO}"

		# link rs6k proto files to rs6ksmp proto files
		for pf in ${rs6k_proto_files}
		do
      		if_type=`echo ${pf} | ${CUT} -d"." -f2`
			${LN} -s ${pf} ${location}/${NETDIR}/rs6ksmp.${if_type}.proto
		done

		# link chrp proto files to chrpsmp proto files
		for pf in ${chrp_proto_files}
		do
      		if_type=`echo ${pf} | ${CUT} -d"." -f2`
			${LN} -s ${pf} ${location}/${NETDIR}/chrpsmp.${if_type}.proto
		done

		# get proto list again after changes
		proto_files="${location}/${PROTO}"

		# link rs6k proto config to rs6ksmp 
 		if [[ -s ${location}/${PROTOEXT}/rs6k.pcfg ]]
		then
			${LN} -s ${location}/${PROTOEXT}/rs6k.pcfg \
				${location}/${PROTOEXT}/rs6ksmp.pcfg
		fi

		# link the rs6k mkboot to rs6ksmp
		if [[ -s ${location}/lib/boot/bin/mkboot_rs6k ]]
		then
			${LN} -s ${location}/lib/boot/bin/mkboot_rs6k \
				${location}/lib/boot/bin/mkboot_rs6ksmp
		fi

		# remove rs6ksmp proto files when done
		remove_rs6ksmp=yes

		# remove chrpsmp proto files when done
		remove_chrpsmp=yes
	fi

	#
	# For each proto file in the SPOT...
	#
	for pf in ${proto_files}
	do
		#
		# Skip any bad proto files
		#
		[[ ! -s ${pf} ]] && continue

		# expecting proto files to be named like:
		#		<platform>.<interface type>.proto
		# ignore the parent directoy pathname & separate the proto filename 
		#		into these parts
		IFS='.'
		set -- ${pf##*/}
		IFS=${OLD_IFS}

		# how many fields in the proto filename?
		if [[ $# -eq 2 ]]
		then

			# assume the platform is rs6k
			platform_type=rs6k
			if_type=${1}

		elif [[ $# -eq 3 ]]
		then

			platform_type=${1}
			if_type=${2}

		else

			warning ${ERR_VALUE} ${pf} ".proto filename"
			continue

		fi

		# interface type must exist in predefined device database or bosboot
		#		will barf
		[[ -z "$( ${ODMGET} -qprefix=${if_type} PdDv 2>/dev/null )" ]] && continue

		# platform must match one of the types specified in the platform attr
		#		which was passed by the caller
		for types in ${platform}
		do

			supported_platform=${types%%=*}
			kernel=${location}/${KERNELDIR}/${types##*=}

			# does this proto file match a supported platform type?
			[[ ${platform_type} != ${supported_platform} ]] && continue

			# skip bad kernels
			[[ ! -s ${kernel} ]] && continue

			# construct a boot image pathname like this:
			# /tftpboot/<SPOTname>.<platform type>.<network interface type>
			bi_name="${TFTPBOOT}/${name}.${platform_type}.${if_type}"

			# Save the original platform type to print out
			# later as a supported platform for booting.
			# Do this in case the platform_type is changed for
			# chrpsmp.
			print_platform=${platform_type}

			# The chrpsmp type is really chrp with an mp kernel.
			# Change the parameters accordingly for the bosboot
			# command.
			if [[ ${platform_type} = "chrpsmp" ]]
			then
			  platform_type="chrp"
			  pf=`echo ${pf} | sed s/chrpsmp/chrp/`
			fi

			# create a network boot image
			if ${cmd}	-b ${bi_name} \
							-d /dev/${if_type} \
							-T ${platform_type} \
							-p ${pf} \
							-k ${kernel} 2>${ERR} 1>&2
			then

				# just previewing info?
				if [[ -n "${preview}" ]]
				then

					preview_data
					continue

				fi

				# print out the attr assignment so that m_instspot can add it to
				#		the SPOTs definition so that NIM knows what kind of interfaces
				#		this SPOT supports
				print "${IF_SUPPORTED}=${platform_type} ${if_type}"

				# flag that we've created a boot image for this platform type
				[[ "${boot_image_created}" != *\ ${platform_type}=+([! ])\ * ]] &&
					eval boot_image_created=\"${boot_image_created} \
${platform_type}=\$enter_dbg_${kernel##*_} \"

			else

				# cache the error messages from BOSBOOT
				${CAT} ${ERR} >>${TMPDIR}/bosboot.errors 2>/dev/null

			fi

		done # for each platform type

	done # for each proto file

	# remove any rs6ksmp proto files that we created
	if [[ ${remove_rs6ksmp} = yes ]]
	then
		${RM} ${location}/${RS6KSMP_PROTO}
		${RM} ${location}/${PROTOEXT}/rs6ksmp.pcfg
		${RM} ${location}/lib/boot/bin/mkboot_rs6ksmp	
	fi

	# remove any chrpsmp proto files that we created
	if [[ ${remove_chrpsmp} = yes ]]
	then
		${RM} ${location}/${CHRPSMP_PROTO}
	fi

} # end mkboot_images_41

#---------------------------- mkboot_images_42 --------------------------------
#
# NAME: mkbooti_images_42
#
# FUNCTION:
#       This function rebuilds the boot images for SPOTs created 
#       on 4.2 or later.  It creates a UP and MP boot image for each 
#       /usr/lib/boot/network/*.proto file located in the SPOT. 
#       For 5.4 SPOTs and later, only 64bit boot images are created.
#       Boot images created by this routine will use the following  
#       naming convention:
#           <spot_name>.<platform>.<kernel>.<if_type> 
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#			cmd
#
# RETURNS: (int)
#		0							= success
#
# OUTPUT:
#		writes IF_SUPPORTED attr assignments on stdout
#       in the form: if_supported = <platform>.<kernel> <if_type>
#-------------------------------------------------------------------------------
function mkboot_images_42 {

typeset types=""
typeset platform_type=""
typeset if_type=""
typeset supported_platform=""
typeset kernel=""
typeset bi_name=""
typeset pf=""
typeset duplicate_platform="no"

	#
	# For each proto file in the SPOT...
	#
	for pf in ${proto_files}
	do
		#
		# Skip any bad proto files
		#
		[[ ! -s ${pf} ]] && continue


		# expecting proto files to be named like:
		#		<platform>.<interface type>.proto
		# ignore the parent directoy pathname & separate the proto filename 
		#		into these parts
		IFS='.'
		set -- ${pf##*/}
		IFS=${OLD_IFS}

		# how many fields in the proto filename?
		if [[ $# -eq 2 ]]
		then

			# assume the platform is rs6k
			platform_type=rs6k
			if_type=${1}

		elif [[ $# -eq 3 ]]
		then

			platform_type=${1}
			if_type=${2}

		else

			warning ${ERR_VALUE} ${pf} ".proto filename"
			continue

		fi

		# interface type must exist in predefined device database or bosboot
		#		will barf
		[[ -z "$( ${ODMGET} -qprefix=${if_type} PdDv 2>/dev/null )" ]] && continue

		if [[ -n "${boot_kernel}" ]]
		then
			KERNELS=${location}/${KERNELDIR}/unix_${boot_kernel}
		elif (( (( (( ${spot_version} == 5 )) && (( ${spot_release} >= 4 )) )) || (( ${spot_version} > 5 )) ))
		then
			KERNELS=${location}/${KERNELDIR}/unix_64
		elif (( (( ${spot_version} == 5 )) && (( ${spot_release} = 3 )) ))
		then
			KERNELS=${location}/${KERNELDIR}/unix_@(mp|64)
		else
			KERNELS=${location}/${KERNELDIR}/unix_[um]p
		fi

        # build a MP and UP boot image for each proto file
	    for kernel in ${KERNELS}
        do
            duplicate_platform=no

            [[ ! -s ${kernel} ]] && continue            

			# construct a boot image pathname like this:
			# /tftpboot/<SPOTname>.<platform type>.<kernel>.<if_type>
            kernel_type=`${BASENAME} ${kernel} | ${CUT} -d"_" -f2`
			bi_name="${TFTPBOOT}/${name}.${platform_type}.${kernel_type}.${if_type}"

			# create a network boot image
			if ${cmd}	-b ${bi_name} \
							-d /dev/${if_type} \
							-T ${platform_type} \
							-p ${pf} \
							-k ${kernel} 2>${ERR} 1>&2
			then

				# just previewing info?
				if [[ -n "${preview}" ]]
				then

					preview_data
					continue

				fi

			# POC - Temporary code that will be removed with firmware limitations eventually get lifted.
			${C_BOOTDISKHDR} -a spot=$name -a if_defined=${platform_type}.${kernel_type}.${if_type}


			    # print out the attr assignment so that m_instspot can add it to
			    # the SPOTs definition so that NIM knows what kind of interfaces
			    # this SPOT supports
				print "${IF_SUPPORTED}=${platform_type}.${kernel_type} ${if_type}"

   		        # has this platform already been added?
		        for types in ${boot_image_created}
		        do
                    if [[ ${types%%=*} = ${platform_type}.${kernel##*_} ]]
                    then
                        duplicate_platform=yes
                        break
                    fi
		        done

				# flag that we've created a boot image for this platform 
                if [[ ${duplicate_platform} = no ]]
                then 
				    [[ "${boot_image_created}" != *\ ${platform_type}=+([! ])\ * ]] &&
					if [[ -n ${if_defined} ]]
					then
					  eval boot_image_created=\"${boot_image_created} \
					      ${platform_type}.${kernel##*_}.${if_type}=\$enter_dbg_${kernel##*_} \"
					else
					  eval boot_image_created=\"${boot_image_created} \
					      ${platform_type}.${kernel##*_}=\$enter_dbg_${kernel##*_} \"
					fi
                fi

			else

				# cache the error messages from BOSBOOT
				${CAT} ${ERR} >>${TMPDIR}/bosboot.errors 2>/dev/null

			fi

		done # for each kernel 

	done # for each proto file


} # end mkbooti_images_42

#---------------------------- turn_debug_on     --------------------------------
#
# NAME: turn_debug_on
#
# FUNCTION:
#		makes the required changed to enable the kernel debugger in the network
#			boot images
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#			cmd
#
# RETURNS: (int)
#		0							= success
#
# OUTPUT:
#		writes enter_dbg symbol addresses to stdout
#-------------------------------------------------------------------------------
function turn_debug_on {

	typeset kernel=""
	typeset kernel_type=""
	typeset enter_dbg=""

	# we want a network boot image which has the kernel debugger enabled
	cmd="${cmd} -I"

	# turn on debugging in the rc.boot file
	if ${AWK} '$0 !~ /^[[:space:]]*export NIM_DEBUG=/{print};\
				/[ 	]*unset NIM_DEBUG/{print "export NIM_DEBUG=\"set -x\""}'\
		${RCBOOT} >${TMPDIR}/rc.boot 2>${ERR}
	then

		${CAT} ${TMPDIR}/rc.boot >${RCBOOT} 2>${ERR} || err_from_cmd ${CAT}

	fi

	# return the enter_dbg info
	for kernel in ${location}/${KERNELDIR}/unix_@(mp|up|64)
	do

		# what type of kernel?
		kernel_type=${kernel##*_}

		enter_dbg=""
		enter_dbg=$( ${NM} -X32_64 -x ${kernel} | ${GREP} enter_dbg | \
						 ${AWK} 'NR==1{print $3}' 2>/dev/null )

		# remember the enter_dbg address
		eval enter_dbg_${kernel_type}=${enter_dbg}

	done

} # end of turn_debug_on

#---------------------------- turn_debug_off    --------------------------------
#
# NAME: turn_debug_off
#
# FUNCTION:
#		changes the appropriate files to disable the kernel debugger for the
#			network boot images
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#			cmd
#
# RETURNS: (int)
#		0							= success
#
# OUTPUT:
#-------------------------------------------------------------------------------
function turn_debug_off {

	# we don't want the kernel debugger enabled
	cmd="${cmd}"

	# turn off debugging in the rc.boot file
	if ${AWK} '$0 !~ /^[[:space:]]*export NIM_DEBUG=/{print}' ${RCBOOT} \
		>${TMPDIR}/rc.boot 2>${ERR}
	then

		${CAT} ${TMPDIR}/rc.boot >${RCBOOT} 2>${ERR} || err_from_cmd ${CAT}

	fi

} # end of turn_debug_off

#---------------------------- preview_data      --------------------------------
#
# NAME: preview_data
#
# FUNCTION:
#		reads the "bosboot -q" information and writes the information to stdout
#			when parameter #1 is non-NULL
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#			1						= when non-NULL, write preview data
#		global:
#
# RETURNS: (int)
#		0							= success
#
# OUTPUT:
#		writes preview data to stdout
#-------------------------------------------------------------------------------
function preview_data {

	typeset write_data=${1}
	typeset line=""
	typeset -i new_tmp=0

	# write the preview data or read new info?
	if [[ -n "${write_data}" ]]
	then

		# write the data
		print "tmp_needed=${tmp_needed}"
		print "tftpboot_needed=${tftpboot_needed}"
		print "num_booti=${num_booti}"

	else

		# parse the "bosboot -q" output
		${CAT} ${ERR} | \
		while read line
		do
			set -- ${line}
			case ${1} in

				/tmp)
					(( ${2} > tmp_needed )) && let tmp_needed=${2}
				;;

				/|/tftpboot|/*/tftpboot)
					(( ${2} > tftpboot_needed )) && let tftpboot_needed=${2}
				;;

			esac
		done

		let num_booti+=1

	fi

} # end of preview_data

#---------------------------- mkbooti           --------------------------------
#
# NAME: mkbooti
#
# FUNCTION:
#    Determines the level of the SPOT whose boot images are being
#    rebuilt, and calls either mkboot_41 or mkboot_42 to rebuild 
#    the images. 
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#			cmd
#
# RETURNS: (int)
#		0							= success; boot images created
#
# OUTPUT:
#-------------------------------------------------------------------------------
function mkbooti {

	typeset enter_dbg=""
	typeset types=""
	typeset -i spot_version=0
	typeset -i spot_release=0

	# generate list of proto files which reside in SPOTname/usr/lib/boot/network
	if [[ -n "${if_defined}" ]]
	then
		# expecting if_defined parameters to look like:
		#		<platform>.kernel.<interface type>
		IFS='.'
		set -- ${if_defined}
		IFS=${OLD_IFS}
		boot_platform=${1}
		boot_kernel=${2}
		boot_network=${3}
		proto_files="${location}/${PROTODIR}/${boot_platform}.${boot_network}.proto"
	else
	    proto_files="${location}/${PROTO}"
	fi

	if [[ -z "${preview}" ]] && [[ -z "${if_remove}" || "${if_remove}" = "yes" ]]
	then

		#
		# We're committed to re-building the boot images, so 
		# delete all existing boot images for this SPOT. 
		#
		${RM} ${TFTPBOOT}/${name}.* 2>${ERR} || err_from_cmd ${RM}
		#
		#
		# Gather the list of available platforms in the SPOT for use
		# by the platform listing routines
		if [[ -n "${if_remove}" ]] && [[ "${if_remove}" = "yes" ]]
		then
			${LS} ${location}/${PROTO} 2>/dev/null | while read pf
			do
				pf=${pf##*/}	# remove path
				if [[ -n "$pf" ]]
				then
					echo "plat_defined=\c"
					echo $pf | ${CUT} -d'.' -f1
				fi
			done | ${SORT} -u
		fi

	fi

	if [[ -z "${preview}" ]]
	then

		# was debug specified?
		if [[ -n "${debug}" ]]
		then

			# we want a network boot image which has the kernel debugger enabled
			turn_debug_on

		else

			# we don't want the kernel debugger enabled
			turn_debug_off

		fi

	fi

    # get the version and release of the SPOT
    # whose boot images we are rebuilding
    ODMDIR=/usr/lib/objrepos ${ODMGET} -q "lpp_name='bos.rte' and update='0'" \
        product >${TMPDIR}/spot.product 2>${ERR} || err_from_cmd ${ODMGET}
    let spot_version=$( ${AWK} '$1=="ver"{print $3}' ${TMPDIR}/spot.product \
                            2>/dev/null )
    let spot_release=$( ${AWK} '$1=="rel"{print $3}' ${TMPDIR}/spot.product \
                            2>/dev/null )

    # build the boot images
    if (( (( (( ${spot_version} == 4 )) && (( ${spot_release} >= 2 )) )) || (( ${spot_version} > 4 )) ))
    then
        # if 4.1 master building a 4.2 SPOT, the platform kernel
		# pairs will be passed in -- build 4.1 version boot images
        if [[ -n "${platform}" ]]
		then
        	mkboot_images_41	
		else
		# if 4.2 master building a 4.2 SPOT or if 4.3 master building
		# all possible boot images, then boot image will be created for
		# every network proto combination.  Otherwise, only the network
		# combination passed in as the nettype will be built.
			if [[ -z "${if_remove}" ]] || [[ -n "${if_defined}" ]] 
			then
        		mkboot_images_42
			fi
		fi
    else
        mkboot_images_41	
    fi

	# replace ERR file with cached error messages
	${CAT} ${TMPDIR}/bosboot.errors >${ERR} 2>/dev/null

	# preview or errors?
	if [[ -n "${preview}" ]]
	then

		# write the preview info
		preview_data "TRUE"

	elif [[ -z "${boot_image_created}" ]] && [[ -z "${if_remove}" ]]
	then

		# no network boot images could be created
		# print the "missing" attr so that it gets added so the SPOT's definition
		print "missing=\"${MSG_MISSING_BOOTI}\""

		# display error message
		[[ -s ${ERR} ]] && err_from_cmd ${BOSBOOT} || error ${ERR_NO_BOOTI}

	elif [[ -s ${TMPDIR}/bosboot.errors ]]
	then

		warning_from_cmd ${BOSBOOT}

	fi

	if [[ -n "${debug}" ]] && [[ -n "${boot_image_created}" ]]
	then

		# print out the enter_dbg info
		for types in ${boot_image_created}
		do

			print "enter_dbg=\"${types%%=*} ${types##*=}\""

		done

	fi

} # end of mkbooti

#---------------------------- c_mkbooti         --------------------------------
#
# NAME: c_mkbooti
#
# FUNCTION:
#		creates a network boot image for each interface which has a proto file
#			in the SPOTname/usr/lib/boot/network directory
#
# EXECUTION ENVIRONMENT:
#
# NOTES:
#		calls error on failure
#
# RECOVERY OPERATION:
#
# DATA STRUCTURES:
#		parameters:
#		global:
#
# RETURNS: (int)
#		0							= boot images created; attr assignments on stdout
#		1							= failure
#
# OUTPUT:
#		writes IF_SUPPORTED attr assignments on stdout
#-------------------------------------------------------------------------------

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

export INUCLIENTS=yes

# NIM initialization
nim_init

# initialize local variables
typeset c=""

# set parameters from command line
while getopts :a:pqv 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}\"
		;;

		p)		# preview bosboot size requirements
				preview=TRUE
				cmd="${cmd} -q"
		;;

		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

# create the boot images
mkbooti

# all done
exit 0

