#!/bin/sh
# $Header: emll/bin/deployPackages /main/108 2012/12/01 13:48:08 fmorshed Exp $
#
# setupCCR
#
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 
#
#    NAME
#      deployPackages - OCM package deployment
#
#    DESCRIPTION
#      This script is invoked by the user to install the OCM software
#      packages or deinstall them.
#
#    EXIT CODES
#      0 - Success
#      1 - Prerequisite failure
#      2 - Invalid argument specified
#      3 - Invalid Usage
#      4 - Failed to obtain synchronization lock
#      5 - Corrupt install
#      6 - Missing command qualifier value.
#      7 - Not a directory.
#      11 - Unexpected Installation failure
#      12 - License Agreement declined
#      21 - OCM registration failure
#      22 - Registration key mismatch
#      81 - Package not supported.  
#      82 - Not an OCM package.
#      83 - A package deployment issue was encountered.
#      84 - No access to the specified package.
#      85 - Qualifiers -distribution and -staged_dir are mutually exclusive
#      86 - Invalid directory specified for the -staged_dir qualifier.
#
#   MODIFIED    (MM/DD/YY)
#    fmorshed   11/28/12 - Do not remove information from central properties
#                          file if the option is only -u.
#    fmorshed   10/01/12 - Support proxy server NTLM scheme in collector. Ship
#                          latest http_collector as well as old one and switch
#                          between them depending on version of Java
#    jsutton    08/06/12 - Extra arch check on Linux X64
#    fmorshed   04/26/12 - When deployPackages -d, also remove collector from central properties file
#    fmorshed   04/29/11 - Revert use of stat! This utility is not on all
#                          platforms (e.g. HP - UX).
#    jsutton    04/22/11 - allow for root user, e.g. 11.2 grid infra
#    fmorshed   04/22/11 - When comparing binHome to current directory, in order to check whether installation 
#                          is in the correct directory, compare the "stat" of the binHome against the
#                          stat of the current directory.  This is so that the comparison can be done when 
#                          that are links involved.
#    fmorshed   03/25/11 - deriveCCR no longer removes the config directory.
#                          Now, it defines an environment variable
#                          DERIVECCR_IN_PROGRESS to tell who ever is invoked by it that
#                          there is a deriveCCR in progress.
#--

# Constant declarations for exit values.
SUCCESS=0
ERR_PREREQ_FAILURE=1
ERR_INVALID_ARG=2
ERR_INVALID_USAGE=3
ERR_LOCK_FAILURE=4
ERR_CORRUPT_INSTALL=5
MISSING_QUALIFIER_VALUE=6
NOT_A_DIRECTORY=7
ERR_UNEXPECTED_FAILURE=11
ERR_LICENSE_DECLINED=12
ERR_REGISTRATION_FAILURE=21
ERR_KEY_MISMATCH=22
PKG_NOT_SUPPORTED=81
INVALID_OCM_PKG=82
PKG_DEPLOY_FAILURE=83
PKG_ACCESS_FAILURE=84
INVALID_QUALIFIER_COMBINATION=85
INVALID_DIRECTORY=86

#
# Reset the locale to ENGLISH for command line operations.
LC_ALL=C
export LC_ALL

#
# Constant exit codes
#
SUCCESS=0
ERR_PREREQ_FAILURE=1
ERR_INVALID_ARG=2
ERR_INVALID_USAGE=3

# Define the paths for /usr/bin. These are used in subsequent path
# specifications for native commands.
_binDir=/bin
_usrBinDir=/usr/bin
_usrLocalBinDir=/usr/local/bin

# Set the variables that map to explicit paths to prevent from trojan
# horse type attacks and allow for more consistent installation experience
# by eliminating the use of aliases.
BASENAME=${_binDir}/basename
CD=cd
CHMOD=${_binDir}/chmod
CP=${_binDir}/cp
DATE=${_binDir}/date
DIRNAME=${_usrBinDir}/dirname
ECHO=${_binDir}/echo
ID=${_usrBinDir}/id
LS=${_binDir}/ls
MKDIRP="${_binDir}/mkdir -p"
MKDIR=${_binDir}/mkdir
MV=${_binDir}/mv
MVF="$MV -f"
RM=${_binDir}/rm
RMF="$RM -f"
RMRF="$RM -rf"
TOUCH=${_binDir}/touch
TR=${_usrBinDir}/tr
SED=${_binDir}/sed

if [ -f ${_binDir}/cut ]
then
    CUT=${_binDir}/cut
elif [ -f ${_usrBinDir}/cut ]
then
    CUT=${_usrBinDir}/cut
fi

if [ -f ${_binDir}/uname ]
then
    UNAME=${_binDir}/uname
elif [ -f ${_usrBinDir}/uname ]
then
    UNAME=${_usrBinDir}/uname
fi

AWK=${_binDir}/awk
PLATFORM=`$UNAME | $CUT -f1`
if [ "$PLATFORM" = "SunOS" ]
then
    if [ -f ${_binDir}/nawk ]
    then
        AWK=${_binDir}/nawk
    elif [ -f ${_usrBinDir}/nawk ]
    then
        AWK=${_usrBinDir}/nawk
    fi
fi
PLATARCH=`$UNAME -m | $CUT -f1`

if [ -f ${_binDir}/egrep ]
then
    EGREP=${_binDir}/egrep
elif [ -f ${_usrBinDir}/egrep ]
then
    EGREP=${_usrBinDir}/egrep
fi

LOCKFILE=""
if [ -f ${_usrBinDir}/lockfile ]
then
    LOCKFILE=${_usrBinDir}/lockfile
elif [ -f ${_usrLocalBinDir}/lockfile ]
then
    LOCKFILE=${_usrLocalBinDir}/lockfile
fi

if [ "$PLATFORM" = "OSF1" ]
then
    if [ -z "${BIN_SH}" ]; then
        BIN_SH=xpg4
        export BIN_SH
        $0 "$@"
        exit $?
    fi
fi

ROOTCHAR=`$DIRNAME $0 | $CUT -b1`
if [ "${ROOTCHAR}" != "/" -a -z "${PWD}" ]
then
    $ECHO "The current shell is not supported for executing commands using relative paths."
    $ECHO "Either execute the command under the bash or ksh shells, or execute the "
    $ECHO "command using the absolute path."
    exit $ERR_PREREQ_FAILURE
fi

CWD=`pwd`

usage()
{
   cat <<EOF
Usage: $0 [-i <package-fs> | -d <package-fs> | -u <package-fs> | -l]

   where:

      -i <package-fs>     installs the package with the filespec specified.
      -d <package-fs>     deinstalls the package installed with the filespec
                          specified
      -u <package-fs>     updates the package with the filespec specified.
      -l                  list inventory

   If no options are specified, all pending deployment packages found in
   \$ORACLE_HOME/ccr/inventory/pending are installed.

EOF
}

determineJavaVersion()
{
    java_version=`${JAVA_HOME}/bin/java -version 2>&1`
    cmd_exit=$?
    java_version=`$ECHO $java_version | \
                  $EGREP 'java version' | $CUT -d'"' -f2 | $CUT -d'"' -f1`
    G_JAVA_MAJOR_VERSION=`$ECHO $java_version | $CUT -d'.' -f1`
    G_JAVA_MINOR_VERSION=`$ECHO $java_version | $CUT -d'.' -f2`
}
 
