#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1997,2007 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
##########################################################################
#                                                                        #
#    Licensed Materials - Property of IBM                                #
#                                                                        #
#    5765-529 PSSP                                                       #
#                                                                        #
#    (C) Copyright IBM Corporation 1996  All Rights Reserved.            #
#                                                                        #
#    US Government Users Restricted Rights - Use, duplication or         #
#    disclosure restricted by GSA ADP Schedule Contract with IBM Corp.   #
#                                                                        #
##########################################################################

# "@(#)58   1.17   src/rsct/pts/pam/config/topsvcsctrl.sh, topology.services, rsct_relgh, relghs001a 5/8/06 15:34:10"

# hatsctrl - Script to manage the Topology Services Daemon as an
#              SRC subsystem.

#########################################################################
#                                                                       #
# Function: get_locale_env                                              #
# Description: set variable LOCALE_ENV according to the locale 		#
#	environment variables.						#
#									#
#########################################################################

get_locale_env() {
    LOCALE_ENV=""
    if [ -n "$LANG" ]
    then
	LOCALE_ENV="$LOCALE_ENV LANG=$LANG"
    fi
    if [ -n "$LC_COLLATE" ]
    then
	LOCALE_ENV="$LOCALE_ENV LC_COLLATE=$LC_COLLATE"
    fi
    if [ -n "$LC_CTYPE" ]
    then
	LOCALE_ENV="$LOCALE_ENV LC_CTYPE=$LC_CTYPE"
    fi
    if [ -n "$LC_MONETARY" ]
    then
	LOCALE_ENV="$LOCALE_ENV LC_MONETARY=$LC_MONETARY"
    fi
    if [ -n "$LC_NUMERIC" ]
    then
	LOCALE_ENV="$LOCALE_ENV LC_NUMERIC=$LC_NUMERIC"
    fi
    if [ -n "$LC_TIME" ]
    then
	LOCALE_ENV="$LOCALE_ENV LC_TIME=$LC_TIME"
    fi
    if [ -n "$LC_MESSAGES" ]
    then
	LOCALE_ENV="$LOCALE_ENV LC_MESSAGES=$LC_MESSAGES"
    fi
    if [ -n "$LC_ALL" ]
    then
	LOCALE_ENV="$LOCALE_ENV LC_ALL=$LC_ALL"
    fi
    # `echo $LOCALE_ENV` (with no '"' surrounding $LOCALE_ENV) prints the
    # contents of $LOCALE_ENV one by one with one space between items.
    # Leading and trailing blanks are deleted.
    LOCALE_ENV=`echo $LOCALE_ENV`
}

#########################################################################
#									#
# Function: is_english_locale                                           #
# Description: Check if the current locale is English. Special locale   #
#     POSIX and C are considered English.				#
# Return code:								#
#	0 : current locale is not an English locale			#
#	1 : current locale is an English locale				#
#									#
#########################################################################

is_english_locale() {
    # Check if current locale is a English
    LOCALE="C"
    if [ -n "${LANG}" ]
    then
	LOCALE=${LANG}
    fi
    if [ -n "${LC_MESSAGES}" ]
    then
	LOCALE=${LC_MESSAGES}
    fi
    if [ -n "${LC_ALL}" ]
    then
	LOCALE=${LC_ALL}
    fi
    # Do not print English messages if the local language is English.
    # C and POSIX are special locales. Treat them as en_US.
    if [[ "$LOCALE" = "C" || "$LOCALE" = "POSIX" ]]
    then
	return 1
    else
	# A locale may look like en_US or en_US.ISO8859-1. Use cut command
	# to remove the territory and language encoding. Use tr command to
	# translate the language name to upper case.
	LOCALE=`echo "$LOCALE" | cut -f 1 -d "_" | tr '[:lower:]' '[:upper:]'`
	if [[ "$LOCALE" = "EN" ]]
	then
	    # Local language is English.
	    return 1
	else
	    # Local language is not English (including "$LOCALE"="",
	    # which should not happen in normal cases)
	    return 0
	fi
    fi
}

#########################################################################
#                                                                       #
# Function: print_message                                               #
# Description: wrapper for message printing. All messages go to stderr. #
#     For now, all messages are printed in both English and the current #
#     language unless current language is en_US, C, or POSIX.           #
#                                                                       #
#     This subroutine makes it easy to print messages in  either English#
#     or current language or both. Also, it ensure all messages will be #
#     printed to the same stream.                                       #
#########################################################################

print_message() {
    print -u2 "`${MSGCMD} $*`"
    if [[ $PRINT_ENG_MSG = "YES" ]]
    then
        print -u2 "`LC_ALL=en_US ${MSGCMD} $*`"
    fi
}

