#!/bin/sh
#
# $Header: opsm/cvutl/cvupackager.sbs /unix/1 2017/04/11 10:12:28 ptare Exp $
#
# cvupackager.sbs 
#
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
#
#    NAME
#      cvupackager.sbs - this is an utility script to prepare and package 
#                        cvupack.zip on top of the release shiphome bits.
#
#    DESCRIPTION
#      An utility script to package standalone cvupack.zip based on the
#      RAC released software bits. 
#
#    NOTES
#      Currently this utility is supported only on UNIX platforms. 
#
#    MODIFIED   (MM/DD/YY)
#    ptare       01/24/17 - check the reverse path filter rp_filter for NICS on
#                           LINUX
#    ptare       01/24/17 - Creation
#

SECHO="/bin/echo -e"
SGREP="/bin/grep"
SAWK="/bin/awk"
SSED="/bin/sed"
SCOPY="/bin/cp"
SRM="/bin/rm"
SCAT="/bin/cat"

_HOST=`/bin/hostname`

PLATFORM=`/bin/uname`
case $PLATFORM in
  Linux)
    ZIP_UTIL_PATH="/usr/bin/zip"
  ;;
  SunOS)
    ZIP_UTIL_PATH="/usr/local/bin/zip"
    SAWK="/usr/xpg4/bin/awk"
  ;;
  AIX)
      ZIP_UTIL_PATH="/usr/bin/zip"
  ;;
  HP-UX)
      ZIP_UTIL_PATH="/usr/local/bin/zip"
  ;;
esac

ZIP_DIR_NAME="._CV_TARGET_AREA"
CVUPACK_ZIP_PATH=
SHIPHOME_LOC=
MANIFEST_FILE_PATH=
SEARCH_RESULT=
WARNING_TEXT="\e[33mWARNING:: \e[39m"
PROGRESS_TEXT="\e[32mPROGRESS:: \e[39m"
ERROR_TEXT="\e[31mERROR:: \e[39m"

