#!/bin/sh
# $Revision: 1.23.4.2 $
#***************************************************************************
# $VRTScprght: Copyright 1993 - 2004 VERITAS Software Corporation, All Rights Reserved $
#***************************************************************************
#
# update software on NetBackup clients

USAGE () {

	${ECHO} "usage: $0 [-ForceInstall -Install_Java -Install_Client_Bins \\
		-Install_ADC] \\
		[-ClientList filename | hardware_type operating_system]"
	quit 22
}

# INSERT fn.set_echo_var
#---------- set_echo_var -- $Revision: 1.2 $ ------------
#
#		This function is a case statement sets
#		the ECHO variable
#		with the appropriate path & flags.

#Define Echo to allow escape characters
case "`uname -s`" in
	Linux*)
		unset POSIXLY_CORRECT
		ECHO="/bin/echo -e"
		;;
	SunOS*)
		ECHO="/usr/bin/echo"
		;;
	*)
		ECHO="echo"
		;;
esac

# INSERT fn.prompt
#---------- Prompt () -- $Revision: 1.1 $ ------------
#	Prompt () - determines the flags to use to print
#			a line without a newline char
#
# 	*** This function uses the set_echo_var function -${ECHO} to 
#		define the Prompt function.
#
#	calling signature - Prompt "some string"
#	return value - none

case "`${ECHO} 'x\c'`" in
	'x\c')
		Prompt()
		{
			${ECHO} -n "$*"
		}
		;;
	x)
		Prompt()
		{
			${ECHO} "$*\c"
		}
		;;
	*)
		Prompt()
		{
			${ECHO} -n "$*"
		}
		;;
esac


# INSERT fn.confirm
#---------- confirm () -- $Revision: 1.4 $ ------------
#
#	confirm () - Takes three parameters:
#		     1: "y" or "n" to be displayed as the default
#		     2:  a prompt string to be displayed to the user
#		     3:  help text string (optional)
#
#			It is expected that the Trace_File variable
#			has been set to a file or /dev/null.
#			
#			*** This function uses the Prompt function
#				which uses the set_echo_var function - ${ECHO}.
#
#	calling signature:	confirm y "some string" [ "help text" ] 
#					or
#				confirm n "some string" [ "help text" ]
#
#	returns:		0 for Yes, 1 for No		

confirm ()
{
	help=${3}
	Q=""
	if [ -n "${help}" ]; then 
		Q=",?"
	fi
	Prompt "${2} [y,n${Q}] (${1}) "
	valid=0
	until [ ${valid} -ne 0 ]
	do
		#read ans and if it is empty, initialize it with the default
		read ans
		: ${ans:=${1}}


		#write to the tracefile

		${ECHO} ${ans} >> ${Trace_File}


		case "${ans}" in
			Y*|y*)
				valid=1
				return 0 ;;
			N*|n*)
				valid=1
				return 1 ;;
			?*)
				${ECHO} ""
				${ECHO} ${help}
				${ECHO} ""
				Prompt "${2} [y,n${Q}] (${1}) "
				;;
			*)
				${ECHO} ""
				Prompt "${ans} is invalid input.  Enter [y,n${Q}] (${1}) " 
				;;
		esac
	done
}

# INSERT fn.get_number
#---------- get_number () -- $Revision: 1.2 $ ------------
#
#	get_number () - Takes four parameters, three are mandatory.
#			Parameter one:   string displayed to the user
#				  two:   minimum value
#				  three: maximum value
#				  four (optional):  default
#
#			The input must be a number inbetween the min and max.
#			The number is placed in the VALUE variable.
#			*** This function uses the Prompt function and the prompt
#				function uses the set_echo_var function - ${ECHO}.
#			*** It is expected that the Trace_File variable has been 
#				set to a file or /dev/null.
#
#	calling signature:
#			get_number "some string" min_value max_value -d default_value
#				or
#			get_number "some string" min_value max_value

get_number ()
{
	#grab the default param if given
	if [ $# -gt 4 ] ; then
		if [ "${4}" = "-d" ] ; then
			defaultNum=${5}
		else
			defaultNum="none"
		fi		
	else
		defaultNum="none"
	fi

	valid=0
	until [ ${valid} -ne 0 ]
	do
		if [ ${defaultNum} = "none" ] ; then
			Prompt "${1} [${2} - ${3}]: "
		else

			Prompt "${1} [${2} - ${3}] (default: ${defaultNum}): "
		fi

		read VALUE
		#read ans and if it is empty, initialize it with the default
		VALUE=${VALUE:=${defaultNum}}


		if [ ${VALUE} = "none" ] ; then
			${ECHO} "" >> ${Trace_File} #this way "none" won't be written
		else
			${ECHO} ${VALUE} >> ${Trace_File}
		fi


		#check to see if input is really a number
		echo ${VALUE} | egrep -e \(\^[0-9]\+\$\) > /dev/null

		#if a number & in range
		if [ $? -eq 0 ] ; then
			if [ ${VALUE} -ge ${2} -a ${VALUE} -le ${3} ] ; then
				return
			fi
		fi 

		if [ "${VALUE}" != "none" ] ; then #this handles so that "none" won't be printed to the screen	
			${ECHO} "ERROR: ${VALUE} is invalid input. Please try again."
			${ECHO} ""
		fi
	done
}

# INSERT fn.set_tar_options
#---------- set_tar_options -- $Revision: 1.9 $ ------------
#
#		This function takes one parameter, a
#		string which is the MACHINE or platform type.
#		It sets two variables: TAR_C_OPTIONS and
#			TAR_X_OPTIONS
#
#		NOTE: The v flag is not handled in this function. If you want 
#		to add the v flag, you need to set it in your scripts.
#		For example, place the v before the variable like so, v${TAR_X_OPTIONS}.
#		The v must go before the variable because in the ALPHA|SGI
#		case statement you can't put the v after the 20 blocking factor.
#
#		calling signature:
#			set_tar_options "MachineType"

set_tar_options ()
{
	case "${1}" in
		ALPHA* | alpha* | OSF1* | SGI* | sgi6* | IRIX* )

			TAR_C_OPTIONS="cf" #same as default

			TAR_X_OPTIONS="xbpf 20"
			#x - extract
			#b - use blocking factor
			#p - use original tarred file protection properties
			#f - use given filename
			#20 - portable blocking factor
			;;
		HP* | hp* )

			TAR_C_OPTIONS="cOfA"
			#c - create new archive
			#O - write a pre-POSIX format archive
			#f - use given filename
			#A - suppress warning messages for ACL entries

			TAR_X_OPTIONS="xpfA"
			#x - extract
			#p - use original tarred file protection properties
			#f - use given filename
			#A - suppress warning messages for ACL entries	
			;;

		* )
			TAR_C_OPTIONS="cf"
			#c - create new archive
			#f - use given filename

			TAR_X_OPTIONS="xpf"
			#x - extract
			#p - use original tarred file protection propeties
			#f - use given filename
			;;
	esac
}

