# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,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 
package ERRM_cli_utils;
# sccsid = "@(#)43   1.49   src/rsct/rm/ER/cli/pm/ERRM_cli_utils.pm.perl, errmcli, rsct_rady, rady2035a 11/12/15 16:39:00"
######################################################################
#                                                                    #
# Package: ERRM_cli_utils.pm                                         #
#                                                                    #
# Description:                                                       #
#   This package contains utility/common subroutines for the         #
#   Event Response Resource Manager (ERRM) CLI commands.             #
#                                                                    #
# Subroutines Available:                                             #
#                                                                    #
#   error_exit - performs required cleanup and exits with the        #
#     appropriate ERRM CLI error exit code.                          #
#                                                                    #
#   printCIMsg - print common informational message to STDOUT.       #
#     Requires the program name and message mnemonic as inputs.      #
#                                                                    #
#   printCEMsg - print common error message to STDERR.               #
#     Requires the program name and message mnemonic as inputs.      #
#                                                                    #
#   find_resource_name - find the resource name in a specified       #
#     class to determine if it exists.                               #
#     Requires the resource name and class as inputs.                #
#                                                                    #
#   find_resource_handle - find the resource handle in the           #
#     Association class to determine if it exists.                   #
#     Requires the resource handle and original class as inputs.     #
#                                                                    #
#   find_association_handle - find the condition and response        #
#     handles in the Association class to determine if it exists.    #
#     Requires the condition and response handles as inputs.         #
#                                                                    #
#   get_handle - find the handle for a resource name.                #
#     Requires the resource name and class as inputs.                #
#                                                                    #
#   get_assoc_handles - find the Association class handles and       #
#     active flags for a condition and/or response handle.           #
#     Requires condiion handle and/or response handle.               #
#                                                                    #
#   parse_days_string - parse the day string for the response        #
#     commands.                                                      #
#     Requires the specified day string as input.                    #
#                                                                    #
#   parse_time_string - parse the time string for the response       #
#     commands.                                                      #
#     Requires the specified time string as input.                   #
#                                                                    #
#   get_source_node - returns a string that is the resolved node     #
#     name of this node (the node the command is running on).        #
#     No parameters.                                                 #
#                                                                    #
#   resolve_node - returns a string that is the resolved node name   #
#     of an input node name.                                         #
#     Requires the node name to resolve.                             #
#                                                                    #
#   get_locator_node - returns the resource name and it's locator    #
#     node from a resource name/locator combination.                 #
#     Requires the resource name.                                    #
#                                                                    #
#   process_monitor_status - returns the MonitorStatus portion of    #
#     the MonitorStatus SD and its description.                      #
#     Requires the MonitorStatus SD and the text description hash.   #
#                                                                    #
#   process_active_status - returns the translated value of the      #
#     association active flag.                                       #
#     Requires the active flag value and the text description hash.  #
#                                                                    #
#   set_orig_rmc_scope - sets CT_MANAGEMENT_SCOPE back to the value  #
#     it originally had when the ERRM command was invoked.           #
#                                                                    #
#   check_set_cluster_scope - checks CT_MANAGEMENT_SCOPE to see if   #
#     it is valid for a cluster operation. If not, it is set to      #
#     DM/SR/Local scope.                                             #
#                                                                    #
#   find_names_from_assoc - finds condition and response names from  #
#     Association handle.                                            #
#                                                                    #
#   change_locked_attr - changes the locked attribute for an ERRM    #
#     resource.                                                      #
#     Requires lock value, locator, class, resource.                 #
#                                                                    #
#   process_exit_code - returns either 0, the signal exit code,      #
#     or the process error code for the called process.              #
#     Requires the exit code to examine.                             #
#                                                                    #
#   process_api_error - extracts and prints errors from the output   #
#     of a c-api command (mkrsrc-api, etc..).                        #
#     Requires the command output including STDERR.                  #
#                                                                    #
#   remove_api_error - removes error messages from the output of a   #
#     c-api command (mkrsrc-api, etc..).                             #
#     Requires the command output including STDERR.                  #
#                                                                    #
#   escape_selstr - modify a selection string so that special SQL    #
#     characters are escaped in the string so they do not perform    #
#     special SQL functions (%#_).                                   #
#                                                                    #
#   in_cluster - returns true if in a cluster, false if not.         #
#     No parameters.                                                 #
#                                                                    #
#   getIMsg - returns the text of a message. Used for NLS.           #
#     Requires the program name and message mnemonic as inputs.      #
#                                                                    #
# Examples:                                                          #
#   printCEMsg("EMsgCUcliBadOperand", $rsrc_class);                  #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/errmcli.errmcli.map - message mapping     #
#                                                                    #
# Outputs:                                                           #
#   stdout - common informational messages that get displayed.       #
#   stderr - common error messages that get displayed.               #
#                                                                    #
# External References:                                               #
#   Commands: ctdspmsg                                               #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   000921 JAC 67664: Initial design & write.                        #
#   001013 JAC 67469: Add varaibles for condition commands.          #
#   010102 JAC 67470: Updates for mk and rm commands.                #
#   010119 JAC 67471: Updates for start and stop commands.           #
#   010215 JAC 71203: Fix parse_days_string when in a date range.    #
#   010308 JAC 71005: Escape some special characters in strings.     #
#   010420 JAC 73421: Change get_handle to check for null handle.    #
#                     (above should have been part of 72894)         #
#   010501 JAC 73619: Do not send any RMC CLI std err to garbage.    #
#   010507 JAC 73620: Check for RMC CLI user error (rc=5) and        #
#                     return ERRM user error for this case.          #
#   011119 JAC 77597: Changes for distributed RMC                    #
#   011128 JAC 77596: Add routine to process MonitorStatus attribute.#
#   011206 JAC 78841: Fix selection strings for specifying locator.  #
#   011213 JAC 78976: Fix selection strings for specifying locator.  #
#   020121 JAC 79558: Fix selection strings for specifying locator.  #
#   020128 JAC 79559: Add constant for rmc local scope.              #
#   020208 JAC 71728: Add NLS support for headers and xlating values.#
#   020411 JAC 81754: Add signal checking and switch to xxx-api.     #
#   020424 JAC 81488: Modify in_cluster routine.                     #
#   020425 JAC 82407: Fix return code from get_assoc_handles.        #
#   020428 JAC 82364: Change mgt scopes to l,d,p from l,c,s.         #
#   020523 JAC 83318: Fix in_cluster to ignore IBM.Host errors and   #
#                     do not resolve hostname in get_soure_node.     #
#   020603 JAC 83676: Set local scope before listing IBM.Host.       #
#   020607 JAC 83317: Change process_exit_code to write error msg    #
#                     if a signal has occurred.                      #
#   020719 JAC 84425: Add $rc to process_api_error.                  #
#   020723 JAC 85048: Fix parse_time_string changing gt to >.        #
#   020725 JAC 85139: Count not found error in process_api_error.    #
#   020725 JAC 84654: Change mgt scopes to l,m,p from l,d,p.         #
#   020729 JAC 85061: Add check_set_cluster_scope to use 4 (DM/SR/   #
#                     local) for scope if scope not set.             #
#   030610 JAC 95615: Add support for locked attribute.              #            
#   030619 JAC 96060: Add function to change locked attribute.       #            
#   040408 JAC 105863: Use unescape_chars to change \\\" to \".      #            
#   040428 JAC 108194: Add escape_selstr function.                   #
#   071016 JAC 146726: Set delimiter for -api calls.                 #
#   080104 JAC 148354: Don't export resolve_node.                    #
#   081103 JAC 153203: Add error events.                             #
######################################################################

use Exporter ();
@ISA = qw(Exporter);
@EXPORT_OK = qw(
    error_exit
    printCIMsg
    printCEMsg
    find_resource_name
    find_resource_handle
    find_association_handle
    find_names_from_assoc
    get_handle
    get_assoc_handles
    parse_days_string
    parse_time_string
    get_source_node
    get_locator_node
    process_monitor_status
    process_active_status
    set_orig_rmc_scope
    process_exit_code
    process_api_error
    remove_api_error
    check_set_cluster_scope
    change_locked_attr
    getIMsg
    in_cluster
    escape_selstr
    $TRUE $FALSE
    $CTDIR $CTBINDIR
    $MKRSRC $RMRSRC $CHRSRC $LSRSRC $RUNACT
    $RSCCOND $RSCEVRS $RSCASSC
    $MKCNDCRIT $MKCNDWARN $MKCNDINFO
    $SEVCRIT $SEVWARN $SEVINFO $DELIMITERI $DELIMITERO
    $RMC_CLI_USER_ERROR $RMC_CLI_RSRC_NOT_FOUND
    @EVENTTYPE @EVENTTPCD
    $GARBAGE $LSNOTFND $STARTMON $STOPMON
    $LCL_SCOPE $LCL_SCOPE_VAL
    $SR_SCOPE $SR_SCOPE_VAL $SR_SCOPE_OLD
    $CSM_SCOPE $CSM_SCOPE_VAL $CSM_SCOPE_OLD
    $CSM_SCOPE_OLD2 $MAX_UINT32
    $EVENT_BATCHING_ON $EVENT_BATCHING_OFF
    $RMC_LOCAL_SCOPE
);

use lib "/opt/rsct/pm";
use locale;

