#!/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. 2001,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 
#"@(#)01   1.1.1.1   src/rsct/rmc/cli/bin/lscmdargdef.perl, rmccli, rsct_relgh, relghs001a 3/7/02 15:33:19"
######################################################################
#                                                                    #
# Module: lscmdargdef                                                #
#                                                                    #
# Purpose:                                                           #
#   lscmdargdef - Lists (displays) command argument definitions.     #
#                                                                    #
# Syntax:                                                            #
#   lscmdargdef [-h] [-e] [-v] [-l|-i|-t|-d|-D Delimiter] [-x] [-T]  #
#               [-V] [Resource_class command_name]                   #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes this command's usage statement to stdout.   #
#   -e      Expands the descriptions. By default the definitions are #
#           displayed, but the textual descriptions are not          #
#           displayed because they may be lengthy. Specify this flag #
#           to see both the definitions and descriptions.            #
#   -v      Display argument valid values.                           #
#   -i      Input format. Generates a template of the Resource Data  #
#           Input File. The output is displayed in long (stanza)     #
#           format, which after appropriate editing can be used as   #
#           input to the appropriate command. The SD element         #
#           data types are displayed as the value in the Attr=value  #
#           pairs. It is suggested that when you use this flag, the  #
#           output of the lscmdargdef command be directed to a file. #
#           The -i flag overrides the -v flag.                       #
#   -l      Specifies long formatted output, one entry per line.     #
#           This is the default display format. If the lscmdargdef   #
#           command is issued with the -l flag, but without a        #
#           resource class and command name, the -l flag is ignored  #
#           when the command returns the list of defined resource    #
#           class names.                                             #
#   -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 that uses the specified  #
#           delimiter. Use this flag to specify a delimiter 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. Suppress header printing.                #
#   -T      Trace. Writes the command's trace messages to standard   #
#           error. For your software-service organization's use only.#
#   -V      Verbose. Writes this command's verbose messages to       #
#           standard out.                                            #
#                                                                    #
# Operands:                                                          #
#   Resource_class  Resource class name. The name of the resource    #
#                   class whose command argument definitions are to  #
#                   be displayed. If Resource_class and command_name #
#                   operands are not specified, a list of all of the #
#                   resource class names is displayed.               #
#                                                                    #
#   command_name    If a Resource_class operand is specified, one    #
#                   valid command name must be supplied as well.     #
#                   The valid command names are: mkrsrc, rmrsrc,     #
#                   startrsrc, stoprsrc, and resetrsrc.              #
#                                                                    #
#                                                                    #
# Description:                                                       #
#   The lscmdargdef command lists the definitions of resource class  #
#   command arguments.                                               #
#                                                                    #
#   Use lscmdargdef with no operands specified to get a list of all  #
#   resource class names.                                            #
#                                                                    #
#   By default, for the arguments that contain descriptions, the     #
#   descriptions are not displayed. Specify the -e flag to display   #
#   the descriptions. Because the translation of these descriptions  #
#   may take some time and because some of the descriptions are very #
#   long, the default is not to display these descriptions. If       #
#   descriptions for members of the valid_vals list are available,   #
#   they are displayed with the -e flag as well.                     #
#                                                                    #
#   By default, for arguments that have defined valid values, the    #
#   valid values are not displayed.  Specify the -v flag to          #
#   view the valid values for requested command arguments.           #
#   Because valid values are not returned as part of the base        #
#   command argument definition, and extra calls to RMC must be made #
#   to retrieve the valid values, the default is not to display them.#
#                                                                    #
# 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:                                                          #
#   lscmdargdef                 (lists all resource class names)     #
#   lscmdargdef IBM.SharedResourceCluster rmrsrc (lists argument     #
#                                definitions for the rmrsrc commands)#
#   lscmdargdef -i IBM.SharedResourceCluster mkrsrc (input file      #
#                                format for mkrsrc command)          #
#   lscmdargdef -v -e IBM.SharedResourceCluster stoprsrc (list       #
#                                argument definitions with valid     #
#                                values for input and extended       #
#                                descriptions)                       #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the lscmdargdef man page in /usr/sbin/rsct/man.                  #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /usr/sbin/rsct/msgmaps/mccli.lscmdargdef.map - message mapping   #
#   /usr/sbin/rsct/msgmaps/mccli.mccli.map - message mapping         #
#                                                                    #
# Outputs:                                                           #
#   stdout - display of the resource action definitions.             #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  MC_cli_utils.pm, MC_cli_display_utils.pm, MC_cli_rc.pm #
#             CT_cli_utils.pm, CT_cli_data_type_utils                #
#   Extensions:  CT::MC, CT::MCerr, CT::CT                           #
#   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:                                                   #
#   010827 YSK 75111: Initial design & write.                        #
#   020307 JAC 80687: Remove -v and update usage.                    #
######################################################################

