# $Header: adr_common.pl 22-may-2007.17:42:10 jsoule Exp $
#
# adr_common.pl
#
# Copyright (c) 2002, 2007, Oracle. All rights reserved.  
#
#    NAME
#      adr_common.pl - <one-line expansion of the name>
#
#    DESCRIPTION
#      adr_common.pl contains common routines for utility applications, such
#      dbclone, rman, and data utilities.
#
#    NOTES
#      <other useful comments, qualifications, etc.>
#
#    MODIFIED   (MM/DD/YY) 
#    jsoule      05/22/07 - relocate tracing support
#    jsoule      03/15/07 - created from db_common.pl
#

require "emd_common.pl";

use strict;
use File::Basename;
use File::Copy;
use File::Temp qw/ tempfile tempdir /;
use vars qw($OS $NT $S $TEMP $CP $MV $PS $DF $Registry);

#### GLOBAL Platform-specific flags for all EM OSs ####
if($^O =~ /solaris/i){
  $OS = "SOL2";
	$NT = 0;
  $S = '/';
  $TEMP = "/tmp";
	$CP = "/bin/cp";
	$MV = "/bin/mv";
	$PS = "/bin/ps";
  $DF = "/bin/df -k"
}
elsif($^O =~ /MSWin32/i){
  $OS = "NT";
	$NT = 1;
  eval 'use Win32::TieRegistry';
  $S = '\\';
	if(exists($ENV{TMP})){
		$TEMP = $ENV{TMP};
	}
	elsif(exists($ENV{TEMP})){
		$TEMP = $ENV{TEMP};
	}
	else{
		$TEMP = $ENV{SYSTEMDRIVE} . "\\temp"; # Bug# 5642432
	}
	## The %SystemDrive% variable seems to come back in TEMP;
	##  substitute in the value
	$TEMP =~ s/%SystemDrive%/$ENV{SYSTEMDRIVE}/i;
	$CP = "copy";
	$MV = "rename";
	$PS = "ps";
}
elsif($^O =~ /aix/i){
  $NT = 0;
  $S = '/';
  $TEMP = "/tmp";
	$CP = "/bin/cp";
	$MV = "/bin/mv";
	$PS = "/bin/ps";
  $DF = "/bin/df -Pk"
}
elsif($^O =~ /linux/i){
  $OS = "LINUX";
  $NT = 0;
  $S = '/';
  $TEMP = "/tmp";
	$CP = "/bin/cp";
	$MV = "/bin/mv";
	$PS = "/bin/ps";
  $DF = "/bin/df -k"
}
elsif($^O =~ /hpux/i){
  $NT = 0;
  $S = '/';
  $TEMP = "/tmp";
	$CP = "/bin/cp";
	$MV = "/bin/mv";
	$PS = "/bin/ps";
  $DF = "/usr/bin/df -Pk"
}
## Operating system unknown (probably Unix)
else{
  $OS = "";
	$NT = 0;
  $S = '/';
  $TEMP = "/tmp";
	$CP = "/bin/cp";
	$MV = "/bin/mv";
	$PS = "/bin/ps";
  $DF = "/bin/df -k"
}

sub isWinOS
{
  my $isWin = "NOK";
  if($^O =~ /MSWin/i)
   {
     $isWin = "OK";
   }
   return $isWin;
}

# --------- OS platform-specific (END) -----------------------------------

our $tracefile;

my $ADRCOMMON_PERL_TRACE_LEVEL_DEBUG = 1; # analogous to EMAGENT debug tracing

sub TRACE {
    TRACE0($ADRCOMMON_PERL_TRACE_LEVEL_DEBUG, @_);
}

sub TRACE0 {
    my ($level, @args) = @_;
    my $trace_level = $ENV{EMAGENT_PERL_TRACE_LEVEL};

    if ($trace_level ne "" && $level ne "" && $trace_level <= $level) {
        open(LOG, ">>$tracefile");
        print LOG localtime(time) . "  - ";
#       printf LOG "%.6f ", Time::HiRes::time();
        print LOG @args;
        close(LOG);
    }
}

