#! /bin/sh
# $Header$
#
#bcpyrght
#***************************************************************************
#* $Copyright: Copyright (c) 2022 Veritas Technologies LLC. All rights reserved $ *
#***************************************************************************
#ecpyrght
#
# bpstart_notify.oracle_bli
#
# This script is called by NetBackup when bpbkar is started up on the client
# to do a block incremental backup. It can be used to put the DB in
# backup mode, or to shut the DB down depending on the backup method
# that is desired.
#
# This script:
#	receives 4 parameters: CLIENTNAME POLICYNAME SCHEDNAME SCHEDTYPE
#	must be executable by the root user
#	should exit with 0 upon successful completion
#
# The following environment variables are also available:
#       KEYWORD        - The KEYWORD associated with the policy
#       STREAMS        - The number of policies with the same KEYWORD
#       BACKUPID       - The NetBackup image ID
#       UNIXBACKUPTIME - The backup time in seconds since 1970
#       BACKUPTIME     - The backup time in readable form
#       BPSTART_TIMEOUT  - The bpstart_notify timeout value
#
# If this script will not complete within a few seconds, you should set
# the BPSTART_TIMEOUT in the /usr/openv/netbackup/bp.conf file on the server.
# You should also be aware that the time taken by this script will delay
# the initiation of other client's backups.
#
# To use this script, copy it to the /usr/openv/netbackup/bin/ directory
# on a client and make the modifications as directed below. Then copy
# it to bpstart_notify.POLICY where POLICY is the name of each of the
# policies that will back up a subset of the filesystems. For example, if
# policies orasid_block_incr1, orasid_block_incr2, and orasid_block_incr3
# are used, copy it to bpstart_notify.orasid_block_incr1,
# bpstart_notify.orasid_block_incr2, and bpstart_notify.orasid_block_incr3.
#
# Once the bpstart_notify.POLICY files have been created, change the mode
# bits on the files to 500 and change the owner to root.
#
# CAUTION:  writing anything to stdout or stderr can cause backup problems
# so direct any output to /dev/null or the file defined by OUTF.
#


# -----------------------------------------------------------------------------
# Replace the xxxxxx in ORACLE_DBA with the oracle administrator's user name.
# -----------------------------------------------------------------------------

#ORACLE_DBA=oracle
ORACLE_DBA=xxxxxx

# -----------------------------------------------------------------------------
# Replace xxxxxx below with the name of the policy that will do
# the DB shutdown/startup or alter tablespace operations. Normally,
# if you have 3 policies named block_incr1, block_incr2, and block_incr3,
# you would set POLICY_IN_CONTROL to block_incr1 so that you could
# increase or decrease the number of policies easily.
# -----------------------------------------------------------------------------

POLICY_IN_CONTROL=xxxxxx

# -----------------------------------------------------------------------------
# Replace the xxxxxx in ORACLE_BASE with the directory at the top of the
# Oracle software and administrative file structure. The recommended value 
# from Oracle is /MOUNTPOINT/app/oracle. 
# For example: ORACLE_BASE=/u01/app/oracle
# -----------------------------------------------------------------------------

ORACLE_BASE=xxxxxx
export ORACLE_BASE

# -----------------------------------------------------------------------------
# Replace the xxxxxx in ORACLE_HOME with the directory containing the Oracle
# software for a given Oracle Server release. The recommended value from
# Oracle is ${ORACLE_BASE}/product/RELEASE. 
# For example: ORACLE_HOME=${ORACLE_BASE}/product/10.2
# -----------------------------------------------------------------------------

#ORACLE_HOME=${ORACLE_BASE}/product/RELEASE
ORACLE_HOME=xxxxxx
export ORACLE_HOME

# -----------------------------------------------------------------------------
# The Oracle admin command path.
# -----------------------------------------------------------------------------

#SQLCMD=${ORACLE_HOME}/bin/sqlplus
SQLCMD=xxxxxx

# ---------------------------------------------------------------------------
# Change the Oracle login.
# ---------------------------------------------------------------------------
 
SQLLOGIN="sys/change_on_install as sysdba"

# -----------------------------------------------------------------------------
# Change the ORACLE_SID value if it is not the same as the KEYWORD.
# -----------------------------------------------------------------------------

ORACLE_SID=$KEYWORD
export ORACLE_SID

# -----------------------------------------------------------------------------
# Change the Oracle init file path (if necessary).
# -----------------------------------------------------------------------------

ORACLE_INIT=${ORACLE_BASE}/admin/${ORACLE_SID}/pfile/init${ORACLE_SID}.ora

# -----------------------------------------------------------------------------
# If you want to receive mail for a successful execution of the script,
# replace the xxxxxx for the MAIL_ADDR_SUCCESS variable with a mail address.
# If you want to receive mail for a unsuccessful execution of the script,
# replace the xxxxxx for the MAIL_ADDR_FAILURE variable with a mail address.
# -----------------------------------------------------------------------------

