#!/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 = "@(#)65   1.19.1.29   src/rsct/rm/ER/cli/bin/lsresponse.perl, errmcli, rsct_rady, rady2035a 3/27/20 03:20:47"
######################################################################
#                                                                    #
# Module: lsresponse                                                 #
#                                                                    #
# Purpose:                                                           #
#   lsresponse - list actions for one or more response resources     #
#                                                                    #
# Current Syntax:                                                    #
#   lsresponse  [-h] [-A] [-C|-l|-t|-d|-D Delimiter] [-b]            #
#      [-q] [-x] [-U] [-TV] [Response [Response...]:Node_name]       #
#                                                                    #
# Flags:                                                             #
#   -A      Displays all of the attributes associated with the       #
#           response  names.                                         #
#   -C      The output of the command is the mkresponse  command     #
#           that could be used to create the response.   If more     #
#           than one response  is listed, every response  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.           #
#   -h      Help.  Writes this command's usage statement to stdout.  #
#   -l      Long formatted output.  The response  information is     #
#           displayed on separate lines.                             #
#   -a      All. List response information for all nodes in the      #
#           cluster.                                                 #
#   -b      Batching. List the responses that support event          #
#           batching.                                                #
#   -q      Quiet.  Does not return an error when the Condition      #
#           specified does not exist.                                #
#   -t      Tabular formatted output.  The response  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:                                                          #
#   Response        The name of the response whose actions are       #
#                   to be listed. Node_name specifies where the      #
#                   responses are defined.                           #
#                                                                    #
# Description:                                                       #
#   The lsresponse  command is used to list information about        #
#   defined responses.                                               #
#                                                                    #
# 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 responses, run the following command:             #
#        lsresponse                                                  #
#      Output is similar to:                                         #
#        Name                                                        #
#        "E-mail root anytime"                                       #
#        "E-mail root first shift"                                   #
#        "Critical notifications"                                    #
#   2. To list general information about the response                #
#      "Critical notifications" in long format, run the              #
#      following command:                                            #
#        lsresponse "Critical notifications"                         #
#      Output is similar to:                                         #
#       Name             = "Critical notifications"                  #
#       Action           = "Log Critical Event"                      #
#       DaysOfWeek       = 1+2+7                                     #
#       TimeOfDay        = 0000-2400                                 #
#       ActionScript     = "/opt/rsct/bin/logevent \            #
#                          /tmp/criticalEvents"                      #
#       ReturnCode       = 0                                         #
#       CheckReturnCode  = "y"                                       #
#       EventType        = "b"                                       #
#       StandardOut      = "y"                                       #
#       EnvironmentVars  = "Lang=UsEn"                               #
#       UndefRes         = "n"                                       #
#                                                                    #
#       Action           = "E-mail root"                             #
#       DaysOfWeek       = 6+2,6+2,6+5                               #
#       TimeOfDay        = 1700-2400,0000-0800,0000-2400             #
#       ActionScript     = "/opt/rsct/bin/notifyevent root"     #
#       ReturnCode       = 0                                         #
#       CheckReturnCode  = "y"                                       #
#       EventType        = "b"                                       #
#       StandardOut      = "y"                                       #
#       EnvironmentVars  = ""                                        #
#       UndefRes         = "n"                                       #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the mkresponse  man page in /opt/rsct/man.                  #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/errmcli.lsresponse.map - message mapping  #
#                                                                    #
# Outputs:                                                           #
#   stdout - display information on the response.                    #
#   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:                                                   #
#   010120 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.          #
#   011118 JAC 78513: Change parse on colon to use $DELIMITER        #
#   011120 JAC 77597: Distributed RMC. Check for node locator.       #
#   011128 JAC 77599: Add processing for new EnvList in Actions.     #
#   011203 JAC 78058: Add processing for new UndefResFlag in Actions.#
#   011206 JAC 78841: Fix selection string for locating resources.   #
#   020107 JAC 79091: Use correct response variable for lsrsrc.      #
#   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 71728: Add NLS support for headers and xlating values.#
#   020212 JAC 77598: Allow responses with no Actions to be shown.   #
#   020215 JAC 78996: Add new display columns and fix some formats.  #
#   020221 JAC 80506: Allow for multiple locators (sep by commas).   #
#   020301 JAC 80764: Fix for showing UndefRes when no actions.      #
#   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 responses 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 response names and use  #
#                      LIKE in select string.                        #
#   071026 JAC 146726: set delimiters for -api commands.             #
#   081103 JAC 154299: fix for nested foreach on same variable.      #
#   081103 JAC 153203: add error event handling.                     #
#   081113 JAC 153204: add event batching support.                   #
######################################################################

