#Author:   Sudeep Saha
#Date Created: 10/29/2004
#contains OSD perl code
#sunagarw  08/14/2007 -- Generate traceback.
#sksaha    10/29/2004 -- created file
#sksaha    11/04/2004 -- Add package info

package sAgentUtils;

#
# sDebugCore
# sDebugCore is called when the monitor detects a core dump
# Parameter : CoreFile
#
sub sDebugCore
{
    $self = $_[0];
    $debugFile = $_[1];
    my $rc = 0;

    if($self->{initialized})
    {
	my($DBX) = "";

        if ( defined($ENV{EM_WINDBG_PATH}) && $ENV{EM_WINDBG_PATH} ne "" )
	{
            my($tempDbg) = $ENV{EM_WINDBG_PATH}."/cdb.exe";
            if( -e $tempDbg )
            {
		$DBX = $tempDbg;
            }
	}

        # If the Windbg path not defined or it does not exits in the path.
        # Assuming that the debugger(windbg) will be installed at this 
        # default location.
        if( $DBX eq "" )
        {
	    $DBX = "c:/Program Files/Debugging Tools for Windows/cdb.exe";
	}

        if( -e $DBX )
	{
	    my($traceBack) = $debugFile.".traceback";
	    my($dumpFile)  = $debugFile;
	    my ($EMHOME) = $self->{emHome};

           if ( ($^O eq "MSWin32") or ($^O eq "Windows_NT") )
	   {
	       my($agentbin) = "$ENV{EMDROOT}/bin";
	       my($sympath) = "c:/cache";
	       my($batfile)   = $EMHOME."/sysman/emd/"."genTraceback.bat";
	       my($downloadurl) = "http://msdl.microsoft.com/download/symbols";

               my($execmd)= ".echo;".
                            ".echo Exception Thread;".
                            ".echo ----------------;".
                            ".ecxr;".
                            ".echo;".
                            ".echo Threads;".
                            ".echo -------;".
                            "~*kb;".
                            "q" ;

	       open BATF, ">$batfile";
               printf BATF "\"$DBX\"".
                           " -n -i ".
                           "$agentbin".
                           " -y srv*$sympath*".
                           "$downloadurl".";"."$agentbin".
                           " -logo ".
                           "$traceBack".
                           " -z ".
                           "$dumpFile".
                           " -c ".
                           "\"$execmd\"";
               close BATF;
        
	       $rc = 0xffff & system("$batfile > NULL");
	       $rc >>= 8;
               if($rc != 0)
	       {
                   # error running core dump command
		   print "----- ".localtime()."::Error running $batfile : $! \n";
	       }
               else
               {
                   # Remove temporary command file only on success.
		   unlink("$batfile");
               }
	       return 0;
	   }
	}
        else
        {
	    print("----- ".localtime()."::INFO Skipping traceback file generation for diagnosis. EM_WINDBG_PATH not defined or debugger not available in default location. \n");
        }    
    } 
}

#
# Delete extra cores.
#
sub deleteExtraAgentCores_Win
{
  my ($agentHome) = @_[0];
  my ($coreFileDir) = $agentHome."/sysman/emd/";

  # multiple of 2 to keep together hang dump files(2/incident)
  # Double the number of files to count for the tracebacks now.
  my ($maxCores) = 4*2; 

  if (defined($ENV{EMAGENT_MAX_CORES}))
  {
      $maxCores = $ENV{EMAGENT_MAX_CORES};
  }

  opendir(DIR,$coreFileDir) or return;
  #filtering files starting with core
  @coreFileList = grep { /^core.*/ && -f "$coreFileDir/$_"  } readdir(DIR); 
  closedir(DIR);

  foreach $coreFile (@coreFileList) {
      $coreFile = $coreFileDir.$coreFile;
  }
  # Sort the list according to modified timestamp

  @sortedCoreFileList = sort by_modtime @coreFileList;

  $coreFileCount = @sortedCoreFileList;

  if (($coreFileCount) <= $maxCores) { return; }

  print(localtime()." Deleting extra core files($coreFileCount>$maxCores)\n");

  do
  {
      $coreFile = shift(@sortedCoreFileList);
      print(localtime()." Deleting corefile $coreFile\n");
      unlink($coreFile);
  }while(scalar(@sortedCoreFileList) > ($maxCores));
}

sub by_modtime {
    # 9th elem of stat array is the modtime of the file
    my $a_modtime = (stat($a))[9];
    my $b_modtime = (stat($b))[9];

    if ($a_modtime < $b_modtime) {
	return -1;
    } elsif($a_modtime == $b_modtime) {
	return 0;
    } elsif($a_modtime > $b_modtime) {
	return 1;
    }
}
1;