determineHttpClientClasspath()
{
    G_HTTP_CLIENT_CLASSPATH="${CCR_HOME}/lib/http_client_11116.jar" 
    if [ "$G_JAVA_MINOR_VERSION" = "2" -o \
         "$G_JAVA_MINOR_VERSION" = "3" -o \
         "$G_JAVA_MINOR_VERSION" = "4" -o \
         "$G_JAVA_MINOR_VERSION" = "5" ]
    then
        G_HTTP_CLIENT_CLASSPATH="${CCR_HOME}/lib/http_client_12.jar" 
    fi  
    export G_HTTP_CLIENT_CLASSPATH
}

#
# Check prerequisites
#
checkPrerequisites()
{
    if [ ! -z "${JAVA_HOME_CCR}" ]
    then
        _JAVA_HOME=${JAVA_HOME_CCR}
        _JAVA_BIN=${JAVA_HOME_CCR}/bin
        _javaLoc="The JAVA_HOME_CCR environment variable"
    elif [ ! -z "${JAVA_HOME}" ]
        then
            _JAVA_HOME=$JAVA_HOME
            _JAVA_BIN=${JAVA_HOME}/bin
            _javaLoc="JAVA_HOME"
        else
            _CCR_PARENT=`$DIRNAME ${CCR_HOME}`
            _JAVA_HOME=${_CCR_PARENT}/jdk
            _JAVA_BIN=${_JAVA_HOME}/bin
            _javaLoc="The ORACLE_HOME"
    fi

    # find jre home, if jdk home is not found
    if [ ! -f ${_JAVA_BIN}/java ]
    then
         _JAVA_HOME=${_CCR_PARENT}/jre
         _JAVA_BIN=${_JAVA_HOME}/bin
    fi

    if [ ! -f ${_JAVA_BIN}/java ]
    then
        $ECHO "${_javaLoc} does not contain java."
        $ECHO "${_javaLoc} is not a valid JDK/JRE directory."
        $ECHO "Redefine JAVA_HOME to refer to a JDK/JRE 1.2.2 or greater and invoke "
        $ECHO "  $ORACLE_HOME\ccr\bin\emSnapshotEnv."
        exit $ERR_PREREQ_FAILURE
    fi


    JAVA_HOME=${_JAVA_HOME}
    export JAVA_HOME
    determineJavaVersion
    
    if [ $cmd_exit -ne 0 -o \
         -z "${G_JAVA_MAJOR_VERSION}" -o \
         -z "${G_JAVA_MINOR_VERSION}" ]
    then
        $ECHO "${_javaLoc} does not contain a valid JDK/JRE."
        $ECHO "Redefine JAVA_HOME to refer to a JDK/JRE 1.2.2 or greater."
        exit $ERR_PREREQ_FAILURE
    fi

    if [ "$G_JAVA_MAJOR_VERSION" -ne "1" -o \
         "$G_JAVA_MINOR_VERSION" -eq "1" ]
    then
        $ECHO "Java version must be 1.2.2 or greater"
        $ECHO "Redefine JAVA_HOME to refer to a JDK/JRE 1.2.2 or greater."
        exit $ERR_PREREQ_FAILURE
    fi
}

# This function wraps the ERROR writing that needs to go to STDERR in a
# function for consistency. Requires the string be passed as a singular
# argument.
ERROR()
{
    $ECHO "$@" 1>&2
}

#
# Enables the shell signal handler. Due to inconsistencies in versions and
# shell implementations, we can't rely on ERR as a valid signal name. This
# is implemented in specific sh implementations that are platform version
# specific.
#
enableErrorHandler()
{
    set -e
    trap 'rollback' EXIT
}

#
# Disables the registered error handler
#
disableErrorHandler()
{
    set +e
    trap 0
}

setHostName()
{
  CCR_HOST_NAME=`hostname`

  export CCR_HOST_NAME
}

setOCMDirPaths()
{
  # Check whether its a shared OCM install
  if [ ${_sharedHomesSupported} -eq 0 ]
  then
    if [ -z "${ORACLE_CONFIG_HOME}" ]
    then
      CCR_CONFIG_HOME="${CCR_HOME}/hosts/${CCR_HOST_NAME}"
    elif [ -d ${ORACLE_CONFIG_HOME} ]
    then
      set +e
      _isRelative=`$ECHO ${ORACLE_CONFIG_HOME} | $EGREP -c '^/'`
      if [ ${_isRelative} -eq 0 ] ; then
        $ECHO '$ORACLE_CONFIG_HOME refers to a relative path.'
        $ECHO 'Redefine ORACLE_CONFIG_HOME to refer to an absolute path, or'
        $ECHO 'unset it if the configuration state is in the ccr directory tree.'
        exit $ERR_PREREQ_FAILURE
      set -e
      else
        # strip any trailing dirsep
        ORACLE_CONFIG_HOME=`$ECHO ${ORACLE_CONFIG_HOME} | $SED -e 's/\/*$//'`
        CCR_CONFIG_HOME="${ORACLE_CONFIG_HOME}/ccr"
      fi
    else
      $ECHO '$ORACLE_CONFIG_HOME should point to the directory containing OCM configurations for the host.'
      exit $ERR_PREREQ_FAILURE
    fi
  else
    CCR_CONFIG_HOME=${CCR_HOME}
  fi
  export CCR_CONFIG_HOME

  # Check to see whether OCM is primitarily configured.
  isOCMConfigured 1
  if [ $G_OCMConfigured -eq 0 ]; then
      $ECHO "OCM is not configured for this host or ORACLE_CONFIG_HOME. Please configure OCM first."
      exit $ERR_PREREQ_FAILURE
  fi
}

# Verify there is no mismatch between config and the user specified config location
configMatchesHome()
{
    if [ ${_sharedHomesSupported} -eq 0 ]; then
        _definedHomePath=""
        if [ -f ${CCR_CONFIG_HOME}/config/collector.properties ]; then
            _definedHomePath=`$EGREP '^ccr.binHome=' \
                                   ${CCR_CONFIG_HOME}/config/collector.properties | \
                                       $SED -e 's?^ccr.binHome=??'`
        fi

        if [ -z "${_definedHomePath}" -a \
             -f ${CCR_CONFIG_HOME}/config/default/collector.properties ]; then
            _definedHomePath=`$EGREP '^ccr.binHome=' \
                              ${CCR_CONFIG_HOME}/config/default/collector.properties | \
                                  $SED -e 's?^ccr.binHome=??'`
        fi

        if [ "${_definedHomePath}" != "${CCR_HOME}" ]; then
            # Before we error out, check another case for Solaris only
            # Check absolute paths, sh behaves differently on Solaris
            # sh sets pwd to canonical path, replacing all symlinks
            if [ "${PLATFORM}" = "SunOS" ]; then
                _definedHomePath_Abs=`cd $_definedHomePath && pwd -P`
                CCR_HOME_Abs=`cd $CCR_HOME && pwd -P`
            else
                _definedHomePath_Abs=${_definedHomePath}
                CCR_HOME_Abs=${CCR_HOME}
            fi

            if [ "${_definedHomePath_Abs}" != "${CCR_HOME_Abs}" ]; then
                $ECHO "Error: This OCM configuration location corresponds to the installation in "
                $ECHO "the directory: \"${_definedHomePath}\"."
                exit $ERR_PREREQ_FAILURE
            fi
        fi
    fi
}

