1#!%TCLSH%
2
3#
4# Display equipment list, or equipment details
5#
6# Called by: every topo script
7#
8# Parameters (form or url):
9#	- eq: equipment name (glob)
10#	- iface: interface name
11#
12# History
13#   2006/06/05 : pda      : design
14#   2006/08/14 : pda      : merge listeq
15#   2007/01/04 : pda      : add parameter uid
16#   2007/01/11 : pda      : common initialisation
17#   2007/01/11 : pda      : possible to substitute uid
18#   2008/05/06 : pda      : add localition
19#   2008/07/31 : pda/boggia : tree view
20#   2008/08/01 : pda      : wifi statistics
21#   2010/08/31 : pda/jean : add "native vlan" information
22#   2010/12/11 : pda      : i18n
23#   2010/12/25 : pda      : use cgi-dispatch
24#
25
26#
27# Template pages used by this script
28#
29
30set conf(page1)		eq.html
31set conf(pagen)		topolist.html
32
33#
34# Next actions
35#
36
37set conf(nexteq)	"eq"
38set conf(nextl2)	"l2"
39set conf(nextl3)	"l3"
40set conf(nextmetro)	"metro"
41set conf(nextifchg)	"ifchg"
42
43#
44# Script parameters
45#
46
47set conf(dumpgraph)	"dumpgraph -o eq %s"
48set conf(extractcoll)	"extractcoll -w %s"
49
50#
51# Netmagis general library
52#
53
54source %LIBNETMAGIS%
55
56# ::webapp::cgidebug ; exit
57
58##############################################################################
59# Wifi statistics
60##############################################################################
61
62#
63# General note:
64# Wifi statistics is an array containing following indexes:
65#	tab(:ssid)		{<ssid> ... <ssid>}	(sorted list)
66#	tab(:assoc:cumul)	<id>+<id>+...
67#	tab(:assoc:ssid)	{<ssid> ... <ssid>}	(sorted list)
68#	tab(:assoc:ssid:<ssid>)	{<id>}	ou {}
69#	(idem with :auth)
70# Function "cumul-wifi" accumulates these statistics
71#
72
73#
74# Initialize wifi statistics
75#
76# Input:
77#   - _tab : name of an array containing, in return, accumulated stats
78# Output:
79#   - return value: none
80#   - parameter _tab : see above
81#
82# History
83#   2008/08/03 : pda        : design
84#
85
86proc init-cumul-wifi {_tab} {
87    upvar $_tab tab
88
89    catch {unset tab}
90
91    set lkeys {assoc auth}
92
93    set tab(:ssid)	   {}
94
95    foreach k $lkeys {
96	set tab(:$k:cumul)  {}
97	set tab(:$k:ssid)   {}
98	set tab(:$k:ap)     {}
99    }
100}
101
102#
103# Cumulate wifi statistics for an access point
104#
105# Input:
106#   - sensors : wifi sensor list for this access point
107#		{{<nbauthwifi|nbassocwifi> <id> <ssid>}
108#   - _tab : name of an array containing, in return, accumulated stats
109# Output:
110#   - return value: none
111#   - parameter _tab : see above
112#
113# History
114#   2008/08/02 : pda        : design
115#
116
117proc cumul-wifi {sensors _tab} {
118    upvar $_tab tab
119
120    init-cumul-wifi tab
121
122    set lkeys {assoc auth}
123
124    foreach l $sensors {
125	lassign $l kw id ssid
126
127	if {! [info exists seen($ssid)]} then {
128	    lappend tab(:ssid) $ssid
129	    set seen($ssid) 1
130	    foreach k $lkeys {
131		set tab(:$k:ssid:$ssid) {}
132	    }
133	}
134
135	switch $kw {
136	    nbassocwifi { set k "assoc" }
137	    nbauthwifi  { set k "auth" }
138	    default     { set k "???" }
139	}
140
141	lappend tab(:$k:cumul) $id
142	lappend tab(:$k:ssid:$ssid) $id
143	lappend tab(:$k:ssid) $ssid
144    }
145
146    foreach k $lkeys {
147	set tab(:$k:cumul) [join $tab(:$k:cumul) "+"]
148    }
149
150    set tab(:ssid) [lsort $tab(:ssid)]
151    foreach k $lkeys {
152	set tab(:$k:ssid) [lsort $tab(:$k:ssid)]
153    }
154}
155
156#
157# Cumulate wifi statistics for a new access point
158#
159# Input:
160#   - _tr : array containing all stats
161#   - _t1 : array containing stats for one access point
162# Output:
163#   - return value: none
164#   - parameters _tr, _t1 : see above
165#
166# History
167#   2008/08/04 : pda        : specification
168#   2008/08/14 : pda        : end of coding
169#
170
171proc accumulate {_tr _t1} {
172    upvar $_tr tr
173    upvar $_t1 t1
174
175    set lkeys {assoc auth}
176
177    #
178    # Add ssid to list of ssids
179    #
180
181    foreach ssid $t1(:ssid) {
182	if {[lsearch $ssid $tr(:ssid)]} then {
183	    lappend tr(:ssid) $ssid
184	}
185    }
186
187    #
188    # Add per ssid stats
189    #
190
191    foreach k $lkeys {
192	foreach ssid $t1(:$k:ssid) {
193	    set c ":$k:ssid:$ssid"
194	    if {[info exists tr($c)]} then {
195		set l [concat $tr($c) $t1($c)]
196	    } else {
197		set l $t1($c)
198	    }
199	    set tr($c) $l
200	}
201    }
202
203    #
204    # Add per ap stats
205    #
206
207    foreach k $lkeys {
208	set l {}
209	foreach ssid $t1(:$k:ssid) {
210	    lappend l $t1(:$k:ssid:$ssid)
211	}
212	lappend tr(:$k:ap) [join $l "+"]
213    }
214
215    #
216    # Cumulate the cumul
217    #
218
219    foreach k $lkeys {
220	if {$tr(:$k:cumul) eq ""} then {
221	    set tr(:$k:cumul) $t1(:$k:cumul)
222	} else {
223	    append tr(:$k:cumul) "+$t1(:$k:cumul)"
224	}
225    }
226
227    #
228    # Sort final lists
229    #
230
231    set tr(:ssid) [lsort $tr(:ssid)]
232    foreach k $lkeys {
233	set tr(:$k:ssid) [lsort $tr(:$k:ssid)]
234    }
235}
236
237##############################################################################
238# Make a tree from an equipment list
239##############################################################################
240
241#
242# Place an element into a tree
243#
244# Input:
245#   - _thier : array containing the tree
246#   - list : element list by level
247#   - cumul : 1 if elements must be accumulated, else 0 (see below)
248# Output:
249#   - return value: none
250#   - array _thier : updated
251#
252# Example 1 :
253#   if list = {anapat -ap 3} and cumul = 1 and thier =
254#	t()		= {anapat}
255#	t(anapat)	= {anapat-ap}
256#	t(anapat-ap)	= {anapat-ap1}
257#	t(anapat-ap1)	= {}
258#   then thier is updated with:
259#	t()		= {anapat}
260#	t(anapat)	= {anapat-ap}
261#	t(anapat-ap)	= {anapat-ap1 anapat-ap3} (order don't matter 3/1 or 1/3)
262#	t(anapat-ap1)	= {}
263#	t(anapat-ap3)	= {}
264#
265# Example 2 :
266#   in above example, if cumul = 0, we should have the list:
267#		{anapat anapat-ap anapat-ap3}
268#
269# Example 3 :
270#   if list = {horus} and thier =
271#	(nothing)
272#   then thier is updated with:
273#	t()		= {horus}
274#	t(horus)	= {}
275#
276# History
277#   2008/07/31 : pda/boggia : design
278#
279
280proc place-into-tree {_thier list cumul} {
281    upvar $_thier thier
282
283    set root ""
284    set idx ""
285    foreach word $list {
286	if {$cumul} then {
287	    append idx $word
288	} else {
289	    set idx $word
290	}
291	if {! ([info exists thier($root)] && $idx in $thier($root))} then {
292	    lappend thier($root) $idx
293	}
294	set root $idx
295    }
296    lappend thier($root) {}
297}
298
299#
300# Make a tree from an equipment list
301#
302# Input:
303#   - _t : tree
304#   - leq : equipment list
305# Output:
306#   - return value: none
307#   - _t : updated
308#
309# Note: grouping in a tree is realized on equipment name, which is
310#   splitted following a local specific policy, which is:
311#	[xxx] [-tt] [nn]
312#   where xxx is a prefix, -tt is the equipment type and nn the number
313#   within the type. For example, "anapat-ap3" is splitted in: anapat -ap 3
314#
315# History
316#   2008/07/31 : pda/boggia : design
317#
318
319proc listeq-to-tree {_t leq} {
320    upvar $_t t
321
322    catch {unset t}
323
324    #
325    # First phase: make a tree from all elements
326    #
327
328    foreach eq $leq {
329	if {[regexp  {(.*)(-[a-z]+)([0-9]+)$} $eq bidon n1 n2 n3]} then {
330	    place-into-tree t [list $n1 $n2 $n3] 1
331	} else {
332	    place-into-tree t [list $eq] 1
333	}
334    }
335
336    #
337    # Second phase: move up one level (recursively) all equipments
338    # when they are alone on their level (except "-ap" equipments,
339    # which are wifi access-points in our local policy)
340    #
341
342    # XXX : not yet
343
344    #
345    # Third phase: sort each level
346    #
347
348    foreach i [array names t] {
349	set t($i) [lsort $t($i)]
350    }
351}
352
353#
354# Display equipment tree
355#
356# Input:
357#   - root: root of tree
358#   - _thier : tree
359#   - _tabeq : array containaing all equipments
360#   - _tabwifi : array containing all wifi sensors
361# Output:
362#   - return value: list of trees where root is at this level
363#
364# History
365#   2008/07/31 : pda/boggia : design
366#   2008/08/01 : pda/boggia : add tabwifi
367#
368
369proc display-eq-tree {root _thier _tabeq _tabwifi} {
370    global conf
371    upvar $_thier thier
372    upvar $_tabeq tabeq
373    upvar $_tabwifi tabwifi
374
375    set tree {}
376    set nwifi 0
377    init-cumul-wifi twa
378
379    foreach son $thier($root) {
380	#
381	# The goal of this loop is to avoid to make multiple levels
382	# when there is only one son at each level
383	#
384	set prec $root
385	while {$son ne "" && [llength $thier($son)] <= 1} {
386	    set prec $son
387	    set son [lindex $thier($son) 0]
388	}
389
390	#
391	# Node or leaf ?
392	#
393
394	if {$son eq ""} then {
395	    #
396	    # Leaf: it's an equipment
397	    #
398	    set type  [lindex $tabeq($prec) 0]
399	    set model [lindex $tabeq($prec) 1]
400
401	    d urlset "" $conf(nexteq) [list [list "eq" $prec]]
402	    set url [d urlget ""]
403	    set link [::webapp::helem "a" $prec "href" $url]
404	    lappend tree [list "$link $type $model"]
405
406	    #
407	    # Wifi stats
408	    #
409	    if {[info exists tabwifi($prec)]} then {
410		incr nwifi
411		cumul-wifi $tabwifi($prec) tw
412		accumulate twa tw
413	    }
414	} else {
415	    #
416	    # Note: repeat recursively
417	    #
418	    lappend tree [display-eq-tree $son thier tabeq tabwifi]
419	}
420    }
421
422    #
423    # Root display
424    #
425
426    set rhtml $root
427    if {$nwifi > 1 && $nwifi == [llength $thier($root)]} then {
428	#
429	# Display wifi stats if all leafs are access points
430	#
431
432	#
433	# Cumul
434	#
435
436	append rhtml [format " (%s " [mc "sums"]]
437	foreach k {assoc auth} {
438	    set tk [mc "$k"]
439	    set hid $twa(:$k:cumul)
440	    d urlset "" $conf(nextmetro) [list [list "id" $hid]]
441	    set url [d urlget ""]
442	    append rhtml [::webapp::helem "a" "\[$tk\]" "href" $url]
443	}
444
445	#
446	# Details per SSID
447	#
448
449	append rhtml [format ", %s " [mc "detail/SSID"]]
450	foreach k {assoc auth} {
451	    set tk [mc "$k"]
452	    set lid {}
453	    foreach ssid $twa(:$k:ssid) {
454		set lid [concat $lid $twa(:$k:ssid:$ssid)]
455	    }
456	    set hid [join $lid "|"]
457	    d urlset "" $conf(nextmetro) [list [list "id" $hid]]
458	    set url [d urlget ""]
459	    append rhtml [::webapp::helem "a" "\[$tk\]" "href" $url]
460	}
461
462	#
463	# Details per access point
464	#
465
466	append rhtml [format ", %s " [mc "detail/AP"]]
467	foreach k {assoc auth} {
468	    set tk [mc "$k"]
469	    set hid [join $twa(:$k:ap) "|"]
470	    d urlset "" $conf(nextmetro) [list [list "id" $hid]]
471	    set url [d urlget ""]
472	    append rhtml [::webapp::helem "a" "\[$tk\]" "href" $url]
473	}
474	append rhtml ")"
475    }
476
477    return [linsert $tree 0 $rhtml]
478}
479
480##############################################################################
481# Equipment display
482##############################################################################
483
484proc format-one-eq {eqname iface _tabuid} {
485    global conf
486    upvar $_tabuid tabuid
487
488    #
489    # Read equipment information from graph.
490    #
491
492    set l [eq-iflist $eqname tabuid]
493
494    lassign $l eqname type model location liferr iflist arrayif arrayvlan
495    array set tabiface $arrayif
496
497    #
498    # Title
499    #
500
501    set title [mc "Equipment"]
502    append title " $eqname $type $model"
503    if {$location ne ""} then {
504	append title [format " (%s)" [mc "location"]]
505    }
506
507    #
508    # If an error is found, exit immediately. This case means that
509    # one (or more) interface(s) which is writable, but not readable.
510    #
511
512    if {[llength $liferr] > 0} then {
513	set l [join $liferr " "]
514	set text [mc "Inconsistent permissions on interfaces: %s" $l]
515	return [list $title $text]
516    }
517
518    set eqmod 0
519    set text ""
520    foreach i $iflist {
521	set txt ""
522
523	#
524	# Interface name and parameters (Ethernet, radio)
525	#
526
527	lassign $tabiface($i) name edit radio stat mode desc link native
528	set line [lreplace $tabiface($i) 0 7]
529
530	if {$iface eq $name} then {
531	    append txt [::webapp::helem "b" $name]
532	} else {
533	    append txt "$name"
534	}
535
536	if {[llength $radio] > 0} then {
537	    set channel [conv-channel [lindex $radio 0]]
538	    set power   [lindex $radio 1]
539	    append txt " ("
540	    append txt [mc {channel %1$s power %2$s mW} $channel $power]
541	    append txt ")"
542	}
543
544	if {$stat ne "-"} then {
545	    d urlset "" $conf(nextmetro) [list [list "id" $stat]]
546	    set url [d urlget ""]
547	    append txt " "
548	    append txt [::webapp::helem "a" {[Trafic]} "href" $url]
549	}
550
551	append txt " $mode"
552
553	if {$desc ne "-"} then {
554	    append txt " ("
555	    append txt [::webapp::html-string [binary format H* $desc]]
556	    append txt ")"
557	}
558
559	if {[llength $link] > 1} then {
560	    lassign $link via eq2 if2
561	    d urlset "" $conf(nexteq) [list \
562					    [list "eq" $eq2] \
563					    [list "iface" $if2] \
564					]
565	    set urleqiface [d urlget ""]
566	    append txt " $via "
567	    append txt [mc "to"]
568	    append txt " "
569	    append txt [::webapp::helem "a" "$eq2 $if2" "href" $urleqiface]
570	}
571
572	#
573	# Wifi statistics
574	#
575
576	if {[info exists tabwifi($eqname:$i)]} then {
577
578	    cumul-wifi $tabwifi($eqname:$i) tw
579
580	    append txt " "
581
582	    foreach k {assoc auth} {
583		if {[llength $tw(:$k:ssid)] > 1} then {
584		    #
585		    # Display sums (only if more than one ssid)
586		    #
587
588		    set tk [mc "Sum $k"]
589		    set hid $tw(:$k:cumul)
590		    d urlset "" $conf(nextmetro) [list [list "id" $hid]]
591		    set url [d urlget ""]
592		    append txt " "
593		    append txt [::webapp::helem "a" "\[$tk\]" "href" $url]
594
595		    #
596		    # Detail per ssid (only if more than one ssid)
597		    #
598
599		    set lid {}
600		    foreach ssid $tw(:$k:ssid) {
601			set lid [concat $lid $tw(:$k:ssid:$ssid)]
602		    }
603		    set tk [mc "Detail $k"]
604		    set hid [join $lid "|"]
605		    d urlset "" $conf(nextmetro) [list [list "id" $hid]]
606		    set url [d urlget ""]
607		    append txt " "
608		    append txt [::webapp::helem "a" "\[$tk\]" "href" $url]
609		}
610	    }
611	}
612
613	#
614	# If this interface is writable, activate the button.
615	#
616
617	if {$edit eq "edit"} then {
618	    d urlset "" $conf(nextifchg) [list \
619						[list "eq" $eqname] \
620						[list "iface" $i] \
621					    ]
622	    set e [mc "Edit"]
623	    set url [d urlget ""]
624	    append txt " "
625	    append txt [::webapp::helem "a" "\[$e\]" "href" $url]
626	    incr eqmod
627	}
628
629	#
630	# Traverse vlans available on this interface
631	#
632
633	set nvlan [llength $line]
634	foreach vlan [lsort -index 0 -integer $line] {
635	    lassign $vlan vlanid desc stat
636
637	    if {$desc eq "-"} then {
638		set desc [mc "no description"]
639	    } else {
640		set desc [binary format H* $desc]
641	    }
642	    set natv ""
643	    if {$vlanid == $native} then {
644		set natv [format " (%s)" [mc "native vlan"]]
645	    }
646
647	    append txt "\n<BR>\n"
648
649	    if {$nvlan > 1 || $vlanid != 0} then {
650		d urlset "" $conf(nextl2) [list \
651						[list "eq" $eqname] \
652						[list "iface" $i] \
653						[list "vlan" $vlanid] \
654					    ]
655		set urll2 [d urlget ""]
656		append txt [mc "Vlan"]
657		append txt " "
658		append txt [::webapp::helem "a" "$vlanid ($desc)" "href" $urll2]
659		append txt $natv
660
661		if {$stat ne "-"} then {
662		    set t [mc "Traffic"]
663		    d urlset "" $conf(nextmetro) [list [list "id" $stat]]
664		    set url [d urlget ""]
665		    append txt " "
666		    append txt [::webapp::helem "a" "\[$t\]" "href" $url]
667		}
668	    }
669
670	    foreach ip [lsort [lindex $vlan 3]] {
671		d urlset "" $conf(nextl3) [list [list "addr" $ip]]
672		set urll3 [d urlget ""]
673		append txt " "
674		append txt [::webapp::helem "a" $ip "href" $urll3]
675	    }
676	}
677
678	#
679	# For radio interfaces, fetch sensors
680	#
681
682	if {[info exists tabwifi($eqname:$i)]} then {
683	    foreach ssid $tw(:ssid) {
684		append txt "\n<BR>\n"
685		append txt [mc "SSID %s " $ssid]
686		foreach k {assoc auth} {
687		    set tk [mc $k]
688		    set id [lindex $tw(:$k:ssid:$ssid) 0]
689		    if {$id ne ""} then {
690			d urlset "" $conf(nextmetro) [list [list "id" $id]]
691			set url [d urlget ""]
692			append txt [::webapp::helem "a" "\[$tk\]" "href" $url]
693		    }
694		}
695	    }
696	}
697
698	#
699	# Final result
700	#
701	append text [::webapp::helem "li" [::webapp::helem "p" $txt] STYLE "padding: 0 ; background: none ; list-style: outside url(/images/dash.gif) disc;"]
702    }
703
704    set text [::webapp::helem "ul" $text]
705
706    if {$eqmod > 1} then {
707	set t [mc "Edit interfaces"]
708	d urlset "" $conf(nextifchg) [list [list "eq" $eqname]]
709	set url [d urlget ""]
710	append title " "
711	append title [::webapp::helem "a" "\[$t\]" "href" $url]
712    }
713
714    return [list $title $text]
715}
716
717##############################################################################
718# Display equipment
719##############################################################################
720
721d cgi-register {} {
722    {eq		0 1}
723    {iface	0 1}
724} {
725    global conf
726
727    #
728    # Initialization
729    #
730
731    set msgsta [topo-status $dbfd $tabuid(p_admin)]
732
733    d urlset "%URLFORMEQ%" $conf(nexteq) {}
734    d urlset "%URLFORML2%" $conf(nextl2) {}
735    d urlset "%URLFORML3%" $conf(nextl3) {}
736
737    #
738    # Get equipment informations from graph
739    #
740
741    set cmd [format $conf(dumpgraph) $tabuid(flagsr)]
742    if {! [call-topo $cmd msg]} then {
743	d error [mc "Error while reading equipments: %s" $msg]
744    }
745    foreach line [split $msg "\n"] {
746	switch [lindex $line 0] {
747	    eq {
748		set eqname [lindex $line 1]
749		if {$eq eq "" || [string match -nocase $eq $eqname]} then {
750		    set type  [lindex $line 3]
751		    set model [lindex $line 5]
752		    set tabeq($eqname) [list $type $model]
753		}
754	    }
755	}
756    }
757
758    #
759    # Extract wifi statistics for these equipments
760    #
761
762    set cmd [format $conf(extractcoll) $tabuid(flagsr)]
763    if {! [call-topo $cmd msg]} then {
764	d error [mc "Error while reading wifi sensors: %s" $msg]
765    }
766    foreach line [split $msg "\n"] {
767	switch [lindex $line 0] {
768	    nbassocwifi -
769	    nbauthwifi {
770		lassign $line kw id weq iface ssid
771		if {[info exists tabeq($weq)]} then {
772		    lappend tabwifi($weq) [list $kw $id $ssid]
773		    lappend tabwifi($weq:$iface) [list $kw $id $ssid]
774		}
775	    }
776	}
777    }
778
779    #
780    # If more than one equipment is found, display them in order
781    #
782
783    # 1 if no equipment is searched for, 0 if search for equipment name
784    set ceq [string equal $eq ""]
785
786    # number of equipment found
787    set neq [llength [array names tabeq]]
788
789    switch -glob "$ceq-$neq" {
790	*-0 {
791	    #
792	    # No equipment is found. Proceed as a list, but with an empty list.
793	    # No matter whether or not we searched for an equipment.
794	    #
795
796	    set list [mc "No equipment found"]
797
798	    #
799	    # End of script: output page and close database
800	    #
801
802	    d result $conf(pagen) [list \
803				    [list %MSGSTA% $msgsta] \
804				    [list %OBJETS% [mc "equipments"]] \
805				    [list %LIST%   $list] \
806				    [list %EQ%     $eq] \
807				    [list %VLAN%   ""] \
808				    [list %ADDR%   ""] \
809				    [list %HEADER% ""] \
810				    [list %ONLOAD% ""] \
811				]
812	}
813	*-1 {
814	    #
815	    # We found only one equipment. No matter whether or not
816	    # we searched for it. Extract informations from the graph.
817	    #
818
819	    set eqname [lindex [array names tabeq] 0]
820
821	    set l [format-one-eq $eqname $iface tabuid]
822	    lassign $l title text
823
824	    set eqsta [eq-graph-status $dbfd $eq]
825
826	    #
827	    # End of script: output page and close database
828	    #
829
830	    d result $conf(page1) [list \
831				    [list %MSGSTA% $msgsta] \
832				    [list %EQSTA% $eqsta] \
833				    [list %TITLE% $title] \
834				    [list %TEXTE% $text] \
835				    [list %EQ%    $eq] \
836				    [list %VLAN%  ""] \
837				    [list %ADDR%  ""] \
838				]
839	}
840	0-* {
841	    #
842	    # We search for an equipment (with a regexp for example)
843	    # and we found more than one. Sort equipments.
844	    #
845
846	    set list ""
847	    foreach e [lsort [array names tabeq]] {
848		lassign $tabeq($e) type model
849		d urlset "" $conf(nexteq) [list [list "eq" $e]]
850		set url [d urlget ""]
851		set link [::webapp::helem "a" $e "href" $url]
852		append list [::webapp::helem "li" "$link $type $model"]
853	    }
854	    set list [::webapp::helem "ul" $list]
855
856	    #
857	    # End of script: output page and close database
858	    #
859
860	    d result $conf(pagen) [list \
861				    [list %MSGSTA% $msgsta] \
862				    [list %OBJETS% [mc "equipments"]] \
863				    [list %LIST%   $list] \
864				    [list %EQ%     $eq] \
865				    [list %VLAN%   ""] \
866				    [list %ADDR%   ""] \
867				    [list %HEADER% ""] \
868				    [list %ONLOAD% ""] \
869			    	]
870	}
871	1-* {
872	    #
873	    # We didn't search for an equipment, we just wanted to
874	    # see the list (as a tree).
875	    #
876
877	    listeq-to-tree thier [array names tabeq]
878	    set tree [display-eq-tree "" thier tabeq tabwifi]
879	    set expcoll [list [mc "develop"] [mc "envelop"]]
880	    set t [::webapp::interactive-tree "leq" $tree $expcoll]
881	    lassign $t head1 head2 onload html
882	    set header "$head1\n$head2\n"
883
884	    #
885	    # End of script: output page and close database
886	    #
887
888	    d result $conf(pagen) [list \
889				    [list %MSGSTA% $msgsta] \
890				    [list %OBJETS% [mc "equipments"]] \
891				    [list %LIST%   $html] \
892				    [list %EQ%     $eq] \
893				    [list %VLAN%   ""] \
894				    [list %ADDR%   ""] \
895				    [list %HEADER% $header] \
896				    [list %ONLOAD% $onload] \
897				]
898	}
899    }
900}
901
902##############################################################################
903# Main procedure
904##############################################################################
905
906d cgi-dispatch "topo" ""
907