use CT_cli_input_utils qw(unescape_chars);
use ERRM_cli_rc qw(ERRM_CLI_RMC_ERROR
                 ERRM_CLI_ERROR
                 ERRM_CLI_BAD_FLAG
                 ERRM_CLI_BAD_OPERAND
                 ERRM_CLI_USER_ERROR);

#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$MSGCAT = "errmcli.cat";               # msg catalogue for this cmd
$MSGSET = "errmcli";                   # common message set

$CTDIR = "/opt/rsct";             # RSCT root directory
$CTBINDIR = "$CTDIR/bin";              # Cluster Bin directory path
$LSMSG = "$CTBINDIR/ctdspmsg";         # list / display message rtn
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps"; # msg maps used by $LSMSG

$MKRSRC = "mkrsrc";                    # RMC make resource command
$RMRSRC = "rmrsrc";                    # RMC remove resource command
$CHRSRC = "chrsrc";                    # RMC change resource command
$LSRSRC = "lsrsrc";                    # RMC list resource command
$RUNACT = "runact";                    # RMC run action command
$RSCCOND = "IBM.Condition";            # Condition Resource class name
$RSCEVRS = "IBM.EventResponse";        # Event Resp Resource class
$RSCASSC = "IBM.Association";          # Association Resource class

$LSNOTFND = 0;                         # number of last index on
                                       # lsrsrc if no condition found
$MKCNDCRIT = 2;                        # sev for mkcond critical
$MKCNDWARN = 1;                        # sev for mkcond warning
$MKCNDINFO = 0;                        # sev for mkcond informational
$SEVCRIT = "c";                        # sev for mkcond critical flag
$SEVWARN = "w";                        # sev for mkcond warning flag
$SEVINFO = "i";                        # sev for mkcond info flag
$DAYSNUM = "1234567";                  # days of the week (1=Sun)
@DAYSNUMCD = (1,2,4,8,16,32,64);       # bit map for days encoded
@EVENTTYPE = ("a","r","b","e","A");    # event types for mkresp
@EVENTTPCD = (1,2,3,4,7);              # encoded types for mkresp
$STARTMON = 1;                         # start monitoring condition
$STOPMON = 0;                          # stop monitoring condition
$DELIMITERI = "tvitvitvi";             # input delimiter to use
$DELIMITERO = "tvotvotvo";             # output delimiter to use
$GARBAGE = "/dev/null";                # place to put garbage
$RMC_CLI_USER_ERROR = 5;               # to check for RMC CLI user error
$RMC_CLI_RSRC_NOT_FOUND = 6;           # resource not found error

$LCL_SCOPE = "l";                      # -m local scope
$SR_SCOPE = "p";                       # -m shared resource cluster scope
$CSM_SCOPE = "m";                      # -m csm scope
$SR_SCOPE_OLD = "s";                   # -m shared resource cluster scope
$CSM_SCOPE_OLD = "c";                  # -m csm scope
$CSM_SCOPE_OLD2 = "d";                 # -m csm scope
$LCL_SCOPE_VAL = 1;                    # attribute value for local
$SR_SCOPE_VAL = 2;                     # attribute value for sr 
$CSM_SCOPE_VAL = 4;                    # attribute value for csm

$RMC_LOCAL2_SCOPE = 0;                 # local management scope
$RMC_LOCAL_SCOPE = 1;                  # rmc local management scope
$RMC_SR_SCOPE = 2;                     # SR management scope
$RMC_DM_SCOPE = 3;                     # DM management scope
$RMC_DM_SR_LOCAL_SCOPE = 4;            # DM/SR/local management scope

$MAX_UINT32 = 4294967295;              # max unsigned i32

$EVENT_BATCHING_ON  = 1;               # turn event batching on
$EVENT_BATCHING_OFF = 0;               # turn event batching off

$FALSE = 0;
$TRUE = 1;

#--------------------------------------------------------------------#
# Exported Subroutines (with @EXPORT_OK, -> on demand).              #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Common message handling (error, informational) routines:           #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# error_exit - performs required cleanup and exits.                  #
# Parameters:                                                        #
#   $badrc            in      Bad return code - bad enough to exit   #
#                             processing of this command.            #
# Exit:                                                              #
#   1 ERRM_CLI_RMC_ERROR      Underlying RMC error.                  #
#   2 ERRM_CLI_ERROR          Unexpected error in the command script.#
#   3 ERRM_CLI_BAD_FLAG       Input flag error.                      #
#   4 ERRM_CLI_BAD_OPERAND    Input operand error.                   #
#   5 ERRM_CLI_USER_ERROR     User error.                            #
#                                                                    #
# Global References:                                                 #
#   $main::Cleanup.    in     Hash indicating what needs to be       #
#                             cleaned up.                            #
#                             if {Session} defined - value is        #
#                             session that must terminate.           #
#                             terminate.                             #
#--------------------------------------------------------------------#
sub error_exit
{
my ($badrc) = @_;

SWITCH: {
    ($badrc == ERRM_CLI_RMC_ERROR)   && exit($badrc);
    ($badrc == ERRM_CLI_ERROR)       && exit($badrc);
    ($badrc == ERRM_CLI_BAD_FLAG)    && exit($badrc);
    ($badrc == ERRM_CLI_BAD_OPERAND) && exit($badrc);
    ($badrc == ERRM_CLI_USER_ERROR)  && exit($badrc);
    # At this point all return codes should have been converted to
    # a valid ERRM CLI return code.  But if one wasn't write an
    # error message.
    printCEMsg("EMsgERRMcliBadRC", $badrc);
    exit(ERRM_CLI_ERROR);
}   # end switch

}   # end error_exit


#--------------------------------------------------------------------#
# printCIMsg : Calls $LSMSG to print out the common cluster          #
#   ERRM CLI information messages with the required parameters.      #
#   Messages printed to stdout.                                      #
#   This subroutine is like printIMsg except it is used to print     #
#   the common ERRM CLI messages which are in the errmcli message    #
#   set.                                                             #
#                                                                    #
# Parameters:                                                        #
#   $msg       in  Message mnemonic / message number in a sense.     #
#   $optargs   in  Extra arguments/parameters to send to $LSMSG.     #
#                                                                    #
# Returns:  None.                                                    #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace    in  Prints extra info when trace is on.          #
#   $LSMSG          in  Path & Command to display messages.          #
#   $MSGCAT         in  MC CLI Message catalogue.                    #
#   $MSGSET         in  MC CLI common message set "mccli".           #
#--------------------------------------------------------------------#
sub printCIMsg
{
my ($msg, @optargs) = @_;
my ($optarg, $optargs);

$main::Trace &&
    print STDERR "$LSMSG $MSGSET $MSGCAT $msg @optargs\n";

# Keep the args to LSMSG separate by separating with single quotes
# but must replace internal single quotes with blanks or get an error.
# Must escape internal double quotes for the system call.
foreach $optarg (@optargs) {
    $optarg =~ s/'/\<U\+0027\>/g;
    $optarg =~ s/"/\\"/g;
}
$optargs = "'" . join("' '",@optargs) . "'";

(scalar @optargs > 0) ?
    system "$LSMSG $MSGSET $MSGCAT $msg $optargs | /bin/sed \"s/\<U\+0027\>/'/g\"" :
    system "$LSMSG $MSGSET $MSGCAT $msg";

return;
}   # end printCIMsg


#--------------------------------------------------------------------#
# printCEMsg : Calls $LSMSG to print out the common cluster          #
#   ERRM CLI error messages with the required parameters.            #
#   Messages printed to stderr.                                      #
#   This subroutine is like printEMsg except it is used to print     #
#   the common ERRM CLI messages which are in the errmcli message    #
#   set and it prefixes the message with the appropriate program     #
#   name.                                                            #
#                                                                    #
# Parameters:                                                        #
#   $msg       in  Message mnemonic / message number in a sense.     #
#   $optargs   in  Extra arguments/parameters to send to $LSMSG.     #
#                                                                    #
# Returns:  None.                                                    #
#                                                                    #
# Global Variables:                                                  #
#   $main::PROGNAME in  Calling program/command for error message.   #
#   $main::Trace    in  Prints extra info when trace is on.          #
#   $LSMSG          in  Path and command to display messages.        #
#   $MSGCAT         in  CU CLI Message catalogue.                    #
#   $MSGSET         in  CU CLI common message set "cucli".           #
#--------------------------------------------------------------------#
sub printCEMsg
{
my ($msg, @optargs) = @_;
my ($optarg, $optargs);

$main::Trace &&
    print STDERR "$LSMSG $MSGSET $MSGCAT $msg $main::PROGNAME @optargs\n";

# Keep the args to LSMSG separate by separating with single quotes
# but must replace internal single quotes with blanks or get an error.
# Must escape internal double quotes for the system call.
foreach $optarg (@optargs) {
    $optarg =~ s/'/\<U\+0027\>/g;
    $optarg =~ s/"/\\"/g;
}
$optargs = "'" . join("' '",@optargs) . "'";

(scalar @optargs > 0) ?
    system "$LSMSG $MSGSET $MSGCAT $msg $main::PROGNAME $optargs | /bin/sed \"s/\<U\+0027\>/'/g\" 1>&2" :
    system "$LSMSG $MSGSET $MSGCAT $msg $main::PROGNAME 1>&2";

return;
}   # end printCEMsg