#--------------------------------------------------------------------#
# 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 see the argument definitions for  #
#    the specified resource class and command.                       #
#    They can select to see one of:                                  #
#       * Names of all defined resource classes on this system.      #
#       * Definitions of the command arguments for one of:           #
#         - mkrsrc                                                   #
#         - rmrsrc                                                   #
#         - startrsrc                                                #
#         - stoprsrc                                                 #
#         - resetrsrc                                                #
#       * Argument definitions in input file format.                 #
# B. Initialize a session with RMC.                                  #
# C. Query the definition of the SD RMC.                             #
# D. Display the requested definitions in the appropriate format.    #
# E. Cleanup.                                                        #
#--------------------------------------------------------------------#

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

use CT::CT qw(:ct_data_type_t);

use autouse CT_cli_utils => qw(
    printIMsg
    printEMsg
);
use autouse CT_cli_data_type_utils => qw(
    data_type_to_string
);

use CT::MC qw(
    :mc_qdef_opts_t
    :mc_sd_usage_t
    :mc_vv_usage_t

    qdef_resource_class_bp
    qdef_sd_bp
    qdef_valid_values_bp
    free_response
);

use CT::MCerr;

use MC_cli_rc qw(:return_codes);
use autouse MC_cli_utils => qw(
    init_session 
    term_session
    build_HoAttr
    qdef_resource_class
    required_attr
    error_exit
    printCEMsg
);
use autouse MC_cli_display_utils => qw(
    display_resource_class_names
    display_resource_data
    convert_properties
    convert_variety_list
    convert_sd_valid_values
    convert_sd_valid_values_label
);


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

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

# By default output is written in long format.
our $Opt_Long_Format = $TRUE;               # default - see -l (long form)
our $Opt_Table_Format = $FALSE;             # default - see -t (table)
our $Opt_Delm_Format = $FALSE;              # default - see -d (delimiter)
our $Opt_Delm_Str = ":";                    # default - see -D (colon :) 
our $Opt_No_HDR = $FALSE;                   # default - see -x
our $Opt_Exp_Desc = $FALSE;                 # default - see -e
our $Opt_LS_Input_File = $FALSE;            # default - see -i
our $Opt_Valid_Vals = $FALSE;               # default - see -v 
our $Trace = $FALSE;                        # default - see -T
our $Arg_VV_Usage;                          # mc_vv_usage_t type
our $Arg_SD_Usage;                          # mc_sd_usage_t type


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

our $CTDIR = "/usr/sbin/rsct";              # RSCT root directory
our $CTBINDIR = "$CTDIR/bin";               # Cluster Bin directory path
our $LSMSG = "$CTBINDIR/ctdspmsg";          # display message rtn.
    $ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG
our %Cleanup = ();                          # Hash of items to cleanup
                                            # {Session} $session to term

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#

our @LoArgs = ();                           # List of arg SD fields
our %HoArgs = ();                           # Hash of arg SD fields


#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#

