#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,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 = "@(#)37   1.19.1.31   src/rsct/rm/ER/cli/bin/lscondition.perl, errmcli, rsct_rady, rady2035a 3/27/20 03:20:45"
######################################################################
#                                                                    #
# Module: lscondition                                                #
#                                                                    #
# Purpose:                                                           #
#   lscondition - list one or more condition resources               #
#                                                                    #
# Current Syntax:                                                    #
#   lscondition [-h] [-A] [-m|-n|-e] [-C|-l|-t|-d|-D Delimiter] [-a] #
#      [-q] [-x] [-U] [-TV] [Condition [Condition...]:Node_name]     #
#                                                                    #
# Flags:                                                             #
#   -A      Displays all of the attributes associated with the       #
#           condition names.                                         #
#   -C      The output of the command is the mkcondition command     #
#           that could be used to create the condition.  If more     #
#           than one condition is listed, every condition appears    #
#           on a separate line.                                      #
#   -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.           #
#   -e      Lists only those conditions that are in error.           #
#   -h      Help.  Writes this command's usage statement to stdout.  #
#   -l      Long formatted output.  The condition information is     #
#           displayed on separate lines.                             #
#   -m      Lists only those conditions that are being monitored.    #
#   -n      Lists only those conditions that are not being           #
#           monitored.                                               #
#   -a      All. List condition information for all nodes in the     #
#           cluster.                                                 # 
#   -q      Quiet.  Does not return an error when the Condition      #
#           specified does not exist.                                #
#   -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.                #
#                                                                    #
# Operands:                                                          #
#   Condition      The name of the condition to be listed. Node_name #
#                  specifies where the condition is defined.         # 
#                                                                    #
# Description:                                                       #
#   The lscondition command is used to list information about        #
#   defined conditions.                                              #
#                                                                    #
# 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 all conditions and their monitoring status, run the   #
#      following command:                                            #
#        lscondition                                                 #
#      Output is similar to:                                         #
#        Name                          Monitoring Status             #
#        "File system space used up"   "Monitored"                   #
#        "tmp space used up"           "Not monitored"               #
#        "var space used up"           "Error"                       #
#   2. To list general information about the condition               #
#      "File system space used up" in long format, run the           #
#      following command:                                            #
#        lscondition "File system space used up"                     #
#      Output is similar to:                                         #
#       Listing the condition "File system space used up"            #
#       Name             = "File system space used"                  #
#       MonitorStatus    = "Monitored"                               #
#       ResourceClass    = IBM.FileSystem                            #
#       EventExpression  = "PercentTotUsed > 90"                     #
#       EventDescription = "An event will be generated when more     #
#                          than 90 percent of the total space of the #
#                          filesystem is in use."                    #
#       RearmExpression  = "PercentTotUsed < 75"                     #
#       RearmDescription = "The event will be rearmed when the       #
#                          percent of the space used in the          #
#                          filesystem falls below 75 percent."       #
#       SelectionString  = ""                                        #
#       Severity         = 0                                         #
#       NodeNames        = {"localnode"}                             #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the mkcondition man page in /opt/rsct/man.                  #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/errmcli.lscondition.map - message mapping #
#                                                                    #
# Outputs:                                                           #
#   stdout - display information on the condition.                   #
#   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:                                                   #
#   010108 GTM 67471: Initial design & write.                        #
#   010212 GTM 71293: Enhanced -TV handling.                         #
#   010217 GTM 71363: Correct -m|-n|-e selection of conditions.      #
#   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.       #
#   011127 JAC 77596: Change processing for MonitorStatus attribute. #
#   011206 JAC 78841: Fix selection string for locating resources.   #
#   020121 JAC 79558: Fix selection string for locating resources.   #
#   020121 JAC 78997: Fix if-statement to correct display format.    #
#   020207 JAC 71888: Add verbose messages to message file.          #
#   020208 JAC 80163: Fix if statement for -m flag checking.         #
#   020208 JAC 71728: Add NLS support for headers and xlating values.#
#   020215 JAC 78996: Add new display columns and fix some formats.  #
#   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.             #
#   020725 JAC 85139: Return proper rc when no conditions found.     #
#   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 names and use #
#                      LIKE in select string.                        #
#   071026 JAC 146726: set delimiter for -api calls                  #
#   081113 JAC 153204: add event batching.                           #
######################################################################

