#!/bin/sh
#
# Copyright 06/01/04  Sun Microsystems, Inc. All Rights Reserved.
#
# pragma ident  "@(#)es-backup	1.55 04/06/01 Sun Microsystems"
#

print_usage() {
    /bin/echo ""
    eval /bin/echo `/usr/bin/gettext 'Usage: $PROGNAME [-h] [-y] [-d dir]'`
    /usr/bin/gettext '     -h      : Prints this usage.\n'
    /usr/bin/gettext '     -c      : Does Cold backup.\n'
    /usr/bin/gettext '     -o      : Does Online backup.\n'
    /usr/bin/gettext '     -y      : Use default answer[y]\n'
    /usr/bin/gettext '     -d <dir>: Specify default backup directory path\n'
    /bin/echo ""
}

print_failure_and_exit() {
    echolog "Sun Management Center data backup failed. Exiting ..."
    echolog 'Check $2 for details.' "$LOGFILE"

    # Just in case SunMC is still up
    stop_SunMC

    echolog ''
    exit $1
}

verify_db_files () {
    db_block_size=`/usr/bin/grep db_block_size $ORA_INITFILE | /usr/bin/cut -f2 -d=`
    dbf_files=`/usr/bin/find $ESTBL_BASEDIR/$ORA_DATADIR -name \*.dbf`
    tmplog=${TMP_DIR}/dbv_log.$$

    status=0
    for file in $dbf_files ; do
        /usr/bin/rm -f $tmplog  2>/dev/null 1>&2
        $DBVERIFY file=$file blocksize=$db_block_size >$tmplog 2>&1

        scan_dbv_log $tmplog $file
        if [ $? -ne 0 ] ; then
            echolog 'Verification of database failed.'
            status=1
            break
        fi
    done

    /usr/bin/rm -f $tmplog 2>/dev/null 1>&2
    return $status
}

get_db_users_list () {

# First get a list of  *-dbase.cfg files for all the add-ons.
# Then retrieve the user from  each one and get the add-on name.
# Check if the user exists in the database and if so, create an
# {addon}_USER={user_name} entry for the metafile.
# The core database user is set by db-backup-common, DB_SCHEMA_OWNER will be used in main create_backup_meta function.

[ -f $BACKUPDIR/$METAFILE.user_list ] && rm -rf $BACKUPDIR/$METAFILE.user_list > /dev/null 2>&1

for db_cfg_file in `/usr/bin/find $VAROPTDIR/cfg -name \*-dbase.cfg` ; do

    USER_NAME=`/usr/bin/egrep '^user=' $db_cfg_file | /usr/bin/cut -f2 -d=`

    # Retrieve addon name, and convert to upper case.
    ADDON_NAME=`/usr/bin/ls $db_cfg_file |/bin/awk 'BEGIN { FS="/" } { for (i = NF; i > 0; --i) print $i }'| /usr/bin/grep dbase | /usr/bin/cut -f1 -d- | /usr/bin/tr '[a-z]' '[A-Z]' `

    db_checkUser $SYS_LOGIN $SYSPWD $USER_NAME $LOGFILE
    if [ $? -ne 0 ] ; then
	echolog 'User $2 was not found. Data for $3 user $2 will not be backed up.' $user_name $addon_name
    else
	# Update the metafile
	/usr/bin/echo "$ADDON_NAME"_USER=$USER_NAME >> $BACKUPDIR/$METAFILE.user_list 
    fi
done

}

create_backup_meta() {
    if [ -f $BACKUPDIR/$METAFILE ] ; then
        /usr/bin/rm $BACKUPDIR/$METAFILE
    fi

DATE_FORMAT=`eval echo "+\\\%d\-\\\%m-\\\%y:\\\%H:\\\%M:\\\%S"`
BACKUP_DATE=`date $DATE_FORMAT`

    /usr/bin/cat<<EOF > $BACKUPDIR/$METAFILE
#
# Sun Management Center backup meta file
#
# THIS FILE IS CREATED AND READ AUTOMATICALLY. DO NOT EDIT MANUALLY.
#

BACKUP_FORMAT=$BACKUP_FORMAT
SUNMC_VERSION=$SUNMC_VERSION
SUNMC_USER=$DB_SCHEMA_OWNER
ESCOM_BASEDIR=$ESCOM_BASEDIR
ESTBL_BASEDIR=$ESTBL_BASEDIR
HOSTNAME=`hostname`
COMPRESS_SCHEME=$COMPRESS_SCHEME
COMPRESS_CMD=$COMPRESS_CMD
COMPRESS_EXT=$COMPRESS_EXT
ZCAT_CMD=$ZCAT_CMD
PRM_VERSION=$PRM_VERSION
DB_CHUNKS=$DB_CHUNKS
BACKUP_DATE=$BACKUP_DATE
HOT_TAG=$HOT_TAG

EOF

# Update the metafile with the list of backed up user names.
if [ -f $BACKUPDIR/$METAFILE.user_list ]; then
   /usr/bin/cat $BACKUPDIR/$METAFILE.user_list >> $BACKUPDIR/$METAFILE 
   if [ "$?" -eq 0 ]; then
      /usr/bin/rm -f $BACKUPDIR/$METAFILE.user_list 
   else
      echolog 'Error saving user list.'
      print_failure_and_exit 1
   fi
fi

}

