#! /bin/ksh
#
#pragma ident	"@(#)hadsconfig.m4	1.22	01/05/03 SMI"
#
# Copyright (c) 1996-1999 Sun Microsystems, Inc.  
# All Rights Reserved.
#
# This program is called during the
# installation phase. It reads the data service instance
# definition block from the Templatefile, prompts the
# user for required info and creates instance
# block(s) in the conf file.

#####################################################
#
# Globals
#
#####################################################
#set -x

TEXTDOMAIN=hadsconfig; export TEXTDOMAIN
TEXTDOMAINDIR=/opt/SUNWcluster/locale;  export TEXTDOMAINDIR


PATH="/opt/SUNWcluster/bin:/usr/5bin:/usr/local/bin:\
/usr/bsd:/usr/ucb:/usr/bin:/bin:/etc:/sbin:/usr/sbin:$PATH"
export PATH

PROG=`basename $0`
yes=yes
no=no
YES="`gettext 'yes'`"
NO="`gettext 'no'`"
TMPRUN=/var/opt/SUNWcluster/run
TMPFILE=${TMPRUN}/${PROG}.$$ ; export TMPFILE;
TMPFILE2=${TMPRUN}/${PROG}.$$.2 ; export TMPFILE2;
AWKTMP=${TMPRUN}/${PROG}.awk.$$ ; export AWKTMP;
LOCKFILE=${TMPRUN}/${PROG}.lock ; export LOCKFILE;
PARSEFILE=${TMPRUN}/$PROG.pf.$$ ; export PARSEFILE;
WORKFILE=${TMPRUN}/$PROG.wk.$$
CONF_CHANGED=0

tname=
IS4X=yes

PARSER="/opt/SUNWcluster/bin/parse_svc_env"

trap "cleanup_exit 1 \"`gettext 'Exiting on signal'`\" " 1 2 15

# data for get_string():
# the following are here only to be picked up by xgettextsh;
# the string gets gettexted below using "gettext $msg", which
# wouldn't be picked up by xgettextsh as the real message, but
# as "$msg".
str=`gettext "Name of the instance                   \ "`
str=`gettext "Logical host                           \ "`
str=`gettext "Script to start this instance          \ "`
str=`gettext "Script to run as START_NET method      \ "`
str=`gettext "Script to stop this instance           \ "`
str=`gettext "Script to run as STOP_NET method   	  \ "`
str=`gettext "Script to abort this instance          \ "`
str=`gettext "Retry flag                             \ "`
str=`gettext "Number of times to retry               \ "`
str=`gettext "Time between retries (sec)             \ "`
str=`gettext "Fault probe program                    \ "`
str=`gettext "Time between probes (sec)              \ "`
str=`gettext "Time out value for the probe (sec)     \ "`
str=`gettext "Path to callback program               \ "`
str=`gettext "Local  probe flag                      \ "`
str=`gettext "Remote probe flag                      \ "`
str=`gettext "Take over flag                         \ "`
str=`gettext "Base directory of product installation \ "`
str=`gettext "Configuration Directory                \ "`
str=`gettext "Configuration File                     \ "`
str=`gettext "Server Port Number                     \ "`
str=`gettext "HA-DNS for Domain Name Service         \ "`
str=`gettext "HA-HTTP for Netscape                   \ "`
str=`gettext "HA-NEWS for Netscape                   \ "`
str=`gettext "HA-MAIL for Netscape                   \ "`
str=`gettext "HA-LDAP for Netscape                   \ "`
str=`gettext "HA-HTTP for Sun Web Server             \ "`
str=`gettext "HA-SAP for SAP R3                      \ "`
str=`gettext "HA-LOTUS for Lotus Domino Server       \ "`
str=`gettext "HA-TIVOLI for Tivoli                   \ "`
str=`gettext "HA-NBU for NetBackup                   \ "`
str=`gettext "HA-APACHE for Apache                   \ "`

#####################################################
#
# Set up file descriptors 3 and 4 as copies of stdin and stdout
# for use during calls made while reading our config file from stdin.
#
#####################################################
exec 3<&0 4>&1


#####################################################
#
# cleanup_exit() exitMessage exitcode
#	
#	Prints exitMessage on stderr
#	Removes the TMPFILE and the LOCKFILEs and exits
#   with the return code provided.
#####################################################

cleanup_exit()
{
	exit_code=$1; shift
        printf "$*\n" >&2
	rm -f ${TMPFILE} > /dev/null 2>&1
	rm -f ${TMPFILE2} > /dev/null 2>&1
	rm -f ${LOCKFILE} > /dev/null 2>&1
	rm -f ${AWKTMP} > /dev/null 2>&1
	rm -f ${AWKTMP}_1 > /dev/null 2>&1
	rm -f ${AWKTMP}_2 > /dev/null 2>&1
	rm -f ${AWKTMP}_3 > /dev/null 2>&1
	rm -f $PARSEFILE > /dev/null 2>&1
	rm -f $WORKFILE > /dev/null 2>&1
	exit $exit_code
}

#####################################################
#
# get_string() name
#				name - Name of the Attribute
#				
#				prints the prompt string on stdout
#
#####################################################

get_string()
{

	attr=$1
	echo "${attr}" | nawk ' BEGIN { 
qstr["NAME"] 			= "Name of the instance                   \ ";
qstr["LOGICAL_HOST"]		= "Logical host                           \ ";
qstr["START"]			= "Script to start this instance          \ ";
qstr["START_NET"] 		= "Script to run as START_NET method      \ ";
qstr["STOP"] 			= "Script to stop this instance           \ ";
qstr["STOP_NET"] 		= "Script to run as STOP_NET method   	  \ ";
qstr["ABORT"] 			= "Script to abort this instance          \ ";
qstr["RETRY"]			= "Retry flag                             \ ";
qstr["RETRY_TIMES"]		= "Number of times to retry               \ ";
qstr["RETRY_INTERVAL"]		= "Time between retries (sec)             \ ";
qstr["PROG"]			= "Fault probe program                    \ ";
qstr["INTERVAL"]  		= "Time between probes (sec)              \ ";
qstr["TIMEOUT"]			= "Time out value for the probe (sec)     \ ";
qstr["CALLBACK"]  		= "Path to callback program               \ ";
qstr["LOCAL"]			= "Local  probe flag                      \ ";
qstr["REMOTE"]			= "Remote probe flag                      \ ";
qstr["TAKEOVER"]		= "Take over flag                         \ ";
qstr["BASE_DIR"]		= "Base directory of product installation \ ";
qstr["CONF_DIR"]		= "Configuration Directory                \ ";
qstr["CONF_FILE"]		= "Configuration File                     \ ";
qstr["PORT"]			= "Server Port Number                     \ ";
qstr["BIN_DIR"]			= "Binary Directory                       \ ";

qstr["dns"]			= "HA-DNS for Domain Name Service         \ ";
qstr["nshttp"]			= "HA-HTTP for Netscape                   \ ";
qstr["nsnews"]			= "HA-NEWS for Netscape                   \ ";
qstr["nsmail"]			= "HA-MAIL for Netscape                   \ ";
qstr["nsldap"]			= "HA-LDAP for Netscape                   \ ";
qstr["sws"]			= "HA-HTTP for Sun Web Server             \ ";
qstr["sap"]			= "HA-SAP for SAP R3                      \ ";
qstr["lotus"]			= "HA-LOTUS for Lotus Domino Server       \ ";
qstr["tivoli"]			= "HA-TIVOLI for Tivoli                   \ ";
qstr["netbackup"]		= "HA-NBU for Netbackup                   \ ";
qstr["apache"]			= "HA-APACHE for Apache                   \ ";

		}
		{ print qstr[$1] ; } '
}

#####################################################
#
# prompt_yesno() "prompt" default
#
#               prompt  - the guts of the prompt
#               default - must be "yes" or "no" or "none"
#
#               User may type y, yes, Y, YES, n, no, N, NO.
#               Function will print "yes" or "no" on stdout
#               once user has responded correctly.
#
#####################################################
prompt_yesno()
{
	if [ $# -ne 2 ]; then
		err_echo "`gettext \
'%s: Internal error - bad call to prompt_yesno()'`" "${PROG}"
		return 1
	fi

	if [ "$2" != "${yes}" -a "$2" != "${no}" -a "$2" != none ]; then
		err_echo "`gettext \
'%s: Internal error - bad call to prompt_yesno()'`" "${PROG}"
		return 1
	fi

	prompt="$1 (${YES}/${NO})"
	default=$2
	foo=
	c=

	case ${default} in
	${yes})
			prompt="${prompt} [${YES}]"
			;;
	${no})
			prompt="${prompt} [${NO}]"
			;;
	none)
			default=
			prompt="${prompt}"
			;;
	esac

	c=
	while [ -z "${c}" ]
	do
		echo "${prompt}  \c" >&4
		read c <&3
		#read c foo <&3

		#if [ "${foo}" ]; then
			#c=
			#continue
		#fi

		if [ -z "${c}" ]; then
			c=${default}
		else 
			if [ "${yes}" = "${YES}" -a "${no}" = "${NO}" ]; then
				case ${c} in
				yes | y | YES | Y)
					c=${yes}
					;;
				no | n | NO | N)
					c=${no}
					;;
				*)
					c=
					;;
				esac
			else
				case "${c}" in
				${YES})
					c=${yes}
					;;
				${NO})
					c=${no}
					;;
				*)
					c=
					;;
				esac
			fi
		fi
	done
	echo "${c}"
	return 0
}

#####################################################
#
# print_tabs() number
#
#				number - number of tabs to print on stdout
#						Default is 0
#
####################################################
print_tabs()
{
	if [ $# -gt 1 ]; then
		err_echo "`gettext \
'%s: Internal error - bad call to print_tabs()'`" "${PROG}"
		return 1
	fi

	if [ $# -eq 1 ]; then
		n=$1
	else
		n=0
	fi

	if [ "${n}" -gt 16 -o "${n}" -lt 0 ]; then
		err_echo "`gettext \
'%s: Internal error - Wrong argument to print_tabs()'`" "${PROG}"
		return 1
	fi

	while [ ${n} -gt 0 ]
	do
		echo "\t" "\c"
		n=` expr ${n} - 1 `
	done

	return 0
}

#####################################################
#
# get_exefile() "prompt" default
#
#               prompt  - the guts of the prompt
#               default - A default value or "none"
#
#				User is supposed to enter a executable filename
#               Function will print the filename on stdout
#               once user has responded correctly.
#
#####################################################
get_exefile()
{
	if [ $# -ne 2 ]; then
		err_echo "`gettext \
'%s: Internal error - bad call to get_exefile()'`" "${PROG}"

		return 1
	fi

	if [ -x "$2" -o "$2" = "none" ]; then
		default=$2
	else
		err_echo "`gettext \
'%s: Internal error - bad call to get_exefile()'`" "${PROG}"
		return 1
	fi

	prompt="$1 "
	foo=
	c=

	case ${default} in
	none)
			default=
			prompt="${prompt}?"
			;;
	*)		prompt="${prompt} ($default)? "
			;;
	esac

	c=
	while [ -z "${c}" ]
	do
		echo "${prompt}  \c" >&4
		read c foo <&3

		if [ "${foo}" ]; then
			c=
			continue
		fi

		if [ -z "${c}" ]; then
			c=${default}
		fi

		if [ -z "${c}" ]; then
			continue
		fi

		if [ ! -f "${c}" ] ; then
			err_echo "`gettext 'No such file %s'`" "${c}"
			c=
			continue
		fi

		if [ ! -x "${c}" ] ; then
			err_echo "`gettext 'File %s is not executable '`" "${c}"
			c=
			continue
		fi

	done
	echo "${c}"
	return 0
}

#####################################################
#
# get_input() "prompt" default
#
#               prompt  - the guts of the prompt
#               default - A default value or "none"
#
#				User is supposed to enter a string
#               get_input will print the string on stdout
#               once user has responded correctly.
#
#####################################################
get_input()
{
	if [ $# -ne 2 ]; then
		err_echo "`gettext \
'%s: Internal error - bad call to get_input()'`" "${PROG}"
		return 1
	fi

	default=$2
	pre_prompt=`get_string $1`
	prompt=`gettext "$pre_prompt"`
	if [ ! "${prompt}" ]; then
		prompt="$1"
	fi
	foo=
	c=

	case ${default} in
	none)
			default=
			prompt="${prompt}? "
			;;
	*)		prompt="${prompt} [$default]? "
			;;
	esac

	c=
	while [ -z "${c}" ]
	do
		echo "${prompt}  \c" >&4
		read c foo <&3

		if [ "${foo}" ]; then
			err_echo "`gettext 'Invalid choice'`"
			c=
			continue
		fi

		if [ -z "${c}" ]; then
			c=${default}
		fi

	done
	echo "${c}"
	return 0
}


