#!/bin/bash

#
#  Copyright Red Hat Inc., 2002
#  Copyright Mission Critical Linux, 2000,2001
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the
#  Free Software Foundation; either version 2, or (at your option) any
#  later version.
#
#  This program is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; see the file COPYING.  If not, write to the
#  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge, 
#  MA 02139, USA.
#

# Author: Richard Rabbat <rabbat@missioncriticallinux.com>
# Description: Cluster member configuration utility
#
# $Id: cluconfig,v 1.22 2003/08/26 15:05:54 lhh Exp $

echo_warning() {
    echo -en "\\033[1;33m"
    echo -n "Warning: "
    echo -en "\\033[0;39m"
}

PROG_NAME=$(basename $0)
BIN_PATH=/sbin

CFG_DIR="/etc"
CFG_FILE="$CFG_DIR/cluster.conf"
PROXY_FILE="$CFG_DIR/xmproxyd.conf"
CLUDB="$BIN_PATH/cludb -f $CFG_FILE -o $CFG_FILE"
CLUDB_SAVE="$BIN_PATH/cludb -f $CFG_FILE"
FINDHOSTNAME="$BIN_PATH/clufindhostname"
DISKUTIL="$BIN_PATH/cludiskutil"

PATH=$PATH:/sbin
CLUSTER_NAME_DEF="Red Hat Cluster Manager"
ALIAS_IP_DEF="NONE"
ALIAS_NETMASK_DEF="255.255.255.0"

SUGGEST_READ_INSTALL="Please refer to installation manual section entitled:"
SUGGEST_READ_RAW="'Setting Up the Quorum Partitions'"

CLUHBD=cluhbd
CLUSVCMGRD=clusvcmgrd
CLUQUORUMD=cluquorumd
CLUPOWERD=clupowerd
CLURMTABD=clurmtabd

goodprimarydevice=false
goodshadowdevice=false

LISTOPTIONS=false
RESET_CLUSTER=false
INIT_CLUSTER=false
CLUSTER_CONFIG_RELEASE=2.0

# indeces, used throughout
declare -i iter=0
declare -i idx=0
declare -i i=0
# array for number of channels
declare -ia channels
# number of cluster nodes (set to minimum)
declare -i nodes=0    # ID's for members are assumed 0,1,...
declare -i pc=0    # ID's for power controllers are 0,1,...
declare -i node_idx=0 # we start with node 0

# daemon functions
getpid()
{
    if [ -f /var/run/${base}.pid ] 
    then
        pid=`head -1 /var/run/${base}.pid`
    fi
    if [ "$pid" = "" ]
    then
        pid=`pidof $1`
    fi
    if [ "$pid" = "" ]
    then
        pid=`ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
                   { if ((prog == $5) || (("(" prog ")") == $5) ||
                     (("[" prog "]") == $5) ||
                   ((prog ":") == $5)) { print $1 ; exit 0 } }' $1`
    fi

    echo $pid
}

daemonstatus()
{
    base=`basename $1`
    pid=`getpid $base`
    
    if [ "$pid" != "" ]
    then
        if ps h $pid >/dev/null 2>&1
        then
            # running
	    return 0
        else
            if [ -f /var/run/${base}.pid ]
            then
                # dead but pid file exists.
                return 1
            else
                # stopped
                return 2
            fi
        fi
    else
        # stopped.
        return 3
    fi
}

# make sure daemons are stopped before going further
check_cluster_stopped () {
    for process in $CLUHBD $CLUSVCMGRD $CLUQUORUMD $CLUPOWERD $CLURMTABD; do
	daemonstatus $process
	if [ $? -eq 0 ]; then
	    echo_warning 
	    echo "Cluster daemon '$process' is running"
	    echo "You should stop the cluster before running $PROG_NAME"
	    echo
	    exit 1
	fi
    done
}

checkfileexecutable() {
    if [ -x $1 ]; then
	return 0
    else
	echo -n "  " && echo_warning
	echo $ERRORMSG
	return 1
    fi
}

reset_cluster() {
    echo "Resetting the cluster reinitializes the quorum partitions and the "
    echo "cluster database, removing all cluster member and service information."
    # ask if the user really wants to reset the cluster
    while true; do
        echo -n "Are you sure you want to reset the cluster? yes/no [yes]: "
	read ANS
	ANS=${ANS:=yes}
	if [ $ANS = yes ] || [ $ANS = y ]; then
	    break
	elif [ $ANS = no ] || [ $ANS = n ]; then
	    echo "No changes have been made."
	    exit 1
	fi
    done

    echo "You must stop the cluster daemons on each cluster member"
    echo "before resetting the cluster. To do this, run the cluster"
    echo "stop command on each system.  For example:"
    echo
    echo "# /etc/rc.d/init.d/cluster stop"
    echo 
    echo "Press the Return key after ensuring that the daemons are"
    echo "stopped on each cluster member."

    read ANS

    # take the following actions:

    # check if quorum partitions are valid
    RESULT=`$DISKUTIL -t 2>/dev/null`
    if  [ $? -ne 0 ]; then
	echo_warning
	echo "Unable to validate partitions. The raw device mappings specified "
	echo "in /etc/sysconfig/rawdevices may be in error. Will not try to "
	echo "run cludiskutil. Fix problem then run $PROG_NAME again"
	exit 1
    fi

    # run cludiskutil to "format" the quorum partitions
    echo -n "Running the cludiskutil -I command to initialize the quorum partitions: "
    res=`$DISKUTIL -I 2>/dev/null`
    if [ $? -ne 0 ]; then
	echo_warning
	echo "Problems encountered while executing $DISKUTIL"
        echo "Make sure that your selected quorum partitions are correct."
        exit 1
    fi

    # move CFG_FILE to CFG_FILE.date
    if [ -f $CFG_FILE ]; then
	date_now=`date +%s`
	echo -n "Moving configuration file: "
	RESULT=`mv -f $CFG_FILE $CFG_FILE.$date_now`
	echo "done"
    else
	echo "Configuration file does not exist. No changes have been made."
	exit 1
    fi

    # remove all STONITH data
    RESULT=`rm -f /usr/share/cluster/stonith/*`

    echo "After resetting all members of the cluster, include the quorum"
    echo "partitions in the rawdevices file, as described in the cluster"
    echo "Installation and Administration manual.  Then, run the $PROG_NAME"
    echo "utility to set up the members."

    exit 0
}

init_cluster() {
    # first move configuration file if it exists
    if [ -f $CFG_FILE ]; then
	date_now=`date +%s`
	RESULT=`mv -f $CFG_FILE $CFG_FILE.$date_now`
    fi

    # Check that the raw device is reachable first
    checkrawdevicefile $INIT_DEVICE

    echo "- Retrieving the database from the quorum partition..."
    # retrieve the database from the quorum partition
    RESULT=`$BIN_PATH/cludb --init=$INIT_DEVICE`
    if [ $? -ne 0 ]; then
	echo $RESULT
	exit 111
    fi
    echo "- Verifying database information..."
}

buildhostnames() {
    i=0
    # build string of all ip addresses reported by /sbin/ifconfig
    iplist=`LANG=C /sbin/ifconfig | awk '/inet/ {print $2}' | awk -F: '{print $2}'`
    for q in $iplist; do
	# unless it's localhost
	if [ $q != '127.0.0.1' ]; then
	    hname[$i]=`$FINDHOSTNAME -i $q`
	    [ $? -eq 0 ] && i=i+1
	fi
    done
    return $i
}

