#!/bin/sh
# Copyright 06/01/04 Sun Microsystems, Inc. All Rights Reserved.
# pragma ident  "@(#)db-config-archive.sh	1.1 04/06/01 Sun Microsystems"

# This file is to be used through es-config by the users who wish to configure their 
# database to run in archivelog mode. This is done in order to enable on-line backups.
#
# Usage db-config-archive -edh
#     where the options represent:
#     e : enables ARCHIVELOG option for the database.
#     d : disables ARCHIVELOG option for the database.
#

print_usage() {
    /bin/echo ""
    eval /bin/echo `/usr/bin/gettext 'Usage: $prog_base [-h | -e | -d]'`
    /usr/bin/gettext '     -h      : Prints this usage.\n'
    /usr/bin/gettext '     -e      : Use to enable ARCHIVELOG mode.\n'
    /usr/bin/gettext '     -d      : Use to disable current ARCHIVELOG mode\n'
    /bin/echo ""
}

get_directory_name () {

    selection_done=""
    archivedir_flag=""

    while [ -z "$selection_done" -o "$selection_done" = ""  ]
    do

        #
        # ask user for directory as necessary
        #
        while [ "$archivedir_flag" = "" ]
        do
            echolog ''
            get_input_from_user 'Enter full directory path to store the archivelog files:' 
            if [ -z "$answer" ] ; then
                # User will be prompted again.
                archivedir_flag=""
            else
                /bin/echo "$answer" | /usr/bin/grep "^/" > /dev/null 2>&1
                if [ $? -ne 0 ] ; then
                    echolog "The archive 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" = "/" -o "$answer" = "/tmp" ] ; then
                    echolog 'Invalid directory name: $2' "$answer"
                    continue
                fi

                archivedir_flag="done"
                ARCHIVEDIR="$answer"
            fi
        done

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

            if [ $answer -eq 0 ] ; then
                echolog 'Archive directory not created.'
                archivedir_flag=""
                selection_done=""   
            else
                /usr/bin/mkdir -p "$ARCHIVEDIR" > /dev/null 2>&1
                if [ $? -ne 0 ]; then
                   echolog 'Archive directory not created.'
                   echolog 'Exiting...'
                   exit 1
                fi
                break
            fi

        else

            #
            # Clean out any old files from pre-existing archive directory.
            #
            archivelogs_present=`/usr/bin/ls -1 $ARCHIVEDIR/*.smcarc 2> /dev/null | /usr/bin/wc -l` 

            if [ "$archivelogs_present" -gt 0 ] ; then
                echolog 'The directory $2 contains previous archives.' "$ARCHIVEDIR"
                ask_user "Delete old archives "

                if [ "$answer" -eq 1 ] ; then
                    /usr/bin/rm -f $ARCHIVEDIR/*.smcarc
                    selection_done="done"
                elif [ "$answer" -eq 0 ] ; then
                    # The answer is 'no' in this case.
                    # Return user to the directory selection.
                    archivedir_flag=""
                else
                    echolog 'Exiting upon user request'
                    exit 1
                fi
            else

                #
                #  no old files to delete
                #
                selection_done="done"
            fi
        fi
    done

    # Once the directory is setup, change ownership to database owner.
    /usr/bin/chown $SMCORAU:$SMCORAG $ARCHIVEDIR

    if [ $? -ne 0 ] ; then
        echolog 'Error setting permissions on $2.' "$ARCHIVEDIR"
        echolog 'Exiting...'
        exit 1
    fi
}

setup_ora_files () {

    # Configure tnsname.ora file with a dedicated server connection.
    # In case of adding archiving information to the ora files,
    # This file is better updated first, before updating init.ora file. 

    # Check if tnsnames,ora has already been updated.
    updated_tnsnames=`/usr/bin/cat $TNS_FILE | /usr/bin/grep "SunMC dedicated server connection:"`
    if [ -z "$updated_tnsnames" ]; then

        #
        # tnsname.ora has not been updated, perform update
        #

        # Backup existing tnsname.ora file.
        /usr/bin/su - $SMCORAU -c ". $BASEDIR/sbin/es-common.sh; set_db_env; cp $TNS_FILE $TNS_FILE.arch"
        if [ $? -ne 0 ]; then 
            echolog 'Failed to copy $2 to $3' "$TNS_FILE" "$TNS_FILE.arch"
            echolog "Cannot proceed with current task. Exiting."
            return 1
        fi

        echo "# SunMC dedicated server connection:
$SMCDB_DED_SERVER =
   (DESCRIPTION =
    (ADDRESS_LIST =
       (ADDRESS = (PROTOCOL = TCP)(HOST = $SMCDB_HOST)(PORT = $SMCDB_PORT))
    )
     (CONNECT_DATA = (SERVICE_NAME = $SMCDB_NAME)(SERVER = DEDICATED)
     )
   )" >> $TNS_FILE

        if [ $? -ne 0 ]; then
            echolog 'Error while updating file $2' "$TNS_FILE"
            echolog "Cannot proceed with current task. Exiting."
            return 1
        fi
    fi

    # Check if init.ora has already been updated.
    init_archive_start=`/usr/bin/grep "ARCHIVE_START" $INIT_FILE`
    init_archive_dest=`/usr/bin/grep "ARCHIVE_DEST" $INIT_FILE`
    init_archive_format=`/usr/bin/grep "ARCHIVE_FORMAT" $INIT_FILE`

    # If at least one of the entries is not present, then update the init.ora file with it.
    if [ -z "$init_archive_start" -o -z "$init_archive_dest" -o -z "$init_archive_format" ]; then

        # Backup existing init.ora file.
        /usr/bin/su - $SMCORAU -c ". $BASEDIR/sbin/es-common.sh; set_db_env; cp $INIT_FILE $INIT_FILE.arch"
        if [ $? -ne 0 ]; then 
            echolog 'Failed to copy $2 to $3' "$INIT_FILE" "$INIT_FILE.arch"
            echolog "Cannot proceed with current task. Exiting."
            return 1
        fi

        # Configure init.ora file with necessary additional parameters.
        if [ -z "$init_archive_start" ]; then 

            echo "
LOG_ARCHIVE_START=true" >> $INIT_FILE

            if [ $? -ne 0 ]; then
                echolog 'Error while updating file $2' "$INIT_FILE"
                echolog "Cannot proceed with current task. Exiting."
                return  1
            fi
        fi

        if [ -z "$init_archive_dest" ]; then
            echo "LOG_ARCHIVE_DEST=$ARCHIVEDIR" >> $INIT_FILE

            if [ $? -ne 0 ]; then
                echolog 'Error while updating file $2' "$INIT_FILE"
                echolog "Cannot proceed with current task. Exiting."
                return  1
            fi
        fi

        if [ -z "$init_archive_format" ]; then
            echo "LOG_ARCHIVE_FORMAT=arch_%s.smcarc" >> $INIT_FILE

            if [ $? -ne 0 ]; then
                echolog 'Error while updating file $2' "$INIT_FILE"
                echolog "Cannot proceed with current task. Exiting."
                return  1
            fi
        fi
    fi

    return 0
}

reset_ora_files () {

    # Restore original ora files from <file_name>.arch
    return_code=0

    #
    # restore TNS_FILE if possible
    #
    if [ -f "$TNS_FILE.arch" ]; then 
        /usr/bin/su - $SMCORAU -c ". $BASEDIR/sbin/es-common.sh; set_db_env; cp $TNS_FILE.arch $TNS_FILE"
        if [ $? -ne 0 ]; then
            echolog 'Unable to restore file $2 from $3.' "$TNS_FILE" "$TNS_FILE.arch"
            return_code=1
        else
            # Clean up backed up file.
            /usr/bin/rm -f ${TNS_FILE}.arch
        fi
    else
        echologverbose '$2 file does not exist' "$TNS_FILE.arch"
    fi


    #
    # restore INIT_FILE if possible
    #
    if [ -f "$INIT_FILE.arch" ]; then  
        /usr/bin/cat "$INIT_FILE.arch" | /usr/bin/grep -v "LOG_ARCHIVE_" > "$INIT_FILE"
        if [ $? -ne 0 ]; then
            echolog 'Unable to restore file $2 from $3.' "$INIT_FILE" "$INIT_FILE.arch"
            return_code=1
        else
            # Clean up backed up file.
            /usr/bin/rm -f ${INIT_FILE}.arch
        fi
    else 
        echologverbose '$2 file does not exist' "$INIT_FILE.arch"
    fi

}


update_dbase_file () {

    if [ "$setting" = "disable" ]; then

        # Remove all the archiving info from the dbase,cfg file.
        # Can not just copy backed up file over, need to do a merge.
        /usr/bin/cat ${DBASE} | /usr/bin/grep -v '^archive' > ${DBASE}.tmp 
        if [ $? -ne 0 ]; then 
            echolog 'Failed to update $2 file.' "$DBASE".tmp
            /usr/bin/rm -f ${DBASE}.tmp
            return 1
        fi
    
        /usr/bin/cat ${DBASE}.tmp > ${DBASE}
        if [ $? -ne 0 ]; then
            echolog  'Unable to restore file $2 from $3.' "$DBASE" ${DBASE}.tmp
            /usr/bin/rm -f ${DBASE}.tmp
            return 1
        fi
    
        /usr/bin/rm -f ${DBASE}.tmp
    
    elif [ "$setting" = "enable" ]; then

        # Update dbase.cfg file with archiving destination and dedicated server name.
        echo "archivelog_mode=ON
archivelog_dest=${ARCHIVEDIR}
archive_dedicated_server=${SMCDB_DED_SERVER}" >> ${DBASE}  

        if [ $? -ne 0 ]; then 
           echolog 'Failed to update $2 file.' "$DBASE"
           return 1
        fi
    fi
}

post_backup_message () {
 
    echolog ""
    echolog "It is strongly recommended that you run cold backup before setting database in ARCHIVELOG mode."
    echolog "You can quit now, run es-backup -c and return to re-run this script."
    echolog ""
    echolog "If you have already completed steps listed above, you can continue to setup requested mode."
    ask_user "Would you like to continue to setup database in ARCHIVELOG mode "

    if [ "$answer" -ne 1 ] ; then
        exit 0
    fi 
}

set_archivelog_mode () {

    if [ "$setting" = "enable" ]; then 
        arch_flag=""
    elif [ "$setting" = "disable" ]; then
        arch_flag=no
    fi

    # This needs to be done while database is in mount mode, not open.

    db_mountDb
    if [ $? -ne 0 ]; then
        return 1
    fi
    
    oratmp=/tmp/db-unset.$$
    /usr/bin/rm -f $oratmp
  
    /usr/bin/su - $SMCORAU  -c ". $BASEDIR/sbin/es-common.sh; set_db_env;
                        $ORACLE_HOME/bin/sqlplus -s /nolog<<EOF>$oratmp 2>/dev/null
connect / as sysdba;
set verify off;
set echo off;
set feedback off;
alter database ${arch_flag}archivelog;
EOF"
  
    if [ $? -ne 0 ]; then
        echolog ''
        echolog 'Failed to alter database to $2 archivelog mode.' "$setting"
        /usr/bin/rm -f $oratmp
        return 1
    fi
 
    db_checkErr $oratmp $LOGFILE

    if [ $? -ne 0 ]; then
        echolog ''
        echolog 'Failed to alter database to $2 archivelog mode.' "$setting"
        /usr/bin/rm -f $oratmp
        return 1

    elif [ "$setting" = "disable" ]; then

        # In case of successfully disabled archivelog mode,
        # Clean up archivelog files generated by it so far.
        if [ ! -z ${ARCHIVEDIR} -a -d ${ARCHIVEDIR} ] ; then
            /usr/bin/rm -f ${ARCHIVEDIR}/*.smcarc 
            rmdir_if_empty ${ARCHIVEDIR}
        fi
    fi

    /usr/bin/su - $SMCORAU  -c ". $BASEDIR/sbin/es-common.sh; set_db_env;
                        $ORACLE_HOME/bin/sqlplus -s /nolog<<EOF>$oratmp 2>/dev/null
connect / as sysdba;
set verify off;
set echo off;
set feedback off;
shutdown immediate;
EOF"

    if [ $? -ne 0 ]; then
        echolog ''
        echolog 'Failed to alter database to $2 archivelog mode.' "$setting"
        /usr/bin/rm -f $oratmp
        return 1
    fi

    /usr/bin/rm -f $oratmp

    return  0
}

###############################################
#
#   Main entry point
#
# Environment of this script:
#
prog_base=`/usr/bin/basename $0`
PROGNAME=$0
BASEDIR=`/usr/bin/pkgparam SUNWescom BASEDIR`
SCRIPT_DIR=${BASEDIR}/SUNWsymon/lib/sbin

. ${BASEDIR}/SUNWsymon/sbin/es-common.sh
. ${SCRIPT_DIR}/db-common.sh

set_basedir
set_db_env
set_commondirs
create_temp_directory
set_db_password

NLS_LANG=AMERICAN_AMERICA.UTF8; export NLS_LANG
LOGFILE="$VAROPTDIR/install/db-conf-archiving.$$"
INIT_FILE="$ORACLE_HOME/admin/SunMC/pfile/initSunMC.ora"
TNS_FILE="$ORACLE_HOME/network/admin/tnsnames.ora"
DBASE=${ESDIR}/cfg/dbase.cfg
SMCDB_HOST=`/usr/bin/cat ${DBASE} | /usr/bin/grep host | /usr/bin/cut -f2 -d=`
SMCDB_PORT=`/usr/bin/cat ${DBASE} | /usr/bin/grep port | /usr/bin/cut -f2 -d=`
SMCDB_NAME=`/usr/bin/cat ${DBASE} | /usr/bin/grep database | /usr/bin/cut -f2 -d=`
ARCHIVEDIR=`/usr/bin/cat ${DBASE} | /usr/bin/grep archivelog_dest | /usr/bin/cut -f2 -d=`
SMCDB_DED_SERVER=SUNMC_DED


#
# Parse command-line options
#
setting=""

while getopts ed OPT ; do
    case $OPT in
        e)
            setting="enable"
            ;;
        d)
            setting="disable"
            ;;
        *)
            /bin/echo ""
            print_usage
            exit 1
            ;;
    esac
done

# verify a valid option selected
if [ -z "$setting" ]; then
    print_usage
    exit 1
fi

umask 022

# Verify the mode that database is currently in.

db_start_database

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

/usr/bin/su - $SMCORAU -c ". $BASEDIR/sbin/es-common.sh; set_db_env;
    $ORACLE_HOME/bin/sqlplus -s /nolog <<EOF 
	connect / as sysdba
	set pagesize 0
 	set heading off
	set echo off
	set feedback off
	set termout off
        spool $sqlout
	select log_mode from v\\\$database;
EOF
      ">> $LOGFILE 2>&1 

if [ $? -ne 0 ] ; then
    echolog""
    echologverbose 'Unable to retrieve log mode from Sun Management Center database'
else
    LOG_MODE=`/usr/bin/grep 'ARCHIVELOG' $sqlout`
    if [ -z "$LOG_MODE" ]; then
        echologverbose 'Unable to retrieve log mode from Sun Management Center database'
    else
        echolog ""
        echolog 'The database currently appears to be in $2 mode.' "$LOG_MODE"
        get_input_from_user "Do you want to proceed to $setting archiving [y/n]:"
        if [ "$answer" != "y" ] ; then
            /usr/bin/rm -f $sqlout
            echolog 'Exiting...'
            exit 0
        fi
    fi
fi

/usr/bin/rm -f $sqlout

echolog ""
    $BASEDIR/sbin/es-stop -A 
    if [ $? -ne 0 ]; then
        echolog 'Error stopping Sun Management Center....'
        exit 1
    fi

if [ "$setting" = "enable" ]; then
   
    post_backup_message
    get_directory_name
    setup_ora_files

    if [ $? -ne 0 ]; then
        # Restore original backed up ora files from <filename>.arch
        reset_ora_files
        exit 1
    fi

elif [ "$setting" = "disable" ]; then

    reset_ora_files

fi

set_archivelog_mode
if [ $? -eq 0 ]; then

    # Archivelog mode operation was successful.
    # Update dbase.cfg file according to whether archivelog
    # was enabled or disabled.
    update_dbase_file 

    echolog ""
    echolog 'Archivelog mode has been successfully $2d.' "$setting"
    echolog ""

elif [ $? -ne 0 -a "$setting" = "enable" ]; then

    # In this case user attempted to enable archiving and it failed.
    # Will need to clean up changes made to the ora files so far.
    # There is nothing can be done in case when disabling of archivelog failed,
    # other then re-trying the procedure. Procedure to disable archivelog mode
    # is re-runable without harm.

    reset_ora_files

    exit 1
fi


    echolog 'Re-starting Sun Management Center...'
    $BASEDIR/sbin/es-start -A
    if [ $? -ne 0 ] ; then
        echolog 'Failed to restart Sun Management Center.'
        exit 1
    fi

exit 0
