#!/bin/sh

######################################################################
# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 
#
#  phnguyen  5/17/04   Create and support
#                          -jdk, -jre, -oh
#  shgangul  6/21/04   Check for OPATCH_DEBUG env variable
#  shgangul  7/12/04   opatch can be invoked from any directory
#  shgangul  7/15/04   use jdk to invoke opatch, otherwise use jre
#  shgangul  7/16/04   Display the Java call for debug
#  phnguyen  7/19/04   add "./" to class path
#  phnguyen  7/31/04   more jre parsing, error if can't find java
#  shgangul  8/05/04   change opatch to oracle.opatch package
#  shgangul  8/27/04   sync up with opatch.bat to support OPATCH_PLATFORM_ID
#  phnguyen  8/04/04   Support OPATCH_PLATFORM_ID=integer
#  shgangul  8/27/04   add fallback schemes for jre/jdk
#  phnguyen  8/30/04   Print "OPatch Succeeded" if OK
#  shgangul  9/01/04   Further changes for jre/jdk priorities
#  shgangul  9/07/04   java not present in jdk/jre option, error out
#  shgangul  12/15/04  Supply PATH variable to java
#  shgangul  02/02/05  Minor bug in parsing -jdk option
#  phnguyen  02/01/05  Introduce OPATCH_NO_FUSER to bypass fuser check
#  vsriram   02/28/05  Print "OPatch Succeeded" if exit code is b/w 171 and 200
#  shgangul  03/15/05  Pass in properties to OPatch
#  phnguyen  05/14/05  add opatchprereq.jar and opatchutil.jar to class path 
#  shgangul  07/18/05  Do not pass PATH env var to OPatch JVM
#  vsriram   12/06/05  Change the permissions of .patch_storage and set umask
#  vsriram   12/13/05  Use -d inside if condition, as -e doesnot work on Solaris.
#  vsriram   01/24/06  Remove umask setting and don't change the perm of 
#                      .patch_storage contents
#  vsriram   05/10/06  Return 0 as exit code, even for warnings.
#  vganesan  02/27/08  Pass $BASE (running directory of 'opatch') as a property
#                      to java invocation. This is needed to locate ocm.zip in 
#                      OPatch.
#  vganesan  03/04/08  Add 'emocmutl.jar' to the classpath
#  vganesan  08/19/08  Check osInfo API/class in emocmutl.jar for IBM based
#                      platforms if 'ocm.zip' is bundled
#  phnguyen  05/20/08  Bug 7114214
#  phnguyen  05/20/08  Bug bmmbhmb 
#  phnguyen  05/16/08  Bug 7038091
#  vganesan  05/16/08  Refix Bug 7038091 with inputs from John Sutton
#  phnguyen  05/16/08  Bug bkbtkcm
#  vganesan  05/16/08  Refix Bug bkbtkcm with inputs from John Sutton
####################################################################
BASE=`dirname $0`;
PWD=`pwd`;

autopatch=0;
autohelp=0;

argCount=$#


if [ "$1" = "auto" ]; then
  autopatch=1
fi

if [ $autopatch = 1 ]; then
  if [ $argCount -gt 1 ]; then 
    if [ $2 = "-h" ]; then
      autohelp=1
    elif [ $2 = "-help" ]; then
      autohelp=1
    fi
  fi
fi

if [ $autohelp = 1 ]; then
  $BASE/crs/auto_patch.pl -h
  exit 
fi

