#!/usr/local/bin/perl
# 
# $Header: emdb/scripts/unix/DBConsoleLifeCycle.pm /st_emdbsa_11.2/3 2010/06/17 21:12:14 mappusam Exp $
#
# DBConsoleLifeCycle.pm
# 
# Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 
#
#    NAME
#      DBConsoleLifeCycle.pm - Handles start/stop of dbconsole.
#
#    DESCRIPTION
#      'start dbconsole' starts both the agent and dbconsole.
#      'stop dbconsole' stops both the agent and dbconsole.
#
#    NOTES
#
#    MODIFIED   (MM/DD/YY)
#    mappusam    06/16/10  - backout the
#                            rtakeish_rfi_backport_9453151_11.2.0.2.0_1 because
#                            the build break
#    rtakeish    04/22/10  - bug9453151, after rebooting a server machine,
#                            database control was unable to be started.
#    ashomish    02/04/09  - fix bug 7664495
#    sresrini    08/17/07  - bug 6339100
#    misun       05/21/07  - fix the bug 5737442: em behaves differently on
#                            various platforms of windows.
#    vivsharm    04/04/07  - If EM OC4J ADMIN password is defined use that
#    vivsharm    01/22/07  - XbranchMerge vivsharm_bug-5737442 from
#                            st_emdbsa_11.1beta4
#    vivsharm    01/18/07  - the code to stop OC4J was not getting called on NT
#    misun       08/16/06  - update DB version number
#    rsamaved    09/01/06  - dbconsole startup fix
#    balnaff     07/13/05  - leaving with the correct exit code 
#    balnaff     03/24/05  - fixing bug 3878900 
#    kduvvuri    10/06/04  - fix bug 3487814. Handle the exit code on windows. 
#    vnukal      09/23/04  - Obsolete exit file.
#    kduvvuri    07/20/04  - Remove start/stop agent from DBConsole mode.
#    kduvvuri    07/09/04  - EXITFILE for windows.
#    kduvvuri    06/17/04  - stopCEMDANDConsole moved to EMSAConsoleCommon.pm
#    kduvvuri    05/18/04  - created

package DBConsoleLifeCycle;
use EmctlCommon;
use EmCommonCmdDriver;
use DBConsole;
use EMSAConsoleCommon;
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;

   # if 2nd arg is  dbconsole, look for start and stop as the first args.
   #print "doIT of DBConsoleLifeCycle.pm: self is $classname, args from dbconsole.pm @$rargs\n";
   if ( $rargs->[1] eq "dbconsole"  )
   {
     #print "Processing <options> dbconsole \n";

     if ( $rargs->[0] eq "start" )
     {
        #print "Processing start dbconsole\n";
        startEM_SAConsole();
        $result = $EMCTL_DONE;
     }
     elsif ( $rargs->[0] eq "stop" )
     {
        #print "processing stop dbconsole\n";
        $rc = stopEM_SAConsole();
        $result =  $EMCTL_DONE;
        exit $rc;
     }
     elsif ( $rargs->[0] eq "istop" )
     {
        #print "Processing istop dbconsole\n";
        #Kondayya, return this value to emctl and cause it to exit with
        #this value.
        $rc = istopEM_SAConsole();
        $result =  $EMCTL_DONE;
     }
     else
     {
        $result =  $EMCTL_UNK_CMD;
     }
   }
   else
   {
     $result = $EMCTL_UNK_CMD;
   }

   return $result;
}


#
# Subroutine to check if the existing DB Console is running
#
sub checkEM_SAConsole()
{
   $alreadyRunningMsg =  " - An instance of Oracle Enterprise Manager 11g Database Control is already running. \n";
   $saCommObj = EMSAConsoleCommon->new();	
   $saCommObj->checkSAConsole($alreadyRunningMsg);
}