#
# Retrieve list of Oracle data files that need to be backed up
# Note: this only includes data files; the caller should make sure other
# important files like initfiles and controlfiles are included in the backup.
#
get_dbfile_list () {
    sqlout=/tmp/sqlout.$$
    /usr/bin/rm -f $sqlout

    $SQLPLUS /nolog <<EOF >>$LOGFILE 2>&1
	connect $SYS_LOGIN/$SYSPWD
	set pagesize 0
	set heading off
	set echo off
	set feedback off
	set termout off
	spool $sqlout
	select file_name from dba_data_files;
EOF

    if [ $? -ne 0 ] ; then
        echolog 'Unable to retrieve list of Sun Management Center database files'
        status=1
    else
        DBFILE_LIST=`/usr/bin/grep '^/' $sqlout`
        status=0
    fi

    /usr/bin/rm -f $sqlout
    return $status
}

# count_fragments $basename
# Find out how many fragments /usr/bin/split generated.
# If only one, drop the .aaa suffix.
# Initializes DB_CHUNKS to be used later when creating the metafile.
count_fragments () {
    basename=$1

    if [ ! -f ${basename}.aab ] ; then
        /usr/bin/mv ${basename}.aaa $basename
        DB_CHUNKS=1
    else
        DB_CHUNKS=`/usr/bin/ls -1 ${basename}.* | /usr/bin/wc -l | /usr/bin/awk '{print $1}' `
    fi
}

#
# Tar and compress the database files
#
cold_backup() {
    DB_CHUNKS=1

    start_db
    echolog 'Retrieving list of files to be backed up...'
    get_dbfile_list
    if [ $? -ne 0 ] ; then
        print_failure_and_exit 1
    fi

    shutdown_db

    #
    # Validate existing database
    #
    echolog 'Checking existing Sun Management Center database for errors'
    verify_db_files
    if [ $? -ne 0 ] ; then
        print_failure_and_exit 1
    fi
    echolog 'Database check successful.'

    echolog 'Performing cold backup. Please wait ...'
    cd $ESTBL_BASEDIR

    # Compose list of all files that need to be backed up
    filelist="$ORA_INITFILE $ORA_EVENTDIR $ORA_CTRLFILES $DBFILE_LIST"

    bakfile_base="$BACKUPDIR/${DBBAKFILE}.${COMPRESS_EXT}"
    /usr/bin/tar cf - $filelist | $COMPRESS_CMD | /usr/bin/split -b ${CHUNK_SIZE}m -a 3 - ${bakfile_base}.

    if [ $? -ne 0 ] ; then
        echolog 'Cannot make backup copy of database.'
        print_failure_and_exit 1
    fi

    count_fragments $bakfile_base

    return 0
}

#
# Scan the database log for errors
#
ora_scan_export_log ()
{
    file=$1

    error=`/usr/bin/egrep -n "ORA-|PLS-|SP2-|EXP-" $file | /usr/bin/egrep -v "EXP-00067" | /usr/bin/head -1 | /usr/bin/cut -d: -f1`
    if [ "$error" -gt 0 ]; then
        numlines=`/usr/bin/wc -l $file | /usr/bin/awk '{print $1}'`
        offset=`/usr/bin/expr $numlines - $error`

        echolog "Oracle Error: Start..." 
        /usr/bin/tail -${offset} $file >>$LOGFILE
        echolog "Oracle Error: End"
        return 1
    fi

    return 0
}

