# map.tcl --
#
# This file contains utilities to manipulate maps and map items.
#
# Copyright (c) 1996-1997 University of Twente.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tnm
package require TnmInet $tnm(version)
package provide TnmMap $tnm(version)

proc TnmMapGetIPAddress {node} {
    set ip [lindex [$node cget -address] 0]
    if [catch {netdb ip class $ip}] {
	if [catch {netdb hosts address [$node cget -name]} ip] {
	    error "no address known for node \"$node\""
	}
    }
    return $ip
}

proc TnmMapGetSnmpSession {node} {
    set map [$node map]
    set alias [$node attribute snmp:alias]
    if [string length $alias] {
	if {[catch {snmp session -alias $alias} s] == 0} {
	    return $s
	}
    }
    set config [$node attribute snmp:config]
    if [string length $config] {
	if {[catch {eval snmp session $config} s] == 0} {
            return $s
        }
    }

    set ip [TnmMapGetIPAddress $node]
    if {[catch {snmp session -address $ip} s] == 0} {
	return $s
    }

    error "no SNMP parameters for \"$node\""
}

proc TnmMapNotifyViaEmail {item {interval 1800}} {
    set map [$item map]
    set to [$item attribute :Contact]
    if ![string length $to] {
        set to [$map attribute :Contact]
    }
    if ![string length $to] {
	return
    }

    set now [clock seconds]
    set last [$item attribute notify:mail:last]
    if {[string length $last] && $now - $last < $interval} {
	return
    }
    $item attribute notify:mail:last $now

    set name [$item cget -name]
    if ![string length $name] {
	set name [$item cget -address]
    }
    set subject "\[Tnm\]: $name ([$item health] %)"
    set body "\nMessages: (last [$item cget -expire] seconds)\n\n"
    foreach msg [$item info messages] {
	set time [clock format [$msg time] -format {%T}]
	append body [format "%s (%2d):\t %s\n" \
		$time [$msg health] [$msg text]]
    }
    Tnm_InetMail $to $body $subject
}

proc TnmMapTraceRoute {node {maxlength 32} {retries 3}} {
    set dst [TnmMapGetIPAddress $node]
    for {set i 0} {$i < $retries} {incr i} { 
	lappend icmparg $dst
    }
    set l ""
    for {set ttl 1} {[lsearch $l $dst] < 0 && $ttl < $maxlength} {incr ttl} {
        set trace [icmp -retries 0 trace $ttl $icmparg]
        set l ""
        set time ""
        foreach {ip rtt} $trace {
            if {[string length $rtt]} {
                if {[lsearch $l $ip] < 0} { lappend l $ip }
                append time [format " %5d ms" $rtt]
            } else {
                append time "   *** ms"
            }
        }
	set names ""
        foreach ip $l {
            if {[catch {netdb hosts name $ip} name]} {
                if {[catch {dns name $ip} name]} {
                    set name $ip
                }
            }
            if {[lsearch $names $name] < 0} { lappend names $name }
        }
	$node raise TnmMapTraceRoute:Value \
		[format "%2d %-47s %s" $ttl [string range $names 0 46] $time]
    }
    $node raise TnmMapTraceRoute:Done
}

