1#!/usr/local/bin/perl 2# $Id: index.cgi,v 1.6 2005/04/16 14:30:21 jfranken Exp $ 3# * List all subnets and shared networks 4# 5# File modified 2005-04-15 by Johannes Franken <jfranken@jfranken.de>: 6# * Added support for DNS Zones (list, edit, create zone-directives) 7# * Added a button to edit key-directives 8# * Added a button to edit dhcp.conf in a text editor 9 10require './dhcpd-lib.pl'; 11$display_max = $config{'display_max'} || 1000000000; 12&ReadParse(); 13$horder = $in{'horder'}; 14$norder = $in{'norder'}; 15if ($horder eq "" && open(INDEX, "<$module_config_directory/hindex.".$remote_user)) { 16 chop($horder = <INDEX>); 17 close(INDEX); 18 } 19if (!$horder) { 20 $horder = 0; 21 } 22if ($norder eq "" && open(INDEX, "<$module_config_directory/nindex.".$remote_user)) { 23 chop($norder = <INDEX>); 24 close(INDEX); 25 } 26if (!$norder) { 27 $norder = 0; 28 } 29$nocols = $config{'dhcpd_nocols'} ? $config{'dhcpd_nocols'} : 5; 30$conf = &get_config(); 31%access = &get_module_acl(); 32 33# Check if dhcpd is installed 34if (!-x $config{'dhcpd_path'}) { 35 &ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1, 0, 36 &help_search_link("dhcpd", "man", "doc", "howto", "google")); 37 print &text('index_dhcpdnotfound', $config{'dhcpd_path'}, 38 "$gconfig{'webprefix'}/config.cgi?$module_name"),"<p>\n"; 39 40 &foreign_require("software", "software-lib.pl"); 41 $lnk = &software::missing_install_link("dhcpd", $text{'index_dhcpd'}, 42 "../$module_name/", $text{'index_title'}); 43 print $lnk,"<p>\n" if ($lnk); 44 45 &ui_print_footer("/", $text{'index_return'}); 46 exit; 47 } 48 49# Check if it is the right version 50@st = stat($config{'dhcpd_path'}); 51if ($st[7] != $config{'dhcpd_size'} || $st[9] != $config{'dhcpd_mtime'}) { 52 # File has changed .. get the version 53 local $ver = &get_dhcpd_version(\$out); 54 if (!$ver) { 55 &ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1, 0, 56 &help_search_link("dhcpd", "man", "doc", "howto", "google")); 57 print (&text('index_dhcpdver2',$config{'dhcpd_path'}, 58 2, 3)),"<p>\n"; 59 print "<pre>$out</pre>\n"; 60 &ui_print_footer("/", $text{'index_return'}); 61 exit; 62 } 63 $config{'dhcpd_version'} = $ver; 64 $config{'dhcpd_size'} = $st[7]; 65 $config{'dhcpd_mtime'} = $st[9]; 66 &write_file("$module_config_directory/config", \%config); 67 } 68 69&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1, 0, 70 &help_search_link("dhcpd", "man", "doc", "howto", "google"), 71 undef, undef, &text('index_version', $config{'dhcpd_version'})); 72 73# Create lookup type HTML 74# XXX change text, add to lookup_* 75$matches = ui_select("match", $config{'match_default'} || 0, 76 [ [0, $text{'index_match0'} ], 77 [1, $text{'index_match1'} ], 78 [2, $text{'index_match2'} ] ]); 79 80# get top-level hosts 81foreach $h (&find("host", $conf)) { 82 push(@host, $h); 83 } 84foreach $g (&find("group", $conf)) { 85 push(@group, $g); 86 foreach $h (&find("host", $g->{'members'})) { 87 push(@host, $h); 88 $group{$h} = $g->{'index'}; 89 $par{$h} = $g; 90 push(@{$g->{'hosts'}}, $h->{'values'}->[0]); 91 } 92 } 93 94# get subnets and shared nets, and the hosts and groups within them 95@subn = &find("subnet", $conf); 96foreach $u (@subn) { 97 $maxsubn = $maxsubn > $u->{'index'} ? $maxsubn : $u->{'index'}; 98 foreach $h (&find("host", $u->{'members'})) { 99 $maxhost = $maxhost > $h->{'index'} ? $maxhost : $h->{'index'}; 100 $subnet{$h} = $u->{'index'}; 101 $par{$h} = $u; 102 push(@host, $h); 103 } 104 foreach $g (&find("group", $u->{'members'})) { 105 $maxgroup = $maxgroup > $g->{'index'} ? $maxgroup : $g->{'index'}; 106 $subnet{$g} = $u->{'index'}; 107 $par{$g} = $u; 108 push(@group, $g); 109 foreach $h (&find("host", $g->{'members'})) { 110 $maxhost = $maxhost > $h->{'index'} ? $maxhost : $h->{'index'}; 111 $subnet{$h} = $u->{'index'}; 112 $group{$h} = $g->{'index'}; 113 $par{$h} = $g; 114 push(@{$g->{'hosts'}}, $h->{'values'}->[0]); 115 push(@host, $h); 116 } 117 } 118 } 119@shan = &find("shared-network", $conf); 120foreach $s (@shan) { 121 $maxshar = $maxshar > $s->{'index'} ? $maxshar : $s->{'index'}; 122 foreach $h (&find("host", $s->{'members'})) { 123 $maxhost = $maxhost > $h->{'index'} ? $maxhost : $h->{'index'}; 124 $shared{$h} = $s->{'index'}; 125 $par{$h} = $s; 126 push(@host, $h); 127 } 128 foreach $g (&find("group", $s->{'members'})) { 129 $maxgroup = $maxgroup > $g->{'index'} ? $maxgroup : $g->{'index'}; 130 $shared{$g} = $s->{'index'}; 131 $par{$g} = $s; 132 push(@group, $g); 133 foreach $h (&find("host", $g->{'members'})) { 134 $maxhost = $maxhost > $h->{'index'} ? $maxhost : $h->{'index'}; 135 $group{$h} = $g->{'index'}; 136 $shared{$h} = $s->{'index'}; 137 $par{$h} = $g; 138 push(@{$g->{'hosts'}}, $h->{'values'}->[0]); 139 push(@host, $h); 140 } 141 } 142 foreach $u (&find("subnet", $s->{'members'})) { 143 $maxsubn = $maxsubn > $u->{'index'} ? $maxsubn : $u->{'index'}; 144 $par{$u} = $s; 145 push(@subn, $u); 146 $shared{$u} = $s->{'index'}; 147 foreach $h (&find("host", $u->{'members'})) { 148 $maxhost = $maxhost > $h->{'index'} ? $maxhost : $h->{'index'}; 149 $subnet{$h} = $u->{'index'}; 150 $shared{$h} = $s->{'index'}; 151 $par{$h} = $u; 152 push(@host, $h); 153 } 154 foreach $g (&find("group", $u->{'members'})) { 155 $maxgroup = $maxgroup > $g->{'index'} ? $maxgroup : $g->{'index'}; 156 $subnet{$g} = $u->{'index'}; 157 $shared{$g} = $s->{'index'}; 158 $par{$g} = $u; 159 push(@group, $g); 160 foreach $h (&find("host", $g->{'members'})) { 161 $maxhost = $maxhost > $h->{'index'} ? $maxhost : $h->{'index'}; 162 $subnet{$h} = $u->{'index'}; 163 $group{$h} = $g->{'index'}; 164 $shared{$h} = $s->{'index'}; 165 $par{$h} = $g; 166 push(@{$g->{'hosts'}}, $h->{'values'}->[0]); 167 push(@host, $h); 168 } 169 } 170 } 171 } 172foreach $s (@shan) { 173 $s->{'order'} = (1 + $s->{'index'}) * (2 + $maxsubn); 174 } 175foreach $s (@subn) { 176 $s->{'order'} = (defined($shared{$s}) ? (1 + $shared{$s}) * (2 + $maxsubn) : 0) 177 + 1 + $s->{'index'}; 178 } 179if ($norder == 0) { 180 @subn = (@subn, @shan); 181 } 182elsif ($norder == 1) { 183 @subn = (@subn, @shan); 184 @subn = sort { $a->{'order'} <=> $b->{'order'} } @subn; 185 } 186elsif ($norder == 2) { 187 @subn = sort { $a->{'values'}->[0] <=> $b->{'values'}->[0] } @subn; 188 @shan = sort { $a->{'values'}->[0] cmp $b->{'values'}->[0] } @shan; 189 @subn = (@subn, @shan); 190 } 191 192# display subnets and shared nets 193my @cansubn; 194foreach $u (@subn) { 195 local $can_view = &can('r', \%access, $u); 196 next if !$can_view && $access{'hide'}; 197 local ($l, $t, $i); 198 push(@cansubn, $u); 199 if ($u->{'name'} eq "subnet") { 200 push(@ulinks, $l = $can_view ? 201 "edit_subnet.cgi?idx=$u->{'index'}". 202 ($shared{$u} ne "" ? "&sidx=$shared{$u}" : "") : 203 undef); 204 push(@uicons, $i = "images/subnet.gif"); 205 push(@checkboxids, $u->{'index'}. 206 ($shared{$u} ne "" ? "/$shared{$u}" : "")); 207 } 208 else { 209 push(@slinks, $l = $can_view ? 210 "edit_shared.cgi?idx=$u->{'index'}" : undef); 211 push(@sicons, $i = "images/shared.gif"); 212 push(@checkboxids, $u->{'index'}); 213 } 214 if ($config{'desc_name'} && $u->{'comment'}) { 215 push(@utitles, $t = &html_escape($u->{'comment'})); 216 } 217 else { 218 push(@utitles, $t = &html_escape($u->{'values'}->[0])); 219 } 220 push(@uslinks, $l); # so that ordering is preserved 221 push(@ustitles, $t); 222 push(@usicons, $i); 223 } 224@checkboxes = map { &ui_checkbox("d", $_) } @checkboxids; 225if ($access{'r_sub'} || $access{'c_sub'} || 226 $access{'r_sha'} || $access{'c_sha'}) { 227 print &ui_subheading($text{'index_subtitle'}); 228 $sp = ""; 229 if (@ulinks < $display_max && @slinks < $display_max) { 230 @links = @uslinks; 231 @titles = @ustitles; 232 @icons = @usicons; 233 } 234 elsif (@ulinks < $display_max) { 235 @links = @ulinks; 236 @titles = @utitles; 237 @icons = @uicons; 238 } 239 elsif (@slinks < $display_max) { 240 @links = @slinks; 241 @titles = @stitles; 242 @icons = @sicons; 243 } 244 if (@links) { 245 # Show table of subnets and shared nets 246 $show_subnet_delete = 1; 247 print &ui_form_start("delete_subnets.cgi"); 248 &subnet_add_links(); 249 if ($config{'hostnet_list'} == 0) { 250 &icons_table(\@links, \@titles, \@icons, $nocols, 251 undef, undef, undef, \@checkboxes); 252 } 253 else { 254 &net_table(\@cansubn, 0, scalar(@cansubn), \@links, 255 \@titles, \@checkboxids); 256 } 257 } 258 elsif (!@ulinks && !@slinks) { 259 # No subnets or shared nets 260 print "$text{'index_nosubdef'} <p>\n"; 261 } 262 $show_subnet_shared = 1; 263 } 264&subnet_add_links(); 265if ($show_subnet_delete) { 266 print &ui_form_end([ [ "delete", $text{'index_delete'} ] ]); 267 } 268 269# Show too-many forms 270if ($show_subnet_shared) { 271 if (@ulinks >= $display_max) { 272 # Could not show all subnets, so show lookup form 273 print &ui_form_start("lookup_subnet.cgi", "get"); 274 print &ui_table_start(undef, undef, 2); 275 print &ui_table_row($text{'index_subtoomany'}, &ui_submit($text{'index_sublook2'})); 276 print &ui_table_row($matches, &ui_textbox("subnet", "", 30)); 277 print &ui_table_end(); 278 print &ui_form_end(undef,undef,1); 279 } 280 if (@slinks >= $display_max) { 281 # Could not show all shared nets, so show lookup form 282 print &ui_form_start("lookup_shared.cgi", "get"); 283 print &ui_table_start(undef, undef, 2); 284 print &ui_table_row($text{'index_shatoomany'}, &ui_submit($text{'index_shalook2'})); 285 print &ui_table_row($matches, &ui_textbox("shared", "", 30)); 286 print &ui_table_end(); 287 print &ui_form_end(undef,undef,1); 288 } 289 } 290 291print &ui_hr(); 292 293foreach $g (@group) { 294 $parent = (defined($subnet{$g}) ? 1 + $subnet{$g} : 0) + 295 (defined($shared{$g}) ? (1 + $shared{$g}) * (2 + $maxsubn) : 0); 296 $g->{'order'} = $parent + (1 + $g->{'index'}) / (2 + $maxgroup); 297 } 298foreach $h (@host) { 299 $parent = (defined($group{$h}) ? (1 + $group{$h}) / (2 + $maxgroup) : 0) + 300 (defined($subnet{$h}) ? 1 + $subnet{$h} : 0) + 301 (defined($shared{$h}) ? (1 + $shared{$h}) * (2 + $maxsubn) : 0); 302 $h->{'order'} = $parent + (1 + $h->{'index'}) / 303 ((1 + @group) * (2 + $maxhost)); 304 } 305if ($horder == 0) { 306 @host = (@host, @group); 307 } 308elsif ($horder == 1) { 309 @host = (@host, @group); 310 @host = sort { $a->{'line'} <=> $b->{'line'} } @host; 311 } 312elsif ($horder == 2) { 313 @host = sort { $a->{'values'}->[0] cmp $b->{'values'}->[0] } @host; 314 @host = (@host, @group); 315 } 316elsif ($horder == 3) { 317 @host = sort { &hardware($a) cmp &hardware($b) } @host; 318 @host = (@host, @group); 319 } 320elsif ($horder == 4) { 321 @host = sort { &ipaddress($a) cmp &ipaddress($b) } @host; 322 @host = (@host, @group); 323 } 324 325# display hosts 326my @canhost; 327foreach $h (@host) { 328 local $can_view = &can('r', \%access, $h); 329 next if !$can_view && $access{'hide'}; 330 push(@canhost, $h); 331 if ($h->{'name'} eq 'host') { 332 # Add icon for a host 333 push(@hlinks, $l = $can_view ? 334 "edit_host.cgi?idx=$h->{'index'}". 335 (defined($group{$h}) ? "&gidx=$group{$h}" : ""). 336 (defined($subnet{$h}) ? "&uidx=$subnet{$h}" : ""). 337 (defined($shared{$h}) ? "&sidx=$shared{$h}" : "") : 338 undef); 339 if ($config{'desc_name'} && $h->{'comment'}) { 340 push(@htitles, &html_escape($h->{'comment'})); 341 } 342 else { 343 push(@htitles, &html_escape($h->{'values'}->[0])); 344 } 345 if ($config{'show_ip'}) { 346 $fv = &fixedaddr($h); 347 $htitles[$#htitles] .= "<br>".$fv if ($fv); 348 } 349 if ($config{'show_mac'}) { 350 local $hard = &find("hardware", $h->{'members'}); 351 $htitles[$#htitles] .= "<br>$hard->{'values'}->[1]" 352 if ($hard); 353 } 354 $t = $htitles[$#htitles]; 355 push(@hicons, $i = "images/host.gif"); 356 push(@hgcheckboxids, join("/", $h->{'index'}, $group{$h}, 357 $subnet{$h}, $shared{$h})); 358 } 359 else { 360 # Add icon for a group 361 push(@glinks, $l = $can_view ? 362 "edit_group.cgi?idx=$h->{'index'}". 363 (defined($subnet{$h}) ? "&uidx=$subnet{$h}" : ""). 364 (defined($shared{$h}) ? "&sidx=$shared{$h}" : "") : 365 undef); 366 $gm = @{$h->{'hosts'}}; 367 push(@gtitles, $t = &html_escape(&group_name($gm, $h))); 368 push(@gicons, $i = "images/group.gif"); 369 push(@hgcheckboxids, join("/", $h->{'index'}, $subnet{$h}, 370 $shared{$h})); 371 } 372 push(@hglinks, $l); 373 push(@hgtitles, $t); 374 push(@hgicons, $i); 375 } 376@hgcheckboxes = map { &ui_checkbox("d", $_) } @hgcheckboxids; 377if ($access{'r_hst'} || $access{'c_hst'} || 378 $access{'r_grp'} || $access{'c_grp'}) { 379 print &ui_subheading($text{'index_hst'}); 380 $sp = ""; 381 if (@hlinks < $display_max && @glinks < $display_max) { 382 @links = @hglinks; 383 @titles = @hgtitles; 384 @icons = @hgicons; 385 } 386 elsif (@hlinks < $display_max) { 387 @links = @hlinks; 388 @titles = @htitles; 389 @icons = @hicons; 390 } 391 elsif (@glinks < $display_max) { 392 @links = @glinks; 393 @titles = @gtitles; 394 @icons = @gicons; 395 } 396 if (@links) { 397 # Some hosts or groups to show 398 &index_links($horder, "h", 5, $text{'index_hdisplay'}, 399 "norder=$norder"); 400 $show_host_delete = 1; 401 print &ui_form_start("delete_hosts.cgi"); 402 &host_add_links(); 403 if ($config{'hostnet_list'} == 0) { 404 &icons_table(\@links, \@titles, \@icons, $nocols, 405 undef, undef, undef, \@hgcheckboxes); 406 } 407 else { 408 &host_table(\@canhost, 0, scalar(@canhost), \@links, 409 \@titles, \@hgcheckboxids); 410 } 411 } 412 elsif (!@hlinks && !@glinks) { 413 # None to show at all 414 print "$text{'index_nohst'} <p>\n"; 415 } 416 $show_host_group = 1; 417 } 418&host_add_links(); 419if ($show_host_delete) { 420 print &ui_form_end([ [ "delete", $text{'index_delete'} ] ]); 421 } 422 423# Show too-many forms 424if ($show_host_group) { 425 if (@hlinks >= $display_max) { 426 # Could not show all hosts, so show lookup form 427 print &ui_form_start("lookup_host.cgi", "get"); 428 print &ui_table_start(undef, undef, 2); 429 print &ui_table_row($text{'index_hsttoomany'}, &ui_submit($text{'index_hstlook2'})); 430 print &ui_table_row($matches, &ui_textbox("host", "", 30)); 431 print &ui_table_end(); 432 print &ui_form_end(undef,undef,1); 433 } 434 if (@glinks >= $display_max) { 435 # Could not show all groups, so show lookup form 436 print &ui_form_start("lookup_group.cgi", "get"); 437 print &ui_table_start(undef, undef, 2); 438 print &ui_table_row($text{'index_grptoomany'}, &ui_submit($text{'index_grplook2'})); 439 print &ui_table_row($matches, &ui_textbox("group", "", 30)); 440 print &ui_table_end(); 441 print &ui_form_end(undef,undef,1); 442 } 443 } 444 445print &ui_hr(); 446 447############ START ZONES ##### 448 449if ($config{'dhcpd_version'} >= 3 && $access{'zones'}) { 450 print &ui_subheading($text{'zone_key'}); 451 452 # get zones 453 @zones = &find("zone", $conf); 454 @zones = sort { $a->{'values'}->[0] <=> $b->{'values'}->[0] } @zones; 455 if (@zones) { 456 # display zones 457 print &ui_link("edit_zones.cgi?new=1",$text{'index_addzone'})." \n" if $access{'c_sub'}; 458 foreach $z (@zones) { 459 # print "ZONE: $z->{'value'} <br>"; 460 push(@zlinks, "edit_zones.cgi?idx=$z->{'index'}"); 461 push(@zicons, "images/files.gif"); 462 push(@ztitles, &html_escape($z->{'values'}->[0])); 463 } 464 if ($config{'hostnet_list'} == 0) { 465 # user wants icons 466 &icons_table(\@zlinks, \@ztitles, \@zicons, $nocols); 467 } 468 else { 469 # user wants text 470 &zone_table(\@zones, 0, scalar(@zones), \@zlinks, \@ztitles); 471 } 472 } 473 else { 474 print "<b>$text{'index_nozones'}</b><p>\n"; 475 } 476 print &ui_link("edit_zones.cgi?new=1",$text{'index_addzone'})." \n" if $access{'c_sub'}; 477 print &ui_hr(); 478 479} 480 481# Buttons for global actions 482print &ui_buttons_start(); 483 484if ($access{'global'}) { 485 # Edit global client options 486 print &ui_buttons_row("edit_options.cgi", 487 $text{'index_buttego'}, $text{'index_ego'}, 488 &ui_hidden("global", 1)); 489 } 490 491if ($config{'dhcpd_version'} >= 3 && $access{'global'}) { 492 # TSIG keys 493 print &ui_buttons_row("edit_keys.cgi", 494 $text{'index_buttekey'}, $text{'index_key'}); 495 } 496if (!$access{'noconfig'}) { 497 # Manually edit config file 498 print &ui_buttons_row("edit_text.cgi", 499 $text{'index_buttetext'}, $text{'index_text'}); 500 } 501if (!$access{'noconfig'}) { 502 # Select network interfaces 503 print &ui_buttons_row("edit_iface.cgi", 504 $text{'index_buttiface'}, $text{'index_iface'}); 505 } 506if ($access{'r_leases'}) { 507 # Show active leases 508 print &ui_buttons_row("list_leases.cgi", 509 $text{'index_buttlal'}, $text{'index_lal'}); 510 } 511if ($access{'apply'}) { 512 $pid = &is_dhcpd_running(); 513 if ($pid) { 514 # Apply and stop buttons 515 print &ui_buttons_row("restart.cgi", 516 $text{'index_buttapply'}, $text{'index_apply'}, 517 &ui_hidden("pid", $pid)); 518 print &ui_buttons_row("stop.cgi", 519 $text{'index_stop'}, $text{'index_stopdesc'}, 520 &ui_hidden("pid", $pid)); 521 } 522 else { 523 # Start button 524 print &ui_buttons_row("start.cgi", 525 $text{'index_buttstart'}, $text{'index_start'}); 526 } 527 } 528print &ui_buttons_end(); 529 530&ui_print_footer("/", $text{'index_return'}); 531 532# Returns canonized hardware address. 533sub hardware { 534 local ($hconf, $addr); 535 $hconf = $_[0]->{'members'} ? &find("hardware", $_[0]->{'members'}) : undef; 536 if ($hconf) { 537 $addr = uc($hconf->{'values'}->[1]); 538 $addr =~ s/(^|\:)([0-9A-F])(?=$|\:)/$1\x30$2/g; 539 } 540 return $hconf ? $addr : undef; 541} 542 543# Returns ip address for sorting on 544sub ipaddress 545{ 546return undef if (!$_[0]->{'members'}); 547local $iconf = &find("fixed-address", $_[0]->{'members'}); 548return undef if (!$iconf); 549return sprintf "%3.3d.%3.3d.%3.3d.%3.3d", 550 split(/\./, $iconf->{'values'}->[0]); 551} 552 553sub fixedaddr { 554 local ($fixed, $addr); 555 $fixed = &find("fixed-address", $_[0]->{'members'}); 556 if ($fixed) { 557 $addr = join(" ", grep { $_ ne "," } @{$fixed->{'values'}}); 558 return $addr; 559 } else { 560 return undef; 561 } 562} 563 564sub netmask { 565 return $_[0]->{'values'}->[2]; 566} 567 568# index_links(current, name, max, txt, ref) 569sub index_links 570{ 571local (%linkname, $l); 572local @links; 573for (my $l = 0; $l < $_[2]; $l++) { 574 my $msg = $text{"index_$_[1]order$l"}; 575 if ($l eq $_[0]) { 576 push(@links, $msg); 577 } 578 else { 579 push(@links, &ui_link("?$_[1]order=$l\&$_[4]",$msg) ); 580 } 581 } 582print "<b>$_[3]</b> ",&ui_links_row(\@links),"\n"; 583open(INDEX, "> $module_config_directory/$_[1]index.".$remote_user); 584print INDEX "$_[0]\n"; 585close(INDEX); 586} 587 588sub host_table 589{ 590local ($i, $h, $parent); 591local @tds = ( "width=5" ); 592print &ui_columns_start([ "", $text{'index_hostgroup'}, 593 $text{'index_parent'}, $text{'index_hardware'}, 594 $text{'index_nameip'} ], 100, 0, \@tds); 595for ($i = $_[1]; $i < $_[2]; $i++) { 596 local @cols; 597 local $firstcol; 598 $parent = ""; 599 $par_type = ""; 600 $h = $_[0]->[$i]; 601 if ($h->{'name'} eq 'host') { 602 $firstcol .= $sp; 603 } 604 else { 605 $firstcol .= $text{'index_group'}." "; 606 $sp = "\ \ "; 607 } 608 if ($_[3]->[$i]) { 609 $firstcol .= &ui_link($_[3]->[$i], $_[4]->[$i]); 610 } 611 else { 612 $firstcol .= $_[4]->[$i]; 613 } 614 push(@cols, $firstcol); 615 616 if ($par{$h}->{'name'} eq "group") { 617 $par_type = $text{'index_togroup'}; 618 $parent = &group_name(scalar @{$par{$h}->{'hosts'}}); 619 } elsif ($par{$h}->{'name'} eq "subnet") { 620 $par_type = $text{'index_tosubnet'}; 621 $parent = $par{$h}->{'values'}->[0]; 622 } elsif ($par{$h}->{'name'} eq "shared-network") { 623 $par_type = $text{'index_toshared'}; 624 $parent = $par{$h}->{'values'}->[0]; 625 } 626 627 if ($config{'desc_name'} && $par{$h}->{'comment'}) { 628 $parent = $par{$h}->{'comment'}; 629 } 630 push(@cols, "$par_type $parent"); 631 push(@cols, $_[3]->[$i] ? &hardware($h) : ""); 632 push(@cols, $_[3]->[$i] ? &fixedaddr($h) : ""); 633 print &ui_checked_columns_row(\@cols, \@tds, "d", $_[5]->[$i]); 634 } 635print &ui_columns_end(); 636} 637 638#&net_table(\@subn, 0, scalar(@subn), \@links, \@titles, \@checkboxids); 639sub net_table 640{ 641local ($i, $n); 642local @tds = ( "width=5" ); 643print &ui_columns_start([ "", $text{'index_net'}, $text{'index_netmask'}, 644 $text{'index_desc'}, $text{'index_parent'} ], 100, 645 0, \@tds); 646for ($i = $_[1]; $i < $_[2]; $i++) { 647 local @cols; 648 $n = $_[0]->[$i]; 649 local $first; 650 if ($n->{'name'} eq 'subnet') { 651 $first = $sp; 652 } 653 else { 654 $sp = "\ \ "; 655 } 656 if ($_[3]->[$i]) { 657 $first .= &ui_link($_[3]->[$i],$_[4]->[$i]); 658 } 659 else { 660 $first .= $_[4]->[$i]; 661 } 662 push(@cols, $first); 663 push(@cols, $_[3]->[$i] ? &netmask($n) : ""); 664 push(@cols, $n->{'comment'}); 665 push(@cols, $par{$n} ? 666 "$text{'index_toshared'} $par{$n}->{'values'}->[0]" : ""); 667 print &ui_checked_columns_row(\@cols, \@tds, "d", $_[5]->[$i]); 668 } 669print &ui_columns_end(); 670} 671 672 673#&zone_table(\@zones, 0, scalar(@zones), \@zlinks, \@ztitles); 674sub zone_table 675{ 676my $i; 677print &ui_table_start($text{'index_zone'}, "width=95%", 2); 678for ($i = $_[1]; $i < $_[2]; $i++) { 679 print &ui_table_row(undef, &ui_link($_[3]->[$i],$_[4]->[$i]) ); 680 } 681print &ui_table_end(); 682} 683 684sub subnet_add_links 685{ 686local @links; 687if ($show_subnet_delete) { 688 push(@links, &select_all_link("d"), 689 &select_invert_link("d")); 690 } 691push(@links, &ui_link("edit_subnet.cgi?new=1",$text{'index_addsub'}) ) 692 if $access{'c_sub'}; 693push(@links, &ui_link("edit_shared.cgi?new=1",$text{'index_addnet'}) ) 694 if $access{'c_sha'}; 695print &ui_links_row(\@links); 696} 697 698sub host_add_links 699{ 700local @links; 701if ($show_host_delete) { 702 push(@links, &select_all_link("d", 1), 703 &select_invert_link("d", 1)); 704 } 705push(@links, &ui_link("edit_host.cgi?new=1",$text{'index_addhst'}) ) 706 if $access{'c_hst'}; 707push(@links, &ui_link("edit_group.cgi?new=1",$text{'index_addhstg'}) ) 708 if $access{'c_grp'}; 709print &ui_links_row(\@links); 710} 711 712