#####################################################
#
# get_multi_input() "prompt" default
#
#		Like get_input() but allows the user to enter
#		multiple words.
#####################################################
function get_multi_input
{
	if [ $# -ne 2 ]; then
		err_echo "`gettext \
'%s: Internal error - bad call to get_multi_input()'`" "${PROG}"
		return 1
	fi

	default=$2
	pre_prompt=`get_string $1`
	prompt=`gettext "$pre_prompt"`
	if [ ! "${prompt}" ]; then
		prompt="$1"
	fi

	case ${default} in
 	none)
 			default=
 			prompt="${prompt} "
 			;;
 	*)		prompt="${prompt} [$default] "
 			;;
 	esac

	while [ /bin/true ];
	do
		c=$(ckstr -Q -d "${default}" \
			-p "${prompt}" -e "`gettext 'Invalid Input'`")

	if [ ! "$c" ]; then
		continue
	fi

	break
	done

	print -n "${c}"
}

###########################################################
#
# check_dsname Name
#       Checks if an instance name is unique in hadsconf file
#
#   Return 0 if unique
#       Return !=0 if not unique
#
###########################################################

check_dsname()
{
	namelist=` grep -v "^\#" $1 | nawk ' /NAME/ { print $3} ' `
	for instname in ${namelist}
	do
		if [ "${instname}" = $2 ]; then
			return 1
		fi
	done

	return 0
}

###########################################################
#
# err_echo Message
#
#	Prints Message on stderr. Language support could be concentrated here.
#
###########################################################