MAIL_ADDR_SUCCESS=xxxxxx
MAIL_ADDR_FAILURE=xxxxxx

# -----------------------------------------------------------------------------
# Set the backup METHOD variable to one of the following:
#    SHUTDOWN_BKUP_RESTART - Shutdown the DB, backup, and then restart
#    SHUTDOWN_CKPT_RESTART - Shutdown, create the ckpt clones, and restart
#    ALTER_TABLESPACE      - Use the "alter tablespace begin backup" method
#    NODATA_CKPT_HOT       - "alter tablespace begin backup" with nodata ckpts
# If one of the methods requiring DB shutdown are selected, you may experience
# problems with timeouts if the database can't be shut down in a timely
# manner. You may want to change the shutdown command to "shutdown abort",
# or you may want to increase the BPSTART_TIMEOUT value in the bp.conf file
# on the master server, or change the backup METHOD to ALTER_TABLESPACE or
# NODATA_CKPT_HOT if you want to conserve disk space.
# Note: the default BPSTART_TIMEOUT value is 300 seconds.
# -----------------------------------------------------------------------------

# METHOD=SHUTDOWN_BKUP_RESTART
# METHOD=SHUTDOWN_CKPT_RESTART
# METHOD=NODATA_CKPT_HOT
METHOD=ALTER_TABLESPACE

# -----------------------------------------------------------------------------
# Change the following PSCMD variable if necessary.
# -----------------------------------------------------------------------------

PSCMD="/bin/ps -ef"

# -----------------------------------------------------------------------------
# Change the following LD_LIBRARY_PATH variable if necessary.
# -----------------------------------------------------------------------------

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${ORACLE_HOME}/lib

if [ -d /usr/ucblib ]
then
        LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/ucblib
fi

export LD_LIBRARY_PATH

# -----------------------------------------------------------------------------
# END OF THE CONFIGURATION CHANGES.
# -----------------------------------------------------------------------------







# -----------------------------------------------------------------------------
# Get the list of tablespaces.
# -----------------------------------------------------------------------------

get_tablespace_list()
{
$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME ---------------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME get_tablespace_list() START" >>$OUTF
$ECHO "`$TIME` $POLICYNAME ---------------------------" >>$OUTF
$ECHO "" >>$OUTF

/bin/rm -f $TABLES_FILE $LIST_FILE
/bin/rm -f $CMDF

/bin/touch $LIST_FILE
/bin/touch $TABLES_FILE
/bin/chown $ORACLE_DBA $LIST_FILE
/bin/chmod 644 $LIST_FILE
/bin/chmod 644 $TABLES_FILE
/bin/touch $CMDF
/bin/chmod 644 $CMDF

$ECHO "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >>$CMDF
$ECHO "export LD_LIBRARY_PATH" >>$CMDF
$ECHO "$SQLCMD <<EOF" >>$CMDF
$ECHO "$SQLLOGIN" >>$CMDF
$ECHO "set echo on;" >>$CMDF
$ECHO "select distinct 'TABLE ' || dba_tablespaces.tablespace_name from dba_tablespaces, dba_data_files where dba_tablespaces.tablespace_name = dba_data_files.tablespace_name AND dba_tablespaces.status = 'ONLINE';" >>$CMDF
$ECHO "exit;" >>$CMDF
$ECHO "EOF" >>$CMDF

/bin/su $ORACLE_DBA -c "/bin/sh $CMDF" >>$LIST_FILE 2>>$OUTF

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME Database select tablespace_name command output:" >>$OUTF
$ECHO "" >>$OUTF

/bin/cat $LIST_FILE >>$OUTF

grep "^TABLE " $LIST_FILE |sed 's/^TABLE //g' >>$TABLES_FILE

if [ $? -ne 0 ]
then
	# The grep failed, so the select for the tablespace list failed.
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Could not get tablespace list." >>$OUTF
	abort
fi

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -------------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME get_tablespace_list() END" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -------------------------" >>$OUTF
$ECHO "" >>$OUTF
}

# -----------------------------------------------------------------------------
# Put the tablespaces in backup mode.
# -----------------------------------------------------------------------------

