#!/bin/bash
#
# Copyright (c) 2000 Mission Critical Linux, Inc.
#
# Author: Richard Rabbat <rabbat@missioncriticallinux.com>
# Description: Cluster member configuration utility
#
# $Id: member_config,v 1.36 2000/12/04 18:22:52 rabbat Exp $

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

# code to get to Bash version 2.x
MY_VER=`echo $BASH_VERSION | awk -F. '{print $1}'`

if [ $MY_VER = 1 ] ; then
    if [ -x /bin/bash2 ]; then
	/bin/bash2 --norc $0 ;
	exit
    elif [ -x /usr/bin/bash ]; then
	result=`/usr/bin/bash -version | grep "GNU bash, version 2"`
	if [ $? -eq 0 ]; then
	    /bin/bash --norc $0;
	fi
	exit
    elif [ -x /usr/local/bin/bash ]; then
	result=`/usr/local/bin/bash -version | grep "GNU bash, version 2"`
	if [ $? -eq 0 ]; then
	    /usr/local/bin/bash --norc $0;
	fi
	exit
    else
	echo_warning
	echo "Could not find Bash version 2.x. Exiting"
	exit
    fi
fi

UTIL_NAME=$(basename $0)
UTIL_PATH=$(dirname $0)

CFG_DIR="/etc/opt/cluster"
CFG_FILE="$CFG_DIR/cluster.conf"
CLU_CONFIG="$UTIL_PATH/clu_config"
CLU_CHECK="$UTIL_PATH/clu_check"
CLU_CONFIG_SAVE="$CLU_CONFIG -f $CFG_FILE"
FINDHOSTNAME="$UTIL_PATH/findhostname"
DISKUTIL="$UTIL_PATH/diskutil"
REGISTRATION="$UTIL_PATH/registration"
RELEASE_VERSION="$UTIL_PATH/release_version"

PATH=$PATH:/sbin

HEARTBEAT=hb
SVCMGR=svcmgr
QUORUMD=quorumd
POWERD=powerd

goodprimarydevice=false
goodshadowdevice=false
miss=false

# 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 () {
    allclear=true

    echo -n "- Checking that cluster daemons are stopped: "

    for process in $HEARTBEAT $SVCMGR $QUORUMD $POWERD; do
	daemonstatus $process
	if [ $? -eq 0 ]; then
	    allclear=false
	    echo
	    echo_warning 
	    echo "$process still running. You should stop the cluster before continuing"
	    #prompt user to save or discard changes
	    while true; do
		echo -n "Continue anyway? yes/no [no]: "
		# only allow one of the following answers: y, yes, n, or no
		read REPLY
		REPLY=${REPLY:=no}
		if [ $REPLY = no ] || [ $REPLY = n ]; then
		    exit 1
		elif [ $REPLY = yes ] || [ $REPLY = y ]; then
		    break
		fi
	    done
	fi
    done
    $allclear && echo "done"
}

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

# utility functionality checks. make sure that some files are present
check_cluster_utils () {
    # make sure diskutil in same directory
    ERRORMSG="Cannot run tests without diskutil in directory: $UTIL_PATH"
    checkfileexecutable $DISKUTIL
    [ $? -eq 1 ] && exit 1

    # make sure findhostname in same directory
    ERRORMSG="Cannot run tests without findhostname in directory: $UTIL_PATH"
    checkfileexecutable $FINDHOSTNAME
    [ $? -eq 1 ] && exit 1

    # make sure findhostname in same directory
    ERRORMSG="Missing executable (release_version) in directory: $UTIL_PATH"
    checkfileexecutable $RELEASE_VERSION
    [ $? -eq 1 ] && exit 1

    # more files...
    [ ! -x $REGISTRATION ] && miss=true
    [ ! -x $CLU_CHECK ] && miss=true
}

