#!/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 = "@(#)73   1.20.1.25   src/rsct/rm/ER/cli/bin/mkcondition.perl, errmcli, rsct_rady, rady2035a 11/12/15 16:39:41"
######################################################################
#                                                                    #
# Module: mkcondition                                                #
#                                                                    #
# Purpose:                                                           #
#   mkcondition - make a condition resource                          #
#                                                                    #
# Syntax:                                                            #
#   mkcondition [-h] -r Resource_class -e Event_expression           #
#               [-E Rearm_expression] [-d Event_description]         #
#               [-D Rearm_description] [-n Node_name[,Node_name,...] #
#               [-s "Selection_string"] [-S c|w|i] [-m l|m|p]        #
#               [-b interval[,max_events][,retention_period]         #
#               [,max_total_size]                                    #
#               [-p Node_name][-g 0|1|2] [-TV] Condition             #
#                                                                    #
#   mkcondition [-h] -c Existing_condition[:Node_name]               #
#               [-r Resource_class] [-e Event_expression]            #
#               [-E Rearm_expression] [-d Event_Description]         #
#               [-D Rearm_description] [-n Node_name[,Node_name,..]  #
#               [-p Node_name] [-s "Selection_string"] [-m l|m|p]    #
#               [-b interval[,max_events][,retention_period]         #
#               [,max_total_size]                                    #
#               [-S c|w|i][-g 0|1|2] [-TV] Condition                 #
# Flags:                                                             #
#   -h      help - writes this command's usage statement to stdout   #
#   -b interval[,max_events]                                         #
#           The events are to be batched together for the interval   #
#           specified or until the max_events number of events are   #
#           generated. The interval restarts if the max_events number#
#           of events is reached before the interval expires. The    #
#           batching continues until there are no events generated   #
#           for an interval.  Use an interval of 0 to turn batching  #
#           off.  max_events cannot be specified unless interval is  #
#           greater than 0. When interval is greater than 0 and      #
#           max_events is 0, no maximum number of events is used. By #
#           default, interval is 0 and max_events is 0 when interval #
#           is greater than 0.                                       #
#           retention_period is to specify the retention period in   #
#           hour. Batched event file is saved for the time specified #
#           as retention period. Once this time is reached the file  #
#           is automatically deleted.                                #
#           max_totalsize is to specify the total size for the       #
#           batched event file in MB(MegaBytes). Batched event file  #
#           is saved until the size is reached, Once the size is     #
#           reached the file is automatically deleted.               #
#           If both retention_period and max_totalsize are specified,#
#           then Batched event file is saved, until whichever occur  #
#           first.                                                   #
#   -c      Existing_condition to copy to a new condition. Node_name #
#           specifies where it is defined.                           #
#   -r      Resource_class.  The name of the resource class to be    #
#           monitored.                                               #
#   -e      Event_expression. Expression that determines when an     #
#           event occurs.  Expression usually involves the dynamic   #
#           attribute and a comparison.                              #
#   -E      Rearm_expression. Expression to indicate when to restart #
#           monitoring after an event has occurred.  Expression      #
#           usually involes the dynamic attribute and a comparison.  #
#   -d      Event_description. User supplied text to describe the    #
#           event_expression.                                        #
#   -D      Rearm_description. User supplied text to describe the    #
#           rearm_expression.                                        # 
#   -n      Node_namelist where condition is to be monitored.        #
#   -s      Selection_string. Specifies which resources in           #
#           the resource class are monitored.  Default is all        #
#           resources in the class.                                  #
#   -S c|w|i Specifies the severity of the event. c=critical,        #
#           w=warning, and i=informational.  Default is              #
#           informational.                                           #
#   -m l|m|p Specifies the scope of the condition when monitoring    #
#           starts. l=local, d=distributed domain, and p=peer domain.#
#   -g 0|1|2 Specifies granularity levels to control AuditLog records#
#           for the condition. Three levels of granularities are     #
#           provided 0:enable,1: only on error and 2:disable         #
#   -p      Specifies the node on which the condition is defined.    #
#   -T      Trace. IBM Support Center use only.                      #
#   -V      Verbose.                                                 #
#                                                                    #
# Operands:                                                          #
#   Condition       The name of the new condition to be created.     #
#                                                                    #
# Description:                                                       #
#   The mkcondition command creates a new condition definition with  #
#   the name specified by the Condition parameter.  The condition is #
#   used to monitor a resource for the occurrence of the condition   #
#   (or event).   One or more responses to an event can be defined   #
#   by using the mkresponse command.  The conditions can then be     # 
#   linked to the responses by using the mkcondresp command, or by   #
#   using the startcondresp command to link responses and start      #
#   monitoring.                                                      #