alter_tablespace_begin_backup()
{
$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -------------------------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME alter_tablespace_begin_backup() START" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -------------------------------------" >>$OUTF
$ECHO "" >>$OUTF

/bin/rm -f $WORKF
/bin/rm -f $CMDF

/bin/touch $CMDF
/bin/chmod 644 $CMDF
/bin/touch $WORKF
/bin/chown $ORACLE_DBA $WORKF
/bin/chmod 644 $WORKF

$ECHO "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >>$CMDF
$ECHO "export LD_LIBRARY_PATH" >>$CMDF
$ECHO "$SQLCMD <<EOF" >>$CMDF
$ECHO "$SQLLOGIN" >>$CMDF
$ECHO "set echo on;" >>$CMDF

cat $TABLES_FILE |
while read TBLSPACE
do
	$ECHO "alter tablespace $TBLSPACE begin backup;" >>$CMDF
done

$ECHO "exit" >>$CMDF
$ECHO "EOF" >>$CMDF

/bin/su $ORACLE_DBA -c "/bin/sh $CMDF" >>$WORKF 2>>$WORKF

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME Database begin backup command output:" >>$OUTF
$ECHO "" >>$OUTF

/bin/cat $WORKF >>$OUTF

# Look for errors of the form "ORA-00000".

STAT=`egrep "(ORA|DBA|SQL|LCC|MGR)-[0-9]" $WORKF|wc -l`

/bin/touch ${BEGIN_BACKUP_FILE}
/bin/chmod 644 ${BEGIN_BACKUP_FILE}
if [ ${STAT} -ne 0 ]
then
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Could not put database ${ORACLE_SID} in backup mode." >>$OUTF
	/bin/touch "${ERROR_FILE}"
	/bin/chmod 644 "${ERROR_FILE}"
else
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Database ${ORACLE_SID} was put in backup mode." >>$OUTF
fi

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -----------------------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME alter_tablespace_begin_backup() END" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -----------------------------------" >>$OUTF
$ECHO "" >>$OUTF
}

# -----------------------------------------------------------------------------
# Take the database out of backup mode.
# -----------------------------------------------------------------------------

alter_tablespace_end_backup()
{
$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -----------------------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME alter_tablespace_end_backup() START" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -----------------------------------" >>$OUTF
$ECHO "" >>$OUTF

/bin/rm -f $WORKF
/bin/rm -f $CMDF

/bin/touch $CMDF
/bin/chmod 644 $CMDF
/bin/touch $WORKF
/bin/chown $ORACLE_DBA $WORKF
/bin/chmod 644 $WORKF

$ECHO "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >>$CMDF
$ECHO "export LD_LIBRARY_PATH" >>$CMDF
$ECHO "$SQLCMD <<EOF" >>$CMDF
$ECHO "$SQLLOGIN" >>$CMDF
$ECHO "set echo on;" >>$CMDF

cat $TABLES_FILE |
while read TBLSPACE
do
	$ECHO "alter tablespace $TBLSPACE end backup;" >>$CMDF
done

$ECHO "exit" >>$CMDF
$ECHO "EOF" >>$CMDF

/bin/su $ORACLE_DBA -c "/bin/sh $CMDF" >>$WORKF 2>>$WORKF

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME Database end backup command output:" >>$OUTF
$ECHO "" >>$OUTF

/bin/cat $WORKF >>$OUTF

# Look for errors of the form "ORA-00000".

STAT=`egrep "(ORA|DBA|SQL|LCC|MGR)-[0-9]" $WORKF|wc -l`

if [ ${STAT} -ne 0 ]
then
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Could not take database ${ORACLE_SID} out of backup mode." >>$OUTF
	abort
else
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Database ${ORACLE_SID} was taken out of backup mode." >>$OUTF
	/bin/rm -f ${BEGIN_BACKUP_FILE}
fi

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME ---------------------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME alter_tablespace_end_backup() END" >>$OUTF
$ECHO "`$TIME` $POLICYNAME ---------------------------------" >>$OUTF
$ECHO "" >>$OUTF
}

# -----------------------------------------------------------------------------
# Shutdown the oracle DB (for cold backups and shutdown/checkpoint/restart).
# -----------------------------------------------------------------------------

shutdown_database()
{
$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -------------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME shutdown_database() START" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -------------------------" >>$OUTF
$ECHO "" >>$OUTF

/bin/rm -f $WORKF
/bin/rm -f $CMDF

/bin/touch $CMDF
/bin/chmod 644 $CMDF
/bin/touch $WORKF
/bin/chown $ORACLE_DBA $WORKF
/bin/chmod 644 $WORKF

# If you have problems with DB shutdown, you may want to change the shutdown
# command to "shutdown immediate", or "shutdown abort",  or change the backup
# METHOD to ALTER_TABLESPACE or NODATA_CKPT_HOT.

$ECHO "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >>$CMDF
$ECHO "export LD_LIBRARY_PATH" >>$CMDF
$ECHO "$SQLCMD <<EOF" >>$CMDF
$ECHO "$SQLLOGIN" >>$CMDF
$ECHO "set echo on;" >>$CMDF
$ECHO "shutdown" >>$CMDF
$ECHO "exit" >>$CMDF
$ECHO "EOF" >>$CMDF

/bin/su $ORACLE_DBA -c "/bin/sh $CMDF" >>$WORKF 2>>$WORKF

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME Database shutdown command output:" >>$OUTF
$ECHO "" >>$OUTF

/bin/cat $WORKF >>$OUTF

# Look for errors of the form "ORA-00000".

STAT=`egrep "(ORA|DBA|SQL|LCC|MGR)-[0-9]" $WORKF|wc -l`

if [ ${STAT} -eq 0 ]
then
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Database ${ORACLE_SID} shut down." >>$OUTF
	/bin/touch ${SHUTDOWN_FILE}
	/bin/chmod 644 ${SHUTDOWN_FILE}
else
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Database ${ORACLE_SID} could not be shut down." >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Creating error file $ERROR_FILE" >>$OUTF
	/bin/touch "${ERROR_FILE}"
	/bin/chmod 644 "${ERROR_FILE}"
fi

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -----------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME shutdown_database() END" >>$OUTF
$ECHO "`$TIME` $POLICYNAME -----------------------" >>$OUTF
$ECHO "" >>$OUTF
}