#--------------------------------------------------------------------#
# find_resource_name : Uses the list resource RMC CLI command to     #
#   determine if a condition name or response name exists. It is     #
#   determined to exist if there is information returned from the    #
#   list command.                                                    #
#                                                                    #
# Parameters:                                                        #
#   $resource_name   the condition or response name to find          #
#                    the resource name may or may not be followed    #
#                    by :Node_name.                                  #
#   $resource_class  the class to look in (Condition, EventResponse) #
#   $resource_loc    the location or node to look on for the resource#
#                                                                    #
# Returns:                                                           #
#   0                if the name is found                            #
#   -1               if the name is not found                        #
#   ERRM_CLI_USER_ERROR  if there was an RMC_CLI_USER_ERROR          #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace     in case trace is on                             #
#   $main::PROGNAME  for trace message                               #
#   $CTBINDIR        where list command resides                      #
#   $LSRSRC          RMC CLI list command                            #
#   $LSNOTFND        number of output line for name not found        #
#--------------------------------------------------------------------#
sub find_resource_name
{
my $resource_name = shift(@_);
my $resource_class = shift(@_);
my $resource_loc = shift(@_);
my @listout = ();
my $trace_opt = "";
my $node_select = "";
my $rc = 0;

# re-establish original CT_MANAGEMENT_SCOPE
&set_orig_rmc_scope;

# check to see if resource name has a Node_name to locate it.
# if not, set rmc local scope.  if it does, use it in select string.
if ($resource_loc eq "") {
   # set CT_MANAGEMENT_SCOPE to local for query
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE; 
}
# else use location is select string
else {
   $node_select = " && NodeNameList |< {\\\"$resource_loc\\\"}";

   # use DM/SR/Local scope if scope not set and there's a locator
   &check_set_cluster_scope;
}

$main::Trace && print STDERR "$main::PROGNAME: calling lsrsrc-api\n";
$main::Trace && ($trace_opt = " -T ");

# determine if the resource exists
#@listout = `$CTBINDIR/$LSRSRC $trace_opt -x -s "Name == \\\"$resource_name\\\" $node_select" $resource_class`;
@listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${resource_class}${DELIMITERI}\"Name==\\\"$resource_name\\\"$node_select\"${DELIMITERI}${DELIMITERI}${DELIMITERI}Name 2>&1`;
$rc = $?;
$rc = &process_exit_code($rc);
$main::Trace && print STDERR "lsrsrc-api results:\n";
$main::Trace && print STDERR "@listout";
$main::Trace && print STDERR "$main::PROGNAME: lsrsrc-api returned $rc\n";

# show any errors if there was a bad rc except for not found
if (($rc != 0) && ($rc != $RMC_CLI_RSRC_NOT_FOUND)) {
   &process_api_error($DELIMITERO,$rc,@listout);
}

# return ERRM CLI user error if it's an RMC CLI user error
if ($rc == $RMC_CLI_USER_ERROR) { exit(ERRM_CLI_USER_ERROR);}

# return -1 if resource not found
if ($rc == $RMC_CLI_RSRC_NOT_FOUND) {
   return(-1);
}

# if list command failed, print RMC error message and exit
if ($rc != 0) {
    exit(ERRM_CLI_RMC_ERROR);
}

# must have been found
return (0);
}

#--------------------------------------------------------------------#
# find_resource_handle : Uses the list resource RMC CLI command to   #
#   determine if a condition or response handle exists in the        #
#   Association resource class.                                      #
#                                                                    #
# Parameters:                                                        #
#   $resource_handle the condition or response handle to find        #
#   $resource_type   "c" for condition, "r" for response             #
#   $locator         where condition is
#                                                                    #
# Returns:                                                           #
#   0                if the handle is found in the Association class #
#   -1               if the handle is not found                      #
#   ERRM_CLI_USER_ERROR  if lsrsrc returns RMC_CLI_USER_ERROR        #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace     in case trace is on                             #
#   $main::PROGNAME  for trace message                               #
#   $CTBINDIR        where list command resides                      #
#   $LSRSRC          RMC CLI list command                            #
#   $RSCASSC         Association class                               #
#   $LSNOTFND        number of output line for name not found        #
#--------------------------------------------------------------------#
sub find_resource_handle
{
my $resource_handle = shift(@_);
my $resource_type = shift(@_);
my $locator = shift(@_);
my @listout = ();
my $trace_opt = "";
my $node_select = "";
my $rc = 0;

# re-establish original CT_MANAGEMENT_SCOPE
&set_orig_rmc_scope;

# check to see if locator has a Node_name to locate it.
# if not, set rmc local scope.  if it does, use it in select string.
if ($locator eq "") {
   # set CT_MANAGEMENT_SCOPE to local for query
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}
# else use location is select string
else {
   $node_select = " && NodeNameList |< {\\\"$locator\\\"}";

   # use DM/SR/Local scope if scope not set and there's a locator
   &check_set_cluster_scope;
}

# get rid of quotes in handle
$resource_handle =~ s/"//g;

$main::Trace && print STDERR "$main::PROGNAME: calling lsrsrc-api\n";
$main::Trace && ($trace_opt = " -T ");

# list resource_name using the RMC CLI list command to see if it exists
if ($resource_type eq "c") {
#  @listout = `$CTBINDIR/$LSRSRC $trace_opt -x -s "ConditionHandle==\\\"$resource_handle\\\" $node_select" $RSCASSC`;
   @listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCASSC}${DELIMITERI}\"ConditionHandle==\\\"$resource_handle\\\"$node_select\"${DELIMITERI}${DELIMITERI}${DELIMITERI}ConditionHandle 2>&1`;
   $rc = $?;
}
else {
#  @listout = `$CTBINDIR/$LSRSRC $trace_opt -x -s "EventResponseHandle==\\\"$resource_handle\\\" $node_select" $RSCASSC`;
   @listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCASSC}${DELIMITERI}\"EventResponseHandle==\\\"$resource_handle\\\"$node_select\"${DELIMITERI}${DELIMITERI}${DELIMITERI}EventResponseHandle 2>&1`;
   $rc = $?;
}

$rc = &process_exit_code($rc);
$main::Trace && print STDERR "lsrsrc-api results:\n";
$main::Trace && print STDERR "@listout";
$main::Trace && print STDERR "$main::PROGNAME: lsrsrc-api returned $rc\n";

# show any errors if there was a bad rc except for not found
if (($rc != 0) && ($rc != $RMC_CLI_RSRC_NOT_FOUND)) {
   &process_api_error($DELIMITERO,$rc,@listout);
}

# return ERRM CLI user error if it's an RMC CLI user error
if ($rc == $RMC_CLI_USER_ERROR) { exit(ERRM_CLI_USER_ERROR);}

# return -1 if resource not found
if ($rc == $RMC_CLI_RSRC_NOT_FOUND) {
   return(-1);
}

# if list command failed, print RMC error message and exit
if ($rc != 0) {
    exit(ERRM_CLI_RMC_ERROR);
}

# must have been found
return (0);
}


#--------------------------------------------------------------------#
# find_association_handle : Uses the list resource RMC CLI command   #
#   to determine if a condition/response handle exists in the        #
#   Association resource class.                                      #
#                                                                    #
# Parameters:                                                        #
#   $cond_handle     the condition handle                            #
#   $resp_handle     the response handle                             #
#   $locator         where the condition/response is defined         #
#                                                                    #
# Returns:                                                           #
#   0                if the condition/response handles are found     # 
#                    in the Association class                        # 
#   -1               if the handle is not found                      #
#   ERRM_CLI_USER_ERROR   if RMC_CLI_USER_ERROR                      #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace     in case trace is on                             #
#   $main::PROGNAME  for trace message                               #
#   $CTBINDIR        where list command resides                      #
#   $LSRSRC          RMC CLI list command                            #
#   $RSCASSC         Association class                               #
#   $LSNOTFND        number of output line for name not found        #
#--------------------------------------------------------------------#
sub find_association_handle
{
my $cond_handle = shift(@_);
my $resp_handle = shift(@_);
my $locator = shift(@_);
my @listout = ();
my $trace_opt = "";
my $node_select = "";
my $rc = 0;

# get rid of quotes in handles
$cond_handle =~ s/"//g;
$resp_handle =~ s/"//g;

# re-establish original CT_MANAGEMENT_SCOPE
&set_orig_rmc_scope;

# check to see if resource name has a Node_name to locate it.
# if not, set rmc local scope.  if it does, use it in select string.
if ($locator eq "") {
   # set CT_MANAGEMENT_SCOPE to local for query
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}
# else use location is select string
else {
   $node_select = " && NodeNameList |< {\\\"$locator\\\"}";

   # use DM/SR/Local scope if scope not set and there's a locator
   &check_set_cluster_scope;
}

$main::Trace && print STDERR "$main::PROGNAME: calling lsrsrc-api\n";
$main::Trace && ($trace_opt = " -T ");

# check to see if the condition - resource are already in Association
#@listout = `$CTBINDIR/$LSRSRC $trace_opt -x -s "ConditionHandle==\\\"$cond_handle\\\" && EventResponseHandle==\\\"$resp_handle\\\" $node_select" $RSCASSC`;
@listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCASSC}${DELIMITERI}\"ConditionHandle==\\\"$cond_handle\\\" && EventResponseHandle==\\\"$resp_handle\\\"$node_select\"${DELIMITERI}${DELIMITERI}${DELIMITERI}ResourceHandle 2>&1`;
$rc = $?;

