]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/commitdiff
Endlich neues Webinterface
authorms <ms@ea5c0bd1-69bd-2848-81d8-4f18e57aeed8>
Wed, 22 Feb 2006 19:52:10 +0000 (19:52 +0000)
committerms <ms@ea5c0bd1-69bd-2848-81d8-4f18e57aeed8>
Wed, 22 Feb 2006 19:52:10 +0000 (19:52 +0000)
git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@69 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8

config/cfgroot/header.pl
html/html/include/content.css [new file with mode: 0644]
html/html/include/domMenu.js [deleted file]
html/html/include/ipcop.css [deleted file]
html/html/include/menu.css [new file with mode: 0644]
html/html/include/selectbox.js [new file with mode: 0644]
html/html/include/style.css [new file with mode: 0644]

index b16a98c8891757aad8ed31e8143ce84da3bb16f7..353e8c07b3acceae008d144051280d3d6525d66a 100644 (file)
-# 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 "&nbsp;"; }
-       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/&/&amp;/g;
-       $outstring =~ s/\'/&#039;/g;
-       $outstring =~ s/\"/&quot;/g;
-       $outstring =~ s/</&lt;/g;
-       $outstring =~ s/>/&gt;/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'>&nbsp;$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 "&nbsp;"; }\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/&/&amp;/g;\r
+       $outstring =~ s/\'/&#039;/g;\r
+       $outstring =~ s/\"/&quot;/g;\r
+       $outstring =~ s/</&lt;/g;\r
+       $outstring =~ s/>/&gt;/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'>&nbsp;$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
diff --git a/html/html/include/content.css b/html/html/include/content.css
new file mode 100644 (file)
index 0000000..81bc293
--- /dev/null
@@ -0,0 +1,48 @@
+table.list {\r
+       width: 100%;\r
+       margin: 0;\r
+       margin-top: 5px;\r
+       border: 1px solid #ccc;\r
+       padding: 10px;\r
+}\r
+\r
+table tr.header {\r
+       background-image: url(../images/table-header.gif);\r
+       background-repeat: no-repeat;\r
+       background-color: #e6e6e6;\r
+}\r
+\r
+table.list tr.header td {\r
+       font-size: 10px;\r
+       padding: 4px;\r
+       margin: 0;\r
+       font-weight: bold;\r
+       border-bottom: 1px solid #ccc;          \r
+}\r
+\r
+table.list tr.odd {\r
+       background: #fff;\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+table.list tr.even {\r
+       background: #eeeced;\r
+       padding: 4px;\r
+       margin: 0;\r
+}\r
+\r
+table.list tr td {\r
+       padding: 4px;\r
+       margin: 0;\r
+}\r
+\r
+#page-content a {\r
+    text-decoration: underling;\r
+    color: #ca232b;\r
+}\r
+\r
+#page-content a:hover {\r
+       text-decoration: underline;\r
+       color: #000000;\r
+}\r
diff --git a/html/html/include/domMenu.js b/html/html/include/domMenu.js
deleted file mode 100644 (file)
index 7ce4dbd..0000000
+++ /dev/null
@@ -1,1167 +0,0 @@
-// {{{ 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'), "\\'") + "'";
-}
-
-// }}}
diff --git a/html/html/include/ipcop.css b/html/html/include/ipcop.css
deleted file mode 100644 (file)
index 699a21c..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-body {
-    margin: 0px;
-    padding: 0px;
-    background: url(/images/header.png) no-repeat;
-    background-color: #D7D8E8;
-    color: #000000;
-    font-family: Verdana, Tahoma, Arial, Sans-serif;
-    font-size: 11px;
-}
-
-td {
-    font-size: 11px;
-}
-
-img {
-    border: 0;
-    border-width : 0; 
-    border-style : none; 
-    border-color : inherit; 
-}
-
-pre {
-    font-size: 12px;
-}
-
-a {
-    color: #000000;
-}
-
-form {
-    margin: 0;
-    padding: 0;
-}
-
-td.ipcop_menuLocationMain {
-    color: #FFFFFF;
-    font-family: Verdana, Tahoma, Arial, Sans-serif;
-    font-size: 16px;
-    font-weight: bold;
-    font-variant: small-caps;
-}
-
-td.ipcop_menuLocationSub {
-    color: #FFFFFF;
-    font-family: Verdana, Tahoma, Arial, Sans-serif;
-    font-size: 11px;
-    font-weight: bold;
-    font-variant: small-caps;
-}
-
-td.ipcop_Version {
-    color: #10044A;
-    font-size: 10px;
-    font-weight: bold;
-}
-
-/* Dommenu */
-.ipcop_menuElementTD {
-    border: 0;
-    color: #DEDFEF;
-    font-size: 11px;
-    font-weight: bold;
-    text-decoration: none;
-    width: 90px;
-    padding: 0px 0px 5px 0px;
-    margin: 0px 10px 0px 10px;
-}
-
-.ipcop_menuElementNoJS {
-    color: #DEDFEF;
-    font-size: 11px;
-    font-weight: bold;
-    text-decoration: none;
-    padding: 0px 0px 5px 0px;
-    margin: 0px 10px 0px 10px;
-}
-
-div.ipcop_menuBar {
-    margin-bottom: 1px;
-}
-
-div.ipcop_subMenuBar {
-    border: 0;
-    background-color: #6B69AD;
-}
-
-div.ipcop_menuElement, div.ipcop_subMenuElement {
-    border: 0;
-    color: #DEDFEF;
-    font-variant: small-caps;
-    font-size: 11px;
-    font-weight: bold;
-}
-
-div.ipcop_menuElement {
-    width: 70px;
-    margin: 4px 10px 4px 10px;
-}
-
-div.ipcop_menuElementHover {
-    color: #FFFFFF;
-}
-
-div.ipcop_subMenuElement {
-    padding: 3px;
-    color: #DEDFEF;
-}
-div.ipcop_subMenuElementHover {
-    padding: 3px;
-    color: #FFFFFF;
-}
-
-/* Connection Status */
-span.ipcop_StatusBig {
-    font-weight: bold;
-    font-size: 14px;
-}
-
-span.ipcop_StatusBigRed {
-    color: #FF0000;
-    font-weight: bold;
-}
diff --git a/html/html/include/menu.css b/html/html/include/menu.css
new file mode 100644 (file)
index 0000000..e9953c7
--- /dev/null
@@ -0,0 +1,192 @@
+#menu-top {\r
+       margin-left: 205px;\r
+       font-family: verdana, arial, sans-serif;        \r
+       font-size: xx-small;\r
+    /* false value for WinIE4/5 */\r
+    voice-family: "\"}\"";   \r
+    /* trick WinIE4/5 into thinking rule is over */\r
+    voice-family: inherit;   \r
+    /* recover from trick */\r
+    /* intended value for better browsers */\r
+       font-weight: bold;\r
+       padding: 0;\r
+}\r
+\r
+#menu-top ul {\r
+       list-style: none;\r
+       padding: 0;\r
+       margin: 0;\r
+/*     background-color: #000;*/       \r
+}\r
+\r
+#menu-top ul li {\r
+       float: left;\r
+       background-image: url(../images/menu_top_left.gif);\r
+       background-position: top left;\r
+       background-repeat: no-repeat;   \r
+       height: 22px;\r
+       padding: 0;\r
+       margin: 0; \r
+       margin-right: 7px;\r
+}\r
+\r
+#menu-top ul li a {\r
+       color: #fff;\r
+       text-decoration: none;\r
+       line-height: 22px;\r
+       padding-left: 7px;\r
+       padding-right: 7px;     \r
+       display: run-in;\r
+}\r
+\r
+#menu-top ul li div.rcorner {\r
+       float: left;\r
+       background-image: url(../images/menu_top_right.gif);    \r
+       background-position: top right;\r
+       background-repeat: no-repeat;\r
+       padding-left: 7px;\r
+       padding-right: 7px;\r
+}\r
+\r
+#menu-top ul li.selected div.rcorner {\r
+       float: left;\r
+       background-image: url(../images/menu_top_right_selected.gif);   \r
+       background-position: top right;\r
+       background-repeat: no-repeat;\r
+       padding-left: 7px;      \r
+       padding-right: 7px;     \r
+}\r
+       \r
+\r
+#menu-top ul li.selected {\r
+       background-image: url(../images/menu_top_left_selected.gif);\r
+}\r
+\r
+\r
+#menu-left {   /* for ie55  */\r
+       width: 160px;\r
+       background-color: #f2f2f2;\r
+       background-image: url(../images/menu_left_top.gif);\r
+       background-position: top right;\r
+       background-repeat: no-repeat;\r
+       font-family: verdana, arial, sans-serif;\r
+       font-size: xx-small;    \r
+    /* false value for WinIE4/5 */\r
+    voice-family: "\"}\"";   \r
+    /* trick WinIE4/5 into thinking rule is over */\r
+    voice-family: inherit;   \r
+    /* recover from trick */\r
+    \r
+    /* intended value for better browsers */\r
+       font-weight: bold;\r
+       padding: 0;\r
+       margin-left: 15px;\r
+}\r
+\r
+#menu-left ul\r
+{\r
+       background-image: url(../images/menu_left_bottom.gif);\r
+       background-position: bottom left;\r
+       background-repeat: no-repeat;\r
+       list-style: none;\r
+       padding: 7px 0 7px 0;\r
+       margin: 0;\r
+/*     background-color: #000;*/\r
+}\r
+\r
+       \r
+#menu-left ul ul {\r
+       background: none;\r
+       /* background-color: #c1c1c1; */\r
+       background-color: #ccc;\r
+       margin: 0;\r
+       padding: 0;\r
+       border-top: 1px solid #ccc;\r
+}\r
+       \r
+#menu-left ul li {\r
+       margin: 0;\r
+       border-bottom: 1px solid #ccc;\r
+       border-left: 1px solid #ccc;\r
+       border-right: 1px solid #ccc;\r
+       padding-left: 15px;\r
+}\r
+       \r
+#menu-left ul li:last-child {\r
+       border-bottom: 1px solid #f2f2f2;\r
+}\r
+\r
+#menu-left ul li.selected {\r
+       background-position: top left;\r
+       background: url(../images/menu_left_selected.gif);\r
+       background-color: #ca232b;      \r
+       border-top: 1px solid #222;     \r
+       border-bottom: 1px solid #222;\r
+       border-left: 1px solid #222;\r
+       border-right: 1px solid #222;\r
+}\r
+\r
+#menu-left ul li.selected span {\r
+       display: none;\r
+}\r
+       \r
+#menu-left ul li a {\r
+       width: 100%;\r
+       color: #555;\r
+       text-decoration: none;\r
+       padding: 3px 5px 3px 0px;\r
+       line-height: 20px; \r
+       margin: 0;\r
+}\r
+\r
+#menu-left ul li.selected a {\r
+       color: #fff;\r
+       text-decoration: none;\r
+       padding: 3px 5px 3px 0px;\r
+       margin: 0;\r
+}\r
+       \r
+#menu-left ul ul li.selected {\r
+       background: #6c6c6c;\r
+}\r
+\r
+#menu-subtop ul {\r
+       background: none;\r
+        background-image: url(../images/heading-back.gif);\r
+       background-position: bottom left;\r
+       background-repeat: no-repeat;\r
+       list-style: none;\r
+        border-right: 1px solid #ccc;\r
+       padding-left: 30px;\r
+        font-size: 10px;\r
+        font-weight: bold;\r
+        color: #656565;\r
+        margin: 0;\r
+       margin-bottom: 15px;\r
+        line-height: 20px;\r
+        display: block;\r
+       width: inherit;\r
+       height: 20px;\r
+}\r
+\r
+#menu-subtop ul li {\r
+       margin: 0;\r
+       float: left;\r
+       padding-right: 15px;\r
+}\r
+\r
+#menu-subtop ul li a {\r
+        text-decoration: underline;\r
+       font-weight: normal;\r
+}      \r
+\r
+#menu-subtop ul li.selected {\r
+       float: left;\r
+       padding-right: 15px;\r
+}\r
+\r
+#menu-subtop ul li.selected a {\r
+        text-decoration: none;\r
+       font-weight: bold;\r
+        color: #555555;\r
+}
\ No newline at end of file
diff --git a/html/html/include/selectbox.js b/html/html/include/selectbox.js
new file mode 100644 (file)
index 0000000..d57ffdf
--- /dev/null
@@ -0,0 +1,61 @@
+// ===================================================================\r
+// Author: Matt Kruse <matt@mattkruse.com>\r
+// WWW: http://www.mattkruse.com/\r
+//\r
+// NOTICE: You may use this code for any purpose, commercial or\r
+// private, without any further permission from the author. You may\r
+// remove this notice from your final code if you wish, however it is\r
+// appreciated by the author if at least my web site address is kept.\r
+//\r
+// You may *NOT* re-distribute this code in any way except through its\r
+// use. That means, you can include it in your product, or your web\r
+// site, or any other form where the code is actually being used. You\r
+// may not put the plain javascript up on your site for download or\r
+// include it in your javascript libraries for download. \r
+// If you wish to share this code with others, please just point them\r
+// to the URL instead.\r
+// Please DO NOT link directly to my .js files from your site. Copy\r
+// the files to your server and use them there. Thank you.\r
+// ===================================================================\r
+\r
+/* SOURCE FILE: selectbox.js */\r
+function hasOptions(obj){if(obj!=null && obj.options!=null){return true;}return false;}\r
+function selectUnselectMatchingOptions(obj,regex,which,only){if(window.RegExp){if(which == "select"){var selected1=true;var selected2=false;}else if(which == "unselect"){var selected1=false;var selected2=true;}else{return;}var re = new RegExp(regex);if(!hasOptions(obj)){return;}for(var i=0;i<obj.options.length;i++){if(re.test(obj.options[i].text)){obj.options[i].selected = selected1;}else{if(only == true){obj.options[i].selected = selected2;}}}}}\r
+function selectMatchingOptions(obj,regex){selectUnselectMatchingOptions(obj,regex,"select",false);}\r
+function selectOnlyMatchingOptions(obj,regex){selectUnselectMatchingOptions(obj,regex,"select",true);}\r
+function unSelectMatchingOptions(obj,regex){selectUnselectMatchingOptions(obj,regex,"unselect",false);}\r
+function sortSelect(obj){var o = new Array();if(!hasOptions(obj)){return;}for(var i=0;i<obj.options.length;i++){o[o.length] = new Option( obj.options[i].text, obj.options[i].value, obj.options[i].defaultSelected, obj.options[i].selected) ;}if(o.length==0){return;}o = o.sort(\r
+function(a,b){if((a.text+"") <(b.text+"")){return -1;}if((a.text+"") >(b.text+"")){return 1;}return 0;});for(var i=0;i<o.length;i++){obj.options[i] = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);}}\r
+function selectAllOptions(obj){if(!hasOptions(obj)){return;}for(var i=0;i<obj.options.length;i++){obj.options[i].selected = true;}}\r
+function moveSelectedOptions(from,to){if(arguments.length>3){var regex = arguments[3];if(regex != ""){unSelectMatchingOptions(from,regex);}}if(!hasOptions(from)){return;}for(var i=0;i<from.options.length;i++){var o = from.options[i];if(o.selected){if(!hasOptions(to)){var index = 0;}else{var index=to.options.length;}to.options[index] = new Option( o.text, o.value, false, false);}}for(var i=(from.options.length-1);i>=0;i--){var o = from.options[i];if(o.selected){from.options[i] = null;}}if((arguments.length<3) ||(arguments[2]==true)){sortSelect(from);sortSelect(to);}from.selectedIndex = -1;to.selectedIndex = -1;}\r
+function copySelectedOptions(from,to){var options = new Object();if(hasOptions(to)){for(var i=0;i<to.options.length;i++){options[to.options[i].value] = to.options[i].text;}}if(!hasOptions(from)){return;}for(var i=0;i<from.options.length;i++){var o = from.options[i];if(o.selected){if(options[o.value] == null || options[o.value] == "undefined" || options[o.value]!=o.text){if(!hasOptions(to)){var index = 0;}else{var index=to.options.length;}to.options[index] = new Option( o.text, o.value, false, false);}}}if((arguments.length<3) ||(arguments[2]==true)){sortSelect(to);}from.selectedIndex = -1;to.selectedIndex = -1;}\r
+function moveAllOptions(from,to){selectAllOptions(from);if(arguments.length==2){moveSelectedOptions(from,to);}else if(arguments.length==3){moveSelectedOptions(from,to,arguments[2]);}else if(arguments.length==4){moveSelectedOptions(from,to,arguments[2],arguments[3]);}}\r
+function copyAllOptions(from,to){selectAllOptions(from);if(arguments.length==2){copySelectedOptions(from,to);}else if(arguments.length==3){copySelectedOptions(from,to,arguments[2]);}}\r
+function swapOptions(obj,i,j){var o = obj.options;var i_selected = o[i].selected;var j_selected = o[j].selected;var temp = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);var temp2= new Option(o[j].text, o[j].value, o[j].defaultSelected, o[j].selected);o[i] = temp2;o[j] = temp;o[i].selected = j_selected;o[j].selected = i_selected;}\r
+function moveOptionUp(obj){if(!hasOptions(obj)){return;}for(i=0;i<obj.options.length;i++){if(obj.options[i].selected){if(i != 0 && !obj.options[i-1].selected){swapOptions(obj,i,i-1);obj.options[i-1].selected = true;}}}}\r
+function moveOptionDown(obj){if(!hasOptions(obj)){return;}for(i=obj.options.length-1;i>=0;i--){if(obj.options[i].selected){if(i !=(obj.options.length-1) && ! obj.options[i+1].selected){swapOptions(obj,i,i+1);obj.options[i+1].selected = true;}}}}\r
+function removeSelectedOptions(from){if(!hasOptions(from)){return;}for(var i=(from.options.length-1);i>=0;i--){var o=from.options[i];if(o.selected){from.options[i] = null;}}from.selectedIndex = -1;}\r
+function removeAllOptions(from){if(!hasOptions(from)){return;}for(var i=(from.options.length-1);i>=0;i--){from.options[i] = null;}from.selectedIndex = -1;}\r
+function addOption(obj,text,value,selected){if(obj!=null && obj.options!=null){obj.options[obj.options.length] = new Option(text, value, false, selected);}}\r
+\r
+\r
+/* SOURCE FILE: OptionTransfer.js */\r
+\r
+function OT_transferLeft(){moveSelectedOptions(this.right,this.left,this.autoSort,this.staticOptionRegex);this.update();}\r
+function OT_transferRight(){moveSelectedOptions(this.left,this.right,this.autoSort,this.staticOptionRegex);this.update();}\r
+function OT_transferAllLeft(){moveAllOptions(this.right,this.left,this.autoSort,this.staticOptionRegex);this.update();}\r
+function OT_transferAllRight(){moveAllOptions(this.left,this.right,this.autoSort,this.staticOptionRegex);this.update();}\r
+function OT_saveRemovedLeftOptions(f){this.removedLeftField = f;}\r
+function OT_saveRemovedRightOptions(f){this.removedRightField = f;}\r
+function OT_saveAddedLeftOptions(f){this.addedLeftField = f;}\r
+function OT_saveAddedRightOptions(f){this.addedRightField = f;}\r
+function OT_saveNewLeftOptions(f){this.newLeftField = f;}\r
+function OT_saveNewRightOptions(f){this.newRightField = f;}\r
+function OT_update(){var removedLeft = new Object();var removedRight = new Object();var addedLeft = new Object();var addedRight = new Object();var newLeft = new Object();var newRight = new Object();for(var i=0;i<this.left.options.length;i++){var o=this.left.options[i];newLeft[o.value]=1;if(typeof(this.originalLeftValues[o.value])=="undefined"){addedLeft[o.value]=1;removedRight[o.value]=1;}}for(var i=0;i<this.right.options.length;i++){var o=this.right.options[i];newRight[o.value]=1;if(typeof(this.originalRightValues[o.value])=="undefined"){addedRight[o.value]=1;removedLeft[o.value]=1;}}if(this.removedLeftField!=null){this.removedLeftField.value = OT_join(removedLeft,this.delimiter);}if(this.removedRightField!=null){this.removedRightField.value = OT_join(removedRight,this.delimiter);}if(this.addedLeftField!=null){this.addedLeftField.value = OT_join(addedLeft,this.delimiter);}if(this.addedRightField!=null){this.addedRightField.value = OT_join(addedRight,this.delimiter);}if(this.newLeftField!=null){this.newLeftField.value = OT_join(newLeft,this.delimiter);}if(this.newRightField!=null){this.newRightField.value = OT_join(newRight,this.delimiter);}}\r
+function OT_join(o,delimiter){var val;var str="";for(val in o){if(str.length>0){str=str+delimiter;}str=str+val;}return str;}\r
+function OT_setDelimiter(val){this.delimiter=val;}\r
+function OT_setAutoSort(val){this.autoSort=val;}\r
+function OT_setStaticOptionRegex(val){this.staticOptionRegex=val;}\r
+function OT_init(theform){this.form = theform;if(!theform[this.left]){alert("OptionTransfer init(): Left select list does not exist in form!");return false;}if(!theform[this.right]){alert("OptionTransfer init(): Right select list does not exist in form!");return false;}this.left=theform[this.left];this.right=theform[this.right];for(var i=0;i<this.left.options.length;i++){this.originalLeftValues[this.left.options[i].value]=1;}for(var i=0;i<this.right.options.length;i++){this.originalRightValues[this.right.options[i].value]=1;}if(this.removedLeftField!=null){this.removedLeftField=theform[this.removedLeftField];}if(this.removedRightField!=null){this.removedRightField=theform[this.removedRightField];}if(this.addedLeftField!=null){this.addedLeftField=theform[this.addedLeftField];}if(this.addedRightField!=null){this.addedRightField=theform[this.addedRightField];}if(this.newLeftField!=null){this.newLeftField=theform[this.newLeftField];}if(this.newRightField!=null){this.newRightField=theform[this.newRightField];}this.update();}\r
+function OptionTransfer(l,r){this.form = null;this.left=l;this.right=r;this.autoSort=true;this.delimiter=",";this.staticOptionRegex = "";this.originalLeftValues = new Object();this.originalRightValues = new Object();this.removedLeftField = null;this.removedRightField = null;this.addedLeftField = null;this.addedRightField = null;this.newLeftField = null;this.newRightField = null;this.transferLeft=OT_transferLeft;this.transferRight=OT_transferRight;this.transferAllLeft=OT_transferAllLeft;this.transferAllRight=OT_transferAllRight;this.saveRemovedLeftOptions=OT_saveRemovedLeftOptions;this.saveRemovedRightOptions=OT_saveRemovedRightOptions;this.saveAddedLeftOptions=OT_saveAddedLeftOptions;this.saveAddedRightOptions=OT_saveAddedRightOptions;this.saveNewLeftOptions=OT_saveNewLeftOptions;this.saveNewRightOptions=OT_saveNewRightOptions;this.setDelimiter=OT_setDelimiter;this.setAutoSort=OT_setAutoSort;this.setStaticOptionRegex=OT_setStaticOptionRegex;this.init=OT_init;this.update=OT_update;}\r
+\r
diff --git a/html/html/include/style.css b/html/html/include/style.css
new file mode 100644 (file)
index 0000000..49393e7
--- /dev/null
@@ -0,0 +1,103 @@
+/* Stylesheet for endian firewall */\r
+/* Author: Raphael Vallazza */\r
+\r
+/* body */\r
+\r
+body {\r
+       margin: 0px;\r
+       padding: 0px;\r
+       padding-top: 3px;\r
+       background-color: #FFFFFF;\r
+       background-image: url(../images/background.gif);\r
+       font-family: tahoma,verdana,arial,sans-serif;\r
+       background-repeat: repeat-x;\r
+       font-size: 11px;\r
+       color: #444;\r
+       min-width: 760px;\r
+}\r
+\r
+h1, h2 {\r
+       font-size: 16px;\r
+       font-weight: bold;\r
+       color: #ca232a;\r
+       padding: 0;\r
+       margin: 0;\r
+       margin-bottom: 10px;\r
+}\r
+\r
+h3 {\r
+       width: inherit;\r
+       background: url(../images/heading-back.gif);\r
+       background-repeat: no-repeat;\r
+       border-right: 1px solid #ccc;\r
+       font-size: 10px;\r
+       font-weight: bold;\r
+       color: #656565;\r
+       margin: 0;\r
+       padding-left: 30px;\r
+       line-height: 20px;\r
+       display: block;\r
+}\r
+\r
+h4, h5 {\r
+       font-size: 12px;\r
+       font-weight: bold;\r
+       color: #ca232a;\r
+}\r
+\r
+#placeholder {\r
+       width: 760px;\r
+       height: 1px;\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+/* main content box */\r
+#header {\r
+       width: 100%;\r
+       height: 74px;\r
+       margin: 0;\r
+       padding: 0;\r
+       display: block;\r
+}\r
+\r
+#logo-product {\r
+       padding-top: 17px;\r
+       padding-left: 40px;\r
+       margin: 0;\r
+       float: left;\r
+}\r
+\r
+#logo-ipfire {\r
+       padding-top: 10px;\r
+       padding-right: 50px;\r
+       margin: 0;\r
+       float: right;\r
+}\r
+\r
+#header-icons {\r
+       padding-top: 27px;\r
+       padding-right: 30px;\r
+       margin: 0;\r
+       float: right;\r
+}\r
+\r
+#content {\r
+       width: 100%;\r
+       margin-top: 50px;\r
+}\r
+\r
+#page-content {\r
+       margin-left: 20px;\r
+}\r
+\r
+select, input, textarea {\r
+       font-family: sans-serif;\r
+       font-size: 100%;\r
+}\r
+\r
+form {\r
+    margin: 0;\r
+    padding: 0;\r
+}\r
+\r