# $Header: alert.tcl 29-mar-99.04:10:13 dholail Exp $
#
# copyright (c) 1999 by the Oracle Corporation
#
# NAME:
#
#  alert.tcl : Event tcl file that checks if errors exist in the alert file
#
# ARGUMENTS:
#           None    
#
# RETURN:
#           $CLEAR_EVENT or
#           $NO_EVENT or
#           $WARNING_EVENT or
#           $ALERT_EVENT
#
# OUTPUT:
#           The error messages from the alert files.
# $Log:  $
#
# Revision 1.5  1998/02/10  groyal
# missing alert file should not be a script failure
#
# Revision 1.4  1996/01/09  23:59:49  yliu
# use oramsg(orahome)
#
# Revision 1.3  1995/10/19 00:17:50  yliu
# moved the init code into EvalEvent
#
# Revision 1.2  1995/09/28  20:28:58  yliu
# use message file
#
# Revision 1.1  1995/09/07  17:19:27  yliu
# Initial revision
#


# Event definition
oradefine event /oracle/rdbms/fault/alert description=VOC-01011 \
report=VOC-01012
oraresults output
oradefine end


# Initialize global variables
#comment out to fix bug#606739
#set last_report $NO_EVENT
set output ""
oraeventpersist last_alert_size -1


# The main event checking functions
proc EvalEvent {} {


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


    # initialize the return code and output
    set ret_code $NO_EVENT
    set output ""
    set alertfile ""
    set err ""

    # set related variables
    set alert_errors {ORA-006 ORA-01578 ORA-00060}
    set warning_errors {ORA-}

    if {[catch {set alertfile [ALERTFILE]} err]} {
	lappend output $err
        if {$last_report == $SCRIPT_FAIL} {
	    return $NO_EVENT
        } else {
	    set last_report $SCRIPT_FAIL
	    return $SCRIPT_FAIL
        }
    }


    # during initialization, set the alert file size
    if {$last_alert_size == -1} {
        if { [file exists $alertfile] } {
	    if {[catch {set last_alert_size [file size $alertfile]} err]} {
	        lappend output [format [msgtxt [NETWORK] nms 1005] alert.tcl] 
	        lappend output $err
	        if {$last_report == $SCRIPT_FAIL} {
		    return $NO_EVENT
       	        } else {
		    set last_report $SCRIPT_FAIL
		    return $SCRIPT_FAIL
	        }
	    }
        } else {
            set last_alert_size 0
        }
        return $NO_EVENT
    }

    # check for the existence of the alert file
    if { ![file exists $alertfile] } {
        ORATCL_DEBUG "alert : $oramsg(oraobject) : [oratime] : $alertfile does not exist"
        return $NO_EVENT
    }

    # get the new alert file size
    if {[catch {set current_alert_size [file size $alertfile]} err]} {
        lappend output [format [msgtxt [NETWORK] nms 1005] alert.tcl] 
        lappend output $err
        if {$last_report == $SCRIPT_FAIL} {
	    return $NO_EVENT
        } else {
	    set last_report $SCRIPT_FAIL
	    return $SCRIPT_FAIL
        }
    }

    # print out event trace info 
    ORATCL_DEBUG "alert : $oramsg(oraobject) : [oratime] : $alertfile, $current_alert_size"


    # must be a new alert log
    if {$last_alert_size > $current_alert_size} {
        ORATCL_DEBUG "alert : $oramsg(oraobject) : [oratime] : $alertfile looks new : $last_alert_size, $current_alert_size"
        set last_alert_size 0
    }

    
    set alerts ""

    # check for new errors
    if {$last_alert_size != $current_alert_size} {
        set number_of_errors 0
	if {[catch {set fd [open $alertfile r]} err]} {
            lappend output [format [msgtxt [NETWORK] nms 1005] alert.tcl] 
	    lappend output $err
	    if {$last_report == $SCRIPT_FAIL} {
	        return $NO_EVENT
            } else {
	        set last_report $SCRIPT_FAIL
	        return $SCRIPT_FAIL
	    }
    	} else {		        
            if {[catch {seek $fd $last_alert_size start} err]} {
                lappend output [format [msgtxt [NETWORK] nms 1005] alert.tcl] 
		lappend output $err
                catch {close $fd} err
	    	if {$last_report == $SCRIPT_FAIL} {
	            return $NO_EVENT
	        } else {
		    set last_report $SCRIPT_FAIL
	            return $SCRIPT_FAIL
	    	}
    	    }
	}

        while {[gets $fd line] >= 0} {
            set alert_found 0
            foreach error $alert_errors {
                if {[string first $error $line] >= 0} {
                    set alert_found 1
                    set ret_code $ALERT_EVENT
                    lappend alerts $line
                    incr number_of_errors 
                }
            }
            if {$alert_found == 0} {
                foreach error $warning_errors {
                    if {[string first $error $line] >= 0} {
                        if {$ret_code == $NO_EVENT} {
                            set ret_code $WARNING_EVENT
                        }
                        lappend alerts $line
                        incr number_of_errors 
                    }
                }
            }
            if {$number_of_errors == 20} {
                lappend alerts ...
                break
            }
        }
        catch {close $fd} err
    }

    set last_alert_size $current_alert_size

    # clear the event if script failed last time
    if { $ret_code == $NO_EVENT && $last_report == $SCRIPT_FAIL } {
        set last_report $CLEAR_EVENT
        return $CLEAR_EVENT
    }

    # return
    # this event triggers even if it's already triggered if new errors
    # are present in the alert file
    if { $ret_code != $NO_EVENT } {
        append output $alerts
        ORATCL_DEBUG "alert : $oramsg(oraobject) : [oratime] : MESSAGE - $ret_code, $output"
    }
    return $ret_code


}