# Parse the command line, exit if there are errors 
my ($rc, $resource) = &parse_cmd_line;
($rc == 0) || error_exit($rc);

my $session;
my $response;
my $response_vv;

# Initialize a session with RMC
($rc, $session) = init_session();
($rc == 0) || error_exit($rc);
$Cleanup{Session} = $session;

# If no resource names were specified as an operand to this command
# display the list of all resource names.
if (!$resource) {               # No resource operand
    # Nee a Response Class
    $response = CT::MC::qdef_rsrc_class_rsp_t->new;

    # Let this subroutine handle the real call to the extension
    # and dealing with all of the return codes..
    $rc = qdef_resource_class($session, "", $response, $Opt_Exp_Desc);
    ($rc == 0) || error_exit($rc); 
    
    # Display the Resource Class Definitions
    $rc = display_resource_class_names($response, $Opt_No_HDR, 
        $Opt_Long_Format, 0, $Opt_Delm_Format, $Opt_Delm_Str);
    ($rc == 0) || error_exit($rc);
}

elsif ($Opt_LS_Input_File) {
    # Output in command input format

    # Need a Response Class
    $response = CT::MC::qdef_sd_rsp_t->new;

    $rc = qdef_sd($session, $resource, $response);
    ($rc == 0) || error_exit($rc);

    # Format argument SDs into the appropriate hash format.
    format_args_for_input($response, \@LoArgs, \%HoArgs);

    # Display the input file header
    !$Opt_No_HDR &&
        print "PersistentResourceArguments::\n"; 
    
    # Display arguments
    $rc = display_args(\@LoArgs, \%HoArgs); 
    ($rc == 0) || error_exit($rc);
}

else {                          # List argument definitions
    # Need a Response Class
    $response = CT::MC::qdef_sd_rsp_t->new;

    $rc = qdef_sd($session, $resource, $response);
    ($rc == 0) || error_exit($rc);

    # Get response for valid values if they were requested by user.
    # Call subroutine to handle valid values extension.
    if ($Opt_Valid_Vals) {
        $response_vv = CT::MC::qdef_valid_vals_rsp_t->new;
        $rc = qdef_valid_vals($session, $resource, 
                              $response_vv, $Arg_VV_Usage);
        ($rc == 0) || error_exit($rc);
    }

    # Format argument SDs into the appropriate hash format.
    format_args($response, \@LoArgs, \%HoArgs, $response_vv);

    # Display header

    !$Opt_No_HDR &&
        printIMsg("IMsglscmdargdefLsCmdArgHdr", $resource); 
    
    # Display arguments
    $rc = display_args(\@LoArgs, \%HoArgs); 
    ($rc == 0) || error_exit($rc);
}

if ($response->array_count > 0) {
    $rc = CT::MC::free_response($response);
    ($rc == 0) || error_exit($rc);
}

if (defined($response_vv) && ($response_vv->array_count > 0)) {
    $rc = CT::MC::free_response($response_vv);
    ($rc == 0) || exit $rc;
}

# Cleanup 
$rc = term_session($session);
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                Resource Class Name.                    #
#   $properties              Attributes having these properties      #
#                            should be displayed.                    #
#                                                                    #
# Global Variables Modified:                                         #
#   $Opt_Exp_Desc      output   True (-e) print both definition      #
#                               and description (print all).         #
#   $Opt_LS_Input_File output   True (-i) create/list an input file  #
#                               suitable for runact.                 #
#   $Opt_Valid_Vals    output   True (-v) display valid values.      #
#   $Opt_Long_Format   output   True (-l) print one entry per line   #
#   $Opt_Table_Format  output   True (-t) table format.              #
#   $Opt_Delm_Format   output   True (-d|-D) print delimiter         #
#                               separated output.                    #
#   $Opt_Delm_Str      output   the string to use as the delimiter,  #
#                               default is colon (:).                #
#   $Opt_No_HDR        output   True (-x) print without header       #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
return (0,0) if $#ARGV == -1;           # No args: display class names.

