#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2004,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 = "@(#)06   1.17   src/rsct/rm/LPRM/cli/bin/lphistory.perl, LPRM, rsct_rady, rady2035a 11/12/15 16:38:26"

# Return LP commands history in the current RMC session

use strict;
use locale;
use Time::Local;
BEGIN
  {
 # this enables us to redirect where it looks for other RSCT files during development
 $::rsctroot = $ENV{'RSCT_ROOT'} || '/opt/rsct';
 $::rsctpm = "$::rsctroot/pm";
 $::rsctmsgmaps = "$::rsctroot/msgmaps";
  }

use lib $::rsctpm;
use Getopt::Std;
use CT_cli_utils qw(printIMsg printEMsg);
use CT_cli_display_utils qw(set_display);

use LPRM_cli_utils qw(process_api_error process_exit_code remove_api_error getIMsg);
use LPRM_cli_include qw($DELIMITERI $DELIMITERO);
use Socket;

$main::PROGNAME = 'lphistory';
$main::MSGCAT = 'lprmcli.cat';
$main::LSMSG = '/opt/rsct/bin/ctdspmsg';

# For the usage, see sensorcli.msg
sub usage { printIMsg('IMsgLphistoryUsagesNew2');  exit (scalar(@_) ? $_[0] : 1); }

# Parse the cmd line args and check them
if (! getopts('an:u:m:C:S:B:E:L:hTVc') ) { &usage(3); }
if ($::opt_h) { &usage(0); }
#if (((scalar(@ARGV) >= 1) && ($::opt_c)) || ($::opt_h))  { &usage; }
if ((scalar(@ARGV) >= 1) && ($::opt_c)) { &usage(4); }
if (($::opt_L) && ($::opt_c)) { printEMsg('EMsglphistoryLandcExclusive');&usage(4); }
if (scalar(@ARGV)>1) { &usage(4); }
if ($::opt_a && $::opt_n) { &usage(5); }
#if ($::opt_V) { $::opt_v = 1; }

my $numCmds = 0;
my $matchcriteria = "TemplateId <= 2";
my $selectstr = "Name='LPRM'";

if (scalar(@ARGV) < 1 && $::opt_c)
   {
    $numCmds = 0;
   }
elsif (scalar(@ARGV) < 1 && !defined($::opt_c))
   {
    $numCmds = 10;
   }
else
   {
    $numCmds = shift @ARGV;
    if ($numCmds < 1 || $numCmds > 1000)
       {
        printEMsg('EMsglphistoryInvalidNumCmds');
        exit(5) ;
       }
   }

if ($::opt_a || defined($::opt_n))
  {
 #todo: support symbolic names for values 2 and 3
 if ($ENV{CT_MANAGEMENT_SCOPE}!=2 && $ENV{CT_MANAGEMENT_SCOPE}!=3) { $ENV{CT_MANAGEMENT_SCOPE}=4; }
  }
else { $ENV{CT_MANAGEMENT_SCOPE}=1; }

if (defined($::opt_n))
  {
        my @nodes = split(/[, ]+/,$::opt_n);
        if (length($selectstr)) { $selectstr .= ' && '; }
        $selectstr .= q/NodeNameList IN ('/ . join("','",@nodes) . q/')/;
  }

if (defined($::opt_u))
  {
   $matchcriteria = $matchcriteria." && ";
   if ($::opt_u =~ /\%/)
      {$matchcriteria = $matchcriteria."UserID LIKE '$::opt_u'"; }
   else
      {$matchcriteria = $matchcriteria."UserID='$::opt_u'"; }
  }

if (defined($::opt_m))
  {
   $matchcriteria = $matchcriteria." && ";
   if ($::opt_m =~ /\%/)
      {$matchcriteria = $matchcriteria."MappedID LIKE '$::opt_m'"; }
   else
      {$matchcriteria = $matchcriteria."MappedID='$::opt_m'"; }
  }

if (defined($::opt_C))
  {
   $matchcriteria = $matchcriteria." && ";
   if ($::opt_C =~ /\%/)
      {$matchcriteria = $matchcriteria."CommandName LIKE '$::opt_C'"; }
   else
      {$matchcriteria = $matchcriteria."CommandName='$::opt_C'"; }
  }

if (defined($::opt_S))
  {
   $matchcriteria = $matchcriteria." && ";
   $matchcriteria = $matchcriteria."Command='$::opt_S'";
  }
if (defined($::opt_B))
  {
   $matchcriteria = $matchcriteria." && ";
   my $starttime = convtime2local($::opt_B)*1000000; 
   #print $starttime;
   $matchcriteria = $matchcriteria."Time >= $starttime";
  }

if (defined($::opt_E))
  {
   $matchcriteria = $matchcriteria." && ";
   my $endtime = convtime2local($::opt_E)*1000000; 
   #print $endtime;
   $matchcriteria = $matchcriteria."Time <= $endtime";
  }
my @dispoption;
if (defined($::opt_L))
   {
     if (($::opt_L =~ /[^acemntux]/))
        {printEMsg ('EMsglphistoryInvalidDisplayOption'); 
         exit(5);}
     else
        {
         if (($::opt_L =~ /[cemntux]/) && $::opt_L =~ /a/)
             {printEMsg ('EMsglphistoryInvalidDisplayCombination'); 
              exit(5);}
         else
            { if ($::opt_L eq "a") {$::opt_L = "tumnxc";}     @dispoption = split(//,$::opt_L);
             if (defined($::opt_n) || defined($::opt_a) && ($::opt_L =~ /^n/))
                {push(@dispoption,'n');} 
            }
        }
   }
else
   {
    $dispoption[0] = "c";
    if (defined($::opt_n) || defined($::opt_a))
       {$dispoption[1] = "n";} 
   }
    
   
if (length($selectstr)) { $selectstr = qq("$selectstr"); }
if (length($matchcriteria)) { $matchcriteria = qq("$matchcriteria"); }
my $cmd = "";

if ($::opt_T) {print STDERR "$main::PROGNAME: calling runact-api to get command history list\n ";}

if ($numCmds != 0){
$cmd = qq(/usr/bin/runact-api -I $DELIMITERI -D $DELIMITERO -s IBM.AuditLog${DELIMITERI}${selectstr}${DELIMITERI}GetRecords${DELIMITERI}MatchCriteria${DELIMITERI}${matchcriteria}${DELIMITERI}IncludeDetail${DELIMITERI}0 2>&1);
}
else {
$cmd = qq(/usr/bin/runact-api -I $DELIMITERI -D $DELIMITERO -s IBM.AuditLog${DELIMITERI}${selectstr}${DELIMITERI}DeleteRecords${DELIMITERI}MatchCriteria${DELIMITERI}${matchcriteria} 2>&1);
}

if ($::opt_V) { $main::PROGNAME = 'lslpcmd'; printIMsg('IMsgRmcCmd', $cmd); $main::PROGNAME = 'lphistory'; }

my @output = `$cmd`;
#my $rc = $? >> 8;
my $rc = $?;
$rc = process_exit_code($rc);

if ($rc && (!defined($::opt_a) && !defined($::opt_n))) #print the error
  {
        if ($::opt_T) {print STDERR "$main::PROGNAME: runact-api returned $rc\n ";}
        #if (!$::opt_V) { $output[0] =~ s/.*::.*::.*::.*::.*:://; }
        #print @output;
        process_api_error($DELIMITERO,$rc,@output);
        exit $rc;
  }
elsif($numCmds == 0)
  {
  # print errors and remove them from the output
  process_api_error($DELIMITERO,$rc,@output);
  @output = remove_api_error(@output);
  }
else # if rc == 0 or opt_a or opt_n is specified, then print the history list
 {
  # print errors and remove them from the output
  process_api_error($DELIMITERO,$rc,@output);
  @output = remove_api_error(@output);
  my $ind = 1;   #row index for history display
  my @histArray; #array to hold display data that feeds into set_display
  $histArray[0][0]="";  # title
  # get the heading fields from msg catalogue
  my @heading = getIMsg("IMsglphistoryHeading");
  # form heading
  my @headerArray = split(/::/,$heading[0]);
  #Time::UserID::MappedID::NodeName::StdErr::RC::CommandPath::CommandName
  my $m =1; # column index for header data
  #based on disp options order the header's order can change too
  foreach my $headopt(@dispoption)
    {
         if ($headopt eq "t")
            {
              $histArray[0][$m] = $headerArray[0] ;   
            }
         if ($headopt eq "u")
            {
              $histArray[0][$m] = $headerArray[1] ;  
            }
         if ($headopt eq "m")
            {
              $histArray[0][$m] =   $headerArray[2] ; 
            }
         if ($headopt eq "n")
            {
              $histArray[0][$m] =   $headerArray[3] ; 
            }
         if ($headopt eq "e")
            {
              $histArray[0][$m] =   $headerArray[4] ; 
            }
         if ($headopt eq "x")
            {
              $histArray[0][$m] =   $headerArray[5] ; 
            }
         if ($headopt eq "c")
            {
              $histArray[0][$m] =   $headerArray[6] ; 
            }
    $m = $m + 1;
    } 
  # num of cmds to display, so skip that many records. 
  my $numToSkip = $#output + 1 - $numCmds; 
  foreach my $outent(@output)
    {
     if ($numCmds <= ($#output+1))
        {
         if ($numToSkip != 0)
            {
              $numToSkip = $numToSkip - 1;
              next;
             }
        }
     #get the display data into @node 
     my @node = split(/$DELIMITERO/,$outent); 
     my $i=1;
     my $j=0;
     foreach my $opt(@dispoption)
        {
         if ($opt eq "t")
            {
              $histArray[$ind][$i] = localtime($node[2]/1000000);   
            }
         if ($opt eq "u")
            {
              $histArray[$ind][$i] = $node[20];   
            }
         if ($opt eq "m")
            {
              $histArray[$ind][$i] = $node[22];   
            }
         if ($opt eq "n")
            {
              chop($node[28]);
              $histArray[$ind][$i] = $node[28];   
            }
         if ($opt eq "e")
            {
              $histArray[$ind][$i] = $node[26];   
            }
         if ($opt eq "x")
            {
              $histArray[$ind][$i] = $node[24];   
            }
         if ($opt eq "c")
            {
              $histArray[$ind][$i] = $node[14];   
            }
         #if ($opt eq "a")
         #   {
         #     $histArray[$ind][1] =$node[2] ;   
         #    for ( $i = 2; $i <= 8; $i++)
         #        {
         #           $histArray[$ind][$i] = $node[$j+14];
         #           $j=$j+2;
         #print "histArray[$ind][$i] = $histArray[$ind][$i]\n";
         #}
         #   }
         $i= $i+1; #column index  for display data
        } 
     $ind = $ind +1;
    }
     #my %command=('CommandPath' => $node[14], 'CommandName' => $node[16], 'Mechanism' => $node[18], 'UserID' => $node[20], 'MappedID' => $node[22], 'RC' => $node[24], 'StdErr' => $node[26], 'NodeName' => $node[28]); 
    
  $rc = set_display("column", "TRUE", $ind-1, 8, \@histArray, "");
 }
exit $rc;

sub convtime2local()
{
   my $time2bchanged = shift(@_);
   my @loctime;
   my $timelen = length($time2bchanged);
   #print $timelen;
   if ($timelen != 12)
      {
       printEMsg('EMsglphistoryInvalidTime');
       exit(5);
      }
   my $p = 0;
   my $lentoext = 2;
   while ($timelen != 0)
    {
      if ($p == 8)
         {
          $lentoext = 4;
          $timelen=$timelen -2;
         }
      $loctime[$p/2] = substr($time2bchanged,$p ,$lentoext);
      #print "loctime[$p/2] = $loctime[$p/2]\n";
      $p=$p+2;
      $timelen=$timelen -2;
    }
   #for timelocal, subtract 1 from month and 1900 from year
   my $convertedtime = timelocal(00,$loctime[3],$loctime[2],$loctime[1],$loctime[0]-1,$loctime[4]-1900);
   #print "timelocal(00,$loctime[3],$loctime[2],$loctime[1],$loctime[0]-1,$loctime[4]-1900)";
   #print $convertedtime;
   return $convertedtime;
}