# INSERT fn.inetd_entries
#---------- inetd.entries -- $Revision: 1.1 $ ------------
#	Set up the entries needed for inetd or xinetd by
#	defining a bunch of mini-functions the calling
#	scripts can reference.
#
#	There are 2 major types (inetd or xinetd).
#	New entries need to be added to both sections.
#
#-------------------------------------------------------------------------------
# inetd entries - NOWAIT will be filled in based on machine type later
# when the appropriate function is called.  For most machines,
# NOWAIT will be "nowait" but for Linux, it will be "nowait.300".

bpcd_i ()
{
	bpcd_i_entry="bpcd	stream	tcp	${NOWAIT}	root	/usr/openv/netbackup/bin/bpcd bpcd"
}

bpjava_msvc_i ()
{
	bpjava_msvc_i_entry="bpjava-msvc	stream	tcp	${NOWAIT}	root	/usr/openv/netbackup/bin/bpjava-msvc bpjava-msvc -transient"
}

vnetd_i ()
{
	vnetd_i_entry="vnetd	stream	tcp	${NOWAIT}	root	/usr/openv/bin/vnetd vnetd"
}

vopied_i ()
{
	vopied_i_entry="vopied	stream	tcp	${NOWAIT}	root	/usr/openv/bin/vopied vopied"
}

#-------------------------------------------------------------------------------
# xinetd entries - GROUP_LINE will be filled in based on machine type
# later when the appropriate function is called.  For most machines,
# GROUP_LINE will be nothing, but for MACINTOSH, it will be replaced
# by "groups = yes"

bpcd_x ()
{
	bpcd_x_entry="# Service bpcd for NetBackup
service bpcd
{
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = root
        server                  = /usr/openv/netbackup/bin/bpcd
        disable                 = no
        ${GROUP_LINE}
}"
}

bpjava_msvc_x ()
{
	bpjava_msvc_x_entry="# Service bpjava-msvc for NetBackup
service bpjava-msvc
{
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = root
        server                  = /usr/openv/netbackup/bin/bpjava-msvc
        server_args             = -transient
        disable                 = no
        ${GROUP_LINE}
}"
}

vnetd_x ()
{
	vnetd_x_entry="# Service vnetd for NetBackup
service vnetd
{
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = root
        server                  = /usr/openv/bin/vnetd
        disable                 = no
        ${GROUP_LINE}
}"
}

vopied_x ()
{
	vopied_x_entry="# Service vopied for NetBackup
service vopied
{
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = root
        server                  = /usr/openv/bin/vopied
        disable                 = no
        ${GROUP_LINE}
}"
}


# Announce possible clients at the wrong level
#
# Input $1 = the "found" file
#	$2 = the hardware type for the message

announce_possibles () {

	Entries=`wc -l $1 | sed s/' '/''/g | cut -d '/' -f1`
	if [ $Entries -gt 4 ] ; then
		head -4 $1
		cat $1 >> $LOGFILE
		${ECHO} "  ...		There are $Entries $2 clients to check."
	else
		cat $1 | tee -a $LOGFILE
	fi

}

# Check for services entries and set up inetd entries

Check_Services () {

	Done=0
	# Read the bprd, bpjava-msvc, bpcd, vopied, and vnetd entries from
	# /etc/services.
	Services="bpcd bpjava bprd vnetd vopied"
	for service in $Services
	do
		grep '^'$service /etc/services > /dev/null
		if [ $? != 0 ] ; then
			${ECHO} "You need an entry for $service in /etc/services" >& 2
			Done=1
		else
			grep '^'$service /etc/services > ${TMPDIR}/${service}_service
		fi
	done

	# inetd entries are coming from the functions in the fn.inetd_entries file.
	# Make all entries use nowait.  Will change to nowait.300 if needed later.

	NOWAIT="nowait"
	bpcd_i
	${ECHO} "${bpcd_i_entry}" > ${TMPDIR}/bpcd_inetd.conf
	vopied_i
	${ECHO} "${vopied_i_entry}" > ${TMPDIR}/vopied_inetd.conf
	bpjava_msvc_i
	${ECHO} "${bpjava_msvc_i_entry}" > ${TMPDIR}/bpjava_inetd.conf
	vnetd_i
	${ECHO} "${vnetd_i_entry}" > ${TMPDIR}/vnetd_inetd.conf
}

# Update a client in a given class
# this function calls set_tar_options
#

