#! /bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1996,2019 
# 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 
#*===========================================================================*/
#* CPRY PGM
#* 
#*  Licensed Materials - Property of IBM
#*  
#*  5765-529 PSSP
#*  
#*  (C) Copyright IBM Corp. 1996 All Rights Reserved.
#* 
#*  US Government Users Restricted Rights - Use, duplication or disclosure
#*  restricted by GSA ADP Schedule Contract with IBM Corp.
#* 
#* CPRY
#*===========================================================================*/
#*                                                                           */
#* Module Name:  hagsctrl                                                    */
#*                                                                           */
#* Description:                                                              */
#*      Script to manage the Group Services Daemon as an SRC subsystem.      */
#*                                                                           */
#*      This file is formatted with tabstops of 4.                           */
#*===========================================================================*/

# sccsid = "@(#)21   1.56   src/rsct/pgs/cmds/aix/hagsctrl.sh, gsctrl, rsct_rady, rady2035a 11/16/15 15:05:19"

#Fix for Defect 181688
unalias -a

#########################################################################
# Currently, we inherit the locale according to the locale
# environment variables passed in the HATS script.
# However, we may need to set it to SP-admin locale if
# SP-admin locale becomes required.
# startsrc needs to pass environment variables explicitly. Make an
# environment variable list to pass locale information.
# 
# Create LOCALE_ENV that has all neccessary locale information
#
#########################################################################

function make_full_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
}