$rc = &process_exit_code($rc);
$main::Trace && print STDERR "lsrsrc-api results:\n";
$main::Trace && print STDERR "@listout";
$main::Trace && print STDERR "$main::PROGNAME: lsrsrc-api returned $rc\n";

# show any errors if there was a bad rc except for not found
if (($rc != 0) && ($rc != $RMC_CLI_RSRC_NOT_FOUND)) {
   &process_api_error($DELIMITERO,$rc,@listout);
}

# return ERRM CLI user error if it's an RMC CLI user error
if ($rc == $RMC_CLI_USER_ERROR) { exit(ERRM_CLI_USER_ERROR);}

# return -1 if resource not found
if ($rc == $RMC_CLI_RSRC_NOT_FOUND) {
   return(-1);
}

# if list command failed, print RMC error message and exit
if ($rc != 0) {
    exit(ERRM_CLI_RMC_ERROR);
}

# must have been found
return (0);
}


#--------------------------------------------------------------------#
# get_handle: Obtain the resource handle for the named resource in   #
#   the class given.  Uses the RMC CLI lsrsrc command.               #
#                                                                    #
# Parameters:                                                        #
#   $resource_name   the existing condition or response name         #
#   $resource_class  the class to look in (Condition, EventResponse) #
#   $locator         the node to look on                             #
#                                                                    #
# Returns:                                                           #
#   $rc              0 if resource handle found                      #
#                    ERRM_CLI_USER_ERROR if RMC_CLI_USER_ERROR       #
#   $resource_handle the resource handle                             #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace     in case trace is on                             #
#   $main::PROGNAME  for trace message                               #
#   $CTBINDIR        where list command resides                      #
#   $LSRSRC          RMC CLI list command                            #
#--------------------------------------------------------------------#
sub get_handle
{
my $resource_name = shift(@_);
my $resource_class = shift(@_);
my $locator = shift(@_);
my $resource_handle = "";
my $node_select = "";
my @listout = ();
my $rc = 0;

# re-establish original CT_MANAGEMENT_SCOPE
&set_orig_rmc_scope;

# check to see if resource name has a Node_name to locate it.
# if not, set rmc local scope.  if it does, use it in select string.
if ($locator eq "") {
   # set CT_MANAGEMENT_SCOPE to local for query
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}
# else use location is select string
else {
   $node_select = " && NodeNameList |< {\\\"$locator\\\"}";

   # use DM/SR/Local scope if scope not set and there's a locator
   &check_set_cluster_scope;
}

$main::Trace && print STDERR "$main::PROGNAME: calling lsrsrc-api\n";

# list resource_name using the RMC CLI list command to get the handle
#$resource_handle = `$CTBINDIR/$LSRSRC -t -x -s "Name == \\\"$resource_name\\\" $node_select" $resource_class ResourceHandle`;
@listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${resource_class}${DELIMITERI}\"Name==\\\"$resource_name\\\"$node_select\"${DELIMITERI}${DELIMITERI}${DELIMITERI}ResourceHandle 2>&1`;
$rc = $?;
$rc = &process_exit_code($rc);

$main::Trace && print STDERR "lsrsrc-api results:\n";
$main::Trace && print STDERR "@listout";
$main::Trace && print STDERR "$main::PROGNAME: lsrsrc-api returned $rc\n";

# show any errors if there was a bad rc except for not found
if (($rc != 0) && ($rc != $RMC_CLI_RSRC_NOT_FOUND)) {
   &process_api_error($DELIMITERO,$rc,@listout);
}

# return ERRM CLI user error if it's an RMC CLI user error
if ($rc == $RMC_CLI_USER_ERROR) { exit(ERRM_CLI_USER_ERROR);}

# return -1 if resource not found
if ($rc == $RMC_CLI_RSRC_NOT_FOUND) {
   return (-1,"");
}

# if list command failed, print RMC error message and exit
if ($rc != 0) {
    exit(ERRM_CLI_RMC_ERROR);
}

# must have been found
$resource_handle = $listout[0];
chomp($resource_handle);
$resource_handle = "\"".$resource_handle."\"";
return (0,$resource_handle);
}


#--------------------------------------------------------------------#
# parse_days_string - Parse the days of the week string returning    #
#   the encoded days for the Actions attribute of EventResponse.     #
#   The default of 1-7 is filled in if no value is specified (for    #
#   example: 3,4,,8.)                                                #
#                                                                    #
# Input:                                                             #
#   $days_string             valid user input for -d                 #
# Return:                                                            #
#   $ndays                   the number of coded days found          #
#   $days_code               the coded days value                    #
#                                                                    #
#--------------------------------------------------------------------#
sub parse_days_string
{
my $days_string = shift @_;             # input days string
my $ndays = 0;                          # count the number of coded days
my $days_code = "";                     # will return coded days
my $day = "";                           # part of $day_string
my $lendays = 0;                        # length of $days_string
my $range = $FALSE;                     # looks for a - in $days_string
my $tot_code = 0;                       # keeps count of coded days
my $i = 0;                              # loop counter
my $k = 0;                              # loop counter
my $pos = 0;                            # find coded values
my $range_num = 0;                      # next number for range
my $comma = "";                         # when >1 days, need a comma


# look for any ,, used.  Fill them in with 1-7 (default)
while($days_string =~ /,,/) { $days_string =~ s/,,/,1-7,/;}

# find the length of day string
$lendays = length $days_string;

# look for an ending comma.  Fill in with 1-7 (default)
if (substr($days_string,$lendays-1,1) eq ",") {
   $days_string = $days_string . "1-7";
   }

# look for a beginning comma. Fill in with 1-7 (default)
if (substr($days_string,0,1) eq ",") {
   $days_string = "1-7" . $days_string;
   }

# make sure we have the corrected length of day string
$lendays = length $days_string;

# loop looking at each character in day string.
# make sure it's 1-7, a -, or a comma and process accordingly.
for ($i=0;$i<$lendays;$i++){
    $day = substr($days_string,$i,1);
 
    # is day character a number 1 to 7?
    if ($day =~ /[1-7]/){
       # it's a number. are we in a range that was specified?
       if ($range){
          # it's in a range.  is the next number in the range valid?
          if ($day lt $range_num) {                   # 71203 lt, not le
              printCEMsg("EMsgERRMcliImproperUsageOperand","-d");
              exit(ERRM_CLI_USER_ERROR);
             }

          # in a valid range, add days until we come to the end of the range
          for ($k=$range_num;$k<=$day;$k++){
              $pos = index $DAYSNUM,$k;       # determine coded value
              $tot_code = $tot_code + $DAYSNUMCD[$pos];  # add to total
              }
          $range = $FALSE;              # reset back after processing done
       }

       # it's a number, but not part of a range
       else {
           $pos = index $DAYSNUM,$day;  # determine coded value 
           $tot_code = $tot_code + $DAYSNUMCD[$pos];  # add to total
           }
 
       # in case this is the start of a range, keep track of what should be next
       $range_num = $day + 1;
       }                                # end of if it's 1-7

    # is day character a hyphen?
    elsif ($day eq "-") { 

       # if we're in a range, it can't be a hyphen
       if ($range) { 
           printCEMsg("EMsgERRMcliImproperUsageOperand","-d");
           exit(ERRM_CLI_USER_ERROR);
           }
       # set the range flag so we know we're in a range specification
       $range = $TRUE; 
       }                                # end of it's a hyphen

    # is day character a plus? (multiple days but not a range)
    elsif ($day eq "+") {

       # don't need to do anything.  move on to next day .
       }                                # end of it's a plus

    # is day character a comma?
    elsif ($day eq ",") {

       # if we're in a range, it can't be a comma
       if ($range) {
           printCEMsg("EMsgERRMcliImproperUsageOperand","-d");
           exit(ERRM_CLI_USER_ERROR);
           }

       # end of previous day specification. concatenate to coded string and
       # reset some things
       $days_code = $days_code . $comma . $tot_code;
       $tot_code = 0;
       $range = $FALSE;
       $comma = ",";
       $ndays++;                        # count the number of coded values
       }                                # end of it's a comma

    # an invalid character 
    else {
       printCEMsg("EMsgERRMcliImproperUsageOperand","-d");
       exit(ERRM_CLI_USER_ERROR);
       }
}

# add the last coded value to the coded value string
$days_code = $days_code . $comma . $tot_code;

$ndays++;                               # count the last value 

return ($ndays,$days_code);
}


