# $Header: orainit.tcl 29-mar-00.20:40:51 sgrover Exp $
# $Header: orainit.tcl 29-mar-00.20:40:51 sgrover Exp $
#
# copyright (c) 1995 by the Oracle Corporation
#
# NAME:
#
#  orainit.tcl : This file contains the portable definitions and procedures
#                used by all tcl scripts. 
#
# $Log:  $
# Revision 1.9  1996/02/28  20:16:45  yliu
# Fixed parsing problem in convertin and out
#
# Revision 1.8  1996/02/07 18:36:52  yliu
# added convertin and convertout
#
# Revision 1.7  1996/01/11 00:41:25  yliu
# added msgtxt1
#
# Revision 1.6  1996/01/10 00:02:19  yliu
# added msgtxt command
#
# Revision 1.5  1995/09/27 18:50:18  yliu
# added global lists
#
# Revision 1.4  1995/09/14  23:01:19  yliu
# Added divide procedure
#
#

# Global definitions
set SCRIPT_FAIL -2
set CLEAR_EVENT -1
set NO_EVENT 0
set WARNING_EVENT 1
set ALERT_EVENT 2
set SYS_TYPE sys
set TOTAL_TYPE total
set USED_TYPE used
set CHUNK_TYPE chunk
set IO_TYPE io
set TIME_STAMP timestamp
set month_list {Jan Feb Mar Apl May Jun Jul Aug Sep Oct Nov Dec}
set sysstat_name {lib_cache dc_cache buf_cache physical_io sort table_scan user_logged_on active_users sga_size uga_size}
set nmi_trace_info ""


# Set the prompt for oratclsh
set tcl_prompt1 PROMPT
proc PROMPT {} {
    puts -nonewline "oratclsh\[[history nextid]\]- "
    flush stdout
}


proc get_oids {base end} {
    # Gets value of all oids btwn base and end and puts them in a list
    # Basically it is like a get-bulk operation
    set db_ret [oradbsnmp getnext $base]
    set oid [lindex $db_ret 0]
    set end_oid [lindex [oradbsnmp getnext $end] 0]
    set ret ""
    while {[string compare $oid $end_oid] < 0} {
	lappend ret [lindex $db_ret 1]
	set db_ret [oradbsnmp getnext $oid]
	set oid [lindex $db_ret 0]
    }
    return $ret
}


proc divide {a b} {
    # Divide a by b, filter out divide by zero condition
    if {$b == 0} {
        expr 0
    } else {
        expr $a * 1.0 / $b
    }
}


# Returns the message corresponding to the message number from the 
# message file of the specified product and facility.
# The output is in the format of "FACILITY-ERROR : MESSAGE TEXT"
# If the message look up fails an error message of the form
# "Message <error> not found; No message file for product=<product>, 
#  facility=<facility>" is returned.                                                                           
# Notes:
# a) The message file is assumed to be present in agent's oracle home.
#    If the target is actually installed in a home different than agent and 
#    the agent's home doen't have the corresponding message file installed,
#    then the message look up fill fail.
# b) The above assumption is based on the restriction of current agent code
#    that it can't open the message file installed on a different home.
# c) It is also assumed that  the message ranges don't change between 
#    versions. Addition of new messages without affecting the range is fine.
# d) The database and sqlnet message files are guarenteed to be present in
#    agent's oracle home, since they are installed as dependendent products
#    of agent.

proc msgtxt {product facility error} {
    set msgid [openmsg $product $facility]
    set text "$facility-$error: [getmsg $msgid $error]"
    closemsg $msgid
    return $text
}


# Look at msgtxt proc for details
# Note:
# The output is in the format of "MESSAGE TEXT"
proc msgtxt1 {product facility error} {
    set msgid [openmsg $product $facility]
    set text [getmsg $msgid $error]
    closemsg $msgid
    return $text
}


proc convertin {agent_characterset string} {
    # Convert character set for incoming string
    global oramsg
    regexp {([A-Za-z_ ]+).([A-Za-z0-9]+)} $oramsg(language) a b c
    set cvtstring [cvtcharset $c $agent_characterset $string]
    return $cvtstring
}


proc convertout {agent_characterset string} {
    # Convert character set for outgoing string
    global oramsg
    regexp {([A-Za-z_ ]+).([A-Za-z0-9]+)} $oramsg(language) a b c
    set cvtstring [cvtcharset $agent_characterset $c $string]
    return $cvtstring
}