#                                                                    #
# 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. Define a condition with the name "JFS space used up" to check #
#      for percent space used greater than 90% and to rearm when it  #
#      is back down below 85%                                        #
#      mkcondition -r IBM.FileSystem -e "PercentTotUsed > 90" \      #
#           -E "PercentTotUsed < 85" "JFS space used up"             #
#   2. Define a condition with the name "tmp space used up" to check #
#      for percent space used greater than 90% for /tmp and to rearm #
#      when it is back down below 85%, including comments            #
#      mkcondition -r IBM.FileSystem -e "PercentTotUsed > 90" \      #
#           -E "PercentTotUsed < 85" \                               #
#           -d "Generate event when tmp > 90 percent full" \         #
#           -D "Resume monitoring when tmp < 85 percent full" \      #
#           -s 'Name=="/tmp"' "tmp space used up"                    #
#   3. Define a condition with the name "Space used up" as a copy of #
#      "JFS space used up"                                           #
#      mkcondition -c "JFS space used up" "Space used up"            #
#   4. Define a condition with the name "var space used up" as a     #
#      copy of "tmp space used up", but change the selection to /var #
#      mkcondition -c "tmp space used up" -s 'Name=="/var"'  \       #
#           "var space used up"                                      #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the mkcondition man page in /opt/rsct/man.                  #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/errmcli.mkcondition.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:                                                   #
#   001012 JAC 67469: Initial design & write.                        #
#   001226 JAC 67470: Completed mkcondition command.                 #
#   010103 JAC 70296: Make TRUE/FALSE come from utils.               #
#   010116 JAC 70594: Modify selection string processing.            #
#   010125 JAC 70355: Modify Trace message to use variables.         #
#   010126 JAC 70783: Place NodeName value in single quotes.         #
#   010129 JAC 70951: Shift rc after RMC calls if error occurs.      #
#   010303 JAC 71042: Remove setting DynamicAttribute.               #
#   010308 JAC 71005: Escape some special characters in strings.     #
#   010430 JAC 73619: Do not send any RMC CLI std err to garbage.    #
#   010507 JAC 73620: Check for RMC CLI user error (rc=5) and        #
#                     return ERRM user error for this case.          #
#   010516 JAC 74036: Convert nodenames to long names, if possible   #
#   011119 JAC 77597: Add distributed RMC changes                    #
#   011206 JAC 78841: Fix selection string for locating resources.   #
#   011213 JAC 78976: Fix selection string for locating resources.   #
#   020121 JAC 79558: Fix selection string for locating resources.   #
#   020128 JAC 79559: Change how destination/locator node is used.   #
#   020416 JAC 81754: Fix exit code check and Switch to xxx-api cmds.#
#   020428 JAC 82364: Change mgt scope to l|d|p from l|c|s.          #
#   020429 JAC 82425: Change some escaping/quoting for xxx-api cmds. #
#   020503 JAC 82639: Try to fix escaping/quoting again.             #
#   020719 JAC 84425: Add $rc to process_api_error call.             #
#   020725 JAC 84654: Change mgt scopes to l,m,p from l,d,p.         #
#   020729 JAC 85061: Use 4 (DM/SR/local) for scope if locator used  #
#                     or -p used and scope not set.                  #
#   040407 JAC 105863: Use escape_chars for "\" searches.            #
#   070724 JAC 141919: Add error msg for -n with no -m or -m l.      #
#   071026 JAC 146726: set delimeter for -api commmands.             #
#   080104 JAC 148354: remove reference to resolve_node.             #
#   081106 JAC 153204: add batching flag.                            #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# 1. Parse command line flags and operands, determine which flavor   #
#    of this command we are actually invoking.                       #
# 2. Print usage if -h specified.                                    #
# 3. Make sure one and only one condition is specified.              #
# 4. Make sure the condition doesn't already exist.                  #
# 5. If using -c for copy, make sure condition to copy exists.       #
# 6. Translate flags into attribute names for RMC mkrsrc command.    #
# 7. If copy, retrieve any attributes not specified in command.      #
# 8. Call RMC command mkrsrc. Also pass along -VT if necessary.      #
# 9. 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 CT_cli_input_utils qw(escape_chars);

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_source_node
                    get_locator_node
                    set_orig_rmc_scope check_set_cluster_scope
                    process_api_error process_exit_code
                    $TRUE $FALSE
                    $CTBINDIR $CTDIR
                    $SEVCRIT $SEVWARN $SEVINFO $DELIMITERI $DELIMITERO
                    $MKCNDCRIT $MKCNDWARN $MKCNDINFO
                    $LCL_SCOPE $SR_SCOPE $CSM_SCOPE 
                    $SR_SCOPE_OLD $CSM_SCOPE_OLD $CSM_SCOPE_OLD2
                    $LCL_SCOPE_VAL $SR_SCOPE_VAL $CSM_SCOPE_VAL
                    $RMC_CLI_USER_ERROR $RMC_LOCAL_SCOPE
                    $MAX_UINT32
                    $LSRSRC $MKRSRC $RSCCOND);

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

