#
# Module LoadFile.tcl  
#
# $Log: LoadFile.tcl,v $
# Revision 1.2  2006/10/18 05:04:03  vfom
# Added code for including prefs and internal vars to config
#
# Revision 1.1.1.1  2006/09/21 10:57:02  vfom
# Loading TkNetmon to CVS
#
#
#---------------------------------------------------------------
#   Global namespace definitions  
#---------------------------------------------------------------
namespace eval ::Parser::Global {
    proc RootDir { path } {  
	if { [file isdirectory $path] } {
	    set ::rootDir $path  
	} else {
	    puts stderr "Can't access RootDir:\"$path\""
	}
    }
    proc ChRootDir { path } {  
	if { [file isdirectory $path] } {
	    set ::chRootDir $path  
	} else {
	    puts stderr "Can't access ChRootDir:\"$path\""
	}
    }
    proc UserName { name } {     set ::userName $name      }
    proc GroupName { name } {     set ::groupName $name     }
    proc Polling { num }  {  
	if { [string is integer $num ] } {
	    set ::nodePoll $num   
	} else {
	    puts stderr "Polling: Expected integer, got: \"$num\""
	}
    }
    proc Timeout { num }  {  
	if { [string is integer $num ]} {
	    set ::nodeTmo $num   
	} else {
	    puts stderr "Timeout: Expected integer, got: \"$num\""
	}
    }	
    proc Retries { num }  {  
	if { [string is integer $num ]} {
	    set ::nodeRetr $num   
	} else {
	    puts stderr "Retries: Expected integer, got: \"$num\""
	}
    }
    proc Saving  { num }  {  
	if { [string is integer $num ]} {
    	    set ::dataSaveInterval $num    
	} else {
	    puts stderr "Saving: Expected integer, got: \"$num\""
	}
    }
    proc TimeFmt { str }  {  set ::timeFmt $str  }
    proc SrcAddress { str } { 
	if { [IsValidIpAddr $str ]} {
	    set ::node_SrcIp $str 
	} else {
	    puts stderr "SrcAddress: Expected valid ip address, got: \"$num\""
	}
    }
    proc AddSnmpVar { vname oid } { 
	foreach sublist  $::snmpVarsList {	
	    set xname [lindex $sublist 0 ]
	    if { [lsearch -exact $xname $vname] >=0 } {
		puts stderr "AddSnmpVar: Duplicated variable: $vname"
		return
	    }
	}
	if { [IsValidOID $oid ] } {
	    lappend ::snmpVarsList [list $vname $oid ]
	} else {
	    puts stderr "AddSnmpVar:\"$vname\": Incorrect OID parameter: $oid"
	}
    }
    proc Group   { gname script } {
	lappend ::ifGroupList $gname
	set ::ifGroupDefinition($gname) [list $script]	
    }
    proc Port    { pname script }  { 
	set ::netStateServerPort $pname
	set ::netStateServerAccess [list]
	if [ catch { namespace eval ::Parser::Port $script } rezult ] {
	    puts stderr "PORT:$rezult"
        }
    }
    proc ServiceMenus { script } {
	set ::menuIndex	0
	if [ catch { namespace eval ::Parser::ServiceMenus $script } rezult ] {
	    error $rezult
	    puts stderr "MENU:$rezult"
        }
    }
    proc Method  { pname script }  {  
	if { [lsearch -exact $::pollMethods $pname ] >= 0 } {
	    puts stderr "GLOBAL:Method always defined: \"$pname\". Ignored."
	    return
	}
	lappend ::pollMethods $pname
	set ::pollMBodyArray($pname) $script 	
    }
    proc Save    { pname script }  {  
	if { [lsearch -exact $::saveMethods $pname ] >= 0 } {
	    puts stderr "GLOBAL:Save always defined: \"$pname\". Ignored."
	    return
	}
	lappend ::saveMethods $pname
	set ::saveMBodyArray($pname) $script  
    }
    proc Trap { tname script } {
	if { [lsearch -exact $::trapMethods $tname ] >= 0 } {
	    puts stderr "GLOBAL:Trap always defined: \"$tname\". Ignored."
	    return
	}
	lappend ::trapMethods $tname
	set ::Parser::Trap::Entr "1.3.6.1.4.1.9"
	set ::Parser::Trap::Spc 0
	if [ catch { namespace eval ::Parser::Trap $script } rezult ] {
	    puts stderr "TRAP:$tname:$rezult"
	    return
	}    
	set ::trapMBodyArray($tname) [ list $::Parser::Trap::Entr $::Parser::Trap::Spc ]
    }
    proc SqlDatabase { script } {
	if [ catch { namespace eval ::Parser::SqlDatabase $script } rezult ] {
	    puts stderr "SqlDatabase:$rezult"
	    return
	}        
    }
    proc EventsLog { script } {
	if [ catch { namespace eval ::Parser::EventsLog $script } rezult ] {
	    puts stderr "EventsLog:$rezult"
	    return
	}        
    }
    proc Preferences { script } {
	if [ catch { namespace eval ::Parser::Prefs $script } rezult ] {
	    puts stderr "PREFS:$rezult"
	    return
	}        
    }
    