yesno () {
    while true; do
	echo -n "Keep your selection? [yes]: "
	# only allow one of the following answers: y, yes, n, or no
	read ANS
	ANS=${ANS:=yes}
	if [ $ANS = yes ] || [ $ANS = y ] ; then
	    leave=true
	    break
	elif [ $ANS = no ] || [ $ANS = n ] ; then
	    leave=false
	    break
	fi
    done
}

# function that checks whether config file exists, and if so, whether the 
# user would like to update it or do away with it.
pickconfigfile () {
    if $LISTOPTIONS; then
	if [ -f $CFG_FILE ]; then
	    usingconfigfile=true
	else
	    echo_warning
	    echo "Cannot find configuration file. The cluster has not been set up yet."
	    exit 1
	fi
    else
	# set variable to false
	usingconfigfile=false
	if [ -f $CFG_FILE ]; then
	    # sanity check
	    echo "- Configuration file exists already."
	    while true; do
		echo -n "  Would you like to use those prior settings as defaults? (yes/no) [yes]: "
		read ANS
		ANS=${ANS:=yes}
		if [ $ANS = yes ] || [ $ANS = y ] ; then
		    # set variable to true
		    usingconfigfile=true
		    break
		elif [ $ANS = no ] || [ $ANS = n ] ; then
		    date_now=`date +%s`
		    RESULT=`mv -f $CFG_FILE $CFG_FILE.$date_now`
		    break
		fi
	    done
	fi
    fi
}

find_num_nodes () {
    while true; do
	RESULT=`grep member$nodes $CFG_FILE`
	if [ $? != 0 ]; then 
            break
	else
	    nodes=nodes+1
        fi
    done
}

find_num_controllers () {
    while true; do
	RESULT=`grep powercontroller$pc $CFG_FILE`
	if [ $? != 0 ]; then 
            break
	else
	    pc=pc+1
        fi
    done
}

# function for raw devices
checkrawdevicefile() {
    gooddevicechoice=false
    if [ -c $1 ]; then
	# in this case, character device seems to be all clear
	gooddevicechoice=true
	leave=true
    elif [ -f $1 -o -b $1 ]; then
	echo_warning
	echo "$1 is not a character device! Proceed?"
	# prompt to keep or discard
	yesno
	if [ "$leave" == "true" ]; then
	    gooddevicechoice=true
	fi
    elif [ -e $1 ]; then
	echo_warning
	echo "$1 is neither a regular file nor device! Proceed?"
	yesno
    else
	echo_warning
	echo "$1 does not exist! Proceed?"
	yesno
    fi
}

# function that checks that a special character device file exists
checkcharacterdevicefile() {
    gooddevicechoice=false
    if [ -c $1 ]; then
	# remove characters /dev/
	device=`basename $1`

	res=`grep "getty $device" /etc/inittab`
	res2=`echo $res | awk -F# '{print $1}' | grep "getty $device"`

	if [ $? -eq 0 ]; then
	    echo_warning
	    echo "Device $1 exists but getty is running on it in /etc/inittab"
	    # prompt to keep or discard
	    yesno
	else
	    # in this case, character device seems to be all clear
	    gooddevicechoice=true
	    leave=true
	fi
    elif [ -f $1 -o -b $1 ]; then
	echo_warning
	echo "$1 is not a character device! Proceed?"
	# prompt to keep or discard
	yesno
	if [ "$leave" == "true" ]; then
	    gooddevicechoice=true
	fi
    elif [ -e $1 ]; then
	echo_warning
	echo "$1 is neither a regular file nor device! Proceed?"
	yesno
    else
	echo_warning
	echo "$1 does not exist! Proceed?"
	yesno
    fi
}

# function that checks that a certain host exists
checkhost() {
    # if somebody submitted localhost, this is bad
    if [ $1 = 'localhost' ]; then
	echo_warning
	echo "localhost not a valid entry"
	return
    fi

    # on some distributions, /etc/hosts lists the hostname and localhost
    # as 127.0.0.1, this is bad. So check that they do not map.
    
    # if one can't find the entry using gethostbyname, exit function now
    resgethostbyname=`$FINDHOSTNAME -n $1`
    if [ $? -ne 0 ]; then
	echo_warning
	echo "Hostname $1 does not map to any network interface."
	return
    fi

    # read hostname for IP address 127.0.0.1
    resgethostbyaddr=`$FINDHOSTNAME -i 127.0.0.1`
    if [ $resgethostbyname = $resgethostbyaddr ]; then
	echo_warning
	echo "The entry in /etc/hosts for 127.0.0.1 points to both 'localhost' and '$1'.  Please fix before continuing."
	exit 1
    fi

    # if found, then extra check, let's ping it (either my interface
    # or my partner's interface, so I should reach it)
    echo "Looking for host $1 (may take a few seconds)..."
    result=`ping -c 1 $1 2>/dev/null`
    if [ $? -eq 0 ]; then
	# if i_am_member, check if it's one of the interfaces' hostnames
	if [ ${i_am_member[$2]} ]; then
	    # iterate over names in array
	    declare -i i=0
	    present=false

	    while [ $i -lt $hostnames ]; do
		# compare fully qualified name to entries in hostname list
		
		[ ${hname[$i]} = $resgethostbyname ] && present=true
		i=i+1
	    done

	    # if we haven't found it
	    if ! $present; then
		echo -n "Hostname does not map to any interface. "

		# prompt to keep or discard
		yesno
	    else
		# hostname is in list. Success!
		leave=true
	    fi
	else
	    leave=true # just leave
	fi
    elif [ $? -eq 1 ]; then
	# host not responding (may be unplugged or interface down)
	echo_warning
	echo "Host $1 not responding"

	# prompt to keep or discard
	yesno
    else
	# error reported back by ping
	echo_warning
	echo "Host $1 not found"

	# prompt to keep or discard
	yesno
    fi
}

# function to enter information about primary and shadow Quorum partitions
inputquorumpartitions() {
    num=$1
    echo
    echo "Information about Quorum Partitions"
    leave=false
    correct=$INIT_CLUSTER
    while ! $leave; do
	if $correct; then
	    REPLY=${quorumPartitionPrimary[$num]}
	else
	    echo -n "Enter Primary Quorum Partition"
	    [ ${quorumPartitionPrimary[$num]} ] && echo -n " [${quorumPartitionPrimary[$num]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${quorumPartitionPrimary[$num]}}
	fi
	if [ $REPLY ]; then
	    if [ ${i_am_member[$num]} ]; then
		checkrawdevicefile $REPLY
		correct=$leave
		goodprimarydevice=$gooddevicechoice
	    else
		leave=true
	    fi
	fi
    done
    quorumPartitionPrimary[$num]=$REPLY

    leave=false
    correct=$INIT_CLUSTER
    while ! $leave; do
	if $correct; then
	    REPLY=${quorumPartitionShadow[$num]}
        else
	    echo -n "Enter Shadow Quorum Partition"
	    [ ${quorumPartitionShadow[$num]} ] && echo -n " [${quorumPartitionShadow[$num]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${quorumPartitionShadow[$num]}}
	fi
	if [ $REPLY ]; then
	    # make sure primary and shadow are not the same
	    if [ $REPLY != ${quorumPartitionPrimary[$num]} ]; then
		if [ ${i_am_member[$num]} ]; then
		    checkrawdevicefile $REPLY
		    goodshadowdevice=$gooddevicechoice
		    correct=$leave
		else
		    leave=true
		fi
	    else
		echo_warning
	        echo "Primary and Shadow Partitions cannot be the same."
	    fi
	fi

    done
    quorumPartitionShadow[$num]=$REPLY

    echo
    # if defaults, then pick the ones used for member $num to suggest as
    # defaults for member $num +1
    if ! $usingconfigfile; then
	quorumPartitionPrimary[$num+1]=${quorumPartitionPrimary[$num]}
	quorumPartitionShadow[$num+1]=${quorumPartitionShadow[$num]}
    fi
}

