#!/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 = "@(#)76   1.16.1.7   src/rsct/rm/ER/cli/bin/rmresponse.perl, errmcli, rsct_rady, rady2035a 11/12/15 16:39:45"
######################################################################
#                                                                    #
# Module: rmresponse                                                 #
#                                                                    #
# Purpose:                                                           #
#   rmresponse - remove a response                                   #
#                                                                    #
# Syntax:                                                            #
#   rmresponse  [-h] [-f] [-q] [-TV] Response[:Node_name]            #
#                                                                    #
# Flags:                                                             #
#   -h      help - writes this command's usage statement to stdout   #
#   -f      forces the response to be removed even if it is linked   #
#           with conditions. The links with the conditions are       #
#           removed as well as the response, but the conditions are  #
#           not removed.                                             #
#   -q      Do not return an error when the response does not exist  #
#   -T      Trace. IBM Support Center use only.                      #
#   -V      Verbose.                                                 #
#                                                                    #
# Operands:                                                          #
#   Response       The name of a defined response to be removed.     #
#                  Node_name specifies where the response is defined.#
#                                                                    #
# Description:                                                       #
#   The rmresponse command removes the response specified by the     #
#   response operand. The response must already exist to be          #
#   removed. When the response must be removed even if it linked     #
#   with conditions, the -f flag must be specified.  This forces the #
#   response and the links with the conditions to be removed.  If the#
#   -f flag is not specified and links with conditions exist. the    #
#   response is not removed.  Conditions are not removed by this     #
#   command.                                                         #
#                                                                    #
# Exit Values:                                                       #
#   0  ERRM_CLI_SUCCESS      Command completed successfully.         #
#   1  ERRM_CLI_RMC_ERROR    Command terminated due to an underlying #
#                            RMC error.                              #
#   2  ERRM_CLI_ERROR        Command terminated due to an underlying #
#                            error in the command script.            #
#   3  ERRM_CLI_BAD_FLAG     Command terminated due to user          #
#                            specifying an invalid flag.             #
#   4  ERRM_CLI_BAD_OPERAND  Command terminated due to user          #
#                            specifying a bad operand.               #
#   5  ERRM_CLI_USER_ERROR   Command terminated due to a user error. #
#                            For example specifying a name that      #
#                            already exists.                         #
#                                                                    #
# Examples:                                                          #
#   1. Remove the response named "Broadcast event on-shift":         #
#      rmresponse "Broadcast event on-shift"                         #
#   2. Remove the response named "Broadcast event on-shift" even if  #
#      the response is linked with conditions:
#      rmresponse "Broadcast event on-shift"                         #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the rmresponse man page in /opt/rsct/man.                   #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/errmcli.rmresponse.map - message mapping  #
#                                                                    #
# Outputs:                                                           #
#   stdout - display information on the condition.                   #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  ERRM_cli_utils.pm, ERRM_cli_rc.pm                      #
#             CT_cli_utils.pm                                        #
#   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:                                                   #
#   001101 JAC 67469: Initial design & write.                        #
#   010102 JAC 67470: Completed rmresponse command.                  #
#   010103 JAC 70296: Make TRUE/FALSE come from utils.               #
#   010123 JAC 70355: Updates for final messages ship.               #
#   010129 JAC 70951: Shift rc after RMC calls if error occurs.      #
#   010308 JAC 71005: Escape some special characters in strings.     #
#   010402 JAC 72894: Eliminate extra call to lsrsrc and don't check #
#                     association if -f specified                    #
#   010507 JAC 73620: Check for RMC CLI user error (rc=5) and        #
#                     return ERRM user error for this case.          #
#   011120 JAC 77597: Distributed RMC. Check for locator.            #
#   011206 JAC 78841: Fix selection string for locating resources.   #
#   020107 JAC 79089: Fix selection string for NodeNameList.         #
#   020121 JAC 79558: Fix selection string for NodeNameList.         #
#   020128 JAC 79559: Change how destination/locator node is used.   #
#   020416 JAC 81754: Fix exit code check and switch to xxx-api cmds.#
#   020719 JAC 84425: Add $rc to process_api_error call.             #
#   020729 JAC 85061: Use 4 (DM/SR/local) for scope if locator used  #
#                     and scope not set.                             #
#   071026 JAC 146726: set delimiter for calling -api commands.      #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# 1. Parse command line flags and operands, determine which flavor   #
#    of this command we are actually invoking.                       #
#    This command allows a user to remove responses.                 #
# 2. Print usage if -h specified                                     #
# 3. Make sure one and only one response is specified                #
# 4. Make sure the response exists.  Return an error if it does not  #
#    exist and the -q flag was not specified.                        #
# 5. Make sure the response is not in an association.  Return an     #
#    error if it is in an association and the -f flag was not        #
#    specified.                                                      # 
# 6. Call RMC command rmrsrc using the response within a selection   #
#    string.  Also pass along -VT if necessary.                      #
# 7. Return back any errors.                                         #
#                                                                    #
#--------------------------------------------------------------------#

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