buildhostnames() {
    # build string of all ip addresses reported by /sbin/ifconfig
    iplist=`/sbin/ifconfig | awk '/inet addr/ {print $2}' | awk -F: '{print $2}'`
    declare -i i=1
    declare -i j=0
    while true; do
	# chop out an IP from the list at specified index
	ip[$i]=`echo $iplist | cut -d\  -f $i`
	# no more, break out
	[ ! ${ip[$i]} ] && break

	# unless it's localhost
	if [ ${ip[$i]} != '127.0.0.1' ]; then
	    hname[$j]=`$FINDHOSTNAME -i ${ip[$i]}`
	    [ $? -eq 0 ] && j=j+1
	fi
	i=i+1
    done

    return $j
}

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 for raw devices
checkrawdevicefile() {
    gooddevicechoice=false
    if [ -c $1 ]; then
	# in this case, character device seems to be all clear
	gooddevicechoice=true
	echo "Raw device $1 found "
	leave=true
     else
	echo_warning
	echo "Device $1 not found"

	# prompt to keep or discard
	yesno
    fi
}

# function that checks that a special character device file exists
checkcharacterdevicefile() {
    gooddevicechoice=false
    if [ -c $1 ]; then
	echo -n "Device $1 found "

	# 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 "but getty 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
	    echo "and no getty running on it"
	    leave=true
	fi
     else
	echo_warning
	echo "Device $1 not found"

	# prompt to keep or discard
	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 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
	echo "Host $1 found"

	# 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
		echo "Hostname corresponds to an interface on member $2"
		# 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 "Setting information about Quorum Partitions"
    leave=false
    while ! $leave; do
	echo -n "Enter Primary Quorum Partition"
	[ ${quorumPartitionPrimary[$num]} ] && echo -n " [${quorumPartitionPrimary[$num]}]"
	echo -n ": "
	read REPLY
	REPLY=${REPLY:=${quorumPartitionPrimary[$num]}}
	if [ $REPLY ]; then
	    if [ ${i_am_member[$num]} ]; then
		checkrawdevicefile $REPLY
		goodprimarydevice=$gooddevicechoice
	    else
		leave=true
	    fi
	fi
    done
    quorumPartitionPrimary[$num]=$REPLY
    echo "Primary Quorum Partition set to ${quorumPartitionPrimary[$num]}"

    leave=false
    while ! $leave; do
	echo -n "Enter Shadow Quorum Partition"
	[ ${quorumPartitionShadow[$num]} ] && echo -n " [${quorumPartitionShadow[$num]}]"
	echo -n ": "
	read REPLY
	REPLY=${REPLY:=${quorumPartitionShadow[$num]}}
	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
		else
		    leave=true
		fi
	    else
		echo_warning
	        echo "Primary and Shadow Partitions cannot be the same."
	    fi
	fi

    done
    quorumPartitionShadow[$num]=$REPLY
    echo "Shadow Quorum Partition set to ${quorumPartitionShadow[$num]}"
    echo

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

# function to enter information about power switch
inputpswitchinfo() {
    num=$1
    echo "Information about power switch connected to member $num"
    leave=false
    while ! $leave; do
	echo -n "Enter serial port for power switch"
	[ ${powerSerialPort[$num]} ] && echo -n " [${powerSerialPort[$num]}]"
	echo -n ": "
	read REPLY
	REPLY=${REPLY:=${powerSerialPort[$num]}}
	if [ $REPLY ]; then
	    # check the device file is present if script run on member n
	    if [ ${i_am_member[$num]} ]; then
		checkcharacterdevicefile $REPLY
	    else
		leave=true
	    fi
	fi
    done
    powerSerialPort[$num]=$REPLY
    echo "Serial port for power switch set to ${powerSerialPort[$num]}"

    while true; do
	echo -n "Specify one of the following switches (RPS10/APC)"
	[ ${powerSwitchType[$num]} ] && echo -n " [${powerSwitchType[$num]}]"
	echo -n ": "
	# only allow one of the following answers: RPS10, APC and NONE
	read ANS
	ANS=${ANS:=${powerSwitchType[$num]}}
	if [ $ANS ]; then
	    if [ $ANS = NONE ]; then
		echo "Note: Operating a cluster without a remote power switch does not provide"
		echo "maximum data integrity guarantees."
		break
	    fi
	    if [ $ANS = RPS10 ] || [ $ANS = rps10 ] || [ $ANS = APC ] || 
	       [ $ANS = apc ] ; then
		break
	    fi
	fi
    done
    powerSwitchType[$num]=$ANS

    echo "Power switch type set to ${powerSwitchType[$num]}"
    echo

    # if defaults, then pick the ones used for member 0 to suggest as
    # defaults for member 1
    if ! $usingconfigfile && [ $num -eq 0 ]; then
	powerSerialPort[1]=${powerSerialPort[0]}
	powerSwitchType[1]=${powerSwitchType[0]}
    fi
}

# function to enter channel name
inputchanname() {
    declare -i mem=$1
    declare -i n=$mem*50
    if [ ${chan_type[$iter]} = net ]; then
	chan_call_name[$iter+$n]=name
	# read in hostname at interface[iter]
	leave=false
	while ! $leave; do
	    echo -n "Enter hostname of cluster member ${name[$mem]} on heartbeat channel $iter"
	    [ ${chan_name[$iter+$n]} ] && echo -n " [${chan_name[$iter+$n]}]"
	    echo -n ": "
	    read REPLY
	    REPLY=${REPLY:=${chan_name[$iter+$n]}}
	    # we always ping the ports, whether we are member 0 or 1,
	    # since we're supposed to reach them
	    if [ $REPLY ]; then
		checkhost $REPLY $mem
	    fi
	done
	echo -n "Channel name set to: "
    else
	chan_call_name[$iter+$n]=device
	# read in device name at interface[iter]
	leave=false
	while ! $leave; do	    
	    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]}}
	    if [ $REPLY ]; then
		# check the device file is present if script run on member n
		if [ ${i_am_member[$mem]} ]; then
		    checkcharacterdevicefile $REPLY
		else
		    leave=true
		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
	    
	echo -n "Device name set to: "
    fi

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