# -----------------------------------------------------------------------------
# Restart the oracle DB.
# -----------------------------------------------------------------------------

restart_database()
{
$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME ------------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME restart_database() START" >>$OUTF
$ECHO "`$TIME` $POLICYNAME ------------------------" >>$OUTF
$ECHO "" >>$OUTF

/bin/rm -f $WORKF
/bin/rm -f $CMDF

/bin/touch $CMDF
/bin/chmod 644 $CMDF
/bin/touch $WORKF
/bin/chown $ORACLE_DBA $WORKF
/bin/chmod 644 $WORKF

$ECHO "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >>$CMDF
$ECHO "export LD_LIBRARY_PATH" >>$CMDF
$ECHO "$SQLCMD <<EOF" >>$CMDF
$ECHO "$SQLLOGIN" >>$CMDF
$ECHO "set echo on;" >>$CMDF
if [ "${ORACLE_INIT}" = "" ]
then
	$ECHO "startup" >> $CMDF
else
	$ECHO "startup pfile=$ORACLE_INIT" >>$CMDF
fi
$ECHO "exit" >>$CMDF
$ECHO "EOF" >>$CMDF

/bin/su $ORACLE_DBA -c "/bin/sh $CMDF" >>$WORKF 2>>$WORKF

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME Database startup command output:" >>$OUTF
$ECHO "" >>$OUTF

/bin/cat $WORKF >>$OUTF

# Look for errors of the form "ORA-00000".

STAT=`egrep "(ORA|DBA|SQL|LCC|MGR)-[0-9]" $WORKF|wc -l`

if [ ${STAT} -eq 0 ]
then
	# No errors, but find out if the instance is really up.

	SMONPROC=`${PSCMD}|grep "smon_${ORACLE_SID}"|grep -v grep|wc -l`

	if [ ${SMONPROC} -eq 0 ]
	then
		$ECHO "" >>$OUTF
		$ECHO "`$TIME` $POLICYNAME Could not find smon_${ORACLE_SID} process." >>$OUTF
		$ECHO "`$TIME` $POLICYNAME Creating error file $ERROR_FILE" >>$OUTF
		/bin/touch "${ERROR_FILE}"
		/bin/chmod 644 "${ERROR_FILE}"
	else
		$ECHO "" >>$OUTF
		$ECHO "`$TIME` $POLICYNAME Database ${ORACLE_SID} restarted." >>$OUTF
		/bin/rm -f ${SHUTDOWN_FILE}
	fi
else
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Database ${ORACLE_SID} could not be restarted." >>$OUTF
	$ECHO "`$TIME` $POLICYNAME Creating error file $ERROR_FILE" >>$OUTF
	/bin/touch "${ERROR_FILE}"
	/bin/chmod 644 "${ERROR_FILE}"
fi

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME ----------------------" >>$OUTF
$ECHO "`$TIME` $POLICYNAME restart_database() END" >>$OUTF
$ECHO "`$TIME` $POLICYNAME ----------------------" >>$OUTF
$ECHO "" >>$OUTF
}


# -----------------------------------------------------------------------------
# Exit the script.
# -----------------------------------------------------------------------------

abort()
{
$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME END bpstart_notify exit status 1" >>$OUTF
$ECHO "" >>$OUTF

# Make sure the error file is created so that other streams know of problems.

/bin/touch "${ERROR_FILE}"
/bin/chmod 644 "${ERROR_FILE}"

if [ "$POLICYNAME" = "$POLICY_IN_CONTROL" ]
then
	/bin/rm -f $START_FILE $START_LINK
else
	/bin/rm -f $START_LINK
fi

if [ "${MAIL_ADDR_FAILURE}" != "xxxxxx" ]
then
	# Mail the output to someone.
	# CAUTION: Some platforms do not allow the -s parameter on mail.

	if [ $SUBJECT -eq 1 ]
	then
		cat $OUTF | $MAIL -s "${POLICYNAME} bpstart_notify exit 1" $MAIL_ADDR_FAILURE
	else
		cat $OUTF | $MAIL $MAIL_ADDR_FAILURE
	fi
fi

exit 1
}