#--------------------------------------------------------------------#
# 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 conditions           #
#    - print usage if -h specified                                   #
#    - set $Opt variables according to flags specified               #
# B. Call RMC command lsrsrc. Also pass along -TV if necessary.      #
#    - if no condition names, call lsrsrc once to get all defined    #
#      conditions and their monitoring status                        #
#    - if no condition names and -A, call lsrsrc once with all       #
#      supported attr names                                          #
#    - if at least one condition is specified, call lsrsrc for each  #
#      condition                                                     #
# C. Do post processing on raw lsrsrc output.                        #
#    - copy lsrsrc data into 2D array                                #
#    - if -m keep only monitored w/out error conditions              #
#    - if -n keep only non-monitored conditions                      #
#    - if -e keep only monitored w/error conditions                  #
#    - change monitor status value from number to string             #
#    - change severity value from number to string                   #
# D. Format and display output.                                      #
#    - if at least one condition's worth of output was obtained,     #
#      execute display code                                          #
#    - if -C display example mkcondition commands for each condition #
#    - 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::Long; 

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
                    process_monitor_status
                    process_api_error process_exit_code
                    set_orig_rmc_scope check_set_cluster_scope
                    remove_api_error in_cluster
                    getIMsg
                    escape_selstr
                    $CTDIR $CTBINDIR
                    $SEVCRIT $SEVWARN $SEVINFO $GARBAGE
                    $MKCNDCRIT $MKCNDWARN $MKCNDINFO
                    $LCL_SCOPE $SR_SCOPE $CSM_SCOPE
                    $LCL_SCOPE_VAL $SR_SCOPE_VAL $CSM_SCOPE_VAL
                    $RMC_CLI_USER_ERROR $DELIMITERI $DELIMITERO
                    $RMC_CLI_RSRC_NOT_FOUND
                    $LSNOTFND $LSRSRC $MKRSRC $RSCCOND);


#--------------------------------------------------------------------#
# Global Constants                                                   #
#--------------------------------------------------------------------#
Getopt::Long::Configure ("bundling", "no_auto_abbrev",
                         "no_ignore_case", "require_order",
                         "prefix_pattern=(--|-)");

# attribute names
$Attr_Name = "Name";
$Attr_MonStatus = "MonitorStatus";
$Attr_NodeNameList = "NodeNameList";
$Attr_Rsrc_Class = "ResourceClass";
$Attr_EvExpr = "EventExpression";
$Attr_EvDesc = "EventDescription";
$Attr_RearmExpr = "RearmExpression";
$Attr_RearmDesc = "RearmDescription";
$Attr_SelStr = "SelectionString";
$Attr_Sev = "Severity";
$Attr_NodeNames = "NodeNames";
$Attr_MgtScope = "ManagementScope";
$Attr_Locked = "Locked";
$Attr_NoToggle= "NoToggleExprFlag";
$Attr_BatchingInterval= "EventBatchingInterval";
$Attr_BatchingMaxNum= "EventBatchingMaxEvents";
$Attr_BatchingRetPeriod= "BatchedEventRetentionPeriod";
$Attr_BatchingMaxsize= "BatchedEventMaxTotalSize";
$Attr_BatchAuditlog= "AuditLogControl";

## raw MonitorStatus values (from p. 57 of ERRM v1.3 compdes)
#$not_mon = 0;
#$mon_ok = 1;
#$mon_err = 2;

## MonitorStatus display strings
#$not_mon_str = "Not monitored";
#$mon_ok_str = "Monitored";
#$mon_err_str = "Error";


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$TRUE = 1;
$FALSE = 0;

$Trace = $FALSE;                        # default - trace off 
                                        #         -T flag

$Verbose = $FALSE;                      # default - verbose turned off
                                        #         -V flag

$Scope_orig_set = $FALSE;               # default - no CT_MANAGEMENT_SCOPE
$Scope_orig_value = 0;                  # default - scope value

$Opt_All_Attrs = $TRUE;                 # default - all attributes
                                        #         -A flag

$Opt_Mkcond_Ex = $FALSE;                # default - do not display
                                        # mkcondition 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_Only_Error = $FALSE;               # default - do not restrict to
                                        # conditions with monitoring error
                                        #         -e flag

$Opt_Only_Mon = $FALSE;                 # default - do not restrict to
                                        # monitored conditions
                                        #         -m flag

$Opt_Only_NotMon = $FALSE;              # default - do not restrict to
                                        # non-monitored conditions
                                        #         -n flag

$Opt_Quiet = $FALSE;                    # default - do not supress display
                                        # of error when non-existent
                                        # condition is specified
                                        #         -q flag