# display all selected information and save if user wants so
display_and_save () {
    echo "------------------------------------"
    echo "The following choices will be saved:"
    echo "------------------------------------"

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

	echo "Name: ${name[$idx]}"
	echo "Primary quorum partition set to ${quorumPartitionPrimary[$idx]}"
	echo "Shadow quorum partition set to ${quorumPartitionShadow[$idx]}"
	echo "Heartbeat channels: $channels"
	#reset other index
	iter=0
	while [ $iter -lt $channels ]; do
	    echo -n "Channel type: ${chan_type[$iter]}. "
	    echo "Name: ${chan_name[$iter+$idx*50]}"
	    iter=iter+1
	done
	echo -n "Power Switch type: ${powerSwitchType[$idx]}. "
	echo "Port: ${powerSerialPort[$idx]}"

	idx=idx+1
    done

    echo "------------------------------------"
    echo
    #prompt user to save or discard changes
    while true; do
	echo -n "Save changes? 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 output 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

    # write cluster name
    if $miss; then
	$CLU_CONFIG -p cluster%name "Kimberlite High Availabity Cluster"
    else
	$CLU_CONFIG -p cluster%name "Convolo High Availabity Cluster"
    fi
    # write log levels
    $CLU_CONFIG -p svcmgr%logLevel $svcmgr_logLevel
    $CLU_CONFIG -p powerd%logLevel $powerd_logLevel
    $CLU_CONFIG -p quorum%logLevel $quorum_logLevel
    $CLU_CONFIG -p heartbeat%logLevel $heartbeat_logLevel
    
    #reset index
    iter=0
    while [ $iter -lt $nodes ]; do
	$CLU_CONFIG -p members%member$iter%id $iter
	$CLU_CONFIG -p members%member$iter%name ${name[$iter]}
	$CLU_CONFIG -p members%member$iter%powerSerialPort ${powerSerialPort[$iter]}
	$CLU_CONFIG -p members%member$iter%powerSwitchType ${powerSwitchType[$iter]}
	$CLU_CONFIG -p members%member$iter%quorumPartitionPrimary ${quorumPartitionPrimary[$iter]}
	$CLU_CONFIG -p members%member$iter%quorumPartitionShadow ${quorumPartitionShadow[$iter]}

	#in case extra default channels existed in configuration file
	$CLU_CONFIG -x members%member$iter%chan*
	#reset other index
	idx=0
	while [ $idx -lt $channels ]; do
	    $CLU_CONFIG -p members%member$iter%chan$idx%type ${chan_type[$idx]}
	    $CLU_CONFIG -p members%member$iter%chan$idx%${chan_call_name[$idx]} ${chan_name[$idx+$iter*50]}
	    idx=idx+1
	done
	iter=iter+1
    done

    echo "done."
    echo "Changes have been saved to $CFG_FILE"
}

