#Author: Kondayya Duvvuri
#Date Created : 05/13/2004
#Handles all the emctl options pertaining to oms.

#schoudha 06/12/20 -- Bug-5726004-Change banner for emctl
#shianand 05/08/17 -- Bug 4911857. Moving SSO registration to SecureOMSCmds.pm
#neearora 05/08/17 -- Bug 4241177. Change implementation of getVersion 
#                     to read version from file. Added command
#                     emctl getversion oms    
#kduvvuri 04/07/28 -- add getVersion.
#shianand 05/05/23 -- fix bug 4216045.
#shianand 05/06/24 -- fix bug 4287567 Cutting over dcmctl to opmnctl in "emctl status oms".
#shianand 05/03/31 -- Refactoring Secure Commands.
#shianand 11/14/05  - fix secure status oms to status oms -secure [-omsurl <>]

package EMomsCmds;
use EmCommonCmdDriver;
use EmctlCommon;
use SecureOMSCmds;

$EM_OC4J_HOME=getOC4JHome($CONSOLE_CFG);
$EMHOME = getEMHome($CONSOLE_CFG);

my $STATUS_OMS_UP                  = 0;
my $STATUS_OMS_INIT                = 1;
my $STATUS_OMS_REP_VER_ERR         = 2;
my $STATUS_OMS_REP_CON_ERR         = 3;
my $STATUS_OMS_REP_MODE_ERR        = 4;
my $STATUS_OMS_EM_KEY_ERROR        = 5;
my $STATUS_OMS_DOWN                = 8;
my $STATUS_OMS_UNK_ERR             = 9;
my $STATUS_OPMN_DOWN               = 10;
my $STATUS_REPOS_PATCH_ERR         = 11;
my $STATUS_REPOS_UPGRADE_ERR       = 12;
my $STATUS_OMS_PATCH_ERR           = 13;
my $STATUS_OMS_UPGRADE_ERR         = 14;

sub new {
  my $classname = shift;
  my $self = { };
  bless ( $self, $classname);
  return $self;
}

sub doIT {
   my $classname = shift;
   my $rargs = shift;
   my $result = $EMCTL_UNK_CMD;

   $argCount = @$rargs; 
   #print "doIT of EMomsCmds: self is $classname, args passed @$rargs\n";
   if ( $rargs->[1] eq "oms" )
   {
     #print "Processing <options> oms \n";

     if ( $rargs->[0] eq "start" )
     {
        #print "Processing start oms\n";
        startOMS($rargs->[2]);
        $result = $EMCTL_DONE;
     }
     elsif ( $rargs->[0] eq "stop" )
     {
        #print "Processing stop oms\n";
        stopOMS();
        $result = $EMCTL_DONE;
     }
     elsif ( $rargs->[0] eq "status" )
     {
        if ($rargs->[2] eq "-secure")
        {
          my $exitCode = &SecureOMSCmds::secureStatus($rargs->[1], $rargs->[4]);
          my @retArray = ($EMCTL_DONE,$exitCode);
          return \@retArray;
        }
        #print "Processing status oms\n";
        statusOMS();
        $result =  $EMCTL_DONE;
     }
     elsif ( $rargs->[0] eq "config")
     {
       $result = configOMS($rargs);
     }
     elsif ( $rargs->[0] eq "setpasswd")
     {
       setReposPasswd();
       $result = $EMCTL_DONE;
     }
     elsif ( lc($rargs->[0]) eq "getversion")
     {
       getVersion();
       $result = $EMCTL_DONE;
     }
   }

   return $result;
}