$Opt_Resource = $FALSE;                 # default - no resource
$Opt_Event_Expr = $FALSE;               # default - no event expr
$Opt_Event_Descr = $FALSE;              # default - no event descr
$Opt_Rearm_Expr = $FALSE;               # default - no rearm expr
$Opt_Rearm_Descr = $FALSE;              # default - no rearm descr
$Opt_Selection = $FALSE;                # default - no selection
$Opt_Severity = $FALSE;                 # default - no severity
$Opt_Nodes = $FALSE;                    # default - no node list
$Opt_Copy_Condition = $FALSE;           # default - no copy condition
$Opt_Mgt_Scope = $FALSE;                # default - no management scope
$Opt_Put_Node = $FALSE;                 # default - no put node
$Opt_No_Toggle= $FALSE;                 # default - no no toggle expr
$Opt_Batch = $FALSE;                    # default - no event bacthing
$Opt_Batch_Max = $FALSE;                # default - no event max
$Opt_Batch_Ret = $FALSE;                # default - no file retention period 
$Opt_Batch_Size = $FALSE;               # default - no file size
$Opt_Audit_Log	= $FALSE;		# default - no audit log control

$PROGNAME = "mkcondition";              # 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 $condition = "";                     # Condition to make
my $resource_name = "";                 # resource for -r flag
my $event_expr = "";                    # expression for -e
my $event_desc = "";                    # description for -d
my $rearm_expr = "";                    # expression for -E
my $rearm_desc = "";                    # description for -D
my $select_str = "";                    # select string for -s 
my $severity = 0;                       # default for -r
my $nodelist = "";                      # default for -n
my $new_nodelist = "";                  # resolved nodelist 74036
my $copy_condition = "";                # Condition to copy
my $put_node = "";                      # where to define condition -p
my $mgt_scope = "";                     # management scope -m
my $get_attrs = "";                     # attr list for copy
my $copy_vals = "";                     # attr values for copy
my $passopts = "";                      # options to pass to RMC
my $other_opts = "";                    # options to pass to RMC
my $this_attr = "";                     # attr name for copy
my $this_value = "";                    # value of attr name for copy
my $one_node = "";                      # one from nodelist 74036
my @nodes = ();                         # list of nodes 74036
my $hname = "";                         # used by gethost 74036
my $haliases = "";                      # used by gethost 74036 
my $haddrtype = "";                     # used by gethost 74036
my $hlength = 0;                        # used by gethost 74036
my @haddrs = ();                        # used by gethost 74036
my $comma = "";                         # used by gethost 74036
my @cmd_out = ();                       # command output 
my $batch_interval = 0;                 # event batching interval
my $batch_max_events = 0;               # max events for batching
my $batch_ret_period = 0; 		# time for batch event file to be saved
my $batch_max_totalsize = 0;		# max size for the batch event file
my $audit_log = 0; 			# audit log control flag

#--------------------------------------------------------------------#
# 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, $condition, $resource_name, $event_expr, 
 $event_desc, $rearm_expr, $rearm_desc, $select_str, 
 $severity, $nodelist, $copy_condition,
 $mgt_scope, $batch_interval, $batch_max_events, $batch_ret_period, $batch_max_totalsize, $audit_log , $put_node) = &parse_cmd_line;
($rc == 0) || error_exit($rc);

if ($Verbose) { printIMsg("IMsgmkconditionStart",$condition);}

# pass the trace or verbose flags to mkrsrc
if ($Trace) { $passopts = $passopts." -T"; }
if ($Verbose) { $passopts = $passopts." -V"; }

# for anything that's a string, escape any inner double quotes (71005)
$condition = escape_chars($condition);
$copy_condition = escape_chars($copy_condition);
$resource_name = escape_chars($resource_name);
$event_expr = escape_chars($event_expr);
$event_desc = escape_chars($event_desc);
$rearm_expr = escape_chars($rearm_expr);
$rearm_desc = escape_chars($rearm_desc);
$select_str = escape_chars($select_str);
$nodelist = escape_chars($nodelist);

# add any optional parameters of mkcondition to pass to mkrsrc
# if parameter not specified, may need to get it for copy
if ($Opt_Resource) {                    # resource present
   $other_opts = $other_opts."${DELIMITERI}ResourceClass${DELIMITERI}$resource_name"; }
else { $get_attrs = $get_attrs."${DELIMITERI}ResourceClass"; }
   