if [ $autopatch = 1 ]; then
  # it must be 
  # 'opatch auto'
  # 'opatch auto <patch loc>'
  # 'opatch auto -rollback'
  # 'opatch auto -rollback <patch loc>' 

  if [ $argCount -eq 1 ]; then
     # this must be just 'opatch auto'
     givenLoc=$PWD
     patchdir=`dirname $givenLoc`
     id=`basename $givenLoc`

     # Check to make sure <patch_loc>/custom/server exist
     if [ ! -d $givenLoc/custom/server ]; then
         echo "$givenLoc is not a valid CRS bundle patch location."
         $BASE/crs/auto_patch.pl -h
         exit -1;         
     fi

     shift
     # echo $BASE/crs/auto_patch.pl -patchdir $patchdir -patchn $id
     $BASE/crs/auto_patch.pl -patchdir $patchdir -patchn $id
     exit

  elif [ $argCount -gt 1 ] && [ $2 != "-rollback" ]; then
     # either 'opatch auto [other-args]' or 'opatch auto <patch_loc> [other-args]'

     givenLoc=$2
     if [ -d $givenLoc ]; then
        # must be 'opatch auto <patch_loc> other-args'
        # echo "opatch auto <patch_loc> [other-args]"
        givenLoc=$2
        patchdir=`dirname $givenLoc`
        id=`basename $givenLoc`       

         # Check to make sure <patch_loc>/custom/server exist
        if [ ! -d $givenLoc/custom/server ]; then
           echo "$givenLoc is not a valid CRS bundle patch location."
           $BASE/crs/auto_patch.pl -h
           exit -1;
        fi

        shift
        shift
        # echo $BASE/crs/auto_patch.pl -patchdir $patchdir -patchn $id $@
        $BASE/crs/auto_patch.pl -patchdir $patchdir -patchn $id $@
        exit
     else
        # must be 'opatch auto [other-args]' or bad patch loc
        # just let auto_patch decide, assume it is 'opatch auto [other-args]
        # echo "opatch auto [other-args]"
        givenLoc=$PWD
        patchdir=`dirname $givenLoc`
        id=`basename $givenLoc`

        # Check to make sure <patch_loc>/custom/server exist
        if [ ! -d $givenLoc/custom/server ]; then
           echo "$givenLoc is not a valid CRS bundle patch location."
           $BASE/crs/auto_patch.pl -h
           exit -1;
        fi

        shift
        # echo $BASE/crs/auto_patch.pl -patchdir $patchdir -patchn $id $@
        $BASE/crs/auto_patch.pl -patchdir $patchdir -patchn $id $@
        exit 
     fi 

  elif [ $argCount -gt 1 ] && [ $2 = "-rollback" ]; then
     givenLoc=$2
     # either 'opatch auto -rollback [other-args] or 'opatch auto -rollback <patchloc> [other-args]'
     if [ $argCount -eq 2 ]; then
        # must be just 'opatch auto rollback' 
        givenLoc=$PWD
        patchdir=`dirname $givenLoc`
        id=`basename $givenLoc`

        # Check to make sure <patch_loc>/custom/server exist
        if [ ! -d $givenLoc/custom/server ]; then
           echo "$givenLoc is not a valid CRS bundle patch location."
           $BASE/crs/auto_patch.pl -h
           exit -1;
        fi

        shift
        shift
        # echo $BASE/crs/auto_patch.pl -rollback -patchdir $patchdir -patchn $id $@
        $BASE/crs/auto_patch.pl -rollback -patchdir $patchdir -patchn $id $@
        exit
    
     elif [ -d $3 ]; then
        # must be 'opatch auto -rollback <patch_loc> [other-args]
        # echo "opatch auto -rollback <patch_loc> [other-args]"
        givenLoc=$3
        patchdir=`dirname $givenLoc`
        id=`basename $givenLoc`

        # Check to make sure <patch_loc>/custom/server exist
        if [ ! -d $givenLoc/custom/server ]; then
           echo "$givenLoc is not a valid CRS bundle patch location."
           $BASE/crs/auto_patch.pl -h
           exit -1;
        fi

        shift
        shift
        shift
        # echo $BASE/crs/auto_patch.pl -rollback -patchdir $patchdir -patchn $id $@
        $BASE/crs/auto_patch.pl -rollback -patchdir $patchdir -patchn $id $@
        exit
     else
        # must be 'opatch auto -rollback [other-args]' or bad patch loc
        # just let auto_patch decide, assume it is 'opatch auto -rollback [other-args]
        # echo "opatch auto -rollback [other-args]"
        givenLoc=$PWD
        patchdir=`dirname $givenLoc`
        id=`basename $givenLoc`

        # Check to make sure <patch_loc>/custom/server exist
        if [ ! -d $givenLoc/custom/server ]; then
           echo "$givenLoc is not a valid CRS bundle patch location."
           $BASE/crs/auto_patch.pl -h
           exit -1;
        fi

        shift
        shift
        # echo $BASE/crs/auto_patch.pl -rollback -patchdir $patchdir -patchn $id $@
        $BASE/crs/auto_patch.pl -rollback -patchdir $patchdir -patchn $id $@
        exit

     fi
  else 
 
    echo "Please run 'opatch auto [-rollback] <patch location>'"
    # echo "           'opatch auto [-rollback]' if you are in the patch location." 
    exit -1
  fi