# several data fields for the baytech power controller
read_network_controller_info() {
    declare -i count=0
    correct=$INIT_CLUSTER
    leave=false
    while ! $leave; do
	if $correct; then
	    REPLY=${powerSwitchIPaddr[$node_idx]}
	else
	    echo -n "Enter IP address or hostname used to access the power switch"
	    [ ${powerSwitchIPaddr[$node_idx]} ]  && echo -n " [${powerSwitchIPaddr[$node_idx]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${powerSwitchIPaddr[$node_idx]}}
	fi
	# we always ping the port since we're supposed to reach the controller
        checkhost $REPLY 1000 # of course, it's not on any host
	correct=$leave
    done
    powerSwitchIPaddr[$node_idx]=$REPLY
    powercontrollerIPaddr[$node_idx]=$REPLY

    found=false
    while [ $count -lt $node_idx ]; do
	if [ ${powerSwitchIPaddr[$count]} = ${powerSwitchIPaddr[$node_idx]} ]; then
	    found=true
	    break
	fi
	count=count+1
    done

    correct=$INIT_CLUSTER
    if $correct; then
	REPLY=${powerSwitchPortName[$node_idx]}
    else
	while true; do
	    echo -n "Enter the name of the outlet that power cycles member '${name[$node_idx]}'"
	    [ "${powerSwitchPortName[$node_idx]}" ] && [ "${powerSwitchPortName[$node_idx]}" = "unused" ] && powerSwitchPortName[$node_idx]=${name[$node_idx]}
	    [ "${powerSwitchPortName[$node_idx]}" ]  && echo -n " [${powerSwitchPortName[$node_idx]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${powerSwitchPortName[$node_idx]}}
	    [ "$REPLY" ] && break;
	done
    fi
    powerSwitchPortName[$node_idx]=$REPLY

    if $found; then
	echo "Information about power switch ${powerSwitchIPaddr[$node_idx]} already set."
	return
    else 
	pc=pc+1
    fi

    correct=$INIT_CLUSTER
    if $correct; then
	REPLY=${powercontrollerLogin[$num]}
    else
	if [ "${powercontrollerType[$num]}" = "WTI_NPS" ]; then
	    powercontrollerLogin[$num]=unused
	else
	    while true; do
		echo -n "Enter the login name for the power switch"
		[ ${powercontrollerLogin[$num]} ] &&  echo -n " [${powercontrollerLogin[$num]}]"
		echo -n ": "
		read REPLY
		REPLY=${REPLY:=${powercontrollerLogin[$num]}}
		[ $REPLY ] && break;
	    done
	    powercontrollerLogin[$num]=$REPLY
	fi
    fi

    correct=$INIT_CLUSTER
    if $correct; then
	REPLY=${powercontrollerPasswd[$num]}
    else
	while true; do
	    echo -n "Enter the password for the power switch"
	    [ ${powercontrollerPasswd[$num]} ] &&  echo -n " [${powercontrollerPasswd[$num]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${powercontrollerPasswd[$num]}}
	    [ $REPLY ] && break;
	done
	powercontrollerPasswd[$num]=$REPLY
    fi
}

# some data fields required for the operation of the rps10 or apc power switch
read_serial_controller_info() {
    # we just added a power controller
    pc=pc+1
    REPLY=
    correct=$INIT_CLUSTER
    leave=false
    while ! $leave; do
	if $correct; then
	    REPLY=${powercontrollerLogin[$num]}
	else
	    echo -n "Enter the serial port connected to the power switch"
	    [ ${powercontrollerLogin[$num]} ] && echo -n " [${powercontrollerLogin[$num]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${powercontrollerLogin[$num]}}
	fi
        if [ $REPLY ]; then
	    # make sure that this device name has not been used previously
	    j=0
	    duplicate=false
	    while [ $j -lt $iter ]; do
	        if [ "${chan_name[$j + $num*50]}" = "$REPLY" ]; then
		    echo_warning
		    echo "Device name already used for hearbeat channel $j."
		    duplicate=true
		    correct=false
		    break
		fi
	        j=j+1
	    done

	    # check the device file is present if script run on member n
	    if ! $duplicate; then
	        if [ ${i_am_member[$num]} ]; then
		    checkcharacterdevicefile $REPLY
		    correct=$leave
		else
		    leave=true
		fi
	    fi
	fi
    done
    powerSwitchPortName[$node_idx]=${name[$node_idx]}
    powerSwitchIPaddr[$node_idx]=${name[$node_idx]}
    powercontrollerIPaddr[$num]=${name[$num]}
    powercontrollerLogin[$num]=$REPLY
}

# this allows us to allow to enter information for power switches that will be 
# supported in future STONITH drivers 
read_unknown_controller_info() {
    # we just added a power controller
    pc=pc+1

    correct=$INIT_CLUSTER
    if $correct; then
	REPLY=${powerSwitchPortName[$num]}
    else
	while true; do
	    echo -n "Enter power switch parameter 1 controlling ${name[$node_idx]}"
	    [ ${powerSwitchPortName[$num]} ] && echo -n " [${powerSwitchPortName[$num]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${powerSwitchPortName[$num]}}
	    [ $REPLY ] && break;
	done
	powerSwitchPortName[$num]=$REPLY
    fi

    correct=$INIT_CLUSTER
    if $correct; then
	REPLY=${powerSwitchIPaddr[$num]}
    else
	while true; do
	    echo -n "Enter power switch parameter 2"
	    [ ${powerSwitchIPaddr[$num]} ] && echo -n " [${powerSwitchIPaddr[$num]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${powerSwitchIPaddr[$num]}}
	    [ $REPLY ] && break;
	done
	powerSwitchIPaddr[$num]=$REPLY
    fi

    # set the IP address to the same value
    powercontrollerIPaddr[$num]=$REPLY

    correct=$INIT_CLUSTER
    if $correct; then
	REPLY=${powercontrollerLogin[$num]}
    else
	while true; do
	    echo -n "Enter power switch parameter 3"
	    [ ${powercontrollerLogin[$num]} ] && echo -n " [${powercontrollerLogin[$num]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${powercontrollerLogin[$num]}}
	    [ $REPLY ] && break;
	done
	powercontrollerLogin[$num]=$REPLY
    fi

    correct=$INIT_CLUSTER
    if $correct; then
	REPLY=${powercontrollerPasswd[$num]}
    else
	while true; do
	    echo -n "Enter power switch parameter 4"
	    [ ${powercontrollerPasswd[$num]} ] && echo -n " [${powercontrollerPasswd[$num]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${powercontrollerPasswd[$num]}}
	    [ $REPLY ] && break;
	done
	powercontrollerPasswd[$num]=$REPLY
    fi
}