#
# Find out how large the database is. This is computed by querying Oracle
# itself to tell us how many KBs of data we have. Based on this, we can later
# compute a rough estimate of how much space we will need for the export backup.
#
# On successful exit, the total number of KBs currently being used in Oracle
# is stored in $usize and total allocated database size is stored in $dsize.
#
# The caller is responsible for handling the case when we fail to compute
# this number.
#
compute_db_size() {

    start_db

    sqlout=/tmp/sqlout.$$
    /usr/bin/rm -f $sqlout

    # The following query returns the number of KB's of used space.
    $SQLPLUS /nolog <<EOF >>$LOGFILE 2>&1
connect $SYS_LOGIN/$SYSPWD
set pagesize 0
set heading off
set echo off
set feedback off
spool $sqlout
set linesize 512
select ltrim(rtrim(totalbytes/1024)), ltrim(rtrim(round((totalbytes - totalfree) / 1024)))
from (select sum(bytes) as totalfree from dba_free_space),
        (select sum(bytes) as totalbytes from dba_data_files);
EOF

    if [ $? -eq 0 ] ; then
        dsize=`/usr/bin/egrep '^[ \t]*[0-9]*[ \t]*[0-9]*[ \t]*$' $sqlout | /usr/bin/awk '{ print $1 }'`
        usize=`/usr/bin/egrep '^[ \t]*[0-9]*[ \t]*[0-9]*[ \t]*$' $sqlout | /usr/bin/awk '{ print $2 }'`

        if [ $? -eq 0 ] ; then
            /usr/bin/rm -f $sqlout

            if [ "$dsize" != "" -a "$usize" != "" ] ; then
                /usr/bin/rm -f $sqlout
                return 0
            fi
        fi
    fi

    # Check failed.
    echolog 'Unable to compute current size of database'

    /usr/bin/rm -f $sqlout
    return 1
}

# guess_bak_size $dbsize $m 
#	Compute a guesstimate of how much space (in KB) the backup will need.
#	The constant $m is a "magic" constant extrapolated from test
#	runs, and depend on used database size.
#
#	Guesstimate returned as $result.
guess_bak_size () {
    size=$1
    m=$2

    result=`/bin/echo $size \* $m | /usr/bin/bc -l | /usr/bin/cut -f1 -d.`
    if [ $? -ne 0 ] ; then
        return 1
    fi

    # Lower bound for estimation
    if [ "$result" -lt $MIN_BAKSIZE ] ; then
        result=$MIN_BAKSIZE
    fi
}

# estimate_export_size $dbsize
#	Estimates the (compressed) database export size in KB. This is
#	basically a function of the given database size, adjusted
#	so that it gives a loose upper bound.
#
#	Returns result in $exportsize.
estimate_export_size() {
    usize=$1

    # Estimate database backup size
    if [ $usize -lt 500000 ]; then
	guess_bak_size $usize 0.04
    elif [ $usize -lt 2000000 ]; then
    	guess_bak_size $usize 0.15
    else
	guess_bak_size $usize 0.2
    fi

    if [ $? -ne 0 ] ; then
        return 1
    fi

    exportsize=$result
    return 0
}

# estimate_cold_size $dbsize
#	Estimates compressed cold backup (database files only) size in KB.
#
#	Returns result in $coldsize.
estimate_cold_size() {
    dbsize=$1

    if [ "$PRM_EXISTS" ] ; then
        guess_bak_size $dbsize 0.2 -1200000
        if [ $? -ne 0 ] ; then
            return 1
        fi
    else
        guess_bak_size $dbsize 0.2 18000
        if [ $? -ne 0 ] ; then
            return 1
        fi
    fi

    coldsize=$result
    return 0
}

# save_db_sys_perms $login $passwd $savefile
# Save database SYS permissions (they are not exported by DBEXP)
# Note that $login/$passwd should be sys/... .
save_db_sys_perms () {
    login=$1
    passwd=$2
    savefile=$3
    /usr/bin/rm -f $savefile

    sql="select 'grant '||privilege||' on '||owner||'.'||
	table_name||' to '||grantee||' '||
	decode(grantable,'YES','WITH Grant option')||';'
	from dba_tab_privs
	where owner = 'SYS'
	and table_name NOT IN 
	( select OBJECT_NAME from dba_objects 
	  where OBJECT_TYPE='CONSUMER GROUP' and OWNER='SYS');
	select 'grant '||privilege||' ('||column_name||') '||
	' on '||owner||'.'||table_name||' to '||grantee||' '||
	decode(grantable,'YES','WITH Grant option')||';'
	from dba_col_privs
	where owner = 'SYS'"

    db_runSqlSpool "$sql" "$savefile" "SQL" $login $passwd $LOGFILE
    return $rcode
}

export_sys_perms () {
    backup_file=$BACKUPDIR/$DB_PERMS_FILE
    filepath=`dirname $backup_file`

    if [ ! -d "$filepath" ] ; then
        /usr/bin/mkdir -p "$filepath"
        if [ $? -ne 0 ] ; then
            echolog 'Unable to create directory $2 in backup.' "$2"
            return 1
        fi
    fi

    #
    # TBD: might want to compress this, although it is not expected to be
    # very large.
    #
    save_db_sys_perms "$SYS_LOGIN" "$SYSPWD" $backup_file

    return $?
}