    proc Object  { name script }  { 
	set hostKey ".node$::nodeIndex"
	if { [info exists node_key($name) ]} {
	    puts stderr "OBJECT:Object exist: \"$name\". Ignored."
	    return
	}
	set ::node_name($hostKey)	$name
	set ::node_key($name)		$hostKey
	set ::node_state($hostKey)		UNK
	set ::node_flashcnt($hostKey)	0
	set ::node_health($hostKey)	0
	set ::node_descr($hostKey)	$name
	set ::node_datadir($hostKey)	""
	set ::node_ip($hostKey)		$::nodeIP
	set ::node_srcip($hostKey)	$::node_SrcIP
	set ::node_snmpget($hostKey)	$::node_getCommunity
	set ::node_snmptrap($hostKey)	$::node_trapCommunity
	set ::node_poll($hostKey)	$::nodePoll
	set ::node_tmo($hostKey)	$::nodeTmo
	set ::node_retr($hostKey)	$::nodeRetr
	set ::node_dataSaveInterval($hostKey)	$::dataSaveInterval
	set ::node_font($hostKey)	$::nodeFont
	set ::node_fontcolor($hostKey)  $::nodeFontColor
	set ::node_icon($hostKey)	$::nodeIcon
	set ::node_menu($hostKey)	"Default"
	set ::node_action($hostKey)	$::node_dblClickCmd
	set ::node_soundup($hostKey)	""
	set ::node_sounddown($hostKey)	""
	set ::node_snmpver($hostKey)	$::node_SnmpVer
	set ::node_snmpvarslist($hostKey) [list]
	set ::node_snmptrapslist($hostKey) [list]
	set ::node_methodslist($hostKey) [list]
	set ::node_iflist($hostKey)	[list]
	set ::node_srvlist($hostKey)	[list]
	set ::node_bgplist($hostKey)	[list]
	set ::Parser::Object::x 0
	set ::Parser::Object::y 0
	if [ catch { namespace eval ::Parser::Object $script } rezult ] {
	    puts stderr "OBJECT:$name:$rezult"
	    return
	}
	set i_h [image height $::arIcons($::node_icon($hostKey))]
	label $hostKey -image $::arIcons($::node_icon($hostKey)) -padx 2 -pady 2 -relief raised
	lower $hostKey; raise $hostKey .canvas
	.canvas create window $::Parser::Object::x $::Parser::Object::y -window $hostKey \
	    -tags [list $hostKey $hostKey.icon $::node_name($hostKey) ]

	.canvas create text $::Parser::Object::x \
	    [ expr $::Parser::Object::y - $i_h/2 - 2 ] -anchor s \
	    -text "$::node_name($hostKey)" -fill $::node_fontcolor($hostKey)\
	    -font $::node_font($hostKey)  -justify center \
	    -tags  [list $hostKey $hostKey.up ]

	.canvas create text $::Parser::Object::x \
	    [ expr $::Parser::Object::y + $i_h/2 + 2] -anchor n\
	    -text "rtt=0" -fill $::node_fontcolor($hostKey) \
	    -font $::node_font($hostKey) -justify center\
	    -tags  [list $hostKey $hostKey.dn ]	
	incr ::nodeIndex
    }
    proc Line { script } {
	set ::Parser::Line::color $::linkColor
	set ::Parser::Line::width $::linkWidth
	if [ catch { namespace eval ::Parser::Line $script } rezult ] {
	    #error $rezult
	    puts stderr "LINE:$rezult"
	    return
	}
	.canvas create line $::Parser::Line::x1 $::Parser::Line::y1 \
	    $::Parser::Line::x2 $::Parser::Line::y2 \
	    -fill  $::Parser::Line::color \
	    -width $::Parser::Line::width 
    }
    proc Link { script } {
	set ::Parser::Link::color $::linkColor
	set ::Parser::Link::width $::linkWidth
	if [ catch { namespace eval ::Parser::Link $script } rezult ] {
	    #error $rezult
	    puts stderr "LINK:$rezult"
	    return
	}
	# check nodes existance ?
	set key1 $::node_key($::Parser::Link::first)
	set key2 $::node_key($::Parser::Link::second)
	set id1 [ .canvas find withtag "$key1.icon" ]
	set id2 [ .canvas find withtag "$key2.icon" ]
	set x1  [lindex [.canvas coords $id1] 0]
	set y1  [lindex [.canvas coords $id1] 1]
	set x2  [lindex [.canvas coords $id2] 0]
	set y2  [lindex [.canvas coords $id2] 1]
	.canvas create line $x1 $y1 $x2 $y2 \
	    -fill  $::Parser::Link::color \
	    -width $::Parser::Link::width \
	    -tags [list  $::Parser::Link::first $::Parser::Link::second ]

    }
    proc Text { script } {
	set ::Parser::Text::anch  $::textAnchor
	set ::Parser::Text::font  $::textFont
	set ::Parser::Text::color $::textFontColor
	set ::Parser::Text::ajst  $::textJust
	set ::Parser::Text::body  ""
	if [ catch { namespace eval ::Parser::Text $script } rezult ] {
	    # error $rezult
	    puts stderr "TEXT:$rezult"
	    return
	}
	if { $::Parser::Text::body  != ""} {
	    .canvas create text $::Parser::Text::x $::Parser::Text::y \
		-font $::Parser::Text::font    \
		-fill  $::Parser::Text::color  \
		-justify $::Parser::Text::ajst \
	        -anchor $::Parser::Text::anch  \
		-text $::Parser::Text::body 

	}
    }
    proc Include { fname } {
	if { $::nodeIndex == 0 } {
	    set ::predIncludeFile $fname
	} else {
	    set ::postIncludeFile $fname
	}
    }
}

