#!/bin/sh

trap 'echo "Patch installation aborted!";$UNDO;exit 1' 1 2 3 15
#    
case $ORACLE_TRACE in
    T)  set -x ;;
esac

SAVE_SUFFIX='pre1371144'

LIBS_OBJECTS="lib/libserver8.a:ksl.o"

LIBSQLNET_OBJS=""

#Parse library list from LIBS_OBJECTS
for entry in $LIBS_OBJECTS; do
    MANDATORY_LIBS="$MANDATORY_LIBS `echo $entry|awk -F: '{print $1}'`"
done

MAKE_TRIPLETS="rdbms/lib:ins_rdbms.mk:ioracle"

MANDATORY_FILES=""

NEW_FILES=""

OPTIONAL_FILES=""

EXECUTABLES="bin/oracle"

SHUTDOWN=true

PATCH_HOME=`pwd`

#File where instructions to undo the patch are stored
UNDO=$PATCH_HOME/undo_$SAVE_SUFFIX.sh

#Create $UNDO file empty and with correct protections.
rm -f $UNDO
echo "#!/bin/sh" > $UNDO
CHMOD=/usr/bin/chmod
$CHMOD 744 $UNDO

if [ -z "$NO_MAKE" ]; then
    DO_MAKE=true
else
    DO_MAKE=false
fi

clear
ALL_FILES="$MANDATORY_FILES $OPTIONAL_FILES $NEW_FILES"
ABORTFLAG=false;     
     
# Check to see if all the necessary files and libraries exist.

for FILE in $MANDATORY_FILES $MANDATORY_LIBS; do
    if  [ ! -f $ORACLE_HOME/$FILE -o  ! -w $ORACLE_HOME/$FILE ];then
        echo  ">>> File $ORACLE_HOME/$FILE is missing or not writable"
        ABORTFLAG=true;
    fi
done

if $ABORTFLAG; then
    echo '
         Patch can not be installed. 
         One or more files are missing or not writeable'
    exit 1
fi

size=0
sizeall=0
sizetmp=0
maxlib=0
#Calculate space requirements in $ORACLE_HOME
for FILE in $MANDATORY_LIBS; do
    sizelib=`/bin/ls -l $ORACLE_HOME/$FILE|
           /usr/bin/awk '{printf "%d",$5/1024/1024*2}'`
    # round up
    if [ $sizeexe = '0' ]; then
       sizeexe=1
    fi
    if [ $sizelib -gt $maxlib ];then
        maxlib=$sizelib
    fi
done
sizeall=$maxlib

#Get current TMPDIR
if [ -z "$TMPDIR" ]; then
    TMPDIR=$ORACLE_HOME/lib; export TMPDIR
    echo "Using $TMPDIR as temporary working directory"
fi

#Calculate space requirements in $ORACLE_HOME and $TMPDIR
for FILE in $EXECUTABLES; do
    sizeexe=`/bin/ls -l $ORACLE_HOME/$FILE|
           /usr/bin/awk '{printf "%d",$5/1024/1024}'`
    # round up
    if [ $sizeexe = '0' ]; then
       sizeexe=1
    fi
    sizeall=`expr $sizeexe \* 2 + $sizeall`
    if [ $sizeexe -gt $sizetmp ]; then
        sizetmp=$sizeexe
    fi
done

echo "
    This procedure assumes that:
        - Your current working directory is $PATCH_HOME where 
          you have read this patch.
        - You have at least $sizeall Mb available in the $ORACLE_HOME filesystem. "

$DO_MAKE && echo "        - You have at least $sizetmp Mb available in $TMPDIR filesystem "

$SHUTDOWN && echo "        - You have shutdown all databases before running this script."

echo "        - YOU WILL NOT INTERRUPT THIS PROCEDURE!
Are you ready to continue? [N] => \c"

read YN
echo "
     "

if [ "$YN" != 'Y' -a "$YN" != 'y' ];then
    echo 'Patch installation aborted'
    exit 1
fi

#Make sure we do not produce non writable new files
umask 022
#
#Verify that no database is running
#
if $SHUTDOWN; then
    sga=`/bin/ls $ORACLE_HOME/dbs/sgadef* 2>/dev/null`
    if [ ! -z "$sga" ]; then
        echo 'Seems that some databases in $ORACLE_HOME are active'
        echo 'Patch installation aborted'
        echo Found file: $sga
        exit 1
    fi
fi

#Verify that the required space in $ORACLE_HOME is available
freedisk=`/bin/df -Pk $ORACLE_HOME | sed '1d' | 
          /usr/bin/awk '{printf "%d",$2/1024}'`
if [ $freedisk -lt $sizeall ]; then
    echo "Not enough free space found in $ORACLE_HOME"
    echo "Needed: $sizeall, found: $freedisk"
    exit 1
fi

if $DO_MAKE; then
#Verify that the required temporary space in $TMPDIR is available
    freedisk=`/bin/df -Pk $TMPDIR | sed '1d' | 
              /usr/bin/awk '{printf "%d",$2/1024}'`
    if [ $freedisk -lt $sizetmp ]; then
        echo "Not enough free space found in $TMPDIR"
        echo "Needed: $sizetmp, found: $freedisk"
        exit 1
    fi
fi

# save all files that we will update/replace

echo "*** Starting saving original files"
for FILE in $ALL_FILES; do
    if [ ! -f $ORACLE_HOME/$FILE$SAVE_SUFFIX -a -f $ORACLE_HOME/$FILE ];then
        echodo mv $ORACLE_HOME/$FILE $ORACLE_HOME/$FILE$SAVE_SUFFIX
        echodo cp $ORACLE_HOME/$FILE$SAVE_SUFFIX $ORACLE_HOME/$FILE
        echo "echodo mv  $ORACLE_HOME/$FILE$SAVE_SUFFIX $ORACLE_HOME/$FILE" >> $UNDO
    fi
