#!/usr/sbin/rsct/perl5/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2007 
# 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 
#"@(#)33   1.57   src/rsct/rmc/cli/bin/lsrsrc.perl, rmccli, rsct_relgh, relghs001a 10/25/06 09:56:29"
######################################################################
#                                                                    #
# Module: lsrsrc                                                     #
#                                                                    #
# Purpose:                                                           #
#   lsrsrc - Lists (displays) resources or a resource class.         #
#                                                                    #
# Syntax:                                                            #
#   lsrsrc [-h] [-s "Selection_string"] [-A p|d|b] [-p Property]     #
#          [-a] [-l|-i|-t|-d|-D Delimiter] [-x] [-T] [-V]            #
#          [Resource_class [Attr...]]                                #
#                                                                    #
#   lsrsrc [-h] [-s "Selection_string"] -r  [-a]                     #
#          [-l|-t|-d|-D Delimiter] [-x] [-T] [-V] [Resource_class]   #
#                                                                    #
#   lsrsrc [-h] -c [-A p|d|b] [-p Property] [-a]                     #
#          [-l|-i|-t|-d|-D Delimiter] [-x] [-T] [-V]                 #
#          [Resource_class [Attr...]                                 #
#                                                                    #
#   lsrsrc [-h] -C Peer_domain_names [-A p|d|b] [-p Property]        #
#          [-l|-i|-t|-d|-D Delimiter] [-x] [-T] [-V]                 #
#          [Resource_class [Attr...]                                 #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes the command's usage statement to stdout.    #
#   -c      Class. Displays the attributes for the resource class.   #
#           By default, the resource attributes, not the resource    #
#           class, are displayed. This flag overrides the -r flag.   #
#   -C Peer_domain_names  Class. Displays the attributes for the     #
#           globalized resource class in a peer domain in a managment#
#           domain.  Peer_domain_names is a list of peer domains     #
#           separated by a comma.                                    #
#           By default, the resource attributes, not the resource    #
#           class, are displayed. This flag overrides the -r flag.   #
#   -r      Resource Handle. Displays the resource handles for the   #
#           resources that match the specified selection string or   #
#           all resources when no selection string is specified.     #
#   -s "Selection string" Specifies the selection string. All        #
#           selection strings must be enclosed within either double  #
#           or single quotation marks. If the selection string       #
#           contains double quotation marks, enclose the entire      #
#           selection string in single quotation marks. For example: #
#           -s 'Name == "testing"'                                   #
#           -s 'Name ?= "test"'                                      #
#           Only persistent attributes can be listed in a selection  #
#           string.                                                  #
#   -A      Attribute type. By default only persistent attributes    #
#           are displayed. This flag can be used only when no        #
#           attribute names are specified on the command line.       #
#           p - Displays only persistent attributes.                 #
#           d - Displays only the dynamic attributes.                #
#           b - Displays both persistent and dynamic attributes.     #
#           For best performance, specify the -A p flag.             #
#   -p Property Displays attributes with the specified property. By  #
#           default, only public attributes are displayed. To        #
#           display all the attributes regardless of the property,   #
#           use the -p 0 flag. Use this flag in conjunction with     #
#           the -A flag when no attributes are specified on the      #
#           command line. Refer to ct_mc.h for persistent and        #
#           dynamic property values. An or-ing of the properties     #
#           will be accepted to display only attributes that have    #
#           any of the specified properties.                         #
#   -a      All nodes. The lsrsrc command applies to all nodes in    #
#           the cluster. The cluster scope is determined by the      #
#           environment variable CT_MANAGEMENT_SCOPE. If it is not   #
#           set, first the management domain scope is used, then     #
#           peer domain scope, and then local scope is used until    #
#           the scope is a valid scope for the command. The command  #
#           will run once for the first valid scope found.           #
#   -l      Long formatted output. Each attribute is displayed on a  #
#           separate line. This is the default display format. If    #
#           the lsrsrc command is issued with the -l flag, but       #
#           without a resource class name, the -l flag is ignored    #
#           when the command returns the list of defined resource    #
#           class names.                                             #
#   -i      Input format. Generates a template of the Resource Data  #
#           Input File which can then, after appropriate editing, be #
#           used as input to the mkrsrc command. The output is       #
#           displayed in long (stanza) format. All required and      #
#           optional attributes that can be used to define a         #
#           resource are displayed. The attribute data type is       #
#           displayed as the value in the Attr=value pairs. It is    #
#           suggested that when you use this flag, the output of the #
#           lsrsrc command be directed to a file.                    #
#           The -i flag overrides the -Ad, and -Ab flags and is      #
#           ignored if -r is specified.                              #
#   -t      Tabular formatted output. Each attribute is displayed    #
#           in a separate column, one resource per 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 using 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.                     #
#   -x      Exclude header. Suppresses header printing.              #
#   -T      Trace. Writes the command's trace messages to standard   #
#           error. For your software-service organization use only.  #
#   -V      Verbose. Writes this command's verbose messages to       #
#           standard output.                                         #
#                                                                    #
# Operands:                                                          #
#   Resource_class  Resource class name. The name of the resource    #
#                   class whose resources you wish displayed. Zero   #
#                   or one Resource_class operand can be specified.  #
#                   If no Resource_class operand is specified, a     #
#                   list of all resource class names is displayed.   #
#                                                                    #
#  Attr             Attribute name. Both persistent and dynamic      #
#                   attribute names may be specified to control      #
#                   which attributes are displayed and their order.  #
#                   Zero or more attribute may be specified.         #
#                   Attributes must be separated by spaces. If no    #
#                   attribute names are specified, the -A p|d|b flag #
#                   controls whether only persistent attributes,     #
#                   only dynamic attributes, or both persistent and  #
#                   dynamic attributes are displayed.                #
#                                                                    #
# Description:                                                       #
#   The lsrsrc command is used to list the persistent and dynamic    #
#   attributes and their values of either a resource or resource     #
#   class.                                                           #
#                                                                    #
#   When no Attr operand is specified, only attributes that are      #
#   defined as public are displayed. Use the -p flag to override     #
#   this default. When no Attr operand is specified, the -A p|d|b    #
#   flag controls whether only persistent, or only dynamic or both   #
#   persistent and dynamic attributes and their values are displayed.#
#                                                                    #
#   When one or more attribute names are specified, exactly the      #
#   attribute names specified and their values are displayed in the  #
#   order specified, provided that each of the specified attribute   #
#   names are valid.                                                 #
#                                                                    #
#   To get a list of all of the resource classes, enter the lsrsrc   #
#   command with no operands.                                        #
#                                                                    #
#   Specify the -c flag to display a list of the resource class      #
#   attributes and values.                                           #
#                                                                    #
#   Specify the -r flag to display only the resource handles         #
#   linked with the resources for the specified class.               #
#                                                                    #
#   Specify the -a flag to display resources from all nodes in the   #
#   cluster.                                                         #
#                                                                    #
#   By default the resource attributes and values are displayed in   #
#   long format. Use the -t, -d, or -D flags for the resources       #
#   to be displayed in tabular or delimiter formatted output.        #
#                                                                    #
#   For best performance, specify either the -A p flag or only       #
#   persistent attributes as operands.                               #
#                                                                    #
#   Note: Any attribute that has a data type defined as ct_none (for #
#         example, a Quantum) is not listed by the lsrsrc command.   #
#         RMC does not return attribute values for attributes that   #
#         are defined as Quantum. To list attribute definitions,     #
#         use the lsrsrcdef command.                                 #
#                                                                    #
# Exit Values:                                                       #
#   0  MC_CLI_SUCCESS        Command completed successfully.         #
#   1  MC_CLI_RMC_ERROR      Command terminated due to an underlying #
#                            RMC error.                              #
#   2  MC_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  MC_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   4  MC_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   5  MC_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            Resource name as the Resource operand.  #
#                                                                    #
# Examples:                                                          #
#   1. List all the resource class names                             #
#      lsrsrc                                                        #
#   2. List IBM.Processor resource persistent attributes.            #
#      lsrsrc IBM.Processor                                          #
#   3. List IBM.Host resource dynamic attributes.                    #
#      lsrsrc -Ad IBM.Host                                           #
#   4. List IBM.Condition resource class persistent attributes.      #
#      lsrsrc -c IBM.Condition                                       #
#   5. List IBM.Processor resource persistent attributes Name and    #
#      ProcessorType in tabular format (long is the default format). #
#      lsrsrc -t IBM.Processor Name ProcessorType                    #
#   6. List only the resource handles associated with IBM.Condition  #
#      resources that have a Name containing the word Page.          #
#      lsrsrc -r -s 'Name ?= "Page"' IBM.Condition                   #
#   7. List both Persistent and Dynamic Attributes                   #
#      lsrsrc -Ab IBM.Foo                                            #
#   8. List specific Persistent and Dynamic Attributes               #
#      lsrsrc IBM.Foo Name OpState                                   #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the lsrsrc man page in /usr/sbin/rsct/man.                       #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /usr/sbin/rsct/msgmaps/mccli.lsrsrc.map - message mapping        #
#   /usr/sbin/rsct/msgmaps/mccli.mccli.map - message mapping         #
#                                                                    #
# Outputs:                                                           #
#   stdout - display of the resource or resource class attr & values.#
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  MC_cli_utils.pm, MC_cli_rc.pm, MC_cli_display_utils.pm #
#             CT_cli_utils.pm, CT_cli_input_utils                    #
#   Perl library routines: Getopt::Long                              #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   990924 SAB 48420: Initial design & write.                        #
#   010311 SAB 63852: Prepared for GA.                               #
#   020220 JAC 79829: Make some changes for distributed rmc for when #
#                     some nodes respond and some don't.             #
#   020716 JAC 84819: Change -a to -A and use -a for all in cluster. #
#   020801 JAC 85417: Update usage message.                          #
#   020802 JAC 84820: Add -i flag.                                   #
#   020822 JAC 88082: Rework code to use lsrsrc-api.                 #
#   021108 JAC 89001: Fix for autouse needs to be use.               #
#   021206 JAC 89575: Quoting of RHs and binary values.              #
#   030206 JAC 91053: Fix setting of p/d attr counters for heading.  #
#   030214 JAC 90033: Add code to quote BIN/RH in SDs.               #
#   030219 JAC 89003: Check for NodeList attr being one element.     #
#   030219 JAC 91964: Format binary type as strings of 8 hex chars.  #
#   030221 JAC 92015: Fix what output title says when no output.     #
#   030302 JAC 92317: Fix to display string with comma in SD.        #
#   030305 JAC 92311: Put formatting into MC_cli_utils.pm.           #
#   030404 JAC 92787: Don't allow -s "" for selection string.        #
#   030709 JAC 96745: Add delimiter to call to remove_api_error.     #
#   040111 JAC 100165: Add -C flag for peer domains in DM scope.     #
#   040121 JAC 103355: Some fixes for -C flag.                       #
#   040128 JAC 103595: Fix message arg for using -C and -c together. #
#   040216 JAC 104186: Bad attribiute names returned in output.      #
#   040407 JAC 105863: Use escape_chars for "\" searches.            #
#   060620 JAC 135982: -i gets only REQD/OPT DEFINE properties.      #
#   061017 JAC 139644: Don't show ActivePeerDomain if no output.     #
#   061024 JAC 140150: Fix help message.                             #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A. Parse command line flags and operands, determine which flavor   #
#    of this command we are actually invoking.                       #
#       * List either the resource class (-c) or resource attributes.#
#       * List only persistent attributes (-A p - the default)       #
#       * List only dynamic attributes    (-A d)                     #
#       * List both persistent and dynamic attributes (-A b)         #
#       * List only the attributes that were specified on the        #
#         command line.                                              #
# B. Query RMC for the attribute values.                             #
# C. Display the resource attributes and values.                     #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/usr/sbin/rsct/pm";
use locale;
use Getopt::Long; 

