# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,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 
package CT_cli_utils;
# sccsid = "@(#)46   1.27   src/rsct/cli/pm/CT_cli_utils.pm.perl, ctcli, rsct_rady, rady2035a 11/12/15 16:42:09"
######################################################################
#                                                                    #
# Package: CT_cli_utils.pm                                           #
#                                                                    #
# Description:                                                       #
#   This Perl Module / Package contains utility/common subroutines   #
#   for the Perl RSCT Commands.                                      #
#   Note: Do not place utilities in here that reference the CT::CT   #
#   Perl to C extensions. This module will be used by commands that  #
#   do not need to use the CT::CT perl to C extensions and will not  #
#   want the extra Perl overhead of loading those extensions.        #
#                                                                    #
# Subroutines Available:                                             #
#   printCIMsg          - Use $LSMSG to print general ctcli          #
#                         information messages.                      #
#                                                                    #
#   printCEMsg          - Use $LSMSG to print general ctcli          #
#                         error messages.                            #
#                                                                    #
#   printIMsg           - Uses the calling commands:                 #
#                         $main::LSMSG, $main::PROGNAME,             #
#                         $main::MSGCAT to print command specific    #
#                         informational messages.                    #
#                                                                    #
#   printEMsg           - Uses the calling commands:                 #
#                         $main:LSMSG, $main::PROGNAME,              #
#                         $main::MSGCAT to print command specific    #
#                         error messages.                            #
#                                                                    #
#   calc_cmdarg_length  - Calculates the maximum number of chars     #
#                         that can be used for a command argument.   #
#                                                                    #
# Examples:                                                          #
#   printCEMsg("EMsgCTcliInputError", $input_line);                  #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   None.                                                            #
#                                                                    #
# Outputs:                                                           #
#   None.                                                            #
#                                                                    #
# External References:                                               #
#   Commands:   $LSMSG                                               #
#   Variables:  $main::PROGNAME         in  Name of calling command. #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   000900 SAB XXXXX: Initial design and write.                      #
#   010202 SAB 71115: Moved data type stuff to CT_cli_data_types.pm  #
#   031020 JAC 100623: Check for certain distros (hopefully temp).   #
#   031103 JAC 100977: Change the KERNEL level.                      #
#   041124 JAC 115377: Change the KERNEL level again for SLES9.      #
#   050722 JAC 126161: Change the KERNEL level again for RHEL4U1.    #
#   051024 JAC 125712: Add the calc_cmdarg_length function.          #
#   051101 JAC 130467: Make KERNEL level change for all RHEL4 updates#
#   090402 MB  xxxxxx: Add TRUE/FALSE/CTDIR/CTBINDIR to export list. #
######################################################################

use Exporter ();
@ISA = qw(Exporter);
@EXPORT_OK = qw(
    printCEMsg
    printCIMsg  
    printIMsg
    printEMsg
    calc_cmdarg_length
    $TRUE $FALSE
    $CTDIR $CTBINDIR
);

use locale;
use lib "/opt/rsct/pm";


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$MSGCAT = "ctcli.cat";                 # Msg catalogue for this cmd
$MSGSET = "ctcli";                     # Common message set

# set LD_ASSUME_KERNEL if running on RHEL3 or RHEL4 Updates
my $rh_relfile = "/etc/redhat-release";
my $rh_vers = '^Red Hat Enterprise Linux .* release 3 (.*)$';
my $rh_vers4Us = '^Red Hat Enterprise Linux .* release 4 (.* Update .*)$';
if (-f $rh_relfile){
   `/bin/grep \"$rh_vers\" $rh_relfile > /dev/null 2>&1`;
   my $rhexit = $? >> 8;
   if ($rhexit == 0){
      $ENV{'LD_ASSUME_KERNEL'}="2.4.19";
   }
   # set LD_ASSUME_KERNEL if running on RHEL4U1
   else {
      `/bin/grep \"$rh_vers4Us\" $rh_relfile > /dev/null 2>&1`;
      $rhexit = $? >> 8;
      if ($rhexit == 0){
         $ENV{'LD_ASSUME_KERNEL'}="2.4.19";
      }
   }
}

# set LD_ASSUME_KERNEL if running on SLES9
my $sl_relfile = "/etc/SuSE-release";
my $sl_vers = '^SUSE LINUX Enterprise Server 9 (.*)$';
my $sl_patch = 'PATCHLEVEL';
my $sl_patchlevel = 0;
if (-f $sl_relfile){
   `/bin/grep \"$sl_vers\" $sl_relfile > /dev/null 2>&1`;
   my $slexit = $? >> 8;
   if ($slexit == 0){
      $sl_patchlevel = `/bin/grep \"$sl_patch\" $sl_relfile | awk '{print \$3}' 2>/dev/null`;
      $slexit = $? >> 8;
      chop($sl_patchlevel);
      if(($slexit != 0) || ($sl_patchlevel < 4)) {
          $ENV{'LD_ASSUME_KERNEL'}="2.4.19";
      }
   }
}