#########################################################################
# Get the current Locale and determine whether English output is also needed
# Output: LOCALE
#	  PRINT_ENG_MSG
#########################################################################
function get_current_locale
{
   # Check if current locale is a English
   LOCALE=`/usr/bin/locale`
   # /usr/bin/locale may produce LC_MESSAGES=en_US or LC_MESSAGES="en_US".
   # We use two sed "s" commands, the first one gets rid of LC_MESSAGES=,
   # the second one removes the two surrounding '"' if they are there.
   LOCALE=`echo "$LOCALE" | grep LC_MESSAGES | sed "s/LC_MESSAGES=//;s/\"//g"`

   # 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
	PRINT_ENG_MSG="NO"
   else
	# A locale may look like en_US or en_US.ISO8859-1. Use cut command
	# to remove the language encoding.
	LOCALE=`echo "$LOCALE" | cut -f 1 -d "."`
	if [[ "$LOCALE" = "en_US" || "$LOCALE" = "En_US" || "$LOCALE" = "en_GB" || "$LOCALE" = "En_GB" ]]
	then
		# Local language is English.
		PRINT_ENG_MSG="NO"
	else
		# Local language is not English (including "$LOCALE"=""),
		# which should not happen in normal cases)
		PRINT_ENG_MSG="YES"
	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.                                       #
#########################################################################

function print_message
{
    MSGCMD="/opt/rsct/bin/hadspmsg hagsctrl ha_gs.cat"
    print -u2 "`${MSGCMD} $*`"

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

#########################################################################
#									#
# Function: PSSP_running						#
# Description: Check if PSSP is running correctly.			#
# This script heavily depends on PSSP. We need a good way to find out if#
# PSSP is correctly installed and running correctly.			#
# Currently, we have no official way to do the task. Since SDR is an	#
# important component of PSSP, we assume PSSP is running if SDR is	#
# running. There is a PSSP command SDR_test that test if SDR runs.	#
# However, SDR_test requires root privilege. We make this a function so	#
# that we can change it easily when a better way is found.		#
# Return code:								#
#       0 : PSSP is running correctly					#
#       1 : PSSP is not running correctly				#
#									#
#########################################################################

PSSP_running() {
    # Check if SDR is working.
    if (( `/usr/lpp/ssp/bin/SDRGetObjects -x Syspar 2> /dev/null | wc -l` != 0 ))
    then
       	return 0
    else
       	return 1
    fi
}

#########################################################################
# Main starts here
# Get common shell functions, e.g. updservices. We will use updservices until
# a more robust method of updating /etc/services is available.
#########################################################################

SS_PATH=/opt/rsct/bin      # path to subsystem daemon

DOMAIN_TYPE=PSSP                # used to support the SP realm

MYNAME=`basename $0`            # name invoked by
SUBSYS=${MYNAME%%ctrl}          # name of subsystem group
if [ "hags" != ${SUBSYS} ]      # allow us to easily set up test domains
then
  DOMAIN_TYPE=TEST
fi

TRACEFILEPREFIX=trace

SUBSYSNAME=$SUBSYS              # name of subsystem on a node
PROG=${SUBSYS}d                 # name of subsystem daemon

DFLT_LOG_DIR=/var/ha/log
DFLT_LCK_DIR=/var/ha/lck
DFLT_RUN_DIR=/var/ha/run
DFLT_SOC_DIR=/var/ha/soc

# name of default daemon log; partition name is appended to it
#DFLT_LOG=${PGSD_LOGDIR:-/var/ha/log}/${SUBSYS}.default.
DFLT_LOG=${PGSD_LOGDIR:-/var/ha/log}/${TRACEFILEPREFIX}.default.
                                

SUBSYS2=${SUBSYS}glsm           # name of subsystem group for global AM
SUBSYSNAME2=$SUBSYS2            # name of subsystem on a node
PROG2=${SUBSYS2}d               # name of subsystem daemon
                                # name is appended to it
                                # name of default daemon log; partition
DFLT_LOG2=${SW_GROUPIE_LOGDIR:-/var/ha/log}/${SUBSYS2}.default.

CMD=$(basename $0)
SPMSG=${SS_PATH}/hadspmsg
MSGMAPPATH=/opt/rsct/msgmaps
export MSGMAPPATH

                                # Set path to known value
PATH=/opt/rsct/bin:/opt/rsct/install/bin:/usr/lpp/ssp/bin:/usr/lpp/ssp/install/bin:/usr/bin:/usr/sbin
export PATH

#
# setup the proper locale environment
make_full_locale_env

# find the current working locale
get_current_locale


# Define a range of possible port numbers for this daemon to use
STARTING_PORT_NUMBER=10000
HIGHEST_PORT_NUMBER=10100

#
#######################################################
function rnotify
{
#######################################################
# Use /usr/lpp/ssp/bin/hagsdown_note when hags is abnomally terminated.
# Register hags handling routine
export ODMDIR=/etc/objrepos
if [[ `/usr/lpp/ssp/install/bin/node_number` -ne 0 ]]
 then
 if [ -z "`/usr/bin/odmget -q notifyname=hags SRCnotify 2>/dev/null`" ]
  then
  /usr/bin/mknotify -n hags -m "/opt/rsct/bin/hagsdown_note"
 fi
fi
#######################################################
}

function get_security_mode
{
  # The "lsauthpts -c" command will return a list of colon delimited
  authpts=`/usr/lpp/ssp/bin/lsauthpts -c`
  if [[ $? -ne 0 ]]; then
     authpts="" # just in case
  fi
}



#######################################################
# Get dce credentials - dsrvtgt checks for dce before obtaining creds.
# Use ssp/spbgroot pricipal for write access to SDR. 
function get_dce_creds_for_sdr
{
   if [[ ! -e /usr/lpp/ssp/bin/dsrvtgt ]]; then
        # 56941 - File not exist. Assume no security
	print -u2 "/usr/lpp/ssp/bin/dsrvtgt not exist. Assume no security";
        return 1
   fi

   get_security_mode
   if [[ $authpts = *dce* ]]; then
	old_krb5=$KRB5CCNAME
	KRB5CCNAME=$(/usr/lpp/ssp/bin/dsrvtgt ssp/spbgroot)
	rc=$?
	if [[ $rc -ne 0 || $KRB5CCNAME = "" ]]; then
		#$SPMSG hagsctrl ha_gs.cat EMsg_Cannot_get_dce_creds $CMD
		print_message EMsg_Cannot_get_dce_creds $CMD
		exit 1;
	fi
	dce_cred_detected=1
	export KRB5CCNAME
   fi
   return 0
}

# Remove any DCE credentials file we may have obtained.
# Return KRB5CCNAME to original value.
function remove_dce_creds_for_sdr
{
   if [[ ! -z $dce_cred_detected ]]; then
	/bin/kdestroy >/dev/null 2>&1
	KRB5CCNAME=$old_krb5
	export KRB5CCNAME
   fi
}

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

# The following function selects a port number to be placed into /etc/services
# for this daemon. Once the port number is selected, it is placed into
# /etc/services using a Port Management Command (PMC). If the PMC fails with
# an indication that the port number is already in use, then another port
# number is selected and the PMC is again invoked. This procedure is repeated
# until a port number can be successfully placed into /etc/services or until
# this function runs out of port numbers to try. If a selected port can be
# placed into /etc/services then it is also placed into the SDR class 
# specified by the function arguments.
#
# However, if a port number is passed to this function, then attempt to add
# it to /etc/services (but do not update the SDR). If the attempt fails do not
# select another port number.
#
# The caller of this function can determine the port number selected for the
# specified service by examining the set_port_number variable.  This function
# does not "typeset" the set_port_number variable, so assignments made to
# the variable in this function can be seen by the caller.
#
# Input:   $1   SDR Class
#          $2   1st attribute name/value pair to pass to SDR
#          $3   service name
#          $4   protocol (tcp or udp)
#          $5   port number (optional). If specified $1 and $2 not used
#
# Return Status:  0  service entered into /etc/services and, optionally, into
#                    the SDR
#                 1  error
#                 2  Specified or selected port(s) already in /etc/services
#                 3  Specified service name already in /etc/services
#                52  Cannot add object to SDR
#

function set_port_number {

                                # define variables local to this function
	typeset class_name
	typeset class_attr1
	typeset service_name
	typeset service_proto
	typeset port_number
	typeset	start_port
	typeset	Used_ports      # sorted array of port numbers in the SDR
	typeset up_cnt          # count of port numbers in the SDR
	typeset up_ndx          # index into Used_ports array

	class_name=$1
	class_attr1=$2
	service_name=$3
	service_proto=$4
	port_number=$5          # this argument is optional

	set_port_number=        # No port number has been selected yet.

	if [[ -z $class_name || -z $class_attr1 || -z $service_name \
			|| -z $service_proto ]]
	then
		return 1
	fi

	if [[ -n $port_number ]]
	then
		updservices -s $service_name -p $port_number -t $service_proto
		rc=$?
		if [[ $rc -eq 0 ]]
		then
                  # return the port number selected
                  set_port_number=$port_number
		fi
		return $rc
	fi

        # Get ports currently used by this and similar subsystems in all
        # partitions.  Get the information from the SDR, and sort it 
        # numerically.

	set -A Used_ports											\
        $(														\
        (													\
        SDRGetObjects -x -G Syspar_ports port;			\
        SDRGetObjects -x    SP_ports     port			\
        ) 2>/dev/null |										\
        sort -un 2>/dev/null								\
		)

	up_cnt=${#Used_ports[@]}				# get number of ports in use
	up_ndx=0

        #
        # Look for a port number that is not used in /etc/services or the SDR.
        #

	start_port=$STARTING_PORT_NUMBER

	while (( start_port <= HIGHEST_PORT_NUMBER ))
	do

          # If port number registered in SDR, try the next one.

		while ((up_ndx < up_cnt)) && ((Used_ports[up_ndx] < start_port))
		do
			((up_ndx += 1))
		done

		if ((up_ndx < up_cnt)) && ((Used_ports[up_ndx] == start_port))
		then
			((start_port += 1))
			continue
		fi

                # Port number not in SDR.  Try to put it in /etc/services and SDR.

		updservices -s $service_name -p $start_port -t $service_proto
		rc=$?
                # if put into /etc/services
		if (( rc == 0)) 
		then
			# get DCE creds
			get_dce_creds_for_sdr

			SDRCreateObjects $class_name $class_attr1 port=$start_port
                        # if can't add object to SDR
			if (( $? != 0 ))
			then
				$SPMSG hagsctrl ha_gs.cat EMsg_Cannot_create_object \
					$CMD $class_name "${class_attr1},port=$start_port"
				remservices -s $service_name -t $service_proto
				if (( $? != 0 ))
				then
					$SPMSG hagsctrl ha_gs.cat \
						EMsg_Cannot_Remove_Service_Entry \
						$CMD $service_name /etc/services
				fi

				# remove DCE creds
				remove_dce_creds_for_sdr
				return 52
			fi
                        # return the port number selected
			set_port_number=$start_port 

			# remove DCE creds
			remove_dce_creds_for_sdr
			return 0
		fi

                # if error other than "port in use"
		if (( rc != 2 )) 
		then
			return $rc
		fi

		((start_port += 1))
	done

	return 2
}

# mainline code

# Parse command line
Domain_name=
Code_level=
Tracelist=
Argcount=0
while getopts ":askdczutorhgb" opt
do
	case $opt in
		a )	Op=add;      Argcount=$((Argcount + 1));;
		s )	Op=start;    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));;
		u )	Op=unconfig; Argcount=$((Argcount + 1));;
		t )	Op=traceon;  Tracelist="all"; Argcount=$((Argcount + 1));;
		o )	Op=traceoff; Tracelist="all"; Argcount=$((Argcount + 1));;
                r )	Op=refresh;  Argcount=$((Argcount + 1));;
                g )	Op=migrdone;  Argcount=$((Argcount + 1));;
                b )	Op=migrbegin;  Argcount=$((Argcount + 1));;
		h )	$SPMSG hagsctrl ha_gs.cat IMsg_hagsctrl_Usage $CMD
			# IMsg_hagsctrl_Usage needs to add "-z" for 51488
				 exit 0;;
		? )	$SPMSG hagsctrl ha_gs.cat IMsg_hagsctrl_Usage $CMD
				 exit 1;;
	esac