use CT_cli_utils qw(printIMsg
                    printEMsg);

use ERRM_cli_rc qw(ERRM_CLI_SUCCESS ERRM_CLI_RMC_ERROR
                   ERRM_CLI_ERROR ERRM_CLI_BAD_FLAG
                   ERRM_CLI_BAD_OPERAND ERRM_CLI_USER_ERROR);
use ERRM_cli_utils qw(error_exit
                    printCIMsg
                    printCEMsg
                    find_resource_name get_locator_node
                    find_resource_handle get_source_node
                    get_handle set_orig_rmc_scope
                    check_set_cluster_scope
                    process_api_error process_exit_code
                    $TRUE $FALSE
                    $DELIMITERI $DELIMITERO
                    $CTDIR $CTBINDIR
                    $RMC_CLI_USER_ERROR $RMC_LOCAL_SCOPE
                    $RMRSRC $RSCEVRS $RSCASSC);

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

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

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

$PROGNAME = "rmresponse";               # Program Name for messages
$LSMSG = "$CTBINDIR/ctdspmsg";          # list / display message rtn
$MSGCAT = "errmcli.cat";                # msg catalogue for this cmd
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
my $resource = "";                      # resource to remove
my $passopts = "";                      # options to pass to RMC
my $Force_req = $FALSE;                 # is -f required to delete?
my $Quiet_req = $FALSE;                 # is -q requested for quiet?
my $response_handle = "";               # response handle
my $temp_name = "";                     # holds condition name
my $node_select = "";                   # for NodeNameList when used
my $locator = "";                       # locator
my @cmd_out = ();                       # command output

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

# save original rmc management scope value, in case it's changed later
if (defined $ENV{CT_MANAGEMENT_SCOPE}) {
   $Scope_orig_set = $TRUE;
   $Scope_orig_value = $ENV{CT_MANAGEMENT_SCOPE};
}

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

if ($Verbose) { printIMsg("IMsgrmresponseStart", $resource); }

if ($Trace || $Verbose) { $passopts = $passopts." -"; }

if ($Trace) { $passopts = $passopts."T"; }

if ($Verbose) { $passopts = $passopts."V"; }

# extract the locator, if it exists
($temp_name, $locator) = get_locator_node($resource);
# put back response name without locator
if ($locator ne "") {
   $resource = $temp_name;
}

# list the response to see if it exists
($rc, $response_handle) = get_handle($resource, $RSCEVRS, $locator);

# if RMC CLI user error, exit
if ($rc == $RMC_CLI_USER_ERROR) {
    exit(ERRM_CLI_USER_ERROR);
    }

if ($rc != 0) {                         # response does not exist
   if ($Quiet_req) {                    # don't care about it
      exit(0);
   }
   printEMsg("EMsgrmresponseResponseNotFound",$resource);
   exit(ERRM_CLI_USER_ERROR);
}