use autouse CT_cli_utils => qw(
    printIMsg
    printEMsg
);
use CT_cli_input_utils qw(
    escape_chars
    check_input_file
);

use MC_cli_rc qw(:return_codes);
use MC_cli_utils qw(
    translate_lsAOpt
    error_exit
    process_api_error
    process_exit_code
    remove_api_error
    format_value_for_display
    read_from_Stdin
    printCIMsg 
    printCEMsg
    $RMC_RSRC_PATTR_REQD_FOR_DEFINE
    $RMC_RSRC_PATTR_OPTION_FOR_DEFINE
    $RMC_RSRC_PATTR_PUBLIC
);
use autouse MC_cli_display_utils => qw(
    display_resource_data_api
);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
Getopt::Long::Configure ("bundling", "no_auto_abbrev", 
                         "no_ignore_case", "require_order",
                         "prefix_pattern=(--|-)");
$TRUE = 1;
$FALSE = 0;

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

# By default output is written in long format.
$Opt_Long_Format  = $TRUE;              # default - see -l (long form)
$Opt_Table_Format = $FALSE;             # default - see -t (tabular) 
$Opt_Delm_Format  = $FALSE;             # default - see -d (delimiter)
$Opt_Delm_Str = ":";                    # default - see -D (colon :) 
$Opt_No_HDR = $FALSE;                   # default - see -x
$Opt_LS_Class = $FALSE;                 # default - see -c
$Opt_LS_Class_DM = $FALSE;              # default - see -C
$Opt_LS_DAttr = $FALSE;                 # default - see -A p 
$Opt_LS_PAttr = $TRUE;                  # default - see -A p
$Opt_LS_RHandle = $FALSE;               # default - see -r 
$Opt_LS_Cluster = $FALSE;               # default - see -a 
$Opt_LS_Input_File = $FALSE;            # default - see -i 
$Opt_LS_Classes_Only = $FALSE;          # only listing classes
$Opt_LS_Attr= $FALSE;                   # when attributes are specified
$Opt_Node_File= $FALSE;                 # default - see -N 
$Opt_Stdin= $FALSE;                     # default - see -N with Stdin
$Opt_Properties = $FALSE;               # default - see -p, True if specified