# -----------------------------------------------------------------------------
# Main script starts here.
# -----------------------------------------------------------------------------

if [ -x /usr/bin/mailx ]
then
	MAIL=/usr/bin/mailx
	SUBJECT=1
elif [ -x /usr/ucb/mail ]
then
	MAIL=/usr/ucb/mail
	SUBJECT=1
elif [ -x /usr/bin/mail ]
then 
	MAIL=/usr/bin/mail
	SUBJECT=0
else
	MAIL=/bin/mail
	SUBJECT=0
fi

ECHO=/bin/echo

if [ "$#" -ne 4 ]
then
	$ECHO "`$TIME` $POLICYNAME Expected 4 parameters, but got $# instead." >>$OUTF
	abort
fi

# -----------------------------------------------------------------------------
# Assign names to our parameters.
# -----------------------------------------------------------------------------

CLIENTNAME=$1
POLICYNAME=$2
SCHEDNAME=$3
SCHEDTYPE=$4

# -----------------------------------------------------------------------------
# Create some variables using the environment variables from bpbkar.
# -----------------------------------------------------------------------------

CONTROL_DIR=/usr/openv/netbackup/bin/BLOCK_INCR

SHUTDOWN_BKUP_RESTART_FILE=${CONTROL_DIR}/SHUTDOWN_BKUP_RESTART.${ORACLE_SID}
SHUTDOWN_CKPT_RESTART_FILE=${CONTROL_DIR}/SHUTDOWN_CKPT_RESTART.${ORACLE_SID}
ALTER_TABLESPACE_FILE=${CONTROL_DIR}/ALTER_TABLESPACE.${ORACLE_SID}
NODATA_CKPT_HOT_FILE=${CONTROL_DIR}/NODATA_CKPT_HOT.${ORACLE_SID}

SHUTDOWN_FILE=${CONTROL_DIR}/shutdown.${ORACLE_SID}
BEGIN_BACKUP_FILE=${CONTROL_DIR}/begin_backup.${ORACLE_SID}

POLICY_IN_CONTROL_FILE=${CONTROL_DIR}/policy_in_control.${KEYWORD}

START_FILE=${CONTROL_DIR}/start.${ORACLE_SID}
START_LINK=${CONTROL_DIR}/start.${ORACLE_SID}.${POLICYNAME}

POST_CKPT_FILE=${CONTROL_DIR}/post_ckpt.${ORACLE_SID}
POST_CKPT_LINK=${CONTROL_DIR}/post_ckpt.${ORACLE_SID}.${POLICYNAME}

END_FILE=${CONTROL_DIR}/end.${ORACLE_SID}
END_LINK=${CONTROL_DIR}/end.${ORACLE_SID}.${POLICYNAME}

ERROR_FILE=${CONTROL_DIR}/error.${KEYWORD}
TABLES_FILE=${CONTROL_DIR}/tablespaces.${ORACLE_SID}
CMDF=${CONTROL_DIR}/ora_cmd.${ORACLE_SID}
LIST_FILE=${CONTROL_DIR}/tblspace_list.${ORACLE_SID}
OUTF=${CONTROL_DIR}/bpstart_notify_output.${ORACLE_SID}
WORKF=${CONTROL_DIR}/db_cmd_output.${ORACLE_SID}

TIME='/bin/date +%T'

# -----------------------------------------------------------------------------
# Make sure there are no files left around from system crashes.
# -----------------------------------------------------------------------------

/bin/rm -f ${POST_CKPT_FILE}*
/bin/rm -f ${END_FILE}* 
/bin/rm -f ${SHUTDOWN_FILE} ${BEGIN_BACKUP_FILE}

if [ ! -d $CONTROL_DIR ]
then
	/bin/mkdir $CONTROL_DIR
	/bin/chmod 1777 $CONTROL_DIR
fi

# -----------------------------------------------------------------------------
# Make sure the control directory has the proper permissions
# -----------------------------------------------------------------------------
/bin/chmod 1777 $CONTROL_DIR

if [ "${SCHEDTYPE}" = "UBAK" -o $STREAMS -eq 0 ]
then
        # If this is not a block incremental, exit now.
        exit 0
fi

if [ ! -f $OUTF ]
then
	/bin/touch $OUTF
	/bin/chmod 644 $OUTF
fi

$ECHO "" >>$OUTF
$ECHO "===============================================================================" >>$OUTF
$ECHO "`date` $POLICYNAME START bpstart_notify" >>$OUTF
$ECHO "===============================================================================" >>$OUTF
$ECHO "" >>$OUTF