backup_export ()
{
    start_db
    echolog 'Performing export backup. Please wait...'

    outfile=/tmp/ora_out.$$
    /usr/bin/rm -f $outfile       2>/dev/null 1>&2

    retstat=0

    #
    # Need to separately back up SYS grants
    #
    export_sys_perms
    if [ $? -ne 0 ] ; then
        echolog 'Unable to backup database system permissions'
        return 1
    fi

    #
    # Create pipe for export
    #
    pipe=/tmp/pipe.$$

    create_pipe $pipe
    if [ $? -ne 0 ]; then
        return 1
    fi

    #
    # Output from pipe will be compressed and split into 2GB fragments as
    # necessary.
    #
    bakfile_base="${BACKUPDIR}/${DUMPFILE}.${COMPRESS_EXT}"
    /usr/bin/cat $pipe | $COMPRESS_CMD | /usr/bin/split -b ${CHUNK_SIZE}m -a 3 - ${bakfile_base}. &
    pipepid=$!

    #
    # Do the export
    #
    # NOTE: potential security issue with passwords on command line
    $DBEXP ${SYS_LOGIN}/${SYSPWD} full=y direct=y file=$pipe buffer=64000 2>$outfile 1>&2

    retstat=$?

    ora_scan_export_log $outfile
    if [ $? -ne 0 -o "$retstat" -ne 0 ]; then
        echolog 'Database export error' 
        retstat=2
    fi

    # If only one chunk was produced by the split, we might as well rename it
    # to a non-suffixed filename.
    count_fragments $bakfile_base

    get_dbfile_list
    if [ $? -ne 0 ] ; then
        echolog 'Unable to execute get_dbfile_list'
        print_failure_and_exit 1
    fi

    #
    # Clean up
    #
    shutdown_db
    kill $pipepid >/dev/null 2>&1
    /usr/bin/rm -f $pipe $outfile 2>/dev/null 1>&2
    return $retstat
}


backup_export_online ()
{
    start_db
    echolog 'Performing online export  backup. Please wait...'

    outfile=/tmp/ora_out.$$
    /usr/bin/rm -f $outfile       2>/dev/null 1>&2

    retstat=0

    #
    # Need to separately back up SYS grants
    #
    export_sys_perms
    if [ $? -ne 0 ] ; then
        echolog 'Unable to backup database system permissions'
        return 1
    fi

    #
    # Create pipe for export
    #
    pipe=/tmp/pipe.$$

    create_pipe $pipe
    if [ $? -ne 0 ]; then
        return 1
    fi

    #
    # Output from pipe will be compressed and split into 2GB fragments as
    # necessary.
    #
    bakfile_base="${BACKUPDIR}/${DUMPFILE}.${COMPRESS_EXT}"
    /usr/bin/cat $pipe | $COMPRESS_CMD | /usr/bin/split -b ${CHUNK_SIZE}m -a 3 - ${bakfile_base}. &
    pipepid=$!

    #
    # Do the export
    #
    # NOTE: potential security issue with passwords on command line
    $DBEXP ${SYS_LOGIN}/${SYSPWD} full=y direct=y file=$pipe buffer=64000 2>$outfile 1>&2

    retstat=$?

    ora_scan_export_log $outfile
    if [ $? -ne 0 -o "$retstat" -ne 0 ]; then
        echolog 'Database export error' 
        retstat=2
    fi

    # If only one chunk was produced by the split, we might as well rename it
    # to a non-suffixed filename.
    count_fragments $bakfile_base

    get_dbfile_list
    if [ $? -ne 0 ] ; then
        echolog 'Unable to execute get_dbfile_list'
        print_failure_and_exit 1
    fi

    #
    # Clean up
    #
    kill $pipepid >/dev/null 2>&1
    /usr/bin/rm -f $pipe $outfile 2>/dev/null 1>&2
    return $retstat
}