client_update() {

	ret=0
	Output=${TMPDIR}/client_update.$$.${JobIndex}
	exec > $Output 2>&1

	CLIENT=${3}

	# Check to see if the client is the master (the local machine).
	# Use bpclntcmd so we aren't fooled by virtual names.

	DoingServer=0
	am_i_master=0
	${BP_BIN}/bpclntcmd -is_local_host ${CLIENT} > /dev/null 2>&1
	if [ $? -eq 0 ] ; then
		# Don't try to update the server with files from itself.
		if [ $Install = TRUE ] ; then
			return
		fi
		DoingServer=1
		am_i_master=1
	fi

	if [ $Install_Client_Bins = 1 ] ; then
		if [ -f ${CLIENT_BIN_DIR}/${1}/${2}/version ] ; then
			ClientRelease=`cat ${CLIENT_BIN_DIR}/${1}/${2}/version | cut -f2 -d" " | cut -c 1-3`
		else
			ClientRelease=NONE
		fi
		if [ ${ClientRelease} != ${MyRelease} -a ${ClientRelease} != NONE ] ; then
			${ECHO} "
Will not update client $CLIENT
	$CLIENT is defined as a client type from an earlier release of NetBackup.
"
			ret=3
		elif [ ! -f ${CLIENT_BIN_DIR}/${1}/${2}/template.methods.txt ] ; then
			${ECHO} "
Cannot update client $CLIENT
	Invalid hardware type \"$1\" and/or operating system \"$2\"
	or client binaries are not installed on the server.
"
			ret=2
		else

			${ECHO} "	$CLIENT $1/$2 ..."

			/bin/rm -f ${TMPDIR}/${CLIENT}
			${ECHO} "CLIENT_NAME = ${CLIENT}" > ${TMPDIR}/${CLIENT}

			${BP_BIN}/bpinst -NB ${ForceInstall} $EL -inst_dir ${CLIENT_BIN_DIR}/${1}/${2}/ -host ${CLIENT} -d </dev/null 2>>${Output}.stderr
			Status=$?
			if [ $Status != 0 ] ; then
				ret=2
			else
				Stat=`tail -2 ${Output}.stderr | grep "Version files match"`
				if [ $? = 0 ] ; then
					# if Version files match don't do any upgrade.
					ret=1
				fi
			fi

			cat ${Output}.stderr
			rm -f ${Output}.stderr ${TMPDIR}/${CLIENT}
		fi
	fi

	if [ $Install_Java = 1 -a $ret = 0 -a ${DoingServer} = 0 ] ; then
		# pick the correct JRE for Java client $1/$2
		# and set up USE_APP_INITIALIZER

		JRE_FILE=NONE
		JAVA_FILE=NB-Java.tar.Z
		USE_APP_INITIALIZER=""

		set_tar_options ${1}

		case $1 in
		ALPHA)
			if [ $2 = "OSF1_V5" ] ; then
			JNI_FILE=/usr/openv/lib/server/alpha_5/libSigScheduleJNI.so
			JRE_FILE=Tru64_JRE.tar.Z
			fi ;;
		Linux)
			JNI_FILE=/usr/openv/lib/server/linux/libSigScheduleJNI.so
			JRE_FILE=Linux_JRE.tar.Z;;
		RS6000)
			if [ $2 = "AIX4.3.3" -o $2 = "AIX5" ] ; then
			JNI_FILE=/usr/openv/lib/server/rs6000/libSigScheduleJNI.so
			JRE_FILE=AIX_JRE.tar.Z
			fi ;;
		Solaris)
			if [ `expr "$2" : '.*_x86'` != 0 ] ; then
				JNI_FILE=/usr/openv/lib/server/Solaris_x86/libSigScheduleJNI.so
				JRE_FILE=Solaris_x86_JRE.tar.Z
			elif [ $2 = "Solaris7" -o $2 = "Solaris8" -o $2 = "Solaris9" ] ; then
				JNI_FILE=/usr/openv/lib/server/Solaris/libSigScheduleJNI.so
				JRE_FILE=Solaris_Sparc_JRE.tar.Z
			fi ;;
		HP9000*)
			if [ $2 = "HP-UX11.00" -o "${2}" = "HP-UX11.11" ] ; then
				JNI_FILE=/usr/openv/lib/server/hp_ux/libSigScheduleJNI.sl
				JRE_FILE=HPUX_JRE.tar.Z
			fi ;;
		esac

		if [ $JRE_FILE != NONE ] ; then
			${ECHO} "	$CLIENT $1/$2 Java Update ..."

			if [ ! -d ${TMPDIR}/JAVA/$$.${JobIndex} ] ; then
				mkdir -p ${TMPDIR}/JAVA/$$.${JobIndex}
			fi

			${BP_BIN}/bpinst -MISC -Z ${JAVA_FILE} -src /usr/openv -dest /usr/openv -host ${CLIENT} -d
			if [ $? != 0 ] ; then
				${ECHO} "${JAVA_FILE} update failed"
				ret=2
			fi

			if [ ${ret} = 0 ] ; then
				${BP_BIN}/bpinst -MISC -Z ${JRE_FILE} -src /usr/openv/java -dest /usr/openv/java -host ${CLIENT} -d
				if [ $? != 0 ] ; then
					${ECHO} "${JRE_FILE} update failed"
					ret=2
				fi
			fi

			if [ ${ret} = 0 ] ; then
				${BP_BIN}/bpinst -MISC -Z `basename ${JNI_FILE}` -src `dirname ${JNI_FILE}` -dest /usr/openv/lib -host ${CLIENT} -d
				if [ $? != 0 ] ; then
					${ECHO} "${JNI_FILE} update failed"
					ret=2
				fi
			fi

			if [ ${ret} = 0 ] ; then
				# modify the extract script and create a client specific one
				cat ${TMPDIR}/JAVA/extract.sh | sed s@X_JRE_FILE_X@${JRE_FILE}@ | sed s@X_TARXOPTION_X@"v${TAR_X_OPTIONS}"@ >${TMPDIR}/JAVA/$$.${JobIndex}/extract.sh

				${BP_BIN}/bpinst -MISC -X -Z extract.sh -src ${TMPDIR}/JAVA/$$.${JobIndex} -dest /usr/openv/netbackup/bin -host ${CLIENT} -d
				if [ $? != 0 ] ; then
					${ECHO} "Java extract.sh update failed"
					ret=2
				fi
			fi

			if [ ${ret} = 0 ] ; then
				# Create a client specific config file
				Cli_nbj_conf=${TMPDIR}/JAVA/$$.${JobIndex}/nbj.conf
				if [ -f ${Cli_nbj_conf} ] ; then
					rm -f ${Cli_nbj_conf}
				fi
				cp ${TMPDIR}/JAVA/nbj.conf $Cli_nbj_conf
				${ECHO} "CLIENT_HOST=$CLIENT" >> $Cli_nbj_conf

				${BP_BIN}/bpinst -MISC -Z nbj.conf -src ${TMPDIR}/JAVA/$$.${JobIndex} -dest /usr/openv/java -host ${CLIENT} -d
				if [ $? != 0 ] ; then
					${ECHO} "Java nbj.conf update failed"
					ret=2
				fi
			fi
			rm -rf ${TMPDIR}/JAVA/$$.${JobIndex}
		fi
	fi

	### Advanced Client Install
	###	- Solaris only check for 4.0v???
	###	- version check????
	###	- check for hw/sw FIM/FMM directory, vfm.conf
	###	- create tar
	###	- ship it
	###	- anytime ret is set to non-zero, stop doing stuff
	if [ $Install_ADC = 1 -a $ret = 0 ] ; then
		skip=no

		set_tar_options ${1}

		case ${1} in
			HP*)
				if [ "${2}" != "HP-UX11.00" -a "${2}" != "HP-UX11.11" ] ; then
					skip=yes
				fi
				;;
			Solaris)
				if [ "${2}" != "Solaris7" -a \
				     "${2}" != "Solaris8" -a "${2}" != "Solaris9" ] ; then
					skip=yes
				fi
				;;
			*)
				skip=yes
				;;
		esac

		if [ "${skip}" = "yes" ] ; then
			${ECHO} "
Install_ADC is not a supported option for client ${CLIENT} running ${1} ${2}.
Skipping the update of NetBackup Advanced Client software for this client.
"
			ret=2
		else
			# get the client running version (not rocket science but we
			# assume bpgetconfig will not be altered.

			VERSION=`${BP_BIN}/admincmd/bpgetconfig -s $CLIENT -l 2>/dev/null | cut -f6 -d';'`
			if [ "${VERSION}" -eq "" ] ; then
				${ECHO} "