$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 = "lscondition";              # 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_attr_names = "";                   # attr names to pass to lsrsrc
#$lsr_opts = " -xd";                     # format options for lsrsrc
$lsr_dbg_opts = "";                     # trace/verbose opts for lsrsrc
@Lof_lsr_output = ();                   # lsrsrc raw output array
@Lof_conds = ();                        # 2D array of data to be displayed
$locator = "";                          # where to look for the conditions
@Cond_list = ();                        # copy of ARGV without locator
$mon_status = 0;                        # monitor status value
my @heading = ();                       # heading for the listed data
my @divider = ();                       # text for the divider in long format
my @monstatustext = ();                 # text to use for monitor status
my %monstatus = ();                     # hash for monitor status descriptions
my $mon_cnt = 0;                        # loop counter
my @YesNoText = ();                     # text to use for Yes No ?
my @tmp_output = ();                    # lsclcfg output
my $cluster_env = $FALSE;               # in a cluster?
my $junk = "";                          # for garbage


#--------------------------------------------------------------------#
#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
#--------------------------------------------------------------------#
my $rc = 0;
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, $locator, @Cond_list) = &parse_cmd_line;

($rc == 0) || error_exit($rc);

if ($Verbose) { printIMsg("IMsglsconditionStart51D");}

# if there are multiple locators, add some quotes
$locator =~ s/,/\\\",\\\"/g;

#
# call lsrsrc based on input data
#

# 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"; }

# 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;

# set cluster scope if locator used or -a used
if ( ($locator ne "") || ($Opt_All_Nodes) ) {
   check_set_cluster_scope;
}
  
# build attr names to be passed to lsrsrc
$lsr_attr_names = $Attr_Name . "${DELIMITERI}";
if ($cluster_env) { $lsr_attr_names .= $Attr_NodeNameList . "${DELIMITERI}";}
$lsr_attr_names .= $Attr_MonStatus . "${DELIMITERI}";
$lsr_attr_names .= $Attr_Rsrc_Class . "${DELIMITERI}";
$lsr_attr_names .= $Attr_EvExpr . "${DELIMITERI}";
$lsr_attr_names .= $Attr_EvDesc . "${DELIMITERI}";
$lsr_attr_names .= $Attr_RearmExpr . "${DELIMITERI}";
$lsr_attr_names .= $Attr_RearmDesc . "${DELIMITERI}";
$lsr_attr_names .= $Attr_SelStr . "${DELIMITERI}";
$lsr_attr_names .= $Attr_Sev . "${DELIMITERI}";
$lsr_attr_names .= $Attr_NodeNames . "${DELIMITERI}";
$lsr_attr_names .= $Attr_MgtScope . "${DELIMITERI}";
$lsr_attr_names .= $Attr_NoToggle . "${DELIMITERI}";
$lsr_attr_names .= $Attr_BatchingInterval . "${DELIMITERI}";
$lsr_attr_names .= $Attr_BatchingMaxNum . "${DELIMITERI}";
$lsr_attr_names .= $Attr_BatchingRetPeriod . "${DELIMITERI}";
$lsr_attr_names .= $Attr_BatchingMaxsize . "${DELIMITERI}";
$lsr_attr_names .= $Attr_BatchAuditlog ;

#print $lsr_attr_names, "\n";
# add Locked attribute if -U used
if ($Opt_Show_Locked) { $lsr_attr_names .= "${DELIMITERI}" . $Attr_Locked; }

# call lsrsrc
if ($Trace) {print STDERR "$PROGNAME: calling lsrsrc-api to get condition data\n";}