#---------------------------------------------------------------
#  
# Port namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Port {
    proc Timeout { num } { 
	if { [string is integer $num ]} {
	    set ::netStateServerTimeout    $num 
	} else {
	    puts stderr "Port Timeout: Expected integer, got: \"$num\""
	}
    }
    proc BindAddress { ip } {
	if { [IsValidIpAddr $ip ] } {
	    set ::netStateServerAddress $ip 
	} else {
	    puts stderr "Port BindAddress: Expected valid ip address, got: \"$ip\""
	}	
    }
    proc Permit  { str } { 
	# regsub {[\^\$\\]} $str {} tmp_str
	lappend ::netStateServerAccess "permit:$str"
    }
    proc Deny    { str } { 
	# regsub {[\^\$\\]} $str {} tmp_str
	lappend ::netStateServerAccess   "deny:$str" 
    }
}
# !!! This is for syntax checking only !!!  
#---------------------------------------------------------------
#  
# Poll namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Poll { } 
# !!! This is for syntax checking only !!!  
#---------------------------------------------------------------
#  
# Save namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Save { }
#---------------------------------------------------------------
#  
# Trap namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Trap { 
variable Entr "" Spc "" 1 " "
    proc Enterprise { oid } {
	if { [::IsValidOID $oid ] } {
	    set ::Parser::Trap::Entr $oid
	} else {
	    puts stderr "Trap: Expected valid enterprise OID, got: \"$oid\""
	}	
    } 
    #
    proc Specific { num } {
	regsub -all -- {[0-9]+} $num {} num2
    	if { $num2 == "" } {
	    set ::Parser::Trap::Spc $num
	} else {
	    puts stderr "Trap: Expected valid enterprise spcific ID, got: \"$num\""
	}	
    } 
    proc Community { str } {    } 
}
#---------------------------------------------------------------
#  
# ServiceMenus namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::ServiceMenus {
    proc MenuItem { args } {
	set ::menuConfigArray($::menuIndex) $args 	
	incr ::menuIndex
    }
}
#---------------------------------------------------------------
#  
# SqlDatabase namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::SqlDatabase { }
#---------------------------------------------------------------
#  
# EventsLog namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::EventsLog { }
#---------------------------------------------------------------
#  
# Preferences namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Prefs {
    #
    proc BGImage  { lbackground } {
	set ::background $lbackground
	if { $::background == "" } { return }
    	if { [file readable $lbackground ] } {	
	    if { [catch {image create photo new_background_image -file $lbackground } ] } {
		puts stderr "Can't create background image from \"$lbackground\"!"
	    } else {
		set img_id [ .canvas find withtag bgimage ]
		.canvas delete $img_id
		.canvas create image 0 0 -image new_background_image -anchor nw -tags bgimage
	    }
	} else {
	    puts stderr "Can't read background image from \"$lbackground\"!"
	}
    }
    proc AddTargets { ip1 ip2 } { 
	if { [IsValidIpAddrRange $ip1 $ip2] } {
	    lappend ::targetList [list $ip1 $ip2]
	} else {
	    puts stderr "AddTargets: Incorrect parameters: $ip1 $ip2"
	}
    }
    proc AddSnmpName { ip str } { 
	if { [IsValidIpAddr $ip ] } {
	    lappend ::snmpList [list $ip $str]
	} else {
	    puts stderr "AddSnmpName: Incorrect parameters: $ip $snmp"
	}
    }
}
#---------------------------------------------------------------
#  
# Object namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Object {
variable x 0.0 y 0.0
    proc Address { ip } { 
	if { [::IsValidIpAddr $ip ] } {
	    set ::node_ip(.node$::nodeIndex) $ip
	} else {
	    puts stderr "Object Address: Expected valid ip address, got: \"$ip\""
	}	
    }
    proc SrcAddress { ip } { 
	if { [::IsValidIpAddr $ip ] } {
	    set ::node_srcip(.node$::nodeIndex) $ip
	} else {
	    puts stderr "Object SrcAddress: Expected valid ip address, got: \"$ip\""
	}	
    }
    proc Polling { num }  {  
	if { [string is integer $num ] } {
	    set ::node_poll(.node$::nodeIndex) $num
	} else {
	    puts stderr "Polling: Expected integer, got: \"$num\""
	}
    }
    proc Timeout { num }  {  
	if { [string is integer $num ]} {
	    set ::node_tmo(.node$::nodeIndex) $num   
	} else {
	    puts stderr "Object Timeout: Expected integer, got: \"$num\""
	}
    }
    proc Retries { num }  {  
	if { [string is integer $num ]} {
	    set ::node_retr(.node$::nodeIndex) $num   
	} else {
	    puts stderr "Object Retries: Expected integer, got: \"$num\""
	}
    }
    proc Saving  { num }  {  
	if { [string is integer $num ]} {
    	    set ::node_dataSaveInterval(.node$::nodeIndex) $num    
	} else {
	    puts stderr "Object Saving: Expected integer, got: \"$num\""
	}
    }
    proc NodeAction { str } { set ::node_action(.node$::nodeIndex) $str }
    proc SnmpVersion { str } { set ::node_snmpver(.node$::nodeIndex) $str  }
    proc GetCommunity { str } { set ::node_snmpget(.node$::nodeIndex) $str  }
    proc TrapCommunity { str } { set ::node_snmptrap(.node$::nodeIndex) $str  }
    proc Trap { trp comm } { 
	if { [lsearch $::trapMethods $trp ] >=0 } {
	    lappend ::node_snmptrapslist(.node$::nodeIndex) $trp  
	} else {
	    puts stderr "OBJECT: $::node_name(.node$::nodeIndex): Undefined trap \"$trp\""	    
	}
    }
    proc Datadir { path } {  set ::node_datadir(.node$::nodeIndex) $path }
    proc AddSnmpVar { vname args } {
	set key .node$::nodeIndex
	foreach sublist $::node_snmpvarslist($key) {	
	    set xname [lindex $sublist 0 ]
	    if { [lsearch -exact $xname $vname] >=0 } {
		puts stderr "OBJECT: AddSnmpVar: Duplicated variable: $vname"
		return
	    }
	}
	set oid [ lindex $args 0 ]
	if { $oid == "=" } { 
	    set oid ""
	    set val [ lindex $args 1 ]
	} else {
	    set val [ lindex $args 2 ]
	}
	lappend ::node_snmpvarslist($key) [list $vname $oid $val ] 
    }
    proc Icon    { ic } {
	if { [catch { $::arIcons($ic) cget -file} ]} { } else {
	    set ::node_icon(.node$::nodeIndex)  $ic
	}
    }
    proc UpSound   { snd } { set ::node_soundup(.node$::nodeIndex) $snd }
    proc DownSound { snd } { set ::node_sounddown(.node$::nodeIndex) $snd }
    proc Menu { mn } { 
	if {[lsearch -exact [ ::getServiceMenus ]  $mn ]} {
	    set ::node_menu(.node$::nodeIndex) $mn 
	} else {
	    puts stderr "Object Menu: Can't find menu \"$mn\". Using \"Default\" instead."
	}
    }
    proc Font { fnt } { set ::node_font(.node$::nodeIndex) $fnt }
    proc FontColor { clr } { set ::node_fontcolor(.node$::nodeIndex) $clr }
    proc Description { txt } {	set ::node_descr(.node$::nodeIndex) $txt }
    proc Method  { pname args } { 
	if { [lsearch $::pollMethods $pname] <0 } {
	    puts stderr "Object Method: Poll method undefined: \"$pname\". Ignored."
	} else {
	    set str {}
	    if { [string equal $pname "snmp" ] || [string equal $pname "router" ] } {
		set x [ lindex $args 0 ] 	
		if { [string equal $x "v1" ] || [string equal $x "v2" ] } {
		    set x [ lindex $args 1 ] 
		} 
		set str "\"$x\""
	    } else {
		foreach i $args { 
		    set subarg "\"$i\""
		    set str [concat $str $subarg]
		}
	    } 
	    lappend ::node_methodslist(.node$::nodeIndex) [list "Method" $pname $str ]
	}
    }
    proc Coords { x y } {  
	# ? validity check 
	set ::Parser::Object::x $x
	set ::Parser::Object::y $y
    }
    proc Save    { sname args } { 
	if { [lsearch $::saveMethods $sname] <0 } {
	    puts stderr "Object Save: Save method undefined: \"$sname\". Ignored."
	} else {
	    set str {}
	    foreach i $args { 
		set subarg "\"$i\""
		set str [concat $str $subarg]
	    }
	    lappend ::node_methodslist(.node$::nodeIndex) [list "Save" $sname $str ]
	}
    }