if ($Opt_Event_Expr) {                  # event expression present
   $other_opts = $other_opts."${DELIMITERI}EventExpression${DELIMITERI}$event_expr"; }
else { $get_attrs = $get_attrs."${DELIMITERI}EventExpression"; }
   
if ($Opt_Event_Descr) {                 # event description present
   $other_opts = $other_opts."${DELIMITERI}EventDescription${DELIMITERI}$event_desc"; }
else { $get_attrs = $get_attrs."${DELIMITERI}EventDescription"; }
   
if ($Opt_Rearm_Expr) {                  # rearm expression present
   $other_opts = $other_opts."${DELIMITERI}RearmExpression${DELIMITERI}$rearm_expr"; }
else { $get_attrs = $get_attrs."${DELIMITERI}RearmExpression"; }
   
if ($Opt_Rearm_Descr) {                 # rearm description present
   $other_opts = $other_opts."${DELIMITERI}RearmDescription${DELIMITERI}$rearm_desc"; }
else { $get_attrs = $get_attrs."${DELIMITERI}RearmDescription"; }
   
if ($Opt_Selection) {                   # selection string present
   $other_opts = $other_opts."${DELIMITERI}SelectionString${DELIMITERI}$select_str"; }
else { $get_attrs = $get_attrs."${DELIMITERI}SelectionString"; }
   
if ($Opt_Severity) {                    # severity present
   $other_opts = $other_opts."${DELIMITERI}Severity${DELIMITERI}$severity"; }
else { $get_attrs = $get_attrs."${DELIMITERI}Severity"; }
   
if ($Opt_Mgt_Scope) {                   # scope present
   $other_opts = $other_opts."${DELIMITERI}ManagementScope${DELIMITERI}$mgt_scope"; }
else { $get_attrs = $get_attrs."${DELIMITERI}ManagementScope"; }
   
if ($Opt_Nodes) {                       # node list present
   $other_opts = $other_opts."${DELIMITERI}NodeNames${DELIMITERI}{$nodelist}"; }
else { $get_attrs = $get_attrs."${DELIMITERI}NodeNames"; }

if ($Opt_Put_Node) {                    # put node present
   # specify where to put the condition
   $other_opts = $other_opts."${DELIMITERI}NodeNameList${DELIMITERI}{$put_node}"; }
#If audit log ionformation is provides
if ($Opt_Audit_Log) {
   $other_opts = $other_opts."${DELIMITERI}AuditLogControl${DELIMITERI}$audit_log"; }
else 
{
   $get_attrs = $get_attrs."${DELIMITERI}AuditLogControl";
}

if ($Opt_No_Toggle)
{
   $other_opts = $other_opts."${DELIMITERI}NoToggleExprFlag${DELIMITERI}1";
}  
elsif ($Opt_Toggle)
{
   $other_opts = $other_opts."${DELIMITERI}NoToggleExprFlag${DELIMITERI}0";
}
else 
{
   $get_attrs = $get_attrs."${DELIMITERI}NoToggleExprFlag";
}

if ($Opt_Batch) {                       # batching events - interval
   $other_opts = $other_opts."${DELIMITERI}EventBatchingInterval${DELIMITERI}\"$batch_interval\""; }
else 
{
   $get_attrs = $get_attrs."${DELIMITERI}EventBatchingInterval";
}

if ($Opt_Batch_Max) {                   # batching events - max events
   $other_opts = $other_opts."${DELIMITERI}EventBatchingMaxEvents${DELIMITERI}\"$batch_max_events\""; }
else 
{
   $get_attrs = $get_attrs."${DELIMITERI}EventBatchingMaxEvents";
}

if ($Opt_Batch_Ret) {                   # batching events - retention period 
   $other_opts = $other_opts."${DELIMITERI}BatchedEventRetentionPeriod${DELIMITERI}\"$batch_ret_period\""; }
else 
{
   $get_attrs = $get_attrs."${DELIMITERI}BatchedEventRetentionPeriod";
}

if ($Opt_Batch_Size) {                   # batching events - max totalsize 
   $other_opts = $other_opts."${DELIMITERI}BatchedEventMaxTotalSize${DELIMITERI}\"$batch_max_totalsize\""; }
else 
{
   $get_attrs = $get_attrs."${DELIMITERI}BatchedEventMaxTotalSize";
}