#--------------------------------------------------------------------#
# 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 actions of defined           #
#    responses.                                                      #
#    - 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 response names, call lsrsrc once to get all defined     #
#      response names                                                #
#    - if no response names and -A, call lsrsrc once with attr       #
#      names "Name" and "Actions"                                    #
#    - if at least one response is specified, call lsrsrc for each   #
#      response with attr names "Name" and "Actions"                 #
# C. Do post processing on raw lsrsrc output.                        #
#    - convert Actions SDArray to display-friendly data and insert   #
#      into 2D array                                                 #
#      - the following action elements must be converted:            #
#        DaysOfWeek (subroutine)                                     #
#        TimeOfDay (subroutine)                                      #
#        CheckReturnCode, EventType, StandardOut (character swap)    #
# D. Format and display output.                                      #
#    - if at least one response's worth of output was obtained,      #
#      execute display code                                          #
#      - if -C display example mkresponse commands for each response #
#      - 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_api_error process_exit_code
                    remove_api_error in_cluster
                    set_orig_rmc_scope check_set_cluster_scope
                    getIMsg
                    escape_selstr
                    $CTDIR $CTBINDIR $DELIMITERI $DELIMITERO
                    $SEVCRIT $SEVWARN $SEVINFO $GARBAGE
                    $MKCNDCRIT $MKCNDWARN $MKCNDINFO
                    $RMC_CLI_USER_ERROR $RMC_CLI_RSRC_NOT_FOUND
                    $LSNOTFND $LSRSRC $MKRSRC $RSCEVRS);


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

# lsrsrc attribute names
$Attr_Name = "Name";
$Attr_NodeNameList = "NodeNameList";
$Attr_Actions = "Actions";
$Attr_Locked = "Locked";
$Attr_Batching = "EventBatching";

# Action element names
#$Resp_Name = "ResponseName";
#$Act_Name = "Action";
#$Act_DofW = "DaysOfWeek";
#$Act_TofD = "TimeOfDay";
#$Act_Script = "ActionScript";
#$Act_RetCd = "ReturnCode";
#$Act_CkRetCd = "CheckReturnCode";
#$Act_EvType = "EventType";
#$Act_StdOut = "StandardOut";
#$Act_EnvList = "EnvironmentVars";
#$Act_UndefRes = "UndefRes";


#--------------------------------------------------------------------#
# 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_All_Attrs = $TRUE;                 # default - all attributes
                                        #         -A flag

$Opt_Mkresp_Ex = $FALSE;                # default - do not display
                                        # mkresponse 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_Quiet = $FALSE;                    # default - do not supress display
                                        # of error when non-existent
                                        # response 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

$Opt_Batching = $FALSE;                 # default - don't show only  
                                        # event batching responses

$PROGNAME = "lsresponse";               # 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 = " -x -D $DELIMITERO";      # format options for lsrsrc
$lsr_dbg_opts = "";                     # trace/verbose opts for lsrsrc
@Lof_lsr_output = ();                   # lsrsrc raw output array
@Lof_resps = ();                        # 2D array of response data to
                                        # be displayed
my $locator = "";                       # where to look for the response
my @Resp_list = ();                     # copy of ARGV without locator
my @heading = ();                       # heading for the listed data
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 $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, @Resp_list) = &parse_cmd_line;
($rc == 0) || error_exit($rc);

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

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

# add EventBatching attribute
$lsr_attr_names .= "${DELIMITERI}" . $Attr_Batching;

# 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 to get response data\n";}

