#! /usr/local/bin/scotty -inf
##
## Some experimental TUBS  specific procs.
##
## Copyright (c) 1994
##
## J. Schoenwaelder
## TU Braunschweig, Germany
## Institute for Operating Systems and Computer Networks
##
## Permission to use, copy, modify, and distribute this
## software and its documentation for any purpose and without
## fee is hereby granted, provided that this copyright
## notice appears in all copies.  The University of Braunschweig
## makes no representations about the suitability of this
## software for any purpose.  It is provided "as is" without
## express or implied warranty.
##

LoadDefaults snmp

SnmpInit SNMP-TUBS

set snmp_port 1701
set snmp_timeout 10

##
## Write background error messages to stderr.
##

proc scottyerror { msg } {
    global errorInfo
#    puts stderr "$msg\n$errorInfo"
}

##
## Load the mib modules required by this script. This will prevent to load 
## all mib modules and reduce memory requirements and statup time.
##

mib load $scotty_lib/mibs/rfc1447.mib
mib load $scotty_lib/mibs/tubs.mib
mib load $scotty_lib/mibs/mlm.mib

##
## Show the system information of MIB II.
##

proc "System Information" {list} {
    ForeachIpNode id ip host $list {
        SnmpShowScalars $ip system
    }
}

proc "Scotty Information" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowScalars $ip scotty.status
    }
}

proc "SNMP Statistics" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowScalars $ip snmp
    }
}

##
## Retrieve the NFS statistics from the agent.
##

proc "NFS Server Statistik" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowScalars $ip nfsServer
    }
}

proc "NFS Client Statistik" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowScalars $ip nfsClient
    }
}

##
## Retrieve the Process Table.
##

proc "Running Processes" {list} {
    ForeachIpNode id ip host $list {
        set s [SnmpOpen $ip]
	if {[catch {$s set {{procReload.0 ""}}} date]} {
	    writeln $date
	    continue
	}
	set date [lindex [lindex $date 0] 2]
        writeln "Running processes for $host \[$ip\]: ($date)"
	set txt ""
	catch {
	    $s walk x "procEntry.procID procEntry.procCmd" {
		set id  [lindex [lindex $x 0] 2]
		set cmd [lindex [lindex $x 1] 2]
		append txt [format "%6d  %s\n" $id $cmd]
	    }
	}
        writeln $txt
        SnmpClose $s
    }
}

##
## Display the tclEvalTable.
##

proc "Show Eval Table" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowTable $ip tclEvalTable
    }
}

proc "Edit Eval Table" {list} {
    ForeachIpNode id ip host $list {
	SnmpEditTable $ip tclEvalTable
    }
}

proc "Create Eval Row" {list} {
    ForeachIpNode id ip host $list {
	set s [SnmpOpen $ip]

	set idx [lindex [lindex [$s get tclEvalSlot.0] 0] 2]
	$s set [list [list tclEvalStatus.$idx INTEGER createAndWait ] ]
	$s set [list [list tclEvalString.$idx "exec date" ] ]
	$s set [list [list tclEvalStatus.$idx INTEGER active ]  ]

	SnmpClose $s
    }
    "Show Eval Table" $list
}

##
## Set the parameters (community, timeout, retry) for snmp requests.
##

proc "Set Parameter" {list} {
    SnmpParameter
}

##
## Show the defaults as loaded from the tkined.defaults files.
##

proc "Show Defaults" {list} {
    ShowDefaults
}

##
## Delete the menus created by this interpreter.
##

proc "Delete SNMP-TUBS" {list} {
    global menus
    foreach id $menus { ined delete $id }
    exit
}

##
## Display some help about this tool.
##

proc "Help SNMP-TUBS" {list} {
    ined browse "Help about SNMP-TUBS" {
	"System Information:" 
	"    Display the system information of the tubs SNMP agent." 
	"" 
	"Scotty Information:" 
	"    Display some information about the scotty midlevel SNMP agent." 
	"" 
	"NFS Server Statistik:" 
	"    Display nfsstat like NFS server statistics." 
	"" 
	"NFS Server Statistik:" 
	"    Display nfsstat like NFS client statistics." 
	"" 
	"Running Processes:" 
	"    Display the process running on the agents host." 
	"" 
	"Set Parameter:" 
	"    This dialog allows you to set SNMP parameters like retries, " 
	"    timeouts, community name and port number. " 
	"" 
	"Show Defaults:" 
	"    Show the defaults that may be defined in the tkined.defaults" 
	"    files. This script makes use of definitions in the form" 
	"" 
	"        snmp.community:      <string>" 
	"        snmp.port:           <number>" 
	"        snmp.retries:        <number>" 
	"        snmp.timeout:        <number>" 
	"" 
	"        snmp.community.<ip>: <string>" 
	"        snmp.port.<ip>:      <number>" 
	"        snmp.retries.<ip>:   <number>" 
	"        snmp.timeout.<ip>:   <number>" 
	"" 
	"    where <ip> is an IP address in dot notation." 
    }
}