# if copying a condition (-c), get condition information and
# update with anything that was specified on the command line
if ($Opt_Copy_Condition) {              # copy a condition
   # get condition information
   # override any info with info specified in command
   if ($get_attrs ne "") {
      $copy_vals = get_condition_info($copy_condition,$get_attrs);
   }

   $get_attrs = substr($get_attrs,length($DELIMITERI));
   # add a dummy string on the end to test for
   if ($get_attrs ne "") { $get_attrs = $get_attrs."${DELIMITERI}END";}
   else { $get_attrs = "END";}

   # add the attr values in for the mkrsrc command to use
   while ($get_attrs ne "END"){

      # get the next attribute and value
      ($this_attr,$get_attrs) = split /$DELIMITERI/, $get_attrs, 2;
      ($this_value,$copy_vals) = split /$DELIMITERO/, $copy_vals, 2;

      # format it properly to use in the mkrsrc command
      if ($this_attr eq "NodeNames") {
         $other_opts = $other_opts."${DELIMITERI}${this_attr}${DELIMITERI}${this_value}"; 
         }
      else {
         
         # if it has outer double quotes, must escape an inner ones
            $this_value = escape_chars($this_value);

            # make sure it's not blank
            $this_value =~ s/^$/\\\"\\\"/;
     
            $other_opts = $other_opts."${DELIMITERI}${this_attr}${DELIMITERI}${this_value}"; 
         }
   }
} 

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

# if the put node (-p, or destination node) was not specified,
# this is a local definition.  Make sure rmc scope is set to
# local scope.
if (!$Opt_Put_Node) {                   # put node not present
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}

# -p is specified, try to help user if scope not set
else {
   # use DM/SR/Local scope if scope not set 
   check_set_cluster_scope;
}

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

@cmd_out=`$CTBINDIR/mkrsrc-api -I $DELIMITERI -D $DELIMITERO "${RSCCOND}${DELIMITERI}Name${DELIMITERI}${condition}${other_opts}" 2>&1`;

$rc = $?;
$rc = &process_exit_code($rc);

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