$PROGNAME = "lsrsrc";                   # Program Name for messages
$MSGCAT = "mccli.cat";                  # msg catalogue for this cmd

$CTDIR = "/usr/sbin/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                                                          #
#--------------------------------------------------------------------#
@attributes = ();                       # Attr names from cmd line
@attributes2 = ();                      # Attr names from lsrsrc-api
@attributes3 = ();                      # reformed attr list 
my @lsr_out = ();                       # output from lsrsrc-api
my @lsr_out2 = ();                      # output from lsrsrc-api
my @out_attrs = ();                     # attribute names from output
my @temp_attrs = ();                    # temp list of attributes
my @temp_attrs2 = ();                   # temp list of attributes
my @temp_line = ();                     # temp list of attr/values
my @attr_info = ();                     # output from lsrsrc-api
my $select_str_arg = "";                # reformatted for lsrsrc-api
my $cmd_opts = "";                      # for lsrsrc-api attribute list 
my $at_name =  "";                      # one attribute name
my $nflag   =  "";                      # list attributes or not 
my $line    =  "";                      # line of output
my $temp_attr = "";                     # attribute name 
my $req_properties = 0;                 # Requested properties
                                        # default, public properties
$DELIMITER = "tvrtvrtvr";               # delimiter for lsrsrc-api commands
my $rc2 = 0;
my $i = 0;
my $j = 0;
my $ii = 0;
my $z = 0;
my $y = 0;
my $SDdef_retr = $FALSE;                # indicate if SD infor available
my %SDdefs = ();                        # SD definitions
my $FOUND = $FALSE;
my $num_p_attrs = 0;                    # number of persistent attrs output
my $num_d_attrs = 0;                    # number of dynamic attrs output
my $num_rows = 0;                       # number of output lines
my $class_name = "";                    # resource class name
my $temp_str = "";                      # for reformatting values
my $temp_str2 = "";                     # for reformatting values
my @temp_str_array = ();                # for reformatting values
my %HoAllAttrs = ();                    # hash of all attr values by name
my $peer_domain_names = "";             # peer domain names for -C
my $Opt_LS_Class_OR_Class_DM;           # class option performed    
my @pdnames_out = ();                   # peer domain names if class function
my $PDNAMES_IN_OUTPUT = $FALSE;         # flag to check for peer domain names
my $DM_SCOPE_SET = $FALSE;              # flag to check for DM scope
my $uflag   =  "";                      # list peer domains in output
my $pd_name =  "";                      # to parse out peer domain
my $real_output = "";                   # to hold output without pd name
my $node_file_name;                     # to hold node filename
@LoPAttr = ();                          # attr names 


#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
my $rc = 0;

# look for the old -a option for attributes and change it to -A
@ARGV = translate_lsAOpt(@ARGV);

# parse the command line, exit if there are errors 
($rc, $resource, $select_str, $req_properties, $peer_domain_names, $node_file_name, @attributes) = 
    &parse_cmd_line;
($rc == 0) || error_exit($rc);

# if -a or -N was specified, make sure CT_MANAGEMENT_SCOPE
# is set.  If it isn't, set it to 4, DM/SR/Local 
if (($Opt_LS_Cluster || $Opt_Node_File) && !defined $ENV{CT_MANAGEMENT_SCOPE}) {
   $ENV{CT_MANAGEMENT_SCOPE} = 4;
}