#
# startOMS
#
sub startOMS()
{
  my ($sleepTime) = @_;
  
  my $output ;
  system("$ORACLE_HOME/opmn/bin/opmnctl start 2>&1");
  $rc = 0xffff & $?;
  $rc >>= 8;
  my $errCode ;

  if($rc != 0 && $rc != 1)
  {
    # opmnctl returns '2' in case it times out on the ping to opmn (see bug 
    # 4176021). We try anyway to see if opmn came up (shouldn't hurt us).

    # Default sleep time to 10s
    unless(defined($sleepTime)) {$sleepTime = 10};

    # Sleep for some time (give OPMN some time to start up...)
    sleep($sleepTime);
    $output .= "\n[_EMCTL_]: Received $rc from opmnctl start.\n" .
               "Running opmnctl status...\n";
    $output .= `$ORACLE_HOME/opmn/bin/opmnctl status 2>&1`;
    $rc = 0xffff & $?;
    $rc >>= 8;

    if ($rc != 0)
    {
      print("Error code returend by opmnctl: '$rc'\n");
      print("Output returned by opmnctl: '$output'\n");
      die("Could not start opmn.\n");
    }
  }

  @states = `$ORACLE_HOME/dcm/bin/dcmctl getState -v -d`;

  $status = statusOHS( \@states );

  if( $status ne "Up" )
  {
     print "Starting HTTP Server ...\n";
     $rc = 0xffff & system("$ORACLE_HOME/opmn/bin/opmnctl startproc type=ohs >$devNull 2>&1");
     $rc >>= 8;
  }

  $errCode = istatusOMS( );
  if( $errCode eq $STATUS_OMS_UP )
  {
     print "Oracle Management Server Already Started.\n";
  }
  else
  {
     print "Starting Oracle Management Server ...\n";
     $rc = 0xffff & system("$ORACLE_HOME/opmn/bin/opmnctl startproc type=oc4j process-type=OC4J_EM >$devNull 2>&1");
     $rc >>= 8;

     print "Checking Oracle Management Server Status ...\n";
     statusOMS();
  }
}

#
# stopOMS
#
sub stopOMS()
{
    $rc = 0xffff & system("$ORACLE_HOME/opmn/bin/opmnctl stopproc type=oc4j process-type=OC4J_EM >$devNull 2>&1");
    $rc >>= 8;

    statusOMS();
}


#
# statusOMS
#
sub statusOMS()
{
  local @states    = @_;
  my $count        = scalar(@states);
  my $printMessage = "TRUE";
  my $errMessage   = "";
  my $errCode = istatusOMS();
  my $msg    = "Oracle Management Server is";
  my $errMsg = "Oracle Management Server is not functioning because of the following reason:";

  if ( $count <= 0)
  {
    $printMessage = "TRUE";
  }
  else
  {
    $printMessage = "FALSE";
  }

  if ($errCode eq $STATUS_OMS_UP)
  {
      print "$msg Up.\n" unless ($printMessage eq "FALSE");
      exit 0;
  }
  elsif ($errCode eq $STATUS_OMS_INIT)
  {
      print "$msg intializing.\nContext not fully initialized yet.\n" unless ($printMessage eq "FALSE");
      exit 0;
  }
  elsif ($errCode eq $STATUS_OMS_REP_VER_ERR)
  {
    $errMessage = "$errMsg\nOracle Management Server version is not compatible with repository version.\n";
  }
  elsif ($errCode eq $STATUS_OMS_UPGRADE_ERR)
  {
    $errMessage = "$errMsg\nOracle Management Server version is not compatible with repository version. Oms needs to be Upgraded.\n";
  }
  elsif ($errCode eq $STATUS_REPOS_UPGRADE_ERR)
  {
    $errMessage = "$errMsg\nOracle Management Server version is not compatible with repository version. Repository needs to be Upgraded.\n";
  }
  elsif ($errCode eq $STATUS_OMS_PATCH_ERR)
  {
    $errMessage = "$errMsg\nOracle Management Server version is not compatible with repository version. Oms needs to be Patched.\n";
  }
  elsif ($errCode eq $STATUS_REPOS_PATCH_ERR)
  {
    $errMessage = "$errMsg\nOracle Management Server version is not compatible with repository version. Repository needs to be Patched.\n";
  }
  elsif ($errCode eq $STATUS_OMS_REP_CON_ERR)
  {
    $errMessage = "$errMsg\nConnection to the repository failed. ".
                  "Verify that the repository connection information provided is correct.\n";
  }
  elsif ($errCode eq $STATUS_OMS_REP_MODE_ERR)
  {
    $errMessage = "$errMsg\nOracle Management Server mode is not compatible with the repository mode.\n";
  }
  elsif ($errCode eq $STATUS_OMS_EM_KEY_ERROR)
  {
    $errMessage = "$errMsg\nThe Em Key is not configured properly. Run \"emctl status emkey\" for more details.\n";
  }
  elsif ($errCode eq $STATUS_OMS_DOWN)
  {
    $errMessage = "$msg Down.\n";
  }
  elsif ($errCode eq $STATUS_OPMN_DOWN)
  {
    $errMessage = "$msg Down.\nOPMN may not be up.\n";
  }
  elsif ($errCode eq $STATUS_OMS_UNK_ERR)
  {
    $errMessage = "$errMsg\nUnexpected error occurred. Check error and log files.\n";
  }

  print "$errMessage" unless ($printMessage eq "FALSE");
  exit $errCode;
}