# function to enter information about power switch
inputpswitchinfo() {
    declare -i j
    # set num to original power controller that power cycles member node_idx
    num=${power[$node_idx]}

    echo "Information About the Power Switch That Power Cycles Member '${name[$node_idx]}'"
    correct=$INIT_CLUSTER
    leave=false
    while ! $leave; do
	if $correct; then
	    ANS=${powercontrollerType[$num]}
	else
	    echo "Choose one of the following power switches:"
	    echo "  o NONE"
	    echo "  o RPS10       - WTI RPS10 Series"
	    echo "  o BAYTECH     - Bay Technical Associates RPC-3"
	    #echo "  o SERVERTECH"
	    #echo "  o APCSERIAL"
	    echo "  o APCMASTER   - APC 9211 or 9212"
	    echo "  o APCPLUS     - APC 9212 (rev 2.2.0) or 9225 (rev 2.0.0)"
	    echo "  o WTI_NPS     - WTI NPS Series"
	    echo "  o SW_WATCHDOG"
	    echo -n "Power switch"
	    POWER_TYPE_PROMPT=${powercontrollerType[$num]}
	    if [ ${powercontrollerType[$num]} ]; then
		if [ ${powercontrollerType[$num]} = null ]; then
		    POWER_TYPE_PROMPT=NONE
		fi
		echo -n " [${POWER_TYPE_PROMPT}]"
	    fi
	    echo -n ": "
	    # only allow one of the following answers: RPS10, BAYTECH, APC and NONE
	    read ANS
	    ANS=${ANS:=${POWER_TYPE_PROMPT}}
	fi
	if [ $ANS ]; then
	    if [ $ANS = NONE ] || [ $ANS = none ]; then
		echo "Note: Operating a cluster without a remote power switch does not provide"
		echo "maximum data integrity guarantees."
		leave=true
	    elif [ $ANS = RPS10 ] || [ $ANS = rps10 ] || [ $ANS = BAYTECH ] || [ $ANS = baytech ] || [ $ANS = apcserial ] || [ $ANS = APCSERIAL ] || [ $ANS = apcmaster ] || [ $ANS = APCMASTER ] || [ $ANS = wti_nps ] || [ $ANS = WTI_NPS ] || [ $ANS = sw_watchdog ] || [ $ANS = SW_WATCHDOG ] || [ $ANS = APCPLUS ] || [ $ANS = apcplus ]; then
		leave=true
	    else
		echo "The power switch type '$ANS' is not among the qualified list of switches"
		echo -n "Are you sure you intend to set the switch type to '$ANS'? yes/no [no]: "
		read REPLY
		REPLY=${REPLY:=no}
		if [ $REPLY = yes ] || [ $REPLY = y ]; then
		    leave=true
		fi
	    fi
	    correct=$leave
	fi
    done

    if [ $ANS = NONE ] || [ $ANS = none ]; then
	# populate database entries
	pc=pc+1
	if [ $num -ne $node_idx ]; then
	    # there was one controller for more than one member
	    num=$node_idx
	fi
        powerSwitchIPaddr[$node_idx]=${name[$node_idx]}
	powerSwitchPortName[$node_idx]=unused
        powercontrollerType[$num]=null
        powercontrollerIPaddr[$num]=${name[$node_idx]}
        powercontrollerLogin[$num]=unused
        powercontrollerPasswd[$num]=unused

    elif [ $ANS = RPS10 ] || [ $ANS = rps10 ]; then
	if [ $num -ne $node_idx ]; then
	    # there was one controller for more than one member
	    num=$node_idx
	fi
	powercontrollerType[$num]=RPS10
	powercontrollerPasswd[$num]=10
	read_serial_controller_info
    elif [ $ANS = APCSERIAL ] || [ $ANS = apcserial ]; then
	if [ $num -ne $node_idx ]; then
	    # there was one controller for more than one member
	    num=$node_idx
	fi
	powercontrollerType[$num]=APCSERIAL
	powercontrollerPasswd[$num]=unused
	read_serial_controller_info
    elif [ $ANS = BAYTECH ] || [ $ANS = baytech ]; then
	powercontrollerType[$num]=BAYTECH
	read_network_controller_info
    elif [ $ANS = SERVERTECH ] || [ $ANS = servertech ]; then
	powercontrollerType[$num]=SERVERTECH
	read_network_controller_info
    elif [ $ANS = APCMASTER ] || [ $ANS = apcmaster ]; then
	powercontrollerType[$num]=APCMASTER
	read_network_controller_info
    elif [ $ANS = APCPLUS ] || [ $ANS = apcplus ]; then
	powercontrollerType[$num]=APCPLUS
	read_network_controller_info
    elif [ $ANS = WTI_NPS ] || [ $ANS = wti_nps ]; then
	powercontrollerType[$num]=WTI_NPS
	read_network_controller_info
    elif [ $ANS = SW_WATCHDOG ] || [ $ANS = sw_watchdog ]; then
	# Copied from switch type "none".
	# populate database entries
	pc=pc+1
	if [ $num -ne $node_idx ]; then
	    # there was one controller for more than one member
	    num=$node_idx
	fi
        powerSwitchIPaddr[$node_idx]=${name[$node_idx]}
	powerSwitchPortName[$node_idx]=unused
        powercontrollerType[$num]=sw_watchdog
        powercontrollerIPaddr[$num]=${name[$node_idx]}
        powercontrollerLogin[$num]=unused
        powercontrollerPasswd[$num]=unused
    else
	# this is an unknown switch type
	powercontrollerType[$num]=$ANS
	read_unknown_controller_info
    fi

    # if defaults, then pick the ones used for member $node_idx to suggest as
    # defaults for member $node_idx+1
    if ! $usingconfigfile; then
	# powerSwitchPortName[$node_idx+1]=${powerSwitchPortName[$node_idx]}
	powercontrollerType[$num+1]=${powercontrollerType[$num]}
	[ ${powercontrollerType[$num+1]} = null ] && powercontrollerType[$num+1]=NONE
        powercontrollerLogin[$num+1]=${powercontrollerLogin[$num]}
        powercontrollerPasswd[$num+1]=${powercontrollerPasswd[$num]}
    fi
}

