#!/bin/sh

######################################################################
# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
#
#  opatch  5/17/04   Create and support
#                          -jdk, -jre, -oh
#  opatch  6/21/04   Check for OPATCH_DEBUG env variable
#  opatch  7/12/04   opatch can be invoked from any directory
#  opatch  7/15/04   use jdk to invoke opatch, otherwise use jre
#  opatch  7/16/04   Display the Java call for debug
#  opatch  7/19/04   add "./" to class path
#  opatch  7/31/04   more jre parsing, error if can't find java
#  opatch  8/05/04   change opatch to oracle.opatch package
#  opatch  8/27/04   sync up with opatch.bat to support OPATCH_PLATFORM_ID
#  opatch  8/04/04   Support OPATCH_PLATFORM_ID=integer
#  opatch  8/27/04   add fallback schemes for jre/jdk
#  opatch  8/30/04   Print "OPatch Succeeded" if OK
#  opatch  9/01/04   Further changes for jre/jdk priorities
#  opatch  9/07/04   java not present in jdk/jre option, error out
#  opatch  12/15/04  Supply PATH variable to java
#  opatch  02/02/05  Minor bug in parsing -jdk option
#  opatch  02/01/05  Introduce OPATCH_NO_FUSER to bypass fuser check
#  opatch  02/28/05  Print "OPatch Succeeded" if exit code is b/w 171 and 200
#  opatch  03/15/05  Pass in properties to OPatch
#  opatch  05/14/05  add opatchprereq.jar and opatchutil.jar to class path 
#  opatch  07/18/05  Do not pass PATH env var to OPatch JVM
#  opatch  12/06/05  Change the permissions of .patch_storage and set umask
#  opatch  12/13/05  Use -d inside if condition, as -e doesnot work on Solaris.
#  opatch  01/24/06  Remove umask setting and don't change the perm of 
#                      .patch_storage contents
#  opatch  05/10/06  Return 0 as exit code, even for warnings.
#  opatch  06/15/06  Put the OPatch/jlib/xmlparserv2.jar in classPath
#  opatch  06/21/06  Look for Jre 1.5 and then fall back to JDK.
#  opatch  08/01/06  Remove dependency on xmlparserv2.
#  opatch  08/17/06  Add opatchactions.jar into classpath
#  opatch  10/25/07  Get JRE_MEMORY_OPTIONS fr oui/oraparam.ini, bugsnhkcnt
#  opatch  02/27/08  Pass $BASE (running directory of 'opatch') as a property
#                      to java invocation. This is needed to locate ocm.zip in 
#                      OPatch.
#  opatch  03/04/08  Add 'emocmutl.jar' to the classpath
#  opatch  08/19/08  Check osInfo API/class in emocmutl.jar for IBM based
#                      platforms if 'ocm.zip' is bundled
#  opatch  05/20/08  Bug bmmbhmb
#  opatch  05/20/08  Bug bmmbhmb
#  opatch  05/16/08  Bug bkbtkcm
#  opatch  05/16/08  Bug bkbtkcm
#  opatch  10/25/07  Get JRE_MEMORY_OPTIONS fr oui/oraparam.ini, bug-snhkcnt
#  opatch  10/25/07  Get JRE_MEMORY_OPTIONS fr oui/oraparam.ini
#  opatch  03/13/09  Add 'orai18n-mapping.jar' to the classpath
#  opatch  06/05/09  Support 'opatch auto [-rollback]'. Need to deal with "abc"
#  opatch  06/08/09  Error out of 'opatch auto' is called on a non-crs bundle
#  opatch  06/23/09  Add 'opatchext.jar' to OPatch classpath 
#  opatch  06/29/09  Set MW_HOME, ORACLE_HOME when invoked from FMW Oracle Home
#  opatch  07/04/09  Add 'opatchfmw.jar' to OPatch classpath
#  opatch  10/05/09  Better messages for MW/OH consistency check
#  opatch  09/09/09  Fix Bug #bkbtkcm
#  opatch  10/20/09  Initialize FMW_ERROR to -1
#  opatch  11/13/09  Support 11.2 auto_patch.pl
#  opatch  11/11/09  Pass Common Home Location to OPatch
#  opatch  05/10/10  Remove custom/server check in 'opatch auto'
#  opatch  12/07/10  Fix -help and chmod issues
#  opatch  11/12/10  Add BIP classpath
#  opatch  11/01/10  Ignore the commented JRE_MEMORY_OPTIONS property
#  opatch  10/22/10  Add ojmisc.jar, emCfg.jar to classpath
#  opatch  10/15/10  Add correct ldif path to the classpath
#  opatch  10/07/10  Add LDIF_PATH to support LDIF classpath temporary
#  opatch  04/07/11  Change oui location logic
#  opatch  05/19/11  Add oraInst.loc of patching OH to system property
#  opatch  11/07/12  Fix "opatch version" exception" by modifying detect MV_HOME
#  opatch  12/01/12  Add domain config jar from oracle_common home for fmw12 
#  opatch  03/04/13  Fix opatch.sh fails on solaris 
#  opatch  25/03/13  Support for JDK and JRE with white spaces in the path 
#  opatch  03/01/13  Fix  JRE LOCATION IN ASCORE (FMW) SHIPHOME
#  opatch  04/19/13  Revert Support for JDK and JRE with white spaces
#  opatch  09/22/13  Modularize opatch script
#  opatch  12/13/13  Use basic unix shell scripting instead of extended syntax set
#  opatch  04/15/15  get JVM_64 for -d64 from OUI globalEnv.properties 
#  opatch  03/02/15  Add APPLY_MAKE env, to decide make action execution order
#  opatch  11/24/13  Fix issue in setUpJava
#  opatch  11/19/15  Use bundled JRE 8 (OPatch/jre)
#  opatch  04/08/16  Update CAS_VERSION to 12.2.0.1.3
#  opatch  04/11/16  Consolidate all 4 opatch scripts
#  opatch  06/07/16  Calling auto_patch.pl using the perl from Oracle Home Location
#  opatch  07/25/16  Disabled opatch getenv feature. This should be cleaned up if it needs to be removed completely.
#  opatch  01/25/17  Update CAS_VERSION to 12.2.0.2.5
#  opatch  02/17/17  Rev up OPatch and CAS version to 12.2.0.2.8
#  opatch  05/30/17  Rev up OPatch and CAS version to 12.2.0.3.1
#  opatch  10/24/17  Rev up OPatch and CAS version to 12.2.0.3.5
#  opatch  01/17/18  Rev up OPatch and CAS version to 12.2.0.5.0
#  opatch  03/14/18  Rev up OPatch and CAS version to 12.2.0.6.0
#  opatch  05/04/18  Rev up OPatch and CAS version to 12.2.6.0.0
#  opatch  06/28/18  Rev up OPatch and CAS version to 12.2.7.0.0
#  opatch  10/23/18  Rev up OPatch and CAS version to 12.2.8.0.0
#  opatch  12/12/18  jdk version must greater than or equal to 1.7
#  opatch  01/04/19  Rev up OPatch and CAS version to 12.2.9.0.0
#  opatch  3/25/19   Rev up OPatch and CAS version to 12.2.10.0.0
#  opatch  07/09/19   Rev up OPatch and CAS version to 12.2.11.0.0
####################################################################