backup_online () 
{
    # Database needs to be open for this operation.
    echolog 'Performing on-line backup. Please wait...' 
    start_db

    # Set necessary variables
    # and get relevant information from dbase.cfg file
    DB_CHUNKS=1
    DBASE=${ESDIR}/cfg/dbase.cfg 
    DED_SVR=`/usr/bin/cat ${DBASE} | /usr/bin/grep archive_dedicated_server | /usr/bin/cut -f2 -d=`
    ARCHIVEDIR=`/usr/bin/cat ${DBASE} | /usr/bin/grep archivelog_dest | /usr/bin/cut -f2 -d=`
    BACKUP_SCRIPT=${TMP_SMC_DB_LOGS}/rman-backup.rcv.$$
    HOT_TAG=full-db-backup.$$
    DB_FORMAT=${BACKUPDIR}/smc_db_t%t_s%s_p%p
    ARCH_FORMAT=${BACKUPDIR}/smc_arc_t%t_s%s_p%p

    # Set permissions on a backup directory,
    # so it is writable by database owner.
    /usr/bin/chown $SMCORAU:$SMCORAG ${BACKUPDIR}
    if [ $? -ne 0 ]; then
       echolog "chown failed after changing the UID ansd GID of user - smcorau."
       return 1
    fi    

    # Generate  temporary backup script.
    echo "run {
allocate channel ch1 type disk;
allocate channel ch2 type disk;
backup
   tag '${HOT_TAG}'
   filesperset 20
   format '${DB_FORMAT}'
   (database);
 sql 'ALTER SYSTEM ARCHIVE LOG CURRENT';
 backup
    filesperset 20
    format '${ARCH_FORMAT}'
    (archivelog all
        delete input);
}" > ${BACKUP_SCRIPT}

    if [ $? -ne 0 ]; then    
       echolog 'Failed to create temporary file $2' ${BACKUP_SCRIPT}
       /usr/bin/rm -f ${BACKUP_SCRIPT}
       return 1
    fi

    # Fix the ownership to belong to database owner
    /usr/bin/chown $SMCORAU:$SMCORAG ${BACKUP_SCRIPT}
    if [ $? -ne 0 ]; then
       echolog "chown failed after changing the UID ansd GID of user - smcorau."
       /usr/bin/rm -f ${BACKUP_SCRIPT}
       return 1
    fi

    # Do the backup using RMAN utility.
    /usr/bin/su - $SMCORAU  -c ". $BASEDIR/sbin/es-common.sh; set_db_env;
                       rman target ${SYS_LOGIN}/${SYSPWD}@${DED_SVR} nocatalog @${BACKUP_SCRIPT}" >>$LOGFILE 2>/dev/null
    if [ $? -ne 0 ]; then
       echolog "Failed to perform online backup."
       /usr/bin/rm -f ${BACKUP_SCRIPT}
       return 1
    fi
  
    /usr/bin/rm -f ${BACKUP_SCRIPT}

    return 0 
}


#
# Create the backup directories if necessary
#
create_backup_dir() {
    if [ ! -d $BACKUPDIR/data ] ; then
        /usr/bin/mkdir -p $BACKUPDIR/data
        if [ $? -ne 0 ] ; then
            echolog 'Failed to create backup directory $2' "$BACKUPDIR/data"
            print_failure_and_exit 1
        fi
    fi
}


backup_cfg_files() {

    #
    # note ensure directories here are no followed by a slash
    #
    TARFILE="$BACKUPDIR/$CFGFILE"
    DIRSTOBACKUP="$ESDIR/cfg $ESDIR/db_upgrade"
    EXCLUDEFILE="/tmp/excludefiles.$$.0.txt"
    filelist="$DIRSTOBACKUP"

    counter=1
    while [ -f $EXCLUDEFILE ]
    do
         EXCLUDEFILE="/tmp/excludefiles.$$.$counter.txt"
         counter=`expr $counter + 1`
    done
    touch $EXCLUDEFILE

    #
    # ensure that all the database tables are not included in
    # this tar file
    #
    for excludefile in `echo $DBFILE_LIST`
    do
        echo "$excludefile" >> $EXCLUDEFILE
    done

    reports=""
    if [ "$PRM_EXISTS" ] ; then
        prm_datfiles1=`/usr/bin/find $ESDIR/PRM/agent -type f | /usr/bin/egrep '\.data?$'`
        prm_datfiles2=`/usr/bin/find $ESDIR/PRM/service -type f | /usr/bin/egrep '\.data?$'`
	prm_datalogfiles=`/usr/bin/find $ESDIR/PRM/agent -type f | /usr/bin/egrep '\.log$'`
	prm_cfgfiles1=`/usr/bin/find $ESDIR/PRM/agent -type f | /usr/bin/egrep cfg`
        prm_cfgfiles2=`/usr/bin/find $ESDIR/PRM/service -type f | /usr/bin/egrep cfg`
        filelist="$filelist $prm_datfiles1 $prm_datfiles2  $prm_datalogfiles $prm_cfgfiles1 $prm_cfgfiles2"
    	if [ -d $ESDIR/reports ] ; then
           reports=$ESDIR/reports 
    	fi 
    fi

    /usr/bin/tar cfX - $EXCLUDEFILE $filelist $reports | $COMPRESS_CMD > ${TARFILE}.Z 2>&1

    if [ $? -ne 0 ] ; then
        echolog 'Failed to backup cfg files. Check disk space.'
        rm -f $EXCLUDEFILE 2>/dev/null
        print_failure_and_exit 1
    fi

    rm -f $EXCLUDEFILE 2>/dev/null
}


