# $Header: archfull.tcl 06-jun-00.10:56:34 jmansur Exp $
#
# copyright (c) 1999 by the Oracle Corporation
#
# NAME:
#
#  archfull.tcl : Event tcl file that checks if the archive device is full
#
# ARGUMENTS:
#           argv(0) == connect string
#           argv(1) == threshold value for alert
#           argv(2) == threshold value for warning
#
# RETURN:
#           $SCRIPT_FAIL or
#           $CLEAR_EVENT or
#           $NO_EVENT or
#           $WARNING_EVENT or
#           $ALERT_EVENT
#
# OUTPUT:
#           The free space left on the archive device.
#
# $Log:  $
# Revision 1.7  1996/06/24  23:56:22  yliu
# fixed bug 370148
#
# Revision 1.6  1996/03/07  22:57:16  yliu
# fixed archive file name problem
#
# Revision 1.5  1996/02/07 01:57:14  yliu
# use character set conversion
#
# Revision 1.4  1996/01/10  02:12:28  yliu
# use message file
#
# Revision 1.3  1995/10/25 18:20:42  yliu
# add connect string to the parameter list
#
# Revision 1.2  1995/09/28  20:45:25  yliu
# use message file
#

# Event definition
oradefine event /oracle/rdbms/space/archfull description=VOC-01021 \
report=VOC-01022 frequency=600
oraarguments connect_str alert_threshold warning_threshold
oravardesc connect_str oracle_signon
oravardesc alert_threshold int minimum=0 default=2000 message=VOC-01023
oravardesc warning_threshold int minimum=0 default=5000 message=VOC-01024
oraresults space_left
oravardesc space_left int
orafixit /oracle/rdbms/space/movearch
oradefine end


# Initialize global variables
#comment out to fix bug#606739
#set last_report $CLEAR_EVENT
set output ""
oraeventpersist last_alerts {}
oraeventpersist last_warnings {}