# put registration numbers for both members
register_members () {
    iter=0
    while [ $iter -lt $nodes ]; do
	registered=false
	leave=false
	while ! $leave; do
	    echo -n "Enter registration number for member $iter"
	    [ ${license[$iter]} ] && echo -n " [${license[$iter]}]"
	    echo -n ": "
	    read ANS
	    ANS=${ANS:=${license[$iter]}}

	    if [ $ANS ]; then
		# save registration number to configuration file
		RESULT=`$REGISTRATION -m member$iter -f -r $ANS 2>&1`
		if [ $? -eq 0 ]; then
		    registered=true
		    echo $RESULT
		    leave=true
		else
		    echo_warning
		    echo $RESULT
		    yesno
		fi
	    fi
	done
	! $registered && $CLU_CONFIG -p members%member$iter%licenseNumber "unregistered"
	# go to next node
	iter=iter+1
    done
}

# run diskutil if user chooses so
run_diskutil () {
    # if either of quorum devices in error
    if ! $goodprimarydevice && ! $goodshadowdevice; then
	echo_warning
	echo "Cannot run diskutil: either or both device names for quorum"
	echo "partitions not properly set"
	echo "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. rawio information in System V "
	echo "init directory may be in error. Will not try to run diskutil."
	echo "Fix problem then run $UTIL_NAME again"
	return
    fi
    while true; do
	# check if quorum partitions are valid
        RESULT=`$DISKUTIL -r 2>/dev/null`
	if [ $? -ne 0 ]; then
	    echo "Quorum partitions have not been set up yet"
	    echo -n "Run 'diskutil -I' to set up the quorum partitions now? yes/no [yes]: "
	    read ANS
	    ANS=${ANS:=yes}
	else
	    echo "Run diskutil -I to set up the quorum partitions now? "
	    echo "- Select 'yes' to clean up a previous install"
	    echo "- Select 'no' if you have just set them up on other member"
	    echo "  and have not started the cluster services on that member"
	    echo "- Select 'no' if you are running it on other cluster member"
	    echo_warning
	    echo -n "Do not run 'diskutil -I' on a running cluster, because "
	    echo -n "it would have severe consequences. yes/no [no]: "
	    # only allow one of the following answers: y, yes, n, or no
	    read ANS
	    ANS=${ANS:=no}
	fi
	if [ $ANS = yes ] || [ $ANS = y ] ; then
	    res=`$DISKUTIL -I 2>/dev/null`
	    if [ $? -ne 0 ]; then
		echo_warning
		echo "Problems encountered while executing $DISKUTIL"
		echo "Make sure your selected quorum partitions are correct."
		exit 1
	    fi
	    break
	elif [ $ANS = no ] || [ $ANS = n ] ; then
	    RESULT=`$DISKUTIL -r 2>/dev/null`
	    if [ $? -ne 0 ]; then
		echo_warning
		echo "The quorum partitions have not been set up yet."
		echo "Cluster services won't start. Run $UTIL_NAME again"
	    fi
	    break
	fi
    done
}