my(@original_argv) = @ARGV;
my $resource = "";
my %opts = (); 
my $command;

# Process the command line...
#if (!&getopts('heidD:ltxvVT',\%opts)) { # Gather options; if errors
if (!&getopts('heidD:ltxVT',\%opts)) { # Gather options; if errors
    &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 lscmdargdef that is OK, it just means display
# a list of all Resource Class Names

# Get the arguments...
if ($#ARGV == 1) {                      # must specify class and command or...
    ($resource, $command) = @ARGV;
}
elsif ($#ARGV == 0) {                   # command name missing.
    printEMsg("EMsglscmdargdefCmdNameMissing", "$command");
    &print_usage;
    return(MC_CLI_BAD_OPERAND, $resource);
}
else {                                  # Wrong number of args or other error.
    &print_usage;                       
    return(MC_CLI_BAD_OPERAND, $resource); 
}

# See which options/flags were used...

if (defined $opts{e}) {                 # -e, display all desc & def
    $Opt_Exp_Desc = $TRUE;
}

if (defined $opts{i}) {
    $Opt_LS_Input_File = $TRUE;
}

# Determine for which CLI command we must display arguments
# and set qdef_sd and qdef_valid_vals usage types appropriatly

if ($command eq "mkrsrc") {
    $Arg_SD_Usage = MC_SD_USAGE_DEFINE_ARG;
    $Arg_VV_Usage = MC_VV_USAGE_DEFINE_ARG;
}

elsif ($command eq "rmrsrc") {
    $Arg_SD_Usage = MC_SD_USAGE_UNDEFINE_ARG;
    $Arg_VV_Usage = MC_VV_USAGE_UNDEFINE_ARG;
}

elsif ($command eq "startrsrc") {
    $Arg_SD_Usage = MC_SD_USAGE_ONLINE_ARG;
    $Arg_VV_Usage = MC_VV_USAGE_ONLINE_ARG;
}

elsif ($command eq "stoprsrc") {
    $Arg_SD_Usage = MC_SD_USAGE_OFFLINE_ARG;
    $Arg_VV_Usage = MC_VV_USAGE_OFFLINE_ARG;
}

elsif ($command eq "resetrsrc") {
    $Arg_SD_Usage = MC_SD_USAGE_RESET_ARG;
    $Arg_VV_Usage = MC_VV_USAGE_RESET_ARG;
}

else {
    printEMsg("EMsglscmdargdefCmdNameError", "$command");
    &print_usage;
    return(MC_CLI_BAD_OPERAND, $resource);
}

# show valid values if not displaying input format
if (defined $opts{v} && !(defined $opts{i})) {
    $Opt_Valid_Vals = $TRUE;
}

# The -l flag overrides -t which overrides -d which overrides -D flag
# When -i flag used always display in long format

if (defined $opts{l} || defined $opts{i}) { # -l long format,
    $Opt_Long_Format = $TRUE;          #    1 entry per line  
}
elsif (defined $opts{t}) {             # -t tabular format
    $Opt_Table_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{d}) {             # -d delimiter format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{D}) {             # -D <delimiter> 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 verbose 
    $Verbose = $TRUE;
}

return(0, $resource); # 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("IMsglscmdargdefUsage");
}   # end usage


