--- /dev/null
+Mini Asterisk GUI Version 2
+===========================
+
+Rewrite of original concept using Javascript.
+
+TODO
+----
+
+[ ] fping ipkg dependancy
+[ ] blog post
+ + javascript with firebox is a joy to debug
+ + cf server side, CGIs
+ + keep CGIs really small, very productive
+ + BASIC style string processing versus regexp
+
--- /dev/null
+#!/bin/sh
+# asterisk.cgi
+# David Rowe 22 Dec 2010
+#
+# CGI to return the output from an Asterisk command line
+
+cat <<EOF
+Content-type: text/html
+
+<html>
+<head>
+<meta http-equiv="cache-control" content="no-cache">
+<meta http-equiv="pragma" content="no-cache">
+<meta http-equiv="expires" content="-1">
+</head>
+<body>
+EOF
+
+CLI=`echo "$QUERY_STRING" | sed -n "s/.*cli=//p" | sed -n "s/%20/ /pg"`
+asterisk -rx "$CLI"
+echo hello
+cat <<EOF
+</body>
+</html>
+EOF
--- /dev/null
+#!/bin/sh
+# fpingnodes.cgi
+# David Rowe 5 Dec 2010
+#
+# CGI to fping a bunch of nodes
+
+cat <<EOF
+Content-type: text/html
+
+<html>
+<head>
+<meta http-equiv="cache-control" content="no-cache">
+<meta http-equiv="pragma" content="no-cache">
+<meta http-equiv="expires" content="-1"></head></head>
+<body>
+EOF
+
+ip=`echo "$QUERY_STRING" | sed -n "s/.*ip=//p" | sed "s/,/ /g"`
+fping $ip -a -b1400 -r1 2>/dev/null
+
+cat <<EOF
+</body>
+</html>
+EOF
--- /dev/null
+#!/bin/sh
+# getconf.cgi
+# David Rowe 12 Dec 2010
+#
+# CGI to return an Asterisk conf file
+
+cat <<EOF
+Content-type: text/html
+
+<html>
+<head>
+<meta http-equiv="cache-control" content="no-cache">
+<meta http-equiv="pragma" content="no-cache">
+<meta http-equiv="expires" content="-1">
+</head>
+<body>
+EOF
+
+CONF_PATH=/etc/asterisk
+FILE=`echo "$QUERY_STRING" | sed -n "s/.*file=//p"`
+if [ -f $CONF_PATH/$FILE ] ; then
+ cat $CONF_PATH/$FILE
+fi
+
+cat <<EOF
+</body>
+</html>
+EOF
--- /dev/null
+#!/bin/sh
+# asterisk.cgi
+# David Rowe 3 March 2011
+#
+# CGI to return the output from an Asterisk command line
+
+cat <<EOF
+Content-type: text/html
+
+<html>
+<head>
+<meta http-equiv="cache-control" content="no-cache">
+<meta http-equiv="pragma" content="no-cache">
+<meta http-equiv="expires" content="-1">
+</head>
+<body>
+EOF
+
+arg=`echo "$QUERY_STRING" | sed -n "s/.*arg=//p"`
+ifconfig $arg
+cat <<EOF
+</body>
+</html>
+EOF
--- /dev/null
+#!/bin/sh
+# setline.cgi
+# David Rowe 12 Dec 2010
+#
+# CGI to set the text on a particular line
+
+cat <<EOF
+Content-type: text/html
+
+<html>
+<head>
+<meta http-equiv="cache-control" content="no-cache">
+<meta http-equiv="pragma" content="no-cache">
+<meta http-equiv="expires" content="-1"></head></head>
+<body>
+EOF
+
+LINE=`echo "$QUERY_STRING" | sed -n "s/.*line=//p"`
+echo $LINE
+
+cat <<EOF
+</body>
+</html>
+EOF
--- /dev/null
+#!/usr/bin/speedy -w
+# -*-perl-*-
+
+use lib qw(/usr/share/perl5/smokeping);
+use CGI::Carp qw(fatalsToBrowser);
+
+use Smokeping 2.003006;
+
+Smokeping::cgi("/etc/smokeping/config");
+
+=head1 NAME
+
+smokeping.cgi - SmokePing webfrontend
+
+=head1 OVERVIEW
+
+This script acts as a 'website' for your SmokePing monitoring operation. It
+presents the targets you are looking at in a tree structure and draws graphs
+as they are required by people looking at the pages.
+
+=head1 DESCRIPTION
+
+To get B<smokeping.cgi> going, you need a webserver which allows you to run
+cgi scripts. The system must be setup so that the B<smokeping.cgi> is
+allowed to write to the image caching area as defined in the config file.
+
+This script runs with normal perl. B<BUT> it will appear to be very slow,
+because it does a lot of things when starting up. So if the script has to be
+started a fresh on every click, this is both slow and a tough thing for your
+webserver. I therefore strongly recomment using SpeedyCGI.
+
+Please refer to the installation document for detailed setup instructions.
+
+=head1 SETUP
+
+When installing SmokePing, this file has to be adjusted to fit your
+local system. Three paths have to be entered.
+
+ use lib qw(/usr/pack/rrdtool-1.0.33-to/lib/perl);
+
+One pointing to your B<rrdtool> installation
+
+ use lib qw(/home/oetiker/public_html/smokeping/lib);
+
+One pointing to the place where you have installed the SmokePing libraries
+
+ use Smokeping;
+
+ Smokeping::cgi("/home/oetiker/.smokeping/config");
+
+The third path is the argument to the Smokeping::cgi command. It points to
+the SmokePing configuration file.
+
+=head1 COPYRIGHT
+
+Copyright (c) 2001 by Tobias Oetiker. All right reserved.
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more
+details.
+
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free
+Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+02139, USA.
+
+=head1 AUTHOR
+
+Tobias Oetiker E<lt>tobi@oetiker.chE<gt>
+
+=cut
--- /dev/null
+/*
+ menu.js
+ David Rowe
+ Jan 4 2010
+
+ Function(s) to create main menu. Interesting to compare this to static HTML.
+*/
+
+var menuItems = [
+ '<a href="phones.sh">Phone System</a>',
+ '<a href="about.sh">About</a>',
+ '<a href="admin.sh">Admin</a>',
+ '<a href="faq.sh">FAQ</a>',
+ '<a href="ipphones.sh">IP Phones</a>',
+ '<a href="logout.sh">Logout</a>',
+ '<a href="network.sh">Network</a>',
+ '<a href="voiplines.sh">VOIP Line</a>'
+];
+
+var menuTips = [
+ 'phones_tip',
+ 'about_tip',
+ 'admin_tip',
+ 'faq_tip',
+ 'ipphones_tip',
+ 'logout_tip',
+ 'network_tip',
+ 'voipline_tip'
+];
+
+var menuToolTips = [
+ '<div id="phones_tip" class="tip">Lists your phones and phone lines</div>',
+ '<div id="about_tip" class="tip">Boring information like software version numbers</div>',
+ '<div id="admin_tip" class="tip">Change your password, reset the default settings, upgrade software</div>',
+ '<div id="faq_tip" class="tip">Frequently asked questions and links to further information</div>',
+ '<div id="ipphones_tip" class="tip">Set up your IP phones</div>',
+ '<div id="logout_tip" class="tip">I think you can work this one out....</div>',
+ '<div id="network_tip" class="tip">Connect the phone system to your network and the Internet</div>',
+ '<div id="voipline_tip" class="tip">Set up your VOIP phone line</div>'
+];
+
+function mainMenu() {
+ var html = '';
+
+ for(var i=0; i<menuToolTips.length; i++) {
+ html += menuToolTips[i] + "\n";
+ }
+
+ html += '<td valign="top" >';
+ html += '<table align="right" width=200>';
+ html += '<tr><td><h2> </h2></td></tr>';
+
+ for(var i=0; i<menuItems.length; i++) {
+ var tooltip = 'onMouseOver="popUp(event,' + "'" + menuTips[i] + "'" + ')" ';
+ tooltip += 'onMouseOut="popUp(event,' + "'" + menuTips[i] + "'" + ')"';
+
+ html += '<tr ' + tooltip + '><td>' + menuItems[i] + '</td></tr>' + "\n";
+ }
+
+ html += '</table>';
+
+ document.getElementById('menu').innerHTML = html;
+}
--- /dev/null
+/*
+ minicommon.js
+ David Rowe
+ Dec 16 2010
+
+ Common functions used by Mini Asterisk GUI.
+*/
+
+// index Zaptel port number (1,2,...), value extension (6001,6002...)
+
+var analog_ext = [];
+
+// zaptel port number (1,2,...), value FXS/FXO
+
+var zap = [];
+
+// all IP extensions, index ext, value true|false to indicate if live
+
+var ip_ext = [];
+
+function loadExtensions() {
+
+ /*
+ Kick off cascading CGIs and callbacks to load analog and ip
+ extension data.
+
+ From extensions.conf and zaptel.conf, determine which zap ports
+ are live and what type they are (FXS or FXO).
+
+ From extensions.conf determine, asterisk -r sip show peers
+ to determine which sip extenions are live
+
+ That will do for now......
+ */
+
+ downloadUrl("/cgi-bin/getconf.cgi?file=../zaptel.conf", loadZapata);
+}
+
+// remove leading and trailing whitespace from a string
+
+function trim(stringToTrim) {
+ return stringToTrim.replace(/^\s+|\s+$/g,"");
+}
+
+
+/*
+ Given extenions.conf lines like this:
+
+ exten => 6011,1,Dial(SIP/6011)
+ exten => 6001,1,Dial(Zap/1)
+ exten => EXT,1,Dial(TECH1/TECH2)
+
+ returns EXT, TECH1, TECH2
+*/
+
+function parseDialPlan(line) {
+ var split1 = line.split(",");
+ var split2 = split1[0].split("=>");
+ var ext = trim(split2[1]);
+ var tech = split1[2];
+ var index1 = tech.indexOf('(');
+ var index2 = tech.indexOf('/');
+ var index3 = tech.indexOf(')');
+
+ var tech1 = tech.substr(index1+1, index2-index1-1);
+ var tech2 = tech.substr(index2+1, index3-index2-1);
+
+ return [ext,tech1,tech2];
+}
+
+
+// called to process /etc/zapata.conf
+// creates an associative array of active Zap ports
+
+function loadZapata(doc,status) {
+ loadHtmlTextFile(
+ doc,
+ function(line) {
+
+ if (line.indexOf('fxoks') != -1) {
+ var split1 = line.split("=");
+ var ports = split1[1].split(",");
+ for(var i=0; i<ports.length; i++) {
+ port = trim(ports[i]);
+ zap[port] = 'FXS';
+ }
+ }
+
+ if (line.indexOf('fxsks') != -1) {
+ var split1 = line.split("=");
+ var ports = split1[1].split(",");
+ for(var i=0; i<ports.length; i++) {
+ port = trim(ports[i]);
+ zap[port] = 'FXO';
+ }
+ }
+
+ }
+ );
+
+ // now we can load extensions.conf
+
+ downloadUrl("/cgi-bin/getconf.cgi?file=extensions.conf", loadExtensionsConf);
+}
+
+// called to process extensions.conf
+// creates an associative array of analog and ip extensions
+
+function loadExtensionsConf(doc,status) {
+ loadHtmlTextFile(doc, function(line) {
+ if ((line.indexOf("exten =>") != -1) &&
+ (line.indexOf("mini_ext") != -1)) {
+ var ret = parseDialPlan(line);
+ var ext = ret[0];
+ var tech1 = ret[1];
+ var tech2 = ret[2];
+ if (tech1 == "Zap") {
+ if (zap[tech2] == undefined)
+ analog_ext[tech2] = "";
+ else
+ analog_ext[tech2] = ext;
+ }
+ if (tech1 == "SIP") {
+ ip_ext[ext] = "";
+ }
+ }
+ }
+ );
+
+ // we get ip extensions from "sip show peer" at asterisk CLI
+
+ downloadUrl("/cgi-bin/asterisk.cgi?cli=sip show peers", loadIpExtensions);
+}
+
+
+function parseSipShowPeers(line) {
+ var myregexp = /\s+/;
+ var s = line.split(myregexp);
+ var ext = s[0].substr(0,4);
+ var ip = s[1];
+ if (ip_ext[ext] != undefined) {
+ if (line.indexOf("OK") != -1)
+ ip_ext[ext] = ip;
+ }
+}
+
+// called to process asterisk CLI "sip show peers"
+// creates an associative array of IP extensions
+
+function loadIpExtensions(doc,status) {
+ loadHtmlTextFile(doc, function(line) {
+ parseSipShowPeers(line);
+ }
+ );
+
+ initialisePage();
+}
+
+
+// Load a html encoded text file, strips off the HTML tags
+// and calls textLineProcessing() for every line
+
+function loadHtmlTextFile(doc, textLineProcessing) {
+
+ var lines = doc.split("\n");
+ var state = "looking for body";
+ var next_state;
+
+ for (var j in lines) {
+ next_state = state;
+ if (state == "looking for body") {
+ if (lines[j].indexOf('<body>') != -1)
+ next_state = "body";
+ }
+ if (state == "body") {
+ if (lines[j].indexOf('</body>') != -1)
+ next_state = "finished";
+ else {
+ // main processing of text here
+ textLineProcessing(lines[j]);
+ }
+ }
+ state = next_state;
+ }
+}
+
+
+/**
+ * Returns an XMLHttp instance to use for asynchronous
+ * downloading. This method will never throw an exception, but will
+ * return NULL if the browser does not support XmlHttp for any reason.
+ * @return {XMLHttpRequest|Null}
+ */
+
+function createXmlHttpRequest() {
+ try {
+ if (typeof ActiveXObject != 'undefined') {
+ return new ActiveXObject('Microsoft.XMLHTTP');
+ } else if (window["XMLHttpRequest"]) {
+ return new XMLHttpRequest();
+ }
+ } catch (e) {
+ changeStatus(e);
+ }
+ return null;
+};
+
+
+/**
+ * This functions wraps XMLHttpRequest open/send function.
+ * It lets you specify a URL and will call the callback if
+ * it gets a status code of 200.
+ * @param {String} url The URL to retrieve
+ * @param {Function} callback The function to call once retrieved.
+ */
+function downloadUrl(url, callback) {
+ var status = -1;
+ var request = createXmlHttpRequest();
+ if (!request) {
+ return false;
+ }
+
+ request.onreadystatechange = function() {
+ if (request.readyState == 4) {
+ try {
+ status = request.status;
+ } catch (e) {
+ // Usually indicates request timed out in FF.
+ }
+ if (status == 200) {
+ callback(request.responseText, request.status);
+ request.onreadystatechange = function() {};
+ }
+ }
+ }
+ request.open('GET', url, true);
+ try {
+ request.send(null);
+ } catch (e) {
+ changeStatus(e);
+ }
+};
--- /dev/null
+html,body{
+ margin:0;
+ padding:0;
+ width:100%;
+ height:100%;
+ font-family:Arial, Helvetica, sans-serif;
+}
+
+div#header{
+ vertical-align:middle;
+ border-bottom:1px solid #000;
+}
+div#main-map{
+ width:70%;
+ height:100%;
+ float:left;
+}
+div#side{
+ width:30%;
+ float:left;
+}
+
+div#dataPanel{
+ width:90%;
+ height:50%;
+ overflow:auto;
+ border:2px solid #DDDDDD;
+}
+input{
+ width:90%;
+}
+
+input.navi{
+ font-size:12px;
+ height:30px;
+ margin-bottom:10px;
+}
+div ul{
+ margin-top:30px;
+ margin-bottom:30px;
+}
+div ul li{
+ display: inline;
+ list-style-type: none;
+ padding-right: 40px;
+ font-size:18px;
+ font-weight:bold;
+}
+
+div ul li.title{
+ font-size:22px;
+ color:#888;
+}
+
+div#header p{
+ color:#888;
+ font-size:14px;
+ padding-left:20px;
+}
+span.instruction{
+ font-weight:bold;
+
+}
+
+.message-box { text-align: center; padding: 5px; color:#545454; width:80%; margin:5px auto; font-size:12px;}
+.clean { background-color: #efefef; border-top: 2px solid #dedede; border-bottom: 2px solid #dedede; }
+.info { background-color: #f7fafd; border-top: 2px solid #b5d3ff; border-bottom: 2px solid #b5d3ff; }
+.ok { background-color: #d7f7c4; border-top: 2px solid #82cb2f; border-bottom: 2px solid #82cb2f; }
+.alert { background-color: #fef5be; border-top: 2px solid #fdd425; border-bottom: 2px solid #fdd425; }
+.error { background-color: #ffcdd1; border-top: 2px solid #e10c0c; border-bottom: 2px solid #e10c0c; }
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+<title>Mini Asterisk - Phones</title>
+
+<link rel="stylesheet" type="text/css" href="ministyle.css">
+<link rel="stylesheet" href="tooltip.css" type="text/css" />
+<script type="text/javascript" src="minicommon.js"></script>
+<script type="text/javascript" src="tooltip.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript" src="network.js"></script>
+<script type="text/javascript">
+
+</script>
+
+</head>
+
+<body onload="initialise()">
+
+ <table align="center" width=800>
+ <tr>
+ <td><div id="menu"></div></td>
+ <td valign="top">
+
+ <form action="set_network.sh" onsubmit="return validate_form(this)" method="get">
+ <table align="center" width=600 border=0>
+ <tr><td colspan="2" align="left" valign="top"><h2>Network</h2></td></tr>
+ <tr>
+ <td><input type="radio" id="static" name="dhcp" value="no" onClick="doStatic()">Static</td>
+ <td><input type="radio" id="dhcp" name="dhcp" value="yes" onClick="doDHCP()">DHCP</td>
+ </tr>
+ <tr><td>IP Address:</td><td><input type="text" name="ipaddress" id="ipaddress" onBlur="isIP(this)"></td></tr>
+ <tr><td>Netmask:</td><td><input type="text" name="netmask" id="netmask" onBlur="isIP(this)"></td></tr>
+ <tr><td>Gateway:</td><td><input type="text" name="gateway" id="gateway" onBlur="isIP(this)"></td></tr>
+ <tr><td>DNS:</td><td><input type="text" name="dns" id="dns" onBlur="isIP(this)"></td></tr>
+ <tr onMouseOver="popUp(event,'network_backdoor')" onmouseout="popUp(event,'network_backdoor')">
+ <td>Emergency IP:</td><td><input type="text" name="backdoor" id="backdoor" onBlur="isIP(this)"></td>
+ </tr>
+ <tr onMouseOver="popUp(event,'network_internet')" onmouseout="popUp(event,'network_internet')">
+ <td>Internet Connection:</td>
+ <td><div id="internet" >
+ <span style="margin-left: 4px;font-weight:bold"> </span></div></td>
+ </tr>
+ <tr><td><input id="networkapply" type="submit" value="Apply"></td></tr>
+ </table>
+ </form>
+
+ </tr>
+
+ </table>
+</body>
+</html>
--- /dev/null
+/*
+ network.js
+ David Rowe
+ March 7 2011
+
+ Network screen for Mini Asterisk GUI.
+*/
+
+var dhcp;
+
+// Called when we load page
+
+function initialise() {
+ mainMenu();
+
+ // kick off cascading CGIs, initialisePage() will be called when complete
+
+ // determine if DHCP or static
+
+ downloadUrl("/cgi-bin/getdhcp.cgi", processDhcp);
+}
+
+
+// called when DHCP CGI returns
+
+function processDhcp(doc,status) {
+ dhcp = "no";
+
+ loadHtmlTextFile(doc, function(line) {
+ parseNetwork(line);
+ }
+ );
+
+ if (dhcp == "no") {
+ downloadUrl("/cgi-bin/getdhcpconf.cgi?file=../init.d/network-static", processDhcp);
+ }
+ else {
+ // grey out fields
+ initilaisePage();
+ }
+}
+
+
+// called when static IP CGI returns
+
+function processStatic(doc,status) {
+ loadHtmlTextFile(doc, function(line) {
+ parseNetwork(line);
+ }
+ );
+
+ initialisePage();
+}
+
+
+function parseNetwork(line) {
+
+ if (line.indexOf("DHCP=") != -1) {
+ var s = line.split('"');
+ dhcp = "yes";
+ }
+
+ if (line.indexOf("IPADDRESS=") != -1) {
+ var s = line.split('"');
+ var ip = s(2);
+ document.getElementById('ip').innerHTML = ip;
+ }
+
+ if (line.indexOf("NETMASK=") != -1) {
+ var s = line.split('"');
+ var netmask = s(2);
+ document.getElementById('netmask').innerHTML = netmask;
+ }
+
+ if (line.indexOf("GATEWAY=") != -1) {
+ var s = line.split('"');
+ var gateway = s(2);
+ document.getElementById('gateway').innerHTML = gateway;
+ }
+
+ if (line.indexOf("DNS=") != -1) {
+ var s = line.split('"');
+ var dns = s(2);
+ document.getElementById('dns').innerHTML = dns;
+ }
+
+}
+
+
+// http://moblog.bradleyit.com/2009/06/javascript-ip-address-validation.html
+
+function isIP(obj) {
+ var ary = obj.value.split(".");
+ var ip = true;
+
+ ip = (ary.length == 4);
+
+ if (ip) {
+ for (var i=0; i<4; i++) {
+ ip = (!ary[i].match(/^\d{1,3}$/) || (Number(ary[i]) > 255)) ? false : ip;
+ }
+ }
+
+ if (!ip) {
+ // the value is NOT a valid IP address
+ obj.style.background = "red";
+ obj.select();
+ }
+ else { obj.style.background = ""; } // the value IS a valid IP address
+
+ return ip;
+}
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+<title>Mini Asterisk - Phones</title>
+
+<link rel="stylesheet" type="text/css" href="ministyle.css">
+<link rel="stylesheet" href="tooltip.css" type="text/css" />
+<script type="text/javascript" src="minicommon.js"></script>
+<script type="text/javascript" src="tooltip.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript" src="phones.js"></script>
+<script type="text/javascript">
+
+</script>
+
+</head>
+
+<body onload="initialise()">
+
+ <table align="center" width=800>
+ <tr>
+ <td><div id="menu"></div></td>
+ <td><div id="phones_table"></div></td>
+ </tr>
+
+ </table>
+</body>
+</html>
--- /dev/null
+/*
+ phones.js
+ David Rowe
+ Dec 12 2010
+
+ Phones screen for Mini Asterisk GUI.
+*/
+
+var update_time = 10;
+
+
+// Called when we load page
+
+function initialise() {
+ mainMenu();
+
+ // kick off cascading CGIs, initialisePage() will be called when complete
+
+ loadExtensions();
+}
+
+
+function initialisePage() {
+ // construct list of phone extensions
+
+ var icon = '<img src="tick.png" alt="Analog Phone OK" />';
+ var html = '';
+
+ html += '<table align="right" width=600>';
+
+ // print out internet connection
+
+ html += '<tr><td colspan="3" align="left" valign="top"><h2>Phone System</h2></td></tr>';
+ html += '<tr><td colspan="2">Internet Connection:</td><td><div id="internet"></div></td></tr>';
+ html += '<tr><td colspan="2">Phone System IP Address:</td><td div id="ipaddress"></div></td></tr>';
+ html += '<tr><td> </td></tr>';
+
+ // print out analog phones
+
+ html += '<tr><td colspan="4" align="left" valign="top"><h2>Phones</h2></td></tr>';
+ for(var i=0; i<zap.length; i++) {
+ if (zap[i] == 'FXS') {
+ html += "<tr><td>" + analog_ext[i] + "</td>" + "<td>" + "Analog Phone" + "</td>";
+ html += "<td>Port" + i + "</td></tr>";
+ }
+ }
+
+ // print out IP phones
+
+ for (j in ip_ext) {
+ if (ip_ext[j] != '') {
+ html += "<tr><td>" + j + "</td>" + "<td>" + "IP Phone" + "</td>";
+ html += "<td>" + ip_ext[j] + "</td></tr>";
+ }
+ }
+
+ // print out phone lines
+
+ html += '<tr><td colspan="4" align="left" valign="top"><h2>Phone Lines</h2></td></tr>';
+ for(var i=0; i<zap.length; i++) {
+ if (zap[i] == 'FXO') {
+ html += "<tr><td>" + "0" + "</td>" + "<td>" + "Analog Phone" + "</td>";
+ html += "<td>Port" + i + "</td></tr>";
+ }
+ }
+
+ html += '</table>';
+
+ document.getElementById("phones_table").innerHTML += html;
+
+ // fire off fping CGI
+
+ downloadUrl("/cgi-bin/fpingnodes.cgi?ip=google.com", processFping);
+
+ // fire off Ifconfig IP address to get IP Address
+
+ downloadUrl("/cgi-bin/ifconfig.cgi?arg=wlan0", processIfconfig);
+}
+
+
+// called when Fping CGI returns
+
+function processFping(doc, status) {
+
+ // Change icon based on ping results
+
+ var icon;
+
+ if (doc.indexOf("google.com") != -1)
+ icon = '<img src="tick.png" />';
+ else
+ icon = '<img src="cross.png" />';
+
+ document.getElementById('internet').innerHTML = icon;
+}
+
+// called when ifconfig CGI returns
+
+function processIfconfig(doc, status) {
+
+ var ip="";
+
+ if (doc.indexOf("inet addr:") != -1) {
+ ip = doc.substr(doc.indexOf("inet addr:"), doc.length);
+ ip = ip.substr(10, ip.length);
+ ip = ip.substr(0, ip.indexOf(" "));
+ }
+
+ document.getElementById('ipaddress').innerHTML = ip;
+}
--- /dev/null
+.tip {font:14px/16px
+Arial,Helvetica,sans-serif; border:solid 1px
+#666666; width:270px; padding:1px;
+position:absolute; z-index:100;
+visibility:hidden; color:#333333; top:20px;
+left:90px; background-color:#ffffcc;
+layer-background-color:#ffffcc;}
--- /dev/null
+// Extended Tooltip Javascript
+// copyright 9th August 2002, 3rd July 2005, 24th August 2008
+// by Stephen Chapman, Felgall Pty Ltd
+
+// permission is granted to use this javascript provided that the below code is not altered
+function pw() {return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth}; function mouseX(evt) {return evt.clientX ? evt.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) : evt.pageX;} function mouseY(evt) {return evt.clientY ? evt.clientY + (document.documentElement.scrollTop || document.body.scrollTop) : evt.pageY} function popUp(evt,oi) {if (document.getElementById) {var wp = pw(); dm = document.getElementById(oi); ds = dm.style; st = ds.visibility; if (dm.offsetWidth) ew = dm.offsetWidth; else if (dm.clip.width) ew = dm.clip.width; if (st == "visible" || st == "show") { ds.visibility = "hidden"; } else {tv = mouseY(evt) + 20; lv = mouseX(evt) - (ew/4); if (lv < 2) lv = 2; else if (lv + ew > wp) lv -= ew/2; lv += 'px';tv += 'px'; ds.left = lv; ds.top = tv; ds.visibility = "visible";}}}
+