err_echo()
{
	if [ $# -eq 0 ] ; then
		return
	fi
	format=$1
	shift
	printf "$format\n" $* >&2
}

#####################################################
#
#   fill_tables keyList valueList
#
#	fills the "instance values" table instValueTable or
# 	the "probe values" table probeValueTable, depending upon
# 	the keyList passed.
#
#		keyList - the attribute names (keys) separated by a ":" as
#				  in a CCD format
#		valueList - the values corresponding to the keys passed. 
#
#####################################################
function fill_tables
{

typeset keyTable
typeset valueTable
typeset i
typeset num
typeset list
typeset l

	set -A keyTable
	set -A valueTable

	let i=0
	list="`echo $1 | tr ':' ' '`"
	for l in ${list}; do
		keyTable[i]=${l}
		let i=i+1
	done

	let i=0
	list="`echo $2 | tr ':' ' '`"
	for l in ${list}; do
		valueTable[i]=${l}
		let i=i+1
	done

	num=${#keyTable[*]}
	let i=0
	while (( i < ${num} )); do
		#print "${i} ${keyTable[i]} ${valueTable[i]}"
    	set_value ${keyTable[i]} ${valueTable[i]}
		let i=i+1
	done
}
#####################################################
#
#	get_value name
#
#		name - the attribute name whose value is desired. name 
#			   should be one of the "instance keys" or "probe keys"
#
#
#####################################################
function get_value
{

typeset name
typeset value
typeset num
typeset i

name=$1  
let i=0
value=""

# Locate "name" in the "instance keys" table
num=${#instKeyTable[*]}

while (( i < ${num} )); do
if [[ "${name}" = ${instKeyTable[i]} ]]; then
    value=${instValueTable[i]}
    break
fi
let i=i+1
done

# if value is "", then the "name" could belong to the "probe keys" table
if [[ -z ${value} ]]; then

	let i=0
	num=${#probeKeyTable[*]}

	while (( i < ${num} )); do
		if [[ "${name}" = ${probeKeyTable[i]} ]]; then
			value=${probeValueTable[i]}
			break
		fi
		let i=i+1
	done

fi

print ${value}
return 0
 
}

#####################################################
#
#   add_instance_to_ccd service value
#
#   adds instance to the CCD
#
#       service - the name of the service.This also forms the
#                 name of the CCD format
#       value - the value of the "column parameter" which should be
#               added to the CCD
#
#####################################################
function add_instance_to_ccd
{
#set -x
typeset -u service
typeset format
typeset value

service=$1
format=$(get_format ${service})
value=$2

	add $service ${format} ${value}
	if [[ $? -ne 0 ]]; then
		cleanup_exit 1 "`gettext 'Error adding instance'`"
	fi

return 0
}

#####################################################
#
#   write_instance service
#
#   write instance to the workfile
#
#       service - the name of the service.This also forms the
#                 name of the CCD format
#
#####################################################
function write_instance
{

#set -x
typeset instance_name
typeset -u service
typeset format
typeset list
typeset -u l
typeset valueList
typeset i
typeset value

service=$1
instance_name=$(get_value NAME)

    print -n "${service} " >> ${WORKFILE}
    print -n "${instance_name} " >> ${WORKFILE}

	format=$(get_format ${service})
    let i=0
    list="`echo ${format} | tr ':' ' '`"
    #if [ "${IS4X}" = "no" ]; then
    #    list="/etc/netscape.mail.conf"
    #fi
    #else
    #    list="`echo ${list} | sed 's/conf_file/conf3_file/g'`"
    #fi
	
	valueList=""
    for l in ${list}; do
		value=$(get_value ${l})
		valueList="${valueList}${value}:"
        let i=i+1
    done
	valueList=${valueList%:}

    print -n "${valueList} " >> ${WORKFILE}
    print "CREATE" >> ${WORKFILE}

value=""
let i=0
num=${#probeKeyTable[*]}
 
let j=1
while (( 1 )); do
    value=$(get_value PROG)
    prog=$(extract "${value}" ${j})
    if [[ $? -ne 0 ]]; then
        break;
    fi
    value=$(get_value TIMEOUT)
    timeout=$(extract "${value}" ${j})
    if [[ $? -ne 0 ]]; then
        break;
    fi
    value=$(get_value INTERVAL)
    interval=$(extract "${value}" ${j})
    if [[ $? -ne 0 ]]; then
        break;
    fi
    value=$(get_value TAKEOVER)
    takeover=$(extract "${value}" ${j})
    if [[ $? -ne 0 ]]; then
        break;
    fi
 
	print -n "${service}_PROBE " >> ${WORKFILE}
	print -n "${instance_name} " >> ${WORKFILE}
    print -n "${instance_name}:${prog}:${interval}:${timeout}:${takeover} " \
		>> ${WORKFILE}
    print "CREATE" >> ${WORKFILE}

let j=j+1
done

return 0
}
#####################################################
#
#	is_populated service
#
#	checks if the service is already populated in the workfile
#
#       service - the name of the service
#
#	returns 1 if found; 0 otherwise
#
#####################################################
function is_populated
{

typeset -u service
typeset s
typeset found

let found=0
service=$1

	for s in ${POPULATED_SERVICES}; do
		if [[ "${s}" = "${service}" ]]; then
			let found=1
			break
		fi
	done

return ${found}
}
#####################################################
#
#   de_populate service
#
#	remove service from POPULATED_SERVICES
#
#       service - the name of the service
#
#####################################################
function de_populate
{

    typeset -u service
	typeset s
	typeset newList

    service=$1

    is_populated ${service}

    if [[ $? -eq 0 ]]; then
        return 0
    fi
	
	newList="" 
    for s in ${POPULATED_SERVICES}; do
        if [[ "${s}" = "${service}" ]]; then
			continue
        fi
		newList="${newList}${s} "
    done

	POPULATED_SERVICES=${newList}

}
#####################################################
#
#   purge_instance instance_name
#
#   purges (ie., completely removes) the service instance (along 
#	with its probe - just look for the given "instance_name" and remove all)
#	from the workfile
#
#####################################################
function purge_instance
{
	typeset instance_name
	typeset sname
	typeset value
	typeset iname
	typeset result
	typeset action

    touch ${TMPFILE}
	
	instance_name=$1

    while read sname iname value action ; do
        if [[ "${iname}" = "${instance_name}" ]]; then
			continue
        fi

        print -n "${sname} " >> ${TMPFILE}
        print -n "${iname} " >> ${TMPFILE}
        print -n "${value} " >> ${TMPFILE}
        print "${action}" >> ${TMPFILE}

    done < ${WORKFILE}

    mv ${TMPFILE} ${WORKFILE}
} 

#####################################################
#
#   populate service
#
#	reads instance records of the service from CCD and popluates
#	the workfile
#
#       service - the name of the service
#
#####################################################
function populate
{

	typeset -u service
	typeset instance_name
	typeset rows
	typeset r
	typeset prows
	typeset pr
	
	service=$1

	is_populated ${service}

	if [[ $? -ne 0 ]]; then
		return 1
	fi

	gettext "."

	check_if_valid
	rows=$(get_all ${service})

	for r in ${rows}; do
		gettext "."
		instance_name=${r#*:}
		instance_name=${instance_name%%:*}
		#instance_name=${r%:*:*:*:*}
		#instance_name=${instance_name#*:}

			gettext "."
    		print -n "${service} " >> ${WORKFILE}
			gettext "."
			print -n "${instance_name} " >> ${WORKFILE}
			gettext "."
			r=${r#*:}
			gettext "."
			print -n "${r}" >> ${WORKFILE}
			print " NOCHANGE" >> ${WORKFILE}
			check_if_valid
			prows=$(get ${service}_PROBE ${instance_name})
			for pr in ${prows}; do
				pr=${pr#*:}
				gettext "."
				print -n "${service}_PROBE " >> ${WORKFILE}
				gettext "."
				print -n "${instance_name} " >> ${WORKFILE}
				gettext "."
				gettext "."
				print -n "${pr}" >> ${WORKFILE}
				print " NOCHANGE" >> ${WORKFILE}
			done
	done
	POPULATED_SERVICES="${POPULATED_SERVICES}${service} "
}
#####################################################
#
#   delete_instance instance_name
#
#   masks the instance deleted in the workfile
#	Later, in write_to_ccd, when the contents of the workfile
#	are updated into the CCD, this instance will be removed
#	from the CCD
#
#####################################################
function delete_instance
{
 
typeset instance_name
typeset sname
typeset value
typeset iname
typeset result
typeset action
 
instance_name=$1
result=""

	if [[ -z ${instance_name} ]]; then
        	printf "`gettext '%s is null'`\n" "${instance_name}"
		return 1
	fi

	touch ${TMPFILE}
    while read sname iname value action ; do
		if [[ "${iname}" = "${instance_name}" ]]; then
			action="DELETE"
        fi

		print -n "${sname} " >> ${TMPFILE}
		print -n "${iname} " >> ${TMPFILE}
		print -n "${value} " >> ${TMPFILE}
		print "${action}" >> ${TMPFILE}
		
    done < ${WORKFILE}

	mv ${TMPFILE} ${WORKFILE}
}
#####################################################
#
#   read_instance service [instance_name] [ignore_delete]
#
#   read instance from the workfile
#
#       service - the name of the service.This also forms the
#                 name of the CCD format
#		instance_name - the name of the instance to read
#		ignore_delete - if set to 1 , return "deleted" instances also
#
#####################################################
function read_instance
{

typeset instance_name
typeset -u service
typeset sname
typeset value
typeset iname
typeset result
typeset action
typeset ignore_delete

service=$1
instance_name=$2
ignore_delete=$3

result=""

	while read sname iname value action ; do
		if [[ "${sname}" = "${service}" ]]; then
			if [[ -z ${instance_name} || \
					"${iname}" = "${instance_name}" ]]; then
				if [[ -n "${ignore_delete}" ]]; then
					result="${result}${value} "
				else
					if [[ "${action}" != "DELETE" ]]; then
						result="${result}${value} "
					fi
				fi
			fi
		fi
	done < ${WORKFILE}

	print "${result}"
}
#####################################################
#
#	check_fingerd
#
#	Checks if fingerd is enabled by looking at /etc/inetd.conf
#
#
#####################################################
function check_fingerd
{
typeset mh_finger
typeset tmpinet

	let mh_finger=2
    INETDCONF=/etc/inetd.conf

	cmd="grep \"^[ \t]*finger\" $INETDCONF"

	eval "$cmd" >/dev/null 2>&1

    case "$?" in
    0)
        # fingerd is enabled on mail host
        let mh_finger=1
        ;;
    1)
        # fingerd is disabled on mail host
        let mh_finger=0
        ;;
    *)
       	let mh_finger=2 
        ;;
    esac
	print ${mh_finger}
}
#####################################################
#
#	create_nsmail_conf
#
#	This function creates the NSMAIL4_CONF CCD row. It reads the
#	NS Mail conf file (/etc/netscape.mail.conf on default) and stores
#	all values therein to CCD. It also puts in other paramters
#	like if fingerd is enabled on this node (the mail host - on
#	which hadsconfig is done), mta_uid etc. This CCD row will be
#	retreived by the "nsmail_sync" command when it runs on all 
#	nodes (which are potential masters) and corresponding 
#	NS Mail conf file will be created, mta uids checked etc.
#	Refer to the nsmail_sync program for details.
#
#
#####################################################
function create_nsmail_conf
{

#set -x

typeset value
typeset conf_str
typeset inst_name
typeset mta_uid
typeset mta_gid
typeset line
typeset param_name
typeset param_value
typeset mailuser

value=$1

fill_tables NSMAIL_FORMAT ${value}

conf_file=$(get_value CONF_FILE)
inst_name=$(get_value NAME)

if [[ -z "${conf_file}" ]]; then
	return
fi

# find mailuser 
temp=`ls -l /etc/nsserver.cfg`
mailuser=`echo $temp | nawk '{print $3}'`

    ID=/usr/bin/id 
    temp=`$ID $mailuser 2>/dev/null`
    if [ $? -ne 0 ]; then
        printf "`gettext \
'User %s does not exist on host %s'`\n" "$mailuser" "`/bin/hostname`"
        return 1
    fi

   
    mta_uid=`echo $temp | sed 's/uid=\([0-9]*\).*/\1/'`
    mta_gid=`echo $temp | sed 's/.*gid=\([0-9]*\).*/\1/'`

    scccd ${CLUSTNAME} NSMAIL4_CONF query name 'SUNWscnsm*' > /dev/null 2>&1
    rc=$?
    if [ $rc -eq 0 ]; then
        scccd ${CLUSTNAME} NSMAIL4_CONF remove_format
    fi
    scccd ${CLUSTNAME} NSMAIL4_CONF add_format ${NSMAIL_CONF_FORMAT}

    conf_str="${inst_name}:SERVERROOT:${conf_file}"
    add_instance_to_ccd NSMAIL4_CONF "${conf_str}"
         
    conf_str="${inst_name}:MAILSRV:${mailuser}"
    add_instance_to_ccd NSMAIL4_CONF "${conf_str}"

    conf_str="${inst_name}:MTAUID:${mta_uid}"
    add_instance_to_ccd NSMAIL4_CONF "${conf_str}"
 
    conf_str="${inst_name}:MTAGID:${mta_gid}"
    add_instance_to_ccd NSMAIL4_CONF "${conf_str}"
}

#######################################

function create_nsmail_conf_old
{

#set -x
typeset value
typeset fingerd_set
typeset conf_str
typeset inst_name
typeset mta_uid
typeset mta_gid
typeset line
typeset param_name
typeset param_value


let fingerd_set=2
value=$1

fill_tables NSMAIL_FORMAT ${value}

conf_file=$(get_value CONF_FILE)
inst_name=$(get_value NAME)

if [[ -z "${conf_file}" ]]; then
	return
fi

# source the conf file
. ${conf_file}

	ID=/usr/bin/id 
    temp=`$ID $MailUserName 2>/dev/null`
    if [ $? -ne 0 ]; then
        printf "`gettext \
'User %s does not exist on host %s'`\n" "$MailUserName" "$MAILHOST"
        return 1
    fi
   
    mta_uid=`echo $temp | sed 's/uid=\([0-9]*\).*/\1/'`
    mta_gid=`echo $temp | sed 's/.*gid=\([0-9]*\).*/\1/'`

	LIBMATCH=/usr/lib/libNSmatch.so
	LHLIBLOOK=$ProgramDir/lib/nislook.so
	LHLIBDUMMY=$ProgramDir/lib/dummylook.so

    #
    # Figure out whether to link libNSmatch.so to nislook.so or dummylook.so
    #
    temp=`ls -l $LIBMATCH`
    if [ $? -ne 0 ]; then
        return 1
    fi
    echo $temp | grep nislook >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        LHLIBMATCH=$LHLIBLOOK
    else
        LHLIBMATCH=$LHLIBDUMMY
    fi

    LHOST=$(get_value LOGICAL_HOST)
    #
    # Fix for Netscape 3.0: the value of the new variable 'MessageHostName'
    # in /etc/netscape.mail.conf needs to be changed from the physical
    # host to the logical host.
    #
	# For Netscape3.5: Need to preserve the domainname
	# Other fix is to tag logical hostname at the end separated by comma (YES! Netscape3.5
	# supports more flexible hostname defenitions... Finally!), BUT that fix, though
	# more flexible, would break HA-Netscape Mail3.0
	#
    MAILHOST=`awk -F= ' $1=="MessageHostName" { print $2 } ' ${conf_file} `
	MAILHOSTNAME=`echo $MAILHOST | awk -F. ' { print $1 } ' `
	MAILDOMAIN=`echo $MAILHOST | awk -F. ' { for(i=2;i<NF+1;i++) printf(".%s", $i) } ' `
	NEWMAILHOST=$LHOST$MAILDOMAIN
    #MAILHOST=`grep ^MessageHostName ${conf_file} | sed 's/.*=//'` > /dev/null 2>&1
    ed -s ${conf_file} <<EOF> /dev/null 2>&1
/^MessageHostName=/s/=$MAILHOST/=$NEWMAILHOST/
w
q
.
EOF


#set -x
       # To make sure this is forward compatible with Mail server 4.1
         scccd ${CLUSTNAME} NSMAIL3_CONF query name 'SUNWscnsm*' > /dev/null 2>&1
         rc=$?
         if [ $rc -eq 0 ]; then
             scccd ${CLUSTNAME} NSMAIL3_CONF remove_format
         fi
         scccd ${CLUSTNAME} NSMAIL3_CONF add_format ${NSMAIL_CONF_FORMAT}

    for line in `cat ${conf_file} | grep -v ^#`; do
        param_name=`echo $line | sed 's/\=.*//'`
        param_value=`echo $line | sed 's/.*\=//'`
        if [ ${param_name} = "AccountURL" ]; then
                # replace any ':' in the parameteres with '}'
                param_value=`echo ${param_value} | sed 's/\:/\}/g'`
        fi
        conf_str="${inst_name}:${param_name}:${param_value}"
        add_instance_to_ccd NSMAIL3_CONF "${conf_str}"
         
    done
    # get MTAUID:MTAGID:mh_finger:LHLIBMATCH into ccd too
    conf_str="${inst_name}:MTAUID:${mta_uid}"
    add_instance_to_ccd NSMAIL3_CONF "${conf_str}"
 
    conf_str="${inst_name}:MTAGID:${mta_gid}"
    add_instance_to_ccd NSMAIL3_CONF "${conf_str}"
 
    conf_str="${inst_name}:mh_finger:${fingerd_set}"
    add_instance_to_ccd NSMAIL3_CONF "${conf_str}"
 
    conf_str="${inst_name}:LHLIBMATCH:${LHLIBMATCH}"
    add_instance_to_ccd NSMAIL3_CONF "${conf_str}"

}

isDataServiceHADS()
{
	for i in `echo $HADS_PKGS`;do
		if [ "$i" = "$CURRENT_PKG" ]; then
			return 1
		fi
	done
	return 0
}



############################################################
#
# replicate_file() filename
#       copies filename to all the sibling hosts
#       takes care to do it only over the private network.
#       Tries only the highly available private link.
#       Uses cdb lookups to find its siblings and their private network
#       address then uses rcp to copy the file. Avoids copying
#       to the local host (rcp may corrupt the file if this is done)
#
############################################################
 
replicate_file()
{
	FILE_TO_COPY=$1

	if [ -z "${FILE_TO_COPY}" ]; then
		err_echo "`gettext 'ERROR: Usage: replicate_file filename'`"
		return 2
	fi

	if [ ! -f "${FILE_TO_COPY}" ]; then
		err_echo "`gettext 'ERROR: Cannot find file %s for replication.'`" "${FILE_TO_COPY}" 
		return 1
	fi

	if [ ! -r /etc/opt/SUNWcluster/conf/default_clustername ]; then
		err_echo "`gettext 'ERROR: Unable to read cluster name for file replication.'`"
		report_replication_error ${FILE_TO_COPY}
		return 1
	fi

	DEF_CLUST_NAME=`head -1 /etc/opt/SUNWcluster/conf/default_clustername 2>/dev/null`
	if [ -z "${DEF_CLUST_NAME}" ]; then
		err_echo "`gettext 'ERROR: Unable to get cluster name for file replication.'`"
		report_replication_error ${FILE_TO_COPY}
		return 1
	fi

	CDBMATCH=/opt/SUNWcluster/bin/cdbmatch
	CLUSTM=/opt/SUNWcluster/bin/clustm

	CDB_FILE="/etc/opt/SUNWcluster/conf/${DEF_CLUST_NAME}.cdb"
	if [ ! -r ${CDB_FILE} ]; then
		err_echo "`gettext 'ERROR: Unable to read %s for file replication.'`" "${CDB_FILE}"
		report_replication_error ${FILE_TO_COPY}
		return 1
	fi

	CLUST_NAME=`${CDBMATCH} cluster.cluster_name ${CDB_FILE} 2>/dev/null`
	if [ $? -ne 0 ]; then
		err_echo "`gettext 'Warning: Could not get cluster name from cdb.  Using %s as the cluster name.'`" "${DEF_CLUST_NAME}"
		CLUST_NAME=${DEF_CLUST_NAME}
	fi

	# Sanity Check--if discrepency, use cdb-supplied information
	if [ "${DEF_CLUST_NAME}" != "${CLUST_NAME}" ]; then
		err_echo "`gettext 'Warning: Cluster names do not match. Using %s as the cluster name.'`" "${CLUST_NAME}"
	fi

	ALL_NODES=`${CLUSTM} getallnodes ${CLUST_NAME} 2>/dev/null`
	if [ $? -ne 0 ]; then
		err_echo "`gettext 'ERROR: Could not get all nodes for the cluster %s.'`" "${CLUST_NAME}"
		report_replication_error ${FILE_TO_COPY}
		return 1
	fi

	THIS_NODE=`${CLUSTM} getlocalnodeid ${CLUST_NAME} 2>/dev/null` 
	if [ $? -ne 0 ]; then
		err_echo "`gettext 'ERROR: Could not get node id for local node for file replication.'`"
		report_replication_error ${FILE_TO_COPY}
		return 1
	fi

	for nodeid in $ALL_NODES
	do
		NODE_NAME=
		NODE_ACTIVE=
		PRIV_IP_ADDR=

		if [ "${nodeid}" -eq "${THIS_NODE}" ]; then
			# No need to copy file because it is already on this host
			continue
		fi

		NODE_NAME=`${CDBMATCH} cluster.node.${nodeid}.hostname ${CDB_FILE} 2>/dev/null`
		if [ $? -ne 0 ]; then
			err_echo "`gettext 'Warning: Could not get hostname for Node %s.'`" "${nodeid}"
			
			# Set node name to the Node ID
			NODE_NAME="Node ${nodeid}"
		fi

		# Assign NODE_NAME to Node ID if cdb returned null hostname
		if [ -z "${NODE_NAME}" ]; then
			NODE_NAME="Node ${nodeid}"
		fi
				
		NODE_ACTIVE=`${CLUSTM} ismember ${CLUST_NAME} ${nodeid} 2>/dev/null`
		if [ $? -ne 0 ]; then
			err_echo "`gettext 'ERROR: Could not get node status for node %s.'`" "${nodeid}"
			report_replication_error ${FILE_TO_COPY} ${NODE_NAME}
			continue
		fi

		if [ "${NODE_ACTIVE}" -eq 0 ]; then
			# Node is not active
			err_echo "`gettext 'ERROR: %s is not part of the cluster so cannot copy file over private link.'`" "${NODE_NAME}"
			report_replication_error ${FILE_TO_COPY} ${NODE_NAME}
			continue
		fi

		# The node is active
		PRIV_IP_ADDR=`${CDBMATCH} cluster.node.${nodeid}.hahost ${CDB_FILE} 2>/dev/null`
		if [ $? -ne 0 ]; then
			err_echo "`gettext 'ERROR: Cannot get address of the private link of %s over which to copy the file.'`" "${NODE_NAME}"
			report_replication_error ${FILE_TO_COPY} ${NODE_NAME}
			continue
		fi

		# try to copy file using the private IP addr
		rcp -p ${FILE_TO_COPY} ${PRIV_IP_ADDR}:${FILE_TO_COPY} >/dev/null 2>&1
		if [ $? -ne 0 ]; then
			err_echo "`gettext 'ERROR: Failed to copy file to %s over private link.'`" "${NODE_NAME}"
			report_replication_error ${FILE_TO_COPY} ${NODE_NAME}
			continue
		fi
	done

	return 0
}
 
report_replication_error()
{
	FAILED_COPY_FILE=$1
	FAILED_COPY_HOST=$2

	# If no host is specified, print out the error message for ALL nodes
	if [ -z "${FAILED_COPY_HOST}" ]; then
		err_echo "`gettext '       Please manually copy the file %s to all nodes in the cluster'`" "${FAILED_COPY_FILE}"
	else
		err_echo "`gettext '       Please manually copy the file %s to %s'`" "${FAILED_COPY_FILE}" "${FAILED_COPY_HOST}"
	fi

	return 0
}


write_to_file()
{

	if [ ! -x "$PARSER" ]; then
        	err_echo "`gettext 'Unable to execute %s'`" "$PARSER"
        	cleanup_exit 1 "`gettext 'Exiting'`"
	fi

	$PARSER -cv $2 > /dev/null 2>&1 || { err_echo "`gettext 'The work file %s is corrupted'`" "$2"; return 1;}
        mv $2 $3 || { err_echo "`gettext 'Unable to update configuration from work file'`"; return 1;}
        gettext "Trying to Replicate configuration to other hosts\n"
        replicate_file $3
        if [ $? -eq 0 ]; then
                gettext "Replicated configuration to other hosts\n"
        fi
}

#####################################################
#
#	write_to_ccd
#
#	Read the workfile and update CCD with all instances of the
#	current service that have been modified.
#
#####################################################
function write_to_ccd
{

#set -x
typeset sname iname value action lname
typeset service
typeset inameList
typeset rows
typeset r
typeset prows
typeset pr

	service=${CURRENT_SERVICE}
	inameList=""

	# remove service from POPULATED_SERVICES
	de_populate ${service}

    while read sname iname value action ; do
        if [[ "${sname}" = "${service}" ]]; then
			inameList="${inameList}${iname} "
			case ${action} in
            	"NOCHANGE")
							continue
							;;
				"DELETE")
							# print "removing ${iname} from CCD ..."
							# remove the service instance from CCD
							check_if_valid
							remove ${service} name ${iname}
							if [[ "${service}" = "NSMAIL" ]]; then
								tconf_file=`echo ${value} | awk -F: '{print $NF}'`
								if [ ${tconf_file} != "/etc/netscape.mail.conf" ]; then
									IS4X=yes
								else
									IS4X=no
								fi
								if [[ "${IS4X}" = "yes" ]];then
									check_if_valid
									remove NSMAIL4_CONF name ${iname}
								else 
									check_if_valid
									remove NSMAIL3_CONF name ${iname}
								fi
		
							fi
							# remove the probe instance from CCD
							check_if_valid
							remove ${service}_PROBE name ${iname}
							;;
				"CREATE")
							if [[ "${service}" = "NSMAIL" ]]; then
								tconf_file=`echo ${value} | awk -F: '{print $NF}'`
								if [ ${tconf_file} != "/etc/netscape.mail.conf" ]; then
									IS4X=yes
								else
									IS4X=no
								fi
								if [[ "${IS4X}" = "yes" ]]; then
									create_nsmail_conf ${value}
								else
									create_nsmail_conf_old ${value}
								fi
							fi
							add_instance_to_ccd ${service} ${value}
							prows=$(read_instance ${service}_PROBE ${iname})
							if [[ -n "${prows}" ]]; then
								for pr in ${prows}; do
									add_instance_to_ccd ${service}_PROBE ${pr}
        						done
							fi
							# Get logical host name for this entry
							lname=${value#*:}
							lname=${lname%%:*}
							# print "lname is ${lname}"

							# Check if service and lname are already
							# linked in CCD
							check_if_valid
							rows=$(get_ds_lname ${service} ${lname})

							# if they are not linked, connect them now
							if [[ -z "${rows}" ]]; then
								check_if_valid
								connect ${service} ${lname}
							fi
							;;
			esac
        fi
    done < ${WORKFILE}

	# remove all service and probe instances of this service from the
	# workfile
	for iname in ${inameList}; do
		purge_instance ${iname}
	done

}
#####################################################
#
#	reset_attributes
#
#	clear all values in instValueTable and probeValueTable
#
#####################################################
function reset_attributes
{
typeset i
typeset num

let i=0
num=${#instValueTable[*]}

while (( i < ${num} )); do
	instValueTable[i]=""
	let i=i+1
done

let i=0
num=${#probeValueTable[*]}

while (( i < ${num} )); do
    probeValueTable[i]=""
    let i=i+1
done

return 0

}
#####################################################
#
#	replace input newvalue position
#
#	replaces the value of the parameter at the given "position"
#	within "input", with the new value. Returns the modified input.
#
#####################################################
function replace
{

typeset result
 
input="$1"
num=$2
newval=$3
result=""
 
#print "replace - ${input} ${num}"
 
let i=0

for val in ${input}; do
    let i=i+1
    if [[ i -eq ${num} ]]; then
		result="${result}${newval} "
	else
		result="${result}${val} "
    fi
done

print ${result}
return 0 
}
#####################################################
#
#   extract input position
#
#   extracts the value of the parameter at the given "position"
#   within "input". If position is out of the bounds of "input",
#	simply returns the entire "input".
#
#####################################################
function extract
{

input="$1"
num=$2

#print "extract - ${input} ${num}"

let i=0

for val in ${input}; do
	let i=i+1
	if [[ i -eq ${num} ]]; then
		print ${val}
		return 0
	fi
done

print ${input}
return 1
}


########################################################################
#
# DisplayHadsInstance(workfile, tmplatefile)
#
########################################################################

DisplayHadsInstance()
{
        gettext "Following are the specifications of this instance\n"
        echo ""
        nawk ' BEGIN                    {target = 0; skip=1}
               $1=="INSTANCE"        {target++; if( target == INST) skip=0;
                				else skip=1; }
               { if(!skip) print $0; } ' INST=$3 < $1 > $AWKTMP || { err_echo "`gettext 'Unable to create temp file'`"; return 1; }
        exec 8<$2 || { err_echo "`gettext 'Unable to redirect I/O'`"; return 1 ;}
 
        while [ 1 ]
        do
                read oneline <&8
                if [ $? -ne 0 ]; then
                        break
                fi
 
                attrName=` echo "${oneline}" | nawk -F"=| " ' { print $1 } ' | nawk ' {print $1} '`
                if [ ! "${attrName}"  ]; then
                        continue
                fi
                iscomment=` echo "${attrName}" | cut -c1`
                if [ "${iscomment}" = \# ]; then
                        continue
                fi
                case ${attrName} in
                        "{" | "}" | "INSTANCE" | "PRIVATE" | "PROBE" | "PROBES"| "SERVICE" | "VERSION") 
                        continue
                        ;;
                esac
                echo "${oneline}" | nawk -F"=|;" ' { printf("%s %s %s %s\n", $1, $2, $3, $4, $5) } ' > ${TMPFILE2} || { cleanup_exit 1 "`gettext 'Unable to create tmp file'`" ; }
                read attrName isqmark maybedefault < ${TMPFILE2}
 
                #echo Attr = ${attrName} isqmark = ${isqmark} maybedefault = ${maybedefault}     
                if [ "${isqmark}" = "?" ]; then
                        #grep ${attrName} $AWKTMP | nawk -F"=|;" ' { printf("%s %s %s %s\n", $1, $2, $3, $4, $5) } ' > ${TMPFILE2} || { cleanup_exit 1 "`gettext 'Unable to create tmp file'`" ; }
						grep ${attrName} $AWKTMP | tr -s '=' ' ' | tr -s ';' ' ' | nawk -v ATTR=${attrName} ' $1==ATTR { printf("%s %s %s %s\n", $1, $2, $3, $4, $5) } ' > ${TMPFILE2} || { print_err "`gettext 'Unable to create tmp file'`" 1 ; }

                        read attrName dflt < ${TMPFILE2}
                        pre_msgstr=`get_string $attrName`
			msgstr=`gettext "$pre_msgstr"`
                        if [ ! "$msgstr" ]; then
                                msgstr="$attrName "
                        fi
                        echo "$msgstr" = "$dflt"
                fi
 
        done
 
        echo ""
        return 0
}

DisplayInstance()
{

gettext "Following are the specifications of this instance\n"
typeset i
typeset num
typeset value
typeset attrName

value=""
let i=0
num=${#instKeyTable[*]}

while (( i < ${num} )); do
	value=$(get_value ${instKeyTable[i]})
	if [[ -n ${value} ]]; then
		pre_attrName=`get_string "${instKeyTable[i]}"`
		attrName=`gettext "$pre_attrName"`
		print "${attrName} :\t ${value}"
	fi
let i=i+1
done

print

value="" 
let i=0  
num=${#probeKeyTable[*]}

let j=1
let empty=1

while (( 1 )); do
let i=0

while (( i < ${num} )); do
    value=$(get_value ${probeKeyTable[i]})
    if [[ -n ${value} ]]; then
		# mark that the table is "not empty"
		empty=0
		value=$(extract "${value}" ${j})	
		if [[ $? -ne 0 ]]; then
			return 0
		fi
        pre_attrName=`get_string "${probeKeyTable[i]}"`
	attrName=`gettext "$pre_attrName"`
        print "${attrName} :\t ${value}"
    fi  
let i=i+1
done
	print
if [[ $empty = 1 ]]; then
	break
fi
let j=j+1
done

return 0
}

isServiceOn()
{
	iss_onoffstatus=` hareg | nawk ' $1==SERVICE { print $2 } ' SERVICE=$1 `
	if [ "$iss_onoffstatus" = "on" ]; then
		return 1
	fi

	return 0
}

warnServiceOn()
{
	clear
	printf "`gettext '\n\tData service \<%s\> is currently ON\n'`" "$1"
	gettext "\tChanges to configuration can not be made at this time\n"
	echo ""
	gettext "Press Enter to Return"
	read junk
	return 0
}

NumberOfInstances()
{
	 ninst=` nawk ' $1=="INSTANCE" { print $0 } ' $1 | wc -l `
	 return $ninst
}

ShowAndChooseInstance()
{
	typeset rows
	typeset -u service
	set -A instList
	typeset instance_name
	typeset r
	typeset format probe_format

	service=$1
	index=0
	n=0

	#rows=$(get_all ${service})
	rows=$(read_instance ${service} "")

	if [[ -z ${rows} ]]; then
		gettext "There are no configured instances\n"
		gettext "Press enter to return "
		read junk
		return 0
	fi

	gettext "\t\t Choose an instance from the following list\n\n"
    let i=1
    for r in ${rows}; do
        instance_name=${r%%:*}
		instList[i]=${instance_name}
        print "\t\t${i} ${instance_name}\n\n"
        let i=i+1
    done
	let i=i-1

	while [ /bin/true ];
	do

	lmsg1="`gettext 'Choose an instance number, or q for main menu'`"
	lmsg2="`gettext 'Invalid choice'`"
	n=$(ckstr -Q -d "" -r "^[1-9][1-9]*$" -r "^q$" \
	-p "${lmsg1} [1-$i]" -e "${lmsg2}")

 		if [ ! "$n" ]; then
 			continue
 		fi
 		if [ "$n" = "q" ]; then
 			return 0
 		fi

	if [ "$n" -lt 1 -o "$n" -gt $i ]; then
		err_echo "`gettext 'Invalid choice'`"
		continue
	fi

	break
	done

	reset_attributes

	instance_name=${instList[n]}

	rows=$(read_instance ${service} ${instance_name})
	format=$(get_format ${service})
	probe_format=$(get_format ${service}_PROBE)
	if [[ -n "${rows}" ]]; then
		for r in ${rows}; do
			fill_tables ${format} ${r}
		done
	fi

	rows=$(read_instance ${service}_PROBE ${instance_name})
	if [[ -n "${rows}" ]]; then
		for r in ${rows}; do
			fill_tables ${probe_format} ${r}
		done
	fi

	return $n
}

ShowAndChooseHadsInstance()
{
        index=0
        n=0

        NumberOfInstances $1
        if [ $? -eq 0 ]; then
                gettext "There are no configured instances\n"
                gettext "Press enter to return "
                read junk
                return 0
        fi
        ilist=` nawk ' $1=="NAME" { print $3 } ' $1 `
        gettext "\t\t Choose an instance from the following list\n\n"
        for inst in $ilist
        do
                index=` expr $index + 1 `
                echo "\t\t$index $inst\n\n"
        done
        while [ /bin/true ]
        do
		lmsg="`gettext 'Choose an instance number, or q for main menu'`"
		printf "${lmsg} [1-%s]\n" "$index"
                read n x
                if [ "$x" ]; then
                        err_echo "`gettext 'Invalid choice'`"
                        continue
                fi
                if [ ! "$n" ]; then
                        continue
                fi
                if [ "$n" = "q" ]; then
                        return 0
                fi
                if [ "$n" -lt 1 -o "$n" -gt $index ]; then
                        err_echo "`gettext 'Invalid choice'`"
                        continue
                fi
                break
        done
 
        return $n
}
 


do_create()
{
#set -x
	typeset -u sname
	typeset restart
	typeset	rows

	restart=0
	sname=$3
	#IS4X=$4
	isServiceOn $3
	onoffstatus=$?
	if [ $onoffstatus -gt 0 ]; then
		warnServiceOn $3
		return
	fi
	tab_depth=0

	if [[ "${sname}" = "NSMAIL" || "${sname}" = "DNS" ]]; then
		rows=$(read_instance ${sname} "")
		if [[ -n "${rows}" ]]; then
			clear
                        #
                        # TRANSLATION_NOTE
                        # The following 3 messages go together:
                        #
                        printf "`gettext \
'\n\nThere already exists an instance of %s'` " "${sname}"
                        printf "`gettext \
'in the configuration. There can be a maximum of'` "
                        printf "`gettext \
'only one instance of %s.'`\n\n" "${sname}"
			gettext "Press Enter to Return"
    		read junk
			return
		fi
	fi

	clear
	gettext "\t\tCreating New Instance"
	echo ""

	exec 5<$1

	reset_attributes

	success=false
	moreattributes=yes
	while [ ${moreattributes} = "yes" ]
	do
		if [[ ${restart} -eq 1 ]]; then
			exec 5<$1
			reset_attributes
			success=false
			moreattributes=yes
			tab_depth=`expr ${tab_depth} - 1 `
			restart=0
		fi
		read oneline <&5
		if [ $? -ne 0 ]; then
			if [ ${tab_depth} -ne 0 ]; then
				err_echo "`gettext 'Unexpected EOF in %s'`" "$2"
			else
				success=true
			fi
			break
		fi

		attrName=` echo "${oneline}" | nawk -F"=|;" ' { print $1 } ' | nawk ' { print $1} '`

		#print "do_create(): attrName = ${attrName}"

		#echo attrName = $attrName
		#read attrName foo isqmark maybedefault <&5
		if [ ! "${attrName}"  ]; then
			continue
		fi

		iscomment=` echo "${attrName}" | cut -c1`
		if [ "${iscomment}" = \# ]; then
			continue
		fi
		case ${attrName} in
			"{")
					#print_tabs ${tab_depth} >&6
					#echo "{" >&6
					tab_depth=`expr ${tab_depth} + 1 `
					continue
					;;
			"}")
					tab_depth=`expr ${tab_depth} - 1 `
					if [ ${tab_depth} -lt 0 ]; then
						err_echo "`gettext \
'Syntax Error in %s'`" "$1"
						break
					fi
					#print_tabs ${tab_depth} >&6
					#echo "}" >&6
					continue
					;;
            "INSTANCE")
                    continue
                    ;;
            "PRIVATE")
                    continue
                    ;;
            "PROBE" | "PROBES")
                    continue
                    ;;
            "SERVICE" | "VERSION")
                    if [ ${tab_depth} -ne 0 ]; then
                        err_echo "`gettext 'Syntax Error in %s'`" "$2"
                        break
                    fi
                    if [ "$CONFISNEW" = $no ]; then
                        continue
                    fi
                    ;;
		esac

		echo "${oneline}" | nawk -F"=|;" ' { printf("%s %s %s %s\n", $1, $2, $3, $4, $5) } ' > ${TMPFILE2} || { cleanup_exit 1 "`gettext 'Unable to create tmp file'`" ; }
		#echo "${oneline}" | nawk -F= ' { printf("%s %s %s %s\n", $1, $2, $3, $4) } ' | nawk -F\; ' { printf("%s %s %s\n", $1, $2, $3) } ' > ${TMPFILE2} || { cleanup_exit 1 "`gettext 'Unable to create tmp file'`" ; }
		read attrName isqmark maybedefault < ${TMPFILE2}

		#print "do_create(): ${attrName} ${isqmark} ${maybedefault}"

		#echo Attr = ${attrName} isqmark = ${isqmark} maybedefault = ${maybedefault}
		if [ "${isqmark}" = "?" ]; then
			if [ "${maybedefault}" ]; then
				defvalue=${maybedefault}
			else
				defvalue=none
			fi
		else
			if [ ! "${isqmark}" ]; then
				cleanup_exit 1 "`gettext 'Syntax Error in'` $2 "
			fi
			defvalue="${isqmark} ${maybedefault}"
			#print_tabs ${tab_depth} >&6
			#echo "${attrName}" = "${defvalue}" \; >&6
			set_value "${attrName}" "${defvalue}"
			continue
		fi

		valueisuniq=false
		CURRENT_SERVICE=$3
		while [ ${valueisuniq} = "false" ]
		do
			attrval=$(get_multi_input "${attrName} " "${defvalue}")
			if [ "${attrName}" = "NAME" ]; then
				validate "${attrName}" "${WORKFILE} $2_${attrval}"
				#validate "${attrName}" "${WORKFILE} SUNWcluster_${attrval}"
				if [[ $? -ne 0 ]]; then
					continue
				fi
				#print_tabs ${tab_depth} >&6
				#echo ${attrName} = "${3}_${attrval}" \; >&6
				tname=${attrval}
				set_value "${attrName}" "$2_${attrval}"
				#set_value "${attrName}" "SUNWcluster_${attrval}"
			elif [[ "${attrName}" = "BASE_DIR" ]] && [[ "$sname" = "NSMAIL" ]]; then
				validate "${attrName}" "${attrval}"
				if [[ $? -ne 0 ]]; then
					continue
				fi
				attrName="`echo ${attrName} | sed 's/BASE_DIR/CONF_FILE/g'`"
				if [[ ! -d ${attrval}/bin/msg ]] && [[ ! -d ${attrval}/bin/mail ]]; then
					printf "`gettext \
'\n\tUnable to find messaging server in %s\n\n'`" "${attrval}"
					attrName="`echo ${attrName} | sed 's/CONF_FILE/BASE_DIR/g'`"
					restart=1
					break
				elif [[ ! -d ${attrval}/bin/msg ]]; then
					attrval="/etc/netscape.mail.conf"
					IS4X=no
				elif [[ ! -d ${attrval}/msg-${tname} ]] && [[ -d ${attrval}/bin/msg ]];then
					printf "`gettext \
'\n\tUnable to find instance %s in %s\n\n'`" "${tname}" "${attrval}"
					attrName="`echo ${attrName} | sed 's/CONF_FILE/BASE_DIR/g'`"
					restart=1
					break
				fi
				set_value "${attrName}" "${attrval}"
				if [ ${attrval} != "/etc/netscape.mail.conf" ]; then
					IS4X=yes
				fi
			else
				#print_tabs ${tab_depth} >&6
				#echo "${attrName}" = "${attrval}" \; >&6
				validate "${attrName}" "${attrval}"
				if [[ $? -ne 0 ]]; then
					continue
				fi
				set_value "${attrName}" "${attrval}"
			fi
			valueisuniq=true
		done
	done

	DisplayInstance
	msg="`gettext 'Add this instance ? '`"
	isok=`prompt_yesno "${msg}" yes `
        if [ "${isok}" = "yes" ]; then
			write_instance $3
			gettext "Instance added to workfile\n"
            CONF_CHANGED=1
            CONFISNEW=$no
        else
            gettext "Instance not added to workfile\n"
        fi
	#print_attr_values

	gettext "Press enter to return to main menu "
	read junk

	return $CONF_CHANGED
}

##################################################################
#
# do_hads_create(tmplatefile, pkgname, servicename, workfile)
#
##################################################################

do_hads_create()
{
#set -x
        isServiceOn $3
        onoffstatus=$?
        if [ $onoffstatus -gt 0 ]; then
                warnServiceOn $3
                return
        fi
        tab_depth=0

        clear
        gettext "\t\tCreating New Instance"
        echo ""
        touch ${TMPFILE}

        if [ $? -ne 0 ]; then
                cleanup_exit 1 "`gettext 'Unable to create'` ${TMPFILE} "
        fi

        exec 5<$1 6>${TMPFILE} || { cleanup_exit 1 "`gettext 'Unable to redirect I/O'`"; }

        success=false
        moreattributes=yes
        while [ ${moreattributes} = "yes" ]
        do
                read oneline <&5
                if [ $? -ne 0 ]; then
                        if [ ${tab_depth} -ne 0 ]; then
                                err_echo "`gettext 'Unexpected EOF in %s'`" "$1"
                        else
                                success=true
                        fi
                        break
                fi
 
                attrName=` echo "${oneline}" | nawk -F"=|;" ' { print $1 } ' | nawk ' { print $1} '`
                #echo attrName = $attrName
                #read attrName foo isqmark maybedefault <&5
                if [ ! "${attrName}"  ]; then
                        continue
                fi
 
                iscomment=` echo "${attrName}" | cut -c1`
                if [ "${iscomment}" = \# ]; then
                        continue
                fi
                case ${attrName} in
                        "{")
                                        print_tabs ${tab_depth} >&6
                                        echo "{" >&6
                                        tab_depth=`expr ${tab_depth} + 1 `
                                        continue
                                        ;;
                        "}")
                                        tab_depth=`expr ${tab_depth} - 1 `
                                        if [ ${tab_depth} -lt 0 ]; then
                                                err_echo "`gettext \
'Syntax Error in %s'`" "$1"
                                                break
                                        fi
                                        print_tabs ${tab_depth} >&6
                                        echo "}" >&6
                                        continue
                                        ;;
                        "INSTANCE")
                                        print_tabs ${tab_depth} >&6
                                        echo "INSTANCE" >&6
                                        continue
                                        ;;
                        "PRIVATE")
                                        print_tabs ${tab_depth} >&6
                                        echo "PRIVATE" >&6
                                        continue
                                        ;;
                        "PROBE" | "PROBES")
                                        print_tabs ${tab_depth} >&6
                                        echo "${attrName}" >&6
                                        continue
                                        ;;
                        "SERVICE" | "VERSION")
                                        if [ ${tab_depth} -ne 0 ]; then
                                                err_echo "`gettext \
'Syntax Error in %s'`" "$1"
                                                break
                                        fi
                                        if [ "$CONFISNEW" = $no ]; then
                                                continue
                                        fi
                                        ;;
                esac
 
                echo "${oneline}" | nawk -F"=|;" ' { printf("%s %s %s %s\n", $1, $2, $3, $4, $5) } ' > ${TMPFILE2} || { cleanup_exit 1 "`gettext 'Unable to create tmp file'`" ; }
                #echo "${oneline}" | nawk -F= ' { printf("%s %s %s %s\n", $1, $2, $3, $4) } ' | nawk -F\; ' { printf("%s %s %s\n", $1, $2, $3) } ' > ${TMPFILE2} || { cleanup_exit 1 "`gettext 'Unable to create tmp file'`" ; }
                read attrName isqmark maybedefault < ${TMPFILE2}
 
                #echo Attr = ${attrName} isqmark = ${isqmark} maybedefault = ${maybedefault}
                if [ "${isqmark}" = "?" ]; then
                        if [ "${maybedefault}" ]; then
                                defvalue=${maybedefault}
                        else
                                defvalue=none
                        fi
                else
                        if [ ! "${isqmark}" ]; then
                                cleanup_exit 1 "`gettext 'Syntax Error in'` $1 "
                        fi
                        defvalue="${isqmark} ${maybedefault}"
                        print_tabs ${tab_depth} >&6
                        echo "${attrName}" = "${defvalue}" \; >&6
                        continue
                fi
                valueisuniq=false
                while [ ${valueisuniq} = "false" ]
                do
                        attrval=`get_multi_input "${attrName} " "${defvalue}" `
                        if [ "${attrName}" = "NAME" ]; then
                                check_dsname $4 "${2}_${attrval}" || { err_echo "`gettext 'Instance %s already exists'`" "${attrval}" ; continue ; }
                                print_tabs ${tab_depth} >&6
                                echo ${attrName} = "${2}_${attrval}" \; >&6
                        else
                                print_tabs ${tab_depth} >&6
                                echo "${attrName}" = "${attrval}" \; >&6
                        fi
                        valueisuniq=true
                done
        done
 
