#!/bin/sh
#
# $Id: dbshut.sh 22-may-2008.05:19:31 arogers Exp $
# Copyright (c) 1991, 2008, Oracle. All rights reserved.  
#

###################################
# 
# usage: dbshut $ORACLE_HOME
#
# This script is used to shutdown ORACLE from /etc/rc(.local).
# It should ONLY be executed as part of the system boot procedure.
#
# This script will shutdown all databases listed in the oratab file
# whose third field is a "Y" or "W".  If the third field is set to "Y" and
# there is no ORACLE_SID for an entry (the first field is a *),
# then this script will ignore that entry.
#
# This script requires that ASM ORACLE_SID's start with a +, and 
# that non-ASM instance ORACLE_SID's do not start with a +.
#
# Note:
# Use ORACLE_TRACE=T for tracing this script.
# Oracle Net Listener is also shutdown using this script.
#
# The progress log for each instance shutdown is logged in file 
# $ORACLE_HOME/shutdown.log.
#
# On all UNIX platforms except SOLARIS
# ORATAB=/etc/oratab
#
# To configure, update ORATAB with Instances that need to be shutdown
#    Entries are of the form:
#    $ORACLE_SID:$ORACLE_HOME:<N|Y>:
#    An example entry:
#    main:/usr/lib/oracle/emagent_10g:Y
#
#####################################

trap 'exit' 1 2 3
case $ORACLE_TRACE in
  T) set -x ;;
esac

# Set path if path not set (if called from /etc/rc)
SAVE_PATH=/bin:/usr/bin:/etc:${PATH} ; export PATH
SAVE_LLP=$LD_LIBRARY_PATH

# The  this to bring down Oracle Net Listener
ORACLE_HOME_LISTNER=$1
if [ ! $ORACLE_HOME_LISTNER ] ; then
  echo "ORACLE_HOME_LISTNER is not SET, unable to auto-stop Oracle Net Listener"
  echo "Usage: $0 ORACLE_HOME"
else
  LOG=$ORACLE_HOME_LISTNER/listener.log

  # Set the ORACLE_HOME for the Oracle Net Listener, it gets reset to
  # a different ORACLE_HOME for each entry in the oratab.
  export ORACLE_HOME=$ORACLE_HOME_LISTNER

  # Stop Oracle Net Listener
  if [ -f $ORACLE_HOME_LISTNER/bin/tnslsnr ] ; then
    echo "$0: Stoping Oracle Net Listener" >> $LOG 2>&1
    $ORACLE_HOME_LISTNER/bin/lsnrctl stop >> $LOG 2>&1 &
  else
    echo "Failed to auto-stop Oracle Net Listener using $ORACLE_HOME_LISTNER/bin/tnslsnr"
  fi
fi

# Set this in accordance with the platform
ORATAB=/etc/oratab
if [ ! $ORATAB ] ; then
  echo "$ORATAB not found"
  exit 1;
fi

# Stops an instance
stopinst() {
  ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  if [ "$ORACLE_SID" = '*' ] ; then
    ORACLE_SID=""
  fi
# Called programs use same database ID
  export ORACLE_SID
  ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
# Called scripts use same home directory
  export ORACLE_HOME
# Put $ORACLE_HOME/bin into PATH and export.
  PATH=$ORACLE_HOME/bin:${SAVE_PATH} ; export PATH
# add for bug 652997
  LD_LIBRARY_PATH=${ORACLE_HOME}/lib:${SAVE_LLP} ; export LD_LIBRARY_PATH
  PFILE=${ORACLE_HOME}/dbs/init${ORACLE_SID}.ora

# See if it is a V6 or V7 database
  VERSION=undef
  if [ -f $ORACLE_HOME/bin/sqldba ] ; then
    SQLDBA=sqldba
    VERSION=`$ORACLE_HOME/bin/sqldba command=exit | awk '
      /SQL\*DBA: (Release|Version)/ {split($3, V, ".") ;
      print V[1]}'`
    case $VERSION in
      "6") ;;
      *) VERSION="internal" ;;
    esac
  else
    if [ -f $ORACLE_HOME/bin/svrmgrl ] ; then
      SQLDBA=svrmgrl
      VERSION="internal"
    else
      SQLDBA="sqlplus /nolog"
    fi
  fi

  case $VERSION in
    "6")  sqldba command=shutdown ;;
    "internal")  $SQLDBA <<EOF
connect internal
shutdown immediate
EOF
     ;;
     *)  $SQLDBA <<EOF
connect / as sysdba
shutdown immediate
quit
EOF
     ;;
  esac

  if test $? -eq 0 ; then
    echo "${INST} \"${ORACLE_SID}\" shut down."
  else
    echo "${INST} \"${ORACLE_SID}\" not shut down."
  fi
}

#
# Loop for every entry in oratab file and and try to shut down
# that ORACLE
#
# Following loop shuts down 'Database Instance[s]' with 'Y' entry

cat $ORATAB | while read LINE
do
  case $LINE in
  \#*)                ;;        #comment-line in oratab
  *)
  ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  if [ "$ORACLE_SID" = '*' ] ; then
      # NULL SID - ignore
      ORACLE_SID=""
      continue
  fi
  # Proceed only if last field is 'Y' or 'W'
  if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "Y" ] ; then
    if [ `echo $ORACLE_SID | cut -b 1` != '+' ]; then
      INST="Database instance"
      ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
      LOG=$ORACLE_HOME/shutdown.log
      echo "Processing $INST \"$ORACLE_SID\": log file $LOG"
      stopinst >> $LOG 2>&1
    fi
  fi
  ;;
  esac
done

#
# Following loop shuts down 'Database Instance[s]' with 'W' entry
#
cat $ORATAB | while read LINE
do
  case $LINE in
  \#*)                ;;        #comment-line in oratab
  *)
  ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  if [ "$ORACLE_SID" = '*' ] ; then
      # NULL SID - ignore
      ORACLE_SID=""
      continue
  fi
  # Proceed only if last field is 'Y' or 'W'
  if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "W" ] ; then
    if [ `echo $ORACLE_SID | cut -b 1` != '+' ]; then
      INST="Database instance"
      ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
      LOG=$ORACLE_HOME/shutdown.log
      echo "Processing $INST \"$ORACLE_SID\": log file $LOG"
      stopinst >> $LOG 2>&1
    fi
  fi
  ;;
  esac
done

#
# Following loop shuts down 'ASM Instance[s]'
#

cat $ORATAB | while read LINE
do
  case $LINE in
    \#*)                ;;        #comment-line in oratab
    *)
    ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
    if [ "$ORACLE_SID" = '*' ] ; then
      # NULL SID - ignore
      ORACLE_SID=""
      continue
    fi
    # Proceed only if last field is 'Y'.
    # Entries whose last field is not Y or N are not DB entry, ignore them.
    if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "Y" ] ; then
      if [ `echo $ORACLE_SID | cut -b 1` = '+' ]; then
        INST="ASM instance"
        ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
        LOG=$ORACLE_HOME/shutdown.log
        echo "Processing $INST \"$ORACLE_SID\": log file $LOG"
        stopinst >> $LOG 2>&1
      fi
    fi
  ;;
  esac
done