# Global variable
JAVA_RUNTIME_VERSION=0
JAVA_VERSION=0
BUNDLED_JRE=0
CAS_VERSION="12.2.19.0.0"
CAS_JAR="*content-store-interfaces*.jar"
OCMRF_OPTION="0"
IS_NEXTGEN_HOME=false

get_opatch_version(){
    opatch_version_txt=${BASE}/version.txt
   if [ -r ${opatch_version_txt} ]; then
	 opatch_version=`grep "OPATCH_VERSION:" ${opatch_version_txt} | awk '{print $1}' | sed 's/OPATCH_VERSION://'`
	 short_opatch_version=`echo $opatch_version | cut -c1-4`
   else 
	echo "version_not_readable"
   fi
} 


# OPatch version	JDK version (used in compilation, which is the minimum
#			version needed in runtime)
#
# 12.2FA/CAS	    1.7
# 12.2FA/NON CAS    1.6
# 11.2			    1.6
# 12.*			    1.6
# 13.*			    1.6

 
init()
{
  BASE=`dirname $0`;
  PWD=`pwd`;
  argCount=$#
  args=$@
   
  # Look for OPATCH_DEBUG env variable
  DEBUG=${OPATCH_DEBUG}
  # Check for OPATCH_DEBUG
  DEBUGVAL=false
  if [ "$DEBUG" = "TRUE" ]; then
     DEBUGVAL=true;
  fi
  if [ "$DEBUG" = "true" ]; then
     DEBUGVAL=true;
  fi

  # Look for APPLY_MAKE env variable
  MAKE=${APPLY_MAKE}
  # Check for APPLY_MAKE
  MAKEVAL=false
  if [ "$MAKE" = "TRUE" ]; then
     MAKEVAL=true;
  fi
  if [ "$MAKE" = "true" ]; then
     MAKEVAL=true;
  fi
  
  # Get ORACLE_HOME from environment variable "ORACLE_HOME"
  OH=${ORACLE_HOME}
  # Get GLCM_OH
  SCRIPTNAME=$0
  case ${SCRIPTNAME} in
  /*)  SCRIPTPATH=`dirname ${SCRIPTNAME}` ;;
  *)  SCRIPTPATH=`dirname ${PWD}/${SCRIPTNAME}` ;;
  esac  
  GLCM_OH=$SCRIPTPATH/../../glcm

  # Get OPATCH_JRE_MEMORY_OPTIONS from environment variable "OPATCH_JRE_MEMORY_OPTIONS"
  JRE_MEMORY_OPTIONS=${OPATCH_JRE_MEMORY_OPTIONS}

  # Get Middleware Home from environment variable "MW_HOME"
  MWH=${MW_HOME}

  # Look for OPATCH_PLATFORM_ID
  PLATFORM=${OPATCH_PLATFORM_ID}

  # Look for OPATCH_NO_FUSER
  NO_FUSER=${OPATCH_NO_FUSER}

  # need implicit Oracle Home?
  NO_IMPLICIT_ORACLE_HOME=${OPATCH_NO_IMPLICIT_OH}

  # 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}

  PLATFORMNAME=`uname`;
  if [ "$PLATFORMNAME" = "AIX" ] ; then
     OBJECT_MODE="32_64"
     export OBJECT_MODE
  fi
  
  PH_BASE_DIR=""
  PH_BASE_FILE=""
  OPATCH_COMMAND=""
}

opatchAutoDetect()
{
   autopatch=0;
   autohelp=0;


  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

   i=1
   CMD_ID_EXIST=
  while [ -n "`echo "$PATH" | cut -d: -f${i}`" ] ; do
        if [ -s "`echo "$PATH" | cut -d: -f${i}`/id" ] ; then
                CMD_ID_EXIST="`echo "$PATH" | cut -d: -f${i}`/id"
                break
        fi
        i=`expr $i + 1`
  done


  if [ -z "$CMD_ID_EXIST" ]; then
        if [ $autopatch = 1 ]; then
                echo id command not avaliable!
                echo opatch auto can not proceed without id command!
                exit 1
        fi
  fi
   UID_INFO=`id`
   IS_ROOT=`echo $UID_INFO | grep "^uid=0("`
  if [ ! "$IS_ROOT" = "" ]; then
     if [ "$1" = "-h" ]; then
        autohelp=1
     elif [ "$1" = "-help" ]; then
        autohelp=1
     fi
  fi
  
  get_opatch_version
  # if it is opatch 11.2*, opatch auto is supported
  if [ "${short_opatch_version}" = "11.2" ]; then
      if [ $autohelp = 1 ]; then
         # calling the perl file using the perl from Oracle Home Location
         $BASE/../perl/bin/perl $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/../perl/bin/perl $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/../perl/bin/perl $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/../perl/bin/perl $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/../perl/bin/perl $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/../perl/bin/perl $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/../perl/bin/perl $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
  # else, opatch auto is deprecated
  else
     if [ $autohelp = 1 ]; then
        echo "Please run opatchauto -help|-h instead. "
        exit 1
     elif [ $autopatch = 1 ]; then
        echo "opatch auto command has been deprecated. Please run opatchauto instead."
        exit 1
     fi
  fi
}

parseCommandLineOPtions()
{
  # 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
   getOUI=0
   getInv=0
   getPhBaseDir=0
   getPhBaseFile=0
   getCustomLogDir=0
   getApplication=0
   getLogSessionId=0

   OPATCH_COMMAND=$1
   SECOND_COMMAND=$2
   if [ "$OPATCH_COMMAND" = "odp" ];then
      opatchPatchLoc=$2
   fi

  JDK=""
  JRE=""
  OUI_LOCATION=""
  FINAL_OUI_LOCATION=""
  PARALLEL_ON_FMW_OH=""
  APPLICATION=""
  LOG_SESSION_ID=""
  HELP=0

  # If -mw_home is specified, use it for the next of the session 
  # after verification of its integrity
   getMWHOME=0

  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 [ $getMWHOME = 1 ]; then
       MWH=$arg
       getMWHOME=0
    fi
    if [ $getOUI = 1 ]; then
       OUI_LOCATION=$arg
       FINAL_OUI_LOCATION=$arg
       if [ "$DEBUGVAL" = "true" ]; then
          echo OPatch is provided with 'oui_loc' option as $OUI_LOCATION
       fi
       getOUI=0
    fi
    if [ $getPhBaseDir = 1 ]; then
       PH_BASE_DIR=$arg
       getPhBaseDir=0
    fi
    if [ $getPhBaseFile = 1 ]; then
       PH_BASE_FILE=$arg
       getPhBaseFile=0
    fi
    if [ $getCustomLogDir = 1 ]; then
       CUSTOM_LOG_DIR=$arg
       getCustomLogDir=0
    fi
    if [ $getApplication = 1 ]; then
       APPLICATION=$arg
       getApplication=0
    fi
    if [ $getLogSessionId = 1 ]; then
       LOG_SESSION_ID=$arg
       getLogSessionId=0
       args=${args[@]/$LOG_SESSION_ID/''};
    fi

    if [ "$arg" = "-oh" ]; then
       getOH=1;
    fi
    if [ "$arg" = "-jre" ]; then
       getJRE=1;
    fi
    if [ "$arg" = "-jdk" ]; then
       getJDK=1;
    fi
    if [ "$arg" = "-mw_home" ]; then
       getMWHOME=1;
    fi
    if [ "$arg" = "-oui_loc" ]; then
       getOUI=1;
       CMDLINE_OUI=1;
    fi
    invptrLocFlag=`echo "$arg" | tr "[A-Z]" "[a-z]"`
    if [ "$invptrLocFlag" = "-invptrloc" ]; then
       getInv=1;
    fi
    if [ "$arg" = "-ocmrf" ]; then
       OCMRF_OPTION="1";
    fi
    if [ "$arg" = "-phBaseDir" ]; then
       getPhBaseDir=1
    fi
    if [ "$arg" = "-phBaseFile" ]; then
       getPhBaseFile=1
    fi
    if [ "$arg" = "-customLogDir" ]; then
       getCustomLogDir=1
    fi
    if [ "$arg" = "-application" ]; then
       getApplication=1
    fi
    if [ "$arg" = "-log_session_id" ]; then
       getLogSessionId=1
    fi
    if [ "$arg" = "-h" ] || [ "$arg" = "-help" ]; then
      HELP=1
    fi

    if [ "$arg" = "-parallel_on_fmw_oh" ]; then
       PARALLEL_ON_FMW_OH="true";
       args=${args[@]/'-parallel_on_fmw_oh'/''};
    fi
    if [ "$arg" = "-log_session_id" ]; then
       args=${args[@]/'-log_session_id'/''};
    fi
  done
}

getLatestVersion()
{
  # check the existence of cas jar 
  casJarsDetection
  CAS_EXISTS=$?
  if [ "$CAS_EXISTS" = 1 ]; then
    # check if it's 'util GetLatestVersion' command
    if [ "$OPATCH_COMMAND" = "util" ] && [ "$SECOND_COMMAND" = "GetLatestVersion" ]; then
      if [ -z "$APPLICATION" ]; then
	echo "Please specify the application to be executed. Please refer 'opatch util GetLatestVersion -help' for details."
        echo
        echo "OPatch failed with error code 255"
        exit 255 
      fi
      if [ "$HELP" = 1 ]; then
        getLatestVersionHelp
        echo 
        echo "OPatch succeeded."
        exit 0
      fi
      absOH=`cd $OH; pwd`
      latestPointerFile=`ls $OH/$APPLICATION/latest-ptr-* 2>/dev/null| sort -d | head -1` 
      latestVersionDirectory=${latestPointerFile#*latest-ptr-}
      latestVerDirPath=$absOH/$APPLICATION/$latestVersionDirectory
      if [ ! -d "$latestVerDirPath" ]; then
	echo "The latest application version directory $latestVerDirPath from the latest pointer file doesn't exist."
        echo
        echo "OPatch failed with error code 255"
        exit 255
      fi
      if [ "$latestVersionDirectory" != "" ]; then
	echo "$latestVerDirPath"
        echo 
        echo "OPatch succeeded."
        exit 0 
      else
	echo ""
        echo 
        echo "OPatch succeeded."
	exit 0
      fi
    fi
  fi
}

getLatestVersionHelp()
{
  echo "DESCRIPTION
    This operation returns the absolute path to the latest version directory
    of the specified application.

SYNTAX
opatch util GetLatestVersion [-application <application_name> ]
							 [-jre <LOC> ]
							 [-oh <ORACLE_HOME> ]

OPTIONS
        -jre
              This option tells OPatch to use JRE (java) from the
              specified location instead of the default location
              under Oracle Home

        -oh
              This option is used to specify the oracle home to work on.
              This takes precedence over the environment variable ORACLE_HOME

PARAMETERS
        -application
              This option is used to specify the application name"
}

sourceOPatchEnv()
{
  if [ ! -f ${BASE}/opatch_env.sh ]; then
    if [ "$DEBUGVAL" = "true" ]; then
       echo "opatch_env.sh does not exist"
    fi
    isOPatchEnv=0
  else
    if [ "$DEBUGVAL" = "true" ]; then
       echo "Found opatch_env.sh. OPatch is going to source it."
    fi
    isOPatchEnv=1

    # CLI passed the option -highmem or -lowmem
    if [ ! -z "$HEAPMEM" ]; then
       if [ "$DEBUGVAL" = "true" ]; then
          echo "CLI option passed: $HEAPMEM"
       fi
       export HEAPMEM
    fi

    # Source the env file to set the variable OPATCH_MAX_HEAP_MEMORY
    . ${BASE}/opatch_env.sh

  fi
}

# Update OPatch version from 13.10 to 13.9.1.0.0
# Option 'ocmrf' is deprecated in OPatch 13.3 - Detect and give warning message
ocmOptionDetect()
{
   VERSION_13_X="0"
   get_opatch_version
   if [ "`echo $opatch_version | grep "13.9"`" != "" ]; then
	  VERSION_13_X="1"
   fi  
   if [ "$OCMRF_OPTION" = "1" ] && [ "$VERSION_13_X" = "1" ]; then
      echo ""
      echo "WARNING: the option \"-ocmrf\" is deprecated and no longer needed.  OPatch no"
      echo "longer checks for OCM configuration. It will be removed in a future release."
      echo ""
   fi
}

setUpHomeDirs()
{
  # Error out if OH is not set and env var OPATCH_NO_IMPLICIT_OH is set to 'true'
  if [ "$OH" = "" ] && [ "$NO_IMPLICIT_ORACLE_HOME" = "true" ]; then
    echo Oracle Home is not set. OPatch cannot proceed!
    echo "OPatch returns with error code = 1"
    exit 1
  fi

  # Calculate the ORACLE_HOME/MW_HOME relative to this script...
  if [ -z "$OH" ]; then

     # Note: this will not work if the script is sourced (. ./wlst.sh)
     SCRIPTNAME=$0
     case ${SCRIPTNAME} in
     /*)  SCRIPTPATH=`dirname ${SCRIPTNAME}` ;;
      *)  SCRIPTPATH=`dirname ${PWD}/${SCRIPTNAME}` ;;
     esac

     C_ORACLE_HOME=`cd ${SCRIPTPATH}/.. ; pwd`
     C_MW_HOME=`cd ${C_ORACLE_HOME}/.. ; pwd`
     if [ "$DEBUGVAL" = "true" ]; then
        echo ORACLE_HOME is NOT set at OPatch invocation 
     fi
  else  
     # User set Oracle Home, check later if MW home is consistently set too
     if [ ! -d "${OH}" ]; then
        echo The Oracle Home $OH is not valid directory. Please give proper Oracle Home.
        echo "OPatch returns with error code = 1"
        exit 1;
     fi
     if [ ! -z "${FMW_COMPONENT_HOME}" ]; then
        C_ORACLE_HOME=${FMW_COMPONENT_HOME}
     else
        if [ -x "${OH}/common/bin/setHomeDirs.sh" ] && [ -x "${OH}/common/bin/setWlstEnv.sh" ]; then
           C_ORACLE_HOME=${OH}
           FMW_COMPONENT_HOME=${OH}
        else
           TEMP_MW_HOME=`cd ${OH}/.. ; pwd`
           for SUB_DIR in $TEMP_MW_HOME/*
           do
              if [ -x "${SUB_DIR}/common/bin/setHomeDirs.sh" ] && [ -x "${SUB_DIR}/common/bin/setWlstEnv.sh" ]; then
                 FMW_COMPONENT_HOME=$SUB_DIR
                 C_ORACLE_HOME=$SUB_DIR
              fi
           done
           if [ -z "${FMW_COMPONENT_HOME}" ]; then
              if [ "$DEBUGVAL" = "true" ]; then
                 echo OPatch was not able to set FMW_COMPONENT_HOME by itself.
              fi
              C_ORACLE_HOME=${OH}
           fi
        fi

     fi
     # Calculate Middleware Home simply by moving up IFF User set Oracle Home
     C_MW_HOME=`cd ${C_ORACLE_HOME}/.. ; pwd`
  fi

  # Check consistency of Oracle Home and Middleware Home values (within each
  # OPatch cmd only if applicable)
  if [ ! -z "${MWH}" ] ; then
     # The user could have set Middleware Home either with the cmd line option
     # or by setting the environment variable MW_HOME, it is captured in MWH
     # Fixup if they put the PATH separator at the end
     #
     MWH=`echo $MWH | sed -e 's|/$||g'`
  fi
  
  if [ -f "${C_MW_HOME}/registry.dat" -o -f "${C_ORACLE_HOME}/inventory/registry.xml" ]; then
     if [ ! -x "${C_ORACLE_HOME}/common/bin/setHomeDirs.sh" ]; then
        MW_HOME=${C_ORACLE_HOME}
        if [ -x "${MW_HOME}/oracle_common/common/bin/setHomeDirs.sh" ]; then
           MWH=${MW_HOME}
        fi
     fi
     if [ "$MWH" = "" ]; then
        MWH=${C_MW_HOME}
     fi
     if [ "$MW_HOME" = "" ]; then
        MW_HOME=${C_MW_HOME}
     fi
     if [ "$OH" = "" ]; then
        OH=${C_ORACLE_HOME}
     fi
  else
     # Regular Oracle Home - We allow implicit setting of Oracle Home for OUI based homes
     if [ "$OH" = "" ]; then
        if [ ! -d "${C_ORACLE_HOME}/oui" ]  ; then
           echo The Oracle Home $C_ORACLE_HOME is not OUI based home. Please give proper Oracle Home.
           exit 1;
        fi
        OH=${C_ORACLE_HOME}
     else
        # Fix if GLCM OH exist, find oui under GLCM OH. 
        if [ ! -d "${GLCM_OH}/oui" ] && [ ! -d "${OH}/oui" ]  ; then
           echo The Oracle Home $OH is not OUI based home. Please give proper Oracle Home.
           echo "OPatch returns with error code = 1"
           exit 1;
        fi
     fi
  fi
}

setUpOUILocation()
{
 if [ "$OUI_LOCATION" = "" -o ! -d "${OUI_LOCATION}" ]; then  
   if [ -d "${GLCM_OH}" ]; then
      #Check whether OH is next gen home.
      if [ -e "${GLCM_OH}/bin/isNextGen.sh" ] ; then
          ${GLCM_OH}/bin/isNextGen.sh -oh $OH &>/dev/null
         if [ $? -eq 0 ]; then
            IS_NEXTGEN_HOME=true
         else
            IS_NEXTGEN_HOME=false
         fi
      fi
      if [ -e "${GLCM_OH}/bin/getOUILibFolder.sh" ] ; then
        OUI_LOCATION=`${GLCM_OH}/bin/getOUILibFolder.sh -oh $OH`
        FINAL_OUI_LOCATION=$OUI_LOCATION
      else
        OUI_LOCATION=$GLCM_OH/oui
        FINAL_OUI_LOCATION=$GLCM_OH/oui
      fi   
   else 
     OUI_LOCATION=$OH/oui
     FINAL_OUI_LOCATION=$OH/oui
      if [ "$OUI_LOCATION" = "" -o ! -d "${OUI_LOCATION}" ]; then
       SCRIPTNAME=$0
       case ${SCRIPTNAME} in
       /*)  SCRIPTPATH=`dirname ${SCRIPTNAME}` ;;
        *)  SCRIPTPATH=`dirname ${PWD}/${SCRIPTNAME}` ;;
       esac
         if [ -d "${SCRIPTPATH}/../oui" ]; then
           OUI_LOCATION=`cd ${SCRIPTPATH}/../oui ; pwd`
           FINAL_OUI_LOCATION=$OUI_LOCATION
         fi
      fi    
   fi
 fi
 

#Final validation of oui directory
 if [ ! -d "${OUI_LOCATION}" ] ; then
     echo The Oracle Home $OH is not OUI based home. Please give proper Oracle Home.
     echo "OPatch returns with error code = 1"
     exit 1;
 fi
}

setUpInvPtrLoc()
{
   # use oraInst.loc of patching oracle home as INVPTRLOC
   invptr=
   if [ -r "${OH}/oraInst.loc" ]; then
      if [ $argCount -ge 1 -a $getInv -eq 0 ]; then
         invptr=" -invPtrLoc ${OH}/oraInst.loc"
      fi
   fi
}

# Assumption:  if JAVA_HOME is set, we want to get java version
getJavaVersion()
{
   JAVA_VERSION=0

   if [ ! -z ${JAVA_HOME} ] ; then
      # Detect if JDK is after 8. If yes, use it. If not search for 8 or older
      JAVA_VERSION=`$JAVA_HOME/bin/java -version 2>&1 | tr -d \" | awk '/version/ {print $3}' | awk ' BEGIN {FS="."} {if($1 <= 1) {print $2} else {print $1} } '`
      if [ -z ${JAVA_VERSION} -o ${JAVA_VERSION} -lt 9 ] ; then
         # continue check java other version < 9
       	JAVA_VERSION=`$JAVA_HOME/bin/java -version 2>&1 | tr -d \" | awk '/version/ {print $3}' | awk ' BEGIN {FS="."} {if($1 <= 1) {print $2} else {print $1} } '` 
        if [ -z ${JAVA_VERSION} ] ; then
         JAVA_VERSION=`$JAVA_HOME/bin/java -version 2>&1 | tr -d \" | awk '/version/ {print $3}' | awk ' BEGIN {FS="."} {if($1 <= 1) {print $2} else {print $1} } '` 
          if [ -z ${JAVA_VERSION} ] ; then
            JAVA_VERSION=`$JAVA_HOME/bin/java -version 2>&1 | awk '/version/ {print $3}' | awk ' BEGIN {FS="-"} { print $1 }' | cut -c 2-`
            if [ -z ${JAVA_VERSION} ] ; then
               JAVA_VERSION=`$JAVA_HOME/bin/java -version 2>&1 | awk '/version/ {print $2}' | awk ' BEGIN {FS="-"} { print $1 }' | cut -c 2-`
            fi
           fi
         fi
       fi
     fi
  if [ "$DEBUGVAL" = "true" ]; then
     echo "  JAVA version : $JAVA_VERSION  [$JAVA_HOME] "
  fi
  return $JAVA_VERSION
}

# Detect the CAS jars if exitss in OPatch/jlib directory
casJarsDetection()
{
   casExist=0
   if [ -f ${BASE}/jlib/${CAS_JAR} ]; then
      casExist=1
     
   fi
   if [ "$DEBUGVAL" = "true" ]; then
      echo "  CAS jars exist ? $casExist  [$BASE/jlib/$CAS_JAR]"
   fi

   CAS_EXIST_ENV=$casExist
   export CAS_EXIST_ENV
   return $casExist
}


#  if ( JAVA>=7 ) then
#     true
#  else
#     false
canUseJava()
{
   CAS_EXISTS=0
   JAVA_VERSION=0

   casJarsDetection
   CAS_EXISTS=$?
   getJavaVersion
   JAVA_VERSION=$?

   # No matter whether CAS jars exist, must use java >= 7
   if [ "$JAVA_VERSION" -ge 7 ]; then
      useJava=1
   else
      useJava=0
   fi

   if [ "$DEBUGVAL" = "true" ]; then
      echo "Can Use JAVA ? $useJava"
   fi
   return $useJava
}

# Detect if cmd line option -jdk/-jre exists
getOptionJreJdk()
{
   HAS_OPTION=0
   CAN_USE_JAVA=0
   # Use JRE if supplied
   if [ "$JRE" != "" ]; then # from -jre
      JAVA_HOME=$JRE
      JAVA=$JAVA_HOME/bin/java
      HAS_OPTION=1
   # Use JDK if supplied
   elif [ "$JDK" != "" ]; then # now from -jdk
      JAVA_HOME=$JDK
      JAVA=$JAVA_HOME/bin/java
      HAS_OPTION=1
   fi
   if [ "$DEBUGVAL" = "true" ]; then
      echo "- Detect the option -jre/-jdk ? $HAS_OPTION"
   fi

   if [ "$HAS_OPTION" = 1 ] ; then
      # Validate the Java executable exists and has execute permission, exit otherwise
      if [ ! -x "$JAVA" ]; then
         echo "$JAVA is not a valid executable for this platform. OPatch cannot proceed!"
         echo "OPatch returns with error code = 1"
         exit 1
      fi
      # invoke canUseJava() to check whether we can use JAVA
      canUseJava
      CAN_USE_JAVA=$?
   fi
   return $CAN_USE_JAVA
}

# Detection of OH java
jvmDiscovery()
{
   CAN_USE_JAVA=0

   if  [ "$DEBUGVAL" = "true" ]; then
       echo "- Start JVM Discovery ..."
   fi
   . "${BASE}/scripts/opatch_jvm_discovery"

   if [ ! -z ${JAVA_HOME} ] ; then
      # invoke canUseJava() to check whether we can use JAVA
      canUseJava
      CAN_USE_JAVA=$?
   fi
   return $CAN_USE_JAVA
}

# Detect the bundled JRE if exists In OPatch/jre
bundledJREDetection()
{
   CAN_USE_JAVA=0

   if [ -d ${BASE}/jre ]; then
      JAVA_HOME=$BASE/jre
      JAVA=$JAVA_HOME/bin/java
      BUNDLED_JRE=1
   fi
   if [ "$DEBUGVAL" = "true" ]; then
      echo "- Detect the bundled jre ($BASE/jre) ? $BUNDLED_JRE"
   fi
   if [ "$BUNDLED_JRE" = 1 ]; then
      # invoke canUseJava() to check whether we can use JAVA
      canUseJava
      CAN_USE_JAVA=$?
   fi
   return $CAN_USE_JAVA
}

## Java Support Statement:  The order of precedence to derive the JAVA_HOME is as follows
##
# 1. option -jdk/-jre --> check to see if "Can use JAVA" ?
#    ==> yes: ready to 'callOPatch'
#    ==> no: go to #2
# 2. bundledJRE detection --> "Can use JAVA" ?
#    ==> yes: ready to 'callOpatch'
#    ==> no: go to #3
# 3. jvm_discovery --> "Can use JAVA" ?
#    ==> yes: ready to 'callOpatch'
#    ==> no: Error and Exit
setUpJava()
{
   CAN_USE_JAVA=0

   # 1. check option -jre/-jdk
   getOptionJreJdk
   CAN_USE_JAVA=$?

   # 2. Bundled JRE detection
   if [ "$CAN_USE_JAVA" = 0 ] ; then
      bundledJREDetection
      CAN_USE_JAVA=$?
   fi

   # 3. JVM discovery
   if [ "$CAN_USE_JAVA" = 0 ] ; then
      jvmDiscovery
      CAN_USE_JAVA=$?
   fi

   if [ "$CAN_USE_JAVA" = 0 ] ; then
      casJarsDetection
      echo "Java (1.7) could not be located. OPatch cannot proceed!"
      echo "OPatch returns with error code = 1"
      exit 1
   fi

   # Now check if Java executable exists and has execute permission, exit otherwise
   # Because from this point on we cannot proceed without Java 
   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 is not a valid executable for this platform. OPatch cannot proceed!"
      echo "OPatch returns with error code = 1"
      exit 1
   fi

   # Get the java runtime version
   # java_version_digit is the second digit of jdk version
   # e.g. for jdk1.6 java_version_digit is 6
   java_version_digit=`$JAVA -version 2>&1 |  tr -d \" | awk '/version/ {print $3}' | awk ' BEGIN {FS="."} {if($1 <= 1) {print $2} else {print $1} } ' `
   JAVA_RUNTIME_VERSION=$java_version_digit

   if  [ "$DEBUGVAL" = "true" ]; then
       _osArch=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp os.arch`
       _javaVMSpecVersion=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.vm.specification.version`
       _javaVMSpecVendor=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.vm.specification.vendor`
       _javaVMSpecName=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.vm.specification.name`
       _javaVMVendor=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.vm.vendor`
       _javaJRESpecVersion=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.specification.version`
       _javaJRESpecVendor=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.specification.vendor`
       _javaJRESpecName=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.specification.name`
       _javaSupportedClassVersion=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.class.version`
       if [ -x "$JAVA_HOME/bin/javap" ]; then
          _javaCompiledClassMajorVersion=`$JAVA_HOME/bin/javap -verbose -classpath $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp |grep major|sed 's/^ *\(.*\) *$/\1/'`
          _javaCompiledClassMinorVersion=`$JAVA_HOME/bin/javap -verbose -classpath $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp|grep minor|sed 's/^ *\(.*\) *$/\1/'`
       fi
       _unameall=`uname -a`
       echo "Machine Info: $_unameall"
       echo "_osArch is $_osArch"
       echo "_javaVMSpecVersion is $_javaVMSpecVersion"
       echo "_javaVMSpecVendor is $_javaVMSpecVendor"
       echo "_javaVMSpecName is $_javaVMSpecName"
       echo "_javaVMVendor is $_javaVMVendor"
       echo "_javaJRESpecVersion is $_javaJRESpecVersion"
       echo "_javaJRESpecVendor is $_javaJRESpecVendor"
       echo "_javaJRESpecName is $_javaJRESpecName"
       echo "_javaSupportedClassVersion is $_javaSupportedClassVersion"
       echo "OPatch compiled with $_javaCompiledClassMajorVersion, $_javaCompiledClassMinorVersion"
   fi
}

setDefaultHeap()
{
   # Set default memory to 3GB only in case of 64 bit Linux architecture and when CAS is in use.
   # When default heap setting is overwritten by OPATCH_JRE_MEMORY_OPTIONS, then do not modify value of heap setting.

   DEFAULT_HEAP="-Xmx768m"
   XMAPS_OPTION="-Xmpas:on"
   PLATFORM=`uname`
   ARCH=`uname -m`
   if [ "$PLATFORM" = "Linux" -a "$ARCH" = "x86_64" ];then
      DEFAULT_HEAP="-Xmx3072m"
   elif [ "$PLATFORM" = "Linux" -a "$ARCH" = "aarch64" ];then
      DEFAULT_HEAP="-Xmx3072m"
   else
      DEFAULT_HEAP="-Xmx1536m" 
   fi
 
   if [ -z "${JRE_MEMORY_OPTIONS}" ]; then
      JRE_MEMORY_OPTIONS=" $DEFAULT_HEAP"
   elif [ -z "`echo $JRE_MEMORY_OPTIONS | grep "\-X*mx[0-9][0-9]*m*G*"`" ]; then
      JRE_MEMORY_OPTIONS=" $JRE_MEMORY_OPTIONS $DEFAULT_HEAP"
   elif [ -z "${OPATCH_JRE_MEMORY_OPTIONS}" ]; then
      JRE_MEMORY_OPTIONS=`echo $JRE_MEMORY_OPTIONS | sed 's/\-X*mx[0-9][0-9]*m*G*/'$DEFAULT_HEAP/`
   fi

   if [ "$PLATFORM" = "HP-UX" ];then
      if [ "$OPATCH_ENABLE_MPAS" = "true" ];then
        JRE_MEMORY_OPTIONS=" $JRE_MEMORY_OPTIONS $XMAPS_OPTION"
      fi
   fi
}