fi

# Get ORACLE_HOME from environment variable "ORACLE_HOME"
OH=${ORACLE_HOME}

# Look for OPATCH_DEBUG env variable
DEBUG=${OPATCH_DEBUG}

# Look for OPATCH_PLATFORM_ID
PLATFORM=${OPATCH_PLATFORM_ID}

# Look for OPATCH_NO_FUSER
NO_FUSER=${OPATCH_NO_FUSER}

# Look for ORACLE_OCM_SERVICE
oracleOcmService=""
if [ "$ORACLE_OCM_SERVICE" != "" ] ; then
  oracleOcmService="-Docm.endpoint=${ORACLE_OCM_SERVICE}"
fi


# Preserve the PATH environment variable
PATHENV=${PATH}

# BugFix for 4745222
PLATFORMNAME=`uname`;
if [ "$PLATFORMNAME" = "AIX" ] ; then
   OBJECT_MODE="32_64"
   export OBJECT_MODE
fi

# If -oh is specified, use it to over-ride env. var. ORACLE_HOME
getOH=0

# All the OPatch properties to be passed in to Java
# Format for properties is abc=xyz
PROPERTIES=""

# If -jre or -jdk are specified, use it to launch opatch,
#   with -jdk > -jre.  And we expect there is a "bin/java" underneath
#   the value supplied
getJRE=0
getJDK=0

JDK=""
JRE=""

for arg in "$@"; do
  if [ $getOH = 1 ]; then
     OH=$arg
     getOH=0
  fi
  if [ $getJRE = 1 ]; then
     JRE=$arg
     getJRE=0
  fi
  if [ $getJDK = 1 ]; then
     JDK=$arg
     getJDK=0
  fi

  if [ "$arg" = "-oh" ]; then
     getOH=1;
  fi
  if [ "$arg" = "-jre" ]; then
     getJRE=1;
  fi
  if [ "$arg" = "-jdk" ]; then
     getJDK=1;
  fi
done

# Error out if OH is not set
if [ "$OH" = "" ]; then
    echo Oracle Home is not set. OPatch cannot proceed!
    echo "OPatch returns with error code = 1"
    exit 1
fi

# Check for OPATCH_DEBUG
DEBUGVAL=false
if [ "$DEBUG" = "TRUE" ]; then
    DEBUGVAL=true;
fi
if [ "$DEBUG" = "true" ]; then
    DEBUGVAL=true;
fi

CP=$OH/oui/jlib
# Use ORACLE_HOME to set Java CLASS_PATH
JAVA= # Default location

# Use JDK if supplied
if [ "$JAVA" = "" ] && [ "$JDK" != "" ]; then # now from -jdk
  JAVA=$JDK/bin/java
fi

# Use JRE if supplied
if [ "$JAVA" = "" ] && [ "$JRE" != "" ]; then # from -jre
  JAVA=$JRE/bin/java
fi

# Check for jdk location inside OH
if [ "$JAVA" = "" ] && [ -x $OH/jdk/bin/java ]; then  # Now look for jdk in OH
  JAVA=$OH/jdk/bin/java
fi

# If OH/jdk not there, use OH/jre/*, it should be 1.4 or above
if [ "$JAVA" = "" ]; then
  JRE_HIGH=
  for i in `ls -1 $OH/jre | sort` ;
  do
    JRE_HIGH=$i ;
  done
  if [ "$JRE_HIGH" != "" ]; then
    JRE_HIGH_FINAL=`echo $JRE_HIGH | awk '
                            BEGIN {FS="."}
                            {
                                if (($1 >= 1) && ($2 >= 4))
                                    print $0
                            }'`
    if [ "$JRE_HIGH_FINAL" != "" ] && [ -x $OH/jre/$JRE_HIGH_FINAL/bin/java ]; then
        JAVA=$OH/jre/$JRE_HIGH_FINAL/bin/java
    fi
  fi
fi