set menus [ ined create MENU "SNMP-TUBS" \
	    "System Information" "Scotty Information" "SNMP Statistics" "" \
	    "NFS Server Statistik" "NFS Client Statistik" "" \
	    "Running Processes" "" \
	    "Show Eval Table" "Edit Eval Table" "Create Eval Row" "" \
	    "TCL MLM:Start Script" "TCL MLM:Delete Script" \
	    "TCL MLM:Script Results" "" \
	    "MLM MIB:ScriptTable" "MLM MIB:SourceTable" \
	    "MLM MIB:ExecutionTable" "MLM MIB:ResultTable" "" \
	    "Set Parameter" "Show Defaults" "" \
	    "Help SNMP-TUBS" "Delete SNMP-TUBS"]

##
## Some debugging MLM stuff. Should work with any MLM MIB.
##

proc "ScriptTable" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowTable $ip mlmScriptTable
    }
}

proc "SourceTable" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowTable $ip mlmSourceTable
    }
}

proc "ExecutionTable" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowTable $ip mlmExecutionTable
    }
}

proc "ResultTable" {list} {
    ForeachIpNode id ip host $list {
	SnmpShowTable $ip mlmResultTable
    }
}

##
## Somewhat nicer commands...
##

proc SelectMLMSript {s txt} {
    catch {unset runable}
    $s walk x "mlmScriptIndex mlmScriptName mlmScriptDescr mlmScriptStatus" {
	set index  [lindex [lindex $x 0] 2]
	set name   [lindex [lindex $x 1] 2]
	set status [lindex [lindex $x 3] 2]
	if {$status == "active"} {
	    set descr($index)  [lindex [lindex $x 2] 2]
	    lappend runable [list $index $name]
	}
    }
    if {[info exists runable]} {
	while {1} {
	    set result [ined list "Select a script to $txt:" [lsort $runable] \
		    [list select describe cancel]]
	    set idx [lindex [lindex $result 1] 0]
	    if {[lindex $result 0] == "cancel"} return
	    if {$idx != ""} { 
		if {[lindex $result 0] == "describe"} {
		    ined acknowledge $descr($idx)
		} else {
		    return $idx 
		}
	    }
	}
    }
    return ""
}

proc "Start Script" {list} {
    static intv reps args

    if {![info exists intv]} { set intv 100 }
    if {![info exists reps]} { set reps 10 }
    if {![info exists args]} { set args "" }

    ForeachIpNode id ip host $list {
        set s [SnmpOpen $ip]
	set script [SelectMLMSript $s start]
	if {$script == ""} {
	    SnmpClose $s
	    continue
	}

	if {[catch {
	    set idx [$s get mlmNextExecution.0]
	    $s set $idx
	    set idx [lindex [lindex $idx 0] 2]
	    $s set [list [list mlmExecutionStatus.$idx createAndWait] ]
	} err]} {
	    writeln $err
	    SnmpClose $s
            continue
	}

	set r [ined request "Start MLM script:" \
                [list [list Arguments: $args ] \
                      [list Interval: $intv ] \
                      [list Repetitions: $reps ] ] [list start cancel] ]

	if {[lindex $r 0] == "cancel"} {
	    catch {$s set [list [list mlmExecutionStatus.$idx destroy]]}
	    SnmpClose $s
	    continue
	}

	set args [lindex $r 1]
	set intv [lindex $r 2]
	set reps [lindex $r 3]

	if {[catch {$s set [list \
		[list mlmExecutionScript.$idx $script] \
		[list mlmExecutionArguments.$idx $args] \
		[list mlmExecutionInterval.$idx $intv] \
		[list mlmExecutionRepetitions.$idx $reps] \
		]} err]} {
            writeln $err
        }

	if {[catch {$s set [list \
                [list mlmExecutionStatus.$idx active] \
		]} err]} {
            writeln $err
        }

	SnmpClose $s
    }
}

proc "Delete Script" {list} {
    ForeachIpNode id ip host $list {
        set s [SnmpOpen $ip]
	set idx [SelectMLMSript $s delete]
	if {$idx == ""} {
	    SnmpClose $s
	    continue
	}
	$s set [list [list mlmScriptStatus.$idx destroy]]
	SnmpClose $s
    }
}

proc "Script Results" {list} {
    ForeachIpNode id ip host $list {
        set s [SnmpOpen $ip]
	set idx [SelectMLMSript $s "show results"]
	if {$idx == ""} {
	    SnmpClose $s
	    continue
	}

	set idxlist ""
	$s walk x "mlmExecutionIndex mlmExecutionScript" {
	    set scr   [lindex [lindex $x 1] 2]
	    if {$scr == $idx} {
		lappend idxlist [lindex [lindex $x 0] 2]
	    }
	}

	if {$idxlist == ""} {
	    ined acknowledge "No results for script $idx on $host \[$ip\]!"
	    continue
	}

	foreach idx $idxlist {
	    set boottime [lindex [lindex [$s get scottyDate.0] 0] 2]
	    writeln "MLM Script Results $idx on $host \[$ip\]:"
	    writeln "$boottime (agent restart)"
	    $s walk x [list mlmResultStatus.$idx mlmResultTimeStamp.$idx \
		    mlmOctetStringValue.$idx ] {
		set status [lindex [lindex $x 0] 2]
		set time   [lindex [lindex $x 1] 2]
		set result [mib format sysDescr [lindex [lindex $x 2] 2]]
		writeln " + $time: $result ($status)"
	    }
	    writeln
	}
	SnmpClose $s
    }
}