The version of NetBackup running on client ${CLIENT} either could not
be determined or is not supported by NetBackup Advanced Client software.
Skipping the update of NetBackup Advanced Client software for this client.
"
				ret=2
			else

				ADC_DIR=${BP_DIR}/vfms/$1/$2/${VERSION}

				if [ ! -d ${ADC_DIR} ] ; then
					${ECHO} "
ERROR:  Directory ${ADC_DIR} not found.
Be sure that NetBackup Advanced Client software is supported on
${1} ${2} clients running version ${VERSION}.  Skipping the update
of client ${CLIENT}.
"
					ret=2
				else
					${ECHO} "
ADC directory ${ADC_DIR}"

					#
					#  Whether shipping to myself or to a remote client, check
					#  if the FIM and FMM subdirs exist.  Either missing is fatal.
					#

					for dir in ${ADC_DIR}/FIM ${ADC_DIR}/FMM
					do
						if [ ! -d ${dir} -a ${ret} -ne 2 ] ; then
							${ECHO} "
ERROR:  Directory ${dir} does
not exist.  NetBackup Advanced Client software has not been installed on
${MASTER}.
"
							ret=2
						fi
					done
				fi
			fi

			mkdir ${TMP_ADC}.${JobIndex}

			if [ ${ret} -eq 0 ] ; then

				# If the client is also the master, don't tar, compress and run
				# bpinst.  Just run the extraction script to execute install_adc.

				if [ ${am_i_master} -ne 1 ] ; then
					WORKDIR=${ADC_DIR}
					cd ${WORKDIR}
					ADC_TARFILE=ADC.tar
					ADC_VERSION=ADC.version
					CLIENT_DIR=${BP_DIR}/vfms
					rm -f ${TMP_ADC}.${JobIndex}/${ADC_TARFILE} ${TMP_ADC}.${JobIndex}/${ADC_TARFILE}.Z
					${ECHO} "Creating & compressing tarfile ${TMP_ADC}.${JobIndex}/${ADC_TARFILE}."
					cp ${ADC_VERSION} ${TMP_ADC}.${JobIndex}/${ADC_VERSION}
					/bin/tar ${SERVER_TAR_C_OPTIONS} ${TMP_ADC}.${JobIndex}/${ADC_TARFILE} ${ADC_VERSION} FIM FMM
					Status=$?
					if [ ${Status} != 0 ] ; then
						${ECHO} "tarfile creation failed with exit status ${Status}."
						${ECHO} "Aborting update of client ${CLIENT}."
						ret=2
					fi
					if [ ${ret} -ne 2 ] ; then
						/usr/bin/compress -f ${TMP_ADC}.${JobIndex}/${ADC_TARFILE}
						Status=$?
						if [ ${Status} != 0 ] ; then
							${ECHO} "tarfile compression failed with exit status ${Status}."
							${ECHO} "Aborting update of client ${CLIENT}."
							ret=2
						fi
					fi
					if [ ${ret} -ne 2 ] ; then
						${BP_BIN}/bpinst -MISC ${VersionCheck} -Z ${ADC_TARFILE}.Z -src ${TMP_ADC}.${JobIndex} -dest ${CLIENT_DIR} -host ${CLIENT} -d
						Status=$?
						if [ ${Status} != 0 ] ; then
							${ECHO} "Aborting update of client ${CLIENT}."
							ret=2
						else
							Stat=`tail -2 ${Output} | grep "version files match - no update"`
							if [ $? = 0 ] ; then
								${ECHO} "Skipping the update of client ${CLIENT}."
								ret=1
							fi
						fi
					fi
				else

					#
					# In case the client has upgraded to a server,
					# use -rf and not just -f.  We already checked
					# that the FIM directory really exists.
					#

					rm -rf ${BP_DIR}/vfms/FIM ${BP_DIR}/vfms/FMM
					ln -s ${ADC_DIR}/FIM ${BP_DIR}/vfms/FIM
					ln -s ${ADC_DIR}/FMM ${BP_DIR}/vfms/FMM
				fi
			fi

			if [ ${ret} -eq 0 ] ; then
				# If we shipped S/W, remove the tag from the extract script
				# to install on the client and update tar extract options.
				cat ${TMP_ADC}/ADC_extract.sh | sed s@X_TARXOPTION_X@v${TAR_X_OPTIONS}@ | sed s@###ADCSWInstall###@@ > ${TMP_ADC}.${JobIndex}/ADC_extract.sh

				### Run extract script ###
				${BP_BIN}/bpinst -MISC -X -Z ADC_extract.sh -src ${TMP_ADC}.${JobIndex} -dest ${BP_BIN} -host ${CLIENT} -d
				if [ $? != 0 ] ; then
					ret=2
				fi
			fi
			rm -rf ${TMP_ADC}.${JobIndex}
		fi # End skip

	fi ### End ADC Install ###

	cat ${Output} >> ${LOGFILE}
	${ECHO} ${ret} > ${CLIENTS}.${JobIndex}
}
# Leave through here to clean up all files

quit () {

	/bin/rm -f ${TMPDIR}/client_update.$$.*
	if [ $1 = 0 -o $1 = 6 ] ; then
		rm -f ${CLIENTS}*
		rm -rf ${TMP_ADC}
		${ECHO} "
The update trace can be found in ${LOGFILE}."
	elif [ $1 = 1 ] ; then	# the server is not setup properly
		rm -f ${CLIENTS}* ${LOGFILE}
		rm -rf ${TMP_ADC}
	elif [ $1 = 2 ] ; then	# there are suspect clients
		${ECHO} "
The complete list of UNIX clients can be found in ${CLIENTS}."
		rm -f ${CLIENTS}.*
		rm -rf ${TMP_ADC}
	elif [ $1 = 3 ] ; then	# No clients to upgrade
		rm -f ${CLIENTS}* ${LOGFILE}
		rm -rf ${TMP_ADC}
	elif [ $1 = 4 ] ; then	# there are suspect clients
		${ECHO} "
The complete list of UNIX clients can be found in ${CLIENTS}."
		rm -f ${CLIENTS}.* ${LOGFILE}
		rm -rf ${TMP_ADC}
	else
		/bin/rm -f ${CLIENTS}*
	fi

	# Only clean up these files if there are no other update_clients running

	OthersRunning=`$PS`
	OthersRunning=`${ECHO} "$OthersRunning" | grep update_clients | wc -l`
	if [ $OthersRunning = ${CMD_Count} ] ; then
		rm -f ${TMPDIR}/bpcd_inetd.conf ${TMPDIR}/bp?d_service ${TMPDIR}/etc_services ${TMPDIR}/bp_servers ${TMPDIR}/vopied_inetd.conf ${TMPDIR}/vopied_service
		rm -f ${TMPDIR}/bpjava_inetd.conf ${TMPDIR}/bpjava_service
		rm -f ${TMPDIR}/vnetd_inetd.conf ${TMPDIR}/vnetd_service
		rm -rf /tmp/JAVA
	fi
	exit $1
}