#Do a syntax check on the tmp file with the parser
 
        if [ "${success}" = "true" ]; then
                if [ "$CONFISNEW" = "$yes" ]; then
                        echo "" > $PARSEFILE
                else
                        nawk -F"=| " ' $1=="SERVICE" || $1=="VERSION" { print $0 } ' $1 > $PARSEFILE
                fi
                if [ $? -ne 0 ]; then
                        err_echo "`gettext 'Error creating parse file'`"
                        success=false
                fi
        fi
 
        if [ "${success}" = "true" ]; then
                if cat $TMPFILE >> $PARSEFILE; then
                        $PARSER -cv  $PARSEFILE > /dev/null
                        if [ $? -ne 0 ]; then
                                err_echo "`gettext 'Error parsing the instance specification'`"
                                #cat $PARSEFILE
                                success=false
                        fi
                else
                        err_echo "`gettext 'Error creating temporary file'`"
                        success=false
                fi
 
                rm -f $PARSEFILE
        fi
        if [ "${success}" = "true" ]; then
 
		isDataServiceHADS;
		if [ $? = 0 ]; then
                	DisplayInstance ${TMPFILE} $1 1
		else
                	DisplayHadsInstance ${TMPFILE} $1 1
		fi
		msg="`gettext 'Add this instance to configuration '`"
                isok=`prompt_yesno "${msg}" yes `
                if [ "${isok}" = "yes" ]; then
                        echo "" >> $4
                        cat ${TMPFILE} >> $4
                        if [ $? -ne 0 ]; then
                                cleanup_exit 1 "`gettext 'Error Appending to'` $4 "
                        fi
                        CONF_CHANGED=1
                        CONFISNEW=$no
                else
                        gettext "Instance not added to configuration\n"
                fi
        fi
 
        rm -f ${TMPFILE} > /dev/null 2>&1
        gettext "Press enter to return to main menu "
        read junk
        return $CONF_CHANGED
}