#--------------------------------------------------------------------#
# qdef_sd - function to call the CT::MC::qdef_sd_bp extension and    #
#   handle possible errors.                                          #
#                                                                    #
# Parameters:                                                        #
#   $session          input   RMC session handle.                    #
#   $resource         input   Name of the resource class whose SD    #
#                             definition we want.                    #
#   $response         in/out  Response data structure, on output     #
#                             this will point to the real resposne.  #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#--------------------------------------------------------------------#
sub qdef_sd
{
my ($session, $resource, $response) = @_;
my $rc = 0;
 
my $error = CT::MC::errnum_t->new;

my $options = $Opt_Exp_Desc ? MC_QDEF_OPTS_NONE : MC_QDEF_OPTS_NODSCRP;

my $sd_usage = $Arg_SD_Usage;

my @empty_array = ();

$Trace && print STDERR "Calling CT::MC::qdef_sd_bp\n";

$rc = CT::MC::qdef_sd_bp($session, $response, $error,
                         $options, $resource, $sd_usage, 
                         \@empty_array, 0);

$Trace && print STDERR "Return  CT::MC::qdef_sd_bp\n";

$rc = error_check("mc_qdef_sd_bp", $resource, $response, $rc, $error);

return $rc;
}   # end qdef_sd


#--------------------------------------------------------------------#
# format_args - format the structured data definitions for resource  #
#               class command arguments. Construct a complex hash    #
#               (%$rHoSDAttr) which can be displayed by              #
#               display_arguments.                                   #
#                                                                    #
# Parameters:                                                        #
#   $response         input   Reference to a sd_rsp_t Perl object.   #
#   $rLoSDAttr        in/out  Reference to the list of SD elements   #
#                             that are present in %$rHoSDAttr.       #
#   $rHoSDAttr        in/out  Reference to the hash of SD elements.  #
#   $response_vv      input   Reference to a vv_rsp_t Perl object.   #
#                                                                    #
# Global References:                                                 #
#   $Opt_Valid_Vals   input   True if valid values are being         #
#                             displayed.                             #
#--------------------------------------------------------------------#
sub format_args
{
my($response, $rLoSDAttr, $rHoSDAttr, $response_vv) = @_;

%$rHoSDAttr = ();

my %HoRspAttr = (
    "element_name"          => 1,
    "display_name"          => 1,
    "description"           => 1,
    "element_data_type"     => 1,
    "element_index"         => 1,
    "valid_vals"            => $Opt_Valid_Vals,
    "valid_vals_label"      => $Opt_Valid_Vals
);

my %elements = ();  # temporary store for SD elem name, data type, and value
my $e;              # index into mc_sd_element array
my $r = 0;          # index into qdef_sd_rsp array (only one response)

@$rLoSDAttr = ();

my $element_cnt = $response->element_count($r);  
my $data_type;

for ($e = 0; $e < $element_cnt; $e++) {
    if ($HoRspAttr{"element_name"}) {
    %elements = ();
    $elements{at_name} = "element_name";
    $elements{at_dtype} = CT_CHAR_PTR;
    $elements{at_value} = $response->element_name($r, $e);
    build_HoAttr($elements{at_name}, $rLoSDAttr, $rHoSDAttr,
             \%elements, 0);
    }

    if ($HoRspAttr{"display_name"}) {
    %elements = ();
    $elements{at_name}  = "display_name";
    $elements{at_dtype} = CT_CHAR_PTR;
    $elements{at_value} = $response->display_name($r, $e);
    build_HoAttr($elements{at_name}, $rLoSDAttr, $rHoSDAttr,
             \%elements, 0);
    }

    if ($HoRspAttr{"description"}) {
    %elements = ();
    $elements{at_name} = "description";
    $elements{at_dtype} = CT_CHAR_PTR;
    $elements{at_value} = $response->description($r, $e);
    build_HoAttr($elements{at_name}, $rLoSDAttr, $rHoSDAttr,
             \%elements, 0);
    }

    if ($HoRspAttr{"element_data_type"}) {
    %elements = ();
    $elements{at_name} = "element_data_type";
    $data_type = $response->element_data_type($r, $e); 
    $elements{at_dtype} = CT_CHAR_PTR;
    $elements{at_value} = data_type_to_string($data_type);
    build_HoAttr($elements{at_name}, $rLoSDAttr, $rHoSDAttr,
             \%elements, 0);
    }

    my $element_index = $response->element_index($r, $e);
    if ($HoRspAttr{"element_index"}) {
    %elements = ();
    $elements{at_name}  = "element_index";
    $elements{at_dtype} = CT_UINT32;
    $elements{at_value} = $element_index;
    build_HoAttr($elements{at_name}, $rLoSDAttr, $rHoSDAttr,
             \%elements, 0);
    } 

    if ($HoRspAttr{"valid_vals"}) {
    %elements = ();
    $elements{at_name} = "valid_vals";
    ($elements{at_dtype}, $elements{at_value}) = 
        convert_sd_valid_values($response_vv, $r,
                    $response_vv->count($r), 
                    $data_type, $element_index);
    build_HoAttr($elements{at_name}, $rLoSDAttr, $rHoSDAttr, 
             \%elements, 0);
    }

    if ($HoRspAttr{"valid_vals_label"}) {
    %elements = ();
    $elements{at_name} = "valid_vals_label";
    ($elements{at_dtype}, $elements{at_value}) = 
        convert_sd_valid_values_label($response_vv, $r,
                      $response_vv->count($r), 
                      $element_index, $data_type);
    build_HoAttr($elements{at_name}, $rLoSDAttr, $rHoSDAttr, 
             \%elements, 0);
    }
}   
}   # sub format_args