# Create a temporary file
# create_temp_file()
# return fileHandle and fileName
sub create_temp_file
{
  my ($suffix) = @_;
  my $dir = tempdir(CLEANUP => 1);
  my $temp_fh;
  my $temp_filename;
  
  if (defined($suffix))
  {
    ($temp_fh, $temp_filename) = tempfile(DIR => $dir, SUFFIX => $suffix );
  }
  else
  {
    ($temp_fh, $temp_filename) = tempfile(DIR => $dir);
  }
  
  TRACE("adr_common.create_temp_file(): Temp file name: $temp_filename\n");

  #For NT only
  &tempLocFallback();
  
  return ($temp_fh, $temp_filename);
}

# Remove a file for a given file name
# removeFile(fileName)
sub removeFile
{
  my ($fileName) = @_;

  TRACE("adr_common.removeFile(): To remove file $fileName\n");
  
  unlink $fileName
    or warn "Could not remove '$fileName': $!";
}

# Check if a specified directory exists
# Return OK if the directory exists, otherwise, return NOK.
# dirExists(dirName)
sub dirExists
{
  my ($dirName) = @_;
  if (! -e "$dirName")
  {
    TRACE("adr_common.dirExists(): Directory $dirName does not exist\n");
    return "NOK";
  }
  elsif (! -d "$dirName")
  {
    TRACE("adr_common.dirExists(): $dirName is not a directory\n");
    return "NOK";
  }
  
  TRACE("adr_common.dirExists(): Directory $dirName exists\n");
  
  return "OK";
}

# Create a specified directory.
# Return OK if succeed, otherwise, return NOK.
# OK is returned if the specified directory already exists.
# mkDir(dirName)
sub mkDir
{
  my ($dirName) = @_;
  TRACE("adr_common.mkDir(): Create directory $dirName\n");
  my $dirExist = &dirExists($dirName);
  if($dirExist eq "OK")
  {
    TRACE("adr_common.mkDir(): Directory $dirName already exists\n");
    return "OK";
  }

  my (@create);
  push(@create, $dirName);

  #create parent directories if necessary
  my ($parent) = dirname($dirName);
  while(! -e "$parent")
  {
    TRACE("adr_common.mkDir(): Need to create $parent\n");
    push(@create, $parent);
    $parent = dirname($parent);
  }

  while ($dirName = pop(@create))
  {
    TRACE("adr_common.mkDir(): Creating $dirName\n");
    if (!mkdir($dirName, 0755)){
      EMD_PERL_ERROR("adr_common.mkDir(): mkdir $dirName failed");
      ## Actually want this error to come out in the job output
      print "mkdir ${dirName}: $!\n";
      return "NOK";
    }
  }
  
  return "OK";
}

#This is NT specific. Sometimes, $TEMP does not work, this 
#method provides some fallback.
sub tempLocFallback
{
  if (!$NT)
  {
    return;
  }

  my $fallback = "N";
  my $filename = "$TEMP\\"."test_temp_location.$$";
  TRACE("adr_common.tempLocFallback(): Test filename: $filename\n");

  my (@res) = `echo "This is a test!" >$filename 2>&1`;
    
  #Test opening the temp file
  open(OUT_PUT, "$filename") || ($fallback = "Y");

  if ($fallback eq "N")
  {
    close OUT_PUT;
    &removeFile($filename);
    TRACE("adr_common.tempLocFallback(): Tested TEMP location: $TEMP\n");
    return;
  }

  ${TEMP} = $ENV{SYSTEMDRIVE} . "\\TEMP"; #Bug# 5642432
  &mkDir(${TEMP}); #Bug# 5642432

  TRACE("adr_common.tempLocFallback(): TEMP location fallback to: $TEMP\n");
}

1;
