#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2019 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# sccsid = "@(#)08   1.18   src/rsct/rmc/cli/bin/refrsrc.perl, rmccli, rsct_rady, rady2035a 11/12/15 16:30:09"
######################################################################
#                                                                    #
# Module: refrsrc                                                    #
#                                                                    #
# Purpose:                                                           #
#   refrsrc - Refreshes the resources within the specified resource  #
#             class.                                                 #
#                                                                    #
# Syntax:                                                            #
#   refrsrc [-h] [-T] [-V] Resource_class                            #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes the command's usage statement to stdout.    #
#   -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        A resource class name.                     #
#                                                                    #
# Description:                                                       #
#   The refrsrc command refreshes the resources within the specified #
#   resource class. Use this command to force the RMC subsystem to   #
#   detect new instances of resources in cases where the             #
#   configuration could be altered by operating system commmands     #
#   (for example, mkfs).                                             #
#                                                                    #
#   This command makes a request to the RMC subsystem to refresh     #
#   the configuration of the resources within a resource class.      #
#   The refresh is actually performed by the resource manager        #
#   responsible for this resource class.                             #
#                                                                    #
#   Any application that is monitoring resources in the specified    #
#   resource class may receive events as the configuration is        #
#   refreshed.                                                       #
#                                                                    #
# 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:                                                          #
#   refrsrc IBM.Foo                                                  #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the refrsrc man page in /opt/rsct/man.                      #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/mccli.refrsrc.map - message mapping       #
#   /opt/rsct/msgmaps/mccli.refrsrc.map - message mapping       #
#                                                                    #
# Outputs:                                                           #
#   stdout - any verbose messages.                                   #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  MC_cli_utils.pm, MC_cli_rc.pm, CT_cli_utils.pm         #
#   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:                                                   #
#   000414 SAB 60910: Initial design & write.                        #
#   010311 SAB 63852: Prepared for GA.                               #
#   021202 JAC 88087: Change to use refrsrc-api.                     #
#   030709 JAC 96745: Add delimiter to call to remove_api_error.     #
#   040407 JAC 105863: Use escape_chars for "\" searches.            #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A. Parse command line flags and operands - getting the resource    #
#    class name to be refreshed.                                     #
# B. Initialize a session with RMC.                                  #
# C. Request RMC to refresh the resources (resource configuration)   #
#    in the specified resource class.                                #
# D. Cleanup.                                                        #
#--------------------------------------------------------------------#

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

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

use MC_cli_rc qw(:return_codes);        # MC_CLI_USER_ERROR, etc.
use autouse MC_cli_utils => qw(
    process_exit_code
    process_api_error
    remove_api_error
    error_exit
    printCEMsg
);


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

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

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

$CTDIR = "/opt/rsct";              # RSCT root directory 
$CTBINDIR = "$CTDIR/bin";               # Cluster Bin directory path
$LSMSG = "$CTBINDIR/ctdspmsg";          # list / display message rtn.
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG 

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

my @ref_out = ();
my $rc = 0;

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

# Refresh the resource class
# call refrsrc-api
if ($Trace) { print STDERR "$PROGNAME: calling refrsrc-api\n";}

# escape quotes... just in case
#$resource =~ s/\\/\\\\/g;
#$resource =~ s/\"/\\\"/g;
$resource = escape_chars($resource);

@ref_out = `$CTBINDIR/refrsrc-api -c "$resource" 2>&1`;

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

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

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

# remove any error messages from the output to display
@ref_out = remove_api_error("::",@ref_out);

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.   #
#         MC_CLI_BAD_FLAG    Command line contained a bad flag.      #
#         MC_CLI_BAD_OPERAND Command line contains a bad operand.    #
#   $resource                Resource Class Name.                    #
#                                                                    #
# Global Variables Modified:                                         #
#   $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 %opts = ();

# Process the command line...
if (!&getopts('hVT', \%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!
}

# refrsrc requires at a minimum the resource class name as an 
# operand. 

# Get the arguments...
if ($#ARGV == 0) { 
    $resource = shift @ARGV;            # user specified resource
}
elsif ($#ARGV > 0) {
    # Too many operands 
    printCEMsg("EMsgMCcliTooManyOperands"); 
    &print_usage;
    return MC_CLI_BAD_OPERAND;
}
else {
    # Print Missing Resource Class Name Operand message 
    printCEMsg("EMsgMCcliMissingRsrcClass");
    &print_usage;                       # display proper usage
    return MC_CLI_BAD_OPERAND;          # return bad rc - bad operand
}

# See which options/flags were used...

if (defined $opts{T}) {                 # -T, turns tracing on
    $Trace = $TRUE;
}

if (defined $opts{V}) {                 # -V, turns verbose mode on
    $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("IMsgrefrsrcUsage");
}   # end print_usage


#--------------------------------------------------------------------#
# 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("EMsgrefrsrcRefRsrcError", $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;
        }
        else {
            printEMsg("EMsgrefrsrcRefRsrcError", $rmc_class);
            my $err_rc_hex = sprintf "0x%8.8lx", $err_rc;
            printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function,
                $err_rc, $err_rc_hex);
            print STDERR $error->error_msg; 
            $rc = MC_CLI_RMC_ERROR;
        }
    }   # end if
}   # end for

return $rc;
}   # end error_check