#Function to prepare and package the cvupack.zip file.
prepareAndZip()
{
  #Process each line of the manifest file at once
  while IFS='' read -r line || [[ -n "$line" ]]; do
    if [ -e "$SHIPHOME_LOC/$line" ]; then
      if [ -d "$SHIPHOME_LOC/$line" ]; then
        mkdir -p "$STAGE_AREA/$line"
        if [ $? -ne 0 ]; then
          reportFailureAndExit "Failed to create the directory "$STAGE_AREA/$line"" "<NLS_MSG><FACILITY>Prve</FACILITY><ID>0006</ID><MSG_DATA><DATA>$STAGE_AREA/$line</DATA></MSG_DATA></NLS_MSG>"
        fi
      else
        $SCOPY "$SHIPHOME_LOC/$line" "$STAGE_AREA/$line"
        if [ $? -ne 0 ]; then
          reportFailureAndExit "Failed to copy the file from "$SHIPHOME_LOC/$line" to "$STAGE_AREA/$line"" "<NLS_MSG><FACILITY>Prvf</FACILITY><ID>7709</ID><MSG_DATA><DATA>$SHIPHOME_LOC/$line</DATA><DATA>$STAGE_AREA/$line</DATA><DATA>$_HOST</DATA></MSG_DATA></NLS_MSG>"
        fi
      fi
    else
      #The file does not exists at the same location in shiphome. Attempt to search for the file
      findFile $SHIPHOME_LOC $line;
      if [ "X$SEARCH_RESULT" != "X" ]; then
        if [ -d "$SEARCH_RESULT" ]; then
          if [ ! -e "$line" ]; then
            mkdir -p "$STAGE_AREA/$line" 
            if [ $? -ne 0 ]; then
              reportFailureAndExit "Failed to create the directory "$STAGE_AREA/$line"" "<NLS_MSG><FACILITY>Prve</FACILITY><ID>0006</ID><MSG_DATA><DATA>$STAGE_AREA/$line</DATA></MSG_DATA></NLS_MSG>"
            fi
          fi
        else
          parentDir="$(dirname "$line")"
          parentDir="$STAGE_AREA/$parentDir"
          if [ ! -e "$parentDir" ]; then
            mkdir -p "$parentDir"
            if [ $? -ne 0 ]; then
              reportFailureAndExit "Failed to create the directory "$parentDir"" "<NLS_MSG><FACILITY>Prve</FACILITY><ID>0006</ID><MSG_DATA><DATA>$parentDir</DATA></MSG_DATA></NLS_MSG>"
            fi
          fi
          $SCOPY "$SEARCH_RESULT" "$STAGE_AREA/$line" 
          if [ $? -ne 0 ]; then
            reportFailureAndExit "Failed to copy the file from "$SEARCH_RESULT" to "$STAGE_AREA/$line"" "<NLS_MSG><FACILITY>Prvf</FACILITY><ID>7709</ID><MSG_DATA><DATA>$SEARCH_RESULT</DATA><DATA>$STAGE_AREA/$line</DATA><DATA>$_HOST</DATA></MSG_DATA></NLS_MSG>"
          fi
        fi
      else
        displayWarning "Skipping \"$line\" ...."
      fi
    fi
  done < "$MANIFEST_FILE_PATH"
  displayProgress "Packaging $CVUPACK_ZIP_PATH ...."
  cd $STAGE_AREA
  ZIP_OUTPUT=`$ZIP_UTIL_PATH -r $CVUPACK_ZIP_PATH .`
  ret=$?
  $SECHO $ZIP_OUTPUT >> $LOG_FILE_PATH
  if [ $ret -ne 0 ]; then
    reportFailureAndExit "Failed to zip the content of directory "$STAGE_AREA" into "$CVUPACK_ZIP_PATH". Look at "$LOG_FILE_PATH" for more details." "<NLS_MSG><FACILITY>Prvg</FACILITY><ID>0740</ID><MSG_DATA><DATA>$STAGE_AREA</DATA><DATA>$CVUPACK_ZIP_PATH</DATA><DATA>$ZIP_UTIL_PATH</DATA><DATA>$ZIP_OUTPUT</DATA></MSG_DATA></NLS_MSG>"
  else
    displayProgress "Successfully created the "$CVUPACK_ZIP_PATH"" 
  fi
  $SRM -rf "$STAGE_AREA" 
  if [ $?  -ne 0 ]; then
    displayWarning "The "$CVUPACK_ZIP_PATH" was created successfully but failed to clean up the directory "$STAGE_AREA".please remove the directory manually."
  fi

}

#Function to search given file inside the give directory
findFile()
{
  SEARCH_RESULT=
  FILE_NAME=$(basename "$2")
  if [ "$FILE_NAME" = "cluvfy" ]; then
    SEARCH_RESULT=`find $1 -name $FILE_NAME -print 2>/dev/null | $SGREP $FILE_NAME | head -n 1`
    if [ "X$SEARCH_RESULT" = "X" ]; then
      FILE_NAME=$FILE_NAME".sbs"
      SEARCH_RESULT=`find $1 -name $FILE_NAME -print 2>/dev/null | $SGREP $FILE_NAME | head -n 1`
    fi 
  else
    SEARCH_RESULT=`find $1 -name $FILE_NAME -print 2>/dev/null | $SGREP $FILE_NAME | head -n 1`
  fi
}

#function to report an error and exit
reportFailureAndExit()
{
  if [ "$NLS_REPORT" = "TRUE" ]; then
    $SECHO "$2"
  else
    $SECHO "$ERROR_TEXT $1"
  fi
  exit 1;
}

diplayUsageAndExit()
{
  $SECHO "Usage:"
  $SECHO "$0 <SHIPHOME_DIR> <CVUPACK_MAIFEST_FILE_PATH> <OUTPUT_ZIP_FILE_PATH> [ZIP_TOOL_LOCATION] [-nls]"
  exit 1;
}

displayProgress()
{
  if [ "$NLS_REPORT" = "FALSE" ]; then
    $SECHO  "$PROGRESS_TEXT $1"
  fi
}

displayWarning()
{
  if [ "$NLS_REPORT" = "FALSE" ]; then
    $SECHO  "$WARNING_TEXT $1"
  fi
  #Ensure to log the warning.
  $SECHO "$1" >> $LOG_FILE_PATH
}

