#!/bin/sh
#
# Copyright 1999 Sun Microsystems, Inc. All Rights Reserved
#
# @(#)ha.sh	1.15 00/02/01 Sun Microsystems, Inc.
#

unset SSADM_ISATTY
SS_BINDIR=/opt/SUNWicg/SunScreen/bin
SS_LIBDIR=/opt/SUNWicg/SunScreen/lib
SS_ADMDIR=/opt/SUNWicg/SunScreen/ssadm
SS_ETCDIR=/etc/opt/SUNWicg/SunScreen
CONFIGS=$SS_ETCDIR/configs
ACTIVE=$SS_ETCDIR/.active
ACTIVE0=$SS_ETCDIR/.active0
read SCREENNAME <$SS_ETCDIR/name

PATH="${SS_LIBDIR}:${SS_ADMDIR}:/usr/bin:/usr/sbin"
export PATH

set_num=31	# SI18N_ADMIN_SCRIPTS
LS()		# localize a string
{
	msg_num=$1; shift
	if [ -x ${SS_LIBDIR}/catgets ]
	then ${SS_LIBDIR}/catgets $set_num $msg_num "$*"
	else echo "$*\c"
	fi
}

set -e


usage()
{
    ustr=`LS 100 "Usage:"`
# LOCO: string of spaces having same length as "Usage:"
    uspc=`LS 101 "      "`
    iMsg=`LS 102 "interface"`
    pMsg=`LS 103 "primaryIPaddress"`
    sMsg=`LS 104 "secondaryIPaddress"`
    echo>&2 "$ustr  ssadm ha status"
    echo>&2 "$uspc  ssadm ha active_mode"
    echo>&2 "$uspc  ssadm ha passive_mode"
    echo>&2 "$uspc  ssadm ha restart"
    echo>&2 "$uspc  ssadm ha init_secondary <$iMsg> <$pMsg>"
    echo>&2 "$uspc  ssadm ha init_primary <$iMsg>>"
    echo>&2 "$uspc  ssadm ha add_secondary <$sMsg>"
    exit 1;
}


network_address_range()
{
    addr=$1
    netmask=$2
    {
	# dc program to compute beginning and ending address of the
	# range described by the local address and netmask.
	# dc registers used:
	# a : local address
	# m : netmask
	# b : beginning of range
	# e : end of range
	echo "[RANGE ]P"
	echo "0 $addr +sa" | sed 's/\./+256*/g'
	echo "16i $netmask sm" | tr '[a-f]' '[A-F]'
	echo "lad 100000000lm-%- sb"
	echo "FFFFFFFFlm- lb+ se"
	echo "lb1000000/p[.]Plb10000/100%p[.]Plb100/100%p[.]Plb100%p"
	echo "[ ]P"
	echo "le1000000/p[.]Ple10000/100%p[.]Ple100/100%p[.]Ple100%p"
    } | dc | tr -d '\012'
}


ether_addr()
{
    ifconfig -a inet | sed -n 's/^	inet *\([0-9.]*\).*/arp \1/p' | sh |
    sed -n 's/.* at \([0-9a-f:]*\) permanent.*/\1/p' | head -1
}


domain=default
domainarg=


init_primary()
{
    read s d p <$ACTIVE/active
    policy=`expr "$p" : '\([^.]*\)'`
    if [ ! -f "$CONFIGS/$domain/$policy" -a -f "$CONFIGS/$domain/Initial" ]
    then policy=Initial
    fi

    if [ -n "$1" ]
    then interface=$1
    else interface=`ssadm -raw edit $domainarg "$policy" -c 'list Interface' |
		    sed -n -e 's/^SCREEN *[^ ][^ ]* *//' \
			   -e 's/"//g' -e 's/ HA .*//p'`
	 if [ -z "${interface}" ]
	 then msg=`LS 110 "Error: There is no HA interface defined."`
	      echo>&2 "ssadm ha: $msg"; exit 1
	 fi
    fi

    screen=`edit $domainarg "$policy" -c "list Screen $SCREENNAME"`
    if [ -z "$screen" ]
    then screen=$SCREENNAME
    fi

    set -- `ifconfig $interface inet | tail +2`
    myIP=$2 netmask=$4
    set -- `ifconfig -a ether | sed -n 's/.*ether //p'` -
    if [ "$1" = - ]
    then msg=`LS 111 "Error: No Ethernet address found in ifconfig -a ether."`
	 echo>&2 "ssadm ha: $msg"; exit 1
    fi
    myETHER=$1

    {
	echo "add Screen $screen HA_PRIMARY HA_IP \"$myIP\" HA_ETHER $myETHER"
	echo "add Address SCREEN $SCREENNAME \"$interface\" `network_address_range $myIP $netmask`"
	echo "add Interface SCREEN $SCREENNAME \"$interface\" HA \"$interface\""
	echo "save"
    } | edit $domainarg "$policy"
    activate $domainarg "$policy"

# LOCO: as in: This machine (dummy) is now ready to be used...
    msg120=`LS 120 "This machine"`
# LOCO: as in: This machine (dummy) is now ready to be used...
    msg121=`LS 121 "is now ready to be used as an HA primary machine."`
    msg122=`LS 122 "To add a secondary machine to the HA cluster, run:"`
    msg123=`LS 123 "\"ssadm ha init_secondary %s\" on the secondary and"`
    msg124=`LS 124 "\"ssadm ha add_secondary <secondaryIP>\" on this machine."`
    echo "$msg120 ($SCREENNAME) $msg121"
    echo "$msg122"
    printf "$msg123\n" "$interface $myIP"
    echo "$msg124"

    exit
}