do_delete()
{
	typeset tIS4X

	CURRENT_SERVICE=$3
	isServiceOn $3
	onoffstatus=$?
	if [ $onoffstatus -gt 0 ]; then
		warnServiceOn $3
		return
	fi
	d_idx=0
	clear

	gettext "\t\t Deleting an instance\n\n"
	ShowAndChooseInstance $3
	inst=$?
	if [ $inst = 0 ]; then
		return 0
	fi

	DisplayInstance

	msg="`gettext 'Delete this instance ?'`"
	resp=`prompt_yesno "${msg}" no `
	if [ "$resp" = "no" ]; then
		gettext "Not deleted\n"
		gettext "Press enter to return to main menu "
		read junk
		return 0
	fi

	inst_name=$(get_value NAME)
	tIS4X=$(get_value CONF_FILE)
	if [[ "${tIS4X}" = "/etc/netscape.mail.conf" ]]; then
		IS4X=no
	fi
        delete_instance ${inst_name}
	CONF_CHANGED=1
	gettext "Instance deleted from workfile\n"
	gettext "Press enter to return to main menu "
	read junk
	return $CONF_CHANGED
}

#################################################################
#
# do_hads_delete(templatefile, pkgname, servicename, workfile)
#
#################################################################

do_hads_delete()
{

  	CURRENT_SERVICE=$3
        isServiceOn $3
        onoffstatus=$?
        if [ $onoffstatus -gt 0 ]; then
                warnServiceOn $3
                return
        fi

        d_idx=0
        clear
 
        gettext "\t\t Deleting an instance\n\n"
        ShowAndChooseHadsInstance $4
        inst=$?
        if [ $inst = 0 ]; then
                return 0
        fi
 
        DisplayHadsInstance $4 $1 $inst
 
	msg="`gettext 'Delete this instance '`"
        resp=`prompt_yesno "${msg}" no `
        if [ "$resp" = "no" ]; then
                gettext "Not deleted\n"
                gettext "Press enter to return to main menu "
                read junk
                return 0
        fi
                
        nawk ' BEGIN {target = 0; skip=0}
               $1=="INSTANCE"        {target++; if( target == INST) skip=1;
                			else skip=0; }     
               { if(!skip) print $0; } ' INST=$inst < $4 > $AWKTMP
        if [ $? -ne 0 ]; then
                err_echo "`gettext 'Unable to create %s'`" "$AWKTMP"
                return -1
        fi
        mv $AWKTMP $4
        if [ $? -ne 0 ]; then
                err_echo "`gettext 'Error: Unable to modify %s'`" "$4"
                gettext "Press enter to return to main menu "
                read junk
                return -1
        fi
 
        CONF_CHANGED=1
        gettext "Instance deleted from configuration\n"
        gettext "Press enter to return to main menu "
        read junk
        return $CONF_CHANGED
}
 