if [ "$#" -eq 5 ] || [ "$#" -eq 4 ] || [ "$#" -eq 3 ]; then
  SHIPHOME_LOC=$1
  MANIFEST_FILE_PATH=$2
  CVUPACK_ZIP_PATH=$3
  NLS_REPORT="FALSE"
  LOG_FILE_PATH="$CVUPACK_ZIP_PATH".log""

  #Check if >4 arguments then if the 4th arg is -nls
  if [ "$#" -ge 4 ]; then
    if [ "$#" -eq 4 ]; then
      if [ "$4" = "-nls" ]; then
        NLS_REPORT="TRUE"
      else
        ZIP_UTIL_PATH=$4
      fi
    elif [ "$#" -eq 5 ]; then
      if [ "$5" = "-nls" ]; then
        NLS_REPORT="TRUE"
        ZIP_UTIL_PATH=$4
      else
        diplayUsageAndExit $0
      fi
    else
      diplayUsageAndExit $0
    fi
  fi
 
  displayProgress "Preparing "$CVUPACK_ZIP_PATH" using manifest file $MANIFEST_FILE_PATH based on the shiphome location $SHIPHOME_LOC."
  #Clean up the previous log files if any
  if [ -e "$LOG_FILE_PATH" ]; then
    $SRM $LOG_FILE_PATH 
    if [ $?  -ne 0 ]; then
      displayWarning "Failed to remove existing "$LOG_FILE_PATH" ...."
    fi
  fi

 
  OUTPUT_DIR="$(dirname "$CVUPACK_ZIP_PATH")"

  if [ ! -d "$OUTPUT_DIR" ] || [ ! -w  $OUTPUT_DIR ]; then
    reportFailureAndExit "Output directory ($OUTPUT_DIR) does not exist or is not writable. Please specify existing writable output directory." "<NLS_MSG><FACILITY>Prvg</FACILITY><ID>0100</ID><MSG_DATA><DATA>$OUTPUT_DIR</DATA><DATA>$_HOST</DATA></MSG_DATA></NLS_MSG>"
  fi
 
  if [ ! -d "$SHIPHOME_LOC" ]; then
    reportFailureAndExit "Shiphome location ($SHIPHOME_LOC) either does not exist or is not readable. Please specify readable shiphome location." "<NLS_MSG><FACILITY>Prvg</FACILITY><ID>0101</ID><MSG_DATA><DATA>$SHIPHOME_LOC</DATA><DATA>$_HOST</DATA></MSG_DATA></NLS_MSG>"
  fi

  #Clean up if there exists a cvupack.zip already
  if [ -e "$CVUPACK_ZIP_PATH" ]; then
    $SRM $CVUPACK_ZIP_PATH 
    if [ $? -ne 0 ]; then
      reportFailureAndExit "Failed to remove existing "$CVUPACK_ZIP_PATH" ...." "<NLS_MSG><FACILITY>Prvg</FACILITY><ID>0103</ID><MSG_DATA><DATA>$CVUPACK_ZIP_PATH</DATA><DATA>$_HOST</DATA></MSG_DATA></NLS_MSG>"
    fi
  fi

  #Create the temp directory under the target directory.
   STAGE_AREA="$OUTPUT_DIR/$ZIP_DIR_NAME"
  if [ -e "$STAGE_AREA" ]; then
    displayProgress "Stage directory $STAGE_AREA already exists.Cleaning up...."
    $SRM -rf "$STAGE_AREA" 
    if [ $? -ne 0 ]; then
      reportFailureAndExit "Failed to clean-up the existing staging directory "$STAGE_AREA"" "<NLS_MSG><FACILITY>Prvg</FACILITY><ID>0102</ID><MSG_DATA><DATA>$STAGE_AREA</DATA><DATA>$_HOST</DATA></MSG_DATA></NLS_MSG>"
    fi
  fi
  #Attempt to create the new staging area
  mkdir -p "$STAGE_AREA"
  if [ $? -ne 0 ]; then
    reportFailureAndExit "Failed to create the staging directory at location "$STAGE_AREA"" "<NLS_MSG><FACILITY>Prve</FACILITY><ID>0006</ID><MSG_DATA><DATA>$STAGE_AREA</DATA></MSG_DATA></NLS_MSG>"
  fi
  
  #Finally prepare the staging area as requried and zip the cvupack.zip
  prepareAndZip;

else
  diplayUsageAndExit $0
fi