done

# Check for PSSP existence for add, delete, clean, unconig, deinstall.
# start, stop, refresh, traceon, traceoff, migrdone, migrbegin do not need PSSP.
if [[ ${Op} = add || ${Op} = delete || ${Op} = clean || ${Op} = unconfig || ${Op} = deinstall ]] 
then
    # Get common shell functions, e.g. updservices. We will use updservices until
    # a more robust method of updating /etc/services is available.

    . /usr/lpp/ssp/install/bin/ssp_functions
    PSSP_running
    if [[ $? -ne 0 ]]
    then
	# print -u2 "SDR(SDRGetObjects -x Syspar) is not running correctly."
        #print_message EMsg_SDR_Not_Healthy $CMD
        print_message EMsg_Cannot_Determine_Syspar_Name $CMD
	exit 1
    fi
fi

# get name of system partition we are in
long_Domain_name=$(spget_syspar -n)
if [[ -z $long_Domain_name ]]
then
	$SPMSG hagsctrl ha_gs.cat EMsg_Cannot_Determine_Syspar_Name $CMD
	exit 1
fi

# Make host name short host name
# strip off . and all that follows
Domain_name=${long_Domain_name%%.*} 

# Get the number of the node we are on

Node_number=$(node_number)
if [[ -z $Node_number ]]
then
	$SPMSG hagsctrl ha_gs.cat EMsg_Cannot_Determine_Node_Number $CMD
	exit 1