setUpJREMemoryOPtions()
{
   # JRE_MEMORY_OPTIONS 
#   if [ $isOPatchEnv = 1 ]; then
#      OPATCH_MEMORY_MB=`echo "${OPATCH_MAX_HEAP_MEMORY}" | bc`
#      OPATCH_MEMORY_MB="-Xmx${OPATCH_MEMORY_MB}m"
#   else
#      OPATCH_MEMORY_MB="-Xmx3072m"
#   fi

   if [ -z "${JRE_MEMORY_OPTIONS}" ]; then
      JRE_MEMORY_OPTIONS=""
      if [ -r $FINAL_OUI_LOCATION/oraparam.ini ]; then
         JRE_MEMORY_OPTIONS=`grep -v "^#" $FINAL_OUI_LOCATION/oraparam.ini | grep "^JRE_MEMORY_OPTIONS=" | sed 's/JRE_MEMORY_OPTIONS=//' | head -1`
         setDefaultHeap
         JROCKIT=`echo $JDK | grep "jrockit"`;
         if [ ! -z "${JROCKIT}" ]; then
            JRE_MEMORY_OPTIONS=`echo $JRE_MEMORY_OPTIONS | sed 's/XX:MaxPermSize=/ms/'`;
         fi
      fi
   else
      setDefaultHeap
      D64_OPTIONS=`echo $JRE_MEMORY_OPTIONS | grep "\-d64"`
      if [ -z "${D64_OPTIONS}" ]; then
         if [ -r $FINAL_OUI_LOCATION/oraparam.ini ]; then
            D64_OPTIONS=`grep -v "^#" $FINAL_OUI_LOCATION/oraparam.ini | grep "^JRE_MEMORY_OPTIONS=" | sed 's/JRE_MEMORY_OPTIONS=//' | head -1 | grep " \-d64"`
         fi
         if [ ! -z "${D64_OPTIONS}" ]; then
            D64=" -d64"
            if [ "$DEBUGVAL" = "true" ]; then
              echo "Adding -d64 to JRE_MEMORY_OPTIONS"
            fi
            JRE_MEMORY_OPTIONS=$JRE_MEMORY_OPTIONS$D64
         fi
      fi
   fi

   # get JVM_64 for -d64
   if [ -z "$JVM_64" ]; then
     . "${BASE}/scripts/opatch_jvm_discovery"
   fi

   D64_PRESENT=`echo $JRE_MEMORY_OPTIONS | grep "\-d64"`
   if [ -z "${D64_PRESENT}" ] && [ "${JVM_64}" = "-d64" ]; then
     ADD_D64=" -d64"
     if [ "$DEBUGVAL" = "true" ]; then
        echo "Adding -d64 to JRE_MEMORY_OPTIONS"
     fi
     JRE_MEMORY_OPTIONS=$JRE_MEMORY_OPTIONS$ADD_D64
   fi
  
   # In case of Out Of Memory Error, OPatch should generate heap dump.
   JRE_MEMORY_OPTIONS="$JRE_MEMORY_OPTIONS -XX:+HeapDumpOnOutOfMemoryError"
   if [ ! -z "$CUSTOM_LOG_DIR" ]; then
     JRE_MEMORY_OPTIONS="$JRE_MEMORY_OPTIONS -XX:HeapDumpPath=$CUSTOM_LOG_DIR/opatch"
   elif [ ! -z "$OH" ]; then
     JRE_MEMORY_OPTIONS="$JRE_MEMORY_OPTIONS -XX:HeapDumpPath=$OH/cfgtoollogs/opatch"
   fi

   #remove -d64 if present incase of JDK 9 and above
   if [ "$JAVA_VERSION" -gt 8 ]; then
       JRE_MEMORY_OPTIONS=`echo $JRE_MEMORY_OPTIONS | sed 's/-d64//g'`
   fi

   # Remove double quotes globally - whatever u get
   JRE_MEMORY_OPTIONS=`echo $JRE_MEMORY_OPTIONS | sed 's/\"//g'`

   # Detect any deprecated flag if any
   detectJdkDeprecatedFlags

   if [ "$DEBUGVAL" = "true" ]; then
      echo "JRE_MEMORY_OPTIONS are $JRE_MEMORY_OPTIONS"
   fi
}