init_secondary()
{

    OSVERSION=`uname -v`
    if [ $OSVERSION = TS7 ]; then
        $SS_LIBDIR/ss_ts_pset 2>/dev/null
    fi

    interface=$1
    masterIP=$2

    [ -n "$interface" -a -n "$masterIP" ] || usage

    set -- `ifconfig $interface inet | tail +2` || exit
    myIP=$2 netmask=$4

    [ -d $CONFIGS/$domain ] || domain -a $domain
    policy $domainarg -as ha_setup
    {
	echo "add Screen \"$masterIP\" HA_PRIMARY HA_IP \"$masterIP\" HA_ETHER 00:00:00:00:00:00"
	echo "add Screen \"$SCREENNAME\" HA_SECONDARY HA_IP $myIP MASTER \"$masterIP\""
	echo "add Address \"$interface\" `network_address_range $myIP $netmask`"
	echo "add Interface \"$interface\" HA \"$interface\""
	echo "save"
    } | edit $domainarg ha_setup
    activate $domainarg ha_setup

    msg120=`LS 120 "This machine"`
# LOCO: as in: This machine (dummy) is now ready to be used...
    msg130=`LS 130 "is now ready to be used as an HA secondary machine."`
    msg131=`LS 131 "To add this machine to the HA cluster, run:"`
    msg132=`LS 132 "\"ssadm ha add_secondary %s\" on the primary machine."`
    echo "$msg120 ($SCREENNAME) $msg130"
    echo "$msg131"
    printf "$msg132\n" "$myIP"

    exit
}


add_secondary()
{
    read s d p <$ACTIVE/active
    policy=`expr "$p" : '\([^.]*\)'`
    if [ ! -f "$CONFIGS/$domain/$policy" -a -f "$CONFIGS/$domain/Initial" ]
    then policy=Initial
    fi

    slaveIP=$1
    [ -n "$slaveIP" ] || usage

    slaveName=`ssadm -r $slaveIP lib/screenname` || exit

    screen=`edit $domainarg "$policy" -c "list Screen $SCREENNAME" |
	    sed -e 's/HA_PRIMARY *//' \
		-e 's/HA_ETHER *[0-9a-fA-F:]* *//' \
		-e 's/MASTER "[^"]*" *//' \
		-e "s/\"$SCREENNAME\"/\"$slaveName\"/"`
    if [ -z "$screen" ]
    then screen=$slaveName
    fi

    {
	echo "add Screen $screen HA_SECONDARY HA_IP \"$slaveIP\" MASTER $SCREENNAME"
	echo "save"
    } | edit $domainarg "$policy"

# LOCO: as in: The secondary machine (dummy) has been added to the HA cluster.
    msg140=`LS 140 "The secondary machine"`
# LOCO: as in: The secondary machine (dummy) has been added to the HA cluster.
    msg141=`LS 141 "has been added to the HA cluster."`
    msg142=`LS 142 "Activate your policy to activate the secondary machine."`
    echo "$msg140 ($slaveName) $msg141"
    echo "$msg142"

    exit
}


if [ "$1" = status ]
then shift; exec ss_ha_status ${1+"$@"}
fi

if [ ${SSADM_ACCESS_LEVEL:-WRITE} != "WRITE" ]
then msg150=`LS 150 "Access denied"`
     echo>&2 "ssadm ha $1: $msg150"; exit 1
fi

case $1 in
init_secondary)	shift; init_secondary ${1+"$@"};;
init_primary)	shift; init_primary ${1+"$@"};;
add_secondary)	shift; add_secondary ${1+"$@"};;
active_mode)	shift; exec ss_ha_active_mode -Z;;
passive_mode)	shift; exec ss_ha_passive_mode -Z;;
restart)	shift; exec ss_ha_restart -f;;
*) usage;;
esac