#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#

$TRUE = 1;
$FALSE = 0;

$CTDIR = "/opt/rsct";             # Cluster directory path
$CTBINDIR = "$CTDIR/bin";              # Cluster Bin directory path
$LSMSG = "$CTBINDIR/ctdspmsg";         # Display message rtn.
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps"; # Msg map path for $LSMSG   


#--------------------------------------------------------------------#
# Exported Subroutines (with @EXPORT_OK, -> on demand).              #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# printCEMsg : Calls $LSMSG to print out the common system           #
#   registry cli error messages with the required paramaters.        #
#   Messages printed to stderr.                                      #
#   This subroutine is like printEMsg except it is used to print     #
#   the common CT CLI messages which are in the ctcli message set    #
#   and it prefixes the message with the appropriate program name.   #
#                                                                    #
# Paramaters:                                                        #
#   msg         Message mnemonic / message number in a sense.        #
#   optargs     Extra arguments/parameters to send to LSMSG.         #
#                                                                    #
# Returns:  None.                                                    #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace    in  Prints extra info when trace is on.          #
#   $main::PROGNAME in  Calling program/command for error message.   #
#   $LSMSG          in  Path and command to display messages.        #
#   $MSGCAT         in  CT CLI Message catalogue.                    #
#   $MSGSET         in  CT CLI common message set "ctcli".           #
#--------------------------------------------------------------------#
sub printCEMsg
{
my ($msg, @optargs) = @_; 
my ($optarg, $optargs); 

$main::Trace &&
  print STDERR "$LSMSG $MSGSET $MSGCAT $msg $main::PROGNAME @optargs\n";

# Keep the args to LSMSG separate by separating with single quotes
# but must replace internal single quotes with blanks or get an error.
# Must escape internal double quotes for the system call.
foreach $optarg (@optargs) {
    $optarg =~ s/'/\<U\+0027\>/g;
    $optarg =~ s/"/\\"/g;
}
$optargs = "'" . join("' '",@optargs) . "'";

(scalar @optargs > 0) ?
    system "$LSMSG $MSGSET $MSGCAT $msg $main::PROGNAME $optargs | /bin/sed \"s/\<U\+0027\>/'/g\" 1>&2" :
    system "$LSMSG $MSGSET $MSGCAT $msg $main::PROGNAME 1>&2";

return;
}   # end printCEMsg


#--------------------------------------------------------------------#
# printCIMsg : Calls $LSMSG to print out the common system           #
#   registry cli informational messages with the required paramaters.#
#   Messages printed to stdout.                                      #
#   This subroutine is like printIMsg except it is used to print     #
#   the common CT CLI messages which are in the ctcli message set.   #
#                                                                    #
# Paramaters:                                                        #
#   msg       in  Message mnemonic / message number in a sense.      #
#   optargs   in  Extra arguments/parameters to send to LSMSG.       #
#                                                                    #
# Returns:  None.                                                    #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace    in  Prints extra info when trace is on.          #
#   $LSMSG          in  Path & Command to display messages.          #
#   $MSGCAT         in  CT CLI Message catalogue.                    #
#   $MSGSET         in  CT CLI common message set "ctcli".           #
#--------------------------------------------------------------------#
sub printCIMsg
{
my ($msg, @optargs) = @_;
my ($optarg, $optargs);

$main::Trace &&
    print STDERR "$LSMSG $MSGSET $MSGCAT $msg @optargs\n";

# Keep the args to LSMSG separate by separating with single quotes
# but must replace internal single quotes with blanks or get an error.
# Must escape internal double quotes for the system call.
foreach $optarg (@optargs) {
    $optarg =~ s/'/\<U\+0027\>/g;
    $optarg =~ s/"/\\"/g;
}
$optargs = "'" . join("' '",@optargs) . "'";

(scalar @optargs > 0) ?
    system "$LSMSG $MSGSET $MSGCAT $msg $optargs | /bin/sed \"s/\<U\+0027\>/'/g\"" :
    system "$LSMSG $MSGSET $MSGCAT $msg";

return;
}   # end printCIMsg