# function to enter channel name
inputchanname() {
    declare -i j
    declare -i mem=$1
    declare -i n=$mem*50

    correct=$INIT_CLUSTER 
    if [ ${chan_type[$iter]} = net ]; then
	chan_call_name[$iter+$n]=name
	# read in hostname at interface[iter]
	leave=false
	while ! $leave; do
	    if $correct; then
		REPLY=${chan_name[$iter+$n]}
	    else
		echo -n "Enter hostname of the cluster member on heartbeat channel $iter"
		[ ${chan_name[$iter+$n]} ] && echo -n " [${chan_name[$iter+$n]}]"
		echo -n ": "
		read REPLY
		REPLY=${REPLY:=${chan_name[$iter+$n]}}
	    fi
	    # we always ping the ports since we're supposed to reach them
	    if [ $REPLY ]; then
                # make sure that this channel name has not been used previously
		j=0
		duplicate=false
                while [ $j -lt $iter ]; do
                    if [ "`$FINDHOSTNAME -n ${chan_name[$j+$n]}`" = "`$FINDHOSTNAME -n $REPLY`" ]; then
			echo_warning
                        echo "Channel name already used for heartbeat channel $j."
			duplicate=true
			correct=false
			break
                    fi
                    j=j+1
                done
		if ! $duplicate; then
		    checkhost $REPLY $mem
		    correct=$leave
		fi
	    fi
	done
    else
	chan_call_name[$iter+$n]=device
	# read in device name at interface[iter]
	leave=false
	while ! $leave; do
	    if $correct; then
		REPLY=${chan_name[$iter+$n]}
	    else
		echo -n "Enter device name"
		[ ${chan_name[$iter+$n]} ] && echo -n " [${chan_name[$iter+$n]}]"
		echo -n ": "
		read REPLY
		REPLY=${REPLY:=${chan_name[$iter+$n]}}
	    fi
	    if [ $REPLY ]; then
                # make sure that this device name has not been used previously
		j=0
		duplicate=false
                while [ $j -lt $iter ]; do
                    if [ "${chan_name[$j+$n]}" = "$REPLY" ]; then
			echo_warning
                        echo "Device name already used for heartbeat channel $j."
			duplicate=true
			correct=false
			break
                    fi
                    j=j+1
                done

		# check the device file is present if script run on member n
		if ! $duplicate; then
		    if [ ${i_am_member[$mem]} ]; then
			checkcharacterdevicefile $REPLY
			correct=$leave
		    else
			leave=true
		    fi
		fi
	    fi
	done

	# so that for the next member, the same default device choice is given
	if ! $usingconfigfile && [ $mem -eq 0 ]; then
	    chan_name[$iter+50]=$REPLY
	fi
    fi

    # set channel name to reply
    chan_name[$iter+$n]=$REPLY
}

# information for each member
input_member_info () {
    echo "--------------------------------"
    echo "Information for Cluster Member $node_idx"
    echo "--------------------------------"

    leave=false
    correct=$INIT_CLUSTER 
    # variable used to decide whether to ask or just display selection
    while ! $leave; do
	allowcheckhost=true
	
	if $correct ; then
	    REPLY=${name[$node_idx]}
	else
	    echo -n "Enter name of cluster member"
	    [ ${name[$node_idx]} ] && echo -n " [${name[$node_idx]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${name[$node_idx]}}
	fi
	if [ $REPLY ]; then
	    i=0
	    while [ $i -lt $node_idx ]; do
		if [ $REPLY = ${name[$i]} ]; then
		    allowcheckhost=false
		    echo_warning
		    echo "Member $i already set to name: $REPLY."
		fi
		i=i+1
	    done
	    if $allowcheckhost; then
		checkhost $REPLY $node_idx
		correct=$leave
	    fi
	fi
    done

    name[$node_idx]=$REPLY
    thishost=`hostname -s`
    if [ "`$FINDHOSTNAME -n ${name[$node_idx]}`" = "`$FINDHOSTNAME -n $thishost`" ]; then
	i=$node_idx+1
	while [ $i -lt $nodes ]; do
	    if [ "`$FINDHOSTNAME -n ${name[$i]}`" = "`$FINDHOSTNAME -n $thishost`" ]; then
		name[$i]=''
	    fi
	    i=$i+1
	done
	i_am_member[$node_idx]=true
	! $usingconfigfile && chan_name[50]=''
    elif ! $usingconfigfile; then
	chan_name[$node_idx*50]=${name[$node_idx]}
    fi

    correct=$INIT_CLUSTER
    echo
    ! $correct && if [ $nodes -ne 2 ] || [ $node_idx -ne 1 ]; then 
	while true; do
	    echo -n "Enter number of heartbeat channels (minimum = 1) [${channels[$node_idx]}]: "
	    read REPLY
	    iter=${REPLY:=${channels[$node_idx]}}
	    [ $iter -gt 0 ] && break
	done

	if [ $iter -lt ${channels[$node_idx]} ]; then
	    channels[$node_idx]=$iter
	    if [ $nodes -eq 2 ]; then
		channels[1]=$iter
	    fi
	else
	    while [ ${channels[$node_idx]} -lt $iter ]; do
		chan_type[${channels[$node_idx]}]='net'
		chan_name[${channels[$node_idx]}+50*$node_idx]=''
		channels[$node_idx]=${channels[$node_idx]}+1
		if [ $nodes -eq 2 ]; then
		    chan_name[${channels[1]}+50]=''
		    channels[1]=${channels[1]}+1
		fi
	    done
	fi
    fi

    # reset index
    iter=0
    while [ $iter -lt ${channels[$node_idx]} ]; do
	correct=$INIT_CLUSTER
	echo "Information about Channel $iter"
	if [ $nodes -ne 2 ]; then
	    REPLY=net
	elif [ $node_idx -eq 1 ]; then
	    REPLY=${chan_type[$iter]}
	else
	    while true; do
		if $correct; then
		    REPLY=${chan_type[$iter]}
		else
		    echo -n "Channel type: net or serial [${chan_type[$iter]}]: "
		    read REPLY
		    REPLY=${REPLY:=${chan_type[$iter]}}
		fi
	        if [ $REPLY ]; then
		    # make sure only net or serial are allowed
		    if [ $REPLY = net ] || [ $REPLY = serial ]; then
		        break
		    else
			correct=false
		    fi
		fi
	    done
	fi

	# in case we switched from serial to net or vice versa then
	# we do not propose the old channel name as a default
	if [ "${chan_type[$iter]}" != "$REPLY" ]; then
	    chan_type[$iter]=$REPLY
	    chan_name[$iter]=''
	    chan_name[$iter+50*$node_idx+50]=''
	fi

	# input channel name
	inputchanname $node_idx
	iter=iter+1
    done

    # input quorum partitions for member
    inputquorumpartitions $node_idx

    # input power switch information
    inputpswitchinfo $node_idx
}