###############################################
#
#   Main entry point
#
prog_base=`/usr/bin/basename $0`
common_cmd=`/bin/echo $0 | /usr/bin/sed s/$prog_base/es-common.sh/`
. $common_cmd

set_basedir
set_db_env
set_commondirs
create_temp_directory

NLS_LANG=AMERICAN_AMERICA.UTF8; export NLS_LANG

check_root

bak_common_cmd=`/bin/echo $0 | /usr/bin/sed s/$prog_base/es-backup-common/`
. $bak_common_cmd

check_logfile backup
export LOGFILE

set_backup_common
if [ $? -ne 0 ] ; then
    echolog 'Script initialization error'
    print_failure_and_exit 1
fi

cd "$BASEDIR"
PWD="$BASEDIR"; export PWD
PROGNAME=$0; export PROGNAME

DBEXP=$ORACLE_HOME/bin/exp

#
# Maximum export size (KB) is the maximum amount of data we shall
# export. Default = 15GB, as a safe cut-off point. Export backups
# are faster to make; 15GB should be around the size where importing
# an export backup will take much longer than restoring a cold backup.
# As a part of bug fix for 4748260, default 20G cutt off was changed to 15G.
#
# Chunk size is the maximum file size (in MB) to be created by 
# the export.
#
MAX_EXPORT_SIZE=`/usr/bin/expr 1024 \* 1024 \* 15`
CHUNK_SIZE=2048

# Minimum space required by backup (KB). This is mainly to account for
# inaccuracy in the estimation functions that may return values that are too
# small or negative.
MIN_BAKSIZE=1024

#
# Backup formats:
#	0	Old (not actually used in metafile, but used internally for
#		pre-3.5 backups)
#	1	Cold backup.
#	2	Exported database dump file.
#       3       On-line backup using RMAN.
#
# Compression schemes:
#	multi	cfg files and DB files are compressed separately; backup
#		dir consists of meta file and data/ subdirectory with
#		compressed archive files
#	single	the entire backup archive is compressed into a single
#		compressed file. (CURRENTLY NOT IMPLEMENTED)
#
BACKUP_FORMAT=0
COMPRESS_SCHEME=multi
COMPRESS_CMD="/usr/bin/compress"
COMPRESS_EXT="Z"
ZCAT_CMD="/usr/bin/zcat"
#COMPRESS_CMD="/usr/bin/gzip"
#COMPRESS_EXT="gz"
#ZCAT_CMD="/usr/bin/gzip -dc"

#
# what should ESDIR be based on -- is there some appropriate
# package parameter?
# NOTE: currently, this will "correctly" determine the /var/opt path for
# 3.0 (where $ESDIR is not set by es-common.sh) and 3.5, where $ESDIR is
# already set.
#
ESDIR=${ESDIR-/var/opt/SUNWsymon}
BACKUPDIR=${ESDIR}/backup

#
# Parse command-line options
#
interactive=1

while getopts cd:erovyh OPT ; do
    case $OPT in
      c)
        BACKUP_FORMAT=1
        ;;
      d)
       	BACKUPDIR=$OPTARG
        ;;
      e)
        BACKUP_FORMAT=2
        ;;
      r)
        BACKUP_FORMAT=4
        ;;
      o)
        BACKUP_FORMAT=3
        validate_archivelog_mode
        if [ $? -ne 0 ]; then
           exit 1
        fi
        ;;
      v)
        VERBOSE=ON
        ;;
      y)
	interactive=0
        ;;
      h)
        /bin/echo ""
        print_usage
        exit 1
        ;;
      *)
        /bin/echo ""
        print_usage
        exit 1
        ;;
    esac
done

DEFAULT_BACKUPDIR=${BACKUPDIR}
umask 022

#
# Make sure that we only have one instance of es-backup/es-restore running.
#
check_process_conflicts es-backup
if [ $? -ne 0 ] ; then
    echolog 'Conflicting process found: es-backup'
    echolog 'Only one instance of es-backup should be running at a time.'
    print_failure_and_exit 1
fi

# In case the es-restore of online backup is again running es-backup -o  
if [ "$BACKUP_AGAIN" != "true" ]; then
check_process_conflicts es-restore

if [ $? -ne 0 ] ; then
    echolog 'Conflicting process found: es-restore'
    echolog 'es-backup should not be run at the same time as es-restore.'
    print_failure_and_exit 1