#--------------------------------------------------------------------#
# format_args_for_input - formats the persistent attributes into     #
#   an input format suitable for mkrsrc or chrsrc. Formats the       #
#   argument definitions into a complex hash of attribute elements   #
#   which can then be easily displayed using utility                 #
#   dislay_resouce_data.                                             #
#                                                                    #
# Parameters:                                                        #
#   $response         input   Reference to a sd_rsp_t Perl object.   #
#   $rLoSDAttr        in/out  Reference to the list of SD elements   #
#                             that are present in %$rHoSDAttr.       #
#   $rHoSDAttr        in/out  Reference to the hash of SD elements.  #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub format_args_for_input
{
my($response, $rLoSDAttr, $rHoSDAttr) = @_;

my %elements = ();  # temporary store for SD elem name, data type, and value
my $e;              # index into mc_sd_element array
my $r = 0;          # index into qdef_sd_rsp array (only one response)

# Format each of the arguments in the response structure so
# we can use more generic printing...

my $element_cnt = $response->element_count($r);

for ($e = 0; $e < $element_cnt; $e++) {

    %elements = ();
    $elements{at_name}  = $response->element_name($r, $e);
    $elements{at_id}    = $response->element_index($r, $e);
    $elements{at_dtype} = CT_CHAR_PTR;
    $elements{at_value} = 
        data_type_to_string ($response->element_data_type($r, $e));
    build_HoAttr($elements{at_name}, $rLoSDAttr, $rHoSDAttr, 
                 \%elements, 0);

}   # end for SD elements

return;
}   # end of format_args_for_input


#--------------------------------------------------------------------#
# display_arguments - display argument SD definitions.               #
#                                                                    #
# Parameters:                                                        #
#   @$rLoArgs         input   Reference to list of argument names    #
#   %$rHoArgs         input   Reference to hash of arguments         #
#                                                                    #
# Returns:                                                           #
#   $rc                       Return code (0 = success).             #
#                                                                    #
# Global References:                                                 #
#   $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_args
{
my($rLoArgs, $rHoArgs) = @_;

my $print_format = "long";
my $delim = "";
my $rc = 0;

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

# For debugging to reference one element
# $rHoArgs->{$attr_name}[$row]{at_value}

# Display a catalogued message as the header instead of using
# the header printing capability of display_resource_data
my $header = "";
my $row_title = "argument";

$rc = display_resource_data($print_format, $Opt_No_HDR, $rLoArgs,
        $row_title, $rHoArgs, $delim, $header);

return $rc;
}   # end display_args