sub istatusOMS()
{
  #local (*args)   = @_;   #fix so that it can be called directly in SecureOMS.pm 
  #local (*states) = @_;
  local @states    = @_;
  my $count = scalar(@states);
  my $printMessage = "TRUE";

#
# Executing $ORACLE_HOME/opmn/bin/opmnctl status returns the following information.
#
# Processes in Instance: INSTANCE_NAME
# -------------------+--------------------+---------+---------
# ias-component      | process-type       |     pid | status  
# -------------------+--------------------+---------+---------
# HTTP_Server        | HTTP_Server        |    8772 | Alive   
# OC4J               | home               |    8773 | Alive   
# OC4J               | OC4J_EM            |    8808 | Alive   
# dcm-daemon         | dcm-daemon         |    3930 | Alive   
# LogLoader          | logloaderd         |     N/A | Down

   if ( $count <= 0)
   {
     @states = `$ORACLE_HOME/opmn/bin/opmnctl status 2>&1`;
     $rc = 0xffff & $?;
     $rc >>= 8;
     if ($rc != 0)
     {
       return $STATUS_OPMN_DOWN;
     }
     $count = scalar(@states);
     $printMessage = "TRUE";
   }
   else
   {
     $printMessage = "FALSE";
   }
 
   my $errCode   = $STATUS_OMS_UP;
   my $omsStatus = "Alive";
   my $i=0;
   while( $i < $count)
   {
     $states[$i] =~ s/\|//gi;
     chomp($states[$i]);
     @comp = split /\s+/, $states[$i];
     chomp($comp[1]);
     if($comp[1] eq "OC4J_EM")
     {
        $omsStatus = $comp[3];
        chomp($omsStatus);
        last;
     }
     $i = $i + 1;
   }
  if ($omsStatus ne "Alive")
  {
      if ($omsStatus eq "Init")
      {
        $omsStatus = "initializing";
        $errCode = $STATUS_OMS_INIT;
      }
      elsif ($omsStatus eq "Down" or $omsStatus eq "NONE" or $omsStatus eq "Stopped")
      {
        $errCode = $STATUS_OMS_DOWN;
      }
      else
      {
        $errCode = $STATUS_OMS_UNK_ERR;
      }
      return $errCode;
  }

  # Here, the OC4j_EM process is up but that is not enough to conclude that
  # OMS is up. We need to hit the site to verify that the OMS is fully
  # up. If there is a problem (context not initialized correctly, connection
  # to the database failed, unsupported repository database version) the 
  # console filter ContextInitFilter will generate a 503 Service Unavailable 
  # and an error message in the response.
  
  # Find the OMS Port in emoms.properties
  my $in_file="$ORACLE_HOME/sysman/config/emoms.properties";
  open(INFILE, "$in_file") || die "Could not open $in_file\n";
    
  #loop through file
  my $omsPort = -1;
  while(<INFILE>) 
  {
    if (/oracle.sysman.emSDK.svlt.ConsoleServerPort=(.*)/)
    {
      $omsPort = $1;
      last;
    }
  }
  close(INFILE);

  die "Could not find Console Server Port in $in_file\n" if ($omsPort == -1);

  my $OMS_URL="http://127.0.0.1:$omsPort/em/genwallet";  
  my $url = URI->new($OMS_URL);
  my $ua = LWP::UserAgent->new;
  $ua->agent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
  my $resp = $ua->get($url->as_string());

  my $errMessage = "";

  if ($resp->is_error())
  {
      $omsStatus = "not functioning because of the following reason:";
      my $omsCode = $resp->headers->header('STATUS-OMS');
      if ($omsCode eq "1")
      {
        $errCode = $STATUS_OMS_INIT;
      }
      elsif ($omsCode eq "2")
      {
        $errCode = $STATUS_OMS_REP_VER_ERR;
      }
      elsif ($omsCode eq "3")
      {
        $errCode = $STATUS_OMS_REP_CON_ERR;
      }
      elsif ($omsCode eq "4")
      {
        $errCode = $STATUS_OMS_REP_MODE_ERR;
      }
      elsif ($omsCode eq "5")
      {
        $errCode = $STATUS_OMS_EM_KEY_ERROR;
      }
      elsif ($omsCode eq $STATUS_OMS_UPGRADE_ERR)
     {
        $errCode = $STATUS_OMS_UPGRADE_ERR;
      }
      elsif ($omsCode eq $STATUS_REPOS_UPGRADE_ERR)
      {
        $errCode = $STATUS_REPOS_UPGRADE_ERR;
      }
      elsif ($omsCode eq $STATUS_OMS_PATCH_ERR)
      {
        $errCode = $STATUS_OMS_PATCH_ERR;
      }
      elsif ($omsCode eq $STATUS_REPOS_PATCH_ERR)
      {
        $errCode = $STATUS_REPOS_PATCH_ERR;
      }
      else
      {
        $errCode = $STATUS_OMS_UNK_ERR;
      }
  }
  return $errCode;
}