# if no condition args, force -t (fixed in 78997)
if (($#Cond_list<0) && (!$Opt_All_Attrs)) { $Opt_Table_Format = $TRUE; }

if ($#Cond_list >= 0) {        # conditions given as input
    my @tmp_lsr_output = ();
    my $cond_name = "";
    my $cond_name_orig = "";
    my $lsr_selstr = "\"Name LIKE \\\"ERRMCLI\\\"\"";
    # check to see if node locator is needed
    if ($locator ne "") {
       $lsr_selstr = "\"Name LIKE \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\"";
    }

    # issue lsrsrc command for each condition provided as input
    foreach $cond_name (@Cond_list) {
        $cond_name_orig = $cond_name;
        $cond_name = escape_selstr($cond_name);
        #$lsr_selstr =~ s/ERRMCLI/$cond_name/;
        $lsr_selstr =~ s/ERRMCLI/%${cond_name}%/;

        # issue the lsrsrc command with the correct flags/operands
      # @tmp_lsr_output = `$CTBINDIR/$LSRSRC $lsr_selstr $lsr_opts $lsr_dbg_opts $RSCCOND $lsr_attr_names`;
        $ENV{CT_CLI_QUOTE_STRING} = 1;
#        my $tmp_lsr_cmd = "$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCCOND}${DELIMITERI}${lsr_selstr}${DELIMITERI}${DELIMITERI}${DELIMITERI}${lsr_attr_names}";
#	print $tmp_lsr_cmd,"\n";
        @tmp_lsr_output = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCCOND}${DELIMITERI}${lsr_selstr}${DELIMITERI}${DELIMITERI}${DELIMITERI}${lsr_attr_names} 2>&1`;

        $rc = $?;
        $rc = &process_exit_code($rc);
        if ($Trace) {
           print STDERR "lsrsrc-api results:\n";
           print STDERR "@tmp_lsr_output";
           print STDERR "$PROGNAME: lsrsrc-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,@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 condition
        if ($rc == $RMC_CLI_USER_ERROR) {
           $errmcli_rc = ERRM_CLI_USER_ERROR;
           }
        # check for other things
        else {
           # save any other RMC CLI error
           if (($rc != 0) && ($rc != $RMC_CLI_RSRC_NOT_FOUND)) {
              $errmcli_rc = ERRM_CLI_RMC_ERROR;
              }

           # else rc=0, worked but may not have found anything
           else {

              # check for not found rc
              if ($rc == $RMC_CLI_RSRC_NOT_FOUND) {
                 unless ($Opt_Quiet) {
                     printEMsg("EMsglsconditionConditionNotFound", $cond_name_orig);
                     $errmcli_rc = ERRM_CLI_USER_ERROR;     # 71382
                     }
                 }
              }
           }

        if ($#tmp_lsr_output >= 0) {
            chomp(@tmp_lsr_output);
            push(@Lof_lsr_output, @tmp_lsr_output);
            }

           # reset selection string template
           $lsr_selstr = "\"Name LIKE \\\"ERRMCLI\\\"\"";
           # check to see if node locator is needed
           if ($locator ne "") {
              $lsr_selstr = "\"Name LIKE \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\"";
           }

        }
    }
else {                  # no condition names given
    unless ($Opt_All_Attrs) {    # use short list of attr names
        $lsr_attr_names = $Attr_Name . "${DELIMITERI}";
        if ($cluster_env) { $lsr_attr_names .= $Attr_NodeNameList . "${DELIMITERI}";}
        $lsr_attr_names .= $Attr_MonStatus;

        # add Locked attribute if -U used
        if ($Opt_Show_Locked) { $lsr_attr_names .= "${DELIMITERI}" . $Attr_Locked; }
    }

    # check to see if node locator is needed
    if ($locator ne "") {
       $lsr_selstr = "-s ${RSCCOND}${DELIMITERI}\"NodeNameList|<{\\\"$locator\\\"}\"";
    }
    # else get them all
    else {
       $lsr_selstr = "-o ${RSCCOND}";
    }
       
    # issue the lsrsrc command
    $ENV{CT_CLI_QUOTE_STRING} = 1;
    @Lof_lsr_output = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO ${lsr_selstr}${DELIMITERI}${DELIMITERI}${DELIMITERI}${lsr_attr_names} 2>&1`;

    $rc = $?;
    $rc = &process_exit_code($rc);
    if ($Trace) {
       print STDERR "lsrsrc-api results:\n";
       print STDERR "@Lof_lsr_output";
       print STDERR "$PROGNAME: lsrsrc-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,@Lof_lsr_output);
    }

    # remove the error messages
        @Lof_lsr_output = remove_api_error(@Lof_lsr_output);

    # check for RMC errors
    if ($rc != 0) {
       # continue if there's partial output
       if ($#Lof_lsr_output >=0) {
          # return ERRM CLI user error if it's an RMC CLI user error
          if ($rc == $RMC_CLI_USER_ERROR) { $errmcli_rc = ERRM_CLI_USER_ERROR;}
          # or it's some rmc error
          else { $errmcli_rc = ERRM_CLI_RMC_ERROR; }
       }
       # there's an error and no output, just exit
       else {
          ($rc == $RMC_CLI_USER_ERROR) && ( error_exit(ERRM_CLI_USER_ERROR) );
          ($rc == $RMC_CLI_RSRC_NOT_FOUND) && ( error_exit(ERRM_CLI_USER_ERROR) );
          error_exit(ERRM_CLI_RMC_ERROR);
       }
    }

    chomp(@Lof_lsr_output);
}

if ($Trace) {print STDERR "$PROGNAME: $LSRSRC returned condition data\n";}

#
# post-process raw lsrsrc oputput
#

if ($Trace) {print STDERR "$PROGNAME: formatting condition data for display\n";}

my $i = 1;
my $j = 1;
my $line = "";
my $attr_val = "";
my $attr_name = "";
my $mon_idx = 1;
my $sev_idx = 8;
my $mgtscope_idx = 10;
my $toggle_idx= 11;
my $batchint_idx= 12;
my $batchmax_idx= 13;
my $batchret_idx= 14;
my $batchsize_idx= 15;
my $auditlog_idx= 16;
my $locked_idx= 17;
my $nodenamelst_idx = 1;
my @uheading = ();
if ($cluster_env) {
   $mon_idx = 2;
   $sev_idx = 9;
   $mgtscope_idx = 11;
   $toggle_idx= 12;
   $batchint_idx= 13;
   $batchmax_idx= 14;
   $batchret_idx= 15;
   $batchsize_idx= 16;
   $auditlog_idx= 17;
   $locked_idx= 18;
} 
my @attr_vals = "";
my @attr_names = ();
my %audit_control = (
	'0' => 'ALL',
	'1' => 'Error Only',
	'2' => 'None',
);
# get heading from message file based on long or short version
if ($Opt_All_Attrs) { 
   if ($cluster_env) { @heading = getIMsg("IMsglsconditionLCHeading4");}
   else { @heading = getIMsg("IMsglsconditionLHeading4");}
}
else {
   if ($cluster_env) { @heading = getIMsg("IMsglsconditionSCHeading");}
   else { @heading = getIMsg("IMsglsconditionSHeading");}
}

# get from message file what to use for Yes or No
@YesNoText= getIMsg("IMsglsconditionNoYes");
@YesNoText= split(/::/,$YesNoText[0]);

# see if Locked heading is needed
if ($Opt_Show_Locked) {
    @uheading = getIMsg("IMsglsconditionUHeading");
    $heading[0] .= "::" . $uheading[0];
}

# form the heading
@attr_names = split(/::/,$heading[0]);
# get the divider text in case it's needed 
@divider = getIMsg("IMsglsconditionDivider");

# get from message file what to use for monitor status
@monstatustext = getIMsg("IMsglsconditionMonStatus");
@monstatustext = split(/::/,$monstatustext[0]);

# fill in the hash for monitor status
for ($mon_cnt=0;$mon_cnt<=$#monstatustext;$mon_cnt=$mon_cnt+2) {
   $monstatus{$monstatustext[$mon_cnt]} = $monstatustext[$mon_cnt+1];
}

# 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_conds[0][0] =  "";
foreach $attr_name (@attr_names) {
    $Lof_conds[0][$i] = $attr_name;
    $i++;
}

# create rows of data
$i = 1;
foreach $line (@Lof_lsr_output) {

    # put condition data into array
    @attr_vals = split(/$DELIMITERO/, $line);

    # translate the MonitorStatus attribute
    ($mon_status, $attr_vals[$mon_idx]) = process_monitor_status($attr_vals[$mon_idx],%monstatus);

    # drop any condition whose monitoring status doesn't match
    # user's preference (indicated via -m, -n, or -e flags)
    if ($Opt_Only_Mon) {
        if ( ($mon_status <=0) || ($mon_status >= 4) ) { next; }
    }
    if ($Opt_Only_NotMon) {
        if ( $mon_status != 0 ) { next; }
    }
    if ($Opt_Only_Error) {
        if ( $mon_status < 4 ) { next; }
    }

    # drop braces from nodenamelist
    if ($cluster_env) {
       $attr_vals[$nodenamelst_idx] =~ s/{//;
       $attr_vals[$nodenamelst_idx] =~ s/}//;
       # use first node name in NodeNameList
       ($attr_vals[$nodenamelst_idx],$junk) = split /,/,$attr_vals[$nodenamelst_idx];
    }

    # if you have severities   71363 
    if ($#attr_vals >= $sev_idx) { 

       # change severity from integer to string for display
       # (change == to eq  71363)
       if ($attr_vals[$sev_idx] eq $MKCNDINFO) {
           $attr_vals[$sev_idx] = "\"" . $SEVINFO . "\"";}
       if ($attr_vals[$sev_idx] eq $MKCNDWARN) {
           $attr_vals[$sev_idx] = "\"" . $SEVWARN . "\"";}
       if ($attr_vals[$sev_idx] eq $MKCNDCRIT) {
           $attr_vals[$sev_idx] = "\"" . $SEVCRIT . "\"";}

       # change severity from integer to string for display
       if ($attr_vals[$mgtscope_idx] eq $LCL_SCOPE_VAL) {
           $attr_vals[$mgtscope_idx] = "\"" . $LCL_SCOPE . "\"";}
       if ($attr_vals[$mgtscope_idx] eq $SR_SCOPE_VAL) {
           $attr_vals[$mgtscope_idx] = "\"" . $SR_SCOPE . "\"";}
       if ($attr_vals[$mgtscope_idx] eq $CSM_SCOPE_VAL) {
           $attr_vals[$mgtscope_idx] = "\"" . $CSM_SCOPE . "\"";}
       }

    # change locked status from integer to string for display
    if ($Opt_Show_Locked) {
        if ($attr_vals[$locked_idx] <=1) {
            $attr_vals[$locked_idx] = "\"$YesNoText[$attr_vals[$locked_idx]]\"";
        }
        else { $attr_vals[$locked_idx] = "\"$YesNoText[2]\""; }
    }
 
    # change toggle value from integer to string for display
    $attr_vals[$toggle_idx] = "\"$YesNoText[! $attr_vals[$toggle_idx]]\"";

    #change ReportAudtitLog value from integer to string for display
    $attr_vals[$auditlog_idx] = "\"$audit_control{$attr_vals[$auditlog_idx]}\"";
    # load the field elements into display array
    $Lof_conds[$i][0] = "\n$divider[0] $i:";
    foreach $attr_val (@attr_vals) {
        $Lof_conds[$i][$j] = $attr_val;
        $j++;
    }
    $j = 1;
    $i++;
}


#
# display output
#


my $row_count = $#Lof_conds;   # set_display expects 0-origin row count
if ( $row_count ) {            # be sure there's data to display

    if ($Opt_Mkcond_Ex) {      # -C: display mkcondition example
       if ($Trace) {print STDERR "$PROGNAME: calling display_cmd_ex to display condition data\n";}
       display_cmd_ex(\@Lof_conds);
    }
    else {                     # standard display
        if ($Trace) {print STDERR "$PROGNAME: calling set_display to display condition data\n";}
        unless ($Opt_No_HDR) { printIMsg("IMsglsconditionOut"); }
        my $display_type = "";
        my $col_count = scalar(@{$Lof_conds[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");
        $rc = set_display($display_type, $Opt_No_HDR, $row_count, $col_count,
                          \@Lof_conds, $Opt_Delm_Str);
    }

    if ($Trace) {print STDERR "$PROGNAME: returned from display routine\n";}
}

if ($Verbose) { printIMsg("IMsglsconditionEnd51D");}

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_All_Attrs     output   True (-A) requests all attrs         #
#   $Opt_Mkcond_Ex     output   True (-C) example mkcondition 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_Only_Error    output   True (-e) monitored with errors      #
#   $Opt_Only_Mon      output   True (-m) monitored with no errors   #
#   $Opt_Only_NotMon   output   True (-n) not monitored              #
#   $Opt_Quiet         output   True (-q) no undef condition errors  #
#   $Opt_Table_Format  output   True (-t) tabular output             #
#   $Opt_No_HDR        output   True (-x) no headings displayed      #
#   $Opt_All_Nodes     output   True (-a) display all nodes          #
#   $Opt_Show_Locked   output   True (-U) display Locked             #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my %opts = ();
my $locator = "";
my $temp_name = "";
my @conditions = ();

# Process the command line...
#if (!&getopts('hAmneCltdD:aqxUVT', \%opts)) {# Gather options; 
if (!GetOptions(\%opts,
		'h' ,
		'A' ,
		'm' ,
		'n' ,
		'e' ,
		'C' ,
		'l' ,
		't' ,
		'd' ,
		'D=s' ,
		'a' ,
		'q' ,
		'x' ,
		'U' ,
		'V' ,
		'T')) {# Gather options; 
                                        # if errors
    &print_usage;                       # display proper usage
    return ERRM_CLI_BAD_FLAG;           # return bad rc - bad flag 
}

$sARGV = scalar(@ARGV);
if(!$sARGV) {
    $Opt_Long_Format = $FALSE;          # force tabular if no parameters
    $Opt_Table_Format = $TRUE;
}

@conditions = @ARGV;
if ($sARGV) {            # conditions and/or locator given as input
   # extract the locator from the last condition name
   ($temp_name, $locator) = get_locator_node($conditions[$sARGV-1]);
   if(containSplChar($temp_name) )
   {
	exit(ERRM_CLI_USER_ERROR);
   }
   # put back condition name without locator
   if ($locator ne "") {
      # fix condition when it's only a locator (:Node)
      if ($temp_name eq "") {
         $#conditions--;
      }
      else {
         $conditions[$sARGV-1] = $temp_name;
      }
   }
}
$sARGV = scalar(@conditions);

# 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{A}) {                # -A list all attrs
    unless ($sARGV) {                   # a little unusual - turn off
        $Opt_All_Attrs = $FALSE;        # only when no conditions and
    }                                   # no -A flag specified
}

if (defined $opts{A}) {                 # -A list all attrs
    $Opt_All_Attrs = $TRUE;             # make sure all attrs enabled
    $Opt_Long_Format = $TRUE;           # turn on long format
    $Opt_Table_Format = $FALSE;         # turn off tabular format
}

if (defined $opts{m}) {                 # -m monitored with no errors
    $Opt_Only_Mon = $TRUE;
}

if (defined $opts{n}) {                 # -n not monitored
    if ($Opt_Only_Mon) {                # no -n with -m
       printCEMsg("EMsgERRMcliImproperUsageCombination","-m","-n");
       &print_usage;
       return ERRM_CLI_BAD_FLAG;
    }
    $Opt_Only_NotMon = $TRUE;
}

if (defined $opts{e}) {                 # -e monitored with errors
    if ($Opt_Only_Mon) {                # no -e with -m
       printCEMsg("EMsgERRMcliImproperUsageCombination","-m","-e");
       &print_usage;
       return ERRM_CLI_BAD_FLAG;
    }
    if ($Opt_Only_NotMon) {             # no -e with -n
       printCEMsg("EMsgERRMcliImproperUsageCombination","-n","-e");
       &print_usage;
       return ERRM_CLI_BAD_FLAG;
    }
    $Opt_Only_Error = $TRUE;
}

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_Mkcond_Ex = $FALSE;
    $Opt_Long_Format = $FALSE;
    $Opt_Delm_Format = $FALSE;
}

if (defined $opts{l}) {                 # -l long formatted output
    $Opt_Long_Format = $TRUE;
    $Opt_Table_Format = $FALSE;
    $Opt_Delm_Format = $FALSE;
    $Opt_Mkcond_Ex = $FALSE; 
}

if (defined $opts{C}) {                 # -C example mkcondition cmd
    if ($sARGV) {
        $Opt_Mkcond_Ex = $TRUE;
    }
    else {
        unless ($Opt_All_Attrs) {
            $Opt_Long_Format = $FALSE;  # turn off default long format
            $Opt_Table_Format = $TRUE;  # turn on tabular format
        }
    }
}

if (defined $opts{a}) {                 # -a 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, $locator, @conditions);     # success
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# display_cmd_ex - print example mkcondition command to stdout       #
#                                                                    #
# Return: none                                                       #
#                                                                    #
# Input parameters:                                                  #
#   $r_conds         reference to two-dimensional array containing   #
#                    condition data formatted for output             #
#--------------------------------------------------------------------#
sub display_cmd_ex {

my $r_conds = shift;

my $r_cond_row = 0;
my $rsrc_class = "";
my $ev_expr = "";
my $ev_desc = "";
my $rearm_expr = "";
my $rearm_desc = "";
my $sel_str = "";
my $severity = "";
my $mgt_scope = "";
my $put_node = "";
my $cond_name = "";
my $cond_name_msg = "";              # 71402
my $batch_txt = "";
my $audit_report = "";

my $rclass_idx = 3;
my $evexpr_idx = 4;
my $evderc_idx = 5;
my $reexpr_idx = 6;
my $redesc_idx = 7;
my $selstr_idx = 8;
my $sev_idx = 9;
my $mgtscp_idx = 11;
my $name_idx = 1;
my $node_idx;
my $batchint_idx = 13;
my $batchmax_idx = 14;
my $batchret_idx= 15;
my $batchsize_idx= 16;
my $auditlog_idx= 17;

my $i = 0;

# adjust index values if in a cluster
if ($cluster_env) {
   $node_idx = 2;
   $rclass_idx = 4;
   $evexpr_idx = 5;
   $evderc_idx = 6;
   $reexpr_idx = 7;
   $redesc_idx = 8;
   $selstr_idx = 9;
   $sev_idx = 10;
   $mgtscp_idx = 12;
   $batchint_idx = 14;
   $batchmax_idx = 15;
   $batchret_idx = 16;
   $batchsize_idx = 17;
   $auditlog_idx = 18;
}

foreach $r_cond_row (@$r_conds) {
    if ($i == 0) {        # skip row 0 - it contains column headings
         $i++;
         next;
    }

    # extract data from output array
    $rsrc_class = ${$r_cond_row}[$rclass_idx];
    $ev_expr = ${$r_cond_row}[$evexpr_idx];
    $ev_desc = ${$r_cond_row}[$evderc_idx];
    $rearm_expr = ${$r_cond_row}[$reexpr_idx];
    $rearm_desc = ${$r_cond_row}[$redesc_idx];
    $sel_str = ${$r_cond_row}[$selstr_idx];
    $severity = ${$r_cond_row}[$sev_idx];
    $mgt_scope = ${$r_cond_row}[$mgtscp_idx];
    $cond_name = ${$r_cond_row}[$name_idx];
    $cond_name_msg = $cond_name;                 #71402
    $cond_name_msg =~ s/\"//g;                   #71402

    if ($cluster_env)
    {
        $put_node= "-n ${$r_cond_row}[$node_idx] ";
    }

    # determine event batching
    $batch_txt = "";
    if ( ${$r_cond_row}[$batchint_idx] > 0 ) {
       $batch_txt = "-b ${$r_cond_row}[$batchint_idx]";
       if ( ${$r_cond_row}[$batchmax_idx] > 0 ){
          $batch_txt .= "," . "${$r_cond_row}[$batchmax_idx]";
       }
       if ( ${$r_cond_row}[$batchret_idx] > 0 ){
          if(! (${$r_cond_row}[$batchmax_idx] > 0 )) {
                $batch_txt .= "," . "${$r_cond_row}[$batchmax_idx]";
          }
          $batch_txt .= "," . "${$r_cond_row}[$batchret_idx]";
       }
       if ( ${$r_cond_row}[$batchsize_idx] > 0 ){
          if(! (${$r_cond_row}[$batchmax_idx] > 0 )) {
                $batch_txt .= "," . "${$r_cond_row}[$batchmax_idx]";
          }
          if(! (${$r_cond_row}[$batchret_idx] > 0 )) {
                $batch_txt .= "," . "${$r_cond_row}[$batchret_idx]";
          }
          $batch_txt .= "," . "${$r_cond_row}[$batchsize_idx]";
       }
    }

    if ( ${$r_cond_row}[$auditlog_idx] > 0 ) {
       $audit_report = ${$r_cond_row}[$auditlog_idx];
    }
    
    # display the example command
    unless ($Opt_No_HDR) {
        printIMsg("IMsglsconditionMkcondEx", $cond_name_msg);
    }
    printf "mkcondition -r %s -e %s -E %s -d %s -D %s -s %s %s -S %s -m %s -g %s %s %s\n",
        $rsrc_class, $ev_expr, $rearm_expr, $ev_desc, $rearm_desc,
        $sel_str, $put_node, $severity, $mgt_scope, $audit_report, $batch_txt, $cond_name;
    print "\n";
}
}   # end display_cmd_ex

#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#--------------------------------------------------------------------#
sub print_usage
{
&printIMsg("IMsglsconditionUsageU");
}   # end print_usage

#-------------------------------------------------------------------#
# containSplChar : returns with error msg if the string has spl char#
#-------------------------------------------------------------------#
sub containSplChar ($)
{
local %specialCharString = (
    '\cA' => "^A",
    '\cB' => "^B",
    '\cC' => "^C",
    '\cD' => "^D",
    '\cE' => "^E",
    '\cF' => "^F",
    '\cG' => "^G",
    '\cH' => "^H",
    '\cI' => "^I",
    '\n' => "\\n",
    '\cK' => "^K",
    '\f' => "\\f",
    '\r' => "\\r",
    '\cN' => "^N",
    '\cO' => "^O",
    '\cP' => "^P",
    '\cQ' => "^Q",
    '\cR' => "^R",
    '\cS' => "^S",
    '\cT' => "^T",
    '\cU' => "^U",
    '\cV' => "^V",
    '\cW' => "^W",
    '\cX' => "^X",
    '\cY' => "^Y",
    '\cZ' => "^Z",
    '\c[' => "^[",
    '\c[\\]' => "^\\",
    '\c]' => "^]",
    '\c^' => "^^",
    '\c_' => "^_",
);
    my $resource=shift(@_);

    foreach $code (keys %specialCharString) {
        if ($resource =~ /$code/) {
            printEMsg("EMsglsconditionInvalidConditionName",$specialCharString{$code});
            return 1;
	}
    }
    return 0;
}