# display all selected information and save if user wants so
display_and_save () {

    echo "Cluster name: $cluster_name"
    if [ "$alias_ip" != "NONE" ] && [ "$alias_ip" != "none" ]; then
        echo "Cluster alias IP address: $alias_ip"
#       echo "Cluster alias netmask: $alias_netmask"
    fi
    echo

    idx=0
    while [ $idx -lt $nodes ]; do
	echo "--------------------"
	echo "Member $idx Information"
	echo "--------------------"

	echo "Name: ${name[$idx]}"
	echo "Primary quorum partition: ${quorumPartitionPrimary[$idx]}"
	echo "Shadow quorum partition: ${quorumPartitionShadow[$idx]}"
	echo "Heartbeat channels: ${channels[$idx]}"
	#reset other index
	iter=0
	while [ $iter -lt ${channels[$idx]} ]; do
	    echo -n "Channel type: ${chan_type[$iter]}, "
	    echo "Name: ${chan_name[$iter+$idx*50]}"
	    iter=iter+1
	done
	echo "Power switch IP address or hostname: ${powerSwitchIPaddr[$idx]}"
	echo "Identifier on power controller for member ${name[$idx]}: ${powerSwitchPortName[$idx]}"
	idx=idx+1
    done
    echo

    idx=0
    while [ $idx -lt $pc ]; do
	echo "--------------------------"
	echo "Power Switch $idx Information"
	echo "--------------------------"
	
	echo "Power switch IP address or hostname: ${powercontrollerIPaddr[$idx]}"
	if [ ${powercontrollerType[$idx]} = null ]; then
	    echo "Type: NONE"
	else
	    echo "Type: ${powercontrollerType[$idx]}"
	fi
	echo "Login or port: ${powercontrollerLogin[$idx]}"
	echo "Password: ${powercontrollerPasswd[$idx]}"
	idx=idx+1
    done
    echo

    if $LISTOPTIONS; then
	# we only list the options and exit gracefully
	exit 0
    fi

    # prompt user to save or discard information/changes
    while true; do
	echo -n "Save the cluster member information? yes/no [yes]: "
	# only allow one of the following answers: y, yes, n, or no
	read REPLY
	REPLY=${REPLY:=yes}
	if [ $REPLY = no ] || [ $REPLY = n ]; then
	    echo "No changes have been made."
	    exit 0
	elif [ $REPLY = yes ] || [ $REPLY = y ]; then
	    break
	fi
    done
    echo -n "Writing to configuration file..."

    # in case the file didn't exist previously
    if [ ! -f $CFG_FILE ]; then 
	echo ' ' >> $CFG_FILE
    fi

    if [ $? -ne 0 ]; then
	echo
	echo "Directory $CFG_DIR not found. Can't save configuration file."
	echo "Make sure you have run the installation properly"
	exit 1
    fi

    $CLUDB -p cluster%name "$cluster_name"
    if [ "$alias_ip" != "NONE" ] && [ "$alias_ip" != "none" ]; then
        $CLUDB -p cluster%alias_ip "$alias_ip"
#       $CLUDB -p cluster%alias_netmask "$alias_netmask"
    else 
	$CLUDB -r cluster%alias_ip
    fi 
    $CLUDB -p database%version $CLUSTER_CONFIG_RELEASE
    # write log levels
    $CLUDB -p clusvcmgrd%logLevel $clusvcmgrd_logLevel
    $CLUDB -p clupowerd%logLevel $clupowerd_logLevel
    $CLUDB -p cluquorumd%logLevel $cluquorumd_logLevel
    $CLUDB -p cluhbd%logLevel $cluhbd_logLevel
    $CLUDB -p clurmtabd%logLevel $clurmtabd_logLevel
    
    #reset index
    iter=0
    while [ $iter -lt $nodes ]; do
	$CLUDB -p members%member$iter%id $iter
	$CLUDB -p members%member$iter%name ${name[$iter]}
	$CLUDB -p members%member$iter%powerSwitchIPaddr ${powerSwitchIPaddr[$iter]}
	$CLUDB -p members%member$iter%powerSwitchPortName "${powerSwitchPortName[$iter]}"
	$CLUDB -p members%member$iter%quorumPartitionPrimary ${quorumPartitionPrimary[$iter]}
	$CLUDB -p members%member$iter%quorumPartitionShadow ${quorumPartitionShadow[$iter]}

	# in case extra default channels existed in configuration file
	$CLUDB -x members%member$iter%chan*
	# new config doesn't include a power switch type in the members section
        $CLUDB -x members%member$iter%powerSwitchType
	# new config doesn't include a power serial port for the switch in 
        # the members section
        $CLUDB -x members%member$iter%powerSerialPort

	# reset other index
	idx=0
	while [ $idx -lt ${channels[$iter]} ]; do
	    $CLUDB -p members%member$iter%chan$idx%type ${chan_type[$idx]}
	    $CLUDB -p members%member$iter%chan$idx%${chan_call_name[$idx]} ${chan_name[$idx+$iter*50]}
	    idx=idx+1
	done
	iter=iter+1
    done

    # in case extra power controllers existed in configuration file
    $CLUDB -x powercontrollers%powercontroller*

    #reset index
    iter=0
    while [ $iter -lt $pc ]; do
	$CLUDB -p powercontrollers%powercontroller$iter%IPaddr ${powercontrollerIPaddr[$iter]}
	$CLUDB -p powercontrollers%powercontroller$iter%login ${powercontrollerLogin[$iter]}
	$CLUDB -p powercontrollers%powercontroller$iter%passwd ${powercontrollerPasswd[$iter]}
	$CLUDB -p powercontrollers%powercontroller$iter%type ${powercontrollerType[$iter]}
	iter=iter+1
    done

    echo "done"
    echo "Configuration information has been saved to $CFG_FILE."
}

# run cludiskutil if user chooses so
run_diskutil () {
    echo "----------------------------"
    echo "Setting up Quorum Partitions"
    echo "----------------------------"
    # if either of quorum devices in error
    if ! $goodprimarydevice && ! $goodshadowdevice; then
	echo_warning
	echo "Cannot run cludiskutil: either or both device names for quorum"
	echo "partitions not properly set.  Fix raw partitions before going further"
	return
    fi

    # check if quorum partitions are valid
    RESULT=`$DISKUTIL -t 2>/dev/null`
    if  [ $? -ne 0 ]; then
	echo_warning
	echo "Unable to validate partitions. The raw device mappings specified "
	echo "in /etc/sysconfig/rawdevices may be in error. Will not try to "
	echo "run cludiskutil. Fix problem then run $PROG_NAME again"
	return
    fi

    echo -n "Running cludiskutil -I to initialize the quorum partitions: "
    res=`$DISKUTIL -I 2>/dev/null`
    if [ $? -ne 0 ]; then
	echo
	echo_warning
	echo "Problems encountered while executing $DISKUTIL"
	echo "  The quorum partitions were not set up yet properly.  Cluster"
	echo "  services can't start.  Please run $PROG_NAME again and make"
	echo "  sure that your selected quorum partitions are correct."
	exit 1
    else
	echo "done"
    fi
}

# save to quorum partition
save_to_quorum () {
    # perform a check on quorum partition. if all systems are go, then
    # save configuration information to quorum partition
    RESULT=`$DISKUTIL -r 2>/dev/null`
    if [ $? -eq 0 ]; then
	echo -n "Saving configuration information to quorum partitions: "
	res=`$CLUDB_SAVE`
	echo "done"
    else
	echo_warning
	echo "Could not verify quorum partitions. Will not attempt to write"
	echo " configuration file. Check quorum partition information."
    fi
}