# look for the response in an association if force not specified
if (!$Force_req) {

    # check Association for response handle
    $rc = find_resource_handle($response_handle,"r",$locator);
    # if RMC CLI user error
    if ($rc == $RMC_CLI_USER_ERROR) {
       exit(ERRM_CLI_USER_ERROR);
      }
    if ($rc == 0) {                     # found in an Association
       printEMsg("EMsgrmresponseForceRequired",$resource);
       exit(ERRM_CLI_USER_ERROR);
    }
}

# ERRM removes any association entries automatically, but leave code
# here as comments.
# remove response from associations if necessary
##if ($Force_req){
##   `$CTBINDIR/$RMRSRC $passopts -s 'EventResponseHandle==$response_handle' $RSCASSC`;
##   $rc = $?;
##}

# set CT_MANAGEMENT_SCOPE to original setting, in case it was used
set_orig_rmc_scope;

# if the destination node was not specified, delete the local definition.
# Make sure rmc scope is set to local scope.
if ($locator eq "") {
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}
# a locator was specified, use it for NodeNameList
else {
   $node_select = " && NodeNameList |< {\\\"$locator\\\"}";

   # use DM/SR/Local scope if scope not set and there's a locator
   check_set_cluster_scope;
}

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

# call rmrsrc to remove the condition

#`$CTBINDIR/$RMRSRC $passopts -s "Name == \\\"$resource\\\" $node_select" $RSCEVRS`;
@cmd_out=`$CTBINDIR/rmrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCEVRS}${DELIMITERI}"Name==\\\"$resource\\\"${node_select}" 2>&1`;
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "rmrsrc-api results:\n";
              print STDERR "@cmd_out";}

if ($Trace) { print STDERR "$PROGNAME: rmrsrc-api returned $rc\n";}

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

# return ERRM CLI user error if it's an RMC CLI user error    73620
if ($Trace) { print STDERR "$PROGNAME: $RMRSRC returned $rc\n"; }
($rc == $RMC_CLI_USER_ERROR) && ( error_exit(ERRM_CLI_USER_ERROR) );

# if rmrsrc command failed, print RMC error message and exit
if ($rc != 0) {
   printCEMsg("EMsgERRMcliUnExpectRMCrc",$rc);
   exit(ERRM_CLI_RMC_ERROR);
   }

if ($Verbose) { printIMsg("IMsgrmresponseEnd", $resource); }

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.   #
#         ERRM_CLI_BAD_FLAG  Command line contained a bad flag.      #
#   $resource                Name of resource to be removed.         #
#                                                                    #
# Global Variables Modified:                                         #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Force_req         output   True (-f) required to delete response#
#   $Quiet_req         output   True (-q) turn quiet mode on         # 
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my $resource = "";                      # response requested
my $Resp_handle = "";                   # response handle
my %opts = ();
my $rc = 0;

# Process the command line...
if (!GetOptions(\%opts,
		'h' ,
		'f' ,
		'q' ,
		'V' ,
		'T')) {       # Gather options; if errors
    &print_usage;                       # display proper usage
    return ERRM_CLI_BAD_FLAG;           # return bad rc - bad flag 
}

# process h flag
if (defined $opts{h}) {                 # -h, help request
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

# process q flag
if (defined $opts{q}) {                 # -q, quiet request
    $Quiet_req = $TRUE;                 # set quiet flag
}

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

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

# Get the arguments...
# Operands:  resource (only one resource allowed)
if ($#ARGV == 0) {                      # index 0 is last one
    $resource = shift @ARGV;            # user specified resources
}

else {            
    # no resource or too many resources specified 
    printCEMsg("EMsgERRMcliInvalidNumberOfOperands");
    &print_usage;
    return ERRM_CLI_BAD_OPERAND;
}

if (defined $opts{f}) {                 # -f force required
    $Force_req = $TRUE                  # set force flag
}

return(0, $resource);                   # success
}   # end parse_cmd_line


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