$ECHO "`$TIME` $POLICYNAME   BACKUPID         = ${BACKUPID}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   UNIXBACKUPTIME   = ${UNIXBACKUPTIME}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   BACKUPTIME       = ${BACKUPTIME}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   CLIENTNAME       = ${CLIENTNAME}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   POLICYNAME        = ${POLICYNAME}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   SCHEDNAME        = ${SCHEDNAME}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   SCHEDTYPE        = ${SCHEDTYPE}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   KEYWORD          = ${KEYWORD}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   STREAMS          = ${STREAMS}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   BPSTART_TIMEOUT  = ${BPSTART_TIMEOUT}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   BPEND_TIMEOUT    = ${BPEND_TIMEOUT}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   POLICY_IN_CONTROL = ${POLICY_IN_CONTROL}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   ORACLE_DBA       = ${ORACLE_DBA}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   ORACLE_BASE      = ${ORACLE_BASE}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   ORACLE_HOME      = ${ORACLE_HOME}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   ORACLE_SID       = ${ORACLE_SID}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   ORACLE_INIT      = ${ORACLE_INIT}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   SQLCMD           = ${SQLCMD}" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   SQLLOGIN         = ${SQLLOGIN}" >>$OUTF

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME   LD_LIBRARY_PATH  = ${LD_LIBRARY_PATH}" >>$OUTF
$ECHO "" >>$OUTF

if [ "$POLICYNAME" = "$POLICY_IN_CONTROL" ]
then
	$ECHO "`$TIME` $POLICYNAME   METHOD           = ${METHOD}" >>$OUTF
	$ECHO "" >>$OUTF
fi

if [ "$ORACLE_DBA" = "xxxxxx" ]
then
	$ECHO "`$TIME` $POLICYNAME The ORACLE_DBA variable is not set" >>$OUTF
	abort
fi

if [ "$POLICY_IN_CONTROL" = "xxxxxx" ]
then
	$ECHO "`$TIME` $POLICYNAME The POLICY_IN_CONTROL variable is not set" >>$OUTF
	abort
fi

if [ "$ORACLE_BASE" = "xxxxxx" ]
then
	$ECHO "`$TIME` $POLICYNAME The ORACLE_BASE variable is not set" >>$OUTF
	abort
fi

if [ "$ORACLE_HOME" = "xxxxxx" ]
then
	$ECHO "`$TIME` $POLICYNAME The ORACLE_HOME variable is not set" >>$OUTF
	abort
fi

if [ "$SQLCMD" = "xxxxxx" ]
then
	$ECHO "`$TIME` $POLICYNAME The SQLCMD variable is not set" >>$OUTF
	abort
fi

if [ "$SQLLOGIN" = "xxxxxx" ]
then
	$ECHO "`$TIME` $POLICYNAME The SQLLOGIN variable is not set" >>$OUTF
	abort
fi

if [ "${ORACLE_INIT}" != "" -a ! -f "${ORACLE_INIT}" ]
then
	$ECHO "`$TIME` $POLICYNAME ORACLE_INIT ${ORACLE_INIT} not found" >>$OUTF
	abort
fi

if [ "$POLICYNAME" = "$POLICY_IN_CONTROL" ]
then
	if [ -f $START_FILE ]
	then
		# If the control file already exists, remove it along with
		# the link files from all the streams.
		/bin/rm -f ${START_FILE}*
	fi
	/bin/rm -f "${ERROR_FILE}"
	/bin/touch $START_FILE
	/bin/chmod 644 $START_FILE
else
	/bin/rm -f $START_LINK

	# Wait for the control file to be created by the "policy in control"
	# before continuing.

	SLEEP_COUNT=0

	while [ ! -f $START_FILE ]
	do
		/bin/sleep 1
		SLEEP_COUNT=`expr $SLEEP_COUNT + 1`

		if [ $SLEEP_COUNT -gt 7200 ]
		then
			# If we hit 2 hours, create the error file ourselves
			# so that we don't wait forever.

			$ECHO "`$TIME` $POLICYNAME Exceeded 7200 second wait count." >>$OUTF
			$ECHO "`$TIME` $POLICYNAME Creating error file $ERROR_FILE" >>$OUTF
			/bin/touch "${ERROR_FILE}"
			/bin/chmod 644 "${ERROR_FILE}"
			abort

		elif [ $SLEEP_COUNT -gt $BPSTART_TIMEOUT ]
		then
			# If we've exceeded the timeout and the policy in
			# control hasn't started yet, start looking for the
			# error file.

			if [ -f "${ERROR_FILE}" ]
			then
				$ECHO "`$TIME` $POLICYNAME Error file $ERROR_FILE detected" >>$OUTF
				$ECHO "`$TIME` $POLICYNAME while waiting for $START_FILE file" >>$OUTF
				abort
			fi
		fi
	done