#--------------------------------------------------------------------#
# printIMsg : calls $LSMSG to print out the message with the         #
#   required paramaters, no sense hard coding them all over.         #
#   Messages printed to stdout.                                      #
#                                                                    #
# Paramaters:                                                        #
#   msg       in  Message mnemonic / message number in a sense.      #
#   optargs   in  Extra arguments/parameters to send to LSMSG.       #
#                                                                    #
# Returns:  None.                                                    #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace    in  Print extra info when trace is on.           #
#   $main::PROGNAME in  Calling program/command for error message.   #
#   $main::LSMSG    in  Path & Command to display messages.          #
#   $main::MSGCAT   in  The calling commands Message catalogue.      #
#--------------------------------------------------------------------#
sub printIMsg
{
my ($msg, @optargs) = @_;
my ($optarg, $optargs);

$main::Trace &&
    print STDERR "$main::LSMSG $main::PROGNAME $main::MSGCAT $msg @optargs\n";

# Keep the args to LSMSG separate by separating with single quotes
# but must replace internal single quotes with blanks or get an error.
# Must escape internal double quotes for the system call.
foreach $optarg (@optargs) {
    $optarg =~ s/'/\<U\+0027\>/g;
    $optarg =~ s/"/\\"/g;
}
$optargs = "'" . join("' '",@optargs) . "'";

(scalar @optargs > 0) ? 
    system "$main::LSMSG $main::PROGNAME $main::MSGCAT $msg $optargs | /bin/sed \"s/\<U\+0027\>/'/g\"" :
    system "$main::LSMSG $main::PROGNAME $main::MSGCAT $msg";

return;
}   # end printIMsg


#--------------------------------------------------------------------#
# printEMsg : calls $LSMSG to print out the message with the         #
#   required paramaters, no sense hard coding them all over.         #
#   Messages printed to stderr.                                      #
#   The difference between this function and printCEMsg is this      #
#   function uses the calling commands Message catalogue and set.    #
#                                                                    #
# Paramaters:                                                        #
#   msg       in  Message mnemonic / message number in a sense.      #
#   optargs   in  Extra arguments/parameters to send to LSMSG.       #
#                                                                    #
# Returns:  None.                                                    #
#                                                                    #
# Global Variables:                                                  #
#   $main::Trace    in  Print extra info when trace is on.           #
#   $main::PROGNAME in  Calling program/command for error message.   #
#   $main::LSMSG    in  Path & Command to display messages.          #
#   $main::MSGCAT   in  The calling commands Message catalogue.      #
#--------------------------------------------------------------------#
sub printEMsg
{
my ($msg, @optargs) = @_;
my ($optarg, $optargs);

$main::Trace &&
    print STDERR "$main::LSMSG $main::PROGNAME $main::MSGCAT $msg @optargs\n";

# Keep the args to LSMSG separate by separating with single quotes
# but must replace internal single quotes with blanks or get an error.
# Must escape internal double quotes for the system call.
foreach $optarg (@optargs) {
    $optarg =~ s/'/\<U\+0027\>/g;
    $optarg =~ s/"/\\"/g;
}
$optargs = "'" . join("' '",@optargs) . "'";

(scalar @optargs > 0) ?
    system "$main::LSMSG $main::PROGNAME $main::MSGCAT $msg $main::PROGNAME $optargs | /bin/sed \"s/\<U\+0027\>/'/g\" 1>&2" :
    system "$main::LSMSG $main::PROGNAME $main::MSGCAT $msg $main::PROGNAME 1>&2";

return;
}   # end printEMsg


#--------------------------------------------------------------------#
# calc_cmdarg_length - function that determines how big of a command #
#   argument can be passed to a program, like mkrsrc-api, for        #
#   example.                                                         #
#                                                                    #
# Return:                                                            #
#   $cmd_arg_len              the maximum size that can be passed    #
#--------------------------------------------------------------------#
sub calc_cmdarg_length
{
my $rc = 0;
my $arg_max = 0;
my $wc_out = "";
my $dummy = "";
my $num_env = 0;
my $size_env = 0;
my $cmd_arg_len = 8192;   # default = 8k

# get the max length for args and env vars
$arg_max = `/usr/bin/getconf ARG_MAX 2>&1`;
$rc = $?;
if ($rc == 0) {

   # get info of env var size
   $wc_out = `/usr/bin/env | /usr/bin/wc 2>&1`;
   $rc = $?;
   if ($rc == 0) {

      # calculate the limit
      ($dummy, $num_env, $dummy, $size_env) = split /\s+/,$wc_out;
      $cmd_arg_len = $arg_max - $size_env - ($num_env*5) - 4096;
   }
}

return $cmd_arg_len
}   # end calc_cmdarg_length


#--------------------------------------------------------------------#
# End Exported Subroutines (with @EXPORT_OK, -> on demand).          #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# End File                                                           #
#--------------------------------------------------------------------#