# if no response args, force -t
if (($#Resp_list<0) && (!$Opt_All_Attrs)) { $Opt_Table_Format = $TRUE; }

#if ($sARGV) {            # responses given as input
if ($#Resp_list >=0 ) {      # responses given as input
    my @tmp_lsr_output = ();
    my $resp_name = "";
    my $resp_name_orig = "";
#   my $lsr_selstr = "-s 'Name ?= " . "\"ERRMCLI\"" . "'";
  # my $lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\"\"";
  # my $lsr_selstr = "\"Name ?= \\\"ERRMCLI\\\"\"";
    my $lsr_selstr = "\"Name LIKE \\\"ERRMCLI\\\"\"";
    # check to see if node locator is needed
    if ($locator ne "") {
     # $lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\"";
     # $lsr_selstr = "\"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\"";
       $lsr_selstr = "\"Name LIKE \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\"";
    }

    # issue lsrsrc command for each response  provided as input
    foreach $resp_name (@Resp_list) {
        $resp_name_orig = $resp_name;
        $resp_name = escape_selstr($resp_name);
        # $lsr_selstr =~ s/ERRMCLI/$resp_name/;
        $lsr_selstr =~ s/ERRMCLI/%${resp_name}%/;

        # issue the lsrsrc command with the correct flags/operands
    #   @tmp_lsr_output = `$CTBINDIR/$LSRSRC $lsr_selstr $lsr_opts $lsr_dbg_opts $RSCEVRS $lsr_attr_names`;
        $ENV{CT_CLI_QUOTE_STRING} = 1;
        @tmp_lsr_output = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCEVRS}${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 response 
        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("EMsglsresponseResponseNotFound", $resp_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 = "-s 'Name ?= " . "\"ERRMCLI\"" . "'";
     #  $lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\"\"";
     #  $lsr_selstr = "\"Name ?= \\\"ERRMCLI\\\"\"";
        $lsr_selstr = "\"Name LIKE \\\"ERRMCLI\\\"\"";
        # check to see if node locator is needed
        if ($locator ne "") {
         # $lsr_selstr = "-s \"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\"";
         # $lsr_selstr = "\"Name ?= \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\"";
           $lsr_selstr = "\"Name LIKE \\\"ERRMCLI\\\" && NodeNameList|<{\\\"$locator\\\"}\"";
        }

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

        # add EventBatching attribute
        $lsr_attr_names .= "${DELIMITERI}" . $Attr_Batching;

        # 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 \"NodeNameList|<{\\\"$locator\\\"}\"";
       $lsr_selstr = "-s ${RSCEVRS}${DELIMITERI}\"NodeNameList|<{\\\"$locator\\\"}\"";
    }
    # else get them all
    else {
     # $lsr_selstr = "";
       $lsr_selstr = "-o ${RSCEVRS}";
    }

    # issue the lsrsrc command
 #  @Lof_lsr_output = `$CTBINDIR/$LSRSRC $lsr_opts $lsr_dbg_opts  $lsr_selstr $RSCEVRS $lsr_attr_names`;
    $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) );
          ($rc == $RMC_CLI_RSRC_NOT_FOUND) && ( exit(0) ); # 100936
          error_exit(ERRM_CLI_RMC_ERROR);
       }
    }

    chomp(@Lof_lsr_output);
}

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

#
# post-process raw lsrsrc oputput
#

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

my $i = 1;
my $j = 0;
my $line = "";
my $attr_val = "";
my $attr_name = "";
my $resp_name = "";
my $act_rawstr = "";
my $act_line = "";
my $act_disp_elt = "";
my @attr_vals = "";
my @attr_names = ();
my @action_SDs = ();
my @act_display = ();

my $nodenamelst_idx = 1;        
my $batching_idx = 0;
my $locked_idx = 3;
my @uheading = ();

# set up "attribute" names
#push(@attr_names, $Resp_Name);
#if ($Opt_All_Attrs) {
#    # build array of names
#    push(@attr_names, $Act_Name);
#    push(@attr_names, $Act_DofW);
#    push(@attr_names, $Act_TofD);
#    push(@attr_names, $Act_Script);
#    push(@attr_names, $Act_RetCd);
#    push(@attr_names, $Act_CkRetCd);
#    push(@attr_names, $Act_EvType);
#    push(@attr_names, $Act_StdOut);
#    push(@attr_names, $Act_EnvList);
#    push(@attr_names, $Act_UndefRes);
#}