fi

# -----------------------------------------------------------------------------
# Create a hard link to the START_FILE. We will use the link count to
# decide when all the streams have been started.
# -----------------------------------------------------------------------------

if [ -f $START_FILE ]
then
	/bin/ln $START_FILE $START_LINK
	LINKCOUNT=`ls -l $START_FILE|sed 's/  / /g'|sed 's/  / /g'|cut -f2 -d" "`
else
	LINKCOUNT=0
fi

while [ $STREAMS -ge $LINKCOUNT ]
do
	if [ -f "${ERROR_FILE}" ]
	then
		$ECHO "`$TIME` $POLICYNAME Error file $ERROR_FILE detected" >>$OUTF
		$ECHO "`$TIME` $POLICYNAME while waiting for link count of $LINKCOUNT on $START_FILE file" >>$OUTF
		abort
	fi

	/bin/sleep 1

	if [ -f $START_FILE ]
	then
		# The "policy in control" may remove our link if
		# the "policy in control" isn't the first one started.
		/bin/ln $START_FILE $START_LINK

		LINKCOUNT=`ls -l $START_FILE|sed 's/  / /g'|sed 's/  / /g'|cut -f2 -d" "`
	else
		LINKCOUNT=0
	fi
done

# -----------------------------------------------------------------------------
# All streams have been started, so we can now continue.
# -----------------------------------------------------------------------------

$ECHO "" >>$OUTF
$ECHO "`$TIME` $POLICYNAME All streams have been started." >>$OUTF
$ECHO "" >>$OUTF

if [ "$POLICYNAME" = "$POLICY_IN_CONTROL" ]
then
	/bin/rm -f $SHUTDOWN_BKUP_RESTART_FILE
	/bin/rm -f $SHUTDOWN_CKPT_RESTART_FILE
	/bin/rm -f $ALTER_TABLESPACE_FILE
	/bin/rm -f $NODATA_CKPT_HOT_FILE
	/bin/rm -f "${POLICY_IN_CONTROL_FILE}"

	# Write the POLICY_IN_CONTROL value to a file so that bpbkar can read it.

	/bin/touch $POLICY_IN_CONTROL_FILE
	/bin/chmod 644 $POLICY_IN_CONTROL_FILE
	$ECHO $POLICY_IN_CONTROL >>"${POLICY_IN_CONTROL_FILE}"

	# Find out if the instance is up.

	SMONPROC=`${PSCMD}|grep "smon_${ORACLE_SID}"|grep -v grep|wc -l`

	if [ ${SMONPROC} -eq 0 ]
	then
		$ECHO "`$TIME` $POLICYNAME Database ${ORACLE_SID} is down." >>$OUTF
	fi

	# Shut down the DB or put it in "backup" mode.

	case "$METHOD"
	in
	"SHUTDOWN_BKUP_RESTART")
		# Shutdown the database, do the backup, and then restart
		# the database (do a cold backup).

		if [ ${SMONPROC} -gt 0 ]
		then
			/bin/touch $SHUTDOWN_BKUP_RESTART_FILE
			/bin/chmod 644 $SHUTDOWN_BKUP_RESTART_FILE
			shutdown_database
		fi
		;;
	"SHUTDOWN_CKPT_RESTART")
		# Shutdown the database, create the checkpoint clones,
		# and then restart the database.

		if [ ${SMONPROC} -gt 0 ]
		then
			/bin/touch $SHUTDOWN_CKPT_RESTART_FILE
			/bin/chmod 644 $SHUTDOWN_CKPT_RESTART_FILE
			shutdown_database
		fi
		;;
	"ALTER_TABLESPACE")
		# Do a hot database backup using the "alter tablespace
		# begin backup" method.

		if [ ${SMONPROC} -eq 0 ]
		then
			# If the database instance is not active, change the
			# METHOD to SHUTDOWN_BKUP_RESTART (with the shutdown
			# already complete). The instance will not be restarted
			# when the backup is completed.

			/bin/touch $SHUTDOWN_BKUP_RESTART_FILE
			/bin/chmod 644 $SHUTDOWN_BKUP_RESTART_FILE
			METHOD=SHUTDOWN_BKUP_RESTART
			$ECHO "`$TIME` $POLICYNAME Switching to cold backup method." >>$OUTF

			# If you would rather fail the backup, touch the
			# $ERROR_FILE instead.
			# /bin/touch "${ERROR_FILE}"
			# /bin/chmod 644 "${ERROR_FILE}"
			# $ECHO "`$TIME` $POLICYNAME Cannot do hot backup." >>$OUTF
		else
			get_tablespace_list
			/bin/touch $ALTER_TABLESPACE_FILE
			/bin/chmod 644 $ALTER_TABLESPACE_FILE
			alter_tablespace_begin_backup
		fi
		;;
	"NODATA_CKPT_HOT")
		# Do a hot database backup using the "alter tablespace begin
		# backup" method and leave the DB in backup mode the whole time.

		if [ ${SMONPROC} -eq 0 ]
		then
			# If the database instance is not active, change the
			# METHOD to SHUTDOWN_BKUP_RESTART (with the shutdown
			# already complete). The instance will not be restarted
			# when the backup is completed.

			/bin/touch $SHUTDOWN_BKUP_RESTART_FILE
			/bin/chmod 644 $SHUTDOWN_BKUP_RESTART_FILE
			METHOD=SHUTDOWN_BKUP_RESTART
			$ECHO "`$TIME` $POLICYNAME Switching to cold backup method." >>$OUTF

			# If you would rather fail the backup, touch the
			# $ERROR_FILE instead.
			# /bin/touch "${ERROR_FILE}"
			# /bin/chmod 644 "${ERROR_FILE}"
			# $ECHO "`$TIME` $POLICYNAME Cannot do hot backup." >>$OUTF
		else
			get_tablespace_list
			/bin/touch $NODATA_CKPT_HOT_FILE
			/bin/chmod 644 $NODATA_CKPT_HOT_FILE
			alter_tablespace_begin_backup
		fi
		;;
	esac

	# We now have all the streams started. Now wait for others to unlink.

	if [ -f $START_FILE ]
	then
		LINKCOUNT=`ls -l $START_FILE|sed 's/  / /g'|sed 's/  / /g'|cut -f2 -d" "`
	else
		LINKCOUNT=0
	fi

	while [ $LINKCOUNT -gt 2 -a ! -f "${ERROR_FILE}" ]
	do
		/bin/sleep 1
		if [ -f $START_FILE ]
		then
			LINKCOUNT=`ls -l $START_FILE|sed 's/  / /g'|sed 's/  / /g'|cut -f2 -d" "`
		else
			LINKCOUNT=0
		fi
	done

	/bin/rm -f $START_LINK
	/bin/rm -f $START_FILE