done

cd $ORACLE_HOME/lib
echo "cd $ORACLE_HOME/lib" >> $UNDO
for pair in $LIBS_OBJECTS; do
    lib=`echo $pair|awk -F: '{print $1}'`
    OBJECTS=`echo $pair|sed "s?$lib:??"|sed 's/,/ /g'`
    for object in $OBJECTS; do
        if [ -f $object ]; then
            echo "Unexpectedly found $object in $ORACLE_HOME/lib"
            echo "Renaming it to: $object${SAVE_SUFFIX}.dup"
            echodo mv $object $object${SAVE_SUFFIX}.dup
        fi
    done
    echodo ar xl $ORACLE_HOME/$lib $OBJECTS
    for object in $OBJECTS; do
        if [ ! -f $object$SAVE_SUFFIX ];then
            echodo mv $object $object$SAVE_SUFFIX
        fi
        echo "echodo mv -f $object$SAVE_SUFFIX $object" >> $UNDO
        echodo cp -pf $PATCH_HOME/$object .
    done
done
echo "%%% Finished saving original files
     "

if [ ! -z "$LIBS_OBJECTS" ]; then
# objects are now archived into their libraries 
    echo "*** Starting archiving new objects"
    for pair in $LIBSQLNET_OBJS $LIBS_OBJECTS; do
        lib=`echo $pair|awk -F: '{print $1}'`
        objects=`echo $pair|sed "s?$lib:??"|sed 's/,/ /g'`
        echo "- Making backup copy of library for error recovery"
        if echodo cp -pf $ORACLE_HOME/$lib $ORACLE_HOME/$lib$SAVE_SUFFIX; then
            if echodo ar crl $ORACLE_HOME/$lib $objects; then
                echo "- Remove backup copy, not needed anymore"
                echodo rm -f $ORACLE_HOME/$lib$SAVE_SUFFIX
                echo "echodo ar crl $ORACLE_HOME/$lib $objects" >> $UNDO
		if [ ! "$lib" = "lib/libsqlnet.a" ] ; then
                    rm -f $objects
                    echo "echodo rm -f $objects" >> $UNDO
		fi
                for object in $objects; do
                    if [ -f $object${SAVE_SUFFIX}.dup ]; then
                        echo "echodo mv $object${SAVE_SUFFIX}.dup $object" >> $UNDO
                    fi
                done
            else
                echo "Errors ocurred during archiving"
                echo "Deinstalling patch..."
                echo "echodo mv $ORACLE_HOME/$lib$SAVE_SUFFIX $ORACLE_HOME/$lib" >> $UNDO
                echo "echodo rm -f $objects" >> $UNDO
                $UNDO
                echo "Fix error and try again"
                exit 1
            fi
        else
            echo "Error making backup copy of $lib"
            echo "Deinstalling patch..."
            $UNDO
            echo "Fix error and try again"
            exit 1
        fi
    done
    echo "%%% Finished archiving new objects
         "
fi

#Copy mandatory files
if [ ! -z "$MANDATORY_FILES" ]; then
    echo "*** Starting copying mandatory files"
    for FILE in $MANDATORY_FILES; do
        echodo cp $PATCH_HOME/`basename $FILE` $ORACLE_HOME/$FILE
    done
    echo "%%%Finished copying mandatory files
         "
fi

#Copy optional files (if they exist)
if [ ! -z "$OPTIONAL_FILES" ]; then
    echo "*** Starting copying optional files"
    for FILE in $OPTIONAL_FILES; do 
        if [ -f $ORACLE_HOME/$FILE -a -w $ORACLE_HOME/$FILE ];then
            echodo cp $PATCH_HOME/`basename $FILE` $ORACLE_HOME/$FILE
        fi
    done   
    echo "%%% Finished copying optional files
         "
fi

#Copy new files
if [ ! -z "$NEW_FILES" ]; then
    echo "*** Starting copying new files"
    for FILE in $NEW_FILES; do 
        echodo cp $PATCH_HOME/`basename $FILE` $ORACLE_HOME/$FILE
    done   
    echo "%%% Finished copying new files
         "
fi

#Relink executables
if $DO_MAKE  && [ ! -z "$MAKE_TRIPLETS" ]; then
    echo "*** Starting relinking of new executables"
    for triplet in $MAKE_TRIPLETS; do
        directory=`echo $triplet|awk -F: '{print $1}'`
        makefile=`echo $triplet|awk -F: '{print $2}'`
        target=`echo $triplet|awk -F: '{print $3}'`
        cd $ORACLE_HOME/$directory
        if echodo make -f $makefile $target; then
            echo "cd $ORACLE_HOME/$directory 
                  echodo make -f $makefile $target" >> $UNDO
        else
            echo "Errors ocurred during relink of $target"
            echo "Deinstalling patch..."
            $UNDO
            echo "Fix error and try again"
            exit 1
        fi
    done
    echo "%%% Done relinking new executables
         "
    echo "Patch applied succesfully."
    echo "Patch can be deinstalled by using $UNDO script"
else
    if [ ! -z "$MAKE_TRIPLETS" ]; then
        echo "You choose not to relink the executable"
        echo "Please perform the following commands to finish applying the patch:"
        for triplet in $MAKE_TRIPLETS; do
            directory=`echo $triplet|awk -F: '{print $1}'`
            makefile=`echo $triplet|awk -F: '{print $2}'`
            target=`echo $triplet|awk -F: '{print $3}'`
            echo "cd $ORACLE_HOME/$directory; make -f $makefile $target"
        done
        echo "Be sure to have at least $sizetmp in your TMPDIR at relink time"
    fi
fi