###################### MAIN ######################

Trace_File=/dev/null #used in fn.* functions
TMPDIR=${TMPDIR:-/tmp}
BP_DIR=/usr/openv/netbackup
BP_BIN=${BP_DIR}/bin
JAVA_DIR=/usr/openv/java
DRIVER_DIR=${BP_BIN}/driver
CLIENT_BIN_DIR=/usr/openv/netbackup/client
ClientList=""
Done=0

LC_MESSAGES="C"
export LC_MESSAGES

Install=FALSE
ForceInstall=""
VersionCheck="-enforce_version_check"
Install_Java=0
Install_ADC=0
Install_Client_Bins=0

PATH=/bin:$PATH
DATE_TIME=`/bin/date +%m-%d-%H%M`.$$
CLIENTS=${TMPDIR}/NB_CLIENT_LIST.${DATE_TIME}

# Based on the HARDWARE type, determine the location of the
# inetd.conf file and the tr command. Prepend /usr/5bin to
# PATH on Suns to get System V behaviour from echo.

if [ -f /usr/openv/netbackup/version ] ; then
	HARDWARE=`head -1 /usr/openv/netbackup/version | cut -f2 -d" "`
	MyRelease=`head -2 /usr/openv/netbackup/version | cut -f3 -d" " | cut -c 1-3`
else
	HARDWARE=NONE
fi

INETD_CONF=/etc/inetd.conf; export INETD_CONF
TR=/bin/tr
PS="/bin/ps -ea"
CMD_Count=1

set_tar_options ${HARDWARE}
#Immediately save the server tar options because
#set_tar_options is called again later for the client(s)
#and the server tar create archive options will be
#overwritten. Only the TAR_C_OPTIONS need to be saved
#because the creation of tars happen on the server.
SERVER_TAR_C_OPTIONS=${TAR_C_OPTIONS}

case "$HARDWARE" in
	ALPHA)
		;;
	HP*)
		TR=/usr/bin/tr ;;
	LINUX*)
		TR=/usr/bin/tr
		CMD_Count=2
		;;
	RS6000)
		PS="/bin/ps -ef -o pid,args";;
	SGI)
		PS="/bin/ps -ea -o pid,args"
		if [ -f /usr/etc/inetd.conf ] ; then
			INETD_CONF=/usr/etc/inetd.conf
		fi ;;
	SOLARIS)
		PS="/bin/ps -ea -o pid,fname=XXXXXXXXXXXXXX" ;;
	*)
		${ECHO} "
/usr/openv/netbackup/version not found or corrupted.
Unknown hardware type: \"$HARDWARE\"
"
		exit 1 ;;
esac

# Get Install flags
got_flag=`expr "$1" : '.*Instal'`
while [ $got_flag != 0 ]
do
	if [ $1 = "Install" ] ; then
		Install=TRUE
	elif [ $1 = "-ForceInstall" ] ; then
		ForceInstall='-force_install'
		VersionCheck=""
	elif [ $1 = "-Install_Java" ] ; then
		Install_Java=1
	elif [ $1 = "-Install_ADC" ] ; then
		Install_ADC=1
	elif [ $1 = "-Install_Client_Bins" ] ; then
		Install_Client_Bins=1
	elif [ $1 = "-Install_VFMS" ] ; then
		USAGE
	fi
	shift
	if [ $# != 0 ] ; then
		got_flag=`expr "$1" : '.*Instal'`
	else
		got_flag=0
	fi
done

# Make sure we're on an active node or a standalone machine
# before we allow the user to push to the clients.

${BP_BIN}/cluster/cluster_active > /dev/null 2>&1
if [ $? -ne 0 ] ; then
	${ECHO} "
This machine appears to be an inactive member of a cluster.  Pushing
software to clients must occur on the active member of the cluster.
"
	exit 0
fi

${BP_BIN}/admincmd/bpauthorize -test_admin >/dev/null
status=$?
if [ ${status} -ne 0 ] ; then
	${ECHO} "
You do not have the proper authorization to perform
this task.  Please resolve and try again."
	exit ${status}
fi

if [ $Install_Java = 0 -a $Install_ADC = 0 ] ; then
	Install_Client_Bins=1
fi

if [ $Install_Java = 1 ] ; then
	Message="
NetBackup Java is not installed and distributed on $HARDWARE servers.

You must install client software locally, from the CD-ROM, to install
NetBackup Java components on a ${class_os} NetBackup client."
	case "$HARDWARE" in
		SGI )
			if [ $Install_Java = 1 ] ; then
				${ECHO} "${Message}" >& 2
				Install_Java=0
			fi
			;;
	esac
fi

