#!/usr/bin/perl # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 2001,2020 # 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 # sccsid = "@(#)70 1.14.1.22 src/rsct/rm/ER/cli/bin/lscondresp.perl, errmcli, rsct_rady, rady2035a 3/27/20 03:20:49" ###################################################################### # # # Module: lscondresp # # # # Purpose: # # lscondresp - list one or more conditions with linked responses. # # # # Current Syntax: # # lscondresp [-h] [-a|-n] [-l|-t|-d|-D Delimiter] [-z] # # [-q] [-x] [-U] [-TV] [Condition[:Node_name] [Response # # [Response...]]] # # # # lscondresp [-h] [-a|-n] [-l|-t|-d|-D Delimiter] # # [-q] [-x] -r [-U] [-TV] Response [Response...][:Node_name] # # # # Flags: # # -a Lists only those responses that are active for the # # condition. # # -d Delimiter-formatted output. The default delimiter is a # # colon (:). Use the -D flag if you wish to change the # # default delimiter. # # -D Delimiter # # Delimiter-formatted output that uses the specified # # delimiter. Use this flag to specify something other # # than the default colon (:). An example is when the data # # to be displayed contains colons. Use this flag to # # specify a delimiter of one or more characters. # # -h Help. Writes this command's usage statement to stdout. # # -l Long formatted output. The condition information is # # displayed on separate lines. # # -n Lists only those responses that are not active for # # the condition. # # -z All. List condition information for all nodes in the # # cluster. # # -q Quiet. Does not return an error when the Condition # # specified does not exist. # # -r Indicates that all command parameters are responses. # # No conditions are specified. This flag causes the # # command to list all linke condition-response information # # for the specified responses. # # -t Tabular formatted output. The condition information is # # displayed in separate columns. # # -U Displays whether the resource is locked or not # # -T Trace. IBM Support Center use only. # # -V Verbose. # # -x Exlude header. Suppress header printing. # # # # Parameters: # # Condition The name of the condition linked to the # # response. The condition is always specified # # first unless the -r flag is used. Node_name # # specifies where the condition is defined. # # Response The name of a response. The links from the # # specified responses to the specified condition # # are displayed. Node_name specifies where the # # response is defined. # # # # Description: # # The lscondresp command lists information about a condition and # # its linked responses. The information shows what responses are # # linked with a condition and whether monitoring is active for a # # condition and its linked response. # # # # Exit Values: # # 0 ERRM_CLI_SUCCESS Command completed successfully. # # 1 ERRM_CLI_RMC_ERROR Command terminated due to an underlying # # RMC error. # # 2 ERRM_CLI_ERROR Command terminated due to an underlying # # error in the command script. # # 3 ERRM_CLI_BAD_FLAG Command terminated due to user # # specifying an invalid flag. # # 4 ERRM_CLI_BAD_OPERAND Command terminated due to user # # specifying a bad operand. # # 5 ERRM_CLI_USER_ERROR Command terminated due to a user error. # # For example specifying a name that # # already exists. # # # # Examples: # # 1. To list information about all conditions with linked # # responses, type: # # lscondresp # # Output is similar to: # # Displaying condition with response information: # # Condition Response State # # "JFS space used up" "Broadcast event on-shift" "Active" # # "JFS space used up" "E-mail root anytime" "Not active" # "Page in Rate" "Log event anytime" "Active" # # # # 2. To list information in tabular format about the condition # # "JFS space used up" with the linked response # # "Broadcase event on-shift", type: # # lscondresp -t "JFS space used up" "Broadcast event on-shift"# # Output is similar to: # # Displaying condition with response information: # # Condition Response State # # "JFS space used up" "Broadcast event on-shift" "Active" # # # # 3. To list information about the condition "JFS space used up", # # type: # # lscondresp "JFS space used up" # # Output is similar to: # # Display condition with response information: # # condition-response link 1: # # Condition = "JFS space used up" # # Response = "Broadcase event on-shift" # # State = "Active" # # condition-response link 2: # # Condition = "JFS space used up" # # Response = "E-mail root anytime" # # State = "Not active" # # # # Man Page: # # For the most current detailed description of this command see # # the lscondresp man page in /opt/rsct/man. # # # #--------------------------------------------------------------------# # Inputs: # # /opt/rsct/msgmaps/errmcli.lscondresp.map - message mapping # # # # Outputs: # # stdout - display information on the condition-response links. # # stderr - any error message. # # # # External Ref: # # Commands: ctdspmsg # # Modules: ERRM_cli_utils.pm, ERRM_cli_rc.pm # # CT_cli_utils.pm # # Extensions: MC.pm, MCerr.pm, CT.pm # # Perl library routines: Getopt::Std # # # # Tab Settings: # # 4 and tabs should be expanded to spaces before saving this file. # # in vi: (:set ts=4 and :%!expand -4) # # # # Change Activity: # # 010125 GTM 67471: Initial design & write. # # 010212 GTM 71293: Enhance -TV processing. # # 010222 JAC 71460: Replace LIKE with ?= in selection string. # # 010226 JAC 71382: Quiet flag (-q) should exit with 0 when name # # not found and error should be user error. # # 010227 JAC 71402: Remove extra quotes in -C display header. # # 010305 JAC 71362: Make display flag precedence C,l,t,d,D. # # 010308 JAC 72121: Change selecetion string to work for quotes. # # 010311 JAC 72226: Correct -d,-D precedence (-d overrides). # # 010507 JAC 73620: Check for RMC CLI user error (rc=5) and # # return ERRM user error for this case. # # 011120 JAC 77597: Distributed RMC. Check for node locator. # # 011206 JAC 78841: Fix selection string for locating resources. # # 020121 JAC 79558: Fix selection string for locating resources. # # 020207 JAC 71888: Add verbose messages to message file. # # 020208 JAC 71728: Add NLS support for headers and xlating values.# # 020215 JAC 78996: Add nodename column for clusters. # # 020220 JAC 80472: Remove matching NodeNameList for cond/resp. # # 020221 JAC 80506: Allow for multiple locators (sep by commas). # # 020305 JAC 80805: Fix to continue if partial output from lsrsrc. # # 020417 JAC 81754: Use xxx-api where possible. # # 020424 JAC 81488: Change how if in cluster is determined. # # 020523 JAC 83318: If location displayed, use 1st NodeNameList val# # 020603 JAC 83363: Save environment before calling in_cluster. # # 020719 JAC 84425: Add $rc to process_api_error call. # # 020730 JAC 85061: Use 4 (DM/SR/local) for scope if locator used # # or -a used and scope not set. -a is new. # # 040211 JAC 103750: Add -U flag to show Locked attribute. # # 040428 JAC 108194: Use escape_selstr for condition and response # # names and use LIKE in select string. # # 071026 JAC 146726: set delimiter for -api calls. # ###################################################################### #------------------------------------------------------------------- ###################################################################### #--------------------------------------------------------------------# # General Program Flow/Logic: # # # # A. Parse command line flags and operands, determine which flavor # # of this command we are actually invoking. # # This command allows a user to list defined condition-response # # links. # # - print usage if -h specified # # - set $Opt variables according to flags specified # # B. Call RMC command lsrsrc. Also pass along -TV if necessary. # # - call lsrsrc to get condition data # # - if no condition names provided as input get all defined # # conditions # # - otherwise get data only for the specified condition # # - exit w/error if no conditions found # # - call lsrsrc to get response data # # - if no response names provided as input get all defined # # responses # # - otherwise get data only for specified responses # # - exit w/error if no responses found # # - call lsrsrc to get all condition-response links # # - exit w/error if no links found # # C. Do post processing on raw lsrsrc output. # # - put condition, response, and condition-response links data # # into 2D arrays for post-processing # # - while loading c-r data into array, skip lines whose # # active flag does not match setting of -a/-n flags # # - compare condition handle of each c-r link with condition(s) # # found; replace matching condition handle with condition name # # - compare response handle of each c-r link with response(s) # # found; replace matching response handle with response name # # - if neither conditions or responses matched at least one c-r # # link, exit with error # # - if no c-r links matched both condition and response handles # # exit with error # # D. Format and display output. # # - if at least one condition-response link's worth of output was # # obtained, execute display code # # - otherwise call CT_cli_display_utils::set_display to format # # and display output # # # #--------------------------------------------------------------------# #--------------------------------------------------------------------# # Included Libraries and Extensions # #--------------------------------------------------------------------# use lib "/opt/rsct/pm"; use locale; use Getopt::Std; use CT_cli_utils qw(printIMsg printEMsg); use CT_cli_display_utils qw(set_display); use ERRM_cli_rc qw(ERRM_CLI_SUCCESS ERRM_CLI_RMC_ERROR ERRM_CLI_ERROR ERRM_CLI_BAD_FLAG ERRM_CLI_BAD_OPERAND ERRM_CLI_USER_ERROR); use ERRM_cli_utils qw(error_exit printCIMsg printCEMsg get_locator_node getIMsg escape_selstr process_active_status process_api_error process_exit_code remove_api_error in_cluster set_orig_rmc_scope check_set_cluster_scope $CTDIR $CTBINDIR $SEVCRIT $SEVWARN $SEVINFO $GARBAGE $MKCNDCRIT $MKCNDWARN $MKCNDINFO $DELIMITERI $DELIMITERO $RMC_CLI_USER_ERROR $RMC_CLI_RSRC_NOT_FOUND $LSNOTFND $LSRSRC $RSCCOND $RSCEVRS $RSCASSC); #--------------------------------------------------------------------# # Global Constants # #--------------------------------------------------------------------# # lsrsrc attribute names $Attr_Name = "Name"; $Attr_Node = "NodeNameList"; $Attr_Cond_RH = "ConditionHandle"; $Attr_Resp_RH = "EventResponseHandle"; $Attr_Active_Flag = "ActiveFlag"; $Attr_Rsrc_Hndl = "ResourceHandle"; $Attr_Locked = "Locked"; # output titles #$Cond_Title = "Condition"; #$Resp_Title = "Response"; #$State_Title = "State"; # raw ActiveFlag values $not_active = 0; $active = 1; # Active display strings #$not_act_str = "Not active"; #$act_str = "Active"; #--------------------------------------------------------------------# # Global Variables # #--------------------------------------------------------------------# $TRUE = 1; $FALSE = 0; $Scope_orig_set = $FALSE; # default - no CT_MANAGEMENT_SCOPE $Scope_orig_value = 0; # default - scope value $Trace = $FALSE; # default - trace off # -T flag $Verbose = $FALSE; # default - verbose turned off # -V flag $Opt_Active = $TRUE; # default - show active links # -a flag $Opt_Mkcondresp_Ex = $FALSE; # default - do not display # mkcondresp example # -C flag $Opt_Delm_Format = $FALSE; # default - no delimited output # -d, -D flags $Opt_Delm_Str = ":"; # default - delimiter character # can be overridden with -D flag $Opt_Long_Format = $TRUE; # default - long formatted output $Opt_Not_Active = $TRUE; # default - show inactive links # -n flag $Opt_Quiet = $FALSE; # default - do not supress display # of error when non-existent # condition is specified # -q flag $Opt_Only_Resps = $FALSE; # default - parameters if given # are of the form: # Condition [Response [Response...]] $Opt_Table_Format = $FALSE; # default - do not display in # tabular format # -t flag $Opt_No_HDR = $FALSE; # default - do not supress heading # output # -x flag $Opt_All_Nodes = $FALSE; # default - cluster display $Opt_Show_Locked = $FALSE; # default - don't show Locked $PROGNAME = "lscondresp"; # Program Name for messages $MSGCAT = "errmcli.cat"; # msg catalogue for this cmd #$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 #--------------------------------------------------------------------# # Variables # #--------------------------------------------------------------------# $sARGV = 0; # size of @ARGV #$lsr_opts = " -xd"; # format options for lsrsrc $lsr_dbg_opts = ""; # trace/verbose opts for lsrsrc $in_cond = ""; # condition name from input $in_cond_orig = ""; # condition name from input @in_resps = (); # response names from input @Lof_conds = (); # 2D array of condition data @Lof_resps = (); # 2D array of response data @Lof_links = (); # 2D array of cond-resp links # -this will also do double duty # as output array $locator = ""; # where to look for the resources $temp_name = ""; # hold resource name my @heading = (); # heading for the listed data my @divider = (); # text for the divider in long format my @actstatustext = (); # text to use for active status my %actstatus = (); # hash for active status descriptions my $act_cnt = 0; # loop counter my @lockedstatustext = (); # text to use for locked status my @tmp_output = (); # lsclcfg output my $cluster_env = $FALSE; # in a cluster? my $junk = ""; # for garbage #--------------------------------------------------------------------# #--------------------------------------------------------------------# # Main Code # #--------------------------------------------------------------------# #--------------------------------------------------------------------# my $rc = 0; my $rmc_rc = 0; # 71382 my $errmcli_rc = 0; # # parse the command line, exit if there are errors # # if no cmdline args, force -t #unless (scalar(@ARGV)) { $Opt_Table_Format = $TRUE; } ($rc) = &parse_cmd_line; ($rc == 0) || error_exit($rc); if ($Verbose) { printIMsg("IMsglscondrespStart51D");} # save original rmc management scope value, in case it's changed later if (defined $ENV{CT_MANAGEMENT_SCOPE}) { $Scope_orig_set = $TRUE; $Scope_orig_value = $ENV{CT_MANAGEMENT_SCOPE}; } # decide if in cluster or not. if in cluster, get NodeNameList if (in_cluster) { $cluster_env = $TRUE; } # set CT_MANAGEMENT_SCOPE to original setting, in case it was used set_orig_rmc_scope; # # call lsrsrc based on input data # my $lsr_lnk_attrs = ""; my $lsr_cr_attrs = ""; my $lsr_selstr = ""; my $resp_name = ""; my $resp_name_orig = ""; my @tmp_lsr_output = (); # handle debug options if ($Trace || $Verbose) { $lsr_dbg_opts = $lsr_dbg_opts." -"; } if ($Trace) { $lsr_dbg_opts = $lsr_dbg_opts."T"; } if ($Verbose) { $lsr_dbg_opts = $lsr_dbg_opts."V"; } # build attr names to be passed to lsrsrc to get links $lsr_lnk_attrs = $Attr_Cond_RH; $lsr_lnk_attrs .= "${DELIMITERI}" . $Attr_Resp_RH; if ($cluster_env) { $lsr_lnk_attrs .= "${DELIMITERI}" . $Attr_Node; } $lsr_lnk_attrs .= "${DELIMITERI}" . $Attr_Active_Flag; if ($Opt_Show_Locked) { $lsr_lnk_attrs .= "${DELIMITERI}" . $Attr_Locked; } # build attr names to be passed to lsrsrc to get conds/resps $lsr_cr_attrs = $Attr_Rsrc_Hndl; $lsr_cr_attrs .= "${DELIMITERI}" . $Attr_Name; if ($cluster_env) { $lsr_cr_attrs .= "${DELIMITERI}" . $Attr_Node; } # determine the locator, if one exists # check the response for locator. name must exist if ($Opt_Only_Resps) { # extract a locator from the last response ($temp_name, $locator) = get_locator_node($in_resps[$#in_resps]); # put back response name without locator if ($locator ne "") { $in_resps[$#in_resps] = $temp_name; } } else { # check condition for locator. condition optional # extract a locator from the condition ($temp_name, $locator) = get_locator_node($in_cond); # put back condition name without locator if ($locator ne "") { $in_cond = $temp_name; } } # if there are multiple locators, add some quotes $locator =~ s/,/\\\",\\\"/g; # if no cmdline args, force -t if (($in_cond eq "") && ($#in_resps < 0)) { $Opt_Table_Format = $TRUE; } # set selection string template #$lsr_selstr = "-s 'Name ?= " . "\"ERRMCLI\"" . "'"; #$lsr_selstr = "-s ${RSCCOND}${DELIMITERI}\"Name?=\\\"ERRMCLI\\\"\""; $lsr_selstr = "-s ${RSCCOND}${DELIMITERI}\"Name LIKE \\\"ERRMCLI\\\"\""; # check to see if the node locator is needed if ($locator ne "") { # $lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; # $lsr_selstr = "-s ${RSCCOND}${DELIMITERI}\"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; $lsr_selstr = "-s ${RSCCOND}${DELIMITERI}\"Name LIKE \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; } # set cluster scope if locator used or -z used if ( ($locator ne "") || ($Opt_All_Nodes) ) { check_set_cluster_scope; } # call lsrsrc to get condition data if ($Trace) {print STDERR "$PROGNAME: calling $LSRSRC to get condition data\n";} if ($in_cond) { # condition given as input $in_cond_orig = $in_cond; $in_cond = escape_selstr($in_cond); # $lsr_selstr =~ s/ERRMCLI/$in_cond/; $lsr_selstr =~ s/ERRMCLI/%${in_cond}%/; } else { # if ($locator ne "") { $lsr_selstr = "-s \"NodeNameList|<{\\\"$locator\\\"}\"";} if ($locator ne "") { $lsr_selstr = "-s ${RSCCOND}${DELIMITERI}\"NodeNameList|<{\\\"$locator\\\"}\"";} # else { $lsr_selstr = "";} else { $lsr_selstr = "-o ${RSCCOND}";} } #@Lof_conds = `$CTBINDIR/$LSRSRC $lsr_selstr $lsr_opts $lsr_dbg_opts $RSCCOND $lsr_cr_attrs`; $ENV{CT_CLI_QUOTE_STRING} = 1; @Lof_conds = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO ${lsr_selstr}${DELIMITERI}${DELIMITERI}${DELIMITERI}${lsr_cr_attrs} 2>&1`; $rmc_rc = $?; $rmc_rc = &process_exit_code($rmc_rc); if ($Trace) { print STDERR "lsrsrc-api results:\n"; print STDERR "@Lof_conds"; print STDERR "$PROGNAME: lsrsrc-api returned $rmc_rc\n"; } # show any errors if there was a bad rc except for not found if ($rmc_rc != 0) { process_api_error($DELIMITERO,$rc,@Lof_conds); } # remove the error messages @Lof_conds = remove_api_error(@Lof_conds); # return ERRM CLI user error if it's an RMC CLI user error 73620 if ($rmc_rc == $RMC_CLI_USER_ERROR) { $errmcli_rc = ERRM_CLI_USER_ERROR; } # check for other things else { # save any other RMC CLI error if (($rmc_rc != 0) && ($rmc_rc != $RMC_CLI_RSRC_NOT_FOUND)) { $errmcli_rc = ERRM_CLI_RMC_ERROR; } } chomp(@Lof_conds); unless (scalar(@Lof_conds)) { # no output from lsrsrc if ($rmc_rc == $RMC_CLI_RSRC_NOT_FOUND) { if ($in_cond) { unless ($Opt_Quiet) { printEMsg("EMsglscondrespConditionNotFound", $in_cond_orig); $errmcli_rc = ERRM_CLI_USER_ERROR; # 71382 } } else { unless ($Opt_Quiet) { printEMsg("EMsglscondrespNoCondsDefined"); # $errmcli_rc = ERRM_CLI_USER_ERROR; # 71382 $errmcli_rc = 0; # 100936 } } } exit($errmcli_rc); } if ($Trace) {print STDERR "$PROGNAME: $LSRSRC returned condition data\n";} # reset selection string #$lsr_selstr = "-s 'Name ?= " . "\"ERRMCLI\"" . "'"; #$lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\"\""; #$lsr_selstr = "-s ${RSCEVRS}${DELIMITER}\"Name?=\\\"ERRMCLI\\\"\""; $lsr_selstr = "-s ${RSCEVRS}${DELIMITERI}\"Name LIKE \\\"ERRMCLI\\\"\""; # check to see if the node locator is needed if ($locator ne "") { # $lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; # $lsr_selstr = "-s ${RSCEVRS}${DELIMITER}\"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; $lsr_selstr = "-s ${RSCEVRS}${DELIMITERI}\"Name LIKE \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; } # issue lsrsrc command for each response provided as input if ($Trace) {print STDERR "$PROGNAME: calling $LSRSRC to get response data\n";} if (scalar(@in_resps)) { foreach $resp_name (@in_resps) { $resp_name_orig = $resp_name; $resp_name = escape_selstr($resp_name); # $lsr_selstr =~ s/ERRMCLI/$resp_name/; $lsr_selstr =~ s/ERRMCLI/%${resp_name}%/; # @tmp_lsr_output = `$CTBINDIR/$LSRSRC $lsr_selstr $lsr_opts $lsr_dbg_opts $RSCEVRS $lsr_cr_attrs`; $ENV{CT_CLI_QUOTE_STRING} = 1; @tmp_lsr_output = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO ${lsr_selstr}${DELIMITERI}${DELIMITERI}${DELIMITERI}${lsr_cr_attrs} 2>&1`; $rmc_rc = $?; $rmc_rc = &process_exit_code($rmc_rc); if ($Trace) { print STDERR "lsrsrc-api results:\n"; print STDERR "@tmp_lsr_output"; print STDERR "$PROGNAME: lsrsrc-api returned $rmc_rc\n"; } # show any errors if there was a bad rc except for not found if ($rmc_rc != 0) { process_api_error($DELIMITERO,$rc,@tmp_lsr_output); } # remove the error messages @tmp_lsr_output = remove_api_error(@tmp_lsr_output); # if lsrsrc command failed due to RMC CLI user error 73620 # set ERRM CLI user error and go to next response if ($rmc_rc == $RMC_CLI_USER_ERROR) { $errmcli_rc = ERRM_CLI_USER_ERROR; } # check for other things else { # save any other RMC CLI error if (($rmc_rc != 0) && ($rmc_rc != $RMC_CLI_RSRC_NOT_FOUND)) { $errmcli_rc = ERRM_CLI_RMC_ERROR; } } unless (scalar(@tmp_lsr_output)) { if ($rmc_rc == $RMC_CLI_RSRC_NOT_FOUND) { # this response was not defined unless ($Opt_Quiet) { printEMsg("EMsglscondrespResponseNotFound", $resp_name_orig); $errmcli_rc = ERRM_CLI_USER_ERROR; # 71382 } } next; } chomp(@tmp_lsr_output); push(@Lof_resps, @tmp_lsr_output); # $lsr_selstr = "-s 'Name ?= " . "\"ERRMCLI\"" . "'"; # $lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\"\""; # $lsr_selstr = "-s ${RSCEVRS}::\"Name?=\\\"ERRMCLI\\\"\""; $lsr_selstr = "-s ${RSCEVRS}${DELIMITERI}\"Name LIKE \\\"ERRMCLI\\\"\""; # check to see if the node locator is needed if ($locator ne "") { # $lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; # $lsr_selstr = "-s ${RSCEVRS}::\"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; $lsr_selstr = "-s ${RSCEVRS}${DELIMITERI}\"Name LIKE \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\""; } } unless (scalar(@Lof_resps)) { if ($errmcli_rc == 0) { # none of the given responses were defined unless ($Opt_Quiet) { printEMsg("EMsglscondrespNoInputRespsFound"); $errmcli_rc = ERRM_CLI_USER_ERROR; # 71382 } } exit($errmcli_rc); } } else { # no responses given as input, so get all defined responses $lsr_selstr = ""; # check to see if the node locator is needed if ($locator ne "") { # $lsr_selstr = "-s \"NodeNameList|<{\\\"$locator\\\"}\""; $lsr_selstr = "-s ${RSCEVRS}${DELIMITERI}\"NodeNameList|<{\\\"$locator\\\"}\""; } else { $lsr_selstr = "-o ${RSCEVRS}";} # @Lof_resps = `$CTBINDIR/$LSRSRC $lsr_selstr $lsr_opts $lsr_dbg_opts $RSCEVRS $lsr_cr_attrs`; $ENV{CT_CLI_QUOTE_STRING} = 1; @Lof_resps = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO ${lsr_selstr}${DELIMITERI}${DELIMITERI}${DELIMITERI}${lsr_cr_attrs} 2>&1`; $rmc_rc = $?; $rmc_rc = &process_exit_code($rmc_rc); if ($Trace) { print STDERR "lsrsrc-api results:\n"; print STDERR "@Lof_resps"; print STDERR "$PROGNAME: lsrsrc-api returned $rmc_rc\n"; } # show any errors if there was a bad rc except for not found if ($rmc_rc != 0) { process_api_error($DELIMITERO,$rc,@Lof_resps); } # remove the error messages @Lof_resps = remove_api_error(@Lof_resps); if ($rmc_rc == $RMC_CLI_USER_ERROR) { $errmcli_rc = ERRM_CLI_USER_ERROR; } # check for other things else { # save any other RMC CLI error if (($rmc_rc != 0) && ($rmc_rc != $RMC_CLI_RSRC_NOT_FOUND)) { $errmcli_rc = ERRM_CLI_RMC_ERROR; } } chomp(@Lof_resps); unless (scalar(@Lof_resps)) { if ($errmcli_rc == 0) { # no responses defined on system unless ($Opt_Quiet) { printEMsg("EMsglscondrespNoRespsFound"); $rc = ERRM_CLI_USER_ERROR; # 71382 } } exit($errmcli_rc); } } if ($Trace) {print STDERR "$PROGNAME: $LSRSRC returned response data\n";} # now get all links defined between conditions and responses if ($Trace) {print STDERR "$PROGNAME: calling $LSRSRC to get condition-response data\n";} $lsr_selstr = ""; # check to see if the node locator is needed if ($locator ne "") { # $lsr_selstr = "-s \"NodeNameList|<{\\\"$locator\\\"}\""; $lsr_selstr = "-s ${RSCASSC}${DELIMITERI}\"NodeNameList|<{\\\"$locator\\\"}\""; } else { $lsr_selstr = "-o ${RSCASSC}";} #@Lof_links = `$CTBINDIR/$LSRSRC $lsr_selstr $lsr_opts $lsr_dbg_opts $RSCASSC $lsr_lnk_attrs`; $ENV{CT_CLI_QUOTE_STRING} = 1; @Lof_links = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO ${lsr_selstr}${DELIMITERI}${DELIMITERI}${DELIMITERI}${lsr_lnk_attrs} 2>&1`; $rmc_rc = $?; $rmc_rc = &process_exit_code($rmc_rc); if ($Trace) { print STDERR "lsrsrc-api results:\n"; print STDERR "@Lof_links"; print STDERR "$PROGNAME: lsrsrc-api returned $rmc_rc\n"; } # show any errors if there was a bad rc except for not found if ($rmc_rc != 0) { process_api_error($DELIMITERO,$rc,@Lof_links); } # remove the error messages @Lof_links = remove_api_error(@Lof_links); # return ERRM CLI user error if it's an RMC CLI user error 73620 if ($rmc_rc == $RMC_CLI_USER_ERROR) { $errmcli_rc = ERRM_CLI_USER_ERROR; } # check for other things else { # save any other RMC CLI error if (($rmc_rc != 0) && ($rmc_rc != $RMC_CLI_RSRC_NOT_FOUND)) { $errmcli_rc = ERRM_CLI_RMC_ERROR; } } chomp(@Lof_links); unless (scalar(@Lof_links)) { if ($errmcli_rc == 0) { # no condition-response links defined on system unless ($Opt_Quiet) { if( ($rmc_rc = $RMC_CLI_RSRC_NOT_FOUND) && ($in_cond ne "") ) { # 100936 $errmcli_rc = ERRM_CLI_USER_ERROR; # 71382 } printEMsg("EMsglscondrespNoLinksFound"); } } exit($errmcli_rc); } if ($Trace) {print STDERR "$PROGNAME: $LSRSRC returned condition-response data\n";} # # post-process raw lsrsrc oputput # if ($Trace) {print STDERR "$PROGNAME: formatting data for display\n";} my $i = 1; my $j = 1; my $cond_match = $FALSE; my $resp_match = $FALSE; my $act_idx = 2; my $locked_idx = 3; if ($cluster_env) { $act_idx = 3; $locked_idx = 4; } my $line = ""; my $attr_val = ""; my $attr_name = ""; my @attr_vals = ""; #my @attr_names = ( $Cond_Title, $Resp_Title, $State_Title); my @attr_names = (); my @temp_arr = (); my @uheading = (); # get heading from message file if ($cluster_env) { @heading = getIMsg("IMsglscondrespCHeading"); } else { @heading = getIMsg("IMsglscondrespHeading"); } # see if Locked heading is needed if ($Opt_Show_Locked) { @uheading = getIMsg("IMsglscondrespUHeading"); $heading[0] .= "::" . $uheading[0]; # also fill in text to use while we're here # get from message file what to use for locked status @lockedstatustext = getIMsg("IMsglscondrespNoYes"); @lockedstatustext = split(/::/,$lockedstatustext[0]); } # form the heading @attr_names = split(/::/,$heading[0]); # get the divider text in case it's needed @divider = getIMsg("IMsglscondrespDivider"); # get from message file what to use for active status @actstatustext = getIMsg("IMsglscondrespActStatus"); @actstatustext = split(/::/,$actstatustext[0]); # fill in the hash for active status for ($act_cnt=0;$act_cnt<=$#actstatustext;$act_cnt=$act_cnt+2) { $actstatus{$actstatustext[$act_cnt]} = $actstatustext[$act_cnt+1]; } # save raw links output then prepare links array for use as output array @temp_arr = @Lof_links; @Lof_links = (); # put raw data into 2D array format suitable for use by # CT_cli_display_utils::set_display # # set up row 0 of the array - column headings # must leave 0th column of 0th row blank $Lof_links[0][0] = ""; foreach $attr_name (@attr_names) { $Lof_links[0][$i] = $attr_name; $i++; } # create rows of raw condition-response data if ($Trace) {print STDERR "$PROGNAME: formatting condition-response data\n";} $i = 1; foreach $line (@temp_arr) { # put condition data into array @attr_vals = split(/$DELIMITERO/, $line); # drop any link whose active state doesn't match # user's preference (indicated via -a, -n flags) if (!$Opt_Active) { if ($attr_vals[$act_idx] == $active) { next; } } if (!$Opt_Not_Active) { if ($attr_vals[$act_idx] == $not_active) { next; } } # change active flag from integer to string for display # if ($attr_vals[$act_idx] == $active) { # $attr_vals[$act_idx] = "\"" . $act_str . "\""; # } # elsif ($attr_vals[$act_idx] == $not_active) { # $attr_vals[$act_idx] = "\"" . $not_act_str . "\""; # } $attr_vals[$act_idx] = process_active_status($attr_vals[$act_idx],%actstatus); # change locked status from integer to string for display if ($Opt_Show_Locked) { if ($attr_vals[$locked_idx] <=1) { $attr_vals[$locked_idx] = $lockedstatustext[$attr_vals[$locked_idx]]; } else { $attr_vals[$locked_idx] = $lockedstatustext[2]; } # add quotes $attr_vals[$locked_idx] = "\"".$attr_vals[$locked_idx]."\""; } # load the field elements into display array $Lof_links[$i][0] = "\n$divider[0] $i:"; foreach $attr_val (@attr_vals) { $Lof_links[$i][$j] = $attr_val; $j++; } $j = 1; $i++; } # put condition data into 2D array if ($Trace) {print STDERR "$PROGNAME: formatting condition data\n";} @temp_arr = (); $i = 0; foreach $line (@Lof_conds) { @attr_vals = split(/$DELIMITERO/, $line); # load elements into 2D array $temp_arr[$i][0] = $attr_vals[0]; $temp_arr[$i][1] = $attr_vals[1]; if ($cluster_env) { $temp_arr[$i][2] = $attr_vals[2]; } $i++; } # save reformatted condition data @Lof_conds = @temp_arr; # put response data into 2D array if ($Trace) {print STDERR "$PROGNAME: formatting response data\n";} @temp_arr = (); $i = 0; foreach $line (@Lof_resps) { @attr_vals = split(/$DELIMITERO/, $line); # load elements into 2D array $temp_arr[$i][0] = $attr_vals[0]; $temp_arr[$i][1] = $attr_vals[1]; if ($cluster_env) { $temp_arr[$i][2] = $attr_vals[2]; } $i++; } # save reformatted response data @Lof_resps = @temp_arr; # for each line of output array, match conditions and responses if ($Trace) {print STDERR "$PROGNAME: filtering condition and response data\n";} for ( $i = 1; $i <= $#Lof_links; $i++ ) { for ( $j = 0; $j <= $#Lof_conds; $j++ ) { # if match: replace condition hndl with condition name if ($Lof_links[$i][1] eq $Lof_conds[$j][0]) { $Lof_links[$i][1] = $Lof_conds[$j][1]; $cond_match = $TRUE; last; } } for ( $j = 0; $j <= $#Lof_resps; $j++ ) { # if match: replace response hndl with response name if ($Lof_links[$i][2] eq $Lof_resps[$j][0]) { $Lof_links[$i][2] = $Lof_resps[$j][1]; $resp_match = $TRUE; last; } } } # end for $i loop # - if either no condition matches or no response matches: ERROR unless ($cond_match && $resp_match) { unless ($Opt_Quiet) { printEMsg("EMsglscondrespNoCondRespMatches"); $rc = ERRM_CLI_USER_ERROR; # 71382 } exit($rc); } # prepare temporary and output arrays @temp_arr = @Lof_links; @Lof_links = ( "" ); my $numattr = 3; if ($cluster_env) { $numattr = 4; } if ($Opt_Show_Locked) { $numattr++; } my $cluster_attr = 3; # build output array that contains only valid cond-resp links if ($Trace) {print STDERR "$PROGNAME: filtering condition-response links\n";} for ( $i = 1; $i <= $#temp_arr; $i++ ) { # do not save if either condition or response elts contains rhandles # if (($temp_arr[$i][1] =~ /^"0x/) || # ($temp_arr[$i][2] =~ /^"0x/)) { if (($temp_arr[$i][1] =~ /^0x/) || ($temp_arr[$i][2] =~ /^0x/)) { splice(@temp_arr, $i, 1); $i--; next; } # save good cond-resp link $Lof_links[$i][0] = "\n$divider[0] $i:"; for ($j = 1; $j <= $numattr; $j++) { $Lof_links[$i][$j] = $temp_arr[$i][$j]; } # get rid of the {} around the node name if ($cluster_env) { $Lof_links[$i][$cluster_attr] =~ s/{//; $Lof_links[$i][$cluster_attr] =~ s/}//; # use first node name in NodeNameList ($Lof_links[$i][$cluster_attr],$junk) = split /,/,$Lof_links[$i][$cluster_attr]; } } # no cond-resp links saved: ERROR unless ($#Lof_links) { unless ($Opt_Quiet) { printEMsg("EMsglscondrespNoCondRespMatches"); $rc = ERRM_CLI_USER_ERROR; # 71382 } exit($rc); } # restore headings for ($j = 0; $j <= $numattr; $j++) { $Lof_links[0][$j] = $temp_arr[0][$j]; } # # display output # my $row_count = $#Lof_links; # set_display expects 0-origin row count if ( $row_count ) { # be sure there's data to display if ($Opt_Mkcondresp_Ex) { # -C: display mkcondresp example if ($Trace) {print STDERR "$PROGNAME: calling display_cmd_ex to display condition-response links\n";} display_cmd_ex(\@Lof_links); } else { # standard display if ($Trace) {print STDERR "$PROGNAME: calling set_display to display condition-response links\n";} unless ($Opt_No_HDR) { printIMsg("IMsglscondrespOut"); } my $display_type = ""; my $col_count = scalar(@{$Lof_links[0]}); # set formatting string needed by set_display ($Opt_Long_Format) && ($display_type = "long"); ($Opt_Table_Format) && ($display_type = "column"); ($Opt_Delm_Format) && ($display_type = "delim"); $rmc_rc = set_display($display_type, $Opt_No_HDR, $row_count, $col_count, \@Lof_links, $Opt_Delm_Str); if ($rc==0) { $rc = $rmc_rc;} # 71382 set display rc if rc so far is } if ($Trace) {print STDERR "$PROGNAME: returned from display routine\n";} } if ($Verbose) { printIMsg("IMsglscondrespEnd51D");} if ($errmcli_rc == 0) { exit($rc);} else { exit($errmcli_rc);} #--------------------------------------------------------------------# # End Main Code # #--------------------------------------------------------------------# #--------------------------------------------------------------------# # parse_cmd_line - Parse the command line for options and operands. # # Set appropriate global variables as outlined below, make sure we # # have a valid combination of arguments / options. # # # # Return: # # $rc 0 Command line parsed fine, no problem. # # ERRM_CLI_BAD_FLAG Command line contained a bad flag. # # # # Global Variables Modified: # # $Verbose output True (-V) turn Verbose mode on # # $Trace output True (-T) turn Trace mode on # # $Opt_Active output True (-a) only active links # # $Opt_Mkcondresp_Ex output True (-C) example mkcondresp cmd # # $Opt_Delm_Format output True (-d) delimited output # # $Opt_Delm_Str output True (-D) delimited output with user # # delimiter string # # $Opt_Long_Format output True (-l) long-format output # # $Opt_Not_Active output True (-n) only inactive links # # $Opt_Quiet output True (-q) no undef condition errors # # $Opt_Only_Resps output True (-r) response parameters only # # $Opt_Table_Format output True (-t) tabular output # # $Opt_No_HDR output True (-x) no headings displayed # # $Opt_All_Nodes output True (-z) display all nodes # # $Opt_Show_Locked output True (-U) display Locked # #--------------------------------------------------------------------# sub parse_cmd_line { my %opts = (); # Process the command line... if (!&getopts('hanltdD:zqrxUVT', \%opts)) {# Gather options; # if errors &print_usage; # display proper usage return ERRM_CLI_BAD_FLAG; # return bad rc - bad flag } # process h flag if (defined $opts{h}) { # -h, help request &print_usage; # print usage statement exit(0); # all done with good return! } if (defined $opts{r}) { # -r all input parms are responses $Opt_Only_Resps = $TRUE; } # process input parameters $sARGV = scalar(@ARGV); if (!$sARGV) { if ($Opt_Only_Resps) { # error - must have at least one response when -r specified printEMsg("EMsglscondrespNoRespRFlag"); &print_usage; return ERRM_CLI_BAD_OPERAND; } $Opt_Long_Format = $FALSE; # force tabular if no parameters $Opt_Table_Format = $TRUE; } else { if ($Opt_Only_Resps) { # treat all parameters as responses push(@in_resps, @ARGV); @ARGV = (); } else { # treat first parameter as condition, rest as responses $in_cond = shift(@ARGV); push(@in_resps, @ARGV); @ARGV = (); } } if (defined $opts{a}) { # -a list active links only $Opt_Active = $TRUE; $Opt_Not_Active = $FALSE; } if (defined $opts{n}) { # -n list inactive links only $Opt_Not_Active = $TRUE; $Opt_Active = $FALSE; } if (defined $opts{D}) { # -D delimited output with specified $Opt_Delm_Format = $TRUE; # delimiter $Opt_Delm_Str = $opts{D}; $Opt_Long_Format = $FALSE; } if (defined $opts{d}) { # -d delimited output $Opt_Delm_Format = $TRUE; $Opt_Delm_Str = ":"; $Opt_Long_Format = $FALSE; } if (defined $opts{t}) { # -t table formatted output $Opt_Table_Format = $TRUE; $Opt_Mkcondresp_Ex = $FALSE; $Opt_Long_Format = $FALSE; $Opt_Delm_Format = $FALSE; } if (defined $opts{l}) { # -l long formatted output $Opt_Long_Format = $TRUE; $Opt_Mkcondresp_Ex = $FALSE; $Opt_Table_Format = $FALSE; $Opt_Delm_Format = $FALSE; } if (defined $opts{C}) { # -C example mkcondresp cmd if ($sARGV) { $Opt_Mkcondresp_Ex = $TRUE; } else { # if no conds/resps, pretend no -C $Opt_Long_Format = $FALSE; # turn off default long format $Opt_Table_Format = $TRUE; # turn on tabular format } } if (defined $opts{z}) { # -z display all nodes in cluster $Opt_All_Nodes = $TRUE; } if (defined $opts{q}) { # -q quiet mode - supress undefined $Opt_Quiet = $TRUE; # condition errors } if (defined $opts{x}) { # -x supress headings $Opt_No_HDR = $TRUE; } if (defined $opts{U}) { # -U show locked $Opt_Show_Locked = $TRUE; } if (defined $opts{T}) { # -T turn trace on $Trace = $TRUE; } if (defined $opts{V}) { # -V turn verbose mode on $Verbose = $TRUE; } return(0); # success } # end parse_cmd_line #--------------------------------------------------------------------# # display_cmd_ex - print example mkcondresp command to stdout # # # # Return: none # # # # Input parameters: # # $r_condresps reference to two-dimensional array containing # # cond-resp link data formatted for output # #--------------------------------------------------------------------# sub display_cmd_ex { my $r_condresps = shift; my $r_condresp_row = 0; my $cond_name = ""; my $resp_name = ""; my $cond_name_msg = ""; # 71402 my $resp_name_msg = ""; # 71402 my $i = 0; foreach $r_condresp_row (@$r_condresps) { if ($i == 0) { # skip row 0 - it contains column headings $i++; next; } # extract data from output array $cond_name = ${$r_condresp_row}[1]; $resp_name = ${$r_condresp_row}[2]; $cond_name_msg = $cond_name; # 71402 $resp_name_msg = $resp_name; # 71402 $cond_name_msg =~ s/\"//g; # 71402 $resp_name_msg =~ s/\"//g; # 71402 # display the example command unless ($Opt_No_HDR) { printIMsg("IMsglscondrespMkcondrespEx", $cond_name_msg, $resp_name_msg); } printf "mkcondresp %s %s\n", $cond_name, $resp_name; print "\n"; } } # end display_cmd_ex #--------------------------------------------------------------------# # print_usage : print the usage statement (syntax) to stdout. # #--------------------------------------------------------------------# sub print_usage { &printIMsg("IMsglscondrespUsageU"); } # end print_usage