# 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
	echo -n "Saving configuration information to quorum partitions: "
	res=`$CLU_CONFIG_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
}

# starting script 
echo "------------------------------------"
echo "Cluster Member Configuration Utility"
echo "------------------------------------"

echo `$RELEASE_VERSION`
echo
echo "This utility sets up the member systems of a 2-node cluster."
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"
echo "entered is consistent with the hardware, the Ethernet ports, the raw"
echo "partitions and the character device files."
echo
echo "After the information is entered, it initializes the partitions"
echo "and saves the configuration information to the quorum partitions."
echo

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

# first make sure the cluster daemons are stopped
check_cluster_stopped

#make sure a few needed utilities are there
check_cluster_utils

# make sure the directory for the configuration file is there
if [ ! -d $CFG_DIR ]; then
    echo "Directory $CFG_DIR not found. Can't save configuration file."
    echo "Make sure you have run the installation properly"
    exit 1
fi

# make sure clu_config is there
if [ ! -x $CLU_CONFIG ]; then
    echo -n "clu_config not in same directory as member_config. "
    echo "Please fix the problem before running this utility."
    exit
else
    # at this point we specify both input and output files
    CLU_CONFIG="$CLU_CONFIG -f $CFG_FILE -o $CFG_FILE"
fi

# indeces, used throughout
declare -i iter=0
declare -i idx=0
# minimum number of heartbeat channels
declare -i channels=1
# number of cluster nodes
declare -i nodes=2
# ID's for member 0 and 1 are assumed 0 and 1 respectively

buildhostnames
declare -i hostnames=$?

# 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
	    RESULT=`rm -f $CFG_FILE`
	    break
	fi
    done
fi

echo

if $usingconfigfile ; then
    # 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]=`$CLU_CONFIG -g members%member$iter%name`
	[ $? -ne 0 ] && name[$iter]=`hostname -s 2>/dev/null`
        ! $miss && license[$iter]=`$CLU_CONFIG -g members%member$iter%licenseNumber`
	[ $? -ne 0 ] && license[$iter]="unregistered"
	powerSwitchType[$iter]=`$CLU_CONFIG -g members%member$iter%powerSwitchType`
	[ $? -ne 0 ] && powerSwitchType[$iter]=RPS10
	powerSerialPort[$iter]=`$CLU_CONFIG -g members%member$iter%powerSerialPort`
	[ $? -ne 0 ] && powerSerialPort[$iter]=/dev/ttyS0
	quorumPartitionPrimary[$iter]=`$CLU_CONFIG -g members%member$iter%quorumPartitionPrimary`
	[ $? -ne 0 ] && quorumPartitionPrimary[$iter]=/dev/raw/raw1
	quorumPartitionShadow[$iter]=`$CLU_CONFIG -g members%member$iter%quorumPartitionShadow`
	[ $? -ne 0 ] && quorumPartitionShadow[$iter]=/dev/raw/raw2

	iter=iter+1
    done
    idx=0
    # read number of channels, channel types and device names for member 0
    while true; do
	chan_type[$idx]=`$CLU_CONFIG -g members%member0%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
	else
	    break
	fi
	# increment number of channels
	channels=channels+1

	chan_name[$idx]=`$CLU_CONFIG -g members%member0%chan$idx%$call_name`
	chan_name[$idx+50]=`$CLU_CONFIG -g members%member1%chan$idx%$call_name`
	idx=idx+1
    done
    # counted one extra
    channels=channels-1

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

    powerd_logLevel=`$CLU_CONFIG -g powerd%logLevel`
    [ $? -ne 0 ] && powerd_logLevel=4
    [ ! $powerd_logLevel ] && powerd_logLevel=4

    quorum_logLevel=`$CLU_CONFIG -g quorum%logLevel`
    [ $? -ne 0 ] && quorum_logLevel=4
    [ ! $quorum_logLevel ] && quorum_logLevel=4

    heartbeat_logLevel=`$CLU_CONFIG -g heartbeat%logLevel`
    [ $? -ne 0 ] && heartbeat_logLevel=4
    [ ! $heartbeat_logLevel ] && heartbeat_logLevel=4