# Verify that the right number of arguments were given
if [ $# = 0 ] ; then
	hardware="ALL"
	os_name="ALL"
elif [ $# = 2 ] ; then
	if [ $1 = "-ClientList" ] ; then
		ClientList=$2
		hardware="ALL"
	else
		hardware=$1
		os_name=$2
	fi
elif [ $# = 3 ] ; then
	if [ $1 = "-ClientList" ] ; then
		ClientList=$2
		hardware="ALL"
	else
		hardware=$1
		os_name=$2
	fi
else
	USAGE
fi

if [ $Install_Java = 1 ] ; then
	if [ -d /usr/openv/java ] ; then
		if [ ! -d /tmp/JAVA ] ; then
			mkdir -p /tmp/JAVA
		fi
		${ECHO} "
Installing NetBackup-Java GUI applications to NetBackup-Java supported clients."

		# create the extract script
		cat <<eof >${TMPDIR}/JAVA/extract.sh
#!/bin/sh
cd /usr/openv

#  Clean up the java directory.  There are a couple of things to keep
#  so create a temp directory to save those in.
java_tmp_dir=/usr/openv/NB_java_tmp.\$\$
if [ ! -d \${java_tmp_dir} ] ; then
	mkdir \${java_tmp_dir}
else
	rm -rf \${java_tmp_dir}/*
fi
for conf in auth.conf nbj.conf
do
	if [ -f ${JAVA_DIR}/\${conf} ] ; then
		mv ${JAVA_DIR}/\${conf} \${java_tmp_dir}/\${conf}.bak
	fi
done
# already have the new JRE so save it off before we clobber the java dir
if [ -f ${JAVA_DIR}/X_JRE_FILE_X ] ; then
	mv ${JAVA_DIR}/X_JRE_FILE_X \${java_tmp_dir}
fi

#  The next section of code tries to figure out if VSM, GDM
#  or a locale package has been installed.  If so, save off
#  the pieces installed by those packages.
for file in HSMApplet.properties allHSM.jar migfb migsa \
	.gdmConf archiver.jar crimson-1.1.jar gdm.conf \
	gdmDashboard.jar gdmSA idl.jar jacorb.jar jaxp-1.1.jar \
	SchedUI_ja_JP.jar VxHelp_ja_JP.jar \
	SchedUI_zh_CN.jar VxHelp_zh_CN.jar
do
	if [ -f ${JAVA_DIR}/\${file} ] ; then
		mv ${JAVA_DIR}/\${file} \${java_tmp_dir}
	fi
done
for loc in ja zh
do
	if [ -f ${JAVA_DIR}/vrts/i18n_\${loc}.properties ] ; then
		if [ ! -d \${java_tmp_dir}/vrts ] ; then
			mkdir \${java_tmp_dir}/vrts
		fi
		mv ${JAVA_DIR}/vrts/i18n_\${loc}.properties \${java_tmp_dir}/vrts
	fi
	for dir in help helpDC ; do
		if [ -d ${JAVA_DIR}/vrts/nbu/\${dir}/\${loc} ] ; then
			if [ ! -d \${java_tmp_dir}/vrts/nbu/\${dir} ] ; then
				mkdir -p \${java_tmp_dir}/vrts/nbu/\${dir}
			fi
			mv /usr/openv/java/vrts/nbu/\${dir}/\${loc} \${java_tmp_dir}/vrts/nbu/\${dir}
		fi
	done
done
for dir in hsm gdm ; do
	if [ -d ${JAVA_DIR}/vrts/\${dir} ] ; then
		if [ ! -d \${java_tmp_dir}/vrts ] ; then
			mkdir \${java_tmp_dir}/vrts
		fi
		mv ${JAVA_DIR}/vrts/\${dir} \${java_tmp_dir}/vrts
	fi
done

#  Now remove the existing java directory and if anything actually
#  got saved, move the temp directory back to /usr/openv/java.
if [ -d ${JAVA_DIR} ] ; then
	rm -rf ${JAVA_DIR} 2>/dev/null
fi
rmdir \${java_tmp_dir} 2>/dev/null
if [ \$? != 0 ] ; then
	mv \${java_tmp_dir} ${JAVA_DIR}
	chgrp -R bin /usr/openv/java
fi

zcat NB-Java.tar.Z | /bin/tar X_TARXOPTION_X -
rm -f /usr/openv/NB-Java.tar.Z
if [ ! -d ${JAVA_DIR}/logs ] ; then
	mkdir ${JAVA_DIR}/logs
	chmod 777 ${JAVA_DIR}/logs
fi

#  note only the backup copy of auth.conf gets copied back
#  not nbj.conf
if [ -f ${JAVA_DIR}/auth.conf.bak ] ; then
	rm -f ${JAVA_DIR}/auth.conf
	mv ${JAVA_DIR}/auth.conf.bak ${JAVA_DIR}/auth.conf
fi

cd ${JAVA_DIR}
zcat X_JRE_FILE_X | /bin/tar X_TARXOPTION_X -
rm -f /usr/openv/java/X_JRE_FILE_X
rm -f ${BP_BIN}/jnbSA ${BP_BIN}/jbpSA
ln -s ${JAVA_DIR}/jbpSA ${BP_BIN}/jbpSA
ln -s ${JAVA_DIR}/jnbSA ${BP_BIN}/jnbSA
chmod 555 /usr/openv/lib/libSigScheduleJNI.s?
eof

		# copy and modify nbj.conf for $CLIENT
		if [ -f /usr/openv/java/nbj.conf ] ; then
			grep -v CLIENT_HOST /usr/openv/java/nbj.conf > /tmp/JAVA.nbj.conf.$$
			if [ ! -f /tmp/JAVA/nbj.conf ] ; then
				mv /tmp/JAVA.nbj.conf.$$ /tmp/JAVA/nbj.conf
			else
				diff /tmp/JAVA.nbj.conf.$$ /tmp/JAVA/nbj.conf 2>/dev/null
				if [ $? != 0 ] ; then
					${ECHO} "
Modified /usr/openv/java/nbj.conf or old /tmp/JAVA/nbj.conf found.
Not doing JAVA client updates."
					Install_Java=0
				fi
			fi
		else
			${ECHO} "
Server is missing /usr/openv/java/nbj.conf.
You must create $CLIENT /usr/openv/java/nbj.conf manually"
		fi
	fi
fi

# Verify that if hardware/os were specified, they're valid
if [ ! "${hardware}" = "ALL" -a ! -f ${CLIENT_BIN_DIR}/${hardware}/${os_name}/template.methods.txt ] ; then
	${ECHO} "
Cannot update client $CLIENT
	Invalid hardware type \"${hardware}\" and/or operating system \"${os_name}\"
	or client binaries are not installed on the server.
"
	USAGE
fi

TAB=`${ECHO} ' ' | $TR ' ' '\011'`
SPACE=' '

# Determine the system's hostname.  Use hostname if available and strip
# away any domain information.
if type hostname | grep 'not found' >/dev/null
then
	MASTER=`uname -n | sed 's/\..*$//'`
else
	MASTER=`hostname | sed 's/\..*$//'`
fi

# Get the domainname into domain without a leading '.' (if there is one).
DOMAIN=`domainname | sed 's/^\.//'`
if [ X"${DOMAIN}" = X ] ; then
	# No domain. Set it to something that will not be matched.
	DOMAIN=ZZZZZZZZ
fi


#  Always set so the quit function has an argument for rm.  However,
#  this directory only actually gets created when Install_ADC is
#  specified.
TMP_ADC=${TMPDIR}/ADC.${DATE_TIME}

if [ $Install_ADC = 1 ] ; then
	# Installation Procedure
	#
	#	- create install sh here document
	#	- extract tar files
	#	- install install_adc installation script
	#	- call to installation script is conditional.
	#			Determined in client_update().
	#
	#   use unique exit statuses here and in install_adc
	#       so you can tell what actually failed.
	#
	if [ ! -d ${TMP_ADC} ] ; then
		mkdir -p ${TMP_ADC}
	fi

	# Create the extract script
	cat << eof > ${TMP_ADC}/ADC_extract.sh
#!/bin/sh

ADC_DIR=/usr/openv/netbackup/vfms/
ADC_TARFILE=ADC.tar.Z
if [ -f \${ADC_DIR}/\${ADC_TARFILE} ] ; then
	cd \${ADC_DIR}
	/usr/bin/zcat \${ADC_TARFILE} | /bin/tar X_TARXOPTION_X -
	if [ \$? -ne 0 ] ; then
		${ECHO} "zcat/tar failed"
		exit 2
	fi
	/bin/rm -f \${ADC_TARFILE}
fi

### Install install_adc (released in the FIM directory)
if [ -f /usr/openv/netbackup/vfms/FIM/install_adc ] ; then
	rm -f /usr/openv/netbackup/bin/install_adc
	cp /usr/openv/netbackup/vfms/FIM/install_adc /usr/openv/netbackup/bin/install_adc
	chmod 755 /usr/openv/netbackup/bin/install_adc
	chgrp bin /usr/openv/netbackup/bin/install_adc
else
	${ECHO} "Can't find install_adc."
	exit 3
fi
### The following line is tagged and used w/ sed in client_update()!
###ADCSWInstall###/usr/openv/netbackup/bin/install_adc
eof

fi ### Install ADC End ###

if [ $Install_Client_Bins = 1 ] ; then
	Check_Services
	if [ $Done = 1 ] ; then
		quit 1
	fi
fi

# Create a log file for output of update_client
LOGFILE=${TMPDIR}/update_clients.${DATE_TIME}
touch ${LOGFILE}

if [ "${ClientList}" = "" ] ; then
	/usr/openv/netbackup/bin/admincmd/bpplclients -allunique -noheader >${CLIENTS} 2>/dev/null
	if [ ! "$hardware" = "ALL" ] ; then
		grep $hardware ${CLIENTS} | grep ${os_name} > ${CLIENTS}.tmp
		mv ${CLIENTS}.tmp ${CLIENTS}
	fi

	ALPHA_FOUND=${TMPDIR}/ALPHA_FOUND.${DATE_TIME}
	FREEBSD_FOUND=${TMPDIR}/FREEBSD_FOUND.${DATE_TIME}
	HP_FOUND=${TMPDIR}/HP_FOUND.${DATE_TIME}
	LINUX_FOUND=${TMPDIR}/LINUX_FOUND.${DATE_TIME}
	RS6000_FOUND=${TMPDIR}/RS6000_FOUND.${DATE_TIME}
	SCO_FOUND=${TMPDIR}/SCO_FOUND.${DATE_TIME}
	SGI_FOUND=${TMPDIR}/SGI_FOUND.${DATE_TIME}
	SOLARIS_FOUND=${TMPDIR}/SOLARIS_FOUND.${DATE_TIME}
	NON_UNIX_FOUND=${TMPDIR}/non-UNIX_clients.${DATE_TIME}
	touch ${CLIENTS}.tmp
	/bin/cat ${CLIENTS} |
	while read class_hw class_os client
	do

		# Check to see if the client is the master (the local machine).
		# Use bpclntcmd so we aren't fooled by virtual names.

		${BP_BIN}/bpclntcmd -is_local_host ${client} > /dev/null 2>&1
		if [ $? -eq 0 ] ; then
			if [ $Install = TRUE ] ; then
				continue
			fi
		fi
		if [ "$class_hw" = "Solaris" -o "$class_hw" = "Sun4" ] ; then
			if [ "$class_os" != "SunOS4" ] ; then
				${ECHO} "  $class_os   \t$client" >> ${SOLARIS_FOUND}
			fi
		elif [ "$class_hw" = "ALPHA" ] ; then
			if [ "$class_os" = "WindowsNT" ] ; then
				${ECHO} "  $class_os  \t$client" >> ${NON_UNIX_FOUND}
				continue
			fi
			${ECHO} "  $class_os   \t$client" >> ${ALPHA_FOUND}
	 	elif [ "$class_hw" = "SCO" ] ; then
			${ECHO} "  $class_os  \t$client" >> ${SCO_FOUND}
	 	elif [ "$class_hw" = "SGI" -o "$class_hw" = "C910_920" ] ; then
			${ECHO} "  $class_os  \t$client" >> ${SGI_FOUND}
		elif [ "$class_hw" = "RS6000" ] ; then
			${ECHO} "  $class_os   \t$client" >> ${RS6000_FOUND}
		elif [ "$class_hw" = "Linux" ] ; then
			${ECHO} "  $class_os   \t$client" >> ${LINUX_FOUND}
		elif [ "$class_hw" = "HP9000-700" -o "$class_hw" = "HP9000-800" ] ; then
			${ECHO} "  $class_os   \t$client" >> ${HP_FOUND}
		elif [ "$class_hw" = "INTEL" ] ; then
			${ECHO} "  $class_os     $client" >> ${FREEBSD_FOUND}
		elif [ "$class_hw" = "MACINTOSH" -a "$class_os" = "MacOS" ] ; then
			${ECHO} "  $class_os  \t$client" >> ${NON_UNIX_FOUND}
			continue
		elif [ "$class_hw" = "PC" -o "$class_hw" = "Novell" -o "$class_hw" = "NDMP" ] ; then
			${ECHO} "  $class_os  \t$client" >> ${NON_UNIX_FOUND}
			continue
		elif [ "$class_hw" = "PC-IA64" ] ; then
			${ECHO} "  $class_os  \t$client" >> ${NON_UNIX_FOUND}
			continue
		fi
		${ECHO} $class_hw $class_os $client >> ${CLIENTS}.tmp
	done

	mv ${CLIENTS}.tmp ${CLIENTS}
	if [ -s ${NON_UNIX_FOUND} ] ; then
		cat ${CLIENTS} | grep -v "^PC" | grep -v "^Novell" | grep -v "^NDMP" > ${CLIENTS}.tmp
		mv ${CLIENTS}.tmp ${CLIENTS}
		${ECHO} "
The following non-UNIX clients with the OS type listed
cannot be installed or upgraded from the server.
  OS Type       Client name"
		Entries=`wc -l $NON_UNIX_FOUND | sed s/' '/''/g | cut -d '/' -f1`
		if [ $Entries -gt 9 ] ; then
			head -9 $NON_UNIX_FOUND
			${ECHO} "  ...
There are $Entries clients in the list."
		else
			cat $NON_UNIX_FOUND
		fi
		${ECHO} "The complete list can be found in $NON_UNIX_FOUND ."
	fi

	ls ${TMPDIR}/*_FOUND.${DATE_TIME} >/dev/null 2>&1
	if [ $? -eq 0 ] ; then
		${ECHO} "
The following clients with the OS type listed may need to be
changed in the NetBackup policy configuration so the appropriate
NetBackup software for the OS type can be installed.
  OS Type       Client name"
		for File in ${TMPDIR}/*_FOUND.${DATE_TIME}
		do
			#Reference hardware type from file name
			#due to possible multiple OS types contained in file.
			HW_Type=`basename ${File} | cut -d"_" -f1`
			announce_possibles ${File} ${HW_Type}
		done
		/bin/rm -f ${TMPDIR}/*_FOUND.${DATE_TIME}
		sort $LOGFILE > $TMPDIR/update_clients.sort.$$
		mv $TMPDIR/update_clients.sort.$$ $LOGFILE
		${ECHO} "
The full list of suspect clients can be found in $LOGFILE."

		${ECHO} ""
		if confirm y "Do you want to continue?"
		then
			${ECHO} "Continuing with the client update.  (Deleting $LOGFILE)"
			rm -f $LOGFILE
		else
			${ECHO} "
Aborting the client update.
"
			quit 2
		fi
	fi
else
	cp ${ClientList} ${CLIENTS}
fi

if [ ! -s ${CLIENTS} ] ; then
	${ECHO} "
There are no clients to upgrade."
	quit 3
else
	sort ${CLIENTS} > ${CLIENTS}.sorted
	mv ${CLIENTS}.sorted ${CLIENTS}
	NUM_CL=`wc -l ${CLIENTS} | sed s/' '/''/g | cut -d '/' -f1`
	if [ $NUM_CL -gt 15 ] ; then
		Default=15
	else
		Default=$NUM_CL
	fi
	if [ $NUM_CL -gt 30 ] ; then
		Max_Num=30
	else
		Max_Num=$NUM_CL
	fi

	${ECHO} "
There are $NUM_CL clients to upgrade."
	if [ $Install_Client_Bins = 1 ] ; then
		${ECHO} "
Do you want the bp.conf file on the clients updated"
		if confirm y "to list this server as the master server?"
		then
			EL=""

			# Build up a list of valid servers on ${TMPDIR}/bp_servers.
			# Look for 0 or more spaces and tabs followed by SERVER.
			SRVR=`egrep "^[${SPACE}${TAB}]*SERVER[${SPACE}${TAB}]*=" ${BP_DIR}/bp.conf`
			if [ "${SRVR}" = "" ] ; then
				${ECHO} "Missing SERVER in /usr/openv/netbackup/bp.conf"
				Done=1
			else
				egrep "^[${SPACE}${TAB}]*SERVER[${SPACE}${TAB}]*=" ${BP_DIR}/bp.conf > ${TMPDIR}/bp_servers
			fi
		else
			EL="-L"
			touch ${TMPDIR}/bp_servers
		fi
	fi
	if [ $Done = 1 ] ; then
		quit 1
	fi
	if [ $NUM_CL != 1 ] ; then
		get_number "Enter the number of simultaneous updates you wish to take place" 1 $Max_Num -d $Default
	else
		VALUE=1
	fi
	MinTime=`expr \( $NUM_CL + 1 \) \/ \( ${VALUE} \* 2 \)`
	MaxTime=`expr \( \( 2 \* $NUM_CL \) + 1 \) \/ ${VALUE}`
	if [ $MinTime -lt 1 ] ; then
		MinTime=1
	fi
	if [ $MaxTime -le $MinTime ] ; then
		MaxTime=`expr $MinTime + 1`
	fi
	${ECHO} "
The upgrade will likely take $MinTime to $MaxTime minutes."
	if confirm y "Do you want to upgrade clients now?"
	then
		${ECHO} "Please be patient."
	else
		${ECHO} "
You will need to upgrade clients later with install_client_files
or update_clients -ClientList filename
"
		quit 4
	fi
fi

${ECHO}
MostJobs=$VALUE
index=0
while [ $index -lt $MostJobs ]
do
	${ECHO} "Available" > ${CLIENTS}.${index}
	index=`expr $index + 1`
done

/bin/cat ${CLIENTS} |
while read class_hw class_os client
do
	index=0
	while [ $index -lt $MostJobs ]
	do
		Available=`cat ${CLIENTS}.${index}`
		if [ "$Available" = "Available" ] ; then
			${ECHO} "In_Use" > ${CLIENTS}.${index}
			JobIndex=$index
			break
		fi
		index=`expr $index + 1`
		if [ $index -ge $MostJobs ] ; then
			sleep 1
			index=0
		fi
	done

	if [ "$hardware" = "ALL" -o \
	  \( "$hardware" = "$class_hw" -a "${os_name}" = "$class_os" \) ] ; then
		(
		${ECHO} "Updating client ${client} -- ${class_hw} hardware running ${class_os}"
		client_update ${class_hw} ${class_os} ${client} ${JobIndex} & \
		PiD=$!
		wait $PiD
		Ustat=`cat ${CLIENTS}.${JobIndex}`
		if [ $Ustat = 1 ] ; then
			${ECHO} "	${client}: Version files match - no update needed"
		elif [ $Ustat = 2 ] ; then
			${ECHO} "	${client}: update failed, see ${LOGFILE}"
		elif [ $Ustat = 3 ] ; then
			${ECHO} "	${client}: Previous Release client type - no update done"
		else
			${ECHO} "	${client}: update complete"
		fi
		${ECHO} "Available" > ${CLIENTS}.${JobIndex}
		)&
	fi
done

# Wait for all jobs to be finished

index=0
while [ $index -lt $MostJobs ]
do
	if [ -f ${CLIENTS}.${index} ] ; then
		Available=`cat ${CLIENTS}.${index}`
		if [ "$Available" = "Available" ] ; then
			rm -f ${CLIENTS}.${index}
		else
			sleep 1
			continue  # wait for this one to be gone.
		fi
	fi
	index=`expr $index + 1`
done

QUIT=0
# The xargs echo converts the wc -l output from "     x" to "x"
NumMatch=`grep -i "Version files match" ${LOGFILE} | wc -l | xargs ${ECHO}`
if [ $NumMatch != 0 ] ; then
	${ECHO} "
$NumMatch of the clients had up to date software according to the version file.
To force the install of the client software on these clients you need to do:
"
	if [ ${Install_ADC} -eq 1 ] ; then
${ECHO} "$0 -ForceInstall -Install_ADC [-ClientList filename | hardware_type operating_system]"
	else
${ECHO} "$0 -ForceInstall [-ClientList filename | hardware_type operating_system]"
	fi
	QUIT=6
fi

# Clean up the /tmp files.
quit ${QUIT}