fi

# Check for valid flags and/or arguments

if ((Argcount == 0))
then
	$SPMSG hagsctrl ha_gs.cat IMsg_hagsctrl_Usage $CMD
	exit 1
fi

if ((Argcount > 1))
then
	$SPMSG hagsctrl ha_gs.cat IMsg_hagsctrl_Usage $CMD
	exit 1
fi

if [[ $Node_number -eq 0 ]]
then
  # append syspar name on CWS
  SUBSYSNAME=${SUBSYS}.${Domain_name%%.*}
  # append syspar name on CWS
  SUBSYSNAME2=${SUBSYS2}.${Domain_name%%.*}
fi

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

case $Op in

  # Add the subsystem to the SRC 

add )
      # Ensure subsystem is stopped if it is already in SRC

	LC_ALL=C lssrc -s "$SUBSYSNAME" | LC_ALL=C /usr/bin/sed 1d | LC_ALL=C read r1 r2 r3 r4
	if [[ -n $r4 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Subsystem_Must_Be_Stopped \
				$CMD $SUBSYSNAME
		exit 1
	fi
	LC_ALL=C lssrc -s "$SUBSYSNAME2" | LC_ALL=C /usr/bin/sed 1d | LC_ALL=C read r1 r2 r3 r4
	if [[ -n $r4 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Subsystem_Must_Be_Stopped \
				$CMD $SUBSYSNAME2
		exit 1
	fi

        # Get the port number to be used by the daemon for PRM communication from
        # the SDR and ensure it is set in /etc/services. If there is no port number
        # in the SDR, and this is the CWS, it will be added to the SDR. If
        # this is a node and no port number is in the SDR, then exit with an error.

	SDRGetObjects -x Syspar_ports subsystem==$SUBSYS port \
				2> /dev/null | read Port_number junk

        # if no port number
	if [[ -z $Port_number ]]
	then
          # if not CWS
          if [[ $Node_number -ne 0 ]]
          then
            $SPMSG hagsctrl ha_gs.cat EMsg_Port_Number_Not_Found \
            $CMD $SUBSYSNAME
            exit 1
          fi
	fi

        # Remove any existing /etc/services entries for this service.

	remservices -s $SERVICENAME -t udp
	if [[ $? -ne 0 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Cannot_Remove_Service_Entry \
			$CMD $SERVICENAME /etc/services
		exit 1
	fi

        # if $Port_number is the NULL string, set_port_number will pick a
        # new port number and update the SDR, as well as /etc/services

	set_port_number Syspar_ports subsystem=$SUBSYS \
							$SERVICENAME udp $Port_number
	rc=$?
	if (( $rc != 0 ))
	then
          # if SDR error, message already displayed
		if (( $rc == 52 ))
		then
			exit 1
		fi
		if [[ -z $Port_number ]]
		then
			Port_number=NOPORT
		fi
		$SPMSG hagsctrl ha_gs.cat EMsg_Cannot_Register_Service_Name \
			$CMD $SERVICENAME udp $Port_number
		exit 1
	fi
        # get port number selected
	Port_picked=$set_port_number

	if [[ ! -x $SS_PATH/$PROG ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Not_Executable $CMD $SS_PATH/$PROG
		exit 1
	fi
	if [[ ! -x $SS_PATH/$PROG2 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Not_Executable $CMD $SS_PATH/$PROG2
		exit 1
	fi
	if [[ ! -x $SS_PATH/$SUBSYS ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Not_Executable $CMD $SS_PATH/$SUBSYS
		exit 1
	fi
	if [[ ! -x $SS_PATH/$SUBSYS2 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Not_Executable $CMD $SS_PATH/$SUBSYS2
		exit 1
	fi

        # ensure subsystems are out of SRC
	rmssys -s $SUBSYSNAME >/dev/null
	rmssys -s $SUBSYSNAME2 >/dev/null

	DFLT_LOG=${DFLT_LOG}$Domain_name

	mkssys -s $SUBSYSNAME -a "$DOMAIN_TYPE -p $Domain_name -d $DFLT_LOG" \
		-p $SS_PATH/$SUBSYS -u 0 -o ${DFLT_LOG} -e ${DFLT_LOG} \
		-R -Q -K -d -w 30 -G $SUBSYS
	if [[ $? -ne 0 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Could_Not_Add $CMD $SUBSYSNAME SRC
		exit 1
	fi

	DFLT_LOG2=${DFLT_LOG2}$Domain_name

	mkssys -s $SUBSYSNAME2 -a "$DOMAIN_TYPE -p $Domain_name -d $DFLT_LOG2" \
		-p $SS_PATH/$SUBSYS2 -u 0 -o ${DFLT_LOG2} -e ${DFLT_LOG2} \
		-R -Q -K -d -w 30 -G $SUBSYS
	if [[ $? -ne 0 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Could_Not_Add $CMD $SUBSYSNAME2 SRC
		exit 1
	fi

        # Add an entry to the inittab file for this subsystem, if it is not
        # already there. The new entry will be put at the end of /etc/inittab
        # However, do not add the entry if this is a HACWS
        
        # Assume adding entry to /etc/inittab
	noitab=0                
	if [[ $Node_number -eq 0 ]]
	then
		noitab=$(lshacws)
	fi

	if (( noitab == 0 ))
	then
		lsitab $SUBSYS > /dev/null 2>&1
                # if entry not there
		if (( $? != 0 ))
		then
			mkitab \
			"$SUBSYS:2:once:/usr/bin/startsrc -g $SUBSYS > /dev/console 2>&1" \
				> /dev/null 2>&1
			if (( $? != 0))
			then
				$SPMSG hagsctrl ha_gs.cat EMsg_Could_Not_Add $CMD \
							$SUBSYSNAME inittab
				exit 1
			fi
		fi
	fi

        #
        # All the necessary steps have been taken to add the subsystem.
        # Finally, vfyservices is called to verify the addition to the 
        # /etc/services file.  The vfyservices function verifies that
        # programs using getservbyname() and getservbyport() will actually
        # see the information this script has put into /etc/services.
        # If this fails, and NIS is in use, the system administrator may need
        # to update /etc/services on the NIS master server.
        #

	vfyservices -s $SERVICENAME -t udp -p $Port_picked
	if [[ $? -ne 0 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Cannot_Verify_Service_Name \
			$CMD $SERVICENAME udp $Port_picked
		exit 1
	fi

	;;

  # start the subsystem 

start )
	startsrc -s $SUBSYSNAME
	startsrc -s $SUBSYSNAME2
	RetCode="$?"
	rnotify
	exit $RetCode
	;;

  # stop the subsystem.  use cancel option to assure
  # that the subsystem really does stop.  SRC gives
  # subsystem X seconds, then sends kill -9.  Ensure that
  # the subsystems are running before actually stopping them.

stop )
       LC_ALL=C lssrc -s "$SUBSYSNAME2" | LC_ALL=C /usr/bin/sed 1d | LC_ALL=C read r1 r2 r3 r4
       if [[ -n $r4 ]]
       then
         stopsrc -c -s $SUBSYSNAME2
         if (( $? != 0))
         then
           exit $?
         fi
       fi

       LC_ALL=C lssrc -s "$SUBSYSNAME" | LC_ALL=C /usr/bin/sed 1d | LC_ALL=C read r1 r2 r3 r4
       if [[ -n $r4 ]]
       then
         stopsrc -c -s $SUBSYSNAME
         if (( $? != 0))
         then
           exit $?
         fi
       fi

       exit 0

       ;;

  # 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. However, we do remove the port number from /etc/services.

delete )
	# Ensure subsystem is stopped 

	LC_ALL=C lssrc -s "$SUBSYSNAME" | LC_ALL=C /usr/bin/sed 1d | LC_ALL=C read r1 r2 r3 r4
	if [[ -n $r4 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Subsystem_Must_Be_Stopped \
				$CMD $SUBSYSNAME
		exit 1
	fi
	LC_ALL=C lssrc -s "$SUBSYSNAME2" | LC_ALL=C /usr/bin/sed 1d | LC_ALL=C read r1 r2 r3 r4
	if [[ -n $r4 ]]
	then
		$SPMSG hagsctrl ha_gs.cat EMsg_Subsystem_Must_Be_Stopped \
				$CMD $SUBSYSNAME2
		exit 1
	fi

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

	remservices -s $SERVICENAME -t udp	# take port number out of /etc/services

	# if there are no remaining subsystems configured in the SRC for this
	# subsystem group, then remove the entry from inittab

	LC_ALL=C lssrc -g $SUBSYS > /dev/null 2>&1
	if (( $? != 0 ))			# if no other entries in SRC
	then
		rmitab $SUBSYS 2> /dev/null
	fi

	;;

  # Clean or unconfigure all elements of the subsystem in all partitions.
  #
  # Clean can be applied to the control workstation or any node.  It DOES 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.
  #
  # Unconfig can only be applied to the control workstation.  It DOES remove
  # information from the SDR.

clean|unconfig)

	# If the option is clean, or the option is unconfig and the script
	# is running on the control workstation, do all the steps not involving
	# the SDR.

	if [[ ($Op = clean) || ($Op = unconfig && $Node_number -eq 0) ]]
	then

		# ensure all subsystem daemons are stopped

		stopsrc -c -g $SUBSYS >/dev/null

		# remove entry from /etc/inittab

		rmitab $SUBSYS 2> /dev/null

		# remove all SRC entries

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

		# remove all entries from /etc/services for this subsystem

		remservices -g -s "${SUBSYS}.*" -t udp

	fi

	# If the option is unconfig and the script is on the control workstation,
	# remove all entries from the SDR for this subsystem.

	# create DCE creds
	get_dce_creds_for_sdr

	if [[ $Op = unconfig && $Node_number -eq 0 ]]
	then
		for syspar in $(splst_syspars -n 2>/dev/null)
		do
			SP_NAME=$syspar SDRDeleteObjects Syspar_ports subsystem==$SUBSYS \
				2>/dev/null
		done
	fi

	;;

# This flag is used in unpost_i.sh to clean up all stuff created at
# run-time before de-install the Group Services subsystem.
# Note: It is important that nodes must be de-installed before CWS.
#       We have no way to detect it automatically. It is the system
#       administrator's responsability to de-install nodes before CWS.

deinstall )
	# Stop Group Services daemon 
	TIMEOUT=60
	PROCLIST=""
	LC_ALL=C lssrc -g ${SUBSYS} 2> /dev/null | LC_ALL=C 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
		# Warning: ${SUBSYS} is not fully stopped in ${TIMEOUT} seconds.
        	print_message IMsg_Subsys_Not_Stopped ${SUBSYS} ${TIMEOUT}
	    fi
	fi

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

	# Remove /etc/services entry
	remservices -g -s "${SUBSYS}.*" -t udp

	# Remove /etc/inittab entry
	rmitab ${SUBSYS} 2> /dev/null

	# Remove SDR entries.
	# SDRDeleteObjects removes only the objects of a class, not the class
	# definition itself. The class definitions are created by SDR_init
	# and should be cleaned up by PSSP uninstall.
	if [[ ${Node_number} -eq 0 ]]
	then
	    get_dce_creds_for_sdr
	    for syspar in $(splst_syspars -n 2> /dev/null)
	    do
		SP_NAME=${syspar} SDRDeleteObjects GS_Config
	    done
	    remove_dce_creds_for_sdr
	else
            get_dce_creds_for_sdr
            SDRDeleteObjects GS_Config node_number==${Node_number}
            remove_dce_creds_for_sdr
	fi

	# Remove log/lck/run/soc files
	if [ -n "${PGSD_LOGFILE}" ]
	then
	    rm -f ${PGSD_LOGFILE} 2> /dev/null
	else
	    rm -f ${DFLT_LOG_DIR}/${SUBSYS}.*  2> /dev/null
	    rm -f ${DFLT_LOG_DIR}/${SUBSYS2}.* 2> /dev/null
	fi
	
	if [ -n "${PGSD_TID_DIR}" ]
	then
	    rm -rf ${PGSD_TID_DIR}/${SUBSYS}.tid.*  2> /dev/null
	    rm -rf ${PGSD_TID_DIR}/${SUBSYS2}.tid.* 2> /dev/null
	else
	    rm -rf ${DFLT_LCK_DIR}/${SUBSYS}.tid.*  2> /dev/null
	    rm -rf ${DFLT_LCK_DIR}/${SUBSYS2}.tid.* 2> /dev/null
	fi
	
	if [ -n "${PGSD_RUN_DIR}" ]
	then
	    rm -rf ${PGSD_RUN_DIR}/${SUBSYS}.*  2> /dev/null
	    rm -rf ${PGSD_RUN_DIR}/${SUBSYS2}.* 2> /dev/null
	else
	    rm -rf ${DFLT_RUN_DIR}/${SUBSYS}.*  2> /dev/null
	    rm -rf ${DFLT_RUN_DIR}/${SUBSYS2}.* 2> /dev/null
	fi
	
	# Client socket directory cannot be specified by environment variable.
	rm -rf ${DFLT_SOC_DIR}/${SUBSYS}.clients.* 2> /dev/null

	# Group Services socket
	if [ -n "${PGSD_SUPP_SOCK}" ]
	then
	    rm -f ${PGSD_SUPP_SOCK}/${SUBSYS}/${SUBSYS}dsocket.* 2> /dev/null
	else
	    rm -f ${DFLT_SOC_DIR}/${SUBSYS}dsocket.* 2> /dev/null
	fi
	
	;;

traceon)

	# turn on all tracing in Group Services daemon for this system partition

	traceson -l -s $SUBSYSNAME
	exit $?

	;;

traceoff)

	# turn off all (but default) tracing in Group Services daemon for this
        # system partition

	tracesoff -s $SUBSYSNAME
	exit $?

	;;

refresh)

	# refresh the subsystem.
	refresh -s $SUBSYSNAME
	refresh -s $SUBSYSNAME2


         ;;

migrdone)

        # migration has completed.

        hagsmigrate -a done -s $SUBSYSNAME

        ;;

migrbegin)

        # migration is beginning.

        hagsmigrate -a begin -s $SUBSYSNAME

        ;;

esac

exit 0