do_show()
{
	CURRENT_SERVICE=$1
	clear

	gettext "\t\t Showing the specifications of an instance\n\n"
	ShowAndChooseInstance $1
	inst=$?
	if [ $inst = 0 ]; then
		return 0
	fi

	DisplayInstance

	gettext "Press enter to return to main menu "
	read junk
	return 0
}

do_hads_show()
{
        clear

        gettext "\t\t Showing the specifications of an instance\n\n"
        ShowAndChooseHadsInstance $1
        inst=$?
        if [ $inst = 0 ]; then
                return 0
        fi

        DisplayHadsInstance $1 $2 $inst

        gettext "Press enter to return to main menu "
        read junk
        return 0
}


do_edit()
{
	typeset CURRENT_SERVICE
	typeset restart

	restart=0

	CURRENT_SERVICE=$3
	isServiceOn $3
	onoffstatus=$?
	if [ $onoffstatus -gt 0 ]; then
		warnServiceOn $3
		return
	fi
	clear
	tab_depth=0

	gettext "\t\t Edit Instance\n\n"
	ShowAndChooseInstance $3
	inst=$?
	if [ $inst = 0 ]; then
		return 0
	fi

	exec 5<$1 || { cleanup_exit 1 "`gettext 'Unable to redirect I/O'`"; }

	success=false
	moreattributes=yes
	let do_edit_probe_num=0
	while [ ${moreattributes} = "yes" ]
	do
		if [[ ${restart} -eq 1 ]]; then
			exec 5<$1
			# reset_attributes -- don't reset attrs here, since
			#                     this is an edit, not a create
			success=false
			moreattributes=yes
			tab_depth=`expr ${tab_depth} - 1 `
			restart=0
		fi
		read oneline <&5
		if [ $? -ne 0 ]; then
			if [ ${tab_depth} -ne 0 ]; then
				err_echo "`gettext 'Unexpected EOF in %s'`" "$2"
			else
				success=true
			fi
			break
		fi

		attrName=` echo "${oneline}" | nawk -F"=| " ' { print $1 } ' | nawk ' {print $1} ' `
		#read attrName foo isqmark maybedefault <&5

		if [ ! "${attrName}"  ]; then
			continue
		fi

		iscomment=` echo "${attrName}" | cut -c1`
		if [ "${iscomment}" = \# ]; then
			continue
		fi

		if [ "$attrName" = "SERVICE" -o "$attrName" = "VERSION" ]; then
			continue
		fi

		case ${attrName} in
			"{")
					tab_depth=`expr ${tab_depth} + 1 `
					continue
					;;
			"}")
					tab_depth=`expr ${tab_depth} - 1 `
					if [ ${tab_depth} -lt 0 ]; then
						err_echo "`gettext \
'Syntax Error in %s'`" "$2"
						break
					fi
					continue
					;;
			"INSTANCE")
					continue
					;;
			"PRIVATE")
					continue
					;;
			"PROBE")
					let do_edit_probe_num=do_edit_probe_num+1
					continue
					;;
			"PROBES")
					continue
					;;
			"SERVICE" | "VERSION")
					if [ ${tab_depth} -ne 0 ]; then
						err_echo "`gettext \
'Syntax Error in %s'`" "$2"
						break
					fi
					if [ "$CONFISNEW" = $no ]; then
						continue
					fi
					;;  
		esac

		echo "${oneline}" | nawk -F"=|;" ' { for(i=1;i<NF+1;i++) printf("%s ", $i) } ' > ${TMPFILE2} || { cleanup_exit 1 "Unable to create tmp file" ; }

		# this is a hack to get around the fact that since CONF_FILE
		# is being overloaded w/ BASE_DIR for nsmail data service,
		# the old_value needs to come from conf_file in the CCD,
		# but the input needs to be represented on the menu as
		# being for base dir.
		if [[ "${attrName}" = "BASE_DIR" ]] && [[ "$CURRENT_SERVICE" = "nsmail" ]]; then
			conf_file_attrName="`echo ${attrName} | sed 's/BASE_DIR/CONF_FILE/g'`"
			old_value=$(get_value "${conf_file_attrName}")
			#print "conf_file_attrName = ${conf_file_attrName} old_value = ${old_value}"
			old_value=$(extract "${old_value}" ${do_edit_probe_num})
			#print "conf_file_attrName = ${conf_file_attrName} old_value = ${old_value}"
		else
			old_value=$(get_value "${attrName}")
			#print "attrName = ${attrName} old_value = ${old_value}"
			old_value=$(extract "${old_value}" ${do_edit_probe_num})
			#print "attrName = ${attrName} old_value = ${old_value}"
		fi

		if [[ "${attrName}" = "NAME" ]]; then
			old_instance_name=${old_value}
		fi

		#print "do_edit(): attrName = ${attrName} ${old_value}"
		read attrName isqmark maybedefault < ${TMPFILE2}

		#echo Attr = ${attrName} isqmark = ${isqmark} maybedefault = ${maybedefault}
		if [ "${isqmark}" = "?" ]; then
				defvalue=${old_value}
		else
			if [ ! "${isqmark}" ]; then
				cleanup_exit 1 "`gettext 'Syntax Error in'` $2 "
			fi
			defvalue="${isqmark} ${maybedefault}"
			set_value "${attrName}" "${defvalue}" ${do_edit_probe_num}
			continue
		fi

		valueisuniq=false
		while [ ${valueisuniq} = "false" ]
		do
			attrval=$(get_multi_input "${attrName} " "${defvalue}")
			if [ "${attrName}" = "NAME" ]; then
				if [ "$attrval" != "$defvalue" -a \
				     "${2}_$attrval" != "$defvalue" ]; then
					validate "${attrName}" "${WORKFILE} $2_${attrval}"
					#validate "${attrName}" "${WORKFILE} SUNWcluster_${attrval}"
					if [[ $? -ne 0 ]]; then
						continue
					fi
					#print_tabs ${tab_depth} >&6
					#echo "${attrName}" = "${3}_${attrval}" \; >&6
					# save this name for possible later
					# use as netscape mail instance name
					tname=${attrval}
					set_value "${attrName}" "${2}_${attrval}" ${do_edit_probe_num}
					#set_value "${attrName}" "SUNWcluster_${attrval}" \
					#				${do_edit_probe_num}
				else
					#echo "${attrName}" = "${attrval}" \; >&6

					# save this name for possible later
					# use as netscape mail instance name
					tname=`echo ${attrval} | sed "s/${2}_//g"`
					set_value "${attrName}" "${defvalue}" ${do_edit_probe_num}
				fi
			elif [[ "${attrName}" = "BASE_DIR" ]] && [[ "$CURRENT_SERVICE" = "nsmail" ]]; then
				validate "${attrName}" "${attrval}"
				if [[ $? -ne 0 ]]; then
					continue
				fi
				attrName="`echo ${attrName} | sed 's/BASE_DIR/CONF_FILE/g'`"
				if [[ ! -d ${attrval}/bin/msg ]] && [[ ! -d ${attrval}/bin/mail ]]; then
					printf "`gettext \
'\n\tUnable to find messaging server in %s\n\n'`" "${attrval}"
					attrName="`echo ${attrName} | sed 's/CONF_FILE/BASE_DIR/g'`"
					restart=1
					break
				elif [[ ! -d ${attrval}/msg-${tname} ]] && [[ -d ${attrval}/bin/msg ]];then
					printf "`gettext \
'\n\tUnable to find instance %s in %s\n\n'`" "${tname}" "${attrval}"
					attrName="`echo ${attrName} | sed 's/CONF_FILE/BASE_DIR/g'`"
					restart=1
					break
				fi
				set_value "${attrName}" "${attrval}"
			else
				validate "${attrName}" "${attrval}"
				if [[ $? -ne 0 ]]; then
					continue
				fi
				#echo "${attrName}" = "${attrval}" \; >&6
				set_value "${attrName}" "${attrval}" ${do_edit_probe_num}
			fi
			valueisuniq=true
		done
	done

	DisplayInstance
	msg="`gettext 'Update this instance ? '`"
	isok=`prompt_yesno "${msg}" no `
	if [ "${isok}" = "yes" ]; then
		CONF_CHANGED=1
		delete_instance ${old_instance_name}
		write_instance $3
		gettext "Instance updated in workfile \n"
	else
		gettext "Instance not updated in workfile \n"
	fi

	gettext "Press enter to return to main menu "
	read junk
	return $CONF_CHANGED
}