if ($Trace) { print STDERR "$PROGNAME: mkrsrc-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
($rc == $RMC_CLI_USER_ERROR) && ( error_exit(ERRM_CLI_USER_ERROR) );

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

if ($Verbose) { printIMsg("IMsgmkconditionEnd",$condition);}
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 condition to make.              #
#   $resource_name           Name of resource class.                 #
#   $event_expr              Event expression.                       #
#   $event_desc              Event description.                      #
#   $rearm_expr              Rearm expression.                       #
#   $rearm_desc              Rearm description.                      #
#   $select_str              Selection string.                       #
#   $severity                Severity.                               #
#   $node_list               Node list.                              #
#   $copy_condition          Name of condition to copy.              #
#                                                                    #
# Global Variables Modified:                                         #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Opt_Resource      output   True (-r) resource specified         #
#   $Opt_Event_Expr    output   True (-e) event expression specified #
#   $Opt_Event_Descr   output   True (-d) event description specified#
#   $Opt_Rearm_Expr    output   True (-E) rearm expression specified #
#   $Opt_Rearm_Descr   output   True (-D) rearm description specified#
#   $Opt_Selection     output   True (-s) selection string specified #
#   $Opt_Severity      output   True (-S) severity specified         #
#   $Opt_Nodes         output   True (-n) node names specified       #
#   $Opt_Copy_Condition output  True (-c) copy specified             #
#   $Opt_Mgt_Scope     output   True (-m) mgt scope specified        #
#   $Opt_Put_Node      output   True (-p) put node specified         #
#   $Opt_Batch         output   True (-b) event batching specified   #
#   $Opt_Batch_Max     output   True (-b) max batching events spec   #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;             # user enetered flags/parms 
my $resource = "";                      # condition name
my $select_str = "";                    # selection string from -s 
my $resource_name = "";                 # resource class from -r
my $event_expr = "";                    # expression from -e
my $event_desc = "";                    # description from -d
my $rearm_expr = "";                    # expression from -E 
my $rearm_desc = "";                    # description from -D
my $sev_value = "";                     # severity from -S
my $node_list = "";                     # hosts from -n
my $severity = $MKCNDINFO;              # default severity
my $copy_condition = "";                # existing condition for copy
my $copy_condition2 = "";               # copy of condition for copy
my $put_node = "";                      # put node from -p
my $locator = "";                       # locates the condition to copy
my $mgt_scope = "";                     # mgt scope from -m
my $mgt_scope_val = 0;                  # mgt scope translated
my @listout = ();                       # output from lsrsrc
my %opts = ();                          # for options parsing
my $batch_interval = 0;                 # event batching interval (sec)
my $batch_max_events = 0;               # max number of batched events
my $batch_ret_period = 0; 		# time for batch event file to be saved
my $batch_max_totalsize = 0;		# max size for the batch event file
my $audit_log = 0; 			# audit log control flag

# Process the command line...
if (!GetOptions(\%opts,
                'h'   ,
                'c=s' ,
                'r=s' ,
                'e=s' ,
                'E=s' ,
                'd=s' ,
                'D=s' ,
                'n=s' ,
                's=s' ,
                'S=s' ,
                'm=s' ,
                'p=s' ,
                'b=s' ,
		'g=s' ,
                'V'   ,
                'T'   ,
                'qtoggle' ,
                'qnotoggle' )) 
{
    &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
}

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

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

# check for where to define (put) condition (not required)
if (defined $opts{p}) {                 # -p for put condition
    $put_node = $opts{p};
    $Opt_Put_Node = $TRUE;              # opt flag specified
    if ($put_node eq ""){               # no text for -p
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-p");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
}

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

    # make sure the condition doesn't contain any colon charactersor control characters
    if ($resource =~ /:/ )
    {
        printEMsg("EMsgmkconditionInvalidConditionName");
        exit(ERRM_CLI_USER_ERROR);
    }
    if(containSplChar($resource) )
    { 
	exit(ERRM_CLI_USER_ERROR);
    }
    # make sure the condition doesn't already exist 
    $rc = find_resource_name($resource,$RSCCOND,$put_node);
    if ($rc == $RMC_CLI_USER_ERROR) {
       exit(ERRM_CLI_USER_ERROR);
       }
    if ($rc == 0) {                     # condition name found
        printEMsg("EMsgmkconditionConditionExists",$resource);
        exit(ERRM_CLI_USER_ERROR);
    }
}

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

# check for copy condition flag
if (defined $opts{c}) {                 # -c for copy condition
    $copy_condition = $opts{c};
    $Opt_Copy_Condition = $TRUE;        # opt flag specified
    if ($copy_condition eq ""){         # no name for -c
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-c");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
    else {
       # extract the locator if it exists
       ($temp_name, $locator) = get_locator_node($copy_condition);
       # copy the condition_name
       $copy_condition2 = $copy_condition; 
       # put back condition name without locator
       if ($locator ne "") { $copy_condition2 = $temp_name;}
      
       # make sure the condition to be copied already exists
       $rc = find_resource_name($copy_condition2,$RSCCOND,$locator);
       if ($rc != 0) {                  # condition name not found
          if ($rc != $RMC_CLI_USER_ERROR) {
             printEMsg("EMsgmkconditionConditionNotFound",$copy_condition);
          }
          exit(ERRM_CLI_USER_ERROR);
       }
    }
}

# check for resource class to be monitored (required)
if (defined $opts{r}) {                 # -r for resource class
    $resource_name = $opts{r};
    $Opt_Resource = $TRUE;              # opt flag specified
    if ($resource_name eq ""){          # no resource name for -r
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-r");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
}
else {
    # -r not specified and is required when no -c for copy
    if (!$Opt_Copy_Condition) {
       printCEMsg("EMsgERRMcliMissingRequiredFlag","-r");
       &print_usage;
       return ERRM_CLI_BAD_FLAG;
    }
}

# check for event expression (required)
if (defined $opts{e}) {                 # -e for event expression 
    $event_expr = $opts{e};
    $Opt_Event_Expr = $TRUE;            # opt flag specified
    if ($event_expr eq ""){             # no expression for -e     
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-e");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
}
else {
    # -e not specified and is required when no -c for copy
    if (!$Opt_Copy_Condition) {
       printCEMsg("EMsgERRMcliMissingRequiredFlag","-e");
       &print_usage;
       return ERRM_CLI_BAD_FLAG;
    }
}

# check for rearm event expression (not required)
if (defined $opts{E}) {                 # -E for rearm expr       
    $rearm_expr = $opts{E};         
    $Opt_Rearm_Expr = $TRUE;            # opt flag specified
    if ($rearm_expr eq ""){             # no text for -E     
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-E");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
}

# check for event description (not required)
if (defined $opts{d}) {                 # -d for event expr descr
    $event_desc = $opts{d};         
    $Opt_Event_Descr = $TRUE;           # opt flag specified
    if ($event_desc eq ""){             # no text for -d
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-d");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
}

# check for rearm event description (not required)
if (defined $opts{D}) {                 # -D for rearm expr descr
    $rearm_desc = $opts{D};
    $Opt_Rearm_Descr = $TRUE;           # opt flag specified
    if ($rearm_desc eq ""){             # no text for -D
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-D");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
}

# check for selection string (not required)
if (defined $opts{s}) {                 # -s for selection string
    $select_str = $opts{s};
    $Opt_Selection = $TRUE;             # opt flag specified
    if ($select_str eq ""){             # no string for -s
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-s");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
}

# check for audit log flag (not required)
if (defined $opts{g}) {                 # -g audit log information
    $audit_log = $opts{g};
    $Opt_Audit_Log = $TRUE;             # opt flag specified
    if ($audit_log eq "")  {#|| $audit_log !~ /^[0-2]$/) {             # no string for -g
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-g");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
}
# check for event severity (not required)
$severity = $MKCNDINFO;                 # default severity
if (defined $opts{S}) {                 # -S for severity 
    $sev_value = $opts{S};
    $Opt_Severity = $TRUE;              # opt flag specified
    if ($severity eq ""){               # no severity for -S
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-S");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
    else {                              # check severity used
      if ($sev_value eq $SEVCRIT) { $severity = $MKCNDCRIT; }
      elsif ($sev_value eq $SEVWARN) { $severity = $MKCNDWARN;}
      elsif ($sev_value eq $SEVINFO) { $severity = $MKCNDINFO;}
      else {                            # wrong severity
         printEMsg("EMsgmkconditionInvalidSeverity",$sev_value,"-S");
         &print_usage;
         return ERRM_CLI_BAD_OPERAND;
      }
    }           
}

# check for host list (not required)
if (defined $opts{n}) {                 # -n for node list
    $node_list = $opts{n};
    $Opt_Nodes = $TRUE;                 # opt flag specified
    if ($node_list eq ""){              # no string for -n
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-n");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }

    # to use -n, you must use -m with a non-local scope
    if ( (!defined $opts{m}) || 
       ( defined $opts{m} && ($opts{m} eq $LCL_SCOPE) ) ) {
       printEMsg("EMsgmkconditionNFlagNeedMFlag");
       return ERRM_CLI_BAD_FLAG;
    }
}

# check for management scope (not required)
if (defined $opts{m}) {                 # -m for mgt scope
    $mgt_scope = $opts{m};
    $Opt_Mgt_Scope = $TRUE;             # opt flag specified
    if ($mgt_scope eq ""){              # no text for -m
       printCEMsg("EMsgERRMcliMissingRequiredFlagOperand","-m");
       &print_usage;
       return ERRM_CLI_BAD_OPERAND;
    }
    else {                              # check scope used
      if ($mgt_scope eq $LCL_SCOPE) { $mgt_scope_val = $LCL_SCOPE_VAL; }
      elsif ($mgt_scope eq $SR_SCOPE) {$mgt_scope_val = $SR_SCOPE_VAL;}
      elsif ($mgt_scope eq $SR_SCOPE_OLD) {$mgt_scope_val = $SR_SCOPE_VAL;}
      elsif ($mgt_scope eq $CSM_SCOPE) {$mgt_scope_val = $CSM_SCOPE_VAL;}
      elsif ($mgt_scope eq $CSM_SCOPE_OLD) {$mgt_scope_val = $CSM_SCOPE_VAL;}
      elsif ($mgt_scope eq $CSM_SCOPE_OLD2) {$mgt_scope_val = $CSM_SCOPE_VAL;}
      else {                            # wrong scope
         printEMsg("EMsgmkconditionInvalidScope",$mgt_scope,"-m");
         &print_usage;
         return ERRM_CLI_BAD_OPERAND;
      }
    }
}

if (defined $opts{qnotoggle}) 
{
    if (defined $opts{qtoggle})
    {
        printCEMsg("EMsgERRMcliImproperUsageCombination", "--qnotoggle", "--qtoggle");
        &print_usage;
        return ERRM_CLI_BAD_FLAG;
    }
    $Opt_No_Toggle= $TRUE;
}
elsif (defined $opts{qtoggle})
{
    $Opt_Toggle= $TRUE;
}

# check for event batching  -b interval[,max_events]
if (defined $opts{b}) {                 # -b for event batching

    # get the interval and optional max events
    ($batch_interval, $batch_max_events, $batch_ret_period, $batch_max_totalsize) = split (/,/, $opts{b});
    if ($batch_interval ne "" ){
       if ( ($batch_interval < 0) || ($batch_interval > $MAX_UINT32) || !($batch_interval =~ /^[0-9]+$/) ){
          printEMsg("EMsgmkconditionInvalidBInterval",$batch_interval,"-b");
          return ERRM_CLI_BAD_OPERAND;
       }
       else {
          $Opt_Batch = $TRUE;           # good interval
       }
    }
    else {
       printEMsg("EMsgmkconditionInvalidBInterval",$batch_interval,"-b");
       return ERRM_CLI_BAD_OPERAND;
    }

    # check the optional max events
    if ($batch_max_events ne "" ){
       if ( (($batch_max_events < 0) || ($batch_max_events > $MAX_UINT32)) ||
            !($batch_interval =~ /^[0-9]+$/) ||
            (($batch_interval == 0) && ($batch_max_events != 0)) ) {
          printEMsg("EMsgmkconditionInvalidBMaxEvents",$batch_max_events,"-b");
          return ERRM_CLI_BAD_OPERAND;
       }
       else {
          $Opt_Batch_Max = $TRUE;       # good interval
       }
    }

    # check option retention period
    if ($batch_ret_period ne "" ){
       if ( (($batch_ret_period < 0) || ($batch_ret_period > $MAX_UINT32)) ||
            !($batch_interval =~ /^[0-9]+$/) || ($batch_interval == 0) )  {
          printEMsg("EMsgmkconditionInvalidBRetPeriod",$batch_ret_period,"-b");
          return ERRM_CLI_BAD_OPERAND;
       }
       else {
          $Opt_Batch_Ret = $TRUE;       # good interval
       }
    }

    # check option max total size
    if ($batch_max_totalsize ne "" ){
       if ( (($batch_max_totalsize < 0) || ($batch_max_totalsize > $MAX_UINT32)) ||
            !($batch_interval =~ /^[0-9]+$/) || ($batch_interval == 0) ) {
          printEMsg("EMsgmkconditionInvalidBMaxTotalSize",$batch_max_totalsize,"-b");
          return ERRM_CLI_BAD_OPERAND;
       }
       else {
          $Opt_Batch_Size = $TRUE;       # good interval
       }
    } 
}

# return everything back to main
return(0, $resource, $resource_name, $event_expr,
       $event_desc, $rearm_expr, $rearm_desc, $select_str, 
       $severity, $node_list, $copy_condition,
       $mgt_scope_val, $batch_interval, $batch_max_events, $batch_ret_period, $batch_max_totalsize, 	   $audit_log, $put_node);      # success
}   # end parse_cmd_line


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


#--------------------------------------------------------------------#
# get_condition_info : Uses the list resource RMC CLI command to     #
#   list certain attributes of a condition.                          # 
#                                                                    #
# Paramaters:                                                        #
#   $condition_name  the condition to list                           #
#   $attr_list       double colon delimited list of attribute names  #
#                                                                    #
# Returns:                                                           #
#   @attr_vals       list of attribute values                        #
#                                                                    #
# Global Variables modified:                                         #
#   None.                                                            #
#--------------------------------------------------------------------#
sub get_condition_info
{
my $condition_name = shift(@_);
my $attr_list = shift(@_);
my $attr_vals = ();
my $trace_opt = "";
my $locator  = "";
my $temp_name = "";
my $node_select = "";
my @lsr_out = ();
my $rc = 0;

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

# re-establish original CT_MANAGEMENT_SCOPE
set_orig_rmc_scope;

# check to see if resource name has a Node_name to locate it.
# if not, set rmc local scope.  if it does, use it in select string.
if ($locator eq "") {
   # set CT_MANAGEMENT_SCOPE to local for query
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}
# else use location is select string
else {
   $node_select = " && NodeNameList |< {\\\"$locator\\\"}";

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

# list condition to get the attr values
if ($Trace) { print STDERR "$PROGNAME: calling lsrsrc-api\n";}

$ENV{CT_CLI_QUOTE_STRING} = 0;
@lsr_out = `$CTBINDIR/lsrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCCOND}${DELIMITERI}\"Name==\\\"$condition_name\\\"${node_select}\"${DELIMITERI}${DELIMITERI}${DELIMITERI}${attr_list} 2>&1`;

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

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

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

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

# return ERRM CLI user error if it's an RMC CLI user error
($rc == $RMC_CLI_USER_ERROR) && ( error_exit(ERRM_CLI_USER_ERROR) );

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

# get attribute values
$attr_vals = $lsr_out[0];
chomp($attr_vals);

return ($attr_vals);
}

sub containSplChar ($)
{
local %specialCharString = (
    '\cA' => "^A",
    '\cB' => "^B",
    '\cC' => "^C",
    '\cD' => "^D",
    '\cE' => "^E",
    '\cF' => "^F",
    '\cG' => "^G",
    '\cH' => "^H",
    '\cI' => "^I",
    '\n' => "\\n",
    '\cK' => "^K",
    '\f' => "\\f",
    '\r' => "\\r",
    '\cN' => "^N",
    '\cO' => "^O",
    '\cP' => "^P",
    '\cQ' => "^Q",
    '\cR' => "^R",
    '\cS' => "^S",
    '\cT' => "^T",
    '\cU' => "^U",
    '\cV' => "^V",
    '\cW' => "^W",
    '\cX' => "^X",
    '\cY' => "^Y",
    '\cZ' => "^Z",
    '\c[' => "^[",
    '\c[\\]' => "^\\",
    '\c]' => "^]",
    '\c^' => "^^",
    '\c_' => "^_",
);
    my $resource=shift(@_);

    foreach $code (keys %specialCharString) {
        if ($resource =~ /$code/) {
            printEMsg("EMsgmkconditionInvalidConditionName1",$specialCharString{$code});
	    return 1;
        }
    }
    return 0;
}