# set DM scope if -C is specified 
if ($Opt_LS_Class_DM) {
   $ENV{CT_MANAGEMENT_SCOPE} = 3;
}

# set DM scope flag if DM or DM/SR/Local scope is set
if ( defined $ENV{CT_MANAGEMENT_SCOPE} && 
       ( $ENV{CT_MANAGEMENT_SCOPE} == 3 || $ENV{CT_MANAGEMENT_SCOPE} == 4 ) ) {
   $DM_SCOPE_SET = $TRUE;
}

# set class op variable
$Opt_LS_Class_OR_Class_DM = $Opt_LS_Class || $Opt_LS_Class_DM;

# set the quote string environment variable, if necessary
if (!defined $ENV{CT_CLI_QUOTE_STRING}){
   $ENV{CT_CLI_QUOTE_STRING} = 1;
}

$select_str = escape_chars($select_str);

# if no resource names specified display the list of resource
# names.
if (!$resource) {               # No resource operands

    # set global variable
    $Opt_LS_Classes_Only = $TRUE;

    # call lsrsrcdef-api to get the list of classes
    if ($Trace) { print STDERR "$PROGNAME: calling lsrsrcdef-api\n";}

    @lsr_out = `$CTBINDIR/lsrsrcdef-api -I $DELIMITER -D $DELIMITER -c "*" 2>&1`;

    # capture the return code from lsrsrcdef-api
    $rc = $?;
    $rc = process_exit_code($rc);

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

    # show any errors if there was a bad rc
    if ($rc != 0) {
       process_api_error($DELIMITER,$rc,@lsr_out);
    }

    # remove any error messages from the output to display
    @lsr_out = remove_api_error($DELIMITER,@lsr_out);

    # extract only the class names
    for ($j=0;$j<=$#lsr_out;$j=$j+2) {
       @temp_line = split(/$DELIMITER/, $lsr_out[$j]);
       push @lsr_out2, $temp_line[0];
    }

    # save the attribute name to display
    push @LoPAttr, "class_name";

    # use table output format
    $Opt_Table_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_LS_DAttr = $FALSE;
    $Opt_LS_PAttr = $FALSE;

    # check for delimited output
    if ($Opt_Delm_Format) { $Opt_Table_Format = $FALSE; }

    # print output if lsrsrcdef-api command worked or there's 
    # something to print
    if ($rc ==0 || $#lsr_out2 >=0 ) 
       {
          # Display the Resource Class Persistent Attributes
          $rc2 = display_resource_api(\@LoPAttr, \@lsr_out2);
          if ($rc == 0) { $rc = $rc2; } 
       }

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

}
elsif ($Opt_LS_RHandle) {
    # List the resource handles

    # call lsrsrc-api
    if ($Trace) { print STDERR "$PROGNAME: calling lsrsrc-api\n";}
    if ($Opt_Node_File)
    {
        # create temp file based on Stdin input
        if ($Opt_Stdin)
        {
            $node_file_name= read_from_Stdin();
        }

        @lsr_out = `$CTBINDIR/lsrsrc-api -I $DELIMITER -D $DELIMITER -i -w ${resource}${DELIMITER}"${select_str}"${DELIMITER}"${node_file_name}" 2>&1`;
 
        # remove temp node file if from STDIN
        if ($Opt_Stdin)
        {
            unlink($node_file_name);
        }
    }
    else
    {
        @lsr_out = `$CTBINDIR/lsrsrc-api -I $DELIMITER -D $DELIMITER -i -s ${resource}${DELIMITER}"${select_str}" 2>&1`;
    }

    # capture the return code from lsrsrc-api
    $rc = $?;
    $rc = process_exit_code($rc);

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

    # show any errors if there was a bad rc
    if ($rc != 0) {
       process_api_error($DELIMITER,$rc,@lsr_out);
    }

    # remove any error messages from the output to display
    @lsr_out = remove_api_error($DELIMITER,@lsr_out);

    # save the attribute name to display
    push @LoPAttr, "ResourceHandle";

    # put quotes around the resource handles
    for ($i=0; $i<=$#lsr_out; $i++) {
       $lsr_out[$i] = "\"".$lsr_out[$i];
       $lsr_out[$i] =~ s/\n/\"\n/;
    }

    # print output if lsrsrc-api command worked or there's 
    # something to print
    if ($rc ==0 || $#lsr_out2 >=0 ) 
       {
          # Display the Resource Class Persistent Attributes
          $rc2 = display_resource_api(\@LoPAttr, \@lsr_out);
          if ($rc == 0) { $rc = $rc2; } 
       }
    ($rc == 0) || error_exit($rc);
}

else {

   # Show only the attributes specified 

   # set up $cmd_opts to have the attribute names
   foreach $at_name (@attributes) {
      $cmd_opts = $cmd_opts . "${DELIMITER}${at_name}";
   }

   # use -n flag in lsrsrc-api
   $nflag = "-n";

   # set up persistent vs dynamic or both if no attribute
   # names were specified.
   if ($#attributes <0) {

      if ($Opt_LS_DAttr && $Opt_LS_PAttr) {
         $cmd_opts = $cmd_opts . "${DELIMITER}*b";
      }
      elsif ($Opt_LS_DAttr){
         $cmd_opts = $cmd_opts . "${DELIMITER}*d";
      }
      elsif ($Opt_LS_PAttr){
         $cmd_opts = $cmd_opts . "${DELIMITER}*p";
      }
      else{
         $cmd_opts = $cmd_opts . "${DELIMITER}*p";
      }

      # set up properties
      $cmd_opts = $cmd_opts . "$req_properties";
   }

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

   # call lsrsrc-api for either resource or resource class
   if ( (!$Opt_LS_Class) && (!$Opt_LS_Class_DM) ) 
   {
       if ($Opt_Node_File)
       {   
           # create temp file based on Stdin input
           if ($Opt_Stdin)
           {
               $node_file_name= read_from_Stdin();
           } 
           
           @lsr_out = `$CTBINDIR/lsrsrc-api -dpt -I $DELIMITER -D $DELIMITER $nflag -i -w ${resource}${DELIMITER}"${select_str}"${DELIMITER}"${node_file_name}"${cmd_opts} 2>&1`;
           
           # remove temp node file if from STDIN
           if ($Opt_Stdin)
           {
               unlink($node_file_name);
           }
       }
       else
       {
           @lsr_out = `$CTBINDIR/lsrsrc-api -dpt -I $DELIMITER -D $DELIMITER $nflag -i -s ${resource}${DELIMITER}"${select_str}"${cmd_opts} 2>&1`;
       }
   }
   else 
   {
      if ($Opt_LS_Class) 
      {
          # make sure to get peer domain names if this is DM scope
          if ($DM_SCOPE_SET) 
          { 
              $uflag = "-u"; 
              $PDNAMES_IN_OUTPUT = $TRUE;
          }
          @lsr_out = `$CTBINDIR/lsrsrc-api -dpt -I $DELIMITER -D $DELIMITER $nflag $uflag -i -c ${resource}${DELIMITER}${cmd_opts} 2>&1`;
      }
      else 
      {
          $PDNAMES_IN_OUTPUT = $TRUE;
          @lsr_out = `$CTBINDIR/lsrsrc-api -dpt -I $DELIMITER -D $DELIMITER $nflag -iu -C ${resource}${DELIMITER}${peer_domain_names}${DELIMITER}${cmd_opts} 2>&1`;
      }
   }

   # capture the return code from lsrsrc-api
   $rc = $?;
   $rc = process_exit_code($rc);

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

   # show any errors if there was a bad rc
   if ($rc != 0) {
      process_api_error(${DELIMITER},$rc,@lsr_out);
   }
   
   # remove any error messages from the output to display
   @lsr_out = remove_api_error($DELIMITER,@lsr_out);

   # if peer domains were returned for class query,
   # take them out of @lsr_out and put in @pdnames_out
   if ($PDNAMES_IN_OUTPUT) {

      @lsr_out2 = ();
      foreach $line (@lsr_out) {
         ($pd_name, $real_output) = split(/$DELIMITER/,$line,2);
         push @lsr_out2, $real_output;
         push @pdnames_out, $pd_name;
      }

      @lsr_out = @lsr_out2;
   }

   # if there were no attributes specified, pull the names
   # out of the lsrsrc-api output
   if ($#attributes <0) {

      # generate attribute list by scanning through @lsr_out
      @out_attrs = ();

      # pull attribute names and data from output
      foreach $line (@lsr_out) {
          @temp_line = split(/$DELIMITER/, $line);
          @temp_attrs = ();

          # get only attribute names
          for ($j=0;$j<=$#temp_line;$j=$j+5){
             $temp_line[$j] =~ s/^\"//;
             $temp_line[$j] =~ s/\"$//;
             
             # for default -i, only use REQD and OPT for define, and PUBLIC
             # attribute.  Check for -i and no -p specified.
             if ( $Opt_LS_Input_File && !$Opt_Properties ) {
                # get the properties field and "and" it with x2A (public/opt/reqd)
                $prop = (hex $temp_line[$j+2]) & 
                           ($RMC_RSRC_PATTR_REQD_FOR_DEFINE   |
                            $RMC_RSRC_PATTR_OPTION_FOR_DEFINE |
                            $RMC_RSRC_PATTR_PUBLIC );
                # if REQD/PUBLIC or OPT/PUBLIC, add it
                if ( ($prop == ($RMC_RSRC_PATTR_REQD_FOR_DEFINE | $RMC_RSRC_PATTR_PUBLIC) ) || 
                     ($prop == ($RMC_RSRC_PATTR_OPTION_FOR_DEFINE | $RMC_RSRC_PATTR_PUBLIC) ) ) { 
                   push @temp_attrs, $temp_line[$j];
                }
             }

             else {
             push @temp_attrs, $temp_line[$j];
             }
          }

          # check to see if this attribute list is different than
          # the composite list       
          if (@out_attrs ne @temp_attrs) {

             # are all the attributes in the composite list
             foreach $attr_name (@temp_attrs) {
                $i = 0;
                $FOUND = $FALSE;

                # look for this attribute name in the list
                while (!$FOUND && (($i<=$#out_attrs) && ($i>=0)) ) {
                   if ($attr_name eq $out_attrs[$i]) { $FOUND = $TRUE; }
                   $i++;
                }

                # if it's not there, just add it to the end
                if (!$FOUND) {
                   push @out_attrs, $attr_name;
                }
             }  
          }  
      }

      # now have list of attributes in @out_attrs
      # assign it to @attributes
      @attributes = @out_attrs;

   }  # end no attributes specified

   # format the output for display
   # @attributes has the attribute name order
   # @lsr_out has the attribute name, def type (p/d), and value
 
   # copy the output and clear out original
   @lsr_out2 = @lsr_out;
   $num_rows = $#lsr_out;
   @lsr_out = ();
   $i = 0;

   # pull data/attribute names out from output
   foreach $line (@lsr_out2) {
       #chomp($line);
       @attr_info = split(/$DELIMITER/, $line);
          
       # split into name, definition type, and data
       for ($j=0;$j<=$#attr_info;$j=$j+5){
          # pull out the attribute name (at j)
          $attr_info[$j] =~ s/^\"//;
          $attr_info[$j] =~ s/\"$//;

          # check if last value, remove the new line character
          if ($j+4 == $#attr_info) {
             chomp($attr_info[$j+4]);
          }

          # format the attribute value if binary, handle or SD
          if ( ($attr_info[$j+1] =~ /^CT_BINARY_PTR/) ||
               ($attr_info[$j+1] =~ /^CT_RSRC_HANDLE_PTR/) ||
               ($attr_info[$j+1] =~ /^CT_SD_PTR/) ) {
             # function call format is value, name, type, class, class_flg,
             #   SDdef_retr, attributes, SDdefs 
             ($attr_info[$j+4], $SDdef_retr) = 
                format_value_for_display($attr_info[$j+4],$attr_info[$j],
                     $attr_info[$j+1], $resource, $Opt_LS_Class_OR_Class_DM, 
                     $SDdef_retr, \@attributes, \%SDdefs);
          }

          # the NodeList attribute special case:
          # lsrsrc-api doesn't put {} around NodeList if there's only one
          # element so we'll do it here (see defect 89003)
          if ( ($attr_info[$j] =~ /^NodeList$/) && ($attr_info[$j+1] =~ /_ARRAY$/)
               && (!($attr_info[$j+4] =~ /^\{/)) ) {
             $attr_info[$j+4] = "{" . $attr_info[$j+4] . "}";
          }

          # pull out the attribute value (at j+4)
          $HoAllAttrs{$attr_info[$j]}[$i]=$attr_info[$j+4];

          # process persistent/dynamic count (used later for heading)
          # (at j+3)
          $attr_info[$j+3] =~ s/^\"//;
          $attr_info[$j+3] =~ s/\"$//;
          if ($attr_info[$j+3] eq "p")  { $num_p_attrs++; }
          if ($attr_info[$j+3] eq "d")  { $num_d_attrs++; }
       }

       $i++;
   }

   # 104186 -  reform the list of attribute names in case some were
   # not valid. Maintain order of names.
   @attributes2 = keys %HoAllAttrs;
   if ( ($#attributes2 != $#attributes) && 
        (! ($Opt_LS_Input_File && !$Opt_Properties) ) ) {
   
       # make a new list of those attrs in both @attributes and @attributes2
       @attributes3 = ();
       foreach $temp_attr (@attributes) {
          $FOUND = $FALSE;
          foreach $temp_attr2 (@attributes2) {
             if ($temp_attr eq $temp_attr2) { $FOUND = $TRUE; }
          }
          if ($FOUND) { push @attributes3, $temp_attr; }
       }

       # create the new list
       @attributes = @attributes3;
   }


   # reform @lsr_out from %HoAllAttrs
   for ($i=0;$i<=$num_rows;$i++){
      # initialize each row
      $lsr_out[$i] = "";

      # get each row from hash by attribute name
      foreach $temp_attr (@attributes) {
         if (defined $HoAllAttrs{$temp_attr}[$i])
            { $lsr_out[$i] .= $DELIMITER . $HoAllAttrs{$temp_attr}[$i]; }
         else  { $lsr_out[$i] .= $DELIMITER . ""; }
      }

      # get rid of first delimiter 
      $lsr_out[$i] =~ s/^${DELIMITER}//;
   }

   # when attrs are specified,
   # correct the PAttr and DAttr global variables to indicate
   # what we actually have, so correct heading is used
   if ($Opt_LS_Attr)
   {
       if ($num_rows >= 0) 
       {
           if ($num_p_attrs > 0) 
           { 
               $Opt_LS_PAttr = $TRUE;
           }
           else
           {  
               $Opt_LS_PAttr = $FALSE;
           }
           if ($num_d_attrs > 0) 
           { 
               $Opt_LS_DAttr = $TRUE;
           }
           else
           {     
               $Opt_LS_DAttr = $FALSE;  
           }
       }
       else
       {
           $Opt_LS_DAttr = $FALSE;
           $Opt_LS_PAttr = $TRUE;
       }
   }

   # print output if lsrsrc-api command worked or there's
   # something to print
   if ($rc ==0 || $#lsr_out2 >=0 )
      {
         # if the peer domain names were taken out before, add them back 
         # to look like the attribute ActivePeerDomain
         if ( $PDNAMES_IN_OUTPUT && ($#lsr_out2 >=0) ) {
            push @attributes, "ActivePeerDomain";
            for ($i=0;$i<=$num_rows;$i++) {
               $lsr_out[$i] .= $DELIMITER . $pdnames_out[$i]; 
            }
         }
         
         # Display the Resource Class Persistent Attributes
         $rc2 = display_resource_api(\@attributes, \@lsr_out);
         if ($rc == 0) { $rc = $rc2; }
      }
   ($rc == 0) || error_exit($rc);

} # end else

exit($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.   #
#         SR_CLI_BAD_FLAG    Command line contained a bad flag.      #
#   $resource                Name of resource to be displayed.       #
#   $select_str              Selection string.                       #
#   $properties              Attributes having these properties      #
#                            should be displayed.                    #
#   @attributes              Array of attributes to be displayed.    #
#                                                                    #
# Global Variables Modified:                                         #
#   $Opt_Current       output   True (-c) print current cluster info #
#   $Opt_LS_Class      output   True (-c) display the resource       #
#                               class attributes.                    #
#   $Opt_LS_DAttr      ouptput  True (-A d) display the resource     #
#                               dynamic attributes.                  #
#   $Opt_LS_PAttr      output   True (-A p) display the resource     #
#                               persistent attributes.               #
#   $Opt_LS_RHandle    output   True (-r) displays the resource      #
#                               handles for specified resource.      #
#   $Opt_LS_Cluster    output   True (-a) list all nodes             #
#   $Opt_LS_Input_File output   True (-i) input file format          #
#   $Opt_Long_Format   output   True (-l) print one entry per line   #
#   $Opt_Table_Format  output   True (-t) print in table format.     #
#   $Opt_Delm_Format   output   True (-d|-D) print delimitter        #
#                               separated output.                    #
#   $Opt_Delm_Str      output   the string to use as the delimitter, #
#                               default is colon (:).                #
#   $Opt_No_HDR        output   True (-x) print without header       #
#   $Opt_Properties    output   True (-p) propery specified.         #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my $resource = "";
my $select_str = "";
my $properties = 0;
my $peer_domain_names = "";
my $node_file_name= "";
my @attributes = ();
my $rc;
my %opts = ();

# Process the command line...
if (!GetOptions(\%opts,
                'h|help|version' ,
                'a' ,
                'c' ,
                'd' ,
                'i' ,
                'l' ,
                'r' ,
                't' ,
                'T' ,
                'V' ,
                'x' ,
                'A=s' ,
                'C=s' ,
                'D=s' ,
                'N=s' ,
                'p=s' , 
                's=s' ))
{
    &print_usage;                       # display proper usage
    return MC_CLI_BAD_FLAG;             # return bad rc - bad flag 
}

# Always accept the -h help flag regardless of other flags or operands
if (defined $opts{h}) {                 # -h, help request  
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

# If no operands in lsrsrc that is OK, it just means display
# a list of all Resource Class Names

# Get the arguments...
# Operands:  [resource [attr...]]
if ($#ARGV >= 0) {
    $resource = shift @ARGV;            # user specified resources
    @attributes = @ARGV;                # array of attribute names
}

# See which options/flags were used...

if (defined $opts{c}) {                 # -c, rsrc class definitions
    $Opt_LS_Class = $TRUE;
    if (defined $opts{s}) { 
        printCEMsg("EMsgMCcliImproperUsageCombination", "-c", "-s"); 
        &print_usage;    
        return MC_CLI_BAD_FLAG;
    }
}

if (defined $opts{C}) {                 # -C, rsrc class definitions
    $Opt_LS_Class_DM = $TRUE;
    $peer_domain_names = $opts{C};
    if (defined $opts{c}) { 
        printCEMsg("EMsgMCcliImproperUsageCombination", "-c", "-C"); 
        &print_usage;    
        return MC_CLI_BAD_FLAG;
    }
    if (defined $opts{s}) { 
        printCEMsg("EMsgMCcliImproperUsageCombination", "-C", "-s"); 
        &print_usage;    
        return MC_CLI_BAD_FLAG;
    }
}

if (defined $opts{r}) {                 # -r, display resource handles
    $Opt_LS_RHandle = $TRUE;
    if (defined $opts{c}) {
        printCEMsg("EMsgMCcliImproperUsageCombination", "-c", "-r");
        &print_usage;
        return MC_CLI_BAD_FLAG;
    }
}

if (defined $opts{s}) {                 # -s "selection_string"
    $select_str = $opts{s};
    # don't allow empty selection string 
    if ($select_str =~ /^$/) {
        printCEMsg("EMsgMCcliSelectStrError");
        &print_usage;
        return MC_CLI_BAD_OPERAND;
    }
}

if (defined $opts{a}) {                 # -a, list all nodes
    $Opt_LS_Cluster = $TRUE;
}

if (defined $opts{A}) {                 # -A, attribute type 
    # -A b  default display both dynamic & persistent attributes
    if ($opts{A} eq "b") {              # -A b, ls dynamic & pers attr
        $Opt_LS_DAttr = $TRUE;
        $Opt_LS_PAttr = $TRUE;
    }
    elsif ($opts{A} eq "d") {           # -A d, ls dynamic attributes
        $Opt_LS_DAttr = $TRUE; 
        $Opt_LS_PAttr = $FALSE;
    } 
    elsif ($opts{A} eq "p") {           # -A p, ls persistent attr
        $Opt_LS_PAttr = $TRUE;
        $Opt_LS_DAttr = $FALSE;
    }
    else {
        # -A flag requires p persistent | d dynamic | b both 
        printCEMsg("EMsgMCcliImproperUsageFlag", "-A $opts{A}");   
        &print_usage;
        return MC_CLI_BAD_FLAG;
    }
}
else {
    # Default - display only persistent attributes 
    $Opt_LS_DAttr = $FALSE; 
    $Opt_LS_PAttr = $TRUE; 
}   

if (defined $opts{i}) {                 # -i input file format
    $Opt_LS_Input_File = $TRUE;
    # Default to displaying only required for define and public.
    # User should enter -p <property> if they want other properties.
    # don't default to optional for define.  NodeIDs and NodeNameList together
    # don't like each other on mkrsrc.
    $properties = $RMC_RSRC_PATTR_REQD_FOR_DEFINE | $RMC_RSRC_PATTR_PUBLIC;
    # -i overrides -Ad and -Ab (-i only makes sense with persistent attrs)
    $Opt_LS_DAttr = $FALSE;
    $Opt_LS_PAttr = $TRUE;
}

if (defined $opts{p}) {                 # -p Property
    $properties = $opts{p};
    $Opt_Properties = $TRUE;
    # Make sure properties is a number (hex, octal or decimal)
    if ($properties !~ /^(0x|\d+)\d*/) {
        printCEMsg("EMsgMCcliImproperUsageFlag", "-p $opts{p}");
        return MC_CLI_USER_ERROR;       
    }
    # Convert properties specified in hex or octal to decimal
    $properties = oct $properties if $properties =~ /^0/;

    # Just some mininmal range checking - valid property values only 
    # range between 0x0001 to 0x0020 but allow for growth here
    # -p 0 means display attributes with any property
    if ($properties < hex("0x0000") || $properties > hex("0xFFFF")) {
        printCEMsg("EMsgMCcliImproperUsageFlag", "-p $opts{p}");
        return MC_CLI_USER_ERROR;
    }
    if ($properties == 0) {
        $properties = hex("0xFFFF");
    }
}
elsif (!defined $opts{i}) {
    # Default to display only public attributes
    # Dynamic and Persistent Public properties are both 0x0020
    $properties = $RMC_RSRC_PATTR_PUBLIC; # Default to Public properties
}


# When attributes are specified they can be persistent or dynamic
# And they can have any property
# This will override -A or -p flag even if it was specified.
if (scalar(@attributes) > 0) {
    $Opt_LS_Attr= $TRUE;
    $properties = 0xFFFF;
}

if (defined $opts{N})
{
    if (defined $opts{a}) {
        printCEMsg("EMsgMCcliImproperUsageCombination", "-N", "-a");
        &print_usage;
        return MC_CLI_BAD_FLAG;
    }
    if (defined $opts{c}) {
        printCEMsg("EMsgMCcliImproperUsageCombination", "-N", "-c");
        &print_usage;
        return MC_CLI_BAD_FLAG;
    }
    if (defined $opts{C}) {
        printCEMsg("EMsgMCcliImproperUsageCombination", "-N", "-C");
        &print_usage;
        return MC_CLI_BAD_FLAG;
    }
    if ($opts{N} eq "-")
    {
        $Opt_Stdin= $TRUE;
    }
    else
    {
        $node_file_name= $opts{N};
        $node_file_name = escape_chars($node_file_name);
        $rc= check_input_file($node_file_name);
        if ($rc)
        {
            return MC_CLI_BAD_OPERAND;
        }
    }
    $Opt_Node_File= $TRUE;
} 

# The -l overrides the -t which overrides the -d which overrides -D
# -i always displays in long format
# Long is the default display format 
if (defined $opts{l} || defined $opts{i}) {
    $Opt_Long_Format = $TRUE;
}
elsif (defined $opts{t}) {
    $Opt_Table_Format = $TRUE;          # -t tabular format
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{d}) {              # -d delimitter format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{D}) {              # -D <delimitter> format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE; 
    $Opt_Delm_Str = $opts{D};
}

if (defined $opts{x}) {                 # -x do not print header
    $Opt_No_HDR = $TRUE;
}

if (defined $opts{T}) {                 # -T turn trace on
    $Trace = $TRUE;
}

if (defined $opts{V}) {                 # -V turn verbose mode on 
    $Verbose = $TRUE;
}

return(0, $resource, $select_str, $properties, $peer_domain_names, 
       $node_file_name, @attributes); # success
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
printIMsg("IMsglsrsrcUsage5");
}   # end print_usage


#--------------------------------------------------------------------#
# display_resource_api - displays the actual resource attribute names#
#   and values using the appropriate output format (long,            #
#   delimitter, or tabular).                                         #
#                                                                    #
# Parameters:                                                        #
#   @$r_attributes    input   Attribute names.                       #
#   @$rData           input   Reference to lsrsrc-api output         #
#                                                                    #
# Returns:                                                           #
#   $rc                       0 - if success, otherwise failure.     #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_RHandle   input   TRUE if displaying resource handles.   #
#   $Opt_LS_Class     input   TRUE if displaying resource class.     #
#   $Opt_LS_PAttr     input   TRUE if displaying pers attributes.    #
#   $Opt_LS_DAttr     input   TRUE if displaying dyna attributes.    #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_resource_api
{
my($r_attributes, $rData, $type) = @_;

my $header;
my @title_row;
my $print_format = "long";
my $delim = "";

# Determine if displaying in long, delimiter or tabular/column format.
if ($Opt_Long_Format) {
    $print_format = "long";
}
elsif ($Opt_Table_Format) {
    $print_format = "column";
}
elsif ($Opt_Delm_Format) {
    $print_format = "delim";
    $delim = $Opt_Delm_Str;
}

# Instead of using the display_resource_data to display the header
# use printIMsg so the header can be properly translated (NLS).
$header = "";
if (!$Opt_No_HDR) {
    if ($Opt_LS_RHandle) {
        printIMsg("IMsglsrsrcLsRsrcHndlHdr", $resource);
    }
    elsif ($Opt_LS_Input_File && $Opt_LS_Class) {
       print "PersistentResourceClassAttributes::\n";
    }
    elsif ($Opt_LS_Input_File) {
       print "PersistentResourceAttributes::\n";
    }
    elsif (!$Opt_LS_Classes_Only && $Opt_LS_PAttr && !$Opt_LS_DAttr) {
        ($Opt_LS_Class) ?
            printIMsg("IMsglsrsrcLsRsrcClassPAttrHdr", $resource) :
            printIMsg("IMsglsrsrcLsRsrcPAttrHdr", $resource);
    }
    elsif (!$Opt_LS_Classes_Only && !$Opt_LS_PAttr && $Opt_LS_DAttr) {
        ($Opt_LS_Class) ?
            printIMsg("IMsglsrsrcLsRsrcClassDAttrHdr", $resource) :
            printIMsg("IMsglsrsrcLsRsrcDAttrHdr", $resource);
    }
    elsif (!$Opt_LS_Classes_Only && $Opt_LS_PAttr && $Opt_LS_DAttr) {
        ($Opt_LS_Class) ?
            printIMsg("IMsglsrsrcLsRsrcClassPAttrDAttrHdr", $resource) :
            printIMsg("IMsglsrsrcLsRsrcPAttrDAttrHdr", $resource);
    }
    elsif (!$Opt_LS_Classes_Only && !$Opt_LS_PAttr && !$Opt_LS_DAttr) {
        ($Opt_LS_Class) ?
            printIMsg("IMsglsrsrcLsRsrcClassPAttrHdr", $resource) :
            printIMsg("IMsglsrsrcLsRsrcPAttrHdr", $resource);
    }
}

($Opt_LS_Class) ?
    $title_row = "resource_class" :
    $title_row = "resource";

# if it's for file input, always use "resource"
if ($Opt_LS_Input_File) {
    $title_row = "resource";
}

# Display the attributes in the order that they were requested
# on the command line.  

my $rc = display_resource_data_api($print_format, $Opt_No_HDR,
    $r_attributes, $title_row, $rData, $delim, $header);
return $rc;
}   # end display_resource_api