do_hads_edit()
{
        isServiceOn $3
        onoffstatus=$?
        if [ $onoffstatus -gt 0 ]; then
                warnServiceOn $3
                return
        fi
        clear
 
        gettext "\t\t Edit Instance\n\n"
        ShowAndChooseHadsInstance $4
        inst=$?
        if [ $inst = 0 ]; then
                return 0
        fi
 
        nawk ' BEGIN {target = 0; skip=0;}
              $1=="INSTANCE"        {target++; if( target == INST) skip=1; }
              { if(!skip) print $0; } ' INST=$inst < $4 > ${AWKTMP}_1
 
        nawk ' BEGIN {target = 0; skip=1; seenit=0;}
              $1=="INSTANCE"        {target++; if( target == INST) seenit=1;
	      if( (target > INST ) && seenit ) skip=0;}
              { if(!skip) print $0; } ' INST=$inst < $4 > ${AWKTMP}_2
   	nawk ' BEGIN {target = 0; skip=1;}
              $1=="INSTANCE"        {target++; if( target == INST) skip=0;
           				else skip=1 ; }         
              { if(!skip) print $0; } ' INST=$inst < $4 > ${AWKTMP}_3

        tab_depth=0
        touch ${TMPFILE}
 
        if [ $? -ne 0 ]; then
                cleanup_exit 1 "`gettext 'Unable to create'` ${TMPFILE} "
        fi
 
        exec 5<$1 6>${TMPFILE} || { cleanup_exit 1 "`gettext 'Unable to redirect I/O'`" ; }
        exec 7<${AWKTMP}_3 || { cleanup_exit 1 "`gettext 'Unable to redirect I/O'`" ; }
 
 
        success=false
        moreattributes=yes
        while [ ${moreattributes} = "yes" ]
        do
               read oneline <&5
                if [ $? -ne 0 ]; then
                        if [ ${tab_depth} -ne 0 ]; then
                                err_echo "`gettext 'Unexpected EOF in %s'`" "$1"
                        else
                                success=true
                        fi
                        break
                fi
 
                attrName=` echo "${oneline}" | nawk -F"=| " ' { print $1 } ' | nawk ' {print $1} ' `
                #read attrName foo isqmark maybedefault <&5
                if [ ! "${attrName}"  ]; then
                        continue
                fi
 
                iscomment=` echo "${attrName}" | cut -c1`
                if [ "${iscomment}" = \# ]; then
                        continue
                fi
 
                if [ "$attrName" = "SERVICE" -o "$attrName" = "VERSION" ]; then
                        continue
                fi
                old_attrName=
                while [ ! "$old_attrName" ]
                do
                        read old_oneline <&7
                        echo "${old_oneline}" | nawk -F"=|;" ' { for(i=1;i<NF+1;i++) printf("%s ", $i) } ' > ${TMPFILE2} || { cleanup_exit 1 "`gettext 'Unable to create tmp file'`" ; }
 
                        read old_attrName old_value <${TMPFILE2}
                        iscomment=` echo "${old_attrName}" | cut -c1`
                        if [ "${iscomment}" = \# ]; then
                                old_attrName=
                                continue
                        fi
                done
 
                if [ "$old_attrName" != "$attrName" ]; then
                        err_echo "`gettext 'Mismatch between template and this instance'`"
                        return 1
                fi
                case ${attrName} in
                        "{")
                                        print_tabs ${tab_depth} >&6
                                        echo "{" >&6
                                        tab_depth=`expr ${tab_depth} + 1 `
                                        continue
                                        ;;
                        "}")
                                        tab_depth=`expr ${tab_depth} - 1 `
                                        if [ ${tab_depth} -lt 0 ]; then
		                                err_echo "`gettext \
'Syntax Error in %s'`" "$1"
                                                break
                                        fi
                                        print_tabs ${tab_depth} >&6
                                        echo "}" >&6
                                        continue
                                        ;;
                        "INSTANCE")
                                        print_tabs ${tab_depth} >&6
                                        echo "INSTANCE" >&6
                                        continue
                                        ;;
                        "PRIVATE")
                                        print_tabs ${tab_depth} >&6
                                        echo "PRIVATE" >&6
                                        continue
                                        ;;
                        "PROBE" | "PROBES")
                                        print_tabs ${tab_depth} >&6
                                        echo "${attrName}" >&6
                                        continue
                                        ;;
                        "SERVICE" | "VERSION")
                                        if [ ${tab_depth} -ne 0 ]; then
		                                err_echo "`gettext \
'Syntax Error in %s'`" "$1"
                                                break
                                        fi
                                        if [ "$CONFISNEW" = $no ]; then
                                                continue
                                        fi
                                        ;;
                esac
 
                echo "${oneline}" | nawk -F"=|;" ' { for(i=1;i<NF+1;i++) printf("%s ", $i) } ' > ${TMPFILE2} || { cleanup_exit 1 "`gettext 'Unable to create tmp file'`" ; } 
                read attrName isqmark maybedefault < ${TMPFILE2}
 
                #echo Attr = ${attrName} isqmark = ${isqmark} maybedefault = ${maybedefault}
                if [ "${isqmark}" = "?" ]; then
                                defvalue=${old_value}
                else
                        if [ ! "${isqmark}" ]; then
                                cleanup_exit 1 "`gettext 'Syntax Error in'` $1 "
                        fi
                        defvalue="${isqmark} ${maybedefault}"
                        print_tabs ${tab_depth} >&6
                        echo "${attrName}" = "${defvalue}" \; >&6
                        continue
                fi
                valueisuniq=false
                while [ ${valueisuniq} = "false" ]
                do
                        attrval=`get_multi_input "${attrName} " "${defvalue}" `
                        if [ "${attrName}" = "NAME" ]; then
				if [ "$attrval" != "$defvalue" -a \
				     "${2}_$attrval" != "$defvalue" ]; then
                                        check_dsname $4 "${2}_${attrval}" || { err_echo "`gettext 'Instance %s already exists'`" "${attrval}" ; continue ; }
                                        print_tabs ${tab_depth} >&6
                                        echo "${attrName}" = "${2}_${attrval}" \; >&6
                                else
                                        print_tabs ${tab_depth} >&6
                                        echo "${attrName}" = "${defvalue}" \; >&6
                                fi
                        else
                                print_tabs ${tab_depth} >&6
                                echo "${attrName}" = "${attrval}" \; >&6
                        fi
                        valueisuniq=true
                done
        done
#If possible do a syntax check on the tmp file with the parser
 
        if [ "${success}" = "true" ]; then
                if [ "$CONFISNEW" = "$yes" ]; then
                        echo "" > $PARSEFILE
                else
                        nawk -F"=| " ' $1=="SERVICE" || $1=="VERSION" { print $0 } ' $1 > $PARSEFILE
                fi
                if [ $? -ne 0 ]; then
                        err_echo "`gettext 'Error creating parse file'`"
                        success=false
                fi
        fi
 
 
        if [ "${success}" = "true" ]; then
                if cat $TMPFILE >> $PARSEFILE; then
                #if cat ${AWKTMP}_1 $TMPFILE ${AWKTMP}_2 > $PARSEFILE ; then
                        $PARSER -cv $PARSEFILE > /dev/null
                        if [ $? -ne 0 ]; then
                                err_echo "`gettext 'Error parsing the instance specification'`"
                                #cat $PARSEFILE
                                success=false
                        fi
                else
                        err_echo "`gettext 'Error creating temporary file'`"
                        success=false
                fi
        fi
        if [ "${success}" = "true" ]; then
 
		if [ "$ans" = "no" ];then
                	DisplayInstance ${TMPFILE} $1 1
		else
                	DisplayHadsInstance ${TMPFILE} $1 1
		fi
		msg="`gettext 'Update this instance in configuration '`"
                isok=`prompt_yesno "${msg}" no ` 
	        if [ "${isok}" = "yes" ]; then
                        cat ${AWKTMP}_1 $TMPFILE ${AWKTMP}_2 > $PARSEFILE
                        mv $PARSEFILE $4
                        if [ $? -ne 0 ]; then
                                cleanup_exit 1 "`gettext 'Error updating instance'`"
                        fi
                        CONF_CHANGED=1
                else
                        gettext "Instance not added to configuration \n"
                fi
        fi
 
        rm -f $PARSEFILE > /dev/null 2>&1
        rm -f ${TMPFILE} > /dev/null 2>&1
        gettext "Press enter to return to main menu "
        read junk
        return $CONF_CHANGED
}