# Detection (and replace) of all deprecated flags introducing in new JDK/JRE
# JDK 8:  MaxPermSize <=== replaced by ===> MaxMetaspaceSize:  default = 128M
# 
detectJdkDeprecatedFlags()
{
   # if JDK8 and has flag 'MaxPermSize', replace MaxPermSize <==> MaxMetaspaceSize
   MAXPERMSIZE_PRESENT=`echo $JRE_MEMORY_OPTIONS | grep "MaxPermSize"`
  
   if [ "${JAVA_RUNTIME_VERSION}" = "8" ] && [ ! -z "${MAXPERMSIZE_PRESENT}" ]; then
       JRE_MEMORY_OPTIONS=`echo $JRE_MEMORY_OPTIONS | sed 's/MaxPermSize/MaxMetaspaceSize/'`
   fi
}

setUpPatchStorage()
{
   # Change the permission of OH/.patch_storage directory and set umask.
   # umask 0007 
   # Do not set umask.
   patchStorage="$OH/.patch_storage"
   chmodResult=0
   if [ -d $patchStorage ]; then
      chmod o-rwx $patchStorage  > /dev/null
      chmodResult=$?
   fi

   if [ $chmodResult != 0 ]; then
      echo "The chmod command failed for ".$patchStorage.". It is possible that you have no permission to access it. OPatch cannot proceed!"
      echo "OPatch returns with error code = 1"
      exit 1
   fi
}