#########################################################################
#                                                                       #
# topsvcsctrl.sh main program starts here.                              #
#                                                                       #
#########################################################################

OSname=$(/bin/uname -s)

case "$OSname" in
  "AIX")
    export PATH=/usr/bin:/usr/sbin:/usr/lpp/ssp/bin:/usr/lpp/ssp/install/bin
    ;;
  "Linux")
    export PATH=/usr/bin:/usr/sbin:/bin
    ;;
  *)
    print_message EMSG678 $(basename $0) ${OSname} ${OSname}
    exit 1
    ;;
esac

export MSGMAPPATH="/usr/sbin/rsct/msgmaps"

DFLT_SCRIPT=topsvcsctrl
DFLT_DAEMON=hatsd
SS_PATH=/usr/sbin/rsct/bin	# path to subsystem daemon
CLSTR_PATH=/usr/sbin/cluster    # path to cluster directory
SCRIPT=$(basename $0)
SUBSYS=${SCRIPT%%ctrl}		# name of subsystem group
SUBSYSNAME=$SUBSYS		# name of subsystem on a node

# Determine the daemon name from script name.
# If the script name is XXtopsvcsctrl, then the daemon name is XXhatsd. e.g if
# the script name is "ltopsvcsctrl", then the daemon to be used is "lhatsd".
# If the script name in not XXtopsvcsctrl, then we don't play this trick and
# use the default daemon name "hatsd". This is used for developer's testing.
# In real world, Topology Services is started by HACMP and the name is
# "topsvcsctrl" all the time.

if [[ "${SCRIPT##*${DFLT_SCRIPT}}" = "" ]]
then
    PROG=${SCRIPT%${DFLT_SCRIPT}}$DFLT_DAEMON
else
    PROG=$DFLT_DAEMON		# name of subsystem daemon
fi
DFLT_LOG_DIR=/var/ha/log
DFLT_LCK_DIR=/var/ha/lck
DFLT_RUN_DIR=/var/ha/run
DFLT_SOC_DIR=/var/ha/soc
DFLT_LOG=/var/ha/log/${SUBSYS}.	# name of default daemon log; partition
				# name is appended to it

CATFILE=${PROG%d}.cat           # message catalog file name
MSGCMD="/usr/sbin/rsct/bin/hadspmsg script ${CATFILE}"

# mainline code

# Set variable LOCALE_ENV to pass the values of current locale environment
# variables for startsrc command.
get_locale_env
# Check if the current locale is English.
is_english_locale
if [[ $? -eq 0 ]]
then
    PRINT_ENG_MSG="YES"
else
    PRINT_ENG_MSG="NO"
fi

# Parse command line

Syspar_name=
Code_level=
Tracelist=
Argcount=0
USAGE="\
$0 -a | -s | -r | -m | -k | -d | -c | -z | -t | -o | -h | -e | -?
-a      add topology/group services
-d      delete topology services
-k      stop topology services
-c      clean topology services(delete from all partitions)
-z      clean up topology services for de-installation
-r      refresh topology services configuration
-m      refresh topology services configuration (migration refresh)
-s      start topology services
-t      turn on tracing for topology services
-o      turn off tracing for topology services
-e      start topology services with the Dead Man Switch enabled
-h|?    this help message"
while getopts ":armskdcztoeh?" opt
do
  case $opt in
    a )	Op=add;      Argcount=$((Argcount + 1));;
    s ) Op=start;    Argcount=$((Argcount + 1));;
    r ) Op=refresh;  Argcount=$((Argcount + 1));;
    m ) Op=migrationrefresh;  Argcount=$((Argcount + 1));;
    k ) Op=stop;     Argcount=$((Argcount + 1));;
    d )	Op=delete;   Argcount=$((Argcount + 1));;
    c ) Op=clean;    Argcount=$((Argcount + 1));;
    z ) Op=deinstall;	Argcount=$((Argcount + 1));;
    e ) Op=startWithDeadManSwitch;    Argcount=$((Argcount + 1));;
    t )	Op=traceon;  Tracelist="$OPTARG"; Argcount=$((Argcount + 1));;
    o )	Op=traceoff; Tracelist="$OPTARG"; Argcount=$((Argcount + 1));;
    h | ? ) #echo "$USAGE"
	    print_message I_TopsvcsctrlUsage ${SCRIPT}
	    exit 0;;
  esac
done

# Check for valid flags and/or arguments

if ((Argcount == 0))
then
    #echo "missing command flag"
    print_message EMSG634 ${SCRIPT}
    # Print out usage message when users have problems with usage.
    print_message I_TopsvcsctrlUsage ${SCRIPT}
    exit 1