#
# statusOHS Returns the status of HTTP Server
#
sub statusOHS()
{
  local (*args) = @_;
  my $count = scalar(@args);

  my $i=0;
  while( $i < $count)
  {
     @comp = split /\s+/, $args[$i];
     if( ($comp[1] eq "HTTP") or ($comp[3] eq "ohs"))
     {
        return $comp[4];
     }
     $i = $i + 1;
  }
}


#
# Config OMS takes
# 1) Array of arguments
#            emctl config oms sso ...
#
sub configOMS()
{
  local (*args) = @_;

  shift(@args);                  # -- shift out config...
  shift(@args);                  # -- shift out oms ...

  if ($args[0] eq "sso") #emctl config oms sso
  {
      shift(@args);                  # -- shift out sso ...
      my $exitCode = sso( \@args );
      my @retArray = ($EMCTL_DONE,$exitCode);
      return \@retArray;
  }
  elsif($args[0] eq "loader") # emctl config oms loader
  {
     my $result = $EMCTL_UNK_CMD;
     shift(@args);                  # -- shift out loader
     $result = configLoader(\@args);
     return($result);
  }

  return($EMCTL_UNK_CMD);
  
}

#
# Sets up the SSO
#
sub sso()
{
  local (*args) = @_;
  my $ret = &SecureOMSCmds::sso (\@args);
  return $ret;
}