#
# start EM_SAConsole
# This starts up the EM_SAConsole [or the StandaloneConsole]
#
sub startEM_SAConsole()
{
    # Check wether the DB Console is running or not
    checkEM_SAConsole();

    # As the headless option is not supported on AIX
    # make sure the DISPLAY is set
    if ($OSNAME eq "aix")
    {
      my $jver = `$JAVA_HOME/bin/java -version 2>&1`;        
      if ( ($jver =~ m/1.4.1/) && ($ENV{DISPLAY} eq "") )
      {
        print "The DISPLAY environment variable is not set, please set it to a valid X-server.\n";
        exit 1;
      }
    }

    print "Starting Oracle Enterprise Manager 11g Database Control ...";

    if($IS_WINDOWS eq "TRUE")
    {
	   my $oracleUnqname = &DBConsole::getOracleUniqueName($ENV{ORACLE_HOME},$ENV{ORACLE_SID});
       my $serviceName = "OracleDBConsole".$oracleUnqname;
       my($rc) = 0xffff & system("$ENV{WINDIR}\\system32\\net.exe start $serviceName");
       $rc >>= 8 ; 
       exit($rc);
    }
    else
    {
       $CHILD_PROCESS = fork();
    }

    #
    # If IS_WINDOWS then we need to use win32 perl libraries to fork/exec
    #
    if( $CHILD_PROCESS == 0 )
    {
        # Need to close the STD handles
        close(STDIN);
        close(STDOUT);
        close(STDERR);

        # Assume the process group leadership...
        setpgrp(0, 0);

        # Exec the emwd process ...
        exec("$PERL_BIN/perl $EMDROOT/bin/emwd.pl dbconsole ".
             " $DB_NOHUPFILE ");
        exit 0; # In case it returns we do not fall back into the parent..
    }
    else
    {
      my ($consoleTries, $rc) = (90, 99);
     
      sleep 4; # sleep for 4 secs to give the emwd a chance ...

      $saStatObj = EMSAConsoleCommon->new();
      while( $consoleTries > 0 )
      { 
         print ".";

         $consoleObj = new DBConsole();
         $rc = $saStatObj->statusSAConsole_Internal($consoleObj);

         #print "ret value from SAConsole internal is $rc\n";
         # print appropriate started or failed error message.
         if($rc == $STATUS_PROCESS_OK)
         {
            $consoleTries = 0;
            last;
         }

         $consoleTries--;
         sleep 2;
      }

      #print "Start SA Console is exiting with The vlaue of rc is $rc\n";
      if( $rc == $STATUS_PROCESS_OK )
      {
         print " started. \n";
         EmctlCommon::footer();
         exit 0;
      }

      print " failed. \n";
      EmctlCommon::footer();
      exit 1;
    }
}


#
# stop EM_SAConsole
# This stops the EM_SAConsole [or the Standalone Console]
# 1) argument list
#
sub stopEM_SAConsole()
{
    local (*args) = @_;

    if($IS_WINDOWS eq "TRUE")
    {
	   my $oracleUnqname = &DBConsole::getOracleUniqueName($ENV{ORACLE_HOME},$ENV{ORACLE_SID});
       my $serviceName = "OracleDBConsole".$oracleUnqname;
       my($rc) = 0xffff & system("$ENV{WINDIR}\\system32\\net.exe stop $serviceName");
       $rc >>= 8 ;
#
#      	DO NOT call istopEM_SAConsole() here.  When the service is stopped, it invokes emctl istop dbconsole, 
#	which will trigger istopEM_SAConsole().  Invoking additional istopEM_SAConsole() here will make a second
#	shutdown attemp on DBControl, which will always fail.
#
#	$rc = istopEM_SAConsole();
       exit($rc);
    }

    return istopEM_SAConsole();
}

#
# This is the internal subroutine to stop the SAC
#
sub istopEM_SAConsole()
{
    local (*args) = @_;


    print "Stopping Oracle Enterprise Manager 11g Database Control ... \n";

    $OMS_RECV_DIR_SET = EmctlCommon::isOmsRecvDirSet();
    if ($OMS_RECV_DIR_SET) {
    my($pid) = 999999;

    if ( -e "$PID_FILE" )
    {
     open(PIDFILE, "<$PID_FILE");
     while(<PIDFILE>)
     {
       $pid = $_;
     }
     close(PIDFILE);
     chomp($pid);
     if( ($pid eq undef) or ($pid eq "") )
     {
       print "\n Cannot determine Oracle Enterprise Manager 11g Database Control process from ".$PID_FILE." \n";
       return 0;
     }
    }
    else
    {
       print "\n Cannot determine Oracle Enterprise Manager 11g Database Control process. ".$PID_FILE." does not exist. \n";
       return 0;
    }
 
    $tries = 30;
    
    my $dbConsole = new DBConsole();
	my($timeinmills) = time();
	my $defaultPwd = $timeinmills;
	my $oc4jadmin_pwd = "";
	$oc4jadmin_pwd = $defaultPwd;

    $dbConsole->Initialize($pid, time(), $DEBUG_ENABLED);
    $rc = $dbConsole->stop($oc4jadmin_pwd); 
    
    if($rc != 0)
    {
       # The failure may be due to invalid password...
       print " failed.\n";
       return $rc;
    }
    else
    {
       unlink ("$PID_FILE");
        }
    }

       # No diffrence between Vob and Install.
       # Keep the user interest busy ...
       print " ... ";
       
       # Now we stop the agent...
       my $emAgent = new EMAgent();
       $emAgent->Initialize($pid, time(), $DEBUG_ENABLED);
       $rc = $emAgent->stop($tries); 
       
       if( $rc < 2 )
       { 
          $rc = 0;
          print " Stopped. \n";
       }
       else
       {
          print " Failed. \n";
    }
    
    return $rc;
}

sub usage
{
  print "        emctl start | stop dbconsole\n";
}

sub DESTROY {
    my $self = shift;
}

1;