# get heading from message file based on long or short version
if ($Opt_All_Attrs) { @heading = getIMsg("IMsglsresponseLHeading2");}
else { @heading = getIMsg("IMsglsresponseSHeading");}

if ($Opt_All_Attrs) {
   if ($cluster_env) { @heading = getIMsg("IMsglsresponseLCHeading2");}
   else { @heading = getIMsg("IMsglsresponseLHeading2");}
}
else {
   if ($cluster_env) { @heading = getIMsg("IMsglsresponseSCHeading");}
   else { @heading = getIMsg("IMsglsresponseSHeading");}
}

# see if Locked heading is needed
if ($Opt_Show_Locked) {
    @uheading = getIMsg("IMsglsresponseUHeading");
    $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("IMsglsresponseNoYes");
    @lockedstatustext = split(/::/,$lockedstatustext[0]);
}

# form the heading
@attr_names = split(/::/,$heading[0]);

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

# create rows of data
$i = 1;
    if ($Opt_All_Attrs) {
      foreach $line (@Lof_lsr_output) {
        # full response-action data

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

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

        # determine where the Locked attr is, in case it's there
        # (needs to be done after the split. too bad it's in a loop
        $locked_idx = $#attr_vals;

        $resp_name = $attr_vals[0];

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

        # determine where the EventBatching attr is
        # (needs to be done after the split. too bad it's in a loop)
        if ($Opt_Show_Locked) {
           $batching_idx = $#attr_vals -1;
        }
        else {
           $batching_idx = $#attr_vals;
        }

        # if -b was used, only show those responses that support event batching
        if ($Opt_Batching) {
           if ($attr_vals[$batching_idx] ==0) {
              next;
           }
        }


        # change event batching status from integer to string for display
        if ($attr_vals[$batching_idx] eq "0") {
                $attr_vals[$batching_idx] = "\"n\"";
            }
        else { $attr_vals[$batching_idx] = "\"y\""};

        # get actions and set up index based on cluster or not
        if ($cluster_env) { 
           $act_rawstr = $attr_vals[2]; 
           $act_start_idx = 3;
           $act_end_idx = 12;
           $attr_vals[1] =~ s/{//;
           $attr_vals[1] =~ s/}//;
        }
        else {
           $act_rawstr = $attr_vals[1];
           $act_start_idx = 2;
           $act_end_idx = 11;
        }

        # gotta keep the quote police happy
        unless ( $resp_name =~ /"/ ) {
            $resp_name = "\"" . $resp_name . "\"";
        }

        # fill in nulls for the action if there's no actions 
        if (($act_rawstr eq "{}") || ($act_rawstr eq "{[]}")) {
           $Lof_resps[$i][0]="";
           $Lof_resps[$i][1]=$resp_name;
           if ($cluster_env) { $Lof_resps[$i][2]=$attr_vals[1]; } 
           for ($j=$act_start_idx;$j<=$act_end_idx;$j++){
              $Lof_resps[$i][$j]="";
           }
           $i++;
           $j=0;
        }
        else {

           # now we need to process raw action data to make it suitable for display

           # - discard leading/trailing grouping characters
           $act_rawstr =~ s/^{\[//;
           $act_rawstr =~ s/\]}$//;

           # - put each action SD in its own array element
           @action_SDs = split(/\],\[/, $act_rawstr);

           # - convert each action line to displayable format and load
           #   into the 2D display array
           foreach $act_line (@action_SDs) {

               # special case: 0th elt must be empty
               $Lof_resps[$i][$j] = "";
               $j++;                   

               # special case: 1st elt must be response name
               $Lof_resps[$i][$j] = $resp_name;
               $j++;

               # add the nodename if in a cluster
               if ($cluster_env) {
                  $Lof_resps[$i][$j] = $attr_vals[1];
                  $j++;
               }

               # call processing routine
               process_action_data($act_line, \@act_display);

               # load 2D display array
               foreach $act_disp_elt (@act_display) {

                   # transfer the display-ready action elements
                   $Lof_resps[$i][$j] = $act_disp_elt;
                   $j++;
               }

               # add the event batching information
               $Lof_resps[$i][$j] = $attr_vals[$batching_idx];
               $j++;

               # add the locked information if needed
               if ($Opt_Show_Locked) {
                  $Lof_resps[$i][$j] = $attr_vals[$locked_idx];
                  $j++;
               }

               $i++;
               $j = 0;
           }
        }
       }
      }
    else {
        # response names only and maybe nodename
        $i = 1;
        $j = 1;
        foreach $line (@Lof_lsr_output) {

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

           # determine where the Locked attr is, in case it's there
           # (needs to be done after the split. too bad it's in a loop)
           $locked_idx = $#attr_vals;

           # determine where the EventBatching attr is
           # (needs to be done after the split. too bad it's in a loop)
           if ($Opt_Show_Locked) {
              $batching_idx = $#attr_vals -1;
           }
           else {
              $batching_idx = $#attr_vals;
           }

           # if -b was used, only show those responses that support event batching
           if ($Opt_Batching) {
              if ($attr_vals[$batching_idx] ==0) {
                 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];
           }

           # 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
           foreach $attr_val (@attr_vals) {
              $Lof_resps[$i][$j] = $attr_val;
              $j++;
           }
           $j = 1;
           $i++;
        }
    } # end if ($Opt_All_Attrs)