fi

if ((Argcount > 1))
then
    #echo "only one command flag permitted"
    print_message EMSG635 ${SCRIPT}
    # Print out usage message when users have problems with usage.
    print_message I_TopsvcsctrlUsage ${SCRIPT}
    exit 1
fi

# set service name for adding port to /etc/services
SERVICENAME=${SUBSYS}

case $Op in

# Add the subsystem to the SRC 

  add ) # Ensure subsystem is stopped if it is already in SRC
      
        # 83457: if INUCLIENTS is set then don't run lssrc to avoid having
        # to wait too long. (the subsystem should not be up anyway)
        # Note on parsing the output of lssrc: trickier than it seems:
        #  1) Error messages issued by lssrc are sent to the standard output
        #     rather than to the standard error
        #  2) In an "lssrc -s" command, the first line of the output is
        #     produced by the SRC master daemon, rather than lssrc. So doing
        #     LC_ALL=C only takes effect on the 2nd line of the output, but
        #     not on the first.
        # The awk statement below skips the 1st line of the output and looks
        # for "active" as the 4th field of the 2nd line.
        if [[ -z "$INUCLIENTS" ]]
        then
            LSSRC=$(LC_ALL=C lssrc -s "$SUBSYSNAME")
            RC=$?
            STATUS=$(echo "$LSSRC" | awk '(FNR != 1) && ($4 ~ /^active$/)' )
            if [[ ($RC = 0) && (-n "$STATUS") ]]
                then

                #echo "The $SUBSYSNAME subsystem must be stopped before remaking it."
	        print_message EMSG636 ${SCRIPT} ${SUBSYS}
                exit 1
            fi
        fi

        SRC_args=

	if [[ ! -x $SS_PATH/$PROG ]]
	then
	    #echo "$SS_PATH/$PROG is not executable"
	    print_message EMSG640 ${SCRIPT} $SS_PATH $PROG
	    exit 1
	fi

        if [[ ! -x $SS_PATH/$SUBSYS ]]
        then
            #echo "$SS_PATH/$SUBSYS is not executable"
	    print_message EMSG640 ${SCRIPT} $SS_PATH $SUBSYS
            exit 1
        fi

	rmssys -s $SUBSYSNAME >/dev/null   # ensure subsystem is out of SRC

	mkssys -s $SUBSYSNAME $SRC_args -p $SS_PATH/$SUBSYS -u 0 \
			-o ${DFLT_LOG}default -e ${DFLT_LOG}default \
			-O -Q -K -d -w 30 -G $SUBSYS
	if [[ $? -ne 0 ]]
	then
	    #echo "could not add $SUBSYSNAME subsystem to SRC"
	    print_message EMSG641 ${SCRIPT} $SUBSYSNAME
	    exit 1
	fi

        # set an SRC notification object: when the daemon 
        # exits abnormally the script topsvcs_down_script is invoked
        # to disable the DMS and thus allow logs to be saved to disk.
        # NOTE: this only works because the SRC is NOT set to restart the
        # subsystem. That is, the mkssys command above must not specify
        # the -R flag.

        case "$OSname" in
          "AIX")
            mknotify -m $SS_PATH/topsvcs_down_script -n $SUBSYSNAME
            ;;
          "Linux")
            ;;
          *)
            print_message EMSG678 $(basename $0) ${OSname} ${OSname}
            ;;
        esac

        ;;

# start the subsystem

  start )  
         startsrc -e "$LOCALE_ENV" -s $SUBSYSNAME
         exit $?
         
         ;;

  startWithDeadManSwitch )
         startsrc -a "-DMS_enable" -e "$LOCALE_ENV" -s $SUBSYSNAME
         exit $?

         ;;

# stop the subsystem

  stop )

         # defect 64745 - removed the check to see if daemon is active
         #                before killing it. We just need to kill it.


         stopsrc -cs $SUBSYSNAME  2> /dev/null
         ;;


# refresh the configuration

  refresh )
#            print "Updating Machines.lst file"
            ${SS_PATH}/$SUBSYS refresh
            exit $?

            ;;

  migrationrefresh )
            ${SS_PATH}/$SUBSYS migration_refresh
            exit $?

            ;;

  
# Delete the subsystem from the SRC. We do not remove the associated port
# number from the SDR, since it may still be needed by this subsystem on
# other nodes. Likewise, we do not remove the port number from /etc/services