function show_all_instances
{
	typeset -u service
	typeset rows

	service=$1
	msg=$2

	check_if_valid
	rows=$(get_all ${service})	

	if [[ -z ${rows} ]]; then
        gettext "There are no configured instances\n"
        gettext "Press enter to return "
        read junk
		return 1
	fi

	gettext "${msg}"
	let i=1
	for r in ${rows}; do
		instance_name=${r%:*:*:*:*}
		instance_name=${instance_name#*:}
		print "\t\t${i}. ${instance_name}\n\n"
		let i=i+1
	done

	print ${rows}
	#return 0
}

do_list()
{
	typeset rows

	CURRENT_SERVICE=$1
    clear
    gettext "\t\t List of configured instances\n\n"
    #rows=$(get_all $1)
    rows=$(read_instance $1 "")

	if [[ -z ${rows} ]]; then
		gettext "There are no configured instances\n"
		gettext "Press enter to return "
		read junk
		return 0
	fi

    let i=1
    for r in ${rows}; do
		instance_name=${r%%:*}
        print "\t\t${i}. ${instance_name}\n\n"
        let i=i+1
    done

    gettext "Press enter to return "
    read junk
    return 0
}


do_hads_list()
{
        l_idx=0

        clear
        gettext "\t\t List of configured instances\n\n"
        NumberOfInstances $1
        if [ $? -eq 0 ]; then
                gettext "There are no configured instances\n"
                gettext "Press enter to return "
                read junk
                return 0
        fi

        ilist=` nawk ' $1=="NAME" { print $3 } ' $1 `
        for inst in $ilist
        do
                l_idx=` expr $l_idx + 1 `
                echo "\t\t$l_idx. $inst\n\n"
        done
        gettext "Press enter to return "
        read junk
        return 0
}


do_quit()
{

	typeset r rows instance_name

	CURRENT_SERVICE=$1
	if [ $CONF_CHANGED -eq 1 ]; then
		gettext "Configuration has changed in workfile \n"
		msg="`gettext 'Update configuration from workfile ? '`"
		response=` prompt_yesno "${msg}" yes `
		if [ "$response" = "no" ]; then
			err_echo "`gettext 'Warning: All changes stored in workfile will be lost'`"
			msg="`gettext 'Please confirm. Update configuration? '`"
			response=` prompt_yesno "${msg}" yes `
			if [ "$response" = "no" ]; then
				err_echo "`gettext 'Abandoning changes'`"
				gettext "Press enter to return "
				read junk
				CONF_CHANGED=0
    			rows=$(read_instance $1 "" yes)
				if [[ -n ${rows} ]]; then
    				for r in ${rows}; do
        				instance_name=${r%%:*}
						purge_instance ${instance_name}
					done
				fi
				de_populate $1
				return 0
			fi
		fi
		isDataServiceHADS 
		if [ $? = 0 ]; then
			write_to_ccd
		else
			write_to_file $1 $2 $3
		fi
		gettext "Press enter to return "
		read junk
	fi
	CONF_CHANGED=0
	return 0
}

do_pkg()
{
#set -x
	clear

	CURRENT_PKG=$1
	tmplfile="/etc/opt/$1/hadsconf.tmpl"
	dsconffile="/etc/opt/$1/hadsconf"
        priv_setup="/opt/$1/bin/privsetup"
        if [ ! -f "${tmplfile}" ]; then
                err_echo "`gettext 'No such file %s'`" "${tmplfile}"
                return 1
        fi

        if [ ! -r "${tmplfile}" ]; then
                err_echo "`gettext 'Could not read instance template'`"
                return 1
        fi

        CONFISNEW=$yes
        if [ -f "${dsconffile}" ]; then
                CONFISNEW=$no
                $PARSER -cv ${dsconffile} > /dev/null 2>&1
                if [ $? -ne 0 ]; then
                        err_echo "`gettext 'The configuration file seems to be corrupted'`"
                        #cat $dsconffile
                        cleanup_exit 1 "`gettext 'Exiting '`"
                fi
                cp $dsconffile $WORKFILE || { err_echo "`gettext 'Cannot copy configuration into tmp file %s'`" "$WORKFILE"; return 1;}
                if [ ! -w "${dsconffile}" ]; then
                        err_echo "`gettext '%s is not writable'`" "${dsconffile}"
                        return 1
                fi
        else
		lmsg="`gettext '# Automatically generated by %s, do not edit'`"
		printf "${lmsg}\n" "${PROG}" > $WORKFILE
                echo "#" >> $WORKFILE
                echo "" >> $WORKFILE
                if [ $? -ne 0 ]; then
                        err_echo "`gettext \
'Fatal error: unable to create %s\n'`" "${WORKFILE}"
                        return 1
                fi
        fi
        
        if [ ! -w "${WORKFILE}" ]; then
                err_echo "`gettext '%s is not writable'`" "${WORKFILE}"
                return 1
        fi

	
	#Print menu and ask user what to do

	populate $2
	
	didpkg=0
	while [ $didpkg -eq 0 ]
	do
		clear
		lmsg="`gettext 'Data Service Configuration Menu for %s\n'`"
		printf "\n\t\t${lmsg}\n\n" "$2"
		gettext "\t\t1. Create a new instance\n\n" 
		gettext "\t\t2. Edit an instance \n\n"
		gettext "\t\t3. Delete an instance \n\n"
		gettext "\t\t4. List instances \n\n"
		gettext "\t\t5. Show instance specifications\n\n"
		gettext "\t\t6. Return to main menu\n\n"
		printf  "\t\t\n\n"
	
		selection=0
		while [ $selection -ne 6 ]
		do
			msg="`gettext 'Select an item from menu'`"
			selection=`get_multi_input "\t${msg} [1-6] " none `
			case $selection in
				1)  
					isDataServiceHADS
					if [ $? = 0 ]; then
						do_create ${tmplfile} $1 $2
					else
						do_hads_create ${tmplfile} $1 $2 ${WORKFILE}
					fi
					break
					;;
				2)  
					isDataServiceHADS
				 	if [ $? = 0 ]; then
						do_edit ${tmplfile} $1 $2
					else
						do_hads_edit ${tmplfile} $1 $2  ${WORKFILE}
					fi
					break
					;;
				3)  
					isDataServiceHADS
				 	if [ $? = 0 ]; then
						do_delete ${tmplfile} $1  $2
					else
						do_hads_delete ${tmplfile} $1  $2 ${WORKFILE}
					fi
					break
					;;
				4) 	
					isDataServiceHADS
				 	if [ $? = 0 ]; then
						do_list $2
					else
						do_hads_list ${WORKFILE}
					fi
					break
					;;
				5) 	
					isDataServiceHADS
				 	if [ $? = 0 ]; then
						do_show $2
					else
						do_hads_show  ${WORKFILE} ${tmplfile}
					fi
					break
					;;
				6) 	do_quit $2 ${WORKFILE} ${dsconffile}
					didpkg=1
					break
					;;
				*) 	err_echo "`gettext 'Invalid choice'`"
					;;
			esac
		done
	done

	rm -f $WORKFILE > /dev/null 2>&1
	return 0
}

print_pkginfo()
{
	echo "$PKGINFOS" | nawk ' $1==name {for(i=2;i<NF+1;i++) printf("%s ", $i) ; print "";} ' name=$1
	echo ""
	return 0
}

#####################################################
#
# set_value key value [probenum]
#
# sets values of keys in the "instance values" table instValueTable
# or the "probe values" table probeValueTable
#
#		key - the key whose value should be set. This should be a
#			  string name which could be found in either the 
#			  "instance keys" table or the "probe keys" table
#		value - the new value to set
#		probenum - This determines the position within a multi-valued key.
#				This argument is valid for a "probe key" only. Multiple
#				values for a single probe key are separated by a space.
#				If this argument is omitted, the passed "value"
#				is appended to the previous value, if present.
#
#####################################################
function set_value
{

typeset -u key
typeset value
typeset i
typeset num

key=$1
value=$2
probe_num=$3

# Locate "key" in "instance keys" table. If found, insert the "value" in
# "instance values" table

let i=0
num=${#instKeyTable[*]}

while (( i < ${num} )); do
if [[ "${key}" = ${instKeyTable[i]} ]]; then
	#print "set_value(): key = ${key}"
	#print "set_value(): instKeyTable[${i}] = ${instKeyTable[i]}"

	# assign the value to the corresponding element in instValueTable
	instValueTable[i]=${value}

	#print_attr_values
	return 0
fi
let i=i+1
done

# if we reach here, it means the "key" was not found in the "instance keys"
# table and so it could be in the "probe keys" table.
# Locate "key" in "probe keys" table. If found, insert the "value" in
# "probe values" table. If there is a "value" already present, append the
# the "new value" to it, with a space in-between

let i=0
num=${#probeKeyTable[*]}

while (( i < ${num} )); do
if [[ "${key}" = ${probeKeyTable[i]} ]]; then
    #print "set_value(): key = ${key}"
    #print "set_value(): probeKeyTable[${i}] = ${probeKeyTable[i]}"

	prev_value=${probeValueTable[i]}
	if [[ -n ${prev_value} ]]; then
		# if the "probe number" was passed, then replace the "value"
		# corresponding to that position
		if [[ -n ${probe_num} ]]; then
			value=$(replace "${prev_value}" ${probe_num} ${value})
    		probeValueTable[i]="${value}"
		else
    	# append the "new value" to "prev_value" with a space in-between
    		probeValueTable[i]="${prev_value} ${value}"
		fi
	else
    	# just insert the "new value"
    	probeValueTable[i]=${value}
	fi

    #print_attr_values
    return 0
fi
let i=i+1
done

return 1
}

function print_attr_names
{

typeset i
typeset num

let i=0
num=${#instKeyTable[*]}

print "num = ${num}"

while (( i < ${num} )); do
    print "instKeyTable[${i}] = ${instKeyTable[i]}"
    let i=i+1
done

}

function print_attr_values
{

typeset i
typeset num

let i=0
num=${#instValueTable[*]}

print "num = ${num}"

while (( i < ${num} )); do
    print "instValueTable[${i}] = ${instValueTable[i]}"
    let i=i+1
done

}
###########################################################
#
# main
#		Validate command line
#		Read the template file
#		Prompt the user for Attribute values (if required)
#		Create the instance block in a temp file. If all goes well
# 		then write this block to the CCD.
###########################################################

if [ $# -ne 0 ]; then
	err_echo "`gettext 'USAGE: %s'`" "${PROG}"
	exit 1
fi

if [ "`id | awk '{print $1}'`" != "uid=0(root)" ]; then
	err_echo "`gettext 'This program must be run as root'`\n"
	exit 1
fi

. ds_utilities

check_if_valid

if [ -f "${LOCKFILE}" ]; then
	err_echo "`gettext '%s has detected another instance of itself running'`" "${PROG}"
	err_echo "`gettext 'Only one instance of this program should be running at a time.'`"
	err_echo "`gettext 'If this is an error, please delete %s manually'`" "${LOCKFILE}"
	err_echo "`gettext 'Then restart this script.'`"
	exit 1
else
	touch ${LOCKFILE}
	if [ $? -ne 0 ]; then
		err_echo "`gettext 'Unable to create lock file %s'`" "${LOCKFILE}"
		exit 1
	fi
fi


# "instance values" table corresponding to the "intance keys" table
set +A instValueTable

# "probe values" table
set +A probeValueTable

# Initialize the instValueTable so that it will have the same number of
# elements as the instKeyTable

let i=0
num=${#instKeyTable[*]}
while (( i < ${num} )); do
    #print "instKeyTable[${i}] = ${instKeyTable[i]}"
	instValueTable[i]=""
	let i=i+1
done

# Initialize the probeValueTable so that it will have the same number of
# elements as the probeKeyTable
 
let i=0  
num=${#probeKeyTable[*]}
while (( i < ${num} )); do
    #print "probeKeyTable[${i}] = ${probeKeyTable[i]}"
    probeValueTable[i]=""
    let i=i+1
done

clear

PKGINFOS=
ALL_PKGS="SUNWschtt SUNWscnew SUNWscnsm SUNWscdns SUNWsclts SUNWsctiv SUNWscsap SUNWscsws SUNWscnsl SUNWscnb SUNWscapc"
HADS_PKGS="SUNWsclts SUNWsctiv SUNWscsap SUNWscsws SUNWscnsl SUNWscnb SUNWscapc"
INSTALLED_PKGS=""

for pkg in $ALL_PKGS
do
	pkginfo -q $pkg > /dev/null 2>&1
	if [ $? -ne 0 ]; then
		continue
	fi
	if [ -f /etc/opt/$pkg/hadsconf.tmpl ]; then
		service=` nawk -F"=|;" ' { for(i=1;i<NF+1;i++) printf("%s ", $i); print "";} ' /etc/opt/$pkg/hadsconf.tmpl | nawk ' $1=="SERVICE" { print $2 } ' `
		if [ -z "$service" ]; then
			continue
		fi
		nfld=` echo "$service" | wc -l `
		if [ "$nfld" -ne 1 ]; then
			continue
		fi
		pre_ds=`get_string "${service}"`
		ds=`gettext "$pre_ds"`
		PKGINFOS="$PKGINFOS$pkg $service - $ds\n"
		INSTALLED_PKGS="$INSTALLED_PKGS $pkg"
	fi
	gettext "." 
done

echo ""
POPULATED_SERVICES=""
didit=0
while [ $didit -eq 0 ]
do
	clear
	m_idx=0
	gettext "\t\t Sun Cluster data service configuration main menu\n\n"
	for pkg in $INSTALLED_PKGS
	do
		m_idx=` expr $m_idx + 1 `
		gettext "\t$m_idx. "
		print_pkginfo $pkg
	done
	m_idx=` expr $m_idx + 1 `
	lmsg="`gettext '\t%s. Quit'`"
	printf "${lmsg}\n\n" "$m_idx"

	choice=0
	while [ 1 ]
	do
		msg="`gettext 'Select an item from menu'`"
		choice=`get_multi_input "\t${msg} [1-$m_idx]" none `
		if [ "$choice" -lt 1 -o "$choice" -gt "$m_idx" ]; then
			err_echo "`gettext 'Invalid choice'`"
			continue
		else
			break
		fi
	done
	if [ "$choice" -eq "$m_idx" ]; then
		didit=1
		continue
	fi
	tmpidx=0
	for tmppack in $INSTALLED_PKGS
	do
		tmpidx=` expr $tmpidx + 1 `
		if [ "$tmpidx" -eq "$choice" ]; then
			service=` echo "$PKGINFOS" | nawk ' $1==name {printf("%s ", $2);} ' name=$tmppack `
			do_pkg $tmppack $service
			break
		fi
	done
done
cleanup_exit 0 ""
##################### End Main Menu ######################