setUpLibraryPath()
{
    IS_NEXT_GEN=false
   if [ "$OUI_LOCATION" != "" ] ; then
      #for NextGen OUI home, we use 'modules' directory as opposed to 'jlib' directory
      CP=$OUI_LOCATION
      if [ -d "$OUI_LOCATION/modules" ] ; then
         IS_NEXT_GEN=true
      fi
   else
      CP=$OH/oui
      if [ -d "$OH/oui/modules" ] ; then
         IS_NEXT_GEN=true
      fi
   fi
   
   if [ -n "$OOP_TEMP_OH" -a -d "$OOP_TEMP_OH" ]; then
      CP=$OOP_TEMP_OH/oui
   fi

   if [ "$IS_NEXT_GEN" = "true" ] ; then
      CP="$CP/modules"
      # for NextGen OUI, classpath attribute of OraInstaller.jar manifest contains all related jar files
      OUI_JARS="$CP/OraInstaller.jar"

   else
      CP="$CP/jlib"
      OUI_JARS="$CP/OraInstaller.jar:$CP/OraInstallerNet.jar:$CP/OraPrereq.jar:$CP/share.jar:$CP/orai18n-mapping.jar:$CP/xmlparserv2.jar:$CP/emCfg.jar:$CP/ojmisc.jar"
   fi

   # Below setting copied from oplan
   PLATFORM=`uname`

   case $PLATFORM in
      HP-UX)
         LD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib
         export LD_LIBRARY_PATH
         SHLIB_PATH=
         export SHLIB_PATH
         ;;
      AIX)
         LIBPATH=$OH/lib:$OH/srvm/lib:$LIBPATH
         export LIBPATH
         ;;
      Linux)
         LD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib:$LD_LIBRARY_PATH
         # Linux ( ppc64 || s390x ) => LD_LIBRARY_PATH lib32
         ARCH=`uname -m`;
         if [ "$ARCH" = "ppc64" -o "$ARCH" = "s390x" ]
         then
            LD_LIBRARY_PATH=$OH/lib32:$OH/srvm/lib32:$LD_LIBRARY_PATH
         fi
         export LD_LIBRARY_PATH
         ;;
      SunOS)
         LD_LIBRARY_PATH_64=$OH/lib:$OH/srvm/lib:$LD_LIBRARY_PATH_64
         export LD_LIBRARY_PATH_64
         LD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib:$LD_LIBRARY_PATH
         export LD_LIBRARY_PATH
         ;;
      OSF1) LD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib:$LD_LIBRARY_PATH
         export LD_LIBRARY_PATH
         ;;
      Darwin)
         DYLD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib:$DYLD_LIBRARY_PATH
         export DYLD_LIBRARY_PATH
         ;;
      *)    
         if [ -d $OH/lib32 ];
         then
            LD_LIBRARY_PATH=$OH/lib32:$OH/srvm/lib32:$LD_LIBRARY_PATH
         else
            LD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib:$LD_LIBRARY_PATH
         fi
         export LD_LIBRARY_PATH
         ;;
   esac
}