#
# An error was encountered in the install phase of a package. Roll back
# to the previously installed version. The assumption is that _packageName
# is defined indicating the package that was being deployed.
#
rollback()
{
    if [ "${_rollback}" = "true" ]
    then
        return
    fi

    if [ ! -z "${_tmpDir}" ]
    then
        if [ -d ${_tmpDir} ]
        then
            $RMRF ${_tmpDir}
        fi
    fi

  # Check if package exists in $CCR_HOME/inventory
  # Disable the trap handler for ERR and EXIT functions 
  if [ "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
      set +e
      trap '' ERR
  else
      disableErrorHandler
  fi
  checkPkgDir ${_file}
  retCode=$?
  if [ "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
      set -e
      trap 'rollback' ERR
  else
      enableErrorHandler
  fi

  # bug 9460322. append diagcheck errors to the log file as well as to stdout
  if [ ! -z "${_diagcheckErrLog}" ];then
    if [ -f ${_diagcheckErrLog} ]; then
      cat ${_diagcheckErrLog} >> ${_log}
      cat ${_diagcheckErrLog}
    fi
  fi

  if [ ${retCode} -eq 0 ]; then
    # Package deployment from CCR_HOME/inventory.
    ERROR "Error encountered in package deployment." 
    
    ERROR "Check the contents of the deployment log - ${_log}"
    ERROR " "

    # force the uninstall of the new package. Note, this will
    # most likely yield errors as the installation failed and a full
    # deinstall will fail as the installation never completed.
    #
    # This is expected and just swallowed.
    $ECHO Deinstalling failed installation of ${_file} >> ${_log}
    uninstall ${_file} >> ${_log} 2>&1

    # Remove the bad kit. It will get downloaded via the collector
    # any way if there was no kit issue, but another resource issue.
    # Except in the case where this is an installation codepath problem.
    if [ -z "${CCR_INSTALL_CODEPATH}" ]
    then
        if [ -f ${_file} ]
        then
            $RMF ${_file}
        fi
    fi
    
    if [ -f ${CCR_HOME}/inventory/${_packageName}.jar ]
    then
        ERROR "Rolling back to previously installed version"
        $ECHO "Rolling back to previously installed version" >> ${_log}
        _rollback=true
        deploy ${CCR_HOME}/inventory/${_packageName}.jar 
        _rollback=false
    fi
  else
    # update components from external staged directory
    _fileName=`$BASENAME ${_file}`
    ERROR "Error encountered in deployment of ${_fileName}" 

    ERROR "Check the contents of the deployment log - ${_log}"
    ERROR " "

    # force the uninstall of the new package. Note, this will
    # most likely yield errors as the installation failed and a full
    # deinstall will fail as the installation never completed.
    #
    # This is expected and just swallowed.
    $ECHO Deinstalling failed installation of ${_file} >> ${_log}
    uninstall ${_file} >> ${_log} 2>&1

    if [ -f ${CCR_HOME}/inventory/${_packageName}.jar ]
    then
        ERROR "Rolling back to previously installed version"
        $ECHO "Rolling back to previously installed version" >> ${_log}
        _rollback=true
        deploy ${CCR_HOME}/inventory/${_packageName}.jar
        _rollback=false
    fi

  fi

  return $PKG_DEPLOY_FAILURE
}

#
# _packageName is already known and set at this point. This function is
# called to extract the currently installed package's uninstall.sh
# script and execute it to remove the previous instance.
#
uninstall()
{
    # Disable the trap handler for ERR and EXIT functions for the deinstall
    if [ "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
        set +e
        trap '' ERR
    else
        disableErrorHandler
    fi

    _installedPackage=$1
    _package=`$BASENAME ${_installedPackage} .jar`
    _deploymentTime=`$DATE +%m-%d-%Y_%H.%M.%S`
    
    # construct a log file if one was not previously defined. Such is the 
    # case if uninstall is called directly    
    if [ -z "${_log}" ]
    then
        _privateLog=1
        _log=${CCR_CONFIG_HOME}/log/uninstall_${_package}-${_deploymentTime}-$$.log
        if [ -f ${_log} ]
        then
            $RM ${_log}
        fi
    fi

    if [ -f ${_installedPackage} ]
    then
        # 
        # Create a temporary directory in TMP and unpack the uninstall 
        # procedure there.
        _tmpUninstallDir=${CCR_TEMP}/uninstall_${_package}-${_deploymentTime}-$$
        $ECHO Uninstalling ${_installedPackage} >> ${_log}
        $MKDIR ${_tmpUninstallDir} >> ${_log} 2>&1
        _installedPackage=`$ECHO ${_installedPackage} | $AWK -f $CCR_BIN/strip_path.awk PWD=$PWD`
        $CD ${_tmpUninstallDir} >> ${_log} 2>&1
        $JAR -xvf ${_installedPackage} uninstall.sh >> ${_log} 2>&1
        $CD $CWD >> ${_log} 2>&1

        if [ -z "${CCR_INTERNAL_CALL_FROM_UPDATEPACKAGE}" ]
        then
            ${CCR_HOME}/lib/emCCRCollector -silent "remove_from_central_props" 
        fi
        
        $CHMOD +x ${_tmpUninstallDir}/uninstall.sh >> ${_log} 2>&1
        $ECHO Uninstall script unpacked, executing the script >> ${_log}
        ${_sh_cmd} ${_tmpUninstallDir}/uninstall.sh >> ${_log} 2>&1
        
        $RMRF ${_tmpUninstallDir} >> ${_log} 2>&1
        $ECHO Uninstall complete >> ${_log}
    fi

    if [ -z "${CCR_INSTALL_DEBUG}" ]
    then
        if [ ! -z "${_privateLog}" ]
        then
            $RM ${_log}
        fi
        _privateLog=
    fi

    if [ "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
        set -e
        trap 'rollback' ERR
    else
        enableErrorHandler;
    fi
}

#
# Called to deploy the package, the _file variable passed in, indicating
# what should be deployed.
#
deploy() {
    # Disable any traps that may have been enabled.
    if [ "$PLATFORM" = "HP-UX" -o  "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
        set +e
        trap '' ERR
    else
        disableErrorHandler
    fi
 
    # 
    # Define some environmental variables that will be used within
    #
    _file=$1
 
    # Get absolute path of the package
    _file=`$ECHO ${_file} | $AWK -f ${CCR_BIN}/strip_path.awk PWD=$PWD`
 
    # Strip path information from package 
    _fileName=`$BASENAME ${_file}`
 
    # 
    # Return an if there was no such file to deploy
    if [ ! -f ${_file} ]
    then
        ERROR "There is no such package as ${_file} to deploy"
        exit $PKG_ACCESS_FAILURE
    fi
    
    _package=`$BASENAME ${_file} .jar`
    _packageDir=`$DIRNAME ${_file}`

    # Get package lock file name
    getPackageName ${_file}
    pkgName=${PACKAGE_NAME}

    _packageLkFile=${_packageDir}/${pkgName}.lk
    #
    # Check to see if the jar .lk file is present. If it is, remove it 
    # and the package, as it is incomplete.
    #
    if [ -f ${_packageLkFile} ]
    then
        $RMF ${_packageLkFile}
        $RMF ${_file}
        return $ERR_LOCK_FAILURE
    fi

    _deploymentTime=`$DATE +%m-%d-%Y_%H.%M.%S`
    _log=${CCR_CONFIG_HOME}/log/install-${_package}-${_deploymentTime}-$$.log
    _tmpDir=${CCR_TEMP}/${_package}-${_deploymentTime}-$$
   
    # If the log exists (it shouldn't due to the timestamp), but...
    # delete it.
    if [ -f ${_log} ]
    then
        $RM ${_log}
    fi
           
    # Determine if the temporary directory exists and if so, attempt to 
    # delete it. 
    if [ -d ${_tmpDir} ]
    then
        $RMRF ${_tmpDir}
        if [ $? -ne 0 ] 
        then
            ERROR "Previous installation detected and not able to remove."
            exit $PKG_DEPLOY_FAILURE
        fi
    fi

    # Register the trap for the error or exit
    if [ "${_rollback}" != "true" ]
    then
        if [  "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
            set -e
            trap 'rollback' ERR
        else
            enableErrorHandler
        fi
    fi
    
    # Unpack the kit into the temporary directory, creating the 
    # directory as we go.
    $MKDIRP ${_tmpDir} >> ${_log} 2>&1
    _file=`$ECHO ${_file} | $AWK -f $CCR_BIN/strip_path.awk PWD=$PWD`
    $CD ${_tmpDir} >> ${_log} 2>&1
    $JAR -xvf ${_file} >> ${_log} 2>&1
    $CD $CWD >> ${_log} 2>&1
    
    _packageName=`$EGREP 'package-name' ${_tmpDir}/META-INF/MANIFEST.MF | $TR -d '\r' | $CUT -f2 -d':' | $CUT -f2 -d' '`
    _packageVersion=`$EGREP 'package-version' ${_tmpDir}/META-INF/MANIFEST.MF | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2 -d' '`
    _packagePlatform=`$EGREP 'package-platform' ${_tmpDir}/META-INF/MANIFEST.MF|$TR -d '\r'|$CUT -f2 -d':'|$CUT -f2 -d' '`
    _packagePlatformLCase=`$ECHO ${_packagePlatform} | $TR "[A-Z]" "[a-z]"`
    _packageMetadataVer=`$EGREP 'package-metadata-version' ${_tmpDir}/META-INF/MANIFEST.MF | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2 -d' '`

    if [ "${_packagePlatform}" != "${PLATFORM}" -a "${_packagePlatformLCase}" != "generic" ]
    then
        ERROR "The kit being installed (${_fileName}) is not for this platform, but for ${_packagePlatform}."
        $ECHO "The kit being installed (${_fileName}) is not for this platform, but for ${_packagePlatform}." >> ${_log}
        if [ "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
            sh exit $PKG_NOT_SUPPORTED
        else
            exit $PKG_NOT_SUPPORTED
        fi
    fi

    # do architecture check ONLY if metadata version >= 1.2
    if [ "`$ECHO ${_packageMetadataVer} 1.2 | $AWK '{if ($1 < $2) print 0; else print 1}'`" = "1" ]
    then
      _packageArch=`$EGREP 'package-architecture' ${_tmpDir}/META-INF/MANIFEST.MF | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2 -d' '`
      _packageSuppArch=`$EGREP 'package-supported-arch' ${_tmpDir}/META-INF/MANIFEST.MF | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2- -d' '`
      _mappedArch=`$ECHO ${_packageSuppArch} | $AWK -v arch=${_osArch} -F, '{for(x=1;x<=NF;x++)if ($x==arch) {print 1; exit} print 0}'`
      # look for a match between os.arch and packageArch, or os.arch within mappedArch
      # skip the check if the platform specified is "generic" (case-blind check)
      if [ "${_packagePlatformLCase}" != "generic" -a "${_packageArch}" != "${_osArch}" ]
      then
        if [ "${_mappedArch}" = "0" ]
        then
          ERROR "The kit being installed (${_fileName}) is not supported on this architecture (${_osArch})."
          $ECHO "The kit being installed (${_fileName}) is not supported on this architecture (${_osArch})." >> ${_log}
          if [ "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
              sh exit $PKG_NOT_SUPPORTED
          else
              exit $PKG_NOT_SUPPORTED
          fi
        fi
      fi
    fi

    # Uninstall the previous kit
    if [ "${_rollback}" = "true" ]
    then
        # force the uninstall of the previous package. Note, this will
        # most likely yield errors as the installation failed and a full
        # deinstall will fail as the installation never completed.
        $ECHO Deinstalling failed installation of ${CCR_HOME}/inventory/pending/${_packageName}.jar >> ${_log}
        uninstall ${CCR_HOME}/inventory/pending/${_packageName}.jar >> ${_log} 2>&1
        $ECHO Rolling back ${_packageName} to version ${_packageVersion} >> ${_log}
    else
        $ECHO Deinstalling previously deployed version of installed package ${_packageName} >> ${_log}
        uninstall ${CCR_HOME}/inventory/${_packageName}.jar
        $ECHO "Deploying ${_packageName} - Version ${_packageVersion}"
    fi

    # Reset the protections of the shell scripts as JAR files do not 
    # retain file permissions.
    $CHMOD u+x ${_tmpDir}/install.sh     >> ${_log} 2>&1
    $CHMOD u+x ${_tmpDir}/postinstall.sh >> ${_log} 2>&1
    $CHMOD u+x ${_tmpDir}/config.sh      >> ${_log} 2>&1
    $CHMOD u+x ${_tmpDir}/uninstall.sh   >> ${_log} 2>&1
    
    # Execute the scripts in order. If there is a failure, then log the
    # error and terminate.
    $ECHO Executing package install script >> ${_log}
    ${_sh_cmd} ${_tmpDir}/install.sh     >> ${_log} 2>&1
    $ECHO Executing package postinstall script >> ${_log}
    ${_sh_cmd} ${_tmpDir}/postinstall.sh >> ${_log} 2>&1
    $ECHO Executing package config script >> ${_log}
    ${_sh_cmd} ${_tmpDir}/config.sh      >> ${_log} 2>&1
    # If the package is a diagcheck package, check whether there are
    # properties need to be configured
    if [ ! -z ${_packageName} -a ${_packageName} = "diagchecks" ]; then
        #Checking whether there are properties need to be configured
        _diagcheckErrLog=${_log}.diagcheck
        # redirect the error to the log file. do not redirect stdout since user
        # needs to see the "missing diagcheck properties" alert
        ${CCR_HOME}/lib/emCCRCollector diagchecks true 2> ${_diagcheckErrLog}
    fi
    $ECHO Completed with package installation >> ${_log}
    
    # Update the inventory of the now successfully deployed package 
    # as long as this was not a rollback.
    if [ ${_rollback} != "true" ]
    then
        if [ -f ${CCR_HOME}/inventory/${_packageName} ]
        then
            $RM ${CCR_HOME}/inventory/${_packageName} >> ${_log} 2>&1
        fi
   
        # Disable error handler
        if [ "$PLATFORM" = "HP-UX" -o  "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
            set +e
            trap '' ERR
        else
            disableErrorHandler
        fi

        # Check if package exists in $CCR_HOME/inventory
        checkPkgDir ${_file}
        retCode=$?

        # Enable error handler
        if [ "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
            set -e
            trap 'rollback' ERR
        else
            enableErrorHandler
        fi

        if [ $retCode -eq 0 ]
        then    
          # Move the package into the package directory as this will be used for
          # reinstall operations if needed
          $MVF ${_file} ${CCR_HOME}/inventory/${_packageName}.jar >> ${_log} 2>&1
        else
          # Copy the package from user-specified package directory.
          $CP ${_file} ${CCR_HOME}/inventory/${_packageName}.jar >> ${_log} 2>&1  
        fi
    fi

    # Clean up the temporary directory.
    $RMRF ${_tmpDir} >> ${_log} 2>&1
    
    # Remove the log file on successful completion
    if [ -z "${CCR_INSTALL_DEBUG}" ]
    then
        $RM ${_log}
    fi

    # De-register the trap handler for failures and exit
    if [ "$PLATFORM" = "HP-UX" -o  "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
        set +e
        trap '' ERR
    else
        disableErrorHandler
    fi
}

exitIfNotOwner()
{
    # Determine the owner of the CCR_HOME directory. This is not
    # foolproof, but will indicate the owner of the home.
    _UID=`$ID | $CUT -d'=' -f2 | $CUT -d'(' -f1`
    _CCR_OWNER=`$LS -Llnd $CCR_HOME |$AWK '{print $3}'`
    _ORACLE_HOME_OWNER=`$LS -Llnd $ORACLE_HOME |$AWK '{print $3}'`

    if [ ${_UID} -ne ${_CCR_OWNER} ]; then
      if [ ${_UID} -ne ${_ORACLE_HOME_OWNER} -o ${_UID} -ne 0 ]; then
        $ECHO "*****"
        $ECHO "Only the owner of the Oracle Configuration Manager installation "
        $ECHO "may deploy or query deployed software packages."
        $ECHO "*****"
        exit $ERR_PREREQ_FAILURE
      fi
    fi
}

#
# Check to see if this is a valid installation. There are other code paths that
# are meant to catch the un-registered conditions that arise here. Specifically
# upgrades and failure to re-register. Therefore, the registration can NEVER
# be a catestrophic return code here. The ONLY condition we can use is to
# verify the directory structure is in tact and the license agreement.
isOCMConfigured()
{
  G_OCMConfigured=0

  if [ -d ${CCR_CONFIG_HOME}/config -a -d ${CCR_CONFIG_HOME}/config/default -a \
       -d ${CCR_CONFIG_HOME}/state -a -d ${CCR_CONFIG_HOME}/state/diagnostic -a \
       -d ${CCR_CONFIG_HOME}/state/previous -a -d ${CCR_CONFIG_HOME}/state/review -a \
       -d ${CCR_CONFIG_HOME}/state/temp -a -d ${CCR_CONFIG_HOME}/state/upload -a \
       -d ${CCR_CONFIG_HOME}/log ] ; then

      # Get the property for the license signature
      getProperty ccr.agreement_signer collector.properties
      _acceptee=$_returnData
    
      if [ ! -z "${_acceptee}" ] ; then
        G_OCMConfigured=1
      else
        $ECHO "The Oracle Configuration Manager license agreement has not been accepted."
      fi
  else
     $ECHO "The Oracle Configuration Manager state/writeable directory structure is incomplete."
  fi
}

init()
{ 
    #
    # Determine the absolute path for the CCR location.
    #
    CCR_BIN=`$DIRNAME $0 | $TR -s '/'`
    # First remove './'s in the beginning
    CCR_BIN=`$ECHO $CCR_BIN | $AWK '{ if (match($0,/^(\.\/)*/)){ sub(/^(\.\/)*/,"",$0) }; print $0; }'`
    # Next replace all '/./'s in between with '/'
    CCR_BIN=`$ECHO $CCR_BIN | $AWK '{ if (match($0,/\/(\.\/)+/)){ gsub(/\/(\.\/)+/,"/",$0) }; print $0; }'`
    # Lastly remove '/.' at the end
    CCR_BIN=`$ECHO $CCR_BIN | $AWK '{ if (match($0,/\/\.$/)){ sub(/\/\.$/,"",$0) }; print $0; }'`
    # Now convert to absolute path
    CCR_BIN=`$ECHO $CCR_BIN | $AWK -f $CCR_BIN/strip_path.awk PWD=$PWD` 

    #
    # Enable debug support if CCR_INSTALL_DEBUG is defined.
    # 
    if [ -z "${CCR_INSTALL_DEBUG}" ] 
    then
        _sh_cmd="${_binDir}/sh -e"
    else
        _sh_cmd="${_binDir}/sh -ex"
    fi

    #
    # Now extract CCR_HOME
    #
    CCR_HOME=`$DIRNAME $CCR_BIN`

    #
    # Extract ORACLE_HOME
    #
    ORACLE_HOME=`$DIRNAME $CCR_HOME`
     
    #
    # Determine if Shared Oracle Home support is available. This is determined
    # thru the new directory 'hosts' under the CCR_HOME.
    #
    if [ -d "${CCR_HOME}/hosts" ]; then
        _sharedHomesSupported=0
    else
        _sharedHomesSupported=1
    fi

    if [ -z "${LOCKFILE}" ]; then
        LOCKFILE=$CCR_HOME/bin/lockfile
        # We now 'distribute' the lockfile script in the core package
        if [ ! -f $LOCKFILE ]; then
            $ECHO "Error: The Oracle Configuration Manager lockfile script is missing. Exiting..."
            exit $ERR_PREREQ_FAILURE
        fi
    fi

    # Exit if not the CCR_HOME owner
    exitIfNotOwner
    setHostName
    setOCMDirPaths

    # Check to insure the configuration matches the specified CCR_HOME. Use
    # emCCR as a validity check vs core.jar as emCCR will be present even in
    # the case where you want to uninstall in a first installation and the 
    # install failed for some reason and core was never moved to $OH/inventory.
    if [  -z "${DERIVECCR_IN_PROGRESS}" -a -f $CCR_HOME/bin/emCCR ]; then
        configMatchesHome
    fi

    # Exit if not the CCR_HOME owner
    # Source environment variable before setting any.
    # Source the user specified environment that is present in the CCR environment
    # snapshot file (maintained by emSnapshotEnv).
    if [ -f "${CCR_CONFIG_HOME}/config/emCCRenv" ]
    then
       . ${CCR_CONFIG_HOME}/config/emCCRenv
    fi

    # Expose the two environmental variables are per the specifications.
    #
    export CCR_HOME
    export ORACLE_HOME

    checkPrerequisites


    if [ ! -f ${_JAVA_HOME}/bin/java ]
    then
       ERROR "JAVA is not found for use in collecting configuration data."
       exit $ERR_PREREQ_FAILURE
    fi

    # Export JAVA_HOME and LD_PRELOAD
    JAVA_HOME=${_JAVA_HOME}
    export JAVA_HOME

    if [ ! -z "${LD_PRELOAD}" ]
    then
        export LD_PRELOAD
    fi
    
    #
    #Use jdk/jar if available, Otherwise use our util.
    #
    if [ -f ${JAVA_HOME}/bin/jar ]
    then
       JAR=${JAVA_HOME}/bin/jar
    else
       if [ -f ${CCR_HOME}/bin/ocmJarUtil ]
       then
          JAR=${CCR_HOME}/bin/ocmJarUtil
       else
          ERROR "OCM JAR Util is not found."
          exit $ERR_PREREQ_FAILURE
       fi
    fi
 
    JAVA=${JAVA_HOME}/bin/java

    $CD ${CCR_HOME}/lib
    if [ "$PLATFORM" = "Linux" ] && [ "$PLATARCH" = "x86_64" -o "$PLATARCH" = "amd64" ]
    then
      _osArch=$PLATARCH
    else
      _osArch=`$JAVA -cp ${G_HTTP_CLIENT_CLASSPATH}:${CCR_HOME}/lib/emocmcommon.jar:${CCR_HOME}/lib/emocmutl.jar:${CCR_HOME}/lib OsInfo`
    fi
    $CD $CWD

    #
    # Get the location of the temporary directory, defaulting to /tmp
    #
    if [ -z "${CCR_TEMP}" ]
    then
        CCR_TEMP=/tmp
        export CCR_TEMP
    fi

    #
    # If the log directory does not exist, create it as it will be needed
    # for the installation of the packages.
    #
    if [ ! -d ${CCR_CONFIG_HOME}/log ]
    then
        $MKDIRP ${CCR_CONFIG_HOME}/log
        $CHMOD 700 ${CCR_CONFIG_HOME}/log
    fi
     
    #
    # Create the base inventory tree if it is not present
    #
    if [ ! -d ${CCR_HOME}/inventory/pending ]
    then
        $MKDIRP ${CCR_HOME}/inventory/pending
        $CHMOD -R 0700 ${CCR_HOME}/inventory
    fi
}

#++
# 
# Extracts the Value for the property specified from the base configuration
# file. Value returned in the variable _returnData
# 
# The algorithm iterates thru all the files in precidence order, taking the
# first one present. Order is:
#     
#   (1) $CCR_CONFIG_HOME/config
#   (2) $CCR_CONFIG_HOME/config/default
#   (3) $CCR_HOME/config
#   (4) $CCR_HOME/config/default
#
# Args:
#    property-name, i.e. ccr.disconnected
#    config-basename, i.e. ccr.properties or collector.properties
#
#--
getProperty()
{
   _propertyName=$1
   _propertyFile=$2
   _returnData=""
      
   if [ -z "${_propertyFile}" -o -z "${_propertyName}" ]; then
       ERROR "INTERNAL ERR (getProperty()) - Missing arguments"
       exit $ERR_UNEXPECTED_FAILURE
   fi
   
   if [ -f ${CCR_CONFIG_HOME}/config/${_propertyFile} ]; then
       _returnData=`$EGREP "^$_propertyName=" ${CCR_CONFIG_HOME}/config/${_propertyFile} | \
                          $SED -e "s/$_propertyName=\s*//"`
   fi
   
   # check alternate properties files if we come up empty, just in case
   if [ -z "${_returnData}" ] ; then
      if [ -f ${CCR_CONFIG_HOME}/config/default/${_propertyFile} ] ; then
         _returnData=`$EGREP "^$_propertyName=" ${CCR_CONFIG_HOME}/config/default/${_propertyFile} | \
                      $SED -e "s/$_propertyName=\s*//"`
      fi
   fi
   if [ -z "${_returnData}" ] ; then
      if [ -f ${CCR_HOME}/config/${_propertyFile} ] ; then
         _returnData=`$EGREP "^$_propertyName=" ${CCR_HOME}/config/${_propertyFile} | \
                      $SED -e "s/$_propertyName=\s*//"`
      fi
   fi
   if [ -z "${_returnData}" ] ; then
      if [ -f ${CCR_HOME}/config/default/${_propertyFile} ] ; then
         _returnData=`$EGREP "^$_propertyName=" ${CCR_HOME}/config/default/${_propertyFile} | \
                      $SED -e "s/$_propertyName=\s*//"`
      fi
   fi
}

deployPackages()
{
    # Check if there are any packages to deploy/install.
    $LS ${CCR_HOME}/inventory/pending/*.jar > /dev/null 2>&1
 
    # If there is at least one file, iterate thru them all and deploy.
    if [ $? -eq 0 ]
    then
        _rollback="false"
        for _file in ${CCR_HOME}/inventory/pending/*.jar;
        do
            getPkgLock ${_file}
            _packageLock=${PACKAGE_LOCK}
            if [ -z "${_packageLock}" ]
            then
                ERROR "Unable to acquire deployment lock for ${_file}. Skipping deployment of the package."
                exit $ERR_LOCK_FAILURE 
            else
  
                # Invoke this same script but this time specifically
                # call out the package to deploy. This is done to
                # limit the failure of a package installation to just
                # the fail packaged and allow other packages available
                # for installation to be deployed.
                #
                # Only perform the installation if the package still exists - could 
                # have been removed before.
                if [ -f ${_file} ]
                then
                    if [ -n "${CCR_TIMESTAMP}" ] ; then
                        if [ ${CCR_TIMESTAMP} -eq 1 ] ; then
                            _curDate=`$DATE +%m-%d-%Y_%H:%M:%S`
                            _curFile=`$BASENAME ${_file}`
                            echo "Deploying ${_curFile} at ${_curDate}"
                        fi
                    fi
                    ${0} -i "${_file}"
                fi

                # Release the installation file lock.
                _tmpPkgLock=`$LS -l ${_packageLock} | $AWK '{print $NF}'`
                $RMF ${_packageLock}
                $RMF ${_tmpPkgLock}
            fi        
        done   
    fi
}

# This method obtains a lock for the given package and return the name
# of the actual lock file to the calling method.
getPkgLock()
{
  # Initialize the file name
  _file=$1

  getPackageName $_file
  pkgName=${PACKAGE_NAME}
  if [ -z "${pkgName}" ]; then
    PACKAGE_LOCK=""
  else 

    # Determine a lock name based upon the package bundle and create a
    # file lock resource to prevent two concurrent processing of the
    # same bundle.
    PACKAGE_LOCK=${CCR_HOME}/inventory/pending/${pkgName}.installLk

    # If the lock file exists, indicate that we are stalling for the package deployment
    # to complete.
    if [ -f ${PACKAGE_LOCK} ]
    then
      $ECHO "Stalling deployment waiting for the package to complete"
    fi
    $LOCKFILE -5 -r 60 -l 600 ${PACKAGE_LOCK} > /dev/null 2>&1
    if [ $? -ne 0 ]
    then
      PACKAGE_LOCK=""
    fi
  fi
}

#
# displays the package information to stdout
#
_displayPackaging()
{
    _package=$1
    
    _curDate=`$DATE +%m-%d-%Y_%H.%M.%S`
    _tmpDir=${CCR_TEMP}/inv-${_curDate}-$$
    _packageName=""
    _packageVersion=""
    _buildDate=""

    if [ -d ${_tmpDir} ]
    then
        ERROR "Temporary directory ${_tmpDir} exists"
        exit $ERR_PREREQ_FAILURE
    fi
    $MKDIRP ${_tmpDir}
    
    # 
    # Get the MANIFEST from the package and strip out the data that is
    # to be presented.
    $CD ${_tmpDir} > /dev/null 2>&1
    $JAR -xf ${_file} META-INF/MANIFEST.MF > /dev/null 2>&1
    $CD $CWD > /dev/null 2>&1
    _packageName=`$EGREP 'package-name' ${_tmpDir}/META-INF/MANIFEST.MF \
                       | $TR -d '\r' | $CUT -f2 -d':' | $CUT -f2 -d' '`
    _packageVersion=`$EGREP 'package-version' ${_tmpDir}/META-INF/MANIFEST.MF \
                       | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2 -d' '`
    _buildDate=`$EGREP 'package-date: ' ${_tmpDir}/META-INF/MANIFEST.MF \
                       | $TR -d '\r'`
                       
    # Get the buildDate, everything past the string 'package-date: '
    _buildDate=`$ECHO $_buildDate | $SED 's/package-date: //'`
    #_buildDate=${_buildDate:14}
                       
    $ECHO Package ${_packageName}, Version: ${_packageVersion} - built ${_buildDate}

    _packageMetadataVer=`$EGREP 'package-metadata-version' ${_tmpDir}/META-INF/MANIFEST.MF \
                         | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2 -d' '`
    # print architecture info ONLY if metadata version >= 1.2
    if [ "`$ECHO ${_packageMetadataVer} 1.2 | $AWK '{if ($1 < $2) print 0; else print 1}'`" = "1" ]
    then
      _packageArch=`$EGREP 'package-architecture' ${_tmpDir}/META-INF/MANIFEST.MF \
                    | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2 -d' '`
      _packageSuppArch=`$EGREP 'package-supported-arch' ${_tmpDir}/META-INF/MANIFEST.MF \
                        | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2- -d' '`

      if [ ! -z "${_packageSuppArch}" ]
      then
        _archInfo="    built on ${_packageArch}; also supported: ${_packageSuppArch}"
      else
        _archInfo="    built on ${_packageArch}"
      fi
      $ECHO "${_archInfo}"
    fi    
    # Remove the temporary files.
    $RMRF ${_tmpDir}
}

#
# Inventory displays the contents of the ${CCR_HOME}/inventory 
# package structure and displays the contents of the packages.
inventory()
{
    _file=""
    
    # Determine the packages that are deployed
    $LS ${CCR_HOME}/inventory/*.jar > /dev/null 2>&1
 
    # If there is at least one file, iterate thru them all and list the contents.
    if [ $? -eq 0 ]
    then
        $ECHO ""
        $ECHO Installed Oracle Configuration Manager Packages:
        $ECHO ===============================================
        for _file in ${CCR_HOME}/inventory/*.jar;
        do
            _displayPackaging ${_file}
        done
    fi

    # Determine the packages that are to be deployed
    $LS ${CCR_HOME}/inventory/pending/*.jar > /dev/null 2>&1
 
    # If there is at least one file, iterate thru them all and list the contents.
    if [ $? -eq 0 ]
    then
        $ECHO ""
        $ECHO Oracle Configuration Manager packages pending deployment:
        $ECHO ========================================================
        for _file in ${CCR_HOME}/inventory/pending/*.jar;
        do
            _displayPackaging ${_file}
        done
    fi
}

# This method takes a OCM jar name as an argument and finds the actual package
# name from it
getPackageName()
{
  _curDate=`$DATE +%m-%d-%Y_%H.%M.%S`
  _tmpDir=${CCR_TEMP}/info-${_curDate}-$$
  PACKAGE_NAME=""
    
  if [ -d ${_tmpDir} ]
  then
    # Remove the temporary files.
    $RMRF ${_tmpDir}
  fi

  $MKDIRP ${_tmpDir}
  
  # 
  # Get the MANIFEST from the package and strip out the data that is
  # to be presented.
  $CD ${_tmpDir} > /dev/null 2>&1 
  $JAR -xf $1 META-INF/MANIFEST.MF > /dev/null 2>&1
  $CD $CWD > /dev/null 2>&1

  # Check to make certain the MANIFEST file exists still.
  if [ ! -f ${_tmpDir}/META-INF/MANIFEST.MF ]; then
      if [ -f $1 ]; then
          ERROR "$1 is not a valid OCM package."
      fi
  else
      PACKAGE_NAME=`$EGREP 'package-name' ${_tmpDir}/META-INF/MANIFEST.MF \
                       | $TR -d '\r' | $CUT -f2 -d':' | $CUT -f2 -d' '`
  fi
         
  # Remove the temporary files.
  $RMRF ${_tmpDir}
}


# This method takes a OCM jar name as an argument and finds the package
# version from it
getPackageVersion()
{
  _curDate=`$DATE +%m-%d-%Y_%H.%M.%S`
  _tmpDir=${CCR_TEMP}/info-${_curDate}-$$
  PACKAGE_VERSION=""

  if [ -d ${_tmpDir} ]
  then
    # Remove the temporary files.
    $RMRF ${_tmpDir}
  fi

  $MKDIRP ${_tmpDir}

  # 
  # Get the MANIFEST from the package and strip out the data that is
  # to be presented.
  $CD ${_tmpDir} > /dev/null 2>&1
  $JAR -xf $1 META-INF/MANIFEST.MF > /dev/null 2>&1
  $CD $CWD > /dev/null 2>&1

  # Check to make certain the MANIFEST file exists still.
  if [ ! -f ${_tmpDir}/META-INF/MANIFEST.MF -a -f $1 ]; then
      ERROR "$1 is not a valid OCM package."
      PACKAGE_VERSION=""
  else
      PACKAGE_VERSION=`$EGREP 'package-version' ${_tmpDir}/META-INF/MANIFEST.MF \
                       | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2 -d' '`
  fi

  # Remove the temporary files.
  $RMRF ${_tmpDir}
}

# Check if package exists in $CCR_HOME/inventory. Return 0 if yes 
# otherwise non-zero.
# Params
# $1 - package name
checkPkgDir()
{
  # get absolute path
  _pkgDir=`$DIRNAME $1`

  # compare
  $ECHO $_pkgDir | $EGREP "^$CCR_HOME/inventory" > /dev/null 2>&1

  return $?

}

# This method is used for updating CCR components from user-specified 
# directory.
# Params
# $1 - package name
updatePackage()
{
  # Package to be deployed
  _file=$1

  # Get absolute path of the package
  _file=`$ECHO ${_file} | $AWK -f ${CCR_BIN}/strip_path.awk PWD=$PWD`

  # Check if package exists
  if [ ! -f ${_file} ]
  then
    ERROR "There is no such package as ${_file} to deploy"
    exit $PKG_ACCESS_FAILURE
  fi

  # Strip path information from _file
  _fileName=`$BASENAME ${_file}`
 
  # Check if package exists in $CCR_HOME/inventory
  checkPkgDir ${_file}
  retCode=$?

  if [ $retCode -eq 0 ]
  then
    ERROR "Invalid package directory. Cannot install package from $CCR_HOME/inventory."
    return $INVALID_DIRECTORY
  fi 

  # Check if package is readable
  if [ ! -r ${_file} ] 
  then
   ERROR "No read access to package ${_file}"
   exit $PKG_ACCESS_FAILURE
  fi

  # Get package name and version
  _curDate=`$DATE +%m-%d-%Y_%H.%M.%S`
  _tmpDir=${CCR_TEMP}/info-${_curDate}-$$
  _packageName=""
  _packageVersion=""

  if [ -d ${_tmpDir} ]
  then
    # Remove the temporary files.
    $RMRF ${_tmpDir}
  fi
  $MKDIRP ${_tmpDir}

  # 
  # Get the MANIFEST from the package and strip out the data that is
  # to be presented.
  $CD ${_tmpDir} > /dev/null 2>&1
  $JAR -xf ${_file} META-INF/MANIFEST.MF > /dev/null 2>&1
  $CD $CWD > /dev/null 2>&1

  # Check if its a valid jar
  if [ ! -f "${_tmpDir}/META-INF/MANIFEST.MF" ]; then
    ERROR "${_fileName} is not a valid OCM package."
    # Remove the temporary files.
    $RMRF ${_tmpDir}
    exit $INVALID_OCM_PKG
  fi

  _packageName=`$EGREP 'package-name' ${_tmpDir}/META-INF/MANIFEST.MF \
                     | $TR -d '\r' | $CUT -f2 -d':' | $CUT -f2 -d' '`
  _packageVersion=`$EGREP 'package-version' ${_tmpDir}/META-INF/MANIFEST.MF \
                     | $TR -d '\r' |$CUT -f2 -d':' | $CUT -f2 -d' '`
  # Remove the temporary files.
  $RMRF ${_tmpDir}

  # Get currently installed package version (if any)
  if [ -f  ${CCR_HOME}/inventory/${_packageName}.jar ]; then
    getPackageVersion ${CCR_HOME}/inventory/${_packageName}.jar
    _currentVersion=${PACKAGE_VERSION}
    compareVersion ${_packageVersion} ${_currentVersion}
    retCode=$?
    if [ $retCode -eq 1 -o $retCode -eq 0 ]; then
      # Currently installed packages are newer or of same version
      # No update needed.
      $ECHO "${_fileName} is an old package. No update required."    
      exit $SUCCESS
    fi
  fi
 
  # Get lock for package name
  _rollback="false"
  getPkgLock ${_file}
  _packageLock=${PACKAGE_LOCK}
  if [ -z "${_packageLock}" ]
  then 
    ERROR "Unable to acquire deployment lock for ${_fileName}. Skipping deployment of the package."
    exit $ERR_LOCK_FAILURE
  else
    # Invoke this same script but this time specifically
    # call out the package to deploy. This is done to
    # limit the failure of a package installation to just
    # the fail packaged and allow other packages available
    # for installation to be deployed.
    #
    # Only perform the installation if the package still exists - could 
    # have been removed before.
    _retCode=$SUCCESS
    if [ -f ${_file} ]
    then 
      if [ -n "${CCR_TIMESTAMP}" ] ; then
          if [ ${CCR_TIMESTAMP} -eq 1 ] ; then
              _curDate=`$DATE +%m-%d-%Y_%H:%M:%S`
              _curFile=`$BASENAME ${_file}`
              echo "Deploying ${_curFile} at ${_curDate}"
          fi
      fi
      CCR_INTERNAL_CALL_FROM_UPDATEPACKAGE="TRUE"
      export CCR_INTERNAL_CALL_FROM_UPDATEPACKAGE    
      ${0} -i "${_file}"
      _retCode=$?
    fi
    # Release the installation file lock.
    _tmpPkgLock=`$LS -l ${_packageLock} | $AWK '{print $NF}'`
    $RMF ${_packageLock}
    $RMF ${_tmpPkgLock}

    exit $_retCode
  fi


}


# Compare $1 with $2 and return following
#  1 if $1 < $2
#  0 if $1 = $2
#  2 if $1 > $2
compareVersion()
{
  # Extract individual versions from input params
  # We assume a five-part decimal number
  # If any given version number is not present then
  # its assumed to be zero.
  targetVersion=$1
  currentVersion=$2
  maxFields=5

  i=0
  j=1

  while [ "${i}" -lt "${maxFields}" ]
  do
    target=`$ECHO "$targetVersion" | sed 's/\([0-9]*\)[.]*\([0-9]*\)[.]*\([0-9]*\)[.]*\([0-9]*\)[.]*\([0-9]*\).*/\'${j}'/'`
    if [ -z "${target}" ]; then
      target=0
    fi

    current=`$ECHO "$currentVersion" | sed 's/\([0-9]*\)[.]*\([0-9]*\)[.]*\([0-9]*\)[.]*\([0-9]*\)[.]*\([0-9]*\).*/\'${j}'/'`
    if [ -z "${current}" ]; then
      current=0
    fi

   # compare each version
   if [ ${target} -gt ${current} ]; then
      return 2
    else
      if [ ${target} -lt ${current} ]; then
        return 1
      fi
    fi

    i=`expr $i + 1`
    j=`expr $j + 1`
  done

  return 0
}

main()
{
    init
 
    #
    # Accept the command line form for options
    getopts ":i:u:d:l" _option $@
    if [ $? -eq 0 ]
    then
        case "${_option}"
        in
            "i")    _rollback=false
                    deploy ${OPTARG};;
            "u")    _rollback=false
                    updatePackage ${OPTARG};;
            "d")    _rollback=false
                    uninstall ${OPTARG}
                    if [ "$PLATFORM" = "HP-UX" -o "$PLATFORM" = "AIX" -o "$PLATFORM" = "OSF1" ]; then
                        set +e
                        trap '' ERR
                    else
                        disableErrorHandler
                    fi;;
            "l")    inventory;;
            ":")    ERROR "Missing required argument for \"-${OPTARG}\""
                    ERROR ""
                    usage 1>&2
                    exit $MISSING_QUALIFIER_VALUE;;
              *)    ERROR "Invalid command qualifier \"${OPTARG}\""
                    ERROR ""
                    usage 1>&2
                    exit $ERR_INVALID_ARG;;
        esac
    else
        deployPackages
    fi
}

main $@
