-# SmoothWall CGIs
-#
-# This code is distributed under the terms of the GPL
-#
-# (c) The SmoothWall Team
-# Copyright (C) 2002 Alex Hudson - getcgihash() rewrite
-# Copyright (C) 2002 Bob Grant <bob@cache.ucr.edu> - validmac()
-# Copyright (c) 2002/04/13 Steve Bootes - add alias section, helper functions
-# Copyright (c) 2002/08/23 Mark Wormgoor <mark@wormgoor.com> validfqdn()
-# Copyright (c) 2003/09/11 Darren Critchley <darrenc@telus.net> srtarray()
-#
-# $Id: header.pl,v 1.34.2.67 2005/10/03 20:01:05 gespinasse Exp $
-#
-
-package Header;
-
-use strict;
-use CGI();
-use Time::Local;
-
-# enable only the following on debugging purpose
-#use warnings;
-#use CGI::Carp 'fatalsToBrowser';
-
-
-$Header::pagecolour = '#ffffff'; # never used, will be removed
-$Header::tablecolour = '#FFFFFF'; # never used, will be removed
-$Header::bigboxcolour = '#F6F4F4'; # never used, will be removed
-$Header::boxcolour = '#EAE9EE'; # only header.pl, ? move in css ?
-$Header::bordercolour = '#000000'; # never used, will be removed
-$Header::table1colour = '#C0C0C0';
-$Header::table2colour = '#F2F2F2';
-$Header::colourred = '#993333';
-$Header::colourorange = '#FF9933';
-$Header::colouryellow = '#FFFF00';
-$Header::colourgreen = '#339933';
-$Header::colourblue = '#333399';
-$Header::colourfw = '#000000'; # only connections.cgi
-$Header::colourvpn = '#990099'; # only connections.cgi
-$Header::colourerr = '#FF0000'; # only header.pl, many scripts use colourred for warnings messages
-$Header::viewsize = 150;
-my %menu = ();
-my $hostnameintitle = 0;
-our $javascript = 1;
-
-### Initialize menu
-sub genmenu
-{
- ### Initialize environment
- my %ethsettings = ();
- &General::readhash("${General::swroot}/ethernet/settings", \%ethsettings);
-
- %{$menu{'1.system'}}=(
- 'contents' => $Lang::tr{'alt system'},
- 'uri' => '',
- 'statusText' => "IPCop $Lang::tr{'alt system'}",
- 'subMenu' => [[ $Lang::tr{'alt home'} , '/cgi-bin/index.cgi', "IPCop $Lang::tr{'alt home'}" ],
- [ $Lang::tr{'updates'} , '/cgi-bin/updates.cgi', "IPCop $Lang::tr{'updates'}" ],
- [ $Lang::tr{'sspasswords'} , '/cgi-bin/changepw.cgi', "IPCop $Lang::tr{'sspasswords'}" ],
- [ $Lang::tr{'ssh access'} , '/cgi-bin/remote.cgi', "IPCop $Lang::tr{'ssh access'}" ],
- [ $Lang::tr{'gui settings'} , '/cgi-bin/gui.cgi', "IPCop $Lang::tr{'gui settings'}" ],
- [ $Lang::tr{'backup'} , '/cgi-bin/backup.cgi', "IPCop $Lang::tr{'backup'} / $Lang::tr{'restore'}" ],
- [ $Lang::tr{'shutdown'} , '/cgi-bin/shutdown.cgi', "IPCop $Lang::tr{'shutdown'} / $Lang::tr{'reboot'}" ],
- [ $Lang::tr{'credits'} , '/cgi-bin/credits.cgi', "IPCop $Lang::tr{'credits'}" ]]
- );
- %{$menu{'2.status'}}=(
- 'contents' => $Lang::tr{'status'},
- 'uri' => '',
- 'statusText' => "IPCop $Lang::tr{'status information'}",
- 'subMenu' => [[ $Lang::tr{'sssystem status'} , '/cgi-bin/status.cgi', "IPCop $Lang::tr{'system status information'}" ],
- [ $Lang::tr{'ssnetwork status'} , '/cgi-bin/netstatus.cgi', "IPCop $Lang::tr{'network status information'}" ],
- [ $Lang::tr{'system graphs'} , '/cgi-bin/graphs.cgi', "IPCop $Lang::tr{'system graphs'}" ],
- [ $Lang::tr{'sstraffic graphs'} , '/cgi-bin/graphs.cgi?graph=network', "IPCop $Lang::tr{'network traffic graphs'}" ],
- [ $Lang::tr{'ssproxy graphs'} , '/cgi-bin/proxygraphs.cgi', "IPCop $Lang::tr{'proxy access graphs'}" ],
- [ $Lang::tr{'connections'} , '/cgi-bin/connections.cgi', "IPCop $Lang::tr{'connections'}" ]]
- );
- %{$menu{'3.network'}}=(
- 'contents' => $Lang::tr{'network'},
- 'uri' => '',
- 'statusText' => "IPCop $Lang::tr{'network configuration'}",
- 'subMenu' => [[ $Lang::tr{'alt dialup'} , '/cgi-bin/pppsetup.cgi', "IPCop $Lang::tr{'dialup settings'}" ],
- [ $Lang::tr{'upload'} , '/cgi-bin/upload.cgi', $Lang::tr{'firmware upload'} ],
- [ $Lang::tr{'modem'} , '/cgi-bin/modem.cgi', "IPCop $Lang::tr{'modem configuration'}" ],
- [ $Lang::tr{'aliases'} , '/cgi-bin/aliases.cgi', "IPCop $Lang::tr{'external aliases configuration'}" ]]
- );
- %{$menu{'4.services'}}=(
- 'contents' => $Lang::tr{'alt services'},
- 'uri' => '',
- 'statusText' => "IPCop $Lang::tr{'alt services'}",
- 'subMenu' => [[ $Lang::tr{'proxy'} , '/cgi-bin/proxy.cgi', "IPCop $Lang::tr{'web proxy configuration'}" ],
- [ $Lang::tr{'dhcp server'} , '/cgi-bin/dhcp.cgi', "IPCop $Lang::tr{'dhcp configuration'}" ],
- [ $Lang::tr{'dynamic dns'} , '/cgi-bin/ddns.cgi', "IPCop $Lang::tr{'dynamic dns client'}" ],
- [ $Lang::tr{'edit hosts'} , '/cgi-bin/hosts.cgi', "IPCop $Lang::tr{'host configuration'}" ],
- [ $Lang::tr{'time server'} , '/cgi-bin/time.cgi', "IPCop $Lang::tr{'time server'}" ],
- [ $Lang::tr{'traffic shaping'} , '/cgi-bin/shaping.cgi', "IPCop $Lang::tr{'traffic shaping settings'}" ],
- [ $Lang::tr{'intrusion detection'} , '/cgi-bin/ids.cgi', "IPCop $Lang::tr{'intrusion detection system'} (Snort)" ]]
- );
- %{$menu{'5.firewall'}}=(
- 'contents' => $Lang::tr{'firewall'},
- 'uri' => '',
- 'statusText' => "IPCop $Lang::tr{'firewall'}",
- 'subMenu' => [[ $Lang::tr{'ssport forwarding'} , '/cgi-bin/portfw.cgi', "IPCop $Lang::tr{'port forwarding configuration'}" ],
- [ $Lang::tr{'external access'} , '/cgi-bin/xtaccess.cgi', "IPCop $Lang::tr{'external access configuration'}" ],
- [ $Lang::tr{'ssdmz pinholes'} , '/cgi-bin/dmzholes.cgi', "IPCop $Lang::tr{'dmz pinhole configuration'}" ],
- [ $Lang::tr{'blue access'} , '/cgi-bin/wireless.cgi', "IPCop $Lang::tr{'blue access'}" ]
- ,[ $Lang::tr{'options fw'} , '/cgi-bin/optionsfw.cgi', "IPCop $Lang::tr{'options fw'}" ]
- ]
- );
- %{$menu{'6.vpns'}}=(
- 'contents' => $Lang::tr{'alt vpn'},
- 'uri' => '',
- 'statusText' => "IPCop $Lang::tr{'virtual private networking'}",
- 'subMenu' => [[ $Lang::tr{'alt vpn'} , '/cgi-bin/vpnmain.cgi', "IPCop $Lang::tr{'virtual private networking'}"]]
- );
- %{$menu{'7.mainlogs'}}=(
- 'contents' => $Lang::tr{'alt logs'},
- 'uri' => '',
- 'statusText' => "IPCop $Lang::tr{'alt logs'}",
- 'subMenu' => [[ $Lang::tr{'log settings'} , '/cgi-bin/logs.cgi/config.dat', "IPCop $Lang::tr{'log settings'}" ],
- [ $Lang::tr{'log summary'} , '/cgi-bin/logs.cgi/summary.dat', "IPCop $Lang::tr{'log summary'}" ],
- [ $Lang::tr{'proxy logs'} , '/cgi-bin/logs.cgi/proxylog.dat', "IPCop $Lang::tr{'proxy log viewer'}" ],
- [ $Lang::tr{'firewall logs'} , '/cgi-bin/logs.cgi/firewalllog.dat', "IPCop $Lang::tr{'firewall log viewer'}" ],
- [ $Lang::tr{'ids logs'} , '/cgi-bin/logs.cgi/ids.dat', "IPCop $Lang::tr{'intrusion detection system log viewer'}" ],
- [ $Lang::tr{'system logs'} , '/cgi-bin/logs.cgi/log.dat', "IPCop $Lang::tr{'system log viewer'}" ]]
- );
- if (! $ethsettings{'BLUE_DEV'}) {
- splice (@{$menu{'5.firewall'}{'subMenu'}}, 3, 1);
- }
- if (! $ethsettings{'BLUE_DEV'} && ! $ethsettings{'ORANGE_DEV'}) {
- splice (@{$menu{'5.firewall'}{'subMenu'}}, 2, 1);
- }
- unless ( $ethsettings{'CONFIG_TYPE'} =~ /^(2|3|6|7)$/ && $ethsettings{'RED_TYPE'} eq 'STATIC' ) {
- splice (@{$menu{'3.network'}{'subMenu'}}, 3, 1);
- }
- if ( ! -e "${General::swroot}/snort/enable" && ! -e "${General::swroot}/snort/enable_blue" &&
- ! -e "${General::swroot}/snort/enable_green" && ! -e "${General::swroot}/snort/enable_orange") {
- splice (@{$menu{'7.mainlogs'}{'subMenu'}}, 4, 1);
- }
- if ( ! -e "${General::swroot}/proxy/enable" && ! -e "${General::swroot}/proxy/enable_blue" ) {
- splice (@{$menu{'2.status'}{'subMenu'}}, 4, 1);
- splice (@{$menu{'7.mainlogs'}{'subMenu'}}, 2, 1);
- }
-}
-
-sub showhttpheaders
-{
- ### Make sure this is an SSL request
- if ($ENV{'SERVER_ADDR'} && $ENV{'HTTPS'} ne 'on') {
- print "Status: 302 Moved\r\n";
- print "Location: https://$ENV{'SERVER_ADDR'}:445/$ENV{'PATH_INFO'}\r\n\r\n";
- exit 0;
- } else {
- print "Pragma: no-cache\n";
- print "Cache-control: no-cache\n";
- print "Connection: close\n";
- print "Content-type: text/html\n\n";
- }
-}
-
-sub showjsmenu
-{
- my $c1 = 1;
-
- print " <script type='text/javascript'>\n";
- print " domMenu_data.setItem('domMenu_main', new domMenu_Hash(\n";
-
- foreach my $k1 ( sort keys %menu ) {
- my $c2 = 1;
- if ($c1 > 1) {
- print " ),\n";
- }
- print " $c1, new domMenu_Hash(\n";
- print "\t'contents', '" . &cleanhtml($menu{$k1}{'contents'}) . "',\n";
- print "\t'uri', '$menu{$k1}{'uri'}',\n";
- $menu{$k1}{'statusText'} =~ s/'/\\\'/g;
- print "\t'statusText', '$menu{$k1}{'statusText'}',\n";
- foreach my $k2 ( @{$menu{$k1}{'subMenu'}} ) {
- print "\t $c2, new domMenu_Hash(\n";
- print "\t\t'contents', '" . &cleanhtml(@{$k2}[0]) . "',\n";
- print "\t\t'uri', '@{$k2}[1]',\n";
- @{$k2}[2] =~ s/'/\\\'/g;
- print "\t\t'statusText', '@{$k2}[2]'\n";
- if ( $c2 <= $#{$menu{$k1}{'subMenu'}} ) {
- print "\t ),\n";
- } else {
- print "\t )\n";
- }
- $c2++;
- }
- $c1++;
- }
- print " )\n";
- print " ));\n\n";
-
- print <<EOF
- domMenu_settings.setItem('domMenu_main', new domMenu_Hash(
- 'menuBarWidth', '0%',
- 'menuBarClass', 'ipcop_menuBar',
- 'menuElementClass', 'ipcop_menuElement',
- 'menuElementHoverClass', 'ipcop_menuElementHover',
- 'menuElementActiveClass', 'ipcop_menuElementHover',
- 'subMenuBarClass', 'ipcop_subMenuBar',
- 'subMenuElementClass', 'ipcop_subMenuElement',
- 'subMenuElementHoverClass', 'ipcop_subMenuElementHover',
- 'subMenuElementActiveClass', 'ipcop_subMenuElementHover',
- 'subMenuMinWidth', 'auto',
- 'distributeSpace', false,
- 'openMouseoverMenuDelay', 0,
- 'openMousedownMenuDelay', 0,
- 'closeClickMenuDelay', 0,
- 'closeMouseoutMenuDelay', -1
- ));
- </script>
-EOF
- ;
-}
-
-sub showmenu
-{
- if ($javascript) {print "<noscript>";}
- print "<table cellpadding='0' cellspacing='0' border='0'>\n";
- print "<tr>\n";
-
- foreach my $k1 ( sort keys %menu ) {
- print "<td class='ipcop_menuElementTD'><a href='" . @{@{$menu{$k1}{'subMenu'}}[0]}[1] . "' class='ipcop_menuElementNoJS'>";
- print $menu{$k1}{'contents'} . "</a></td>\n";
- }
- print "</tr></table>\n";
- if ($javascript) {print "</noscript>";}
-}
-
-sub showsubsection
-{
- my $location = $_[0];
- my $c1 = 0;
-
- if ($javascript) {print "<noscript>";}
- print "<table width='100%' cellspacing='0' cellpadding='5' border='0'>\n";
- print "<tr><td style='background-color: $Header::boxcolour;' width='53'><img src='/images/null.gif' width='43' height='1' alt='' /></td>\n";
- print "<td style='background-color: $Header::boxcolour;' align='left' width='100%'>";
- my @URI=split ('\?', $ENV{'REQUEST_URI'} );
-
- foreach my $k1 ( keys %menu ) {
-
- if ($menu{$k1}{'contents'} eq $location) {
- foreach my $k2 ( @{$menu{$k1}{'subMenu'}} ) {
- if ($c1 > 0) {
- print " | ";
- }
- if (@{$k2}[1] eq "$URI[0]\?$URI[1]" || (@{$k2}[1] eq $URI[0] && length($URI[1]) == 0)) {
- #if (@{$k2}[1] eq "$URI[0]") {
- print "<b>@{$k2}[0]</b>";
- } else {
- print "<a href='@{$k2}[1]'>@{$k2}[0]</a>";
- }
- $c1++;
- }
- }
- }
- print "</td></tr></table>\n";
- if ($javascript) { print "</noscript>";}
-}
-
-sub openpage
-{
- my $title = $_[0];
- my $menu = $_[1];
- my $extrahead = $_[2];
-
- ### Initialize environment
- my %settings = ();
- &General::readhash("${General::swroot}/main/settings", \%settings);
-
- if ($settings{'JAVASCRIPT'} eq 'off') {
- $javascript = 0;
- } else {
- $javascript = 1;
- }
-
- if ($settings{'WINDOWWITHHOSTNAME'} eq 'on') {
- $hostnameintitle = 1;
- } else {
- $hostnameintitle = 0;
- }
-
- print <<END
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html><head>
-END
- ;
- print " <title>";
- if ($hostnameintitle) {
- print "$settings{'HOSTNAME'}.$settings{'DOMAINNAME'} - $title";
- } else {
- print "IPCop - $title";
- }
- print "</title>\n";
-
- print <<END
- $extrahead
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <link rel="shortcut icon" href="/favicon.ico" />
- <style type="text/css">\@import url(/include/ipcop.css);</style>
-END
- ;
- if ($javascript) {
- print "<script type='text/javascript' src='/include/domMenu.js'></script>\n";
- &genmenu();
- &showjsmenu();
- } else {
- &genmenu();
- }
-
- my $location = '';
- my $sublocation = '';
- my @URI=split ('\?', $ENV{'REQUEST_URI'} );
- foreach my $k1 ( keys %menu ) {
- my $temp = $menu{$k1}{'contents'};
- foreach my $k2 ( @{$menu{$k1}{'subMenu'}} ) {
- if ( @{$k2}[1] eq $URI[0] ) {
- $location = $temp;
- $sublocation = @{$k2}[0];
- }
- }
- }
-
- my @cgigraphs = split(/graph=/,$ENV{'QUERY_STRING'});
- if (defined ($cgigraphs[1])){
- if ($cgigraphs[1] =~ /(GREEN|BLUE|ORANGE|RED|network)/) {
- $location = $Lang::tr{'status'};
- $sublocation = $Lang::tr{'sstraffic graphs'};
- }
- if ($cgigraphs[1] =~ /(cpu|memory|swap|disk)/) {
- $location = $Lang::tr{'status'};
- $sublocation = $Lang::tr{'system graphs'};
- }
- }
- if ($ENV{'QUERY_STRING'} =~ /(ip)/) {
- $location = $Lang::tr{'alt logs'};
- $sublocation = "WHOIS";
- }
-
- if ($javascript) {
- print <<END
- <script type="text/javascript">
- document.onmouseup = function()
- {
- domMenu_deactivate('domMenu_main');
- }
- </script>
- </head>
-
- <body onload="domMenu_activate('domMenu_main');">
-END
- ;
- } else {
- print "</head>\n\n<body>\n";
- }
-
- print <<END
-<!-- IPCOP HEADER -->
- <table width='100%' cellpadding='0' cellspacing='0'>
- <col width='53' />
- <col />
- <tr><td><img src='/images/null.gif' width='53' height='27' alt='' /></td>
- <td valign='bottom'><table width='100%' cellspacing='0' border='0'>
- <col width='5' />
- <col width='175' />
- <col />
- <tr><td><img src='/images/null.gif' width='5' height='1' alt='' /></td>
- <td class="ipcop_menuLocationMain" valign='bottom'>$location</td>
- <td class="ipcop_menuLocationSub" valign='bottom'>$sublocation</td>
- </tr></table>
- </td></tr>
- <tr><td valign='bottom' class='ipcop_Version'>
- <img src='/images/null.gif' width='1' height='29' alt='' />${General::version}</td>
- <td valign='bottom'>
-END
- ;
- if ($menu == 1) {
- if ($javascript) {
- print "<div id='domMenu_main'></div>\n";
- }
- &showmenu();
- }
- print " </td></tr></table>\n";
- &showsubsection($location);
- print "<!-- IPCOP CONTENT -->\n";
-}
-
-sub closepage
-{
- print <<END
-<!-- IPCOP FOOTER -->
- <table width='100%' border='0'>
- <tr><td valign='bottom'><img src='/images/bounceback.png' width='248' height='80' alt='' /></td>
- <td align='center' valign='bottom'>
-END
- ;
- my $status = &connectionstatus();
- print "$status<br />\n";
- print `/usr/bin/uptime`;
-
- print <<END
- </td>
- <td valign='bottom'><a href='http://sf.net/projects/ipcop/' target='_blank'><img src='/images/sflogo.png' width='88' height='31' alt='Sourceforge logo' /></a></td>
- </tr></table>
-</body></html>
-END
- ;
-}
-
-sub openbigbox
-{
- my $width = $_[0];
- my $align = $_[1];
- my $sideimg = $_[2];
- my $errormessage = $_[3];
- my $bgcolor;
-
- if ($errormessage) {
- $bgcolor = "style='background-color: $Header::colourerr;'";
- } else {
- $bgcolor = '';
- }
-
- print "<table width='100%' border='0'>\n";
- if ($sideimg) {
- print "<tr><td valign='top'><img src='/images/$sideimg' width='65' height='345' alt='' /></td>\n";
- } else {
- print "<tr>\n";
- }
- print "<td valign='top' align='center'><table width='$width' $bgcolor cellspacing='0' cellpadding='10' border='0'>\n";
- print "<tr><td><img src='/images/null.gif' width='1' height='365' alt='' /></td>\n";
- print "<td align='$align' valign='top'>\n";
-}
-
-sub closebigbox
-{
- print "</td></tr></table></td></tr></table>\n"
-}
-
-sub openbox
-{
- my $width = $_[0];
- my $align = $_[1];
- my $caption = $_[2];
-
- print <<END
- <table cellspacing="0" cellpadding="0" width="$width" border="0">
- <col width='12' />
- <col width='18' />
- <col width='100%' />
- <col width='152' />
- <col width='11' />
-
- <tr><td width='12' ><img src='/images/null.gif' width='12' height='1' alt='' /></td>
- <td width='18' ><img src='/images/null.gif' width='18' height='1' alt='' /></td>
- <td width='100%'><img src='/images/null.gif' width='400' height='1' alt='' /></td>
- <td width='152' ><img src='/images/null.gif' width='152' height='1' alt='' /></td>
- <td width='11' ><img src='/images/null.gif' width='11' height='1' alt='' /></td></tr>
- <tr><td colspan='2' ><img src='/images/boxtop1.png' width='30' height='53' alt='' /></td>
- <td style='background: url(/images/boxtop2.png);'>
-END
- ;
- if ($caption) { print "<b>$caption</b>\n"; } else { print " "; }
- print <<END
- </td>
- <td colspan='2'><img src='/images/boxtop3.png' width='163' height='53' alt='' /></td></tr>
- <tr><td style='background: url(/images/boxleft.png);'><img src='/images/null.gif' width='12' height='1' alt='' /></td>
- <td colspan='3' style='background-color: $Header::boxcolour;'>
- <table width='100%' cellpadding='5'><tr><td align="$align" valign='top'>
-END
- ;
-}
-
-sub closebox
-{
- print <<END
- </td></tr></table></td>
- <td style='background: url(/images/boxright.png);'><img src='/images/null.gif' width='11' height='1' alt='' /></td></tr>
- <tr><td style='background: url(/images/boxbottom1.png);background-repeat:no-repeat;'><img src='/images/null.gif' width='12' height='14' alt='' /></td>
- <td style='background: url(/images/boxbottom2.png);background-repeat:repeat-x;' colspan='3'><img src='/images/null.gif' width='1' height='14' alt='' /></td>
- <td style='background: url(/images/boxbottom3.png);background-repeat:no-repeat;'><img src='/images/null.gif' width='11' height='14' alt='' /></td></tr>
- </table>
-END
- ;
-}
-
-sub getcgihash {
- my ($hash, $params) = @_;
- my $cgi = CGI->new ();
- return if ($ENV{'REQUEST_METHOD'} ne 'POST');
- if (!$params->{'wantfile'}) {
- $CGI::DISABLE_UPLOADS = 1;
- $CGI::POST_MAX = 512 * 1024;
- } else {
- $CGI::POST_MAX = 10 * 1024 * 1024;
- }
-
- $cgi->referer() =~ m/^https?\:\/\/([^\/]+)/;
- my $referer = $1;
- $cgi->url() =~ m/^https?\:\/\/([^\/]+)/;
- my $servername = $1;
- return if ($referer ne $servername);
-
- ### Modified for getting multi-vars, split by |
- my %temp = $cgi->Vars();
- foreach my $key (keys %temp) {
- $hash->{$key} = $temp{$key};
- $hash->{$key} =~ s/\0/|/g;
- $hash->{$key} =~ s/^\s*(.*?)\s*$/$1/;
- }
-
- if (($params->{'wantfile'})&&($params->{'filevar'})) {
- $hash->{$params->{'filevar'}} = $cgi->upload
- ($params->{'filevar'});
- }
- return;
-}
-
-sub cleanhtml
-{
- my $outstring =$_[0];
- $outstring =~ tr/,/ / if not defined $_[1] or $_[1] ne 'y';
- $outstring =~ s/&/&/g;
- $outstring =~ s/\'/'/g;
- $outstring =~ s/\"/"/g;
- $outstring =~ s/</</g;
- $outstring =~ s/>/>/g;
- return $outstring;
-}
-
-sub connectionstatus
-{
- my %pppsettings = ();
- my %netsettings = ();
- my $iface='';
-
- $pppsettings{'PROFILENAME'} = 'None';
- &General::readhash("${General::swroot}/ppp/settings", \%pppsettings);
- &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
-
- my $profileused='';
- if ( ! ( $netsettings{'CONFIG_TYPE'} =~ /^(2|3|6|7)$/ && $netsettings{'RED_TYPE'} =~ /^(DHCP|STATIC)$/ ) ) {
- $profileused="- $pppsettings{'PROFILENAME'}";
- }
-
- if ( ( $pppsettings{'METHOD'} eq 'DHCP' && $netsettings{'RED_TYPE'} ne 'PPTP')
- || $netsettings{'RED_TYPE'} eq 'DHCP' ) {
- if (open(IFACE, "${General::swroot}/red/iface")) {
- $iface = <IFACE>;
- close IFACE;
- chomp ($iface);
- $iface =~ /([a-zA-Z0-9]*)/; $iface = $1;
- }
- }
-
- my ($timestr, $connstate);
- if ($netsettings{'CONFIG_TYPE'} =~ /^(0|1|4|5)$/ && $pppsettings{'TYPE'} =~ /^isdn/) {
- # Count ISDN channels
- my ($idmap, $chmap, $drmap, $usage, $flags, $phone);
- my @phonenumbers;
- my $count=0;
-
- open (FILE, "/dev/isdninfo");
-
- $idmap = <FILE>; chop $idmap;
- $chmap = <FILE>; chop $chmap;
- $drmap = <FILE>; chop $drmap;
- $usage = <FILE>; chop $usage;
- $flags = <FILE>; chop $flags;
- $phone = <FILE>; chop $phone;
-
- $phone =~ s/^phone(\s*):(\s*)//;
-
- @phonenumbers = split / /, $phone;
-
- foreach (@phonenumbers) {
- if ($_ ne '???') {
- $count++;
- }
- }
- close (FILE);
-
- ## Connection status
- my $number;
- if ($count == 0) {
- $number = 'none!';
- } elsif ($count == 1) {
- $number = 'single';
- } else {
- $number = 'dual';
- }
-
- if (-e "${General::swroot}/red/active") {
- $timestr = &General::age("${General::swroot}/red/active");
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connected'} - $number channel (<span class='ipcop_StatusBigRed'>$timestr</span>) $profileused</span>";
- } else {
- if ($count == 0) {
- if (-e "${General::swroot}/red/dial-on-demand") {
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'dod waiting'} $profileused</span>";
- } else {
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'idle'} $profileused</span>";
- }
- } else {
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connecting'} $profileused</span>";
- }
- }
- } elsif ($netsettings{'RED_TYPE'} eq "STATIC" || $pppsettings {'METHOD'} eq 'STATIC') {
- if (-e "${General::swroot}/red/active") {
- $timestr = &General::age("${General::swroot}/red/active");
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connected'} (<span class='ipcop_StatusBigRed'>$timestr</span>) $profileused</span>";
- } else {
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'idle'} $profileused</span>";
- }
- } elsif ( ( (-e "${General::swroot}/dhcpc/dhcpcd-$iface.pid") && $netsettings{'RED_TYPE'} ne 'PPTP' ) ||
- !system("/bin/ps -ef | /bin/grep -q '[p]ppd'") || !system("/bin/ps -ef | /bin/grep -q '[c]onnectioncheck'")) {
- if (-e "${General::swroot}/red/active") {
- $timestr = &General::age("${General::swroot}/red/active");
- if ($pppsettings{'TYPE'} =~ /^(modem|bewanadsl|conexantpciadsl|eagleusbadsl)$/) {
- my $speed;
- if ($pppsettings{'TYPE'} eq 'modem') {
- open(CONNECTLOG, "/var/log/connect.log");
- while (<CONNECTLOG>) {
- if (/CONNECT/) {
- $speed = (split / /)[6];
- }
- }
- close (CONNECTLOG);
- } elsif ($pppsettings{'TYPE'} eq 'bewanadsl') {
- $speed = `/usr/bin/unicorn_status | /bin/grep Rate | /usr/bin/cut -f2 -d ':'`;
- } elsif ($pppsettings{'TYPE'} eq 'conexantpciadsl') {
- $speed = `/bin/cat /proc/net/atm/CnxAdsl:* | /bin/grep 'Line Rates' | /bin/sed -e 's+Line Rates: Receive+Rx+' -e 's+Transmit+Tx+'`;
- } elsif ($pppsettings{'TYPE'} eq 'eagleusbadsl') {
- $speed = `/usr/sbin/eaglestat | /bin/grep Rate`;
- }
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connected'} (<span class='ipcop_StatusBigRed'>$timestr</span>) $profileused (\@$speed)</span>";
- } else {
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connected'} (<span class='ipcop_StatusBigRed'>$timestr</span>) $profileused</span>";
- }
- } else {
- if (-e "${General::swroot}/red/dial-on-demand") {
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'dod waiting'} $profileused</span>";
- } else {
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connecting'} $profileused</span>";
- }
- }
- } else {
- $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'idle'} $profileused</span>";
- }
- return $connstate;
-}
-
-sub speedtouchversion
-{
- my $speedtouch;
- if (-f "/proc/bus/usb/devices")
- {
- $speedtouch=`/bin/cat /proc/bus/usb/devices | /bin/grep 'Vendor=06b9 ProdID=4061' | /usr/bin/cut -d ' ' -f6`;
- if ($speedtouch eq '') {
- $speedtouch= $Lang::tr{'connect the modem'};
- }
- } else {
- $speedtouch='USB '.$Lang::tr{'not running'};
- }
- return $speedtouch
-}
-
-#Sorting of allocated leases
-sub CheckSortOrder {
- my %dhcpsettings = ();
- &General::readhash("${General::swroot}/dhcp/settings", \%dhcpsettings);
-
- if ($ENV{'QUERY_STRING'} =~ /^IPADDR|^ETHER|^HOSTNAME|^ENDTIME/ ) {
- my $newsort=$ENV{'QUERY_STRING'};
- my $act=$dhcpsettings{'SORT_LEASELIST'};
- #Default sort if unspecified
- $act='IPADDRRev' if !defined ($act);
- #Reverse actual ?
- if ($act =~ $newsort) {
- my $Rev='';
- if ($act !~ 'Rev') {$Rev='Rev'};
- $newsort.=$Rev
- };
-
- $dhcpsettings{'SORT_LEASELIST'}=$newsort;
- &General::writehash("${General::swroot}/dhcp/settings", \%dhcpsettings);
- }
-}
-
-sub PrintActualLeases
-{
- our %dhcpsettings = ();
- our %entries = ();
-
- sub leasesort {
- my $qs ='';
- if (rindex ($dhcpsettings{'SORT_LEASELIST'},'Rev') != -1)
- {
- $qs=substr ($dhcpsettings{'SORT_LEASELIST'},0,length($dhcpsettings{'SORT_LEASELIST'})-3);
- if ($qs eq 'IPADDR') {
- my @a = split(/\./,$entries{$a}->{$qs});
- my @b = split(/\./,$entries{$b}->{$qs});
- ($b[0]<=>$a[0]) ||
- ($b[1]<=>$a[1]) ||
- ($b[2]<=>$a[2]) ||
- ($b[3]<=>$a[3]);
- }else {
- $entries{$b}->{$qs} cmp $entries{$a}->{$qs};
- }
- }
- else #not reverse
- {
- $qs=$dhcpsettings{'SORT_LEASELIST'};
- if ($qs eq 'IPADDR') {
- my @a = split(/\./,$entries{$a}->{$qs});
- my @b = split(/\./,$entries{$b}->{$qs});
- ($a[0]<=>$b[0]) ||
- ($a[1]<=>$b[1]) ||
- ($a[2]<=>$b[2]) ||
- ($a[3]<=>$b[3]);
- }else {
- $entries{$a}->{$qs} cmp $entries{$b}->{$qs};
- }
- }
- }
-
- &Header::openbox('100%', 'left', $Lang::tr{'current dynamic leases'});
- print <<END
-<table width='100%'>
-<tr>
-<td width='25%' align='center'><a href='$ENV{'SCRIPT_NAME'}?IPADDR'><b>$Lang::tr{'ip address'}</b></a></td>
-<td width='25%' align='center'><a href='$ENV{'SCRIPT_NAME'}?ETHER'><b>$Lang::tr{'mac address'}</b></a></td>
-<td width='20%' align='center'><a href='$ENV{'SCRIPT_NAME'}?HOSTNAME'><b>$Lang::tr{'hostname'}</b></a></td>
-<td width='30%' align='center'><a href='$ENV{'SCRIPT_NAME'}?ENDTIME'><b>$Lang::tr{'lease expires'} (local time d/m/y)</b></a></td>
-</tr>
-END
- ;
-
- my ($ip, $endtime, $ether, $hostname, @record, $record);
- open(LEASES,"/var/state/dhcp/dhcpd.leases") or die "Can't open dhcpd.leases";
- while (my $line = <LEASES>) {
- next if( $line =~ /^\s*#/ );
- chomp($line);
- my @temp = split (' ', $line);
-
- if ($line =~ /^\s*lease/) {
- $ip = $temp[1];
- #All field are not necessarily read. Clear everything
- $endtime = 0;
- $ether = "";
- $hostname = "";
- } elsif ($line =~ /^\s*ends never;/) {
- $endtime = 'never';
- } elsif ($line =~ /^\s*ends/) {
- $line =~ /(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/;
- $endtime = timegm($6, $5, $4, $3, $2 - 1, $1 - 1900);
- } elsif ($line =~ /^\s*hardware ethernet/) {
- $ether = $temp[2];
- $ether =~ s/;//g;
- } elsif ($line =~ /^\s*client-hostname/) {
- shift (@temp);
- $hostname = join (' ',@temp);
- $hostname =~ s/;//g;
- $hostname =~ s/\"//g;
- } elsif ($line eq "}") {
- @record = ('IPADDR',$ip,'ENDTIME',$endtime,'ETHER',$ether,'HOSTNAME',$hostname);
- $record = {}; # create a reference to empty hash
- %{$record} = @record; # populate that hash with @record
- $entries{$record->{'IPADDR'}} = $record; # add this to a hash of hashes
- } #unknown format line...
- }
- close(LEASES);
-
- #Get sort method
- $dhcpsettings{'SORT_LEASELIST'}='IPADDR'; #default
- &General::readhash("${General::swroot}/dhcp/settings", \%dhcpsettings); #or maybe saved !
- my $id = 0;
- foreach my $key (sort leasesort keys %entries) {
-
- my $hostname = &Header::cleanhtml($entries{$key}->{HOSTNAME},"y");
-
- if ($id % 2) {
- print "<tr bgcolor='$Header::table1colour'>";
- }
- else {
- print "<tr bgcolor='$Header::table2colour'>";
- }
-
- print <<END
-<td align='center'>$entries{$key}->{IPADDR}</td>
-<td align='center'>$entries{$key}->{ETHER}</td>
-<td align='center'> $hostname </td>
-<td align='center'>
-END
- ;
-
- if ($entries{$key}->{ENDTIME} eq 'never') {
- print "$Lang::tr{'no time limit'}";
- } else {
- my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst);
- ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime ($entries{$key}->{ENDTIME});
- my $enddate = sprintf ("%02d/%02d/%d %02d:%02d:%02d",$mday,$mon+1,$year+1900,$hour,$min,$sec);
-
- if ($entries{$key}->{ENDTIME} < time() ){
- print "<strike>$enddate</strike>";
- } else {
- print "$enddate";
- }
- }
- print "</td></tr>";
- $id++;
- }
-
- print "</table>";
- &Header::closebox();
-}
-
-1;
+# SmoothWall CGIs\r
+#\r
+# This code is distributed under the terms of the GPL\r
+#\r
+# (c) The SmoothWall Team\r
+# Copyright (C) 2002 Alex Hudson - getcgihash() rewrite\r
+# Copyright (C) 2002 Bob Grant <bob@cache.ucr.edu> - validmac()\r
+# Copyright (c) 2002/04/13 Steve Bootes - add alias section, helper functions\r
+# Copyright (c) 2002/08/23 Mark Wormgoor <mark@wormgoor.com> validfqdn()\r
+# Copyright (c) 2003/09/11 Darren Critchley <darrenc@telus.net> srtarray()\r
+#\r
+# $Id: header.pl,v 1.34.2.39 2004/11/26 15:51:27 alanh Exp $\r
+#\r
+package Header;\r
+\r
+use CGI();\r
+use Socket;\r
+use Time::Local;\r
+\r
+$|=1; # line buffering\r
+\r
+sub get_version() {\r
+ my $read_ver = `cat /etc/ipfire-release`;\r
+ if ($read_ver =~ /^$/) {\r
+ return "IPFire (unknown version)";\r
+ }\r
+ return $read_ver;\r
+}\r
+\r
+$Header::version = get_version();\r
+$Header::revision = 'final';\r
+$Header::swroot = '/var/ipfire';\r
+$Header::pagecolour = '#ffffff';\r
+#$Header::tablecolour = '#a0a0a0';\r
+$Header::tablecolour = '#FFFFFF';\r
+$Header::bigboxcolour = '#F6F4F4';\r
+$Header::boxcolour = '#EAE9EE';\r
+$Header::bordercolour = '#000000';\r
+$Header::table1colour = '#E0E0E0';\r
+$Header::table2colour = '#F0F0F0';\r
+$Header::colourred = '#993333';\r
+$Header::colourorange = '#FF9933';\r
+$Header::colouryellow = '#FFFF00';\r
+$Header::colourgreen = '#339933';\r
+$Header::colourblue = '#333399';\r
+$Header::colourfw = '#000000';\r
+$Header::colourvpn = '#990099';\r
+$Header::colourerr = '#FF0000';\r
+$Header::viewsize = 150;\r
+$Header::errormessage = '';\r
+my %menuhash = ();\r
+my $menu = \%menuhash;\r
+%settings = ();\r
+%ethsettings = ();\r
+@URI = ();\r
+$Header::supported=0;\r
+\r
+### Make sure this is an SSL request\r
+if ($ENV{'SERVER_ADDR'} && $ENV{'HTTPS'} ne 'on') {\r
+ print "Status: 302 Moved\r\n";\r
+ print "Location: https://$ENV{'SERVER_ADDR'}:10443/$ENV{'PATH_INFO'}\r\n\r\n";\r
+ exit 0;\r
+}\r
+\r
+### Initialize environment\r
+&readhash("${swroot}/main/settings", \%settings);\r
+&readhash("${swroot}/ethernet/settings", \%ethsettings);\r
+$language = $settings{'LANGUAGE'};\r
+$hostname = $settings{'HOSTNAME'};\r
+$hostnameintitle = 0;\r
+\r
+### Initialize language\r
+if ($language =~ /^(\w+)$/) {$language = $1;}\r
+\r
+### Read English Files\r
+if ( -d "/var/ipfire/langs/en/" ) {\r
+ opendir(DIR, "/var/ipfire/langs/en/");\r
+ @names = readdir(DIR) or die "Cannot Read Directory: $!\n";\r
+ foreach $name(@names) {\r
+ next if ($name eq ".");\r
+ next if ($name eq "..");\r
+ next if (!($name =~ /\.pl$/));\r
+ require "${swroot}/langs/en/${name}";\r
+ };\r
+};\r
+\r
+\r
+### Enable Language Files\r
+if ( -d "/var/ipfire/langs/${language}/" ) {\r
+ opendir(DIR, "/var/ipfire/langs/${language}/");\r
+ @names = readdir(DIR) or die "Cannot Read Directory: $!\n";\r
+ foreach $name(@names) {\r
+ next if ($name eq ".");\r
+ next if ($name eq "..");\r
+ next if (!($name =~ /\.pl$/));\r
+ require "${swroot}/langs/${language}/${name}";\r
+ };\r
+};\r
+\r
+\r
+require "${swroot}/langs/en.pl";\r
+require "${swroot}/langs/${language}.pl";\r
+\r
+sub orange_used () {\r
+ if ($ethsettings{'CONFIG_TYPE'} =~ /^[1357]$/) {\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+sub blue_used () {\r
+ if ($ethsettings{'CONFIG_TYPE'} =~ /^[4567]$/) {\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+sub is_modem {\r
+ if ($ethsettings{'CONFIG_TYPE'} =~ /^[0145]$/) {\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+### Initialize menu\r
+sub genmenu {\r
+ my %subsystemhash = ();\r
+ my $subsystem = \%subsystemhash;\r
+\r
+ $subsystem->{'01.home'} = {\r
+ 'caption' => $tr{'alt home'},\r
+ 'uri' => '/cgi-bin/index.cgi',\r
+ 'title' => "$tr{'alt home'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subsystem->{'02.netwizard'} = {\r
+ 'caption' => $tr{'network configuration'},\r
+ 'uri' => '/cgi-bin/netwizard.cgi',\r
+ 'title' => "$tr{'network configuration'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subsystem->{'03.updates'} = {\r
+ 'caption' => $tr{'updates'},\r
+ 'uri' => '/cgi-bin/updates.cgi',\r
+ 'title' => "$tr{'updates'}",\r
+ 'enabled' => 0,\r
+ };\r
+ $subsystem->{'04.passwords'} = {\r
+ 'caption' => $tr{'sspasswords'},\r
+ 'uri' => '/cgi-bin/changepw.cgi',\r
+ 'title' => "$tr{'sspasswords'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subsystem->{'05.ssh'} = {\r
+ 'caption' => $tr{'ssh access'},\r
+ 'uri' => '/cgi-bin/remote.cgi',\r
+ 'title' => "$tr{'ssh access'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subsystem->{'06.gui'} = {\r
+ 'caption' => $tr{'gui settings'},\r
+ 'uri' => '/cgi-bin/gui.cgi',\r
+ 'title' => "$tr{'gui settings'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subsystem->{'07.backup'} = {\r
+ 'caption' => $tr{'backup'},\r
+ 'uri' => '/cgi-bin/backup.cgi',\r
+ 'title' => "$tr{'backup'} / $tr{'restore'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subsystem->{'08.shutdown'} = {\r
+ 'caption' => $tr{'shutdown'},\r
+ 'uri' => '/cgi-bin/shutdown.cgi',\r
+ 'title' => "$tr{'shutdown'} / $tr{'reboot'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subsystem->{'09.credits'} = {\r
+ 'caption' => $tr{'credits'},\r
+ 'uri' => '/cgi-bin/credits.cgi',\r
+ 'title' => "$tr{'credits'}",\r
+ 'enabled' => 1,\r
+ };\r
+\r
+ my %substatushash = ();\r
+ my $substatus = \%substatushash;\r
+ $substatus->{'01.systemstatus'} = {\r
+ 'caption' => $tr{'sssystem status'},\r
+ 'uri' => '/cgi-bin/status.cgi',\r
+ 'title' => "$tr{'system status information'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $substatus->{'02.networkstatus'} = {\r
+ 'caption' => $tr{'ssnetwork status'},\r
+ 'uri' => '/cgi-bin/netstatus.cgi',\r
+ 'title' => "$tr{'network status information'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $substatus->{'03.systemgraphs'} = {\r
+ 'caption' => $tr{'system graphs'},\r
+ 'uri' => '/cgi-bin/graphs.cgi',\r
+ 'novars' => 1,\r
+ 'title' => "$tr{'system graphs'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $substatus->{'04.trafficgraphs'} = {\r
+ 'caption' => $tr{'sstraffic graphs'},\r
+ 'uri' => '/cgi-bin/graphs.cgi',\r
+ 'vars' => 'graph=network',\r
+ 'title' => "$tr{'network traffic graphs'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $substatus->{'05.proxygraphs'} = {\r
+ 'caption' => $tr{'ssproxy graphs'},\r
+ 'uri' => '/cgi-bin/proxygraphs.cgi',\r
+ 'title' => "$tr{'proxy access graphs'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $substatus->{'06.connections'} = {\r
+ 'caption' => $tr{'connections'},\r
+ 'uri' => '/cgi-bin/connections.cgi',\r
+ 'title' => "$tr{'connections'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $substatus->{'99.iptfilters'} = {\r
+ 'caption' => $tr{'iptfilters iptable rules'},\r
+ 'uri' => '/cgi-bin/iptfilters.cgi',\r
+ 'title' => "$tr{'iptfilters iptable rules'}",\r
+ 'enabled' => 1,\r
+ };\r
+\r
+ my %subnetworkhash = ();\r
+ my $subnetwork = \%subnetworkhash;\r
+\r
+ $subnetwork->{'01.dialup'} = {\r
+ 'caption' => $tr{'alt dialup'},\r
+ 'uri' => '/cgi-bin/pppsetup.cgi',\r
+ 'title' => "$tr{'dialup settings'}",\r
+ 'enabled' => 0,\r
+ };\r
+ $subnetwork->{'02.hosts'} = {\r
+ 'caption' => $tr{'edit hosts'},\r
+ 'uri' => '/cgi-bin/hosts.cgi',\r
+ 'title' => "$tr{'host configuration'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subnetwork->{'03.upload'} = {\r
+ 'caption' => $tr{'upload'},\r
+ 'uri' => '/cgi-bin/upload.cgi',\r
+ 'title' => "$tr{'firmware upload'}",\r
+ 'enabled' => 0,\r
+ };\r
+ $subnetwork->{'04.aliases'} = {\r
+ 'caption' => $tr{'aliases'},\r
+ 'uri' => '/cgi-bin/aliases.cgi',\r
+ 'title' => "$tr{'external aliases configuration'}",\r
+ 'enabled' => 1,\r
+ };\r
+\r
+\r
+ my %subserviceshash = ();\r
+ my $subservices = \%subserviceshash;\r
+\r
+ $subservices->{'01.dhcp'} = {\r
+ 'caption' => $tr{'dhcp server'},\r
+ 'uri' => '/cgi-bin/dhcp.cgi',\r
+ 'title' => "$tr{'dhcp configuration'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subservices->{'02.dyndns'} = {\r
+ 'caption' => $tr{'dynamic dns'},\r
+ 'uri' => '/cgi-bin/ddns.cgi',\r
+ 'title' => "$tr{'dynamic dns client'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subservices->{'03.time'} = {\r
+ 'caption' => $tr{'time server'},\r
+ 'uri' => '/cgi-bin/time.cgi',\r
+ 'title' => "$tr{'time server'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subservices->{'04.shaping'} = {\r
+ 'caption' => $tr{'traffic shaping'},\r
+ 'uri' => '/cgi-bin/shaping.cgi',\r
+ 'title' => "$tr{'traffic shaping settings'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subservices->{'05.ids'} = {'caption' => $tr{'intrusion detection'},\r
+ 'enabled' => 1,\r
+ 'uri' => '/cgi-bin/ids.cgi',\r
+ 'title' => "$tr{'intrusion detection system'} (Snort)",\r
+ };\r
+\r
+\r
+ my %subfirewallhash = ();\r
+ my $subfirewall = \%subfirewallhash;\r
+\r
+ \r
+ $subfirewall->{'01.dnat'} = {\r
+ 'caption' => $tr{'ssport forwarding'},\r
+ 'uri' => '/cgi-bin/portfw.cgi',\r
+ 'title' => "$tr{'port forwarding configuration'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subfirewall->{'02.xtaccess'} = {\r
+ 'caption' => $tr{'external access'},\r
+ 'uri' => '/cgi-bin/xtaccess.cgi',\r
+ 'title' => "$tr{'external access configuration'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subfirewall->{'03.dmz'} = {\r
+ 'caption' => $tr{'ssdmz pinholes'},\r
+ 'uri' => '/cgi-bin/dmzholes.cgi',\r
+ 'title' => "$tr{'dmz pinhole configuration'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subfirewall->{'04.outgoing'} = {\r
+ 'caption' => $tr{'outgoing firewall'},\r
+ 'uri' => '/cgi-bin/outgoingfw.cgi',\r
+ 'title' => "$tr{'outgoing firewall'}",\r
+ 'enabled' => 1,\r
+ };\r
+ \r
+\r
+\r
+ my %subhttphash = ();\r
+ my $subhttp = \%subhttphash;\r
+ $subhttp->{'01.proxy'} = {\r
+ 'caption' => $tr{'proxy'},\r
+ 'uri' => '/cgi-bin/advproxy.cgi',\r
+ 'title' => "HTTP: $tr{'web proxy configuration'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subhttp->{'02.contentfilter'} = {\r
+ 'caption' => $tr{'content filter'},\r
+ 'uri' => '/cgi-bin/dansguardian.cgi',\r
+ 'title' => "HTTP: $tr{'content filter'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subhttp->{'03.antivirus'} = {\r
+ 'caption' => $tr{'antivirus'},\r
+ 'uri' => '/cgi-bin/httpantivirus.cgi',\r
+ 'title' => "HTTP: $tr{'antivirus'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subhttp->{'04.proxymanagment'} = {\r
+ 'caption' => $tr{'DS Managment'},\r
+ 'uri' => '/cgi-bin/proxygm.cgi',\r
+ 'title' => "HTTP: $tr{'DS Managment'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subhttp->{'05.activatedgroups'} = {\r
+ 'caption' => $tr{'activated Groups'},\r
+ 'uri' => '/cgi-bin/proxyag.cgi',\r
+ 'title' => "HTTP: $tr{'activated Groups'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subhttp->{'06.advancedproxy'} = {\r
+ 'caption' => $tr{'Proxy Advanced'},\r
+ 'uri' => '/cgi-bin/proxyad.cgi',\r
+ 'title' => "HTTP: $tr{'Proxy Advanced'}",\r
+ 'enabled' => 1,\r
+ };\r
+\r
+\r
+ my %subproxyhash = ();\r
+ my $subproxy = \%subproxyhash;\r
+\r
+ $subproxy->{'01.http'} = {'caption' => $tr{'HTTP'},\r
+ 'enabled' => 1,\r
+ 'subMenu' => $subhttp\r
+ };\r
+ $subproxy->{'02.ftp'} = {'caption' => 'FTP',\r
+ 'enabled' => 1,\r
+ 'subMenu' => $subftp\r
+ };\r
+\r
+\r
+\r
+ my %subopenvpnhash = ();\r
+ my $subopenvpn = \%subopenvpnhash;\r
+ $subopenvpn->{'01.server'} = {'caption' => $tr{'openvpn'},\r
+ 'uri' => '/cgi-bin/openvpn.cgi',\r
+ 'title' => "$tr{'virtual private networking'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $subopenvpn->{'02.client'} = {'caption' => $tr{'openvpnclient'},\r
+ 'uri' => '/cgi-bin/openvpnclient.cgi',\r
+ 'title' => "$tr{'virtual private networking'}",\r
+ 'enabled' => 1,\r
+ };\r
+\r
+ my %subvpnhash = ();\r
+ my $subvpn = \%subvpnhash;\r
+\r
+ $subvpn->{'01.openvpn'} = {'caption' => $tr{'openvpn'},\r
+ 'subMenu' => $subopenvpn,\r
+ 'enabled' => 1,\r
+ };\r
+ $subvpn->{'02.ipsec'} = {'caption' => $tr{'ipsec'},\r
+ 'uri' => '/cgi-bin/vpnmain.cgi',\r
+ 'title' => "$tr{'virtual private networking'}",\r
+ 'enabled' => 1,\r
+ };\r
+\r
+ my %sublogshash = ();\r
+ my $sublogs = \%sublogshash;\r
+\r
+ $sublogs->{'01.summary'} = {'caption' => $tr{'log summary'},\r
+ 'uri' => '/cgi-bin/logs.cgi/summary.dat',\r
+ 'title' => "$tr{'log summary'}",\r
+ 'enabled' => 1\r
+ };\r
+ $sublogs->{'02.settings'} = {'caption' => $tr{'log settings'},\r
+ 'uri' => '/cgi-bin/logs.cgi/config.dat',\r
+ 'title' => "$tr{'log settings'}",\r
+ 'enabled' => 1\r
+ };\r
+ $sublogs->{'03.proxy'} = {'caption' => $tr{'proxy logs'},\r
+ 'uri' => '/cgi-bin/logs.cgi/proxylog.dat',\r
+ 'title' => "$tr{'proxy log viewer'}",\r
+ 'enabled' => 1\r
+ };\r
+ $sublogs->{'04.firewall'} = {'caption' => $tr{'firewall logs'},\r
+ 'uri' => '/cgi-bin/logs.cgi/firewalllog.dat',\r
+ 'title' => "$tr{'firewall log viewer'}",\r
+ 'enabled' => 1\r
+ };\r
+ $sublogs->{'05.ids'} = {'caption' => $tr{'ids logs'},\r
+ 'uri' => '/cgi-bin/logs.cgi/ids.dat',\r
+ 'title' => "$tr{'intrusion detection system log viewer'}",\r
+ 'enabled' => 1\r
+ };\r
+ $sublogs->{'06.contentfilter'} = {'caption' => $tr{'content filter logs'},\r
+ 'uri' => '/cgi-bin/logs.cgi/dansguardian.dat',\r
+ 'title' => "$tr{'content filter log viewer'}",\r
+ 'enabled' => 1\r
+ };\r
+ $sublogs->{'07.urlfilter'} = {\r
+ 'caption' => $tr{'urlfilter log'},\r
+ 'uri' => '/cgi-bin/logs.cgi/urlfilter.dat',\r
+ 'title' => "$tr{'urlfilter log'}",\r
+ 'enabled' => 1,\r
+ };\r
+ $sublogs->{'08.openvpn'} = {'caption' => $tr{'openvpn log'},\r
+ 'uri' => '/cgi-bin/logs.cgi/openvpn.dat',\r
+ 'title' => "$tr{'openvpn log'}",\r
+ 'enabled' => 1\r
+ };\r
+ $sublogs->{'09.system'} = {'caption' => $tr{'system logs'},\r
+ 'uri' => '/cgi-bin/logs.cgi/log.dat',\r
+ 'title' => "$tr{'system log viewer'}",\r
+ 'enabled' => 1\r
+ };\r
+ $sublogs->{'10.userlog'} = {'caption' => $tr{'user proxy logs'},\r
+ 'uri' => '/cgi-bin/logs.cgi/userlog.dat',\r
+ 'title' => "$tr{'user log viewer'}",\r
+ 'enabled' => 1\r
+ };\r
+\r
+\r
+ $menu->{'01.system'} = {'caption' => $tr{'alt system'},\r
+ 'enabled' => 1,\r
+ 'subMenu' => $subsystem\r
+ };\r
+ $menu->{'02.status'} = {'caption' => $tr{'status'},\r
+ 'enabled' => 1,\r
+ 'subMenu' => $substatus\r
+ };\r
+ $menu->{'03.network'} = {'caption' => $tr{'network'},\r
+ 'enabled' => 1,\r
+ 'subMenu' => $subnetwork\r
+ };\r
+ $menu->{'04.services'} = {'caption' => $tr{'alt services'},\r
+ 'enabled' => 1,\r
+ 'subMenu' => $subservices\r
+ };\r
+ $menu->{'05.firewall'} = {'caption' => $tr{'firewall'},\r
+ 'enabled' => 1,\r
+ 'subMenu' => $subfirewall\r
+ };\r
+ $menu->{'06.proxy'} = {'caption' => $tr{'alt proxy'},\r
+ 'enabled' => 1,\r
+ 'subMenu' => $subproxy\r
+ };\r
+ $menu->{'07.vpn'} = {'caption' => 'VPN',\r
+ 'enabled' => 1,\r
+ 'subMenu' => $subvpn\r
+ };\r
+ $menu->{'08.logs'} = {'caption' => $tr{'alt logs'},\r
+ 'enabled' => 1,\r
+ 'subMenu' => $sublogs\r
+ };\r
+\r
+\r
+\r
+ if (! blue_used() && ! orange_used()) {\r
+ $menu->{'05.firewall'}{'subMenu'}->{'03.dmz'}{'enabled'} = 0;\r
+ }\r
+ if (-e '/etc/FLASH') {\r
+ $menu{'06.proxy'}{'subMenu'}->{'01.http'}{'subMenu'}->{'01.proxy'}{'enabled'} = 0; #disable squid\r
+ $menu{'04.services'}{'subMenu'}->{'05.ids'}{'enabled'} = 0; #disable ids\r
+ $menu{'08.logs'}{'subMenu'}->{'05.ids'}{'enabled'} = 0; #disable ids\r
+ }\r
+}\r
+\r
+sub showhttpheaders\r
+{\r
+ print "Pragma: no-cache\n";\r
+ print "Cache-control: no-cache\n";\r
+ print "Connection: close\n";\r
+ print "Content-type: text/html\n\n";\r
+}\r
+\r
+sub is_menu_visible($) {\r
+ my $link = shift;\r
+ $link =~ s#\?.*$##;\r
+ return (-e $ENV{'DOCUMENT_ROOT'}."/../$link");\r
+}\r
+\r
+\r
+sub getlink($) {\r
+ my $root = shift;\r
+ if (! $root->{'enabled'}) {\r
+ return '';\r
+ }\r
+ if ($root->{'uri'} !~ /^$/) {\r
+ my $vars = '';\r
+ if ($root->{'vars'} !~ /^$/) {\r
+ $vars = '?'. $root->{'vars'};\r
+ }\r
+ if (! is_menu_visible($root->{'uri'})) {\r
+ return '';\r
+ }\r
+ return $root->{'uri'}.$vars;\r
+ }\r
+ my $submenus = $root->{'subMenu'};\r
+ if (! $submenus) {\r
+ return '';\r
+ }\r
+ foreach my $item (sort keys %$submenus) {\r
+ my $link = getlink($submenus->{$item});\r
+ if ($link ne '') {\r
+ return $link;\r
+ }\r
+ }\r
+ return '';\r
+}\r
+\r
+\r
+sub compare_url($) {\r
+ my $conf = shift;\r
+\r
+ my $uri = $conf->{'uri'};\r
+ my $vars = $conf->{'vars'};\r
+ my $novars = $conf->{'novars'};\r
+\r
+ if ($uri eq '') {\r
+ return 0;\r
+ }\r
+ if ($uri ne $URI[0]) {\r
+ return 0;\r
+ }\r
+ if ($novars) {\r
+ if ($URI[1] !~ /^$/) {\r
+ return 0;\r
+ }\r
+ }\r
+ if (! $vars) {\r
+ return 1;\r
+ }\r
+ return ($URI[1] eq $vars);\r
+}\r
+\r
+\r
+sub gettitle($) {\r
+ my $root = shift;\r
+\r
+ if (! $root) {\r
+ return '';\r
+ }\r
+ foreach my $item (sort keys %$root) {\r
+ my $val = $root->{$item};\r
+ if (compare_url($val)) {\r
+ $val->{'selected'} = 1;\r
+ if ($val->{'title'} !~ /^$/) {\r
+ return $val->{'title'};\r
+ }\r
+ return 'EMPTY TITLE';\r
+ }\r
+\r
+ my $title = gettitle($val->{'subMenu'});\r
+ if ($title ne '') {\r
+ $val->{'selected'} = 1;\r
+ return $title;\r
+ }\r
+ }\r
+ return '';\r
+}\r
+\r
+\r
+sub showmenu() {\r
+ print <<EOF\r
+ <div id="menu-top">\r
+ <ul>\r
+EOF\r
+;\r
+ foreach my $k1 ( sort keys %$menu ) {\r
+ if (! $menu->{$k1}{'enabled'}) {\r
+ next;\r
+ }\r
+\r
+ my $link = getlink($menu->{$k1});\r
+ if ($link eq '') {\r
+ next;\r
+ }\r
+ if (! is_menu_visible($link)) {\r
+ next;\r
+ }\r
+ if ($menu->{$k1}->{'selected'}) {\r
+ print '<li class="selected">';\r
+ } else {\r
+ print '<li>';\r
+ }\r
+\r
+ print <<EOF\r
+ <div class="rcorner">\r
+ <a href="$link">$menu->{$k1}{'caption'}</a>\r
+ </div>\r
+ </li>\r
+EOF\r
+;\r
+ }\r
+\r
+ print <<EOF\r
+ </ul>\r
+ </div>\r
+EOF\r
+; \r
+}\r
+\r
+sub getselected($) {\r
+ my $root = shift;\r
+ if (!$root) {\r
+ return 0;\r
+ }\r
+\r
+ foreach my $item (%$root) {\r
+ if ($root->{$item}{'selected'}) {\r
+ return $root->{$item};\r
+ }\r
+ }\r
+}\r
+\r
+sub showsubsection($$) {\r
+ my $root = shift;\r
+ my $id = shift;\r
+ if ($id eq '') {\r
+ $id = 'menu-left';\r
+ }\r
+\r
+ if (! $root) {\r
+ return;\r
+ }\r
+ my $selected = getselected($root);\r
+ if (! $selected) {\r
+ return;\r
+ }\r
+ my $submenus = $selected->{'subMenu'};\r
+ if (! $submenus) {\r
+ return;\r
+ }\r
+\r
+ print <<EOF\r
+ <div id="$id">\r
+ <ul>\r
+EOF\r
+;\r
+ foreach my $item (sort keys %$submenus) {\r
+ my $hash = $submenus->{$item};\r
+ if (! $hash->{'enabled'}) {\r
+ next;\r
+ }\r
+\r
+ my $link = getlink($hash);\r
+ if ($link eq '') {\r
+ next;\r
+ }\r
+ if (! is_menu_visible($link)) {\r
+ next;\r
+ }\r
+ if ($hash->{'selected'}) {\r
+ print '<li class="selected">';\r
+ } else {\r
+ print '<li>';\r
+ }\r
+\r
+ print <<EOF\r
+ <a href="$link">$hash->{'caption'}</a>\r
+ </li>\r
+EOF\r
+;\r
+ }\r
+\r
+ print <<EOF\r
+ </ul>\r
+ </div>\r
+EOF\r
+; \r
+\r
+}\r
+\r
+\r
+sub showsubsubsection($) {\r
+ my $root = shift;\r
+ if (!$root) {\r
+ return;\r
+ }\r
+ my $selected = getselected($root);\r
+ if (! $selected) {\r
+ return\r
+ }\r
+ if (! $selected->{'subMenu'}) {\r
+ return\r
+ }\r
+\r
+ showsubsection($selected->{'subMenu'}, 'menu-subtop');\r
+}\r
+\r
+\r
+sub get_helpuri() {\r
+ my $helpfile = '';\r
+ if ($URI[0] =~ /.*\/([^\/]+)\.cgi/) {\r
+ $helpfile = $1;\r
+ } else {\r
+ return '';\r
+ }\r
+ $helpfile .= '.help.html';\r
+\r
+ my $helpuri = '/doc/'.$language.'/'.$helpfile;\r
+ if (! -e $ENV{'DOCUMENT_ROOT'}.$helpuri) {\r
+ return '';\r
+ }\r
+ return $helpuri;\r
+}\r
+\r
+\r
+sub openpage {\r
+ my $title = shift;\r
+ my $boh = shift;\r
+ my $extrahead = shift;\r
+\r
+ @URI=split ('\?', $ENV{'REQUEST_URI'} );\r
+ &readhash("${swroot}/main/settings", \%settings);\r
+ &genmenu();\r
+\r
+ my $h2 = gettitle($menu);\r
+ my $helpuri = get_helpuri();\r
+\r
+ $title = "IPFire - $title";\r
+ if ($settings{'WINDOWWITHHOSTNAME'} eq 'on') {\r
+ $title = "$settings{'HOSTNAME'}.$settings{'DOMAINNAME'} - $title"; \r
+ }\r
+\r
+ print <<END\r
+<!DOCTYPE html \r
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\r
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
+\r
+<html>\r
+ <head>\r
+ <title>$title</title>\r
+\r
+ $extrahead\r
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>\r
+ <link rel="shortcut icon" href="/favicon.ico" />\r
+ <style type="text/css">\@import url(/include/style.css);</style>\r
+ <style type="text/css">\@import url(/include/menu.css);</style>\r
+ <style type="text/css">\@import url(/include/content.css);</style>\r
+\r
+ <script language="javascript" type="text/javascript">\r
+ \r
+ function swapVisibility(id) {\r
+ el = document.getElementById(id);\r
+ if(el.style.display != 'block') {\r
+ el.style.display = 'block'\r
+ }\r
+ else {\r
+ el.style.display = 'none'\r
+ }\r
+ }\r
+ </script>\r
+\r
+ </head>\r
+ <body>\r
+<!-- IPFIRE HEADER -->\r
+\r
+<div id="main">\r
+\r
+<div id="header">\r
+ <img id="logo-product" src="/images/logo_ipfire.gif">\r
+ <img id="logo-ipfire" src="/images/logo_ipfire2.gif"> \r
+ <div id="header-icons">\r
+END\r
+;\r
+\r
+ if ($helpuri ne '') {\r
+ print <<END\r
+ <a href="$helpuri" target="_blank"><img border="0" src="/images/help.gif"></a>\r
+END\r
+;\r
+ } else {\r
+ print '<img src="/images/help.gif">';\r
+ }\r
+\r
+print <<END\r
+ </div>\r
+</div>\r
+\r
+END\r
+;\r
+\r
+ &showmenu();\r
+\r
+print <<END\r
+<div id="content">\r
+ <table width="90%">\r
+ <tr>\r
+ <td valign="top">\r
+END\r
+;\r
+ \r
+ &showsubsection($menu);\r
+\r
+ print <<END\r
+\r
+ </td>\r
+ <td width="100%" valign="top">\r
+ <div id="page-content">\r
+ <h2>$h2</h2>\r
+END\r
+ ;\r
+ \r
+ &showsubsubsection($menu);\r
+\r
+ eval {\r
+ require 'ipfire-network.pl';\r
+ $supported = check_support();\r
+ warn_unsupported($supported);\r
+ };\r
+}\r
+\r
+sub closepage () {\r
+ my $status = &connectionstatus();\r
+ $uptime = `/usr/bin/uptime`;\r
+ \r
+ print <<END\r
+ <div align="center">\r
+ <p>\r
+ <div style="font-size: 9px"><b>Status:</b> $status <b>Uptime:</b>$uptime</div>\r
+ </p>\r
+ <p><a href="http://www.ipfire.org">IPFire</a> $version (c)</p>\r
+ </div>\r
+ </body>\r
+ <meta http-equiv="Page-Enter" content="blendTrans(Duration=1.0,Transition=12)">\r
+ <meta http-equiv="Page-Exit" content="blendTrans(Duration=1.0,Transition=12)">\r
+</html>\r
+END\r
+;\r
+}\r
+\r
+sub openbigbox\r
+{\r
+ my $width = $_[0];\r
+ my $align = $_[1];\r
+ my $sideimg = $_[2];\r
+\r
+ if ($errormessage) {\r
+ $bgcolor = "style='background-color: $colourerr;'";\r
+ } else {\r
+ $bgcolor = '';\r
+ }\r
+}\r
+\r
+sub closebigbox\r
+{\r
+# print "</td></tr></table></td></tr></table>\n" \r
+}\r
+\r
+sub openbox\r
+{\r
+ $width = $_[0];\r
+ $align = $_[1];\r
+ $caption = $_[2];\r
+\r
+ if ($caption) { print "<h3>$caption</h3>\n"; } else { print " "; }\r
+ \r
+ print "<table class=\"list\"><tr><td align=\"$align\">\n";\r
+}\r
+\r
+sub closebox\r
+{\r
+ print "</td></tr></table><br><br>";\r
+}\r
+\r
+sub writehash\r
+{\r
+ my $filename = $_[0];\r
+ my $hash = $_[1];\r
+ \r
+ # write cgi vars to the file.\r
+ open(FILE, ">${filename}") or die "Unable to write file $filename";\r
+ flock FILE, 2;\r
+ foreach $var (keys %$hash) \r
+ {\r
+ $val = $hash->{$var};\r
+ # Darren Critchley Jan 17, 2003 added the following because when submitting with a graphic, the x and y\r
+ # location of the mouse are submitted as well, this was being written to the settings file causing\r
+ # some serious grief! This skips the variable.x and variable.y\r
+ if (!($var =~ /(.x|.y)$/)) {\r
+ if ($val =~ / /) {\r
+ $val = "\'$val\'"; }\r
+ if (!($var =~ /^ACTION/)) {\r
+ print FILE "${var}=${val}\n"; }\r
+ }\r
+ }\r
+ close FILE;\r
+}\r
+\r
+sub readhash\r
+{\r
+ my $filename = $_[0];\r
+ my $hash = $_[1];\r
+ my ($var, $val);\r
+\r
+ open(FILE, $filename) or die "Unable to read file $filename";\r
+ \r
+ while (<FILE>)\r
+ {\r
+ chop;\r
+ ($var, $val) = split /=/, $_, 2;\r
+ if ($var)\r
+ {\r
+ $val =~ s/^\'//g;\r
+ $val =~ s/\'$//g;\r
+\r
+ # Untaint variables read from hash\r
+ $var =~ /([A-Za-z0-9_-]*)/; $var = $1;\r
+ $val =~ /([\w\W]*)/; $val = $1;\r
+ $hash->{$var} = $val;\r
+ }\r
+ }\r
+ close FILE;\r
+}\r
+\r
+sub getcgihash {\r
+ my ($hash, $params) = @_;\r
+ my $cgi = CGI->new ();\r
+ $hash->{'__CGI__'} = $cgi;\r
+ return if ($ENV{'REQUEST_METHOD'} ne 'POST');\r
+ if (!$params->{'wantfile'}) {\r
+ $CGI::DISABLE_UPLOADS = 1;\r
+ $CGI::POST_MAX = 512 * 1024;\r
+ } else {\r
+ $CGI::POST_MAX = 10 * 1024 * 1024;\r
+ }\r
+\r
+ $cgi->referer() =~ m/^https?\:\/\/([^\/]+)/;\r
+ my $referer = $1;\r
+ $cgi->url() =~ m/^https?\:\/\/([^\/]+)/;\r
+ my $servername = $1;\r
+ return if ($referer ne $servername);\r
+\r
+ ### Modified for getting multi-vars, split by |\r
+ %temp = $cgi->Vars();\r
+ foreach my $key (keys %temp) {\r
+ $hash->{$key} = $temp{$key};\r
+ $hash->{$key} =~ s/\0/|/g;\r
+ $hash->{$key} =~ s/^\s*(.*?)\s*$/$1/;\r
+ }\r
+\r
+ if (($params->{'wantfile'})&&($params->{'filevar'})) {\r
+ $hash->{$params->{'filevar'}} = $cgi->upload\r
+ ($params->{'filevar'});\r
+ }\r
+ return;\r
+}\r
+\r
+sub log\r
+{\r
+ my $logmessage = $_[0];\r
+ $logmessage =~ /([\w\W]*)/;\r
+ $logmessage = $1;\r
+ system('/usr/bin/logger', '-t', 'ipfire', $logmessage);\r
+}\r
+\r
+sub age\r
+{\r
+ my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,\r
+ $atime, $mtime, $ctime, $blksize, $blocks) = stat $_[0];\r
+ my $now = time;\r
+\r
+ my $totalsecs = $now - $mtime;\r
+ my $days = int($totalsecs / 86400);\r
+ my $totalhours = int($totalsecs / 3600);\r
+ my $hours = $totalhours % 24;\r
+ my $totalmins = int($totalsecs / 60);\r
+ my $mins = $totalmins % 60;\r
+ my $secs = $totalsecs % 60;\r
+\r
+ return "${days}d ${hours}h ${mins}m ${secs}s";\r
+}\r
+\r
+sub validip\r
+{\r
+ my $ip = $_[0];\r
+\r
+ if (!($ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)) {\r
+ return 0; }\r
+ else \r
+ {\r
+ @octets = ($1, $2, $3, $4);\r
+ foreach $_ (@octets)\r
+ {\r
+ if (/^0./) {\r
+ return 0; }\r
+ if ($_ < 0 || $_ > 255) {\r
+ return 0; }\r
+ }\r
+ return 1;\r
+ }\r
+}\r
+\r
+sub validmask\r
+{\r
+ my $mask = $_[0];\r
+\r
+ # secord part an ip?\r
+ if (&validip($mask)) {\r
+ return 1; }\r
+ # second part a number?\r
+ if (/^0/) {\r
+ return 0; }\r
+ if (!($mask =~ /^\d+$/)) {\r
+ return 0; }\r
+ if ($mask >= 0 && $mask <= 32) {\r
+ return 1; }\r
+ return 0;\r
+}\r
+\r
+sub validipormask\r
+{\r
+ my $ipormask = $_[0];\r
+\r
+ # see if it is a IP only.\r
+ if (&validip($ipormask)) {\r
+ return 1; }\r
+ # split it into number and mask.\r
+ if (!($ipormask =~ /^(.*?)\/(.*?)$/)) {\r
+ return 0; }\r
+ $ip = $1;\r
+ $mask = $2;\r
+ # first part not a ip?\r
+ if (!(&validip($ip))) {\r
+ return 0; }\r
+ return &validmask($mask);\r
+}\r
+\r
+sub validipandmask\r
+{\r
+ my $ipandmask = $_[0];\r
+\r
+ # split it into number and mask.\r
+ if (!($ipandmask =~ /^(.*?)\/(.*?)$/)) {\r
+ return 0; }\r
+ $ip = $1;\r
+ $mask = $2;\r
+ # first part not a ip?\r
+ if (!(&validip($ip))) {\r
+ return 0; }\r
+ return &validmask($mask);\r
+}\r
+\r
+sub validport\r
+{\r
+ $_ = $_[0];\r
+\r
+ if (!/^\d+$/) {\r
+ return 0; }\r
+ if (/^0./) {\r
+ return 0; }\r
+ if ($_ >= 1 && $_ <= 65535) {\r
+ return 1; }\r
+ return 0;\r
+}\r
+\r
+sub validmac\r
+{\r
+ my $checkmac = $_[0];\r
+ my $ot = '[0-9a-f]{2}'; # 2 Hex digits (one octet)\r
+ if ($checkmac !~ /^$ot:$ot:$ot:$ot:$ot:$ot$/i)\r
+ {\r
+ return 0;\r
+ }\r
+ return 1;\r
+}\r
+\r
+sub validhostname\r
+{\r
+ # Checks a hostname against RFC1035\r
+ my $hostname = $_[0];\r
+\r
+ # Each part should be at least two characters in length\r
+ # but no more than 63 characters\r
+ if (length ($hostname) < 2 || length ($hostname) > 63) {\r
+ return 0;}\r
+ # Only valid characters are a-z, A-Z, 0-9 and -\r
+ if ($hostname !~ /^[a-zA-Z0-9-]*$/) {\r
+ return 0;}\r
+ # First character can only be a letter or a digit\r
+ if (substr ($hostname, 0, 1) !~ /^[a-zA-Z0-9]*$/) {\r
+ return 0;}\r
+ # Last character can only be a letter or a digit\r
+ if (substr ($hostname, -1, 1) !~ /^[a-zA-Z0-9]*$/) {\r
+ return 0;}\r
+ return 1;\r
+}\r
+\r
+sub validdomainname\r
+{\r
+ # Checks a domain name against RFC1035\r
+ my $domainname = $_[0];\r
+ my @parts = split (/\./, $domainname); # Split hostname at the '.'\r
+\r
+ foreach $part (@parts) {\r
+ # Each part should be at least two characters in length\r
+ # but no more than 63 characters\r
+ if (length ($part) < 2 || length ($part) > 63) {\r
+ return 0;}\r
+ # Only valid characters are a-z, A-Z, 0-9 and -\r
+ if ($part !~ /^[a-zA-Z0-9-]*$/) {\r
+ return 0;}\r
+ # First character can only be a letter or a digit\r
+ if (substr ($part, 0, 1) !~ /^[a-zA-Z0-9]*$/) {\r
+ return 0;}\r
+ # Last character can only be a letter or a digit\r
+ if (substr ($part, -1, 1) !~ /^[a-zA-Z0-9]*$/) {\r
+ return 0;}\r
+ }\r
+ return 1;\r
+}\r
+\r
+sub validfqdn\r
+{\r
+ # Checks a fully qualified domain name against RFC1035\r
+ my $fqdn = $_[0];\r
+ my @parts = split (/\./, $fqdn); # Split hostname at the '.'\r
+ if (scalar(@parts) < 2) { # At least two parts should\r
+ return 0;} # exist in a FQDN\r
+ # (i.e. hostname.domain)\r
+ foreach $part (@parts) {\r
+ # Each part should be at least two characters in length\r
+ # but no more than 63 characters\r
+ if (length ($part) < 2 || length ($part) > 63) {\r
+ return 0;}\r
+ # Only valid characters are a-z, A-Z, 0-9 and -\r
+ if ($part !~ /^[a-zA-Z0-9-]*$/) {\r
+ return 0;}\r
+ # First character can only be a letter or a digit\r
+ if (substr ($part, 0, 1) !~ /^[a-zA-Z0-9]*$/) {\r
+ return 0;}\r
+ # Last character can only be a letter or a digit\r
+ if (substr ($part, -1, 1) !~ /^[a-zA-Z0-9]*$/) {\r
+ return 0;}\r
+ }\r
+ return 1;\r
+}\r
+\r
+sub validportrange # used to check a port range \r
+{\r
+ my $port = $_[0]; # port values\r
+ $port =~ tr/-/:/; # replace all - with colons just in case someone used -\r
+ my $srcdst = $_[1]; # is it a source or destination port\r
+\r
+ if (!($port =~ /^(\d+)\:(\d+)$/)) {\r
+ \r
+ if (!(&validport($port))) { \r
+ if ($srcdst eq 'src'){\r
+ return $tr{'source port numbers'};\r
+ } else {\r
+ return $tr{'destination port numbers'};\r
+ } \r
+ }\r
+ }\r
+ else \r
+ {\r
+ @ports = ($1, $2);\r
+ if ($1 >= $2){\r
+ if ($srcdst eq 'src'){\r
+ return $tr{'bad source range'};\r
+ } else {\r
+ return $tr{'bad destination range'};\r
+ } \r
+ }\r
+ foreach $_ (@ports)\r
+ {\r
+ if (!(&validport($_))) {\r
+ if ($srcdst eq 'src'){\r
+ return $tr{'source port numbers'}; \r
+ } else {\r
+ return $tr{'destination port numbers'};\r
+ } \r
+ }\r
+ }\r
+ return;\r
+ }\r
+}\r
+\r
+# Test if IP is within a subnet\r
+# Call: IpInSubnet (Addr, Subnet, Subnet Mask)\r
+# Subnet can be an IP of the subnet: 10.0.0.0 or 10.0.0.1\r
+# Everything in dottted notation\r
+# Return: TRUE/FALSE\r
+sub IpInSubnet\r
+{\r
+ $ip = unpack('N', inet_aton(shift));\r
+ $start = unpack('N', inet_aton(shift));\r
+ $mask = unpack('N', inet_aton(shift));\r
+ $start &= $mask; # base of subnet...\r
+ $end = $start + ~$mask;\r
+ return (($ip >= $start) && ($ip <= $end));\r
+}\r
+\r
+sub validemail {\r
+ my $mail = shift;\r
+ return 0 if ( $mail !~ /^[0-9a-zA-Z\.\-\_]+\@[0-9a-zA-Z\.\-]+$/ );\r
+ return 0 if ( $mail =~ /^[^0-9a-zA-Z]|[^0-9a-zA-Z]$/);\r
+ return 0 if ( $mail !~ /([0-9a-zA-Z]{1})\@./ );\r
+ return 0 if ( $mail !~ /.\@([0-9a-zA-Z]{1})/ );\r
+ return 0 if ( $mail =~ /.\.\-.|.\-\..|.\.\..|.\-\-./g );\r
+ return 0 if ( $mail =~ /.\.\_.|.\-\_.|.\_\..|.\_\-.|.\_\_./g );\r
+ return 0 if ( $mail !~ /\.([a-zA-Z]{2,3})$/ );\r
+ return 1;\r
+}\r
+\r
+sub readhasharray {\r
+ my ($filename, $hash) = @_;\r
+\r
+ open(FILE, $filename) or die "Unable to read file $filename";\r
+\r
+ while (<FILE>) {\r
+ my ($key, $rest, @temp);\r
+ chomp;\r
+ ($key, $rest) = split (/,/, $_, 2);\r
+ if ($key =~ /^[0-9]+$/ && $rest) {\r
+ @temp = split (/,/, $rest);\r
+ $hash->{$key} = \@temp;\r
+ }\r
+ }\r
+ close FILE;\r
+ return;\r
+}\r
+\r
+sub writehasharray {\r
+ my ($filename, $hash) = @_;\r
+ my ($key, @temp);\r
+\r
+ open(FILE, ">$filename") or die "Unable to write to file $filename";\r
+\r
+ foreach $key (keys %$hash) {\r
+ if ( $hash->{$key} ) {\r
+ print FILE "$key";\r
+ foreach $i (0 .. $#{$hash->{$key}}) {\r
+ print FILE ",$hash->{$key}[$i]";\r
+ }\r
+ }\r
+ print FILE "\n";\r
+ }\r
+ close FILE;\r
+ return;\r
+}\r
+\r
+sub findhasharraykey {\r
+ foreach my $i (1 .. 1000000) {\r
+ if ( ! exists $_[0]{$i}) {\r
+ return $i;\r
+ }\r
+ }\r
+}\r
+\r
+sub cleanhtml\r
+{\r
+ my $outstring =$_[0];\r
+ $outstring =~ tr/,/ / if not defined $_[1] or $_[1] ne 'y';\r
+ $outstring =~ s/&/&/g;\r
+ $outstring =~ s/\'/'/g;\r
+ $outstring =~ s/\"/"/g;\r
+ $outstring =~ s/</</g;\r
+ $outstring =~ s/>/>/g;\r
+ return $outstring;\r
+}\r
+sub connectionstatus\r
+{\r
+ my $status;\r
+ opendir UPLINKS, "/var/ipfire/uplinks" or die "Cannot read uplinks: $!";\r
+ foreach my $uplink (sort grep !/^\./, readdir UPLINKS) {\r
+ if ( -f "${swroot}/uplinks/${uplink}/active") {\r
+ if ( ! $status ) {\r
+ $timestr = &age("${swroot}/uplinks/${uplink}/active");\r
+ $status = "$tr{'connected'}: $uplink (<span class='ipcop_StatusBigRed'>$timestr</span>) ";\r
+ } else {\r
+ $timestr = &age("${swroot}/uplinks/${uplink}/active");\r
+ $status = "$status , $uplink (<span class='ipcop_StatusBigRed'>$timestr</span>) ";\r
+ }\r
+ } elsif ( -f "${swroot}/uplinks/${uplink}/connecting") {\r
+ if ( ! $status ) {\r
+ $status = "$tr{'connecting'} $uplink";\r
+ } else {\r
+ $status = "$status , $tr{'connecting'} $uplink (<span class='ipcop_StatusBigRed'>$timestr</span>) ";\r
+ }\r
+ }\r
+ $lines++;\r
+ }\r
+ closedir(UPLINKS);\r
+ if ( ! $status ) {\r
+ $status = "$tr{'idle'}";\r
+ }\r
+ $connstate = "<span class='ipcop_StatusBig'>$status</span>";\r
+ return $connstate;\r
+}\r
+\r
+sub srtarray \r
+# Darren Critchley - darrenc@telus.net - (c) 2003\r
+# &srtarray(SortOrder, AlphaNumeric, SortDirection, ArrayToBeSorted)\r
+# This subroutine will take the following parameters:\r
+# ColumnNumber = the column which you want to sort on, starts at 1\r
+# AlphaNumberic = a or n (lowercase) defines whether the sort should be alpha or numberic\r
+# SortDirection = asc or dsc (lowercase) Ascending or Descending sort\r
+# ArrayToBeSorted = the array that wants sorting\r
+#\r
+# Returns an array that is sorted to your specs\r
+#\r
+# If SortOrder is greater than the elements in array, then it defaults to the first element\r
+# \r
+{\r
+ my ($colno, $alpnum, $srtdir, @tobesorted) = @_;\r
+ my @tmparray;\r
+ my @srtedarray;\r
+ my $line;\r
+ my $newline;\r
+ my $ttlitems = scalar @tobesorted; # want to know the number of rows in the passed array\r
+ if ($ttlitems < 1){ # if no items, don't waste our time lets leave\r
+ return (@tobesorted);\r
+ }\r
+ my @tmp = split(/\,/,$tobesorted[0]);\r
+ $ttlitems = scalar @tmp; # this should be the number of elements in each row of the passed in array\r
+\r
+ # Darren Critchley - validate parameters\r
+ if ($colno > $ttlitems){$colno = '1';}\r
+ $colno--; # remove one from colno to deal with arrays starting at 0\r
+ if($colno < 0){$colno = '0';}\r
+ if ($alpnum ne '') { $alpnum = lc($alpnum); } else { $alpnum = 'a'; }\r
+ if ($srtdir ne '') { $srtdir = lc($srtdir); } else { $srtdir = 'src'; }\r
+\r
+ foreach $line (@tobesorted)\r
+ {\r
+ chomp($line);\r
+ if ($line ne '') {\r
+ my @temp = split(/\,/,$line);\r
+ # Darren Critchley - juggle the fields so that the one we want to sort on is first\r
+ my $tmpholder = $temp[0];\r
+ $temp[0] = $temp[$colno];\r
+ $temp[$colno] = $tmpholder;\r
+ $newline = "";\r
+ for ($ctr=0; $ctr < $ttlitems ; $ctr++) {\r
+ $newline=$newline . $temp[$ctr] . ",";\r
+ }\r
+ chop($newline);\r
+ push(@tmparray,$newline);\r
+ }\r
+ }\r
+ if ($alpnum eq 'n') {\r
+ @tmparray = sort {$a <=> $b} @tmparray;\r
+ } else {\r
+ @tmparray = (sort @tmparray);\r
+ }\r
+ foreach $line (@tmparray)\r
+ {\r
+ chomp($line);\r
+ if ($line ne '') {\r
+ my @temp = split(/\,/,$line);\r
+ my $tmpholder = $temp[0];\r
+ $temp[0] = $temp[$colno];\r
+ $temp[$colno] = $tmpholder;\r
+ $newline = "";\r
+ for ($ctr=0; $ctr < $ttlitems ; $ctr++){\r
+ $newline=$newline . $temp[$ctr] . ",";\r
+ }\r
+ chop($newline);\r
+ push(@srtedarray,$newline);\r
+ }\r
+ }\r
+\r
+ if ($srtdir eq 'dsc') {\r
+ @tmparray = reverse(@srtedarray);\r
+ return (@tmparray);\r
+ } else {\r
+ return (@srtedarray);\r
+ }\r
+}\r
+\r
+sub speedtouchversion\r
+{\r
+ if (-f "/proc/bus/usb/devices")\r
+ {\r
+ $speedtouch=`/bin/cat /proc/bus/usb/devices | /bin/grep 'Vendor=06b9 ProdID=4061' | /usr/bin/cut -d ' ' -f6`;\r
+ if ($speedtouch eq '') {\r
+ $speedtouch= $tr{'connect the modem'};\r
+ }\r
+ } else {\r
+ $speedtouch='USB '.$tr{'not running'};\r
+ }\r
+ return $speedtouch\r
+}\r
+\r
+sub CheckSortOrder {\r
+#Sorting of allocated leases\r
+ if ($ENV{'QUERY_STRING'} =~ /^IPADDR|^ETHER|^HOSTNAME|^ENDTIME/ ) {\r
+ my $newsort=$ENV{'QUERY_STRING'};\r
+ &readhash("${swroot}/dhcp/settings", \%dhcpsettings);\r
+ $act=$dhcpsettings{'SORT_LEASELIST'};\r
+ #Reverse actual ?\r
+ if ($act =~ $newsort) {\r
+ if ($act !~ 'Rev') {$Rev='Rev'};\r
+ $newsort.=$Rev\r
+ };\r
+\r
+ $dhcpsettings{'SORT_LEASELIST'}=$newsort;\r
+ &writehash("${swroot}/dhcp/settings", \%dhcpsettings);\r
+ $dhcpsettings{'ACTION'} = 'SORT'; # avoid the next test "First lauch"\r
+ }\r
+\r
+}\r
+\r
+sub PrintActualLeases\r
+{\r
+ &openbox('100%', 'left', $tr{'current dynamic leases'});\r
+ print <<END\r
+<table width='100%'>\r
+<tr>\r
+<td width='25%' align='center'><a href='$ENV{'SCRIPT_NAME'}?IPADDR'><b>$tr{'ip address'}</b></a></td>\r
+<td width='25%' align='center'><a href='$ENV{'SCRIPT_NAME'}?ETHER'><b>$tr{'mac address'}</b></a></td>\r
+<td width='20%' align='center'><a href='$ENV{'SCRIPT_NAME'}?HOSTNAME'><b>$tr{'hostname'}</b></a></td>\r
+<td width='30%' align='center'><a href='$ENV{'SCRIPT_NAME'}?ENDTIME'><b>$tr{'lease expires'} (local time d/m/y)</b></a></td>\r
+</tr>\r
+END\r
+ ;\r
+\r
+ open(LEASES,"/var/lib/dhcp/dhcpd.leases") or die "Can't open dhcpd.leases";\r
+ while ($line = <LEASES>) {\r
+ next if( $line =~ /^\s*#/ );\r
+ chomp($line);\r
+ @temp = split (' ', $line);\r
+\r
+ if ($line =~ /^\s*lease/) {\r
+ $ip = $temp[1];\r
+ #All field are not necessarily read. Clear everything\r
+ $endtime = 0;\r
+ $ether = "";\r
+ $hostname = "";\r
+ }\r
+\r
+ if ($line =~ /^\s*ends/) {\r
+ $line =~ /(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/;\r
+ $endtime = timegm($6, $5, $4, $3, $2 - 1, $1 - 1900);\r
+ }\r
+\r
+ if ($line =~ /^\s*hardware ethernet/) {\r
+ $ether = $temp[2];\r
+ $ether =~ s/;//g;\r
+ }\r
+\r
+ if ($line =~ /^\s*client-hostname/) {\r
+ $hostname = "$temp[1] $temp[2] $temp[3]";\r
+ $hostname =~ s/;//g;\r
+ $hostname =~ s/\"//g;\r
+ }\r
+\r
+ if ($line eq "}") {\r
+ @record = ('IPADDR',$ip,'ENDTIME',$endtime,'ETHER',$ether,'HOSTNAME',$hostname);\r
+ $record = {}; # create a reference to empty hash\r
+ %{$record} = @record; # populate that hash with @record\r
+ $entries{$record->{'IPADDR'}} = $record; # add this to a hash of hashes\r
+ }\r
+ }\r
+ close(LEASES);\r
+\r
+ my $id = 0;\r
+ foreach my $key (sort leasesort keys %entries) {\r
+\r
+ my $hostname = &cleanhtml($entries{$key}->{HOSTNAME},"y");\r
+\r
+ if ($id % 2) {\r
+ print "<tr bgcolor='$table1colour'>"; \r
+ }\r
+ else {\r
+ print "<tr bgcolor='$table2colour'>"; \r
+ }\r
+\r
+ print <<END\r
+<td align='center'>$entries{$key}->{IPADDR}</td>\r
+<td align='center'>$entries{$key}->{ETHER}</td>\r
+<td align='center'> $hostname </td>\r
+<td align='center'>\r
+END\r
+ ;\r
+\r
+ ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime ($entries{$key}->{ENDTIME});\r
+ $enddate = sprintf ("%02d/%02d/%d %02d:%02d:%02d",$mday,$mon+1,$year+1900,$hour,$min,$sec);\r
+\r
+ if ($entries{$key}->{ENDTIME} < time() ){\r
+ print "<strike>$enddate</strike>";\r
+ } else {\r
+ print "$enddate";\r
+ }\r
+ print "</td></tr>";\r
+ $id++;\r
+ }\r
+\r
+ print "</table>";\r
+ &closebox();\r
+}\r
+\r
+\r
+# This sub is used during display of actives leases\r
+sub leasesort {\r
+ if (rindex ($dhcpsettings{'SORT_LEASELIST'},'Rev') != -1)\r
+ {\r
+ $qs=substr ($dhcpsettings{'SORT_LEASELIST'},0,length($dhcpsettings{'SORT_LEASELIST'})-3);\r
+ if ($qs eq 'IPADDR') {\r
+ @a = split(/\./,$entries{$a}->{$qs});\r
+ @b = split(/\./,$entries{$b}->{$qs});\r
+ ($b[0]<=>$a[0]) ||\r
+ ($b[1]<=>$a[1]) ||\r
+ ($b[2]<=>$a[2]) ||\r
+ ($b[3]<=>$a[3]);\r
+ }else {\r
+ $entries{$b}->{$qs} cmp $entries{$a}->{$qs};\r
+ }\r
+ }\r
+ else #not reverse\r
+ {\r
+ $qs=$dhcpsettings{'SORT_LEASELIST'};\r
+ if ($qs eq 'IPADDR') {\r
+ @a = split(/\./,$entries{$a}->{$qs});\r
+ @b = split(/\./,$entries{$b}->{$qs});\r
+ ($a[0]<=>$b[0]) ||\r
+ ($a[1]<=>$b[1]) ||\r
+ ($a[2]<=>$b[2]) ||\r
+ ($a[3]<=>$b[3]);\r
+ }else {\r
+ $entries{$a}->{$qs} cmp $entries{$b}->{$qs};\r
+ }\r
+ }\r
+}\r
+\r
+sub get_uplinks() {\r
+ my @uplinks = ();\r
+ opendir(DIR, "${swroot}/uplinks/") || return \@uplinks;\r
+ foreach my $dir (readdir(DIR)) {\r
+ next if ($dir =~ /^\./);\r
+ next if (-f "${swroot}/uplinks/$dir");\r
+ push(@uplinks, $dir);\r
+ }\r
+ closedir(DIR);\r
+ return \@uplinks;\r
+}\r
+\r
+sub get_iface($) {\r
+ my $filename = shift;\r
+ chomp($filename);\r
+ open (F, $filename) || return "";\r
+ my $iface = <F>;\r
+ close(F);\r
+ chomp($iface);\r
+ return $iface;\r
+}\r
+\r
+sub get_red_ifaces_by_type($) {\r
+ my $type=shift;\r
+ my @gottypeiface = ();\r
+ my @gottypeuplink = ();\r
+ my @gottype = ();\r
+\r
+ my $ref=get_uplinks();\r
+ my @uplinks=@$ref;\r
+ my %set = ();\r
+ foreach my $link (@uplinks) {\r
+ eval {\r
+ &readhash("${swroot}/uplinks/$link/settings", \%set);\r
+ };\r
+ push(@gottype, $link);\r
+\r
+ my $iface = $set{'RED_DEV'};\r
+ if (!$iface) {\r
+ $iface = get_iface("${swroot}/uplinks/$link/interface");\r
+ }\r
+ next if (!$iface);\r
+\r
+ if ($set{'RED_TYPE'} eq $type) {\r
+ push(@gottypeiface, $iface);\r
+ push(@gottypeuplink, $link);\r
+ }\r
+ }\r
+ return (\@gottypeiface, \@gottypeuplink, \@gottype);\r
+}\r
+\r
+sub get_red_ifaces() {\r
+ return `cat ${swroot}/uplinks/*/interface 2>/dev/null`;\r
+}\r
+\r
+sub get_zone_devices($) {\r
+ my $bridge = shift;\r
+ my @ifaces = ();\r
+ open (FILE, "${swroot}/ethernet/$bridge") || return "";\r
+ foreach my $line (<FILE>) {\r
+ chomp($line);\r
+ next if (!$line);\r
+ push(@ifaces, $line);\r
+ }\r
+ close(FILE);\r
+ return \@ifaces;\r
+}\r
+++ /dev/null
-// {{{ docs <-- this is a VIM (text editor) text fold
-
-/**
- * DOM Menu 0.3.2
- *
- * Summary: Allows developers to add dynamic drop down menus on webpages. The
- * menu can either be horizontal or vertical, and can open in either
- * direction. It has both edge detection and <select> tag detection
- * (for browsers that cannot hide these form elements). The styles
- * for the menu items are controlled almost entirely through CSS and
- * the menus are created and destroyed using the DOM. Menu configuration
- * is done using a custom Hash() class and is very portable from a PHP
- * type array structure.
- *
- * Maintainer: Dan Allen <dan@mojavelinux.com>
- *
- * License: LGPL - however, if you use this library, please post to my forum where you
- * use it so that I get a chance to see my baby in action. If you are doing
- * this for commercial work perhaps you could send me a few Starbucks Coffee
- * gift dollars to encourage future developement (NOT REQUIRED). E-mail me
- * for and address.
- *
- * Homepage: http://www.mojavelinux.com/forum/viewtopic.php
- *
- * Freshmeat Project: http://freshmeat.net/projects/dommenu/?topic_id=92
- *
- * Updated: 2003/01/04
- *
- * Supported Browsers: Mozilla (Gecko), IE 5+, Konqueror, (not finished Opera 7), Netscape 4
- *
- * Usage:
- *
- * Menu Options: Each option is followed by the value for that option. The options avaiable are:
- * 'contents'
- * 'rolloverContents',
- * 'uri' (may be javascript)
- * 'statusText'
- * 'target'
- * [0-9] an index to create a submenu item
- *
- * API:
- *
- * menuElementObject {
- * ** properties **
- * data
- * contents
- * uri
- * target
- * statusText
- * parentElement
- * subMenu
- * childElements
- * level
- * index (index within this level)
- * id
- * className
- * style
- * cellSpacing (Konq only)
- *
- * ** events **
- * mouseover/click -> domMenu_openEvent
- * mouseout -> domMenu_closeEvent
- * click -> domMenu_resolveLink
- * }
- *
- * If there is a non-negative click open delay, then any uri of the element will be ignored
- *
- * The alternate contents for a hover element are treated by creating to <span> wrapper elements
- * and then alternating the display of them. This avoids the need for innerHTML, which can
- * do nasty things to the browsers. If <span> turns out to be a bad choice for tags, then a
- * non-HTML element can be used instead.
- *
-**/
-
-// }}}
-// {{{ settings (editable)
-
-var domMenu_data = new domMenu_Hash();
-var domMenu_settings = new domMenu_Hash();
-
-domMenu_settings.setItem('global', new domMenu_Hash(
- 'menuBarClass', 'domMenu_menuBar',
- 'menuElementClass', 'domMenu_menuElement',
- 'menuElementHoverClass', 'domMenu_menuElementHover',
- 'menuElementActiveClass', 'domMenu_menuElementHover',
- 'subMenuBarClass', 'domMenu_subMenuBar',
- 'subMenuElementClass', 'domMenu_subMenuElement',
- 'subMenuElementHoverClass', 'domMenu_subMenuElementHover',
- 'subMenuElementActiveClass', 'domMenu_subMenuElementHover',
- 'subMenuElementHeadingClass', 'domMenu_subMenuElementHeading',
- 'menuBarWidth', '100%',
- 'subMenuMinWidth', 'inherit',
- 'distributeSpace', true,
- 'axis', 'horizontal',
- 'verticalExpand', 'south',
- 'horizontalExpand', 'east',
- 'subMenuWidthCorrection', 0,
- 'verticalSubMenuOffsetY', 0,
- 'verticalSubMenuOffsetX', 0,
- 'horizontalSubMenuOffsetX', 0,
- 'horizontalSubMenuOffsetY', 0,
- 'screenPadding', 0,
- 'openMouseoverMenuDelay', 300,
- 'openMousedownMenuDelay', -1,
- 'closeMouseoutMenuDelay', 800,
- 'closeClickMenuDelay', -1,
- 'openMouseoverSubMenuDelay', 300,
- 'openClickSubMenuDelay', -1,
- 'closeMouseoutSubMenuDelay', 300,
- 'closeClickSubMenuDelay', -1,
- 'baseZIndex', 100
-));
-
-// }}}
-// {{{ global variables
-
-/**
- * Browser variables
- * @var domMenu_is{Browser}
- */
-var domMenu_userAgent = navigator.userAgent.toLowerCase();
-var domMenu_isOpera = domMenu_userAgent.indexOf('opera 7') != -1 ? 1 : 0;
-var domMenu_isKonq = domMenu_userAgent.indexOf('konq') != -1 ? 1 : 0;
-var domMenu_isIE = !domMenu_isKonq && !domMenu_isOpera && document.all ? 1 : 0;
-var domMenu_isIE50 = domMenu_isIE && domMenu_userAgent.indexOf('msie 5.0') != -1;
-var domMenu_isIE55 = domMenu_isIE && domMenu_userAgent.indexOf('msie 5.5') != -1;
-var domMenu_isIE5 = domMenu_isIE50 || domMenu_isIE55;
-var domMenu_isGecko = !domMenu_isKonq && domMenu_userAgent.indexOf('gecko') != -1 ? 1 : 0;
-
-/**
- * Passport to use the menu system, checked before performing menu manipulation
- * @var domMenu_useLibrary
- */
-var domMenu_useLibrary = domMenu_isIE || domMenu_isGecko || domMenu_isKonq || domMenu_isOpera ? 1 : 0;
-
-/**
- * The data for the menu is stored here, loaded from an external file
- * @hash domMenu_data
- */
-var domMenu_data;
-
-var domMenu_selectElements;
-var domMenu_scrollbarWidth = 14;
-var domMenu_eventTo = domMenu_isIE ? 'toElement' : 'relatedTarget';
-var domMenu_eventFrom = domMenu_isIE ? 'fromElement' : 'relatedTarget';
-
-var domMenu_activeElement = new domMenu_Hash();
-
-/**
- * Array of hashes listing the timouts currently running for opening/closing menus
- * @array domMenu_timeouts
- */
-var domMenu_timeouts = new Array();
-domMenu_timeouts['open'] = new domMenu_Hash();
-domMenu_timeouts['close'] = new domMenu_Hash();
-
-var domMenu_timeoutStates = new Array();
-domMenu_timeoutStates['open'] = new domMenu_Hash();
-domMenu_timeoutStates['close'] = new domMenu_Hash();
-
-/**
- * Style to use for a link pointer, which is different between Gecko and IE
- * @var domMenu_pointerStyle
- */
-var domMenu_pointerStyle = domMenu_isIE ? 'hand' : 'pointer';
-
-// }}}
-// {{{ domMenu_Hash()
-
-function domMenu_Hash() {
- var argIndex = 0;
- this.length = 0;
- this.numericLength = 0;
- this.items = new Array();
- while (arguments.length > argIndex) {
- this.items[arguments[argIndex]] = arguments[argIndex + 1];
- if (arguments[argIndex] == parseInt(arguments[argIndex])) {
- this.numericLength++;
- }
-
- this.length++;
- argIndex += 2;
- }
-
- this.removeItem = function(in_key)
- {
- var tmp_value;
- if (typeof(this.items[in_key]) != 'undefined') {
- this.length--;
- if (in_key == parseInt(in_key)) {
- this.numericLength--;
- }
-
- tmp_value = this.items[in_key];
- delete this.items[in_key];
- }
-
- return tmp_value;
- }
-
- this.getItem = function(in_key)
- {
- return this.items[in_key];
- }
-
- this.setItem = function(in_key, in_value)
- {
- if (typeof(this.items[in_key]) == 'undefined') {
- this.length++;
- if (in_key == parseInt(in_key)) {
- this.numericLength++;
- }
- }
-
- this.items[in_key] = in_value;
- }
-
- this.hasItem = function(in_key)
- {
- return typeof(this.items[in_key]) != 'undefined';
- }
-
- this.merge = function(in_hash)
- {
- for (var tmp_key in in_hash.items) {
- if (typeof(this.items[tmp_key]) == 'undefined') {
- this.length++;
- if (tmp_key == parseInt(tmp_key)) {
- this.numericLength++;
- }
- }
-
- this.items[tmp_key] = in_hash.items[tmp_key];
- }
- }
-
- this.compare = function(in_hash)
- {
- if (this.length != in_hash.length) {
- return false;
- }
-
- for (var tmp_key in this.items) {
- if (this.items[tmp_key] != in_hash.items[tmp_key]) {
- return false;
- }
- }
-
- return true;
- }
-}
-
-// }}}
-// {{{ domMenu_activate()
-
-function domMenu_activate(in_containerId)
-{
- var container;
- var data;
-
- // make sure we can use the menu system and this is a valid menu
- if (!domMenu_useLibrary || !(container = document.getElementById(in_containerId)) || !(data = domMenu_data.items[in_containerId])) {
- return;
- }
-
- // start with the global settings and merge in the local changes
- if (!domMenu_settings.hasItem(in_containerId)) {
- domMenu_settings.setItem(in_containerId, new domMenu_Hash());
- }
-
- var settings = domMenu_settings.items[in_containerId];
- for (var i in domMenu_settings.items['global'].items) {
- if (!settings.hasItem(i)) {
- settings.setItem(i, domMenu_settings.items['global'].items[i]);
- }
- }
-
- // populate the zero level element
- container.data = new domMenu_Hash(
- 'parentElement', false,
- 'numChildren', data.numericLength,
- 'childElements', new domMenu_Hash(),
- 'level', 0,
- 'index', 1
- );
-
- // if we choose to distribute either height or width, determine ratio of each cell
- var distributeRatio = Math.round(100/container.data.items['numChildren']) + '%';
-
- // the first menu is the rootMenu, which is a child of the zero level element
- var rootMenu = document.createElement('div');
- rootMenu.id = in_containerId + '[0]';
- rootMenu.className = settings.items['menuBarClass'];
- container.data.setItem('subMenu', rootMenu);
-
- var rootMenuTable = rootMenu.appendChild(document.createElement('table'));
- if (domMenu_isKonq) {
- rootMenuTable.cellSpacing = 0;
- }
-
- rootMenuTable.style.border = 0;
- rootMenuTable.style.borderCollapse = 'collapse';
- rootMenuTable.style.width = settings.items['menuBarWidth'];
- var rootMenuTableBody = rootMenuTable.appendChild(document.createElement('tbody'));
-
- var numSiblings = container.data.items['numChildren'];
- for (var index = 1; index <= numSiblings; index++) {
- // create a row the first time if horizontal or each time if vertical
- if (index == 1 || settings.items['axis'] == 'vertical') {
- var rootMenuTableRow = rootMenuTableBody.appendChild(document.createElement('tr'));
- }
-
- // create an instance of the root level menu element
- var rootMenuTableCell = rootMenuTableRow.appendChild(document.createElement('td'));
- rootMenuTableCell.style.padding = 0;
- rootMenuTableCell.id = in_containerId + '[' + index + ']';
- // add element to list of parent children
- container.data.items['childElements'].setItem(rootMenuTableCell.id, rootMenuTableCell);
-
- // assign the settings to the root level element
- // {!} this is a problem if two menus are using the same data {!}
- rootMenuTableCell.data = data.items[index];
- rootMenuTableCell.data.merge(new domMenu_Hash(
- 'basename', in_containerId,
- 'parentElement', container,
- 'numChildren', rootMenuTableCell.data.numericLength,
- 'childElements', new domMenu_Hash(),
- 'offsets', new domMenu_Hash(),
- 'level', container.data.items['level'] + 1,
- 'index', index
- ));
-
- // assign the styles
- rootMenuTableCell.style.cursor = 'default';
- if (settings.items['axis'] == 'horizontal') {
- if (settings.items['distributeSpace']) {
- rootMenuTableCell.style.width = distributeRatio;
- }
- }
-
- var rootElement = rootMenuTableCell.appendChild(document.createElement('div'));
- rootElement.className = settings.items['menuElementClass'];
- // fill in the menu element contents
- rootElement.innerHTML = '<span>' + rootMenuTableCell.data.items['contents'] + '</span>' + (rootMenuTableCell.data.hasItem('contentsHover') ? '<span style="display: none;">' + rootMenuTableCell.data.items['contentsHover'] + '</span>' : '');
-
- // attach the events
- rootMenuTableCell.onmouseover = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openMouseoverMenuDelay']); };
- rootMenuTableCell.onmouseout = function(in_event) { domMenu_closeEvent(this, in_event); };
-
- if (settings.items['openMousedownMenuDelay'] >= 0 && rootMenuTableCell.data.items['numChildren']) {
- rootMenuTableCell.onmousedown = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openMousedownMenuDelay']); };
- // cancel mouseup so that it doesn't propogate to global mouseup event
- rootMenuTableCell.onmouseup = function(in_event) { var eventObj = domMenu_isIE ? event : in_event; eventObj.cancelBubble = true; };
- if (domMenu_isIE) {
- rootMenuTableCell.ondblclick = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openMousedownMenuDelay']); };
- }
- }
- else if (rootMenuTableCell.data.items['uri']) {
- rootMenuTableCell.style.cursor = domMenu_pointerStyle;
- rootMenuTableCell.onclick = function(in_event) { domMenu_resolveLink(this, in_event); };
- }
-
- // prevent highlighting of text
- if (domMenu_isIE) {
- rootMenuTableCell.onselectstart = function() { return false; };
- }
-
- rootMenuTableCell.oncontextmenu = function() { return false; };
- }
-
- // add the menu rootMenu to the zero level element
- rootMenu = container.appendChild(rootMenu);
-
- // even though most cases the top level menu does not go away, it could
- // if this menu system is used by another process
- domMenu_detectCollisions(rootMenu);
-}
-
-// }}}
-// {{{ domMenu_activateSubMenu()
-
-function domMenu_activateSubMenu(in_parentElement)
-{
- // see if submenu already exists
- if (in_parentElement.data.hasItem('subMenu')) {
- domMenu_toggleSubMenu(in_parentElement, 'visible');
- return;
- }
-
- var settings = domMenu_settings.items[in_parentElement.data.items['basename']];
-
- // build the submenu
- var menu = document.createElement('div');
- menu.id = in_parentElement.id + '[0]';
- menu.className = settings.items['subMenuBarClass'];
- menu.style.zIndex = settings.items['baseZIndex'];
- menu.style.position = 'absolute';
- // position the menu in the upper left corner hidden so that we can work on it
- menu.style.visibility = 'hidden';
- menu.style.top = 0;
- menu.style.left = 0;
-
- in_parentElement.data.setItem('subMenu', menu);
-
- var menuTable = menu.appendChild(document.createElement('table'));
- // ** opera wants to make absolute tables width 100% **
- if (domMenu_isOpera) {
- menuTable.style.width = '1px';
- menuTable.style.whiteSpace = 'nowrap';
- }
-
- if (domMenu_isKonq) {
- menuTable.cellSpacing = 0;
- }
-
- menuTable.style.border = 0;
- menuTable.style.borderCollapse = 'collapse';
- var menuTableBody = menuTable.appendChild(document.createElement('tbody'));
-
- var numSiblings = in_parentElement.data.items['numChildren'];
- for (var index = 1; index <= numSiblings; index++) {
- var dataIndex = in_parentElement.data.items['level'] == 1 && settings.items['verticalExpand'] == 'north' && settings.items['axis'] == 'horizontal' ? numSiblings + 1 - index : index;
- var menuTableCell = menuTableBody.appendChild(document.createElement('tr')).appendChild(document.createElement('td'));
- menuTableCell.style.padding = 0;
- menuTableCell.id = in_parentElement.id + '[' + dataIndex + ']';
-
- // add element to list of parent children
- in_parentElement.data.items['childElements'].setItem(menuTableCell.id, menuTableCell);
-
- // assign the settings to nth level element
- menuTableCell.data = in_parentElement.data.items[dataIndex];
- menuTableCell.data.merge(new domMenu_Hash(
- 'basename', in_parentElement.data.items['basename'],
- 'parentElement', in_parentElement,
- 'numChildren', menuTableCell.data.numericLength,
- 'childElements', new domMenu_Hash(),
- 'offsets', new domMenu_Hash(),
- 'level', in_parentElement.data.items['level'] + 1,
- 'index', index
- ));
-
- // assign the styles
- var parentStyle = in_parentElement.data.items['level'] == 1 ? in_parentElement.parentNode.style : in_parentElement.style;
- menuTableCell.style.cursor = 'default';
-
- var element = menuTableCell.appendChild(document.createElement('div'));
- var outerElement = element;
- outerElement.className = settings.items['subMenuElementClass'];
-
- if (menuTableCell.data.items['numChildren']) {
- element = outerElement.appendChild(document.createElement('div'));
- // {!} depends on which way we are opening {!}
- element.style.backgroundImage = 'url(arrow.gif)';
- element.style.backgroundRepeat = 'no-repeat';
- element.style.backgroundPosition = 'right center';
- // add appropriate padding to fit the arrow
- element.style.paddingRight = '12px';
- }
-
- // fill in the menu item contents
- element.innerHTML = menuTableCell.data.items['contents'];
-
- // attach the events
- menuTableCell.onmouseover = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openMouseoverSubMenuDelay']); };
- menuTableCell.onmouseout = function(in_event) { domMenu_closeEvent(this, in_event); };
-
- if (settings.items['openClickSubMenuDelay'] >= 0 && menuTableCell.data.items['numChildren']) {
- menuTableCell.onmousedown = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openClickSubMenuDelay']); };
- menuTableCell.onmouseup = function(in_event) { var eventObj = domMenu_isIE ? event : in_event; eventObj.cancelBubble = true; };
- if (domMenu_isIE) {
- menuTableCell.ondblclick = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openClickSubMenuDelay']); };
- }
- }
- else if (menuTableCell.data.items['uri']) {
- menuTableCell.style.cursor = domMenu_pointerStyle;
- menuTableCell.onclick = function(in_event) { domMenu_resolveLink(this, in_event); };
- }
- else if (!menuTableCell.data.items['numChildren']) {
- outerElement.className += ' ' + settings.items['subMenuElementHeadingClass'];
- }
-
- // prevent highlighting of text
- if (domMenu_isIE) {
- menuTableCell.onselectstart = function() { return false; };
- }
-
- menuTableCell.oncontextmenu = function() { return false; };
- }
-
- menu = document.body.appendChild(menu);
- domMenu_toggleSubMenu(in_parentElement, 'visible');
-}
-
-// }}}
-// {{{ domMenu_changeActivePath()
-
-/**
- * Close the old active path up to the new active element
- * and return the value of the new active element (or the same if unchanged)
- * If the new active element is not set, the top level is assumed
- *
- * @return mixed new active element or false if not set
- */
-function domMenu_changeActivePath(in_newActiveElement, in_oldActiveElement, in_closeDelay)
-{
- // protect against crap
- if (!in_oldActiveElement && !in_newActiveElement) {
- return false;
- }
-
- // cancel open timeouts since we know we are opening something different now
- for (var i in domMenu_timeouts['open'].items) {
- domMenu_cancelTimeout(i, 'open');
- }
-
- // grab some info about this menu system
- var basename = in_oldActiveElement ? in_oldActiveElement.data.items['basename'] : in_newActiveElement.data.items['basename'];
- var settings = domMenu_settings.items[basename];
-
- // build the old and new paths
- var oldActivePath = new domMenu_Hash();
- if (in_oldActiveElement) {
- var tmp_oldActivePathElement = in_oldActiveElement;
- do {
- oldActivePath.setItem(tmp_oldActivePathElement.id, tmp_oldActivePathElement);
- } while ((tmp_oldActivePathElement = tmp_oldActivePathElement.data.items['parentElement']) && tmp_oldActivePathElement.id != basename);
-
- // unhighlight the old active element if it doesn't have children open
- if (!in_oldActiveElement.data.items['subMenu'] || in_oldActiveElement.data.items['subMenu'].style.visibility == 'hidden') {
- domMenu_toggleHighlight(in_oldActiveElement, false);
- }
- }
-
- var newActivePath = new domMenu_Hash();
- var intersectPoint;
- if (in_newActiveElement) {
- var actualActiveElement = in_newActiveElement;
- window.status = in_newActiveElement.data.items['statusText'] + ' ';
-
- // in the event we have no old active element, just highlight new one and return
- // without setting the new active element (handled later)
- if (!in_oldActiveElement) {
- domMenu_cancelTimeout(in_newActiveElement.id, 'close');
- domMenu_toggleHighlight(in_newActiveElement, true);
- return false;
- }
- // if the new element is in the path of the old element, then pretend event is
- // on the old active element
- else if (oldActivePath.hasItem(in_newActiveElement.id)) {
- in_newActiveElement = in_oldActiveElement;
- }
-
- var tmp_newActivePathElement = in_newActiveElement;
- do {
- // if we have met up with the old active path, then record merge point
- if (!intersectPoint && oldActivePath.hasItem(tmp_newActivePathElement.id)) {
- intersectPoint = tmp_newActivePathElement;
- }
-
- newActivePath.setItem(tmp_newActivePathElement.id, tmp_newActivePathElement);
- domMenu_cancelTimeout(tmp_newActivePathElement.id, 'close');
- // {!} this is ugly {!}
- if (tmp_newActivePathElement != in_oldActiveElement || actualActiveElement == in_oldActiveElement) {
- domMenu_toggleHighlight(tmp_newActivePathElement, true);
- }
- } while ((tmp_newActivePathElement = tmp_newActivePathElement.data.items['parentElement']) && tmp_newActivePathElement.id != basename);
-
- // if we move to the child of the old active element
- if (in_newActiveElement.data.items['parentElement'] == in_oldActiveElement) {
- return in_newActiveElement;
- }
- // if the new active element is in the old active path
- else if (in_newActiveElement == in_oldActiveElement) {
- return in_newActiveElement;
- }
-
- // find the sibling element
- var intersectSibling;
- if (intersectPoint) {
- for (var i in oldActivePath.items) {
- if (oldActivePath.items[i].data.items['parentElement'] == intersectPoint) {
- intersectSibling = oldActivePath.items[i];
- break;
- }
- }
- }
-
- var isRootLevel = in_newActiveElement.data.items['level'] == 1 ? true : false;
- var closeDelay = isRootLevel ? settings.items['closeMouseoutMenuDelay'] : settings.items['closeMouseoutSubMenuDelay'];
- }
- else {
- var isRootLevel = false;
- var closeDelay = settings.items['closeMouseoutMenuDelay'];
- window.status = window.defaultStatus;
- }
-
- // override the close delay with that passed in
- if (typeof(in_closeDelay) != 'undefined') {
- closeDelay = in_closeDelay;
- }
-
- // if there is an intersect sibling, then we need to work from there up to
- // preserve the active path
- if (intersectSibling) {
- // only if this is not the root level to we allow the scheduled close
- // events to persist...otherwise we close immediately
- if (!isRootLevel) {
- // toggle the sibling highlight (only one sibling highlighted at a time)
- domMenu_toggleHighlight(intersectSibling, false);
- }
- // we are moving to another top level menu
- // {!} clean this up {!}
- else {
- // add lingering menus outside of old active path to active path
- for (var i in domMenu_timeouts['close'].items) {
- if (!oldActivePath.hasItem(i)) {
- var tmp_element = document.getElementById(i);
- if (tmp_element.data.items['basename'] == basename) {
- oldActivePath.setItem(i, tmp_element);
- }
- }
- }
- }
- }
-
- // schedule the old active path to be closed
- for (var i in oldActivePath.items) {
- if (newActivePath.hasItem(i)) {
- continue;
- }
-
- // make sure we don't double schedule here
- domMenu_cancelTimeout(i, 'close');
-
- if (isRootLevel) {
- domMenu_toggleHighlight(oldActivePath.items[i], false);
- domMenu_toggleSubMenu(oldActivePath.items[i], 'hidden');
- }
- else {
- var tmp_args = new Array();
- tmp_args[0] = oldActivePath.items[i];
- var tmp_function = 'domMenu_toggleHighlight(argv[0], false); domMenu_toggleSubMenu(argv[0], ' + domMenu_quote('hidden') + ');';
- // if this is the top level, then the menu is being deactivated
- if (oldActivePath.items[i].data.items['level'] == 1) {
- tmp_function += ' domMenu_activeElement.setItem(' + domMenu_quote(basename) + ', false);';
- }
-
- domMenu_callTimeout(tmp_function, closeDelay, tmp_args, i, 'close');
- }
- }
-
- return in_newActiveElement;
-}
-
-// }}}
-// {{{ domMenu_deactivate()
-
-function domMenu_deactivate(in_basename, in_delay)
-{
- if (!in_delay) {
- in_delay = 0;
- }
-
- domMenu_changeActivePath(false, domMenu_activeElement.items[in_basename], in_delay);
-}
-
-// }}}
-// {{{ domMenu_openEvent()
-
-/**
- * Handle the mouse event to open a menu
- *
- * When an event is received to open the menu, this function is
- * called, handles reinitialization of the menu state and sets
- * a timeout interval for opening the submenu (if one exists)
- */
-function domMenu_openEvent(in_this, in_event, in_openDelay)
-{
- if (domMenu_isGecko) {
- try {
- window.getSelection().removeAllRanges();
- } catch (e) {}
- }
-
- // setup the cross-browser event object and target
- var eventObj = domMenu_isIE ? event : in_event;
- var currentTarget = domMenu_isIE ? in_this : eventObj.currentTarget;
- var basename = currentTarget.data.items['basename'];
-
- // if we are moving amoungst children of the same element, just ignore event
- if (eventObj.type != 'mousedown' && domMenu_getElement(eventObj[domMenu_eventFrom], basename) == currentTarget) {
- return;
- }
-
- // if we click on an open menu, close it
- if (eventObj.type == 'mousedown' && domMenu_activeElement.items[basename]) {
- var settings = domMenu_settings.items[basename];
- domMenu_changeActivePath(false, domMenu_activeElement.items[basename], currentTarget.data.items['level'] == 1 ? settings.items['closeClickMenuDelay'] : settings.items['closeClickSubMenuDelay']);
- return;
- }
-
- // if this element has children, popup the child menu
- if (currentTarget.data.items['numChildren']) {
- // the top level menus have no delay when moving between them
- // so activate submenu immediately
- if (currentTarget.data.items['level'] == 1 && domMenu_activeElement.items[basename]) {
- // ** I place changeActivePath() call here so the hiding of selects does not flicker **
- // {!} instead I could tell changeActivePath to clear select ownership but not
- // toggle visibility....hmmm....{!}
- domMenu_activateSubMenu(currentTarget);
- // clear the active path and initialize the new one
- domMenu_activeElement.setItem(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.items[basename]));
- }
- else {
- // clear the active path and initialize the new one
- domMenu_activeElement.setItem(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.items[basename]));
- var tmp_args = new Array();
- tmp_args[0] = currentTarget;
- var tmp_function = 'if (!domMenu_activeElement.items[' + domMenu_quote(basename) + ']) { domMenu_activeElement.setItem(' + domMenu_quote(basename) + ', argv[0]); } domMenu_activateSubMenu(argv[0]);';
- domMenu_callTimeout(tmp_function, in_openDelay, tmp_args, currentTarget.id, 'open');
- }
- }
- else {
- // clear the active path and initialize the new one
- domMenu_activeElement.setItem(basename, domMenu_changeActivePath(currentTarget, domMenu_activeElement.items[basename]));
- }
-}
-
-// }}}
-// {{{ domMenu_closeEvent()
-
-/**
- * Handle the mouse event to close a menu
- *
- * When an mouseout event is received to close the menu, this function is
- * called, sets a timeout interval for closing the menu.
- */
-function domMenu_closeEvent(in_this, in_event)
-{
- // setup the cross-browser event object and target
- var eventObj = domMenu_isIE ? event : in_event;
- var currentTarget = domMenu_isIE ? in_this : eventObj.currentTarget;
- var basename = currentTarget.data.items['basename'];
- var relatedTarget = domMenu_getElement(eventObj[domMenu_eventTo], basename);
-
- // if the related target is not a menu element then we left the menu system
- // at this point (or cannot discern where we are in the menu)
- if (domMenu_activeElement.items[basename]) {
- if (!relatedTarget) {
- domMenu_changeActivePath(false, domMenu_activeElement.items[basename]);
- }
- }
- // we are highlighting the top level, but menu is not yet 'active'
- else {
- if (currentTarget != relatedTarget) {
- domMenu_cancelTimeout(currentTarget.id, 'open');
- domMenu_toggleHighlight(currentTarget, false);
- }
- }
-}
-
-// }}}
-// {{{ domMenu_getElement()
-
-function domMenu_getElement(in_object, in_basename)
-{
- while (in_object) {
- try {
- if (in_object.id && in_object.id.search(new RegExp('^' + in_basename + '(\\[[0-9]\\])*\\[[0-9]\\]$')) == 0) {
- return in_object;
- }
- else {
- in_object = in_object.parentNode;
- }
- }
- catch(e) {
- return false;
- }
- }
-
- return false;
-}
-
-// }}}
-// {{{ domMenu_detectCollisions()
-
-function domMenu_detectCollisions(in_menuObj, in_recover)
-{
- // no need to do anything for opera
- if (domMenu_isOpera) {
- return;
- }
-
- if (typeof(domMenu_selectElements) == 'undefined') {
- domMenu_selectElements = document.getElementsByTagName('select');
- }
-
- // if we don't have a menu, then unhide selects
- if (in_recover) {
- for (var cnt = 0; cnt < domMenu_selectElements.length; cnt++) {
- if (domMenu_isGecko && domMenu_selectElements[cnt].size <= 1 && !domMenu_selectElements[cnt].multiple) {
- continue;
- }
-
- var thisSelect = domMenu_selectElements[cnt];
- thisSelect.hideList.removeItem(in_menuObj.id);
- if (!thisSelect.hideList.length) {
- domMenu_selectElements[cnt].style.visibility = 'visible';
- }
- }
-
- return;
- }
-
- // okay, in_menu exists, let's hunt and destroy
- var menuOffsets = domMenu_getOffsets(in_menuObj);
-
- for (var cnt = 0; cnt < domMenu_selectElements.length; cnt++) {
- var thisSelect = domMenu_selectElements[cnt];
-
- // mozilla doesn't have a problem with regular selects
- if (domMenu_isGecko && thisSelect.size <= 1 && !thisSelect.multiple) {
- continue;
- }
-
- // {!} make sure this hash is congruent with domTT hash {!}
- if (!thisSelect.hideList) {
- thisSelect.hideList = new domMenu_Hash();
- }
-
- var selectOffsets = domMenu_getOffsets(thisSelect);
- // for mozilla we only have to worry about the scrollbar itself
- if (domMenu_isGecko) {
- selectOffsets.setItem('left', selectOffsets.items['left'] + thisSelect.offsetWidth - domMenu_scrollbarWidth);
- selectOffsets.setItem('leftCenter', selectOffsets.items['left'] + domMenu_scrollbarWidth/2);
- selectOffsets.setItem('radius', Math.max(thisSelect.offsetHeight, domMenu_scrollbarWidth/2));
- }
-
- var center2centerDistance = Math.sqrt(Math.pow(selectOffsets.items['leftCenter'] - menuOffsets.items['leftCenter'], 2) + Math.pow(selectOffsets.items['topCenter'] - menuOffsets.items['topCenter'], 2));
- var radiusSum = selectOffsets.items['radius'] + menuOffsets.items['radius'];
- // the encompassing circles are overlapping, get in for a closer look
- if (center2centerDistance < radiusSum) {
- // tip is left of select
- if ((menuOffsets.items['leftCenter'] <= selectOffsets.items['leftCenter'] && menuOffsets.items['right'] < selectOffsets.items['left']) ||
- // tip is right of select
- (menuOffsets.items['leftCenter'] > selectOffsets.items['leftCenter'] && menuOffsets.items['left'] > selectOffsets.items['right']) ||
- // tip is above select
- (menuOffsets.items['topCenter'] <= selectOffsets.items['topCenter'] && menuOffsets.items['bottom'] < selectOffsets.items['top']) ||
- // tip is below select
- (menuOffsets.items['topCenter'] > selectOffsets.items['topCenter'] && menuOffsets.items['top'] > selectOffsets.items['bottom'])) {
- thisSelect.hideList.removeItem(in_menuObj.id);
- if (!thisSelect.hideList.length) {
- thisSelect.style.visibility = 'visible';
- }
- }
- else {
- thisSelect.hideList.setItem(in_menuObj.id, true);
- thisSelect.style.visibility = 'hidden';
- }
- }
- }
-}
-
-// }}}
-// {{{ domMenu_getOffsets()
-
-function domMenu_getOffsets(in_object)
-{
- var originalObject = in_object;
- var originalWidth = in_object.offsetWidth;
- var originalHeight = in_object.offsetHeight;
- var offsetLeft = 0;
- var offsetTop = 0;
-
- while (in_object) {
- offsetLeft += in_object.offsetLeft;
- offsetTop += in_object.offsetTop;
- in_object = in_object.offsetParent;
- }
-
- return new domMenu_Hash(
- 'left', offsetLeft,
- 'top', offsetTop,
- 'right', offsetLeft + originalWidth,
- 'bottom', offsetTop + originalHeight,
- 'leftCenter', offsetLeft + originalWidth/2,
- 'topCenter', offsetTop + originalHeight/2,
- 'radius', Math.max(originalWidth, originalHeight)
- );
-}
-
-// }}}
-// {{{ domMenu_callTimeout()
-
-function domMenu_callTimeout(in_function, in_timeout, in_args, in_basename, in_type)
-{
- if (in_timeout == 0) {
- var tmp_function = new Function('argv', in_function);
- tmp_function(in_args);
- }
- else if (in_timeout > 0) {
- // after we complete the timeout call, we want to remove the reference, so always add that
- var tmp_function = new Function('argv', in_function + ' domMenu_timeouts[' + domMenu_quote(in_type) + '].removeItem(' + domMenu_quote(in_basename) + ');');
-
- var tmp_args = new Array();
- for (var i = 0; i < in_args.length; i++) {
- tmp_args[i] = in_args[i];
- }
-
- if (!domMenu_isKonq && !domMenu_isIE50) {
- domMenu_timeouts[in_type].setItem(in_basename, setTimeout(function() { tmp_function(tmp_args); }, in_timeout));
- }
- else {
- var tmp_data = new Array();
- tmp_data['function'] = tmp_function;
- tmp_data['args'] = tmp_args;
- domMenu_timeoutStates[in_type].setItem(in_basename, tmp_data);
- var tmp_type = domMenu_quote(in_type);
- var tmp_basename = domMenu_quote(in_basename);
-
- domMenu_timeouts[in_type].setItem(in_basename, setTimeout('domMenu_timeoutStates[' + tmp_type + '].items[' + tmp_basename + '][' + domMenu_quote('function') + '](domMenu_timeoutStates[' + tmp_type + '].items[' + tmp_basename + '][' + domMenu_quote('args') + ']); domMenu_timeoutStates[' + tmp_type + '].removeItem(' + tmp_basename + ');', in_timeout));
- }
- }
-}
-
-// }}}
-// {{{ domMenu_cancelTimeout()
-
-function domMenu_cancelTimeout(in_basename, in_type)
-{
- // take advantage of browsers which use the anonymous function
- if (!domMenu_isKonq && !domMenu_isIE50) {
- clearTimeout(domMenu_timeouts[in_type].removeItem(in_basename));
- }
- else {
- // if konqueror, we only want to clearTimeout if it is still running
- if (domMenu_timeoutStates[in_type].hasItem(in_basename)) {
- clearTimeout(domMenu_timeouts[in_type].removeItem(in_basename));
- domMenu_timeoutStates[in_type].removeItem(in_basename);
- }
- }
-}
-
-// }}}
-// {{{ domMenu_correctEdgeBleed()
-
-function domMenu_correctEdgeBleed(in_width, in_height, in_x, in_y, in_padding, in_axis)
-{
- if (domMenu_isIE && !domMenu_isIE5) {
- var pageHeight = document.documentElement.clientHeight;
- }
- else if (!domMenu_isKonq) {
- var pageHeight = document.body.clientHeight;
- }
- else {
- var pageHeight = window.innerHeight;
- }
-
- var pageYOffset = domMenu_isIE ? document.body.scrollTop : window.pageYOffset;
- var pageXOffset = domMenu_isIE ? document.body.scrollLeft : window.pageXOffset;
-
-
- if (in_axis == 'horizontal') {
- var bleedRight = (in_x - pageXOffset) + in_width - (document.body.clientWidth - in_padding);
- var bleedLeft = (in_x - pageXOffset) - in_padding;
-
- // we are bleeding off the right, move menu to stay on page
- if (bleedRight > 0) {
- in_x -= bleedRight;
- }
-
- // we are bleeding to the left, move menu over to stay on page
- // we don't want an 'else if' here, because if it doesn't fit we will bleed off the right
- if (bleedLeft < 0) {
- in_x += bleedLeft;
- }
- }
- else {
- var bleedTop = (in_y - pageYOffset) - in_padding;
- var bleedBottom = (in_y - pageYOffset) + in_height - (pageHeight - in_padding);
-
- // if we are bleeding off the bottom, move menu to stay on page
- if (bleedBottom > 0) {
- in_y -= bleedBottom;
- }
-
- // if we are bleeding off the top, move menu down
- // we don't want an 'else if' here, because if we just can't fit it, bleed off the bottom
- if (bleedTop < 0) {
- in_y += bleedTop;
- }
- }
-
- return new Array(in_x, in_y);
-}
-
-// }}}
-// {{{ domMenu_toggleSubMenu()
-
-function domMenu_toggleSubMenu(in_parentElement, in_style)
-{
- var subMenu = in_parentElement.data.items['subMenu'];
- if (subMenu && subMenu.style.visibility != in_style) {
- var settings = domMenu_settings.items[in_parentElement.data.items['basename']];
- var prefix = in_parentElement.data.items['level'] == 1 ? 'menu' : 'subMenu';
- var className = settings.items[prefix + 'ElementClass'];
- // :BUG: this is a problem if submenus click to open, then it won't
- // have the right class when you click to close
- if (in_style == 'visible') {
- className += ' ' + settings.items[prefix + 'Element' + (in_style == 'visible' ? 'Active' : 'Hover') + 'Class'];
- }
-
- in_parentElement.firstChild.className = className;
-
- // position our submenu
- if (in_style == 'visible') {
- var tmp_offsets = domMenu_getOffsets(in_parentElement);
- if (in_parentElement.data.items['level'] == 1) {
- tmp_offsets.items['top'] += settings.items['verticalSubMenuOffsetY'];
- tmp_offsets.items['bottom'] += settings.items['verticalSubMenuOffsetY'];
- tmp_offsets.items['left'] += settings.items['verticalSubMenuOffsetX'];
- tmp_offsets.items['right'] += settings.items['verticalSubMenuOffsetX'];
- }
-
- // reposition if there was a change in the parent position/size
- if (!in_parentElement.data.items['offsets'].compare(tmp_offsets)) {
- in_parentElement.data.items['offsets'] = tmp_offsets;
-
- if (settings.items['axis'] == 'horizontal' && in_parentElement.data.items['level'] == 1) {
- var xCoor = tmp_offsets.items['left'];
- if (settings.items['verticalExpand'] == 'north') {
- var yCoor = tmp_offsets.items['top'] - subMenu.offsetHeight - settings.items['verticalSubMenuOffsetY'];
- }
- else {
- var yCoor = tmp_offsets.items['bottom'];
- }
- }
- else {
- var xCoor = tmp_offsets.items['right'] + settings.items['horizontalSubMenuOffsetX'];
- var yCoor = tmp_offsets.items['top'] + settings.items['horizontalSubMenuOffsetY'];
- }
-
- var minWidth = settings.items['subMenuMinWidth'];
- var renderedWidth = subMenu.offsetWidth;
- if (minWidth == 'inherit') {
- minWidth = in_parentElement.offsetWidth + settings.items['subMenuWidthCorrection'];
- }
- else if (minWidth == 'auto') {
- minWidth = renderedWidth;
- }
-
- if (domMenu_isKonq) {
- // change with width of the first cell
- subMenu.firstChild.firstChild.firstChild.firstChild.style.width = Math.max(minWidth, renderedWidth) + 'px';
- }
- else {
- // change the width of the table
- subMenu.firstChild.style.width = Math.max(minWidth, renderedWidth) + 'px';
- }
-
- var coordinates = domMenu_correctEdgeBleed(subMenu.offsetWidth, subMenu.offsetHeight, xCoor, yCoor, settings.items['screenPadding'], settings.items['axis']);
- subMenu.style.left = coordinates[0] + 'px';
- subMenu.style.top = coordinates[1] + 'px';
-
- // ** if we inherit, it is necessary to check the parent element width again **
- if (settings.items['axis'] == 'horizontal' && settings.items['subMenuMinWidth'] == 'inherit') {
- subMenu.firstChild.style.width = Math.max(in_parentElement.offsetWidth + settings.items['subMenuWidthCorrection'], renderedWidth) + 'px';
- }
- }
- }
-
- // force konqueror to change the styles
- if (domMenu_isKonq) {
- in_parentElement.firstChild.style.display = 'none';
- in_parentElement.firstChild.style.display = '';
- }
-
- subMenu.style.visibility = in_style;
- domMenu_detectCollisions(subMenu, (in_style == 'hidden'));
- }
-}
-
-// }}}
-// {{{ domMenu_toggleHighlight()
-
-function domMenu_toggleHighlight(in_element, in_status)
-{
- // if this is a heading, don't change the style
- if (!in_element.data.items['numChildren'] && !in_element.data.items['uri']) {
- return;
- }
-
- var settings = domMenu_settings.items[in_element.data.items['basename']];
- var prefix = in_element.data.items['level'] == 1 ? 'menu' : 'subMenu';
- var className = settings.items[prefix + 'ElementClass'];
- var highlightElement = in_element.firstChild;
-
- var pseudoClass;
- if (in_status) {
- if (in_element.data.hasItem('subMenu') && in_element.data.items['subMenu'].style.visibility == 'visible') {
- pseudoClass = 'Active';
- }
- else if (in_element.data.items['numChildren'] || in_element.data.items['uri']) {
- pseudoClass = 'Hover';
- }
- }
-
- if (pseudoClass) {
- className += ' ' + settings.items[prefix + 'Element' + pseudoClass + 'Class'];
- // if we are changing to hover, change the alt contents (only change if needs it)
- if (highlightElement.childNodes.length == 2 && highlightElement.lastChild.style.display == 'none') {
- highlightElement.firstChild.style.display = 'none';
- highlightElement.lastChild.style.display = '';
- }
- }
- else {
- // if we are changing to non-hover, change the alt contents (only change if needs it)
- if (highlightElement.childNodes.length == 2 && highlightElement.firstChild.style.display == 'none') {
- highlightElement.lastChild.style.display = 'none';
- highlightElement.firstChild.style.display = '';
- }
- }
-
- highlightElement.className = className;
-
- // force konqueror to change the styles
- if (domMenu_isKonq) {
- highlightElement.style.display = 'none';
- highlightElement.style.display = '';
- }
-}
-
-// }}}
-// {{{ domMenu_resolveLink()
-
-function domMenu_resolveLink(in_this, in_event)
-{
- var eventObj = domMenu_isIE ? event : in_event;
- var currentTarget = domMenu_isIE ? in_this : eventObj.currentTarget;
- var basename = currentTarget.data.items['basename'];
-
- // close the menu system immediately when we resolve the uri
- domMenu_changeActivePath(false, domMenu_activeElement.items[basename], 0);
-
- if (currentTarget.data.items['uri']) {
- window.status = 'Resolving Link...';
-
- // open in current window
- if (!currentTarget.data.items['target'] || currentTarget.data.items['target'] == '_self') {
- window.location = currentTarget.data.items['uri'];
- }
- // open in new window
- else {
- window.open(currentTarget.data.items['uri'], currentTarget.data.items['target']);
- }
- }
-}
-
-// }}}
-// {{{ domMenu_quote()
-
-function domMenu_quote(in_string)
-{
- return "'" + in_string.replace(new RegExp("'", 'g'), "\\'") + "'";
-}
-
-// }}}