else
	# This is not the "policy in control".
	/bin/sleep 3
	/bin/rm -f $START_LINK

	# Wait for the control file to be deleted by the "policy in control"
	# before continuing.

	while [ -f $START_FILE ]
	do
		if [ -f "${ERROR_FILE}" ]
		then
			$ECHO "`$TIME` $POLICYNAME Error file $ERROR_FILE detected" >>$OUTF
			$ECHO "`$TIME` $POLICYNAME while waiting for $START_FILE to be deleted" >>$OUTF
			abort
		fi

		/bin/sleep 1
	done
fi

if [ -f "${ERROR_FILE}" ]
then
	# Something went wrong

	$ECHO "`$TIME` $POLICYNAME Error file $ERROR_FILE detected" >>$OUTF

	if [ "$POLICYNAME" = "$POLICY_IN_CONTROL" ]
	then
		case "$METHOD"
		in
		"SHUTDOWN_BKUP_RESTART")
			# Restart the database now since we won't be doing
			# the backup.
			if [ -f $SHUTDOWN_FILE ]
			then
				restart_database
			fi
			;;
		"SHUTDOWN_CKPT_RESTART")
			# Restart the database now since we won't be doing
			# the backup.
			if [ -f $SHUTDOWN_FILE ]
			then
				restart_database
			fi
			;;
		"ALTER_TABLESPACE")
			if [ -f $BEGIN_BACKUP_FILE ]
			then
				# Take the database out of backup mode using
				# "alter tablespace end backup".
				alter_tablespace_end_backup
			fi
			;;
		"NODATA_CKPT_HOT")
			if [ -f $BEGIN_BACKUP_FILE ]
			then
				# Take the database out of backup mode using
				# "alter tablespace end backup".
				alter_tablespace_end_backup
			fi
			;;
		esac
	fi

	abort
fi

if [ -f "${ERROR_FILE}" ]
then
	$ECHO "`$TIME` $POLICYNAME Error file $ERROR_FILE detected" >>$OUTF
	abort
else
	$ECHO "" >>$OUTF
	$ECHO "`$TIME` $POLICYNAME END bpstart_notify exit status 0" >>$OUTF
	$ECHO "" >>$OUTF

	if [ "$POLICYNAME" = "$POLICY_IN_CONTROL" ]
	then
		if [ "${MAIL_ADDR_SUCCESS}" != "xxxxxx" ]
		then
			# Mail the output to someone.
			# CAUTION: Some platforms do not allow the -s parameter on mail.

			if [ $SUBJECT -eq 1 ]
			then
				cat $OUTF | $MAIL -s "${POLICYNAME} bpstart_notify exit 0" $MAIL_ADDR_SUCCESS
			else
				cat $OUTF | $MAIL $MAIL_ADDR_SUCCESS
			fi
		fi
	fi

	exit 0
fi