sub configLoader()
{
  my $sharedFlag, $loaderDir;
  if(@args lt 4)
  {
    return($EMCTL_BAD_USAGE);
  }
  if($args[0] eq "-shared")
  {
     shift(@args);                  # -- shift out -shared
     $sharedFlag = $args[0];
     shift(@args);
   }
  else 
  {
     return($EMCTL_BAD_USAGE);
   }

  if($args[0] eq "-dir")
  {
      shift(@args);                  # -- shift out -dir
      $loaderDir = $args[0];
      shift(@args);
   }
  else 
  {
     return($EMCTL_BAD_USAGE);
   }

  if ( not(-e $loaderDir))
  {
    print "Error $loaderDir does not exist\n";
    exit(1);
   }
  elsif (not(-w $loaderDir))
  {
     print "Error $loaderDir is not writable\n";
     exit(1);
   }

  if($sharedFlag eq "yes")
  {
    $sharedFlag = "sharedFilesystem";
  }
  elsif($sharedFlag eq "no")
  {
    $sharedFlag = "nonSharedFilesystem";
  }
  else
  {
     return($EMCTL_BAD_USAGE);
   }

  my $prop_file="$ORACLE_HOME/sysman/config/emoms.properties";
  my $haSet = "no";
  my $loaderDirSet = "no";

  open (IN, "$prop_file") || die $!;
  open (OUT, ">$prop_file".".new") || die $!;

  while ($_ = <IN> ) 
  {

    if ($_ =~ /(^([ ]*[	]*)*)em.loader.coordinationMethod=(.*)/)  
    {
      $_ =~ s/em.loader.coordinationMethod=(.*)/em.loader.coordinationMethod=$sharedFlag/;
      $haSet = "yes";
    }
    elsif ($_ =~ /(^([ ]*[	]*)*)ReceiveDir=(.*)/) 
    {
      $_ =~ s/ReceiveDir=(.*)/ReceiveDir=$loaderDir/;
      $loaderDirSet = "yes";
    }

    print OUT "$_";

  }

  if ($haSet eq "no")
  {
    print OUT "em.loader.coordinationMethod=$sharedFlag\n";
  }

  if ($loaderDirSet eq "no")
  {
    print OUT "ReceiveDir=$loaderDir\n";
  }

  close (OUT);
  close (IN);

  rename("$prop_file".".new","$prop_file") || die $!;
  return $EMCTL_DONE;
}

sub usage
{
    print "       emctl start| stop| setpasswd| getversion oms\n";
    print "       emctl status oms\n";
    print "       emctl status oms -secure [-omsurl <http://<oms-hostname>:<oms-unsecure-port>/em/*>]\n";
    print "       emctl config oms sso -host ssoHost -port ssoPort -sid ssoSid -pass ssoPassword -das dasURL -u user\n";
    print "       emctl config oms loader -shared <yes|no> -dir <loader dir>\n";
    print "       emctl config| status emkey <options>\n";
	print "\n";
}

sub getVersion
{
  my $verStr = "       Enterprise Manager 10g OMS Version 10.2.0.4.2\n"; 

  my $inFile = "$ORACLE_HOME/j2ee/OC4J_EM/applications/em/em/WEB-INF/config/emVersion.xml";
  if(-e $inFile) 
  {
    $CP = "$ORACLE_HOME/oc4j/jdbc/lib/ojdbc5dms.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/ojdbc14dms.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-net-ee.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-utility.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-collation.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-net.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-internal.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-servlet.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-lcsd.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-tools.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-mapping.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n-translation.jar$cpSep$ORACLE_HOME/oc4j/jdbc/lib/orai18n.jar$cpSep$ORACLE_HOME/oc4j/lib/dms.jar$cpSep$ORACLE_HOME/jdbc/lib/ojdbc14.jar$cpSep$ORACLE_HOME/jdbc/lib/nls_charset12.jar$cpSep$ORACLE_HOME/sysman/jlib/emagentSDK.jar$cpSep$ORACLE_HOME/sysman/jlib/emCORE.jar$cpSep$ORACLE_HOME/sysman/jlib/log4j-core.jar$cpSep$ORACLE_HOME/sysman/jlib/emCORE.jar$cpSep$ORACLE_HOME/lib/xmlparserv2.jar";

    $javaStr = "$JAVA_HOME/bin/java ".
               "-cp $CP ".
               "-DEMHOME=$EMHOME ".
               "-DORACLE_HOME=$ORACLE_HOME ".
               "oracle.sysman.emdrep.util.EMVersion $inFile";

    my @result = `$javaStr`;
    my $prodVer;
    my $coreVer;
 
    if (@result)
    {
      my $count = scalar(@result);
      my $i=0;
      while( $i < $count)
      {
        @comp = split /\s+/, $result[$i];
        if( lc($comp[0]) eq "productversion")
        {
          $prodVer = $comp[1];
        }
        elsif( lc($comp[0]) eq "coreversion")
        {
          $coreVer = $comp[1];
        }

        $i = $i + 1;
      }
      if($prodVer && $coreVer)
      {
        $verStr = "       Enterprise Manager ". $prodVer . " OMS Version ". $coreVer . "\n";
      }
    }
  }
  print $verStr; 
}

sub DESTROY {
    my $self = shift;
}

1;