setUpClassPath()
{
   # set _bootClassPath for IBM platforms
   _osArch=""
   if [ -r $BASE/ocm/lib/emocmcommon.jar ] && [ -r $BASE/ocm/ocm.zip ]; then
      _osArch=`$JAVA -cp $BASE/ocm/lib/emocmcommon.jar OsInfo`
   fi
   _bootClassPath=""

   if  [ "$DEBUGVAL" = "true" ]; then
       echo "_osArch (from OCM API) is $_osArch"
   fi
   if [ "${_osArch}" = "ppc" -o "${_osArch}" = "ppc64" -o "${_osArch}" = "s390"  -o "${_osArch}" = "s390x" ]; then
      _bootClassPath="-Xbootclasspath/a:${BASE}/ocm/lib/emocmclnt.jar:${BASE}/ocm/lib/emocmcommon.jar:${BASE}/ocm/lib/emocmclnt-14.jar:${BASE}/ocm/lib/osdt_core3.jar:${BASE}/ocm/lib/osdt_jce.jar:${BASE}/ocm/lib/http_client.jar:${BASE}/ocm/lib/regexp.jar:${BASE}/ocm/lib/jcert.jar:${BASE}/ocm/lib/jnet.jar:${BASE}/ocm/lib/jsse.jar:${BASE}/ocm/lib/log4j-core.jar:${BASE}/ocm/lib/xmlparserv2.jar"
      if  [ "$DEBUGVAL" = "true" ]; then
        echo "IBM platforms: set _bootClassPath to $_bootClassPath"
      fi
   fi

   #set opatch class path
   
   get_opatch_version
   casJarsDetection
   CAS_BASED_HOME=$?
   
   if  [ "$DEBUGVAL" = "true" ]; then
       echo "CAS_BASED_HOME is true(1) or false(0) : $CAS_BASED_HOME"
   fi
   
   if [ "$CAS_BASED_HOME" = 1 ]; then
   		opatchClassPath="$BASE/jlib/oracle.opatch.classpath.dl.jar:$BASE/auto/core/modules/features/oracle.glcm.oplan.core.classpath.jar:$BASE/auto/core/modules/features/oracle.glcm.osys.core.classpath.jar:$BASE/ocm/lib/emocmclnt.jar"   
   # if it is opatch 13.*, nextgen OUI
   elif [ "${short_opatch_version}" = "13.9" ]; then
      opatchClassPath="$OUI_JARS:S$BASE/jlib/oracle.opatch.classpath.jar:$BASE/auto/core/modules/features/oracle.glcm.oplan.core.classpath.jar:$BASE/auto/core/modules/features/oracle.glcm.osys.core.classpath.jar:$BASE/../oui/modules/installer-launch.jar" 
   # if it is opatch 11.2, 12.1, 12.2(db), new opatchauto folder structure 
   elif [ "${short_opatch_version}" = "11.2" -o "${short_opatch_version}" = "12.1" -o "${opatch_version}" = "12.2.0.1.13" ]; then
      opatchClassPath="$OUI_JARS:$BASE/jlib/oracle.opatch.classpath.jar:$BASE/auto/core/modules/features/oracle.glcm.oplan.core.classpath.jar:$BASE/auto/core/modules/features/oracle.glcm.osys.core.classpath.jar:$BASE/ocm/lib/emocmclnt.jar"
   # else, for opatch/fa, legacy oui
   else
      opatchClassPath="$OUI_JARS:$BASE/ocm/lib/emocmclnt.jar:$BASE/jlib/opatch.jar:$BASE/jlib/opatchsdk.jar:$BASE/oplan/jlib/automation.jar:$BASE/oplan/jlib/apache-commons/commons-cli-1.0.jar:$BASE/jlib/oracle.opatch.classpath.jar:$BASE/oplan/jlib/jaxb/activation.jar:$BASE/oplan/jlib/jaxb/jaxb-api.jar:$BASE/oplan/jlib/jaxb/jaxb-impl.jar:$BASE/oplan/jlib/jaxb/jsr173_1.0_api.jar:$BASE/oplan/jlib/OsysModel.jar:$BASE/oplan/jlib/osysmodel-utils.jar:$BASE/oplan/jlib/CRSProductDriver.jar:$BASE/oplan/jlib/oracle.oplan.classpath.jar"
   fi
   
}

setUpOPatchOPtions()
{
   if [ ! "$WL_HOME" = "" ]; then
      if [ -f "${WL_HOME}/server/lib/fusion_trust.jks" ]; then
         FUSION_TRUST_OPTION="-Dweblogic.security.SSL.trustedCAKeyStore=$WL_HOME/server/lib/fusion_trust.jks"
      fi
   fi
}

setUpUmask()
{
   umask 0022
}
printODPUsage()
{   
   echo "Usage: opatch odp <opatchPatchLocation>"
   echo "<opatchPatchLocation> should be patch zip or patch folder."

}
applyOPatchPatch()
{
   if [ -z $opatchPatchLoc ];then
      echo "Please specify patch location."
      printODPUsage
      exit 14
   fi
   
   propFile=$OH/OPatch/config/opatch.properties
   chmod 770 $propFile      
   if [ -f $opatchPatchLoc ] && [[ $opatchPatchLoc = *.zip ]];then
      unzip -jqo $opatchPatchLoc "opatchPatch/config/opatch.properties"  -d  "$OH/OPatch/config/"
      if [ ! $? = 0 ];then
         echo "Patch zip is not appropriate."
         printODPUsage
         exit 14
      fi
   elif [ -f "$opatchPatchLoc/config/opatch.properties" ];then
      cp "$opatchPatchLoc/config/opatch.properties" $propFile
   else
      echo "Patch location $opatchPatchLoc is not appropriate."
      printODPUsage
      exit 14
   fi
   chmod 440 $propFile
   echo "Patch applied Successfully."
}