#    proc Interface { ifname script } { #}
    proc Interface { ifname args } {
	set hostKey	.node$::nodeIndex
	set ifKey	.if$::ifIndex 
	set ::if_owner($ifKey) $hostKey
	if { [string match $ifname "Group" ] } {
	    set xifname [lindex $args 0]
	    if { [lsearch $::ifGroupList $xifname ] <0 } {
		puts stderr "INTERFACE: Unknown IfGroup \"$xifname\""
		return
	    } else {
		set ifname "Group \"$xifname\""
	    }
	    set script [join [lrange $args 1 end]]
	} else {
	    set script [join [lrange $args 0 end]]
	}
	set ::if_name($ifKey)  $ifname
	set ::if_descr($ifKey)      ""
	set ::if_datadir($ifKey)    ""
	set ::if_bandwidth($ifKey)  ""
	set ::if_methodslist($ifKey)  [list]
	if [ catch { namespace eval ::Parser::Interface $script } rezult ] {
	    #error $rezult
	    puts stderr "INTERFACE:$ifname:$rezult"
	    return
	}
	if { [llength $::if_methodslist($ifKey)] >0} {
	    lappend ::node_iflist($hostKey) [list $ifname $ifKey ]
	    incr ::ifIndex
	} else {
	    puts stderr "INTERFACE:$ifname - no methods. Ignored."
	}
    }
    proc Service  { srvname script } { 
	set hostKey	.node$::nodeIndex
	set srvKey	.srv$::srvIndex 
	set ::srv_owner($srvKey) $hostKey
	set ::srv_name($srvKey)  $srvname
	set ::srv_descr($srvKey)      ""
	set ::srv_datadir($srvKey)    ""
	set ::srv_methodslist($srvKey)  [list]
	set ::srv_snmpvarslist($srvKey)  [list]
	if [ catch { namespace eval ::Parser::Service $script } rezult ] {
	    #error $rezult
	    puts stderr "SERVICE:$srvname:$rezult"
	    return
	}
	if { [llength $::srv_methodslist($srvKey)] >0 || [llength srv_snmpvarslist($srvKey)] >0} {
	    lappend ::node_srvlist($hostKey) [list $srvname $srvKey ]
	    incr ::srvIndex
	} else {
	    puts stderr "SERVICE:$srvname - no methods. Ignored."
	}
    }
    proc Bgp { asn script } { 
	set hostKey	.node$::nodeIndex
	set bgpKey	.bgp$::bgpIndex 
	set ::bgp_owner($bgpKey) $hostKey
	set ::bgp_asn($bgpKey)  $asn
	set ::bgp_descr($bgpKey)      ""
	set ::bgp_datadir($bgpKey)    ""
	set ::bgp_methodslist($bgpKey)  [list]
	set ::bgp_peerslist($bgpKey)  [list]
	if [ catch { namespace eval ::Parser::Bgp $script } rezult ] {
	    #error $rezult
	    puts stderr "BGP:$asn:$rezult"
	    return
	}
	if { [llength $::bgp_methodslist($bgpKey)] >0 } {
	    lappend ::node_bgplist($hostKey) [list $asn $bgpKey ]
	    incr ::bgpIndex
	} else {
	    puts stderr "BGP:$asn - no methods. Ignored."
	}
    }
}
#---------------------------------------------------------------
#  
# Interface namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Interface {
    proc Datadir { path } { set ::if_datadir(.if$::ifIndex) $path }
    proc Description { txt } { set ::if_descr(.if$::ifIndex) $txt }
    proc Bandwidth { num } { set ::if_bandwidth(.if$::ifIndex) $num }
    proc Save { sname args } { 
	if { [lsearch $::saveMethods $sname] <0 } {
	    puts stderr "Object Interface Save: Save method undefined: \"$sname\". Ignored."
	} else {
	    set str {}
	    foreach i $args { 
		set subarg "\"$i\""
		set str [concat $str $subarg]
	    }
	    lappend ::if_methodslist(.if$::ifIndex) [list "Save" $sname $str ]
	}
    }
}
#---------------------------------------------------------------
#  
# Service namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Service {
    proc Datadir { path } { set ::srv_datadir(.srv$::srvIndex) $path }
    proc Description { txt } { set ::srv_descr(.srv$::srvIndex) $txt }
    proc Method  { pname args } { 
	if { [lsearch $::pollMethods $pname] <0 } {
	    puts stderr "Object Service Method: Poll method undefined: \"$pname\". Ignored."
	} else {
	    set str {}
	    foreach i $args { 
		set subarg "\"$i\""
		set str [concat $str $subarg]
	    }
	    lappend ::srv_methodslist(.srv$::srvIndex) [list "Method" $pname $str ]
	}
    }
    proc Save { sname args } { 
	if { [lsearch $::saveMethods $sname] <0 } {
	    puts stderr "Object Service Save: Save method undefined: \"$sname\". Ignored."
	} else {
	    set str {}
	    foreach i $args { 
		set subarg "\"$i\""
		set str [concat $str $subarg]
	    }
	    lappend ::srv_methodslist(.srv$::srvIndex) [list "Save" $sname $str ]
	}
    }
    proc AddSnmpVar { vname args } {
	set key .srv$::srvIndex
	foreach sublist $::srv_snmpvarslist($key) {	
	    set xname [lindex $sublist 0 ]
	    if { [lsearch -exact $xname $vname] >=0 } {
		puts stderr "OBJECT:SERVICE: AddSnmpVar: Duplicated variable: $vname"
		return
	    }
	}
	set oid [ lindex $args 0 ]
	if { $oid == "=" } { 
	    set oid ""
	    set val [ lindex $args 1 ]
	} else {
	    set val [ lindex $args 2 ]
	}
	lappend ::node_snmpvarslist($key) [list $vname $oid $val ] 
	lappend ::srv_snmpvarslist($key) [list $vname $oid $val ] 
    }
}
#---------------------------------------------------------------
#  
# Bgp namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Bgp {
    proc Datadir { path } { set ::bgp_datadir(.bgp$::bgpIndex) $path }
    proc Description { txt } { set ::bgp_descr(.bgp$::bgpIndex) $txt }
    proc Peer { ip } { lappend ::bgp_peerslist(.bgp$::bgpIndex) $ip }
    proc Save { sname args } { 
	if { [lsearch $::saveMethods $sname] <0 } {
	    puts stderr "Object Interface Save: Save method undefined: \"$sname\". Ignored."
	} else {
	    set str {}
	    foreach i $args { 
		set subarg "\"$i\""
		set str [concat $str $subarg]
	    }
	    lappend ::bgp_methodslist(.bgp$::bgpIndex) [list "Save" $sname $str ]
	}
    }
}
#---------------------------------------------------------------
#  
# Line namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Line {
variable x1 0.0 y1 0.0 x2 0.0 y2 0.0 color "white" width 1.0
    proc Coords { x1 y1 x2 y2 } { 
	set ::Parser::Line::x1 $x1  
	set ::Parser::Line::y1 $y1  
	set ::Parser::Line::x2 $x2  
	set ::Parser::Line::y2 $y2  
    }
    proc Color { clr } { set ::Parser::Line::color $clr }
    proc Width { wdt } { set ::Parser::Line::width $wdt }
}
#---------------------------------------------------------------
#  
# Link namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Link {
variable first {} second {} color "white" width 1.0
    proc Nodes { first second } { 
	set ::Parser::Link::first $first 
	set ::Parser::Link::second $second 
    }
    proc Color { clr } { set ::Parser::Link::color $clr }
    proc Width { wdt } { set ::Parser::Link::width $wdt }
}
#---------------------------------------------------------------
#  
# Text namespace definitions  
#
#---------------------------------------------------------------
namespace eval ::Parser::Text {
variable x 0.0 y 0.0  anch center font fixed color "white" ajst center body {}
    proc Coords { x y } { 
	set ::Parser::Text::x $x 
	set ::Parser::Text::y $y
    }
    proc Anchor { anch } { set ::Parser::Text::anch $anch }
    proc Font   { fnt } { set ::Parser::Text::font $fnt }
    proc FontColor  { clr } { set ::Parser::Text::color $clr }
    proc Ajustment  { ajst } { set ::Parser::Text::ajst $ajst }
    proc Body  { txt } {  set ::Parser::Text::body $txt }
}
#
#---------------------------------------------------------------
#  
# Main Procedure
#
#---------------------------------------------------------------
#
proc LoadFile { f } {
    #
    NewMap
    set ::activeFile $f 
    #
    if { [ catch { open $::activeFile r } fd ] } {
	del_fromFileHistory $::activeFile
    	error "$fd"
	return
    }        
    alterFileHistory $::activeFile
    set start_pos [file size $::myLogFile ]
    set body [read $fd]
    close $fd
    #
    regsub -all -- {\n\s*\/\*} $body "\n" body2
    regsub -all -- {\n\s*\*\/} $body2 "\n" body3
    regsub -all -- {\n\s*\$} $body3 "\nAddSnmpVar " body2    
    regsub -all -- {\n%include} $body2 "\nInclude" body3
    #    
    if [ catch { namespace eval ::Parser::Global $body3 } rezult ] {
	#error "$rezult"
	puts stderr "GLOBAL:$rezult"
    }
    set stop_pos [file size $::myLogFile ]
    if { $stop_pos > $start_pos } { showErrorLog  $start_pos $stop_pos }
    makeServiceMenus
    updateScrollRegion {}
}
#