fi

fi

#
# Prepare backup directory
#

if [ $interactive -eq 0 ] ; then
    #
    # non-interactive mode
    #
    if [ $BACKUP_FORMAT -ne 3 -a $BACKUP_FORMAT -ne 4 ]; then

       echolog ""
       echolog 'Shutting down Sun Management Center.'
       stop_SunMC
       if [ $? -ne 0 ]; then
          echolog 'Error stopping Sun Management Center....'
          print_failure_and_exit 1
       fi

    fi 

    #
    # create backup directory if necessary
    #
    if [ ! -d $BACKUPDIR ]; then
        create_backup_dir

    #
    # ensure directory is empty
    #

    else
       online_backup_files=`/usr/bin/ls $BACKUPDIR/smc_* 2> /dev/null`
       if  [ -f $BACKUPDIR/$METAFILE -o -f $BACKUPDIR/sunmc.dmp -o -d $BACKUPDIR/data -o ! -z "$online_backup_files" ]; then

           echolog 'Replacing old backup.'
           /usr/bin/rm -f $BACKUPDIR/$METAFILE* $BACKUPDIR/sunmc.dmp
           /usr/bin/rm -f $BACKUPDIR/smc_*
           /usr/bin/rm -rf $BACKUPDIR/data
      fi
    fi

else 
    #
    # interactive mode
    #
    if [ $BACKUP_FORMAT -ne 3 -a $BACKUP_FORMAT -ne 4 ]; then
    
       echolog ""
       echolog 'Sun Management Center must be shutdown to backup data.'
       get_input_from_user "Do you want to proceed [y/n]:"
       if [ "$answer" = "y" ] ; then
           stop_SunMC
           if [ $? -ne 0 ]; then
               echolog 'Error stopping Sun Management Center....'
               print_failure_and_exit 1
           fi
       else
           exit 0
       fi
    fi

 selection_done=""

 while [ -z "$selection_done" -o "$selection_done" = ""  ]
 do
    while [ "$backupdir_flag" = "" ]
    do
        get_input_from_user 'Enter full directory path to store the backup data files[$2]:' "$DEFAULT_BACKUPDIR"
        if [ -z "$answer" ] ; then
            #
            # use default backup directory
            #
            backupdir_flag="done"
	    BACKUPDIR="$DEFAULT_BACKUPDIR"
        else
            /bin/echo "$answer" | /usr/bin/grep "^/" > /dev/null 2>&1
	    if [ $? -ne 0 ] ; then
                echolog "The backup directory path must start with /"
                continue
            fi

            /bin/echo "$answer" | /usr/bin/grep " " > /dev/null 2>&1 
            if [ $? -eq 0 ] ; then
                echolog "Invalid directory name"
                continue
            fi

            if [ "$answer" = "/" ] ; then
                echolog "Invalid directory name: /"
                continue
            fi

            backupdir_flag="done"
            BACKUPDIR="$answer"
        fi
    done

    #
    # Create backup directory, if it does not already exist
    #
    if [ ! -d "$BACKUPDIR" ] ; then
        answer=0
	echolog 'The directory $2 does not exist' "$BACKUPDIR"
	ask_user "Do you want to create it "

        if [ $answer -eq 0 ] ; then
            echolog 'Backup directory not created. Exiting.'
	    exit 1
        fi

        break

    #
    # Clean out any old files from backup directory
    #

    elif [ -f $BACKUPDIR/$METAFILE -o -f $BACKUPDIR/sunmc.dmp -o -d $BACKUPDIR/data -o ! -z "`/usr/bin/ls $BACKUPDIR/smc_* 2> /dev/null`" ] ; then
       	echolog 'The directory $2 contains previous backups.' "$BACKUPDIR"
       	ask_user "Delete old backups "

       if [ "$answer" -eq 1 ] ; then
           /usr/bin/rm -f $BACKUPDIR/$METAFILE*
           /usr/bin/rm -f $BACKUPDIR/sunmc.dmp
           /usr/bin/rm -f $BACKUPDIR/smc_*
           /usr/bin/rm -rf $BACKUPDIR/data
           selection_done="done"
       elif [ "$answer" -eq 0 ] ; then
           #The answer is 'no' in this case.
	   #Return user to the directory selection.
           backupdir_flag=""
       else
           selection_done="done"
           echolog 'Exiting upon user request'
           exit 1
       fi
    else
	#Backup directory exists and is empty.
	selection_done="done"
    fi
 
 done

fi

#
# Create backup directories, if necessary
#
create_backup_dir