# The main event checking functions
proc EvalEvent {} {


    # Declare globals we will use
    global argv last_report output
    global SCRIPT_FAIL CLEAR_EVENT NO_EVENT WARNING_EVENT ALERT_EVENT
    global oramsg env
    global last_alerts last_warnings


    # initialize the return code and output
    set ret_code $CLEAR_EVENT
    set output ""
    set err ""
    set db_version ""
    set alerts {}
    set warnings {}

    # Check if the archive mode is on
    set connect [format "%s@%s" [lindex $argv 0] $oramsg(oraobject)]
    if {[catch {oralogon $connect} lda]} {
        lappend output [msgtxt [RDBMS] ora $oramsg(rc)] ""
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    if {[catch {set cur [oraopen $lda]} err]} {
        lappend output $err
        catch {oralogoff $lda} err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    set sql {select log_mode from v$database}
    if {[catch {orasql $cur $sql}]} {
        lappend output [convertout $oramsg(db_characterset) \
            $oramsg(errortxt)] $sql
        catch {oraclose $cur} err
        catch {oralogoff $lda} err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    if {[catch {set row [orafetch $cur]} err]} {
	lappend output $err
        catch {oraclose $cur} err
        catch {oralogoff $lda} err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    # verify database is operating in ARCHIVELOG mode
    if {[string compare [lindex $row 0] "ARCHIVELOG"] != 0} {
        if {$last_report == $SCRIPT_FAIL} {
            catch {oraclose $cur} err
            catch {oralogoff $lda} err
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            lappend output [msgtxt [NETWORK] nms 1012] ""
            catch {oraclose $cur} err
            catch {oralogoff $lda} err
            return $SCRIPT_FAIL
        }
    }

    # get the database version
    if {[catch {set db_version [DB_VERSION]} err]} {
        lappend output $err
        catch {oraclose $cur} err
        catch {oralogoff $lda} err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    # get the log_archive_dest location
    if {[string compare $db_version "73"] == 0} {
      if {[catch {set all_arch_dest [ARCHIVE_DEST]} err]} {
        lappend output $err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
      }
      ORATCL_DEBUG "archfull : $oramsg(oraobject) : [oratime] : destination = $all_arch_dest"
    } else {
        if {[string compare $db_version "81"] >= 0} {
            set sql {select destination from v$archive_dest
                     where status = 'VALID' and target != 'STANDBY'}
        } elseif {[string compare $db_version "80"] >= 0} {
            set sql {select destination from v$archive_dest
                     where status = 'NORMAL'} 
        }

        if {[catch {orasql $cur $sql}]} {
            lappend output [convertout $oramsg(db_characterset) \
                $oramsg(errortxt)] $sql
            catch {oraclose $cur} err
            catch {oralogoff $lda} err
            if {$last_report == $SCRIPT_FAIL} {
                return $NO_EVENT
            } else {
                set last_report $SCRIPT_FAIL
                return $SCRIPT_FAIL
            }
        }

        if {[catch {set row [orafetch $cur]} err]} {
            lappend output $err
            catch {oraclose $cur} err
            catch {oralogoff $lda} err
            if {$last_report == $SCRIPT_FAIL} {
                return $NO_EVENT
            } else {
                set last_report $SCRIPT_FAIL
                return $SCRIPT_FAIL
            }
        }

        if {$oramsg(rows) == 0} {
            lappend output [format [msgtxt [NETWORK] nms 1005] archfull.tcl]
            lappend output [msgtxt [NETWORK] nms 1083]
            catch {oraclose $cur} err
            catch {oralogoff $lda} err
            if {$last_report == $SCRIPT_FAIL} {
                return $NO_EVENT
            } else {
                set last_report $SCRIPT_FAIL
                return $SCRIPT_FAIL
            }
        }

        while {$oramsg(rc) == 0} {
            set arch_dest [lindex $row 0]
            ORATCL_DEBUG "archfull : $oramsg(oraobject) : [oratime] : destination is $arch_dest"

            lappend all_arch_dest $arch_dest 
            if {[catch {set row [orafetch $cur]} err]} {
                lappend output $err
                catch {oraclose $cur} err
                catch {oralogoff $lda} err
                if {$last_report == $SCRIPT_FAIL} {
                    return $NO_EVENT
                } else {
                    set last_report $SCRIPT_FAIL
                    return $SCRIPT_FAIL
                }
            }
        }
    }

    # log off
    catch {oraclose $cur} err
    catch {oralogoff $lda} err

    # get the disk usage
    if { [catch {diskusage $all_arch_dest} disk_usage] } {
        lappend output [format [msgtxt [NETWORK] nms 1005] archfull.tcl]
        lappend output [msgtxt [NETWORK] nms 1078]
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    # print out event trace info 
    ORATCL_DEBUG "archfull : $oramsg(oraobject) : [oratime] : [lindex $disk_usage 2]"

    # Check for thresholds
    set i 0
    set number_dest [llength $all_arch_dest]
    while {$i < $number_dest} {
        set avail [lindex [lindex $disk_usage 2] $i]
        set disk [lindex [lindex $disk_usage 3] $i]
        if {$avail < [lindex $argv 1]} {
            set ret_code $ALERT_EVENT
            lappend disk_avail $avail
            lappend alerts $disk
        } elseif {$avail < [lindex $argv 2]} {
            if { $ret_code != $ALERT_EVENT } {
                set ret_code $WARNING_EVENT
            }
            lappend disk_avail $avail
            lappend warnings $disk
        }
        incr i
    }

    # return
    if {![string compare $last_warnings $warnings] && \
        ![string compare $last_alerts $alerts] &&
        $ret_code == $last_report } {
        return $NO_EVENT
    } else {
        if {($ret_code == $ALERT_EVENT) ||
            ($ret_code == $WARNING_EVENT)} {
            lappend output $disk_avail
        }

        ORATCL_DEBUG "archfull : $oramsg(oraobject) : [oratime] : MESSAGE - $ret_code, $output"
        set last_report $ret_code
        set last_warnings $warnings
        set last_alerts $alerts
        return $ret_code
    }

}