# Last option is to look inside oraparam.ini for JRE_LOCATION
if [ "$JAVA" = "" ] && [ -r $OH/oui/oraparam.ini ]; then
  JRE_LOCATION=`grep "JRE_LOCATION=" $OH/oui/oraparam.ini | sed 's/JRE_LOCATION=//'`
  ABS_PATH=`echo $JRE_LOCATION | grep "^\/"`
  if [ "$ABS_PATH" = "" ]; then # not absolute path
    JAVA=$OH/oui/bin/$JRE_LOCATION/bin/java
  else
    JAVA=$JRE_LOCATION/bin/java
  fi
fi

# Java executable exists and has execute permission, exit otherwise
if [ "$JAVA" = "" ]; then
    echo Java could not be located. OPatch cannot proceed!
    echo "OPatch returns with error code = 1"
    exit 1
fi
if [ ! -x "$JAVA" ]; then
    echo $JAVA could not be located. OPatch cannot proceed!
    echo "OPatch returns with error code = 1"
    exit 1
fi

# set _bootClassPath for IBM platforms (bug 7038091 and 7114214)
_osArch=""

if [ -r $BASE/ocm/lib/emocmutl.jar ] && [ -r $BASE/ocm/ocm.zip ]; then
   _osArch=`$JAVA -cp $BASE/ocm/lib/emocmutl.jar OsInfo`
fi

_bootClassPath=""

if  [ "$DEBUGVAL" = "true" ]; then
    echo "_osArch is $_osArch"      
fi
if [ "${_osArch}" = "ppc" -o "${_osArch}" = "ppc64" -o "${_osArch}" = "s390" -o "${_osArch}" = "s390x" ]; then 
      _bootClassPath="-Xbootclasspath/a:${BASE}/ocm/lib/emocmutl.jar"
      if  [ "$DEBUGVAL" = "true" ]; then
        echo "IBM platforms: set _bootClassPath to $_bootClassPath"      
      fi
fi

# Change the permission of OH/.patch_storage directory and set umask.
# umask 0007 
# Do not set umask.
patchStorage="$OH/.patch_storage"
if [ -d $patchStorage ]; then
   chmod o-rwx $patchStorage
fi

if [ "$DEBUGVAL" = "true" ]; then
   echo "$JAVA -cp $BASE/ocm/lib/emocmutl.jar:$BASE/ocm/lib/emocmclnt.jar:$CP/OraInstaller.jar:$CP/OraPrereq.jar:$CP/xmlparserv2.jar:$CP/orai18n-mapping.jar:$CP/share.jar:$CP/srvm.jar:$BASE/jlib/opatch.jar:$BASE/jlib/opatchutil.jar:$BASE/jlib/opatchprereq.jar:$BASE/jlib/opatchactions.jar:$BASE/jlib/opatchfmw.jar:$BASE/jlib/opatchext.jar -DOPatch.ORACLE_HOME=$OH -DOPatch.DEBUG=$DEBUGVAL -DOPatch.RUNNING_DIR=$BASE ${oracleOcmService} ${_bootClassPath} oracle/opatch/OPatch $@"
fi

$JAVA -cp $BASE/ocm/lib/emocmutl.jar:$BASE/ocm/lib/emocmclnt.jar:$CP/OraInstaller.jar:$CP/OraPrereq.jar:$CP/xmlparserv2.jar:$CP/orai18n-mapping.jar:$CP/share.jar:$CP/srvm.jar:$BASE/jlib/opatch.jar:$BASE/jlib/opatchutil.jar:$BASE/jlib/opatchprereq.jar:$BASE/jlib/opatchactions.jar:$BASE/jlib/opatchfmw.jar:$BASE/jlib/opatchext.jar -DOPatch.ORACLE_HOME=$OH -DOPatch.DEBUG=$DEBUGVAL -DOPatch.RUNNING_DIR=$BASE ${oracleOcmService} ${_bootClassPath} oracle/opatch/OPatch $@

RESULT=$?

if [ $RESULT -ge  201 ] && [ $RESULT -le 203 ]; then
  echo
  echo "OPatch stopped on request."
  RESULT=0
elif [ $RESULT -ge 204 ] && [ $RESULT -le 210 ];then
  echo
  echo "OPatch completed with warnings.";
  RESULT=0
elif [ $RESULT != 0 ]; then
  echo
  echo "OPatch failed with error code $RESULT";
else
  echo 
  echo "OPatch succeeded."
fi

exit ${RESULT}