callOPatch()
{
    
   if [ ! -z "$OPATCH_COMMAND" ] && [ "$OPATCH_COMMAND" = "odp" ]; then
      applyOPatchPatch
      exit $?
   fi 

   JAVA_AGENT_OPTION=""	

   # add this option because standonline jaxb jars in OPatch/modules use reflection, 
   # jdk9 prints out some warnings in UI, so add this option to deprecate the warnings
   if [ $JAVA_VERSION -ge 9 ]; then
        otherOpt="--illegal-access=deny"
        # jdk9+ needs javaagent to be passed for loading oui class	
	JAVA_AGENT_OPTION="-javaagent:${BASE}/jlib/oracle.opatch.classpath.jar"
   fi
   	 
   if [ "$JAVA_NOVERIFY" = "true" ]; then
        JAVA_VM_OPTION=$JAVA_VM_OPTION" -noverify"
   fi

   if [ "$DEBUGVAL" = "true" ]; then
      echo "$JAVA  $JAVA_AGENT_OPTION $otherOpt $JAVA_VM_OPTION $JRE_MEMORY_OPTIONS -cp $opatchClassPath -DOPatch.ORACLE_HOME=$OH -DOPatch.DEBUG=$DEBUGVAL -DOPatch.MAKE=$MAKEVAL -DOPatch.RUNNING_DIR=$BASE -DOPatch.MW_HOME=$MWH -DOPatch.WL_HOME=$WL_HOME -DOPatch.COMMON_COMPONENTS_HOME=$COMMON_COMPONENTS_HOME -DOPatch.OUI_LOCATION=$OUI_LOCATION -DOPatch.FMW_COMPONENT_HOME=$FMW_COMPONENT_HOME -DOPatch.OPATCH_CLASSPATH=$CLASSPATH -DOPatch.WEBLOGIC_CLASSPATH=$WEBLOGIC_CLASSPATH $FUSION_TRUST_OPTION -DOPatch.SKIP_OUI_VERSION_CHECK="$SKIP_OUI_VERSION_CHECK" -DOPatch.PARALLEL_ON_FMW_OH=$PARALLEL_ON_FMW_OH ${oracleOcmService} ${_bootClassPath} oracle/opatch/OPatch $args $invptr"
   fi
 
   $JAVA $JAVA_AGENT_OPTION $otherOpt $JAVA_VM_OPTION $JRE_MEMORY_OPTIONS -cp $opatchClassPath -DCommonLog.LOG_SESSION_ID="$LOG_SESSION_ID" -DCommonLog.COMMAND_NAME="$OPATCH_COMMAND" -DOPatch.ORACLE_HOME="$OH" -DOPatch.DEBUG="$DEBUGVAL" -DOPatch.MAKE="$MAKEVAL" -DOPatch.RUNNING_DIR="$BASE" -DOPatch.MW_HOME="$MWH" -DOPatch.WL_HOME="$WL_HOME" -DOPatch.COMMON_COMPONENTS_HOME="$COMMON_COMPONENTS_HOME" -DOPatch.OUI_LOCATION=$OUI_LOCATION -DOPatch.FMW_COMPONENT_HOME="$FMW_COMPONENT_HOME" -DOPatch.OPATCH_CLASSPATH="$CLASSPATH" -DOPatch.WEBLOGIC_CLASSPATH="$WEBLOGIC_CLASSPATH" -DOPatch.SKIP_OUI_VERSION_CHECK="$SKIP_OUI_VERSION_CHECK" -DOPatch.NEXTGEN_HOME_CHECK="$IS_NEXTGEN_HOME" -DOPatch.PARALLEL_ON_FMW_OH=$PARALLEL_ON_FMW_OH $FUSION_TRUST_OPTION ${oracleOcmService} ${_bootClassPath} oracle/opatch/OPatch $args $invptr
   RESULT=$?

   if [ -n "$CUSTOM_LOG_DIR" ]; then
      OOP_TEMP_FILE=$CUSTOM_LOG_DIR/opatch/oop_temp.out
   elif [ -n "$OH" ]; then
      OOP_TEMP_FILE=$OH/cfgtoollogs/opatch/oop_temp.out
   fi

   if [ -f "$OOP_TEMP_FILE" ]; then
   
       . $OOP_TEMP_FILE
       rm $OOP_TEMP_FILE

       if [ -n "$OOP_RESTART_CMD" ]; then
           exec $OOP_RESTART_CMD
       fi

   fi

   if [ $argCount -ge 1 ] && [ "$1" = "lspatches" ]; then
      exit ${RESULT}
   fi

   if [ $RESULT -ge  5 ] && [ $RESULT -le 7 ]; then
      echo
      echo "OPatch stopped on request."
      RESULT=0
   elif [ $RESULT -eq 8 ] ;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

   if [ -n "$OOP_TEMP_OH" -a -d "$OOP_TEMP_OH" ]; then 
      rm -rf $OOP_TEMP_OH
   fi
   if [ -n "$OOP_TEMP_JAVA" -a -d "$OOP_TEMP_JAVA" ]; then
      rm -rf $OOP_TEMP_JAVA
   fi

   exit ${RESULT}

}

#OPatch Script Main Entry
main()
{
  init $@

  opatchAutoDetect $args

  parseCommandLineOPtions $args

#  sourceOPatchEnv
  
  ocmOptionDetect
  
  setUpHomeDirs $0

  getLatestVersion

  setUpOUILocation
  
  setUpInvPtrLoc

  setUpJava

  setUpJREMemoryOPtions

  setUpLibraryPath

  setUpClassPath

  setUpOPatchOPtions

  setUpUmask

  callOPatch
}

main $@