#--------------------------------------------------------------------#
# parse_time_string - Parse the times of the day string returning    #
#   the encoded times for the Actions attribute of EventResponse.    #
#   The default of 0000-2400 is filled in if no value is specified   #
#   (for example: 0800-1600,,0800-1800)                              #
#                                                                    #
# Input:                                                             #
#   $time_string             valid user input for -t                 #
# Return:                                                            #
#   $ntimes                  the number of coded times found         #
#   $start_time              the coded start times                   #
#   $end_time                the coded end times                     #
#                                                                    #
#--------------------------------------------------------------------#
sub parse_time_string
{
my $time_string = shift @_;             # input times string
my $time_code = 0;                      # coded time
my $ntimes = 0;                         # number of coded times
my $start_time = "";                    # coded start times
my $end_time = "";                      # coded end times
my $this_is_start_time = $TRUE;         # flag to know what time
my $hhmm = "";                          # substring of time_string  
my $hours = "";                         # substring of hhmm
my $minutes = "";                       # substring of hhmm 
my $lentime = 0;                        # length of time_string
my $i = 0;                              # loop counter
my $prev_start_time = 0;                # remember start time
my $comma = "";                         # separates multiple times

# look for ending any comma.  Fill in with 0000-2400 (default)
while($time_string =~ /,,/) { $time_string =~ s/,,/,0000-2400,/; }

# get the length of the time string
$lentime = length $time_string;

# look for ending comma.  Fill in with 0000-2400 (default)
if (substr($time_string,$lentime-1,1) eq ",") {
   $time_string = $time_string . "0000-2400";
   }

# look for beginning comma.  Fill in with 0000-2400 (default)
if (substr($time_string,0,1) eq ",") {
   $time_string = "0000-2400" . $time_string;
   }

# get possibly new length
$lentime = length $time_string;

# loop through time string pulling off start and stop time.
# validate the times and convert to coded times
for ($i=0;$i<$lentime;$i=$i+5){

    if ($i>=10) { $comma = ",";}        # have >1 time specified

    # check the time format (hh:mm). enough characters?
    if ( ($i+3)>($lentime-1) ) {
         printCEMsg("EMsgERRMcliImproperUsageOperand","-t");
         exit(ERRM_CLI_USER_ERROR);
         }

    # get a time
    $hhmm = substr($time_string,$i,4);

    # extract the hours and check them
    $hours = substr($hhmm,0,2);
    if ($hours lt "00" | $hours gt "24")  {
        printCEMsg("EMsgERRMcliImproperUsageOperand","-t");
        exit(ERRM_CLI_USER_ERROR);
        }

    # extract the times and check them
    $minutes = substr($hhmm,2,2);
    if ($minutes lt "00" | $minutes gt "59")  {
        printCEMsg("EMsgERRMcliImproperUsageOperand","-t");
        exit(ERRM_CLI_USER_ERROR);
        }

    # calculate the coded time in seconds
    $time_code = ($hours * 60 * 60) + ($minutes * 60);

    # for start time, add to coded start times and save to compare
    # against the end time
    if ($this_is_start_time){
       $this_is_start_time = $FALSE;
       $start_time = $start_time . $comma . $time_code;
       $prev_start_time = $time_code;
    }

    # for end time, verify it's more than start time, then add to 
    # coded end times.
    else {
       if ($prev_start_time > $time_code) {
           printCEMsg("EMsgERRMcliImproperUsageOperand","-t");
           exit(ERRM_CLI_USER_ERROR);
           }
       $this_is_start_time = $TRUE;
       $end_time = $end_time . $comma . $time_code;
       $ntimes++;                       # count the number of times 
       }
    }

return ($ntimes,$start_time,$end_time);
}


#--------------------------------------------------------------------#
# get_assoc_handles : Uses the list resource RMC CLI command to      #
#   find all association resource handles from a condition handle    #
#   and / or a response handle in the Association resource class.    #
#                                                                    #
# Parameters:                                                        #
#   $cond_handle     the condition handle to find, or ""             #
#   $resp_handle     the response handle to find, or ""              #
#   $locator         where the condition/response is                 #
#                                                                    #
# Returns:                                                           #
#   $rc              return code                                     #
#                    0  if one or more Association handles are found #
#                    -1 if no Association handles are found          #
#                    ERRM_CLI_USER_ERROR if RMC_CLI_USER_ERROR       #
#   \@handles        all Association handles that were found         #
#                    (by reference)                                  #
#   \@actflags       the corresponding ActiveFlag values             #
#                    (by reference)                                  #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace     in case trace is on                             #
#   $main::PROGNAME  for trace message                               #
#   $CTBINDIR        where list command resides                      #
#   $LSRSRC          RMC CLI list command                            #
#   $RSCASSC         Association class                               #
#   $LSNOTFND        number of output line for name not found        #
#--------------------------------------------------------------------#
sub get_assoc_handles
{
my $cond_handle = shift(@_);            # condition resource handle
my $resp_handle = shift(@_);            # response resource handle
my $locator = shift(@_);                # locator 
my $rc = 0;                             # return code
my @handles = ();                       # array to keep handles
my @act_flags = ();                     # array to keep active flags
my @listout = ();                       # lsrsrc output
my $i = 0;                              # loop counter
my $pos = 0;                            # look through output
my $handle = "";                        # a single handle from output
my $active = 0;                         # a single flag from output
my $node_select = "";
my $trace_opt = "";

# get rid of quotes in handles
$cond_handle =~ s/"//g;
$resp_handle =~ s/"//g;

# re-establish original CT_MANAGEMENT_SCOPE
&set_orig_rmc_scope;

# check to see if resource name has a Node_name to locate it.
# if not, set rmc local scope.  if it does, use it in select string.
if ($locator eq "") {
   # set CT_MANAGEMENT_SCOPE to local for query
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}
# else use location is select string
else {
   $node_select = " && NodeNameList |< {\\\"$locator\\\"}";

   # use DM/SR/Local scope if scope not set and there's a locator
   &check_set_cluster_scope;
}

$main::Trace && print STDERR "$main::PROGNAME: calling lsrsrc-api\n";
$main::Trace && ($trace_opt = " -T ");

# list the Association resource depending on whether you have just a condition,
# just a response, or both
if ($resp_handle eq "") {               # have only a condition
#  @listout = `$CTBINDIR/$LSRSRC $trace_opt -x -s "ConditionHandle==\\\"$cond_handle\\\" $node_select" $RSCASSC ResourceHandle ActiveFlag`;
   @listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCASSC}${DELIMITERI}\"ConditionHandle==\\\"$cond_handle\\\"$node_select\"${DELIMITERI}${DELIMITERI}${DELIMITERI}ResourceHandle${DELIMITERI}ActiveFlag 2>&1`;
   $rc = $?;
   }

elsif ($cond_handle eq "") {            # have only a response
#  @listout = `$CTBINDIR/$LSRSRC $trace_opt -x -s "EventResponseHandle==\\\"$resp_handle\\\" $node_select" $RSCASSC ResourceHandle ActiveFlag`;
   @listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCASSC}${DELIMITERI}\"EventResponseHandle==\\\"$resp_handle\\\"$node_select\"${DELIMITERI}${DELIMITERI}${DELIMITERI}ResourceHandle${DELIMITERI}ActiveFlag 2>&1`;
   $rc = $?;
   }

else {                                  # have both condition and response
#  @listout = `$CTBINDIR/$LSRSRC $trace_opt -x -s "ConditionHandle==\\\"$cond_handle\\\" && EventResponseHandle==\\\"$resp_handle\\\" $node_select" $RSCASSC ResourceHandle ActiveFlag`;
   @listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCASSC}${DELIMITERI}\"ConditionHandle==\\\"$cond_handle\\\" && EventResponseHandle==\\\"$resp_handle\\\"$node_select\"${DELIMITERI}${DELIMITERI}${DELIMITERI}ResourceHandle${DELIMITERI}ActiveFlag 2>&1`;
   $rc = $?;
   }

$rc = &process_exit_code($rc);
$main::Trace && print STDERR "lsrsrc-api results:\n";
$main::Trace && print STDERR "@listout";
$main::Trace && print STDERR "$main::PROGNAME: lsrsrc-api returned $rc\n";

# show any errors if there was a bad rc except for not found
if (($rc != 0) && ($rc != $RMC_CLI_RSRC_NOT_FOUND)) {
   &process_api_error($DELIMITERO,$rc,@listout);
}

# return ERRM CLI user error if it's an RMC CLI user error
if ($rc == $RMC_CLI_USER_ERROR) { exit(ERRM_CLI_USER_ERROR);}

# if list command failed, print RMC error message and exit
if (($rc != 0) && ($rc != $RMC_CLI_RSRC_NOT_FOUND)) {
    exit(ERRM_CLI_RMC_ERROR);
}

# return -1 if resource not found
if ($rc == $RMC_CLI_RSRC_NOT_FOUND) {
   $rc = -1;
}
# if it was found 
if ($rc == 0) {
   $rc = 0;

   # parse the output to find the handles and the active flags
   for ($i=0;$i<=$#listout;$i++) {        # each line of output

      # split the line into handle and flag
      ($handle,$active) = split /$DELIMITERO/,$listout[$i];
      chomp($handle);
      chomp($active);
      $handle = "\"".$handle."\"";
   
      push @handles, $handle;            # save the handle
      push @act_flags, $active;          # save the flag
      }
   }

# return the arrays back as references
return ($rc, \@handles, \@act_flags);
}