# read configuration information from file
read_config_file() {
    # first read the number of cluster members saved in config file
    find_num_nodes

    # then read the number of power controllers saved in config file
    find_num_controllers

    i=0
    while [ $i -lt $nodes ]; do
	channels[$i]=0
	i=i+1
    done

    # using old configuration file
    old_config=false

    # Initialize the different variables to values saved in config file
    # If we don't find variable, set it to default
    while [ $iter -lt $nodes ]; do
	name[$iter]=`$CLUDB -g members%member$iter%name`
	[ $? -ne 0 ] && name[$iter]=`hostname -s 2>/dev/null`
	powerSwitchType[$iter]=`$CLUDB -g members%member$iter%powerSwitchType`
	if [ $? -ne 0 ]; then 
	    powerSwitchType[$iter]=NONE
	else
	    old_config=true
	fi
	powerSerialPort[$iter]=`$CLUDB -g members%member$iter%powerSerialPort`
	[ $? -ne 0 ] && powerSerialPort[$iter]=/dev/ttyS0

	# if using old and new configuration file with STONITH support, read 
	# and set more information 
	if $old_config; then
	    # assume 2 power controllers since that was the supported config
	    # in the previous version of the product.
	    pc=2
	    powerSwitchIPaddr[$iter]=${name[$iter]}
	    powerSwitchPortName[$iter]=${name[$iter]}
	    powercontrollerIPaddr[$iter]=${name[$iter]}
	    powercontrollerLogin[$iter]=${powerSerialPort[$iter]}
	    powercontrollerPasswd[$iter]=unused
	    if [ ${powerSwitchType[$iter]} = null ]; then
		powercontrollerType[$iter]=NONE
	    else
		powercontrollerType[$iter]=${powerSwitchType[$iter]}
	    fi
	else
	    powerSwitchIPaddr[$iter]=`$CLUDB -g members%member$iter%powerSwitchIPaddr`
	    [ $? -ne 0 ] && powerSwitchIPaddr[$iter]=${name[$iter]}

	    powerSwitchPortName[$iter]=`$CLUDB -g members%member$iter%powerSwitchPortName`
	    [ $? -ne 0 ] && powerSwitchPortName[$iter]=${name[$iter]}
	fi
	power[$iter]=$iter
	quorumPartitionPrimary[$iter]=`$CLUDB -g members%member$iter%quorumPartitionPrimary`
	[ $? -ne 0 ] && quorumPartitionPrimary[$iter]=/dev/raw/raw1

	quorumPartitionShadow[$iter]=`$CLUDB -g members%member$iter%quorumPartitionShadow`
	[ $? -ne 0 ] && quorumPartitionShadow[$iter]=/dev/raw/raw2

	idx=0
	# read number of channels, channel types and device names for member 0
	while true; do
	    chan_type[$idx]=`$CLUDB -g members%member$iter%chan$idx%type`
	    # if we didn't find another entry, break out of loop
	    [ $? -ne 0 ] && break
	    [ ! ${chan_type[$idx]} ] && break
	    if [ ${chan_type[$idx]} = serial ]; then
		call_name=device
	    elif [ ${chan_type[$idx]} = net ]; then
		call_name=name
	    elif [ "${chan_type[$idx]}" = "" ]; then 
		break
	    else
		echo_warning
		echo "Configuration file is corrupted:"
		echo "Channel name $idx for member $iter is set to ${chan_type[$idx]}."
		exit 112
	    fi
	    # increment number of channels
	    channels[$iter]=${channels[$iter]}+1

	    chan_name[$idx+50*$iter]=`$CLUDB -g members%member$iter%chan$idx%$call_name`
	    idx=idx+1
	done
	iter=iter+1
    done

    # reset indexes
    iter=0
    while [ $iter -lt $pc ] && ! $old_config; do
        # read as many power controller sections as there are pc
	powercontrollerIPaddr[$iter]=`$CLUDB -g powercontrollers%powercontroller$iter%IPaddr`
	[ $? -ne 0 ] && powercontrollerIPaddr[$iter]=${name[$iter]}

	powercontrollerLogin[$iter]=`$CLUDB -g powercontrollers%powercontroller$iter%login`
	[ $? -ne 0 ] && powercontrollerLogin[$iter]=/dev/ttyS0

	powercontrollerPasswd[$iter]=`$CLUDB -g powercontrollers%powercontroller$iter%passwd`
	[ $? -ne 0 ] && powercontrollerPasswd[$iter]=unused

	powercontrollerType[$iter]=`$CLUDB -g powercontrollers%powercontroller$iter%type`
	[ $? -ne 0 ] && powercontrollerType[$iter]=NONE
	if [ ${powercontrollerType[$iter]} = null ]; then
	    powercontrollerType[$iter]=NONE
	fi
	# otherwise, we have set these variables earlier
	iter=iter+1
    done

    iter=0
    idx=0
    # for each cluster member, find corresponding power controller
    while [ $iter -lt $nodes ]; do
	while [ $idx -lt $pc ]; do
	    if [ "${powerSwitchIPaddr[$iter]}" = "${powercontrollerIPaddr[$idx]}" ]; then
		power[$iter]=$idx
		break
	    fi
	    idx=idx+1
	done
	iter=iter+1
    done
    # If we didn't find any, the cluster configuration was corrupted.
    # The user will be presented with wrong information, that the user
    # will fix when making choices.

    # read in log levels. Needed to make sure defaults are saved to 
    # configuration database
    clusvcmgrd_logLevel=`$CLUDB -g clusvcmgrd%logLevel`
    [ $? -ne 0 ] && clusvcmgrd_logLevel=4
    [ ! $clusvcmgrd_logLevel ] && clusvcmgrd_logLevel=4

    clupowerd_logLevel=`$CLUDB -g clupowerd%logLevel`
    [ $? -ne 0 ] && clupowerd_logLevel=4
    [ ! $clupowerd_logLevel ] && clupowerd_logLevel=4

    cluquorumd_logLevel=`$CLUDB -g cluquorumd%logLevel`
    [ $? -ne 0 ] && cluquorumd_logLevel=4
    [ ! $cluquorumd_logLevel ] && cluquorumd_logLevel=4

    cluhbd_logLevel=`$CLUDB -g cluhbd%logLevel`
    [ $? -ne 0 ] && cluhbd_logLevel=4
    [ ! $cluhbd_logLevel ] && cluhbd_logLevel=4

    clurmtabd_logLevel=`$CLUDB -g clurmtabd%logLevel`
    [ $? -ne 0 ] && clurmtabd_logLevel=4
    [ ! $clurmtabd_logLevel ] && clurmtabd_logLevel=4

    cluster_name=`$CLUDB -g cluster%name`
    [ $? -ne 0 ] && cluster_name=$CLUSTER_NAME_DEF

    alias_ip=`$CLUDB -g cluster%alias_ip`
    [ $? -ne 0 ] && alias_ip=$ALIAS_IP_DEF
#   alias_netmask=`$CLUDB -g cluster%alias_netmask`
#   [ $? -ne 0 ] && alias_netmask=$ALIAS_NETMASK_DEF
}

# set default configuration information
set_config_defaults() {
    # Initialize the different variables to default values
    iter=$oldnodes
    while [ $iter -lt $nodes ]; do
	channels[$iter]=1
	chan_name[$iter*50]=`hostname -s 2>/dev/null`
	chan_type[$iter*50]=net # default hb channels over Ethernet
	name[$iter]=`hostname -s`
	power[$iter]=$iter
	powerSwitchPortName[$iter]=${name[$iter]} 
	powerSwitchIPaddr[$iter]=${name[$iter]}
	powercontrollerType[$iter]=NONE
	powercontrollerIPaddr[$iter]=${name[$iter]}
	powercontrollerLogin[$iter]=/dev/ttyS0
	powercontrollerPasswd[$iter]=10
	quorumPartitionPrimary[$iter]=/dev/raw/raw1
	quorumPartitionShadow[$iter]=/dev/raw/raw2
	iter=iter+1
    done

    # default log level for each of daemons
    clusvcmgrd_logLevel=4
    clupowerd_logLevel=4
    cluquorumd_logLevel=4
    cluhbd_logLevel=4
    clurmtabd_logLevel=4
    cluster_name=$CLUSTER_NAME_DEF
    alias_ip=$ALIAS_IP_DEF
#   alias_netmask=$ALIAS_NETMASK_DEF
}