proc getagenttraceinfo {} {
    # return the trace level and directory
    global nmi_trace_info
    if { $nmi_trace_info == "" } {
	set level 0
	set dir [NETWORK_TRACE_DIR]
	set SnmproHdl [open [SNMPRW_FILE] r];
	while {[gets $SnmproHdl line] >= 0} {
	    if {[regexp nmi.trace_level $line] } {
          if {[regexp ^nmi.trace_level [string trimleft $line]] } {
              set level [string trim [string range $line \
                        [expr [string first = $line] +1] end] " "]
          }
      }
	    if {[regexp nmi.trace_directory $line] } {
          if {[regexp ^nmi.trace_directory [string trimleft $line]] } {
              set dir [string trim [string range $line \
                      [expr [string first = $line] +1] end] " "]
          }
	    }
	}
	set nmi_trace_info [list $level $dir]
	close $SnmproHdl
    }
    return $nmi_trace_info 
}


proc oraagent args {
    # Get the current state of the agent
    # possible arguments are: "", "services", "users", "jobs", "events", 
    # "job_notifications 'username'", "event_reports 'username'"  
    # "user 'username'", "job 'jobID'" and "event 'eventID'"
    set ArgsLen [llength $args]
    set element [string toupper [lindex $args 0]];
    set elementArg [lindex $args 1];
    set elementArg2 [lindex $args 2];
    set usage "Usage: oraagent <services> || <users> || <jobs> || <events> || <job_notifications username> || <event_reports username> || <service servicename> || <user username> || <job jobID> || <event eventID> || <job_notification username notification_id> || <event_report username report_id>";
    if { $ArgsLen > 3 } {
	error $usage;
    } elseif { $ArgsLen == 0 } {
	set DbVerHdl [open [DBSNMPVER_FILE] r];
	while {[gets $DbVerHdl line] >= 0} {
	    if {[regexp product $line] } {
		puts "Version Banner:   [string range $line 9 [expr [string length $line] - 2] ]";
	    }
	}
	close $DbVerHdl;
	puts "Current State:    [lindex [getagentstatus] 1]"
	puts "Trace Level:      [lindex [getagenttraceinfo] 0]"
	puts "Trace Directory:  [lindex [getagenttraceinfo] 1]"
	return ""
    } elseif { $element == "START"} {
	puts [lindex [startagent] 1]
    } elseif { $element == "STOP"} {
	puts [lindex [stopagent] 1]
    } elseif { $element == "SERVICES"} {
	set srvlist ""
	set SHdl [open [SERVICES_FILE] r];
	while {[gets $SHdl line] >= 0} {
	    if {[regexp "=" $line] } {
		lappend srvlist [string trim [lindex [split $line =] 0] " "]
	    }
	}
	close $SHdl
	return [lsort $srvlist]
    } elseif { $element == "SERVICE" && $elementArg != "" } {
	set found  0
	set Name $elementArg;
	set SHdl [open [SERVICES_FILE] r];
	while {[gets $SHdl line] >= 0} {
	    if {[regexp "^$Name =" $line] } {
		set found 1
		regsub -all " " [string trim [string range $line [expr [string first = $line] +1] end] "() "] "" service_descr
		set service_descr_attr [split $service_descr ","]
		puts "Name:             $Name"
		puts "Type:             [lindex $service_descr_attr 0]"
		puts "Address:          [lindex $service_descr_attr 2]" 
	    }
	}
	close $SHdl
	if { $found == 0 } {
	    error "Unknown Service: $Name"
	}
    } elseif { $element == "USERS"} {
	set x [admin_listinputqueue users]
	upvar $x y
	return [lsort [array names y]];
    } elseif { $element == "USER" && $elementArg != "" } {
        set userlist [admin_listinputqueue users]
	upvar $userlist theArray
	set Name [string toupper $elementArg];
        if { [catch {set test [lindex $theArray($Name) 1]}] } {
	    puts "Uknown user: $Name"
	} else {
	    puts "User Name:        $Name";
	    puts "Console Address:  [lindex $theArray($Name) 1]";
	    puts "User Language:    [lindex $theArray($Name) 2]";
	}
    } elseif { $element == "JOBS"} {
	set x [admin_listinputqueue jobSchedule]
	upvar $x y
	return [lsort -integer [array names y]]
    } elseif { $element == "JOB"  && $elementArg != "" } {
	set joblist [admin_listinputqueue jobSchedule]
	upvar $joblist theArray
	set JobId $elementArg;
        if { [catch {set test [lindex $theArray($JobId) 1]}] } {
	    puts "Job with ID does not exist."
	} else {
	    puts "Job ID:           $JobId";
	    puts "Job Owner:        [lindex $theArray($JobId) 0]";
	    puts "OS Credentials:   [lindex $theArray($JobId) 1]";
	    puts "Target Object:    [lindex $theArray($JobId) 2]";
	    puts "Schedule:         [lindex $theArray($JobId) 5]";
	    puts "Status Flags:     [lindex $theArray($JobId) 7], [lindex $theArray($JobId) 8], [lindex $theArray($JobId) 9]";
	}
    } elseif { $element == "EVENTS"} {
	set x [admin_listinputqueue eventRegistrations]
	upvar $x y
	return [lsort -integer [array names y]]
   } elseif { $element == "EVENT" && $elementArg != "" } {
	set eventlist [admin_listinputqueue eventRegistrations]
	upvar $eventlist theArray;
	set EventId $elementArg;
        if { [catch {set test [lindex $theArray($EventId) 1]}] } {
	    puts "Event with ID $EventId does not exist."
	} else {
	    puts "Event ID:         $EventId";
	    puts "Event Name:       [lindex $theArray($EventId) 0]";
	    puts "Event Owner:      [lindex $theArray($EventId) 2]";
	    puts "Target Object:    [lindex $theArray($EventId) 1]";
	    puts "Polling Interval: [lindex $theArray($EventId) 4] seconds";
	    puts "Event Flags:      [lindex $theArray($EventId) 5]";
	    puts "Fixit Job:        [lindex $theArray($EventId) 3]";
	}
    } elseif { $element == "JOB_NOTIFICATIONS" && $elementArg != "" } {
        set userlist [admin_listinputqueue users]
	upvar $userlist theArray
	set Name [string toupper $elementArg];
        if { [catch {set test [lindex $theArray($Name) 1]}] } {
	    puts "Uknown user: $Name"
	} else {
	    set x [admin_listoutputqueue jobStatus $Name ]
	    upvar $x y
	    return [lsort -integer [array names y]]
	}
    } elseif { $element == "JOB_NOTIFICATION" && $elementArg != "" && $elementArg2 != ""} {
        set userlist [admin_listinputqueue users]
	upvar $userlist theArray
	set Name [string toupper $elementArg];
        if { [catch {set test [lindex $theArray($Name) 1]}] } {
	    puts "Uknown user: $Name"
	} else {
	    set x [admin_listoutputqueue jobStatus $Name ]
	    upvar $x y
	    set id $elementArg2
	    if { [catch {set test [lindex $y($id) 1]}] } {
		puts "Job Notification with ID $id does not exist."
	    } else {
		puts "Notification ID:  $id"
		puts "Job ID:           [lindex $y($id) 0]"
		puts "Target Object:    [lindex $y($id) 1]";
		puts "Generation Time:  [lindex $y($id) 2]";
		puts "Type:             [lindex $y($id) 3]";
		puts "Output:           [lindex $y($id) 5]";
		puts "Journal File:     [lindex $y($id) 6]";
	    }
	}
    } elseif { $element == "EVENT_REPORTS" && $elementArg != "" } {
        set userlist [admin_listinputqueue users]
	upvar $userlist theArray
	set Name [string toupper $elementArg];
        if { [catch {set test [lindex $theArray($Name) 1]}] } {
	    puts "Uknown user: $Name"
	} else {
	    set x [admin_listoutputqueue eventReports $Name]
	    upvar $x y
	    return [lsort -integer [array names y]]
	}
    } elseif { $element == "EVENT_REPORT" && $elementArg != "" && $elementArg2 != ""} {
        set userlist [admin_listinputqueue users]
	upvar $userlist theArray
	set Name [string toupper $elementArg];
        if { [catch {set test [lindex $theArray($Name) 1]}] } {
	    puts "Uknown user: $Name"
	} else {
	    set x [admin_listoutputqueue eventReports $Name ]
	    upvar $x y
	    set id $elementArg2
	    if { [catch {set test [lindex $y($id) 1]}] } {
		puts "Event Report with ID $id does not exist."
	    } else {
		puts "Notification ID:  $id"
		puts "Evant Name:       [lindex $y($id) 0]"
		puts "Target Object:    [lindex $y($id) 3]";
		puts "Generation Time:  [lindex $y($id) 2]";
		puts "Type:             [lindex $y($id) 1]";
		puts "Output:           [lindex $y($id) 5]";
	    }
	}
    }  else {
	error $usage;
    }
}