else
    echo "Your cluster configuration may include power switches for maximum"
    echo "data integrity."
    while true; do
	echo -n "- Does the cluster configuration include power switches? (yes/no) [yes]: "
	# only allow one of the following answers: y, yes, n, or no
	read ANS
	ANS=${ANS:=yes}
	if [ $ANS = yes ] || [ $ANS = y ] ; then
	    ask_power_switches=true
	    break
	elif [ $ANS = no ] || [ $ANS = n ] ; then
	    ask_power_switches=false
	    break
	fi
    done
    # Initialize the different variables to default values
    chan_type[0]=net # default hb channels over Ethernet
    chan_name[0]=`hostname -s 2>/dev/null`
    chan_name[50]=`hostname -s 2>/dev/null`

    iter=0
    while [ $iter -lt $nodes ]; do
	name[$iter]=`hostname -s`
	! $miss && license[$iter]="unregistered"
	if $ask_power_switches; then
	    powerSwitchType[$iter]=RPS10
	else
	    powerSwitchType[$iter]=NONE
	fi
	powerSerialPort[$iter]=/dev/ttyS0
	quorumPartitionPrimary[$iter]=/dev/raw/raw1
	quorumPartitionShadow[$iter]=/dev/raw/raw2
	iter=iter+1
    done

    # default log level for each of daemons
    svcmgr_logLevel=4
    powerd_logLevel=4
    quorum_logLevel=4
    heartbeat_logLevel=4
fi

# Enter information for cluster member 0
echo "----------------------------------------"
echo "Setting information for cluster member 0"
echo "----------------------------------------"

leave=false
while ! $leave; do
    echo -n "Enter name of cluster member"
    [ ${name[0]} ] && echo -n " [${name[0]}]"
    echo -n ": "
    read REPLY
    REPLY=${REPLY:=${name[0]}}
    if [ $REPLY ]; then
	checkhost $REPLY 0
    fi
done
name[0]=$REPLY
echo "Cluster member name set to: ${name[0]}"

if [ ${name[0]} = $HOSTNAME ] || [ ${name[0]} = `hostname -s` ]; then
    i_am_member[0]=true
    ! $usingconfigfile && chan_name[50]=''
elif ! $usingconfigfile; then
    chan_name[0]=${name[0]}
fi

echo
while true; do
    echo -n "Enter number of heartbeat channels (minimum = 1) [$channels]: "
    read REPLY
    iter=${REPLY:=$channels}
    [ $iter -gt 0 ] && break
done

if [ $iter -lt $channels ]; then
    channels=iter
else
    while [ $channels -lt $iter ]; do
	chan_type[$channels]='net'
	chan_name[$channels]=''
	chan_name[$channels+50]=''
	channels=channels+1
    done
fi

echo -n "You selected $channels channel"
[ $channels -gt 1 ] && echo -n "s"
echo

# reset index
iter=0
while [ $iter -lt $channels ]; do
    echo "Information about channel $iter: "
    while true; do
	echo -n "Channel type: net or serial [${chan_type[$iter]}]: "
	read REPLY
	REPLY=${REPLY:=${chan_type[$iter]}}
	if [ $REPLY ]; then
	    # make sure only net or serial are allowed
	    if [ $REPLY = net ] || [ $REPLY = serial ]; then
		break
	    fi
	fi
    done

    # in case we switched from serial to net or net to serial then
    # we should 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]=''
    fi

    echo "Channel type set to: ${chan_type[$iter]}"

    # input channel name for member 0
    inputchanname 0
    iter=iter+1