# display help text
help_text() {
    echo "Usage: $PROG_NAME     run utility, perform all operations."
    echo "       $PROG_NAME -l  list configuration information."
    echo "       $PROG_NAME -h  display this help information."
    echo "       $PROG_NAME -r  reinitialize the quorum partitions and"
    echo "                         the cluster database."
    echo
    echo "       $PROG_NAME -i  initialize the cluster configuration file"
    echo "                         from the quorum partition."
    echo
    echo "   -l, --list         saved member configuration information"
    echo "   -h, --help         help"
    echo "   -r, --reset        reset"
    echo "   -i, --init         initialize cluster configuration"
    echo
    echo "  $PROG_NAME initializes the cluster and manages the cluster members."
    echo "  It prompts you for the following information:"
    echo
    echo "    o  Hostname"
    echo "    o  Number of heartbeat channels"
    echo "    o  Information about the type of channels and their names"
    echo "    o  Raw quorum partitions, both primary and shadow"
    echo "    o  Power switch type and device name"
    echo 
    echo "  In addition, it performs checks to make sure that the information entered"
    echo "  is consistent with the hardware, the Ethernet ports, the raw partitions "
    echo "  and the character device files."
    echo "  After the information is entered, it initializes the partitions and saves"
    echo "  the configuration information to the quorum partitions."
    echo
    echo "  The --list option allows you to list saved member configuration information"
    echo
    echo "  The --reset option allows you to reinitialize the quorum partitions and the "
    echo "  cluster database, removing all cluster member and service information"
}

last_words() {
    echo
    echo "----------------------------------------------------------------"
    echo
    echo "Configuration on this member is complete."
    if $INIT_CLUSTER; then
	echo 
	echo "Execute \"/sbin/service cluster start\" to start the cluster software."
	echo
    else
	echo
	echo -n "To configure the next member, invoke the following command on "
	echo "that system:"
	echo
	echo -n "# $BIN_PATH/$PROG_NAME --init="

	if [ ${i_am_member[0]} ]; then
	    echo "${quorumPartitionPrimary[1]}"
	else
	    echo "${quorumPartitionPrimary[0]}"
	fi
	echo
	echo "Refer to the Red Hat Cluster Manager Installation and Administration Guide"
	echo "for details."
    fi
    echo
}

# Start utility calls here

# If CFG_FILE already existed, save that fact
if [ -f $CFG_FILE ]; then
    CFG_FILE_ALREADY_EXISTED=true
else
    CFG_FILE_ALREADY_EXISTED=false
fi

# Find command-line options, interpret and execute them
TEMP=`getopt -o lri:h --long list,reset,init:,help  -- "$@"`

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

eval set -- "$TEMP"
thishost=`hostname -s`
echo
echo "Red Hat Cluster Manager Configuration Utility (running on $thishost)"
echo

while true; do
    case $1 in
	-l|--list)  LISTOPTIONS=true; shift;;
	-r|--reset) RESET_CLUSTER=true; shift;;
	-i|--init)  
	    INIT_DEVICE=$2;
 	    INIT_CLUSTER=true;
	    shift 2;;
	-h|--help)
	    help_text;
	    exit 0;;
	--) shift ; break ;;
    esac
done

if [ $UID != 0 ]; then
    echo "You must be root to use this utility"
    exit
fi

# first make sure the cluster daemons are stopped
! $LISTOPTIONS && check_cluster_stopped

buildhostnames
declare -i hostnames=$?

# reset the cluster to state before running cluconfig or changing rawdevices
if $RESET_CLUSTER; then
    reset_cluster
fi

# init the cluster by retrieving the shared database from the quorum partition
if $INIT_CLUSTER; then
    init_cluster
    usingconfigfile=true
else
    pickconfigfile
fi

if $usingconfigfile ; then
    read_config_file
fi

declare -i oldnodes=$nodes
nodes=2
# reset number of power controllers
pc=0
if ! $usingconfigfile || [ $oldnodes -ne $nodes ] ; then
    set_config_defaults
fi

if $LISTOPTIONS; then
    display_and_save
fi

if ! $INIT_CLUSTER; then
    echo -n "Enter cluster name"
    [ "${cluster_name}" ] && echo -n " [$cluster_name]"
    echo -n ": "
    read REPLY
    cluster_name=${REPLY:=${cluster_name}}

    echo -n "Enter IP address for cluster alias"
    [ "${alias_ip}" ] && echo -n " [$alias_ip]"
    echo -n ": "
    read REPLY
    alias_ip=${REPLY:=${alias_ip}}
#   if [ $alias_ip != NONE ] && [ $alias_ip != none ]; then
#       echo -n "Specify the netmask for the interface"
#       [ "${alias_netmask}" ] && echo -n " [$alias_netmask]"
#       echo -n ": "
#       read REPLY
#       alias_netmask=${REPLY:=${alias_netmask}}
#   fi
fi

# input member information
while [ $node_idx -lt $nodes ]; do
    input_member_info
    node_idx=node_idx+1
    echo
done

# display all options chosen before prompting for saving
if $INIT_CLUSTER; then
    echo -n "Press <Return> to continue. "
    read ANS
fi
display_and_save

# ask to run cludiskutil to setup quorum partitions, if you're setting up on
# first system
! $INIT_CLUSTER && run_diskutil

# perform an integrity check on quorum partitions then save configuration
# file to it
save_to_quorum

# prompt user as to whether they want allow monitoring of the system over HTTP
if $CFG_FILE_ALREADY_EXISTED; then
    if [ -f $PROXY_FILE ]; then
        ### cluconfig was previously run(CFG_FILE_ALREADY_EXISTED is true),
        ### and user chose "yes" to enable monitoring via GUI, so
        ### use "yes" as default value.
        DEFAULT="yes"
    else
        ### cluconfig was previously run(CFG_FILE_ALREADY_EXISTED is true),
        ### and user chose "no" to enable monitoring via GUI, so
        ### use "no" as default value.
        DEFAULT="no"
    fi
else
    ### cluconfig hasn't been run before, so give default of "yes".
    DEFAULT="yes"
fi

while true; do
    echo -n "Do you wish to enable monitoring, both locally and remotely, via the Cluster GUI? yes/no"
    echo -n " [$DEFAULT]"
    echo -n ": "

    # only allow one of the following answers: y, yes, n, or no
    read REPLY
    REPLY=${REPLY:=$DEFAULT}
    if [ $REPLY = no ] || [ $REPLY = n ]; then
	# XXX - Should remove just the cluster line.
	rm -f $PROXY_FILE
	break
    elif [ $REPLY = yes ] || [ $REPLY = y ]; then
	if [ ! -f $PROXY_FILE ]; then 
    	    echo 'localhost cluster 10' >> $PROXY_FILE
	fi
	break
    fi
done

# what still needs to be done, if any
last_words

exit 0