delete )
         # Ensure subsystem is stopped 

         LSSRC=$(LC_ALL=C lssrc -s "$SUBSYSNAME")
         RC=$?
         STATUS=$(echo "$LSSRC" | awk '(FNR != 1) && ($4 ~ /^active$/)' )
         if [[ ($RC = 0) && (-n "$STATUS") ]]
         then
	    #echo "The $SUBSYSNAME subsystem must be stopped before removing it."
	    print_message EMSG636 ${SCRIPT} $SUBSYSNAME
	    exit 1
         fi

         rmssys -s $SUBSYSNAME >/dev/null	# take subsystem out of SRC

         ;;

# Unconfigure all elements of the subsystem in all partitions. However, DO NOT
# remove anything from the SDR. This function is used in preparation to
# restoring the subsystem to a known state - said state defined by the contents
# of the SDR.

  clean )
          # ensure all subsystem daemons are stopped

          stopsrc -g $SUBSYS >/dev/null

          # remove all SRC entries

          LC_ALL=C lssrc -g  $SUBSYS | sed 1d |
          while read ssname junk
          do
            rmssys -s $ssname >/dev/null # take subsystem out of SRC
          done

          ;;

# This flag is used in unpost_i.sh to clean up all stuff created at
# run-time before de-install the Topology Services subsystem.

  deinstall )
	# Stop Topology Services daemon 
	TIMEOUT=60
	PROCLIST=""
	LC_ALL=C lssrc -g ${SUBSYS} 2> /dev/null | grep "active" |
	while read junk junk PID1 junk
	do
	    PROCLIST=${PROCLIST},${PID1}
	done
	if [ -n "${PROCLIST}" ]
	then
	    PROCLIST=${PROCLIST#,}
	    stopsrc -c -g ${SUBSYS} > /dev/null
	    (( i = ${TIMEOUT} ))
	    while (( $i > 0 ))
	    do
		/bin/ps -p ${PROCLIST} > /dev/null
		if [[ $? -ne 0 ]]
		then
		    break
		else
		    sleep 1
		    (( i = $i - 1 ))
		fi
	    done
	    /bin/ps -p ${PROCLIST} > /dev/null
	    if [[ $? -eq 0 ]]
	    then
		#print -u2 Warning: ${SUBSYS} is not fully stopped in ${TIMEOUT} seconds.
		print_message I_TopsvcsctrlDaemonNotStop ${SUBSYS} ${TIMEOUT}
	    fi
	fi
	
	# Remove SRC entries
	LC_ALL=en_US lssrc -g ${SUBSYS} | sed 1d |
	while read ssname junk
	do
	    rmssys -s ${ssname} > /dev/null	# take subsystem out of SRC
	done
   
	# Remove /etc/services entry
	# HACMP creates /etc/services entries at installation time in
	# cluster.es.server.utils.post_i.sh and removes the entries in
	# cluster.es.server.utils.unpost_i.sh.

	# Remove /etc/inittab entry
	# HACMP doesn't have a /etc/inittab entry for Topology Services

	# Remove ODM entries.
	  
	# Remove log/lck/run/soc files
	# /var/ha/log is specified in rsct.basic.rte.il and should be 
	# removed by RSCT de-install.
	if [ -n "${HB_LOGDIR}" ]
	then
	    rm -f ${HB_LOGDIR}/${SUBSYS}.*    2> /dev/null
	else
	    rm -f ${DFLT_LOG_DIR}/${SUBSYS}.* 2> /dev/null
	fi

	# Subdirectory run/${SUBSYS}.* needs to be removed also.
	# /var/ha/run is specified in rsct.basic.rte.il and should be 
	# removed by RSCT de-install. However, /var/ha/run/${SUBSYS}.<part>
	# are not. They should be removed here.
	if [ -n "${HB_RUNDIR}" ]
	then
	    rm -rf ${HB_RUNDIR} 2> /dev/null
	else
	    rm -rf ${DFLT_RUN_DIR}/${SUBSYS}.* 2> /dev/null
	fi

	# Subdirectory soc/${SUBSYS}.* needs to be removed also.
	# /var/ha/soc is specified in rsct.basic.rte.il and should be 
	# removed by RSCT de-install. 
	if [ -n "${HB_SERVER_SOCKET}" ]
	then
	    rm -f ${HB_SERVER_SOCKET}.*      2> /dev/null
	else
	    rm -rf ${DFLT_SOC_DIR}/${SUBSYS} 2> /dev/null
	fi

	;;

  traceon)


           # turn on all tracing in daemon for the system partition
           traceson -s $SUBSYSNAME
           exit $?

           ;;

  traceoff)
            # turn off all tracing in daemon for the system partition
            tracesoff -s $SUBSYSNAME
            exit $?

            ;;
esac

exit 0