done

# input quorum partitions for member 0
inputquorumpartitions 0

# input power switch information for member 0 if power switches are a part
# of the configuration
if $ask_power_switches; then
    inputpswitchinfo 0
fi

# Enter information for cluster member 1
echo "----------------------------------------"
echo "Setting information for cluster member 1"
echo "----------------------------------------"

if [ ${name[1]} ]; then
    if [ ${name[0]} = $HOSTNAME ] || [ ${name[0]} = `hostname -s` ]; then
	if [ ${name[1]} = $HOSTNAME ] || [ ${name[1]} = `hostname -s` ]; then
	    name[1]=''
	fi
    fi
fi

leave=false
while ! $leave; do
    echo -n "Enter name of cluster member"
    [ ${name[1]} ] && echo -n " [${name[1]}]"
    echo -n ": "
    read REPLY
    REPLY=${REPLY:=${name[1]}}
    # make sure that member names are not the same
    if [ $REPLY ]; then
	if [ $REPLY != ${name[0]} ]; then
	    checkhost $REPLY 1
	else
	    echo_warning
	    echo "Members 0 and 1 cannot be the same"
	fi
    fi
done
name[1]=$REPLY
echo "Cluster member name set to: ${name[1]}"

if [ ${name[1]} = $HOSTNAME ] || [ ${name[1]} = `hostname -s` ]; then
    i_am_member[1]=true
fi

#reset index
iter=0

# Enforce the number of channels selected for member 0
echo
echo -n "You previously selected $channels channel"
[ $channels -gt 1 ] && echo -n "s"
echo

while [ $iter -lt $channels ]; do
    echo "Information about channel $iter: "
    # Enforce the respective type of channels selected for member 0
    echo "Channel type selected as ${chan_type[$iter]}"

    # input channel name for member 1
    inputchanname 1
    iter=iter+1
done

# input quorum partitions for member 1
inputquorumpartitions 1

# input power switch information for member 1 if power switches are a part
# of the configuration
if $ask_power_switches; then
    inputpswitchinfo 1
fi

# display all options chosen before prompting for saving
display_and_save

if ! $miss ; then
    # registration process
    echo "----------------------------"
    echo "Cluster Member Registration:"
    echo "----------------------------"
    register_members
fi

echo "----------------------------"
echo "Setting up Quorum Partitions"
echo "----------------------------"
# ask then run diskutil to setup quorum partitions
run_diskutil

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

echo
echo "----------------------------------------------------------------"
echo "Setup on this member is complete.  If errors have been reported,"
echo "correct them."
if ! $miss; then
    echo "Then invoke the following command to check the configuration:"
    echo
    echo "# $CLU_CHECK -c"
fi

echo
echo "If you have not already set up the other cluster member, before"
echo "running member_config, invoke the following command on the"
echo "other cluster member:"
echo
echo -n "# $UTIL_PATH/clu_config --init="
if [ ${i_am_member[0]} ]; then
    echo "${quorumPartitionPrimary[1]}"
else
    echo "${quorumPartitionPrimary[0]}"
fi
echo
if ! $miss; then
    echo "After running member_config on the other member system, be sure to"
    echo "check the configuration with clu_check -c.  You can then start the"
else
    echo "After running member_config on the other member, you can start the"
fi
echo "cluster daemons on each cluster member by invoking the cluster start"
echo "script located in the System V init directory.  For example:"
echo 
echo "# /etc/rc.d/init.d/cluster start"
echo
if ! $miss; then
    echo "After starting the daemons, invoke clu_check with no command options"
    echo "on both member systems to check the running cluster configuration."
fi

exit 0