#--------------------------------------------------------------------#
# find_names_from_assoc -  uses the list resource RMC CLI command to #
#   find the names of the conditions and responses for an Association#
#   resource.                                                        #
#                                                                    #
# Parameters:                                                        #
#   $locator         where the condition/response is                 #
#   @assoc_handles   the list of Association resource handles        #
#                                                                    #
# Returns:                                                           #
#   $rc              return code                                     #
#                    0  if names are found                           #
#                    -1 if no names are found                        #
#                    ERRM_CLI_USER_ERROR if RMC_CLI_USER_ERROR       #
#   \@cond_names     reference to a list of condition names.         #
#   \@resp_names     reference to a list of response names.          #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace     in case trace is on                             #
#   $main::PROGNAME  for trace message                               #
#   $CTBINDIR        where list command resides                      #
#   $LSRSRC          RMC CLI list command                            #
#   $RSCASSC         Association class                               #
#   $LSNOTFND        number of output line for name not found        #
#--------------------------------------------------------------------#
sub find_names_from_assoc
{
my $locator = shift(@_);                # locator
my @assoc_handles = @_;                 # assoc handle array
my $rc = 0;                             # return code
my @cond_rhs = ();                      # condition handles
my @resp_rhs = ();                      # response handles
my @cond_names = ();                    # condition names
my @resp_names = ();                    # response names
my $rh = "";                            # Assoc RH
my $rh_str = "";                        # handles for cmd text
my $cmd_rhs = "";                       # handles for lsrsrc-api
my $cond_rh = "";                       # condition handle
my $resp_rh = "";                       # response handle
my $name = "";                          # resource name
my @listout = ();                       # result from lsrsrc
my $i = 0;                              # counter

# find condition and response handles from association handles

foreach $rh (@assoc_handles) {

   chomp($rh);
   # make sure we know where the quotes are
   $rh =~ s/"//g;

   # build lsrsrc-api command using -r format for resource handle.
   # handle is unique is cluster so locator is not needed.
   $cmd_rhs = $cmd_rhs . " -r \"$rh\"";
}
   
# re-establish original CT_MANAGEMENT_SCOPE
&set_orig_rmc_scope;

# if no locator, use local scope.
if ($locator eq "") {
   # set CT_MANAGEMENT_SCOPE to local for query
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}

# use DM/SR/Local scope if scope not set and there's a locator
else {
   &check_set_cluster_scope;
}

$main::Trace && print STDERR "$main::PROGNAME: calling lsrsrc-api\n";
$main::Trace && ($trace_opt = " -T ");

# find the condition and response handles.
@listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -a ConditionHandle${DELIMITERI}EventResponseHandle $cmd_rhs 2>&1`;
$rc = $?;
$rc = &process_exit_code($rc);
$main::Trace && print STDERR "lsrsrc-api results:\n";
$main::Trace && print STDERR "@listout";
$main::Trace && print STDERR "$main::PROGNAME: lsrsrc-api returned $rc\n";

# show any errors
if ($rc != 0) {
   &process_api_error($DELIMITERO,$rc,@listout);
}

# output from lsrsrc-api is cond_rh::resp_rh  except for delimiter
# one line per pair

$cmd_rhs = "";

foreach $rh_str (@listout) {
   # split the line into condition and response handles
   ($cond_rh,$resp_rh) = split /$DELIMITERO/,$rh_str;
   chomp($cond_rh);
   chomp($resp_rh);

   # build lsrsrc-api command using -r format for resource handle.
   $cmd_rhs = $cmd_rhs . " -r \"$cond_rh\" -r \"$resp_rh\"";
}

# find condition names from condition handles and response names
# from response handles

# re-establish original CT_MANAGEMENT_SCOPE
&set_orig_rmc_scope;

# if no locator, use local scope.
if ($locator eq "") {
   # set CT_MANAGEMENT_SCOPE to local for query
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}

# use DM/SR/Local scope if scope not set and there's a locator
else {
   &check_set_cluster_scope;
}

$main::Trace && print STDERR "$main::PROGNAME: calling lsrsrc-api\n";
$main::Trace && ($trace_opt = " -T ");

# find the condition and response handles.
@listout = `$CTBINDIR/lsrsrc-api -D $DELIMITERO -a Name $cmd_rhs 2>&1`;
$rc = $?;
$rc = &process_exit_code($rc);
$main::Trace && print STDERR "lsrsrc-api results:\n";
$main::Trace && print STDERR "@listout";
$main::Trace && print STDERR "$main::PROGNAME: lsrsrc-api returned $rc\n";

# show any errors
if ($rc != 0) {
   &process_api_error($DELIMITERO,$rc,@listout);
}

# output from lsrsrc-api is name
# 1st line is condition, next line response, repeat in this pattern

# get condition names
for ($i=0; $i <= $#listout; $i = $i + 2) {
   $name = $listout[$i];
   chomp($name);
   push @cond_names, $name;
}

# get response names
for ($i=1; $i <= $#listout; $i = $i + 2) {
   $name = $listout[$i];
   chomp($name);
   push @resp_names, $name;
}

# return the arrays back as references
return ($rc, \@cond_names, \@resp_names);
}

#--------------------------------------------------------------------#
# change_locked_attr - changes the value of the Locked attribute for #
#   the resource specified.                                          #
#                                                                    #
# Parameters:                                                        #
#   $lock_val        Value to set.  0 for unlock, 1 for lock.        #
#   $locator         Node where resource is, if not local.           #
#   $class           Resource class.                                 #
#   $resource        Resource name if condition or responce class.   #
#                    Association handle if association class.        #
#                                                                    #
# Returns:                                                           #
#   $rc              return code                                     #
#                    0  if chrsrc-api successful.                    #
#                    -1 otherwise.                                   #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace     in case trace is on                             #
#   $main::PROGNAME  for trace message                               #
#   $CTBINDIR        where list command resides                      #
#--------------------------------------------------------------------#
sub change_locked_attr
{
my $lock_val = shift(@_);               # value to set Locked to 
my $locator = shift(@_);                # locator
my $class = shift(@_);                  # resource class
my $resource = shift(@_);               # resource to change 
my $rc = 0;                             # return code
my @cmd_out = ();                       # chrsrc-api output
my $cond_rh = "";                       # condition handle
my $resp_rh = "";                       # response handle
my $node_select = "";                   # for locator

# set CT_MANAGEMENT_SCOPE to original setting, in case it was used
&set_orig_rmc_scope;

# if the destination node was not specified, change the local definition.
# Make sure rmc scope is set to local scope.
if ($locator eq "") {
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}
# a locator was specified, use it for NodeNameList
else {
   $node_select = " && NodeNameList |< {\\\"$locator\\\"}";

   # use DM/SR/Local scope if scope not set
   &check_set_cluster_scope;
}

# if class is Condition or EventResponse, use chrsrc-api for 
# name=resource 
if (($class eq $RSCCOND) || ($class eq $RSCEVRS)) {

   if ($main::Trace) { print STDERR "$PROGNAME: calling chrsrc-api\n";}

   @cmd_out = `$CTBINDIR/chrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${class}${DELIMITERI}"Name==\\\"$resource\\\" $node_select"${DELIMITERI}Locked${DELIMITERI}$lock_val 2>&1`;

   $rc = $?;
   $rc = &process_exit_code($rc);

   if ($main::Trace) {
      print STDERR "chrsrc-api results:\n";
      print STDERR "@cmd_out";
      print STDERR "$main::$PROGNAME: chrsrc-api returned $rc\n";
   }

   # show any errors if there was a bad rc except for not found
   if ($rc != 0) {
      process_api_error($DELIMITERO,$rc,@cmd_out);
   }
}

# if association class, use chrsrc-api -r for association handle ($resource)
if ($class eq $RSCASSC) {

   # get rid of the quotes so we know where they are
   $resource =~ s/\"//g;

   if ($main::Trace) { print STDERR "$PROGNAME: calling chrsrc-api\n";}

   @cmd_out = `$CTBINDIR/chrsrc-api -I $DELIMITERI -D $DELIMITERO -r "$resource"${DELIMITERI}Locked${DELIMITERI}$lock_val 2>&1`;

   $rc = $?;
   $rc = &process_exit_code($rc);

   if ($main::Trace) {
      print STDERR "chrsrc-api results:\n";
      print STDERR "@cmd_out";
      print STDERR "$main::$PROGNAME: chrsrc-api returned $rc\n";
   }

   # show any errors if there was a bad rc except for not found
   if ($rc != 0) {
      process_api_error($DELIMITERO,$rc,@cmd_out);
   }
}            # end class=association

# return 
return ($rc);
}


#--------------------------------------------------------------------#
# get_source_node : Returns a string that is the resolved node name  #
#   for the node where the rmc session would (may) be.  That is, if  #
#   CT_CONTACT is set, it's that node, otherwise, it's the node      #
#   you're on.                                                       #
#                                                                    #
# Parameters:                                                        #
#   None.                                                            #
#                                                                    #
# Returns:                                                           #
#   local_node       Resolved name of the node the rmc session would #
#                    or may be on.                                   #
#                                                                    #
# Global Variables:                                                  #
#--------------------------------------------------------------------#
sub get_source_node
{
my $local_node = "";                    # node command runs on
my $hname = "";                         # used by gethost
my $haliases = "";                      # used by gethost
my $haddrtype = "";                     # used by gethost
my $hlength = 0;                        # used by gethost
my @haddrs = ();                        # used by gethost

# see if CT_CONTACT is defined. If so, use it.
# if not, use the node you're on.
if (defined $ENV{CT_CONTACT}) {
   $local_node = $ENV{CT_CONTACT};
}
else {
   # get the name of the node you're on
   $local_node = `/bin/hostname`;
}
chomp($local_node);

# resolve the name
#($hname, $haliases, $haddrtype, $hlength, @haddrs) = gethostbyname($local_node);
#$local_node = $hname;

# return the resolved name
return($local_node);
}   #  end of get_source_node


#--------------------------------------------------------------------#
# resolve_node : Returns a string that is the resolved node name of  #
#   the input node name.                                             #
#                                                                    #
# Parameters:                                                        #
#   node_name        string that is the node name to be resolved.    #
#                                                                    #
# Returns:                                                           #
#   resolved_name    Resolved name of the node. "" if not resolved.  #
#                                                                    #
# Global Variables:                                                  #
#--------------------------------------------------------------------#
sub resolve_node 
{
my $node_name = shift(@_);              # node name to resolve 
my $resolved_name = "";                 # output resolved name
my $hname = "";                         # used by gethost
my $haliases = "";                      # used by gethost
my $haddrtype = "";                     # used by gethost
my $hlength = 0;                        # used by gethost
my @haddrs = ();                        # used by gethost

# resolve the name
($hname, $haliases, $haddrtype, $hlength, @haddrs) = gethostbyname($node_name);

# set the resolved node name
if (!$hname) {
    # if it didn't resolve, keep what it had 
    $resolved_name = $node_name;
}
# it did resolve
else {
      $resolved_name = $hname;
}

# return the resolved name
return($resolved_name);
}   #  end of resolve_node


#--------------------------------------------------------------------#
# get_locator_node : Returns the resource name and locator from a    #
#   resource name/locator combination.  Ex. ConditionName:nodeA      #
#   will return ConditionName and nodeA.                             #
#                                                                    #
# Parameters:                                                        #
#   resource_name_in  The resource name / locator combination.       #
#                                                                    #
# Returns:                                                           #
#   resource_name    resource name.                                  #
#   locator          locator, if there is one.                       #
#                                                                    #
# Global Variables:                                                  #
#--------------------------------------------------------------------#
sub get_locator_node
{
my $resource_name_in = shift(@_);       # resource/locator combo 
my $resource_name = "";                 # resource name for output
my $temp_resource = "";                 # temporary place for names
my $locator = "";                       # locator name for output
my $hname = "";                         # used by gethost
my $haliases = "";                      # used by gethost
my $haddrtype = "";                     # used by gethost
my $hlength = 0;                        # used by gethost
my @haddrs = ();                        # used by gethost

# split the resource/locator based on colons
@temp_resource = split /:/,$resource_name_in;

# if there were some colons, take the last splitee as the locator
if ($#temp_resource > 0) {
   $locator = $temp_resource[$#temp_resource];

   # set the resource name from input but remove locator
   $resource_name = $resource_name_in;
   $resource_name =~s/:$locator$//;
}

# else there's no colons, it's all resource name
else {
   $locator = "";
   $resource_name = $resource_name_in;
}

return($resource_name, $locator);
}   #  end of get_locator_node


#--------------------------------------------------------------------#
# process_monitor_status: returns the MonitorStatus portion of the   #
#   MonitorStatus attribute SD and its description.                  #
#   The MonitorStatus attribute is in form:                          #
#       [monitorstatus,{errornodes},{errorcodes}]                    #
#                                                                    #
# Parameters:                                                        #
#   monitor_status_sd   The MonitorStatus attribute value.           #
#   monitor_desc_text   The hash of values for the descriptions.     #
#                                                                    #
# Returns:                                                           #
#   monitor_status      The MonitorStatus code of the SD.            #
#   monitor_desc        The description for monitor_status.          #
#                                                                    #
# Global Variables:                                                  #
#--------------------------------------------------------------------#
sub process_monitor_status
{
my $monitor_status_sd = shift(@_);      # MonitorStatus SD       
my %monitor_desc_text = @_;             # hash of text descriptions 
my $monitor_status = 0;                 # MonitorStatus code     
my $monitor_desc = "";                  # MonitorStatus description
my @monitor_temp = ();                  # temporary 
my $monitor_temp2 = "";
my $found = $FALSE;                     # keep track of when text found

# split on commas
@monitor_temp = split /,/,$monitor_status_sd;

# take first element
$monitor_temp2 = $monitor_temp[0];

# split on [
@monitor_temp = split /\[/,$monitor_temp2;

# take second element as status
$monitor_status = $monitor_temp[1];

# see if monitor status to find exists
if (defined $monitor_desc_text{$monitor_status}) {
    $found = $TRUE;
}

# translate monitor status
if ($found) {
   $monitor_desc = $monitor_desc_text{$monitor_status};
   }
else {
   $monitor_desc = $monitor_desc_text{"?"};
   }

# add quotes 
$monitor_desc = "\"".$monitor_desc."\"";

return($monitor_status, $monitor_desc);
}   #  end of process_monitor_status


#--------------------------------------------------------------------#
# process_active_status: returns the translated text representing    #
#   the description for the Active flag for an association resource. #
#                                                                    #
# Parameters:                                                        #
#   active_status       The active flag value.                       #
#   active_desc_text    The hash of values for the descriptions.     #
#                                                                    #
# Returns:                                                           #
#   active_desc         The description for active_status.           #
#                                                                    #
# Global Variables:                                                  #
#--------------------------------------------------------------------#
sub process_active_status
{
my $active_status = shift(@_);          # active status code
my %active_desc_text = @_;              # hash of text descriptions
my $active_desc = "";                   # active status description
my $found = $FALSE;                     # keep track of when text found

# see if active status to find exists
if (defined $active_desc_text{$active_status}) {
    $found = $TRUE;
}

# translate active status
if ($found) {
   $active_desc = $active_desc_text{$active_status};
   }
else {
   $active_desc = $active_desc_text{"?"};
   }

# add quotes
$active_desc = "\"".$active_desc."\"";

return($active_desc);
}   #  end of process_active_status


#--------------------------------------------------------------------#
# set_orig_rmc_scope : Uses the global varibales set by the ERRM     #
#   command to set the CT_MANAGEMENT_SCOPE environment variable      #
#   to what it was, or wasn't, back when the command started.        #
#                                                                    #
# Parameters:                                                        #
#   None.                                                            #
#                                                                    #
# Returns:                                                           #
#   None.                                                            #
#                                                                    #
# Global Variables:                                                  #
#   $main::Scope_orig_set   was CT_MANAGEMENT_SCOPE originally set   #
#   $main::Scope_orig_value CT_MANAGEMENT_SCOPE original value if set#
#--------------------------------------------------------------------#
sub set_orig_rmc_scope
{

# if CT_MANAGEMENT_SCOPE was originally set, return it to its original
# value. (may already be that value but so what)
if ($main::Scope_orig_set) {
      $ENV{CT_MANAGEMENT_SCOPE} = $main::Scope_orig_value;
}

# else it shouldn't exist.  Make sure it doesn't
else {
   if (defined $ENV{CT_MANAGEMENT_SCOPE}) {
      # get rid of it
      delete $ENV{CT_MANAGEMENT_SCOPE};
   }
}

}   #  end of set_orig_rmc_scope


#--------------------------------------------------------------------#
# check_set_cluster_scope: Checks the scope environment variable     #
#   CT_MANAGEMENT_SCOPE to see if it is set for a cluster operation. #
#   If it is not set, it is set to 4 for DM/SR/local for the next    #
#   rmc session.  If it is set, and it's set to local, then it is    #
#   set to 4 for DM/SR/local for the next rmc session.  It is        #
#   unchanged if it is DM or SR scope.                               #
#                                                                    #
# Parameters:                                                        #
#   None.                                                            #
#                                                                    #
# Returns:                                                           #
#   None.                                                            #
#                                                                    #
#--------------------------------------------------------------------#
sub check_set_cluster_scope
{

# if CT_MANAGEMENT_SCOPE is not defined, set it to 4 for DM/SR/Local scope
if (!defined $ENV{CT_MANAGEMENT_SCOPE}) {
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_DM_SR_LOCAL_SCOPE;
}

# if it's defined, it shouldn't be local.  If it's local, set it
# to 4 for DM/SR/Local scope
else {
   if ($ENV{CT_MANAGEMENT_SCOPE} == $RMC_LOCAL_SCOPE || 
       $ENV{CT_MANAGEMENT_SCOPE} == $RMC_LOCAL2_SCOPE) {
      $ENV{CT_MANAGEMENT_SCOPE} = $RMC_DM_SR_LOCAL_SCOPE;
   }
}

}   #  end of check_set_cluster_scope


#--------------------------------------------------------------------#
# getIMsg : calls $LSMSG to print out the message with the           #
#   required parameters, like printIMsg, except the message is       #
#   returned instead of printed.  Used for NLS.                      #
#                                                                    #
# Parameters:                                                        #
#   msg       in  Message mnemonic / message number in a sense.      #
#   optargs   in  Extra arguments/parameters to send to LSMSG.       #
#                                                                    #
# Returns:                                                           #
#   msgtext   out Array of messages.                                 #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace    in  Print extra info when trace is on.           #
#   $main::PROGNAME in  Calling program/command for error message.   #
#   $main::LSMSG    in  Path & Command to display messages.          #
#   $main::MSGCAT   in  The calling commands Message catalogue.      #
#--------------------------------------------------------------------#
sub getIMsg
{
my ($msg, @optargs) = @_;
my ($optarg, $optargs);
my @msgtext = ();

$main::Trace &&
    print STDERR "$main::LSMSG $main::PROGNAME $main::MSGCAT $msg @optargs\n";

# Keep the args to LSMSG separate by separating with single quotes
# but must replace internal single quotes with blanks or get an error.
# Must escape internal double quotes for the system call.
foreach $optarg (@optargs) {
    $optarg =~ s/'/ /g;
    $optarg =~ s/"/\\"/g;
}
$optargs = "'" . join("' '",@optargs) . "'";

if (scalar @optargs > 0) {
     @msgtext = `$main::LSMSG $main::PROGNAME $main::MSGCAT $msg $optargs`;
}
else {
     @msgtext = `$main::LSMSG $main::PROGNAME $main::MSGCAT $msg`;
}

return (@msgtext);
}   # end getIMsg


#--------------------------------------------------------------------#
# process_exit_code: returns 0, the signal exit code, or the process #
#   exit code from the called process. This is used to examine the   #
#   exit codes from perl uses for called processes.                  # 
#   The exit value of the subprocess is in the high byte (>>8)       #
#   The low byte has the signal the process died from (if any)(& 127)#
#   To be complete, core dumps are indicated with (& 128) (not used) #
#                                                                    #
# Parameters:                                                        #
#   exit_code           The exit code to be examined.                #
#                                                                    #
# Returns:                                                           #
#   process_exit_code   0, signal, or process exit code.             #
#                                                                    #
# Global Variables:                                                  #
#--------------------------------------------------------------------#
sub process_exit_code
{
my $exit_code = shift(@_);              # the exit code to check
my $process_signal_exit_code = 0;       # signal exit code, if any
my $process_exit_code = 0;              # what to return

# if it's 0, wonderful.
if ($exit_code == 0) { return (0);};

# check for signal process died from, if any
$process_signal_exit_code = $exit_code & 127;

# if there was a signal, return it
if ($process_signal_exit_code > 0) { 
    printCEMsg("EMsgERRMcliUnExpectRMCrc",$process_signal_exit_code);
    return ($process_signal_exit_code);
}

# otherwise return the process exit code
$process_exit_code = $exit_code >> 8;
return ($process_exit_code);
}   # end process_exit_code


#--------------------------------------------------------------------#
# process_api_error - Scans the input varaible for error messages    #
#   found by the c-api command. The c-api command errors are         #
#   found by searching each output line for "ERROR" at the           #
#   beginning of the line.  The error message printed is the last    #
#   double colon delimited string.                                   #
#   Resource not found errors (rc=6) are not printed.                #
#                                                                    #
# Parameters:                                                        #
#   $delimiter        The delimiter used in the error string.        #
#   $rc               The return code from the c-api call.           #
#   @command_output   The output from the command.                   #
#                                                                    #
# Returns:                                                           #
#   None.                                                            #
#                                                                    #
# Global Variables:                                                  #
#--------------------------------------------------------------------#
sub process_api_error
{
my $delimiter = shift(@_);              # output delimiter
my $api_rc    = shift(@_);              # rc from c-api call
my @command_output = @_;                # command output to scan
my $error_count = 0;                    # number of error messages

# scan each line for ERROR
foreach $line (@command_output) {
   
   # does it start with ERROR?
   if ($line =~ /^ERROR.*/) {

      # split it apart based on double colons
      # last one should be error message
      @error_parts = split /$delimiter/, $line;

      if ($error_parts[2] != $RMC_CLI_RSRC_NOT_FOUND) {

         # replace any escaped new lines with new lines
         $error_parts[$#error_parts] =~ s/\\n/\n/g;

         # get rid of any beginning/ending quote that comes from
         # having CT_CLI_QUOTE_STRING turned on (sometimes)
         if ( defined $ENV{CT_CLI_QUOTE_STRING} && $ENV{CT_CLI_QUOTE_STRING}==1) {

            $error_parts[$#error_parts] =~ s/^\"//;
            $error_parts[$#error_parts] =~ s/\"$//;
            #$error_parts[$#error_parts] =~ s/\\\"/\"/g;
            $error_parts[$#error_parts] = unescape_chars($error_parts[$#error_parts]);
         }

         # last one should be error message. print it to STDERR.
         print STDERR $error_parts[$#error_parts];
         $error_count++;
      }
      else {    # rc=resource not found, count that
         $error_count++;
      }
   }
}

# print unexpected error if api rc was not 0 and no messages were displayed
if (($error_count == 0) && ($api_rc != 0)) {
   printCEMsg("EMsgERRMcliUnExpectRMCrc",$api_rc);
}
}   #  end of process_api_error 


#--------------------------------------------------------------------#
# remove_api_error - Scans the input varaible for error messages     #
#   found by the c-api command. The c-api command errors are         #
#   found by searching each output line for "ERROR" at the           #
#   beginning of the line.  An array is returned that is the same as #
#   the input array except that the error messages are removed.      #
#                                                                    #
# Parameters:                                                        #
#   @command_output   The output from the command.                   #
#                                                                    #
# Returns:                                                           #
#   @errorless_output The original @command_output array contents    #
#                     with the errors removed.                       #
#                                                                    #
# Global Variables:                                                  #
#--------------------------------------------------------------------#
sub remove_api_error
{
my @command_output = @_;                # command output to scan
my @errorless_output = ();              # errors removed

# scan each line for ERROR
foreach $line (@command_output) {

   # does it start with ERROR?
   if (!($line =~ /^ERROR.*/)) {

      # put it in the errorless array
      push @errorless_output, $line;
   }
}

return (@errorless_output);
}   #  end of remove_api_error


#--------------------------------------------------------------------#
# escape_selstr:                                                     #
#   Scans a to-be select string respecting multibyte encodings to    #
#   add SQL escapes (#) escapes for %, #, and _ characters so they   #
#   are not interpretted by SQL processing as special characters in  #
#   an rmc select string.                                            #
#                                                                    #
# Paramaters:                                                        #
#   $string_in      string to check for any needed SQL escapes.      #
#                                                                    #
# Returns:                                                           #
#   $string_out     result.                                          #
#                                                                    #
#--------------------------------------------------------------------#
sub escape_selstr
{
use POSIX;
use POSIX qw(:stdlib_h);
use POSIX qw(mblen);
my $string_in = shift(@_);
my $string_in2 = "";
my $string_out = "";
my $lenstring = 0;
my $lenchar = 0;

# get the length of the prospective select string
$lenstring = length($string_in);

# if there are no %,#,_, skip over checking char-by-char
if ($string_in =~ /.*[%#_].*/) {

   for (my $i=0; $i<$lenstring; $i+=$lenchar) {

      # form the string of where we're at
      $string_in2 = substr($string_in,$i);

      # determine if this is a multibyte encoding (mblen>1)
      $lenchar = mblen ($string_in2, MB_CUR_MAX);

      # if it's length is less than 1, treat it as 1 character
      if (!$lenchar >= 1) { $lenchar = 1;}

      # if it's not multibyte and it's a backslash, escape it
      if ( ($lenchar == 1) && ($string_in2 =~ /^[%#_]/) ) {
         $string_out .= "#" . substr($string_in2,0,1);
      }

      # otherwise, just take it as it is
      else {$string_out .= substr($string_in2,0,$lenchar);}

   }

}

# it doesn't have any characters we're worried about so take it as is
else {$string_out = $string_in;}

return ($string_out);
}   # end escape_selstr


#--------------------------------------------------------------------#
# in_cluster : Returns true if in a cluster environment, false if    #
#   not.                                                             #
#                                                                    #
# Parameters:                                                        #
#   None.                                                            #
#                                                                    #
# Returns:                                                           #
#   1 (true)         if in a cluster                                 #
#   0 (false)        if not in a cluster                             #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace    in  Print extra info when trace is on.           #
#   $main::PROGNAME in  Calling program/command for error message.   #
#--------------------------------------------------------------------#
sub in_cluster
{
my @listout = ();
my $trace_opt = "";
my $local_node = "";
my $rc = 0;
my $scope_val = 0;
my $incluster = $FALSE;

# get the node name 
$local_node = &get_source_node;

$main::Trace && print STDERR "$main::PROGNAME: calling lsrsrc-api\n";
$main::Trace && ($trace_opt = " -T ");

# set local scope to find the node we need 
$ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;

# get the ActiveMgtScopes attribute 
@listout = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s IBM.Host${DELIMITERI}\"Name==\\\"$local_node\\\"\"${DELIMITERI}${DELIMITERI}${DELIMITERI}ActiveMgtScopes 2>&1`;
$rc = $?;
$rc = &process_exit_code($rc);
$main::Trace && print STDERR "lsrsrc-api results:\n";
$main::Trace && print STDERR "@listout";
$main::Trace && print STDERR "$main::PROGNAME: lsrsrc-api returned $rc\n";

# if there was an error, continue on as if nothing happened
# but assume that we're in a cluster so nodename is shown in output
if ($rc != 0) {
    $incluster = $TRUE; 
}

# else it worked ok 
else {
   
   # get the scope value 
   $scope_val = $listout[0];

   # scope >1 means there's a cluster
   if ($scope_val > 1) { $incluster = $TRUE; }
   else { $incluster = $FALSE;}
}

return ($incluster);
}   #  end of in_cluster


#--------------------------------------------------------------------#
# End Exported Subroutines (with @EXPORT_OK, -> on demand).          #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# End File.                                                          #
#--------------------------------------------------------------------#