#--------------------------------------------------------------------#
# qdef_valid_vals - function to call the CT::MC::qdef_valid_         #
#   values_bp extension. Based on above code.                        #
#                                                                    #
# Parameters:                                                        #
#   $session          input   RMC session handle.                    #
#   $resource         input   Name of the resource class whose attr  #
#                             definitions we want.                   #
#   @$r_attributes    input   Reference to array of attribute names. #
#   $response         in/out  Response data structure, on output     #
#                             this will point to the real resposne.  #
#   $usage            input   One of mc_vv_usage_t enum types.       #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#                                                                    #
#TODO: While support for retrieving valid values through action      #
#      invokation is documented in the API, as of 8/6/01, it has not #
#      yet been implemented. Once it is implemented in the RMC C API,#
#      support for retrieving valid values using actions should be   #
#      added to this command.                                        #
#--------------------------------------------------------------------#
sub qdef_valid_vals
{
my ($session, $resource, $response, $usage) = @_;
my $rc = 0;

my $options = $Opt_Exp_Desc ? MC_QDEF_OPTS_NONE : MC_QDEF_OPTS_NODSCRP;

my $error = CT::MC::errnum_t->new;

my @empty_array = ();

$Trace && print STDERR "Calling CT::MC::qdef_valid_values_bp\n";

$rc = CT::MC::qdef_valid_values_bp($session, $response, $error,
                   $options, $resource, $usage,
                   \@empty_array, 0);

$Trace && print STDERR "Return  CT::MC::qdef_valid_values_bp\n";

$rc = error_check("mc_qdef_valid_values_bp", $resource, $response, 
    $rc, $error);

return $rc;
}   # end qdef_valid_vals


#--------------------------------------------------------------------#
# error_check - checks the return code from the RMC function and     #
#   the error response return code.  If an error is detected         #
#   appropriate error messages will be displayed.                    #
#                                                                    #
# Parameters:                                                        #
#   $rmc_function     in      Name of the rmc function that was      #
#                             called and whose error code we are     #
#                             checking.                              #
#   $rmc_class        in      The rmc class name.                    #
#   $response         in      RMC response                           #
#   $rmc_rc           in      The rmc function return code.          #
#   $error            in      The error response.                    #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($rmc_function, $rmc_class, $response, $rmc_rc, $error) = @_;

my $rc = 0;
my $err_rc = $error->errnum();

if ($rmc_rc != 0) {
    printEMsg("EMsglscmdargdefLsCmdArgDefError", $rmc_class);
    my $rmc_rc_hex = sprintf "0x%8.8lx", $rmc_rc;
    printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function,
        $rmc_rc, $rmc_rc_hex);
    $rc = MC_CLI_RMC_ERROR;
    return $rc;
}

# Check the errnum in each of the RMC responses
for (my $r = 0; $r < $response->array_count; $r++) {
    # get the error that goes with the specific response
    if ($r > 0) {
        $response->error($error, $r);
        $err_rc = $error->errnum();
    }
    if ($err_rc != 0) {
        if ($err_rc == RMC_ECLASSNOTDEFINED) {
            printCEMsg("EMsgMCcliClassNotDef", $rmc_class);
            $rc = MC_CLI_USER_ERROR;
        }
        elsif ($err_rc == RMC_EACCESS) {
            print STDERR $error->error_msg;
            $rc = MC_CLI_USER_ERROR;
        }
        # It is possible for Resource Class to have no Cmd Args
        # defined - this is not an error. (Next two cases.)
        elsif ($err_rc == RMC_ESDNOTDEFINED) {
            $rc = 0;
        }
        elsif ($err_rc == RMC_EAACNOTDEFINED) {
            $rc = 0;
        }
        else {
            printEMsg("EMsglscmdargdefLsCmdArgDefError", $rmc_class);
            my $err_rc_hex = sprintf "0x%8.8lx", $err_rc;
            printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function, 
                $err_rc, $err_rc_hex);
            $Verbose && print STDERR $error->error_msg; 
            $rc = MC_CLI_RMC_ERROR;
        }
    }   # end if
}   # end for

return $rc;
}   # end error_check