#
# Estimate how much space is required for backup
#
compute_db_size
if [ $? -ne 0 ] ; then
    echolog 'Unable to determine current database size.'
    echolog 'es-backup will not be able to estimate the amount of disk space required for the backup.'

    if [ "$interactive" -eq 1 ] ; then
        ask_user "Do you wish to proceed with the backup anyway "
        if [ "$answer" -ne 1 ] ; then
            echolog 'Exiting upon user request'
            exit 1
        fi
    else
        print_failure_and_exit 1
    fi
else
    DB_SIZE=$usize
    echologverbose 'Database data size: $2 KB' "$usize"

    # If backup format is not determined yet, we decide by checking if the
    # database size is greater than the threshold $MAX_EXPORT_SIZE.
    if [ -z "$BACKUP_FORMAT" -o "$BACKUP_FORMAT" -eq 0 ] ; then
        if [ "$DB_SIZE" -gt "$MAX_EXPORT_SIZE" ] ; then
            BACKUP_FORMAT=1
        else
            BACKUP_FORMAT=2
        fi
    fi
    
    # Only estimate the export size.
    # Cold backup size will not be estimated.
    # Part of the fix forthe bug #4748260, crt-oracle_db-01-03-21-2003.txt

    if   [ "$BACKUP_FORMAT" -eq 2  -o "$BACKUP_FORMAT" -eq 4 ] ; then
        estimate_export_size $DB_SIZE
        if [ $? -ne 0 ] ; then
            echolog 'Error while estimating database export size'
            print_failure_and_exit 1
        fi

        GUESS_BAKSIZE=$exportsize
    fi

    echologverbose 'Estimated backup size: $2 KB' "$GUESS_BAKSIZE"

    #
    # Determine available disk space on backup partition
    # 
    availKB=`/usr/bin/df -k $BACKUPDIR | /usr/bin/sed -e '1d' | /usr/bin/awk '{print $4}'`
    if [ $? -ne 0 ]; then
        echolog "Error to computing available disk space"
        print_failure_and_exit 1 
    fi

    echologverbose 'Available disk space on $2: $3 KB' "$BACKUPDIR" "$availKB"

    if [ "$GUESS_BAKSIZE" -gt "$availKB" ] ; then
        echolog ''
        if [ "$interactive" -eq 1 ] ; then
            echolog 'The estimated backup size $2 KB is larger than the available space in $3.' "$GUESS_BAKSIZE" "$BACKUPDIR"
            echolog 'There may not be enough space to store the backup.'

            ask_user "Abort backup "
            if [ "$answer" -eq 1 ] ; then
                echolog 'Exiting upon user request.'
                print_failure_and_exit 1
            fi
        else
            echolog 'Insufficient disk space in $2. Aborting.' "$BACKUPDIR"
            print_failure_and_exit 1
        fi
    fi
fi

#
# Get all the user names that are about to be backed up.
#
start_db 
get_db_users_list

#
# Backup Sun Management Center database
#
setup_backup_format $BACKUP_FORMAT
if [ "$BACKUP_FORMAT" -eq 1 ] ; then
    #
    # Run db_verify and perform cold backup
    #
    cold_backup

elif [ "$BACKUP_FORMAT" -eq 2 ] ; then
    #
    # Export DB data
    #
    backup_export
    if [ $? -ne 0 ] ; then
        print_failure_and_exit 1
    fi

elif [ "$BACKUP_FORMAT" -eq 4 ] ; then
    #
    # Export DB data online 
    #
    backup_export_online
    if [ $? -ne 0 ] ; then
        print_failure_and_exit 1
    fi

elif [ "$BACKUP_FORMAT" -eq 3 ] ; then
    #
    # Do on-line backup using RMAN.
    #
    backup_online
    if [ $? -ne 0 ] ; then
        print_failure_and_exit 1
    fi

else
    echolog 'Unknown backup format $2' "$BACKUP_FORMAT"
    print_failure_and_exit 1
fi

#
# Backup Sun Management Center cfg files
#
backup_cfg_files

#
# Create Backup Meta File
#
create_backup_meta
if [ $? -ne 0 ] ; then
    print_failure_and_exit 1
fi

echolog 'Backup is successful.'
echolog 'Backup data is saved at the following Sun Management Center backup files:'
echolog ''

/usr/bin/find $BACKUPDIR -type f -print | /usr/bin/tee -a $LOGFILE

/usr/bin/sleep 5

echolog ''
if [ $BACKUP_FORMAT -ne 3 -a $BACKUP_FORMAT -ne 4 ]; then
echolog 'Starting Sun Management Center....'
echolog ''

start_SunMC
if [ $? -ne 0 ]; then
    echolog 'Error starting Sun Management Center....'
    exit 1
fi
fi


exit 0