#
# display output
#

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

    if ($Opt_Mkresp_Ex) {      # -C: display mkresponse  example
        if ($Trace) {print STDERR "$PROGNAME: calling display_cmd_ex to display response data\n";}
       display_cmd_ex(\@Lof_resps);
    }
    else {                     # standard display
         if ($Trace) {print STDERR "$PROGNAME: calling set_display to display response data\n";}
        unless ($Opt_No_HDR) { printIMsg("IMsglsresponseOut"); }
        my $display_type = "";
        my $col_count = scalar(@{$Lof_resps[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_resps, $Opt_Delm_Str);
    }

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

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

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_Mkresp_Ex     output   True (-C) example mkresponse 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_Quiet         output   True (-q) no undef response  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             #
#   $Opt_Batching      output   True (-b) display batching responses #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my %opts = ();
my $locator = "";
my $temp_name = "";
my @responses = ();

# Process the command line...
if (!GetOptions( \%opts,
		'h' ,
		'A' ,
		'C' ,
		'l' ,
		't' ,
		'd' ,
		'D=s' ,
		'a' ,
		'b' ,
		'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);
unless ($sARGV) {
    $Opt_Long_Format = $FALSE;          # though long is normally default
    $Opt_Table_Format = $TRUE;          # format, if there are no resps
}                                       # then set to tabular

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

# 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 responses 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{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_Mkresp_Ex = $FALSE;
    $Opt_Long_Format = $FALSE;
    $Opt_Delm_Format = $FALSE;
}

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

if (defined $opts{C}) {                 # -C example mkresponse cmd
    if ($sARGV) {
        $Opt_Mkresp_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;                 # response  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{b}) {                 # -b show event batching only
    $Opt_Batching = $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, @responses);        # success
}   # end parse_cmd_line



#--------------------------------------------------------------------#
# process_action_data - convert raw action SD to array of            #
#                       displayable action elements                  #
#                                                                    #
# Input parameters:                                                  #
#   $raw_actdata     a single action SD string with outer brackets   #
#                    removed                                         #
#                                                                    #
# Output parameters:                                                 #
#   $r_act_output    reference to a single dimension array of        #
#                    formatted action elements                       #
#--------------------------------------------------------------------#
sub process_action_data {

my($raw_actdata, $r_act_output) = @_;

my $i = 0;
my $start_pos = 0;
my $cur_pos = 0;
my $end_pos = length($raw_actdata);
my $ss_len = 0;
my $end_envlist = 0;
my $temp_str = "";
my $raw_time = "";
my $raw_dow = "";
my @temp_arr = ();
my @start_time = ();
my @end_time = ();
my @dow = ();

if ($Trace) {print STDERR "$PROGNAME: entering process_action_data\n";}

# save action name (no conversion needed)
$cur_pos = index($raw_actdata, "{");
$temp_str = substr($raw_actdata, $start_pos, $cur_pos - 1);
if ( $temp_str =~ /"/ ) {
    ${$r_act_output}[0] = $temp_str;
}
else {
    ${$r_act_output}[0] = "\"" . $temp_str . "\"";
}

# get DaysOfWeek data (conversion needed)
$start_pos = $cur_pos + 1;
$cur_pos = index($raw_actdata, "}");
$ss_len = $cur_pos - $start_pos;
$temp_str = substr($raw_actdata, $start_pos, $ss_len);
@temp_arr = split(/,/, $temp_str);
foreach $raw_dow (@temp_arr) {
    push(@dow, cvt_dow($raw_dow));
}

# save DaysOfWeek display data
${$r_act_output}[1] = $dow[0];
for ($i = 1; $i <= $#dow; $i++) {
    ${$r_act_output}[1] .= "," . $dow[$i];
}

# get StartTime data (conversion needed)
$start_pos = index($raw_actdata, "{", $cur_pos) + 1;
$cur_pos = index($raw_actdata, "}", $start_pos);
$ss_len = $cur_pos - $start_pos;
$temp_str = substr($raw_actdata, $start_pos, $ss_len);
@temp_arr = split(/,/, $temp_str);
foreach $raw_time (@temp_arr) {
    push(@start_time, cvt_tod($raw_time));
}

# get EndTime data (conversion needed)
$start_pos = index($raw_actdata, "{", $cur_pos) + 1;  
$cur_pos = index($raw_actdata, "}", $start_pos);     
$ss_len = $cur_pos - $start_pos;                      
$temp_str = substr($raw_actdata, $start_pos, $ss_len);
@temp_arr = split(/,/, $temp_str);
foreach $raw_time (@temp_arr) {
    push(@end_time, cvt_tod($raw_time));            
}

# save TimeOfDay data
${$r_act_output}[2] = $start_time[0] . "-" . $end_time[0];
for( $i = 1; $i <= $#start_time; $i++ ) {
    ${$r_act_output}[2] .= "," . $start_time[$i] . "-" . $end_time[$i];
}

# save action script string (no conversion needed)
$start_pos = index($raw_actdata, ",", $cur_pos) + 1;
$cur_pos = index($raw_actdata, ",", $start_pos);
$ss_len = $cur_pos - $start_pos;
$temp_str = substr($raw_actdata, $start_pos, $ss_len);
if ( $temp_str =~ /"/ ) {
    ${$r_act_output}[3] = $temp_str;
}
else {
    ${$r_act_output}[3] = "\"" . $temp_str . "\"";
}

# save EventType, CheckReturnCode, ReturnCode, StandardOut
$start_pos = $cur_pos + 1;
$temp_str = substr($raw_actdata, $start_pos, $end_pos);
@temp_arr = split(/,/, $temp_str);

# display order does not match stored order
${$r_act_output}[4] = $temp_arr[2];    # ReturnCode
${$r_act_output}[5] = $temp_arr[1];    # CheckReturnCode
${$r_act_output}[6] = $temp_arr[0];    # EventType
${$r_act_output}[7] = $temp_arr[3];    # StandardOut

# change numeric values to strings for display
if (${$r_act_output}[5] eq "0") {    #CheckReturnCode
    ${$r_act_output}[5] = "\"n\"";
}
else {
    ${$r_act_output}[5] = "\"y\"";
}

if (${$r_act_output}[6] eq "1") {    #EventType
    ${$r_act_output}[6] = "\"a\"";
}
elsif (${$r_act_output}[6] eq "2") {
    ${$r_act_output}[6] = "\"r\"";
}
elsif (${$r_act_output}[6] eq "3") {
    ${$r_act_output}[6] = "\"b\"";
}
elsif (${$r_act_output}[6] eq "4") {
    ${$r_act_output}[6] = "\"e\"";
}
elsif (${$r_act_output}[6] eq "5") {
    ${$r_act_output}[6] = "\"ae\"";
}
elsif (${$r_act_output}[6] eq "6") {
    ${$r_act_output}[6] = "\"re\"";
}
elsif (${$r_act_output}[6] eq "7") {
    ${$r_act_output}[6] = "\"A\"";
}
else {
    ${$r_act_output}[6] = "\"?\"";
}

if (${$r_act_output}[7] eq "0") {    #StandardOut
    ${$r_act_output}[7] = "\"n\"";
}
else {
    ${$r_act_output}[7] = "\"y\"";
}

# get the EnvList info
$start_pos = index($raw_actdata,"{",$start_pos);
$end_envlist = index($raw_actdata,"},",$start_pos);
$ss_len = $end_envlist-$start_pos-1;
${$r_act_output}[8] = substr($raw_actdata,$start_pos+1,$ss_len);

# for EnvList, remove {} around the array
#${$r_act_output}[8] =~ s/\}$//;
#${$r_act_output}[8] =~ s/^\{//;

# if it has imbedded double quotes, surround EnvList with single quotes
if (index(${$r_act_output}[8],"\"")>=0) {
   ${$r_act_output}[8] = "'" . ${$r_act_output}[8] . "'";
}
# else put double quotes around EnvList
else {
   ${$r_act_output}[8] = "\"" . ${$r_act_output}[8] . "\"";
}

# get UndefResFlag
$start_pos = $end_envlist+2;
${$r_act_output}[9] = substr($raw_actdata,$start_pos,1);

# change numeric values to strings for display
if (${$r_act_output}[9] eq "0") {    #UndefResFlag
    ${$r_act_output}[9] = "\"n\"";
}
else {
    ${$r_act_output}[9] = "\"y\"";
}


if ($Trace) {print STDERR "$PROGNAME: leaving process_action_data\n";}

}    # end sub process_action_data


#--------------------------------------------------------------------#
# cvt_dow - convert raw DaysOfWeek data to display format            #
#                                                                    #
# Return: $dow_str   display-friendly DaysOfWeek string              #
#                                                                    #
# Input parameters:                                                  #
#   $raw_dow_str     raw DaysOfWeek data                             #
#--------------------------------------------------------------------#
sub cvt_dow{

my $raw_dow_str = shift;

my $raw_dow = 0;
my $dow_str = "";
my $i = 0;
my $range_ct = 0;

my @day_arr = ( $FALSE, $FALSE, $FALSE, $FALSE, $FALSE, $FALSE, $FALSE );

if ($Trace) {print STDERR "$PROGNAME: entering cvt_dow\n";}

$raw_dow += $raw_dow_str;
# special case: 0 and 127 both mean days 1-7
($raw_dow == 0) && ($raw_dow = 127);

# figure out which days are specified
if ($raw_dow >= 64) {
    $raw_dow -= 64;
    $day_arr[6] = $TRUE;
}
if ($raw_dow >= 32) {
    $raw_dow -= 32;
    $day_arr[5] = $TRUE;
}
if ($raw_dow >= 16) {
    $raw_dow -= 16;
    $day_arr[4] = $TRUE;
}
if ($raw_dow >= 8) {
    $raw_dow -= 8;
    $day_arr[3] = $TRUE;
}
if ($raw_dow >= 4) {
    $raw_dow -= 4;
    $day_arr[2] = $TRUE;
}
if ($raw_dow >= 2) {
    $raw_dow -= 2;
    $day_arr[1] = $TRUE;
}
if ($raw_dow == 1) {
    $day_arr[0] = $TRUE;
}

# now build the DaysOfWeek display string
for( $i = 1; $i < 8; $i++ ) {
    if (!$day_arr[$i-1]) {
        # this day was not selected, so zero out range counter
        # and loop again
        $range_ct = 0;
        next;
    }
    else {
        # this day was selected
        if ($dow_str eq "") {
            # first day selected - copy to output, bump range counter
            $dow_str = $i;
            $range_ct++;
            next;
        }
        else {
            if ($range_ct > 0) {
                if ($range_ct > 1) {
                    if ($range_ct > 2) {
                        # range of 3 or more days already exists
                        # delete last day number and replace with this one
                        chop($dow_str);
                        $dow_str .= $i;
                        $range_ct++;
                        next;
                    }
                    else {
                        # matched 3rd day in range - delete "+x" and
                        # replace with "-y" to denote range
                        chop($dow_str);
                        chop($dow_str);
                        $dow_str .= "-" . $i;
                        $range_ct++;
                        next;
                    } # end if ($range_ct > 2)
                }
                else {
                    # matched 2nd day in range - just add "+x" to
                    # existing string
                    $dow_str .= "+" . $i;
                    $range_ct++;
                    next;
                } # end if ($range_ct > 1)
            }
            else {
                # discontiguous day matched
                $dow_str .= "+" . $i;
                $range_ct++;
                next;
            } # end if ($range_ct > 0)
        } # end if ($dow_str eq "")
    } # end if (!$day_arr[$i-1])
} # end for loop

if ($Trace) {print STDERR "$PROGNAME: leaving cvt_dow\n";}

return($dow_str);
}    # end sub cvt_dow


#--------------------------------------------------------------------#
# cvt_tod - convert raw TimeOfDay data to display format             #
#         - used for both start and end time data                    #
#                                                                    #
# Return: $tod_str   TimeOfDay string in HHMM format                 #
#                                                                    #
# Input parameters:                                                  #
#   $raw_tod_str     raw TimeOfDay data                              #
#--------------------------------------------------------------------#
sub cvt_tod{                                                          

my $raw_tod_str = shift;

my $tod_str = "";       
my $time_hrs = 0;
my $time_mins = 0;

if ($Trace) {print STDERR "$PROGNAME: entering cvt_tod\n";}

use integer;
$time_hrs = $raw_tod_str / 3600;
$time_mins = ($raw_tod_str - $time_hrs * 3600) / 60;

# if hours or minutes in single digits, add leading 0 to
# provide HHMM format
if ($time_hrs < 10) { $time_hrs = "0" . $time_hrs; }
if ($time_mins < 10) { $time_mins = "0" . $time_mins; }

$tod_str = $time_hrs . $time_mins;
no integer;

if ($Trace) {print STDERR "$PROGNAME: leaving cvt_tod\n";}

return($tod_str);
}    # end sub cvt_tod                                                


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

my $r_resps = shift;

my $r_resp_row = 0;
my $act_name = "";
my $dow = "";
my $tod = "";
my $act_scrpt = "";
my $ret_code = "";
my $ev_type = "";
my $resp_name = "";
my $resp_name_msg = "";          # 71402
my $act_name_msg = "";           # 71402
my $batch = "";

my $i = 0;
my $aname_idx = 2;
my $date_idx = 3;
my $time_idx = 4;
my $ascr_idx = 5;
my $rtcd_idx = 6;
my $evtp_idx = 8;
my $evbc_idx = 12;

# reset index if in cluster
if ($cluster_env) {
   $aname_idx = 3;
   $date_idx = 4;
   $time_idx = 5;
   $ascr_idx = 6;
   $rtcd_idx = 7;
   $evtp_idx = 9;
   $evbc_idx = 13;
}

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

    # extract data from output array
    $act_name = ${$r_resp_row}[$aname_idx];
    $dow = ${$r_resp_row}[$date_idx];
    $tod = ${$r_resp_row}[$time_idx];
    $act_scrpt = ${$r_resp_row}[$ascr_idx];
    $ret_code = ${$r_resp_row}[$rtcd_idx];
    $ev_type = ${$r_resp_row}[$evtp_idx];
    chop($ev_type);
    $ev_type =~ s/\"//;
    $resp_name = ${$r_resp_row}[1];
    $resp_name_msg = $resp_name;              # 71402
    $resp_name_msg =~ s/\"//g;                # 71402
    $act_name_msg = $act_name;                # 71402
    $act_name_msg =~ s/\"//g;                 # 71402
    if (${$r_resp_row}[$evbc_idx] =~ /y/) {$batch=" -b ";}

    # display the example command
    unless ($Opt_No_HDR) {
        printIMsg("IMsglsresponseMkrespEx", $resp_name_msg, $act_name_msg);
    }
    printf "mkresponse -n %s -d %s -t %s -s %s -e %s -r %s %s %s\n",
        $act_name, $dow, $tod, $act_scrpt, $ev_type,
        $ret_code, $batch, $resp_name;
    print "\n";
}
}   # end display_cmd_ex

#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#--------------------------------------------------------------------#
sub print_usage
{
&printIMsg("IMsglsresponseUsageB");
}   # 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("EMsglsresponseInvalidResponseName",$specialCharString{$code});
            return 1;
        }
    }
    return 0;
}