#!/usr/local/bin/perl
# 
# $Header: oidtasks.pl 02-mar-2004.09:49:47 xshi Exp $
#
# oidtasks.pl
# 
# Copyright (c) 2002, 2004, Oracle Corporation.  All rights reserved.  
#
#    NAME
#      oidtasks.pl - <one-line expansion of the name>
#
#    DESCRIPTION
#       The script is called by OidSystemScriptManager.java
#       to perform oid tasks
#
#    NOTES
#       Usage: perl oidtasks.pl <task> <oraclehome> [...]
#       Note: The last line is the return message -
#              DO NOT add "\n" in print statement without test.
#       Replace all other oid scripts, the platform dependency
#       will be handled.
#        - currently most of the tasks work on solaris only.
#
#    MODIFIED   (MM/DD/YY)
#    xshi        03/02/04 - nt monitor 3474263 
#    xshi        09/22/03 - fix nt compatible 
#    xshi        08/25/03 - tempfile location 
#    xshi        08/01/03 - correct memory usage
#    xshi        07/07/03 - performance
#    xshi        05/16/03 - add startall, consolidate
#    xshi        03/18/03 - oidbug
#    xshi        01/28/03 - use dnlist
#    xshi        11/05/02 - xshi_bug-2619780_4.0.1
#    xshi        11/01/02 - Creation
# 

my ($cmd, $ohm, $sid, $param) = @ARGV;

$ENV{ORACLE_HOME} = $ohm;

# DO NOT print debug message -
# some command expects one line result only

#
# these commands do not require return value
# print message can be either exit code or error message
#
if ($cmd eq "startOidMon")
{
  $cmd = "$ohm/bin/oidmon connect=$sid start";
  print system($cmd);
}
elsif ($cmd eq "stopOidMon")
{
  $cmd = "$ohm/bin/oidmon connect=$sid stop";
  print system($cmd);
}
elsif ($cmd eq "startInstance")  # start oid with instance number
{
  # param is instance number
  print system("$ohm/bin/oidctl connect=$sid server=OIDLDAPD instance=$param start");
}
elsif ($cmd eq "stopInstance")
{
  # param is instance number
  print system("$ohm/bin/oidctl connect=$sid server=OIDLDAPD instance=$param stop");
}
elsif ($cmd eq "restartInstance")
{
  # param is instance number
  print system("$ohm/bin/oidctl connect=$sid server=OIDLDAPD instance=$param restart");
}
elsif ($cmd eq "startNewInstance")
{
  my ($cmd, $ohm, $sid, $ins, $cfs, $pot) = @ARGV;
  print system("$ohm/bin/oidctl connect=$sid server=OIDLDAPD instance=$ins configset=$cfs flags=\"-p $pot\" start");
}
elsif ($cmd eq "startAll")
{
  print system ( "$ohm/opmn/bin/opmnctl startproc ias-component=OID" );
}
elsif ($cmd eq "stopAll")
{
  print system ( "$ohm/opmn/bin/opmnctl stopproc ias-component=OID" );
}
elsif ($cmd eq "restartAll")
{
  print system ( "$ohm/opmn/bin/opmnctl restartproc ias-component=OID" );
}
elsif ($cmd eq "stopCollection")
{
  my ($cmd, $ohm, $sid, $port, $pwd, @dnlist) = @ARGV;
  $dn = "@dnlist";
  # dnlist may contail white space

  $tempfile = "$ohm/sysman/admin/scripts/oidstopcollection.ldi";
  open (LDIF, ">$tempfile") || die "Cannot create file $tempfile\n";
  print LDIF "dn:\nchangetype:modify\nreplace: orclStatsPeriodicity\norclStatsPeriodicity:60\n";
  print LDIF "-\nreplace: orclStatsFlag\norclStatsFlag:0\n";
  close(LDIF);

  print system("$ohm/bin/ldapmodify -p $port -D \"$dn\" -w $pwd -f $tempfile");
}
elsif ($cmd eq "startCollection")
{
  my ($cmd, $ohm, $sid, $interval, $port, $pwd, @dnlist) = @ARGV;
  $dn = "@dnlist";
  # dnlist may contail white space
 
  $tempfile = "$ohm/sysman/admin/scripts/oidstartcollection.ldi";
  open (LDIF, ">$tempfile") || die "Cannot create file $tempfile\n";
  print LDIF "dn:\nchangetype:modify\nreplace: orclStatsPeriodicity\norclStatsPeriodicity:$interval\n";
  print LDIF "-\nreplace: orclStatsFlag\norclStatsFlag:1\n";
  close(LDIF);

  print system("$ohm/bin/ldapmodify -p $port -D \"$dn\" -w $pwd -f $tempfile");
}
#
# the following commands require executed value to be returned
# - cannot use system call, which will return exit code 0
#
elsif ($cmd eq "checkCredentials")
{  
  my ($cmd, $ohm, $sid, $port, $pwd, @dnlist) = @ARGV;
  # dnlist may contail white space
  $dn = "@dnlist";  
  $cmd = "$ohm/bin/ldapbind -D \"$dn\" -w $pwd -p $port";
  open (F, "$cmd |");
  while(<F>) {
    chomp; 
    # print either bind successful or error message
    print;
  }
}
elsif ($cmd eq "getCollectionStatus")  
{
  # param (4th args) is port
  $cmd = "$ohm/bin/ldapsearch -p $param -b \"\" -s base \"objectclass=*\" orclstatsflag";
  open (F, "$cmd |");
  while(<F>) {
    chomp; 
    if (/orclstatsflag=(.*)/) {
      print $1;
    }
  }
}
elsif ($cmd eq "getCollectionInterval")
{
  # param (4th args) is port
  $cmd = "$ohm/bin/ldapsearch -p $param -b \"\" -s base \"objectclass=*\" orclstatsperiodicity";
  open (F, "$cmd |");
  while(<F>) {
    chomp; 
    if (/orclstatsperiodicity=(.*)/) {
      print $1;
    }
  }
}
elsif ($cmd eq "getVersion")
{
  $version = getVersion();
  print "$version\n";
}
#
# the following commands used by emd metrics
#
elsif ($cmd eq "getResource")
{
  if (($^O =~ "Windows") || ($^O =~ "MSWin32")) {
    my ($mem, $cpu, $status) = getResourceNT();
  }
  else {
    my ($mem, $cpu) = getResource();
  }
  print "em_result=$mem|$cpu\n";

}
elsif ($cmd eq "getUserSessions")  
{
  $numUserSessions = getUserSessions();
  print ("em_result=$numUserSessions\n");
}
elsif ($cmd eq "getResponse")
{
  $status = 0;
  if (($^O =~ "Windows") || ($^O =~ "MSWin32")) {
    my ($cpu, $mem, $status) = getResourceNT();
  }
  else {
    $status = getResponse();
  }
  print ("em_result=$status\n");
}
elsif ($cmd eq "getResourceUsage") # realtime - not used
{
  my ($mem, $cpu) = getResource();
  $mem = $mem/1000;
  $ver = getVersion();
  $userSessions = getUserSessions();
  $status = getResponse();

  print "em_result=$mem|$cpu|$userSessions|$ver|$status\n";

}
else
{
  #print "unknown command: $cmd\n";
  # DO NOT print message
}

sub getResponse() {

  $os = `uname -s`;
  chomp ($os);
  if ($os eq "SunOS" || $os eq "Linux") {
    @PSINFO = `ps -e -o fname,ppid|grep oidldapd|awk '{print \$2}'`;
  }
  elsif ($os eq "OSF1" || $os eq "AIX") {
    @PSINFO = `ps -e -o comm,ppid|grep oidldapd|awk '{print \$2}'`;
  }
  elsif ($os eq "HP-UX") {
    $ENV{UNIX95} = "XPG4";
    @PSINFO = `ps -e -o comm,ppid|grep oidldapd|awk '{print \$2}'`;
  }
  else {
    #print "Platform - $os not supported\n";
  }

  $status = 0;
  foreach $parentPID (@PSINFO)
  {
    if (1 == $parentPID)
    {
      $status = 1;
      break;
    }
  }
  
  return $status;
}

sub getUserSessions() {

  $portIndex = -1;
  $numUserSessions = 0;
  chomp ($os = `uname -s`);

  @PSINFO = `ps -ef|grep oidldapd`;

  # Get all the port numbers of OID servers
  foreach $oidProcessInfo (@PSINFO)
  {
    @data = split(/\s+/, $oidProcessInfo);
    $i = 0;
    foreach $token (@data)
    {
      if ("-p" eq $token)
      {
        $ports[++$portIndex] = $data[$i + 1];
        break;
      }
      $i++;
    }
  }

  foreach $portNo (@ports)
  {
    if ($os eq "Linux") {
      $numUserSessions += `netstat -t tcp|grep ESTABLISHED|awk '{print \$4}'|grep "\:$portNo\"|wc -l`;
    }
    elsif ($os eq "HP-UX" || $os eq "OSF1" || $os eq "AIX") {
      $numUserSessions += `netstat -a | grep "^tcp" | grep ESTABLISHED | awk '{print \$4}'|grep "\.$portNo\"|wc -l`;
    }
    elsif ($os eq "SunOS") {
      $numUserSessions += `netstat -P tcp|grep ESTABLISHED|awk '{print \$1}'|grep "\.$portNo\"|wc -l`;
    }
  }

  return $numUserSessions;
}

sub getResource() {

  $os = `uname -s`;
  chomp ($os);

  if ($os eq "SunOS" || $os eq "Linux") {
    @PSINFO = `ps -e -o fname,ppid,pid,vsz,pmem,pcpu|grep oidldapd`;
  }
  elsif ($os eq "OSF1" || $os eq "AIX") {
    @PSINFO = `ps -e -o comm,ppid,pid,vsz,pmem,pcpu|grep oidldapd`;
  }
  elsif ($os eq "HP-UX") {
    $ENV{UNIX95} = "XPG4";
    @PSINFO = `ps -e -o comm,ppid,pid,vsz,sz,pcpu|grep oidldapd`;
  }
  else {
    #print "Platform - $os not supported\n";
  }

  $mem = 0;
  $cpu = 0;

  foreach $oidProcessInfo (@PSINFO)
  {
    @data = split(/\s+/, $oidProcessInfo);
    $cpu += $data[5];
    if (1 == $data[1])
    {
      $mem += $data[3];
    }
  }

  @resource = ($mem, $cpu);
  return @resource;
}

sub getVersion() {

  $cmd = "$ohm/bin/oidldapd -version 2>&1";
  open (F, "$cmd |");
  while(<F>) {
    #print;
    chomp; 
    if (/\D+ (.).(.).(.).(.).(.)/) {
      print "$1.$2.$3.$4.$5";
      # exit to avoid print out empty line
      exit;
    }
  }
}


# NT
sub getResourceNT() {
  #em_result=1572|oidldapd|N/A|3.47|0.00|36340|53600|0
  #           pid                    cpu  mem
  # we try to grep oidldapd
  @PSINFO = `nmupm TopProcs`;  
  
  $status = 0;
  $mem = 0;
  $cpu = 0;
  
  foreach $oidProcessInfo (@PSINFO) {
    $_ = $oidProcessInfo;
    if(/oidldapd/) {
      @data = split(/\|/, $oidProcessInfo);      
      $cpu += $data[4];
      $mem += $data[5];
      $status = 1;     
    }
  }
  @resource = ($mem, $cpu, $status);
  return @resource;
}