Merge branch 'menu'

This commit is contained in:
Steven Barth 2008-05-22 14:04:03 +00:00
parent f738eb786e
commit 6604399aa8
55 changed files with 627 additions and 541 deletions

View file

@ -0,0 +1,2 @@
include ../../build/config.mk
include ../../build/module.mk

View file

@ -0,0 +1,16 @@
#!/bin/sh
uci batch <<-EOF
set freifunk.community.name='Freifunk Halle'
set freifunk.community.homepage=http://halle.freifunk.net
set freifunk.community.essid=halle.freifunk.net
set freifunk.community.bssid=02:CA:FF:EE:BA:BE
set freifunk.community.realm=pool.freifunk-halle.net
set freifunk.community.channel=1
set freifunk.community.net=104.0.0.0
set freifunk.community.mask=255.0.0.0
set freifunk.community.dhcp=10.0.0.0
set freifunk.community.dhcpmask=255.255.255.0
set freifunk.community.dns='88.198.178.18 141.54.1.1 212.204.49.83 208.67.220.220 208.67.222.222'
commit freifunk
EOF

View file

@ -0,0 +1,18 @@
module("ffluci.controller.luci_fw.luci_fw", package.seeall)
function index()
local page = node("admin", "network", "portfw")
page.target = cbi("luci_fw/portfw")
page.title = "Portweiterleitung"
page.order = 70
local page = node("admin", "network", "routing")
page.target = cbi("luci_fw/routing")
page.title = "Routing"
page.order = 72
local page = node("admin", "network", "firewall")
page.target = cbi("luci_fw/firewall")
page.title = "Firewall"
page.order = 74
end

View file

@ -1,4 +0,0 @@
sel("admin", "network")
act("portfw", "Portweiterleitung")
act("routing", "Routing")
act("firewall", "Firewall")

View file

@ -1,5 +1,16 @@
module("ffluci.controller.splash.splash", package.seeall) module("ffluci.controller.splash.splash", package.seeall)
function index()
local page = node("admin", "services", "splash")
page.target = cbi("splash/splash")
page.title = "Client-Splash"
node("splash", "splash", "activate").target = action_activate
node("splash", "splash", "allowed").target = action_allowed
node("splash", "splash", "unknown").target = action_unknown
node("splash", "splash", "splash").target = template("splash_splash/splash")
end
function action_activate() function action_activate()
local mac = ffluci.sys.net.ip4mac(ffluci.http.env.REMOTE_ADDR) local mac = ffluci.sys.net.ip4mac(ffluci.http.env.REMOTE_ADDR)
if mac and ffluci.http.formvalue("accept") then if mac and ffluci.http.formvalue("accept") then
@ -10,7 +21,7 @@ function action_activate()
end end
end end
function action_accepted() function action_allowed()
ffluci.http.redirect(ffluci.dispatcher.build_url()) ffluci.http.redirect(ffluci.dispatcher.build_url())
end end

View file

@ -1,2 +0,0 @@
sel("admin", "services")
act("splash", "Client-Splash")

View file

@ -1,4 +1,3 @@
#!/usr/bin/haserl --shell=luac #!/usr/bin/haserl --shell=luac
package.path = "/usr/lib/lua/?.lua;/usr/lib/lua/?/init.lua;" .. package.path require("ffluci.dispatcher").createindex()
package.cpath = "/usr/lib/lua/?.so;" .. package.cpath ffluci.dispatcher.httpdispatch()
require("ffluci.dispatcher").httpdispatch()

View file

@ -1,11 +1,9 @@
package.path = "/usr/lib/lua/?.lua;/usr/lib/lua/?/init.lua;" .. package.path
package.cpath = "/usr/lib/lua/?.so;" .. package.cpath
module("webuci", package.seeall) module("webuci", package.seeall)
function prepare_req(uri) function prepare_req(uri)
env = {} env = {}
env.REQUEST_URI = uri env.REQUEST_URI = uri
require("ffluci.menu").get() require("ffluci.dispatcher").createindex()
end end
function init_req(context) function init_req(context)
@ -19,5 +17,5 @@ function init_req(context)
end end
function handle_req(context) function handle_req(context)
require("ffluci.dispatcher").httpdispatch() ffluci.dispatcher.httpdispatch()
end end

View file

@ -1,3 +1,3 @@
LUAC = luac LUAC = luac
LUAC_OPTIONS = -s LUAC_OPTIONS = -s
LUCI_INSTALLDIR = /usr/lib/lua/ffluci LUCI_INSTALLDIR = /usr/lib/lua/5.1/ffluci

View file

@ -5,7 +5,7 @@ PKG_SOURCE_URL:=https://dev.leipzig.freifunk.net/svn/ff-luci/$(PKG_BRANCH)
PKG_REV:=$(shell LC_ALL=C svn info ${PKG_SOURCE_URL} | sed -ne's/^Last Changed Rev: //p') PKG_REV:=$(shell LC_ALL=C svn info ${PKG_SOURCE_URL} | sed -ne's/^Last Changed Rev: //p')
PKG_NAME:=ffluci PKG_NAME:=ffluci
PKG_VERSION:=0.4+svn$(PKG_REV) PKG_VERSION:=0.5+svn$(PKG_REV)
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)

View file

@ -1,15 +1,36 @@
--- b/src/luaconf.h 2008-05-06 20:10:46.000000000 +0200 diff -ur lua-5.1.3/etc/lua.pc lua-5.1.3-new/etc/lua.pc
+++ a/src/luaconf.h 2008-05-06 20:10:27.000000000 +0200 --- lua-5.1.3/etc/lua.pc 2008-01-11 14:12:59.000000000 +0100
@@ -95,9 +95,9 @@ +++ lua-5.1.3-new/etc/lua.pc 2008-05-18 22:09:24.000000000 +0200
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" @@ -8,7 +8,7 @@
R= 5.1.3
# grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/'
-prefix= /usr/local
+prefix= /usr
INSTALL_BIN= ${prefix}/bin
INSTALL_INC= ${prefix}/include
INSTALL_LIB= ${prefix}/lib
diff -ur lua-5.1.3/Makefile lua-5.1.3-new/Makefile
--- lua-5.1.3/Makefile 2008-05-18 22:06:55.000000000 +0200
+++ lua-5.1.3-new/Makefile 2008-05-18 22:09:13.000000000 +0200
@@ -12,7 +12,7 @@
# doc directory.) You may want to make these paths consistent with LUA_ROOT,
# LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/lua.pc).
#
-INSTALL_TOP= /usr/local
+INSTALL_TOP= /usr
INSTALL_BIN= $(INSTALL_TOP)/bin
INSTALL_INC= $(INSTALL_TOP)/include
INSTALL_LIB= $(INSTALL_TOP)/lib
diff -ur lua-5.1.3/src/luaconf.h lua-5.1.3-new/src/luaconf.h
--- lua-5.1.3/src/luaconf.h 2008-05-18 22:07:11.000000000 +0200
+++ lua-5.1.3-new/src/luaconf.h 2008-05-18 22:09:50.000000000 +0200
@@ -95,7 +95,7 @@
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
#else #else
-#define LUA_ROOT "/usr/local/" -#define LUA_ROOT "/usr/local/"
-#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_ROOT "/usr/"
-#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" #define LUA_LDIR LUA_ROOT "share/lua/5.1/"
+#define LUA_ROOT "/usr/" #define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
+#define LUA_LDIR LUA_ROOT "share/lua/"
+#define LUA_CDIR LUA_ROOT "lib/lua/"
#define LUA_PATH_DEFAULT \ #define LUA_PATH_DEFAULT \
"./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"

View file

@ -1,10 +1,9 @@
config core main config core main
option lang de option lang de
option mediaurlbase /ffluci/media option mediaurlbase /ffluci/media
option imagebase /ffluci/images option resourcebase /ffluci/images
option title "Freifunk Kamikaze"
config core category_privileges option subtitle Fledermausedition
option public nobody:nogroup
config extern flash_keep config extern flash_keep
option uci "/etc/config" option uci "/etc/config"

View file

@ -4,63 +4,6 @@ FFLuCI - Dispatcher
Description: Description:
The request dispatcher and module dispatcher generators The request dispatcher and module dispatcher generators
The dispatching process:
For a detailed explanation of the dispatching process we assume:
You have installed the FFLuCI CGI-Dispatcher in /cgi-bin/ffluci
To enforce a higher level of security only the CGI-Dispatcher
resides inside the web server's document root, everything else
stays inside an external directory, we assume this is /lua/ffluci
for this explanation.
All controllers and action are reachable as sub-objects of /cgi-bin/ffluci
as if they were virtual folders and files
e.g.: /cgi-bin/ffluci/public/info/about
/cgi-bin/ffluci/admin/network/interfaces
and so on.
The PATH_INFO variable holds the dispatch path and
will be split into three parts: /category/module/action
Category: This is the category in which modules are stored in
By default there are two categories:
"public" - which is the default public category
"admin" - which is the default protected category
As FFLuCI itself does not implement authentication
you should make sure that "admin" and other sensitive
categories are protected by the webserver.
E.g. for busybox add a line like:
/cgi-bin/ffluci/admin:root:$p$root
to /etc/httpd.conf to protect the "admin" category
Module: This is the controller which will handle the request further
It is always a submodule of ffluci.controller, so a module
called "helloworld" will be stored in
/lua/ffluci/controller/helloworld.lua
You are free to submodule your controllers any further.
Action: This is action that will be invoked after loading the module.
The kind of how the action will be dispatched depends on
the module dispatcher that is defined in the controller.
See the description of the default module dispatcher down
on this page for some examples.
The main dispatcher at first searches for the module by trying to
include ffluci.controller.category.module
(where "category" is the category name and "module" is the module name)
If this fails a 404 status code will be send to the client and FFLuCI exits
Then the main dispatcher calls the module dispatcher
ffluci.controller.category.module.dispatcher with the request object
as the only argument. The module dispatcher is then responsible
for the further dispatching process.
FileId: FileId:
$Id$ $Id$
@ -80,48 +23,24 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
]]-- ]]--
module("ffluci.dispatcher", package.seeall) module("ffluci.dispatcher", package.seeall)
require("ffluci.http") require("ffluci.http")
require("ffluci.template")
require("ffluci.config")
require("ffluci.sys") require("ffluci.sys")
require("ffluci.fs")
-- Sets privilege for given category -- Local dispatch database
function assign_privileges(category) local tree = {nodes={}}
local cp = ffluci.config.category_privileges
if cp and cp[category] then -- Global request object
local u, g = cp[category]:match("([^:]+):([^:]+)") request = {}
ffluci.sys.process.setuser(u)
ffluci.sys.process.setgroup(g) -- Active dispatched node
end dispatched = nil
end
-- Builds a URL from a triple of category, module and action -- Builds a URL
function build_url(category, module, action) function build_url(...)
category = category or "public" return ffluci.http.dispatcher() .. "/" .. table.concat(arg, "/")
module = module or "index"
action = action or "index"
local pattern = ffluci.http.dispatcher() .. "/%s/%s/%s"
return pattern:format(category, module, action)
end
-- Dispatches the "request"
function dispatch(req)
request = req
local m = "ffluci.controller." .. request.category .. "." .. request.module
local stat, module = pcall(require, m)
if not stat then
return error404()
else
module.request = request
module.dispatcher = module.dispatcher or dynamic
setfenv(module.dispatcher, module)
return module.dispatcher(request)
end
end end
-- Sends a 404 error code and renders the "error404" template if available -- Sends a 404 error code and renders the "error404" template if available
@ -129,6 +48,7 @@ function error404(message)
ffluci.http.status(404, "Not Found") ffluci.http.status(404, "Not Found")
message = message or "Not Found" message = message or "Not Found"
require("ffluci.template")
if not pcall(ffluci.template.render, "error404") then if not pcall(ffluci.template.render, "error404") then
ffluci.http.prepare_content("text/plain") ffluci.http.prepare_content("text/plain")
print(message) print(message)
@ -140,6 +60,7 @@ end
function error500(message) function error500(message)
ffluci.http.status(500, "Internal Server Error") ffluci.http.status(500, "Internal Server Error")
require("ffluci.template")
if not pcall(ffluci.template.render, "error500", {message=message}) then if not pcall(ffluci.template.render, "error500", {message=message}) then
ffluci.http.prepare_content("text/plain") ffluci.http.prepare_content("text/plain")
print(message) print(message)
@ -147,154 +68,124 @@ function error500(message)
return false return false
end end
-- Dispatches a request depending on the PATH_INFO variable -- Dispatches a request depending on the PATH_INFO variable
function httpdispatch() function httpdispatch()
local pathinfo = ffluci.http.env.PATH_INFO or "" local pathinfo = ffluci.http.env.PATH_INFO or ""
local parts = pathinfo:gmatch("/[%w-]+") local c = tree
local sanitize = function(s, default) for s in pathinfo:gmatch("/([%w-]+)") do
return s and s:sub(2) or default table.insert(request, s)
end end
local cat = sanitize(parts(), "public") dispatch()
local mod = sanitize(parts(), "index") end
local act = sanitize(parts(), "index")
function dispatch()
local c = tree
local track = {}
assign_privileges(cat) for i, s in ipairs(request) do
dispatch({category=cat, module=mod, action=act}) c = c.nodes[s]
end if not c then
break
end
-- Dispatchers --
for k, v in pairs(c) do
track[k] = v
-- The Action Dispatcher searches the module for any function called end
-- action_"request.action" and calls it
function action(...)
local disp = require("ffluci.dispatcher")
if not disp._action(...) then
disp.error404()
end
end
-- The CBI dispatcher directly parses and renders the CBI map which is
-- placed in ffluci/modles/cbi/"request.module"/"request.action"
function cbi(...)
local disp = require("ffluci.dispatcher")
if not disp._cbi(...) then
disp.error404()
end end
end
-- The dynamic dispatcher chains the action, submodule, simpleview and CBI dispatcher
-- in this particular order. It is the default dispatcher.
function dynamic(...)
local disp = require("ffluci.dispatcher")
if not disp._action(...)
and not disp._submodule(...)
and not disp._simpleview(...)
and not disp._cbi(...) then
disp.error404()
end
end
-- The Simple View Dispatcher directly renders the template
-- which is placed in ffluci/views/"request.module"/"request.action"
function simpleview(...)
local disp = require("ffluci.dispatcher")
if not disp._simpleview(...) then
disp.error404()
end
end
-- The submodule dispatcher tries to load a submodule of the controller
-- and calls its "action"-function
function submodule(...)
local disp = require("ffluci.dispatcher")
if not disp._submodule(...) then
disp.error404()
end
end
-- Internal Dispatcher Functions --
function _action(request)
local action = getfenv(2)["action_" .. request.action:gsub("-", "_")]
local i18n = require("ffluci.i18n")
if action then
i18n.loadc(request.category .. "_" .. request.module) if track.i18n then
i18n.loadc(request.category .. "_" .. request.module .. "_" .. request.action) require("ffluci.i18n").loadc(track.i18n)
action()
return true
else
return false
end end
end
function _cbi(request)
local disp = require("ffluci.dispatcher")
local tmpl = require("ffluci.template")
local cbi = require("ffluci.cbi")
local i18n = require("ffluci.i18n")
local path = request.category.."_"..request.module.."/"..request.action if track.setuser then
ffluci.sys.process.setuser(track.setuser)
end
local stat, map = pcall(cbi.load, path) if track.setgroup then
if stat and map then ffluci.sys.process.setgroup(track.setgroup)
local stat, err = pcall(map.parse, map) end
if c and type(c.target) == "function" then
dispatched = c
stat, err = pcall(c.target)
if not stat then if not stat then
disp.error500(err) error500(err)
end
else
error404()
end
end
-- Calls the index function of all available controllers
function createindex()
local root = ffluci.sys.libpath() .. "/controller/"
local suff = ".lua"
for i,c in ipairs(ffluci.fs.glob(root .. "*/*" .. suff)) do
c = "ffluci.controller." .. c:sub(#root+1, #c-#suff):gsub("/", ".", 1)
stat, mod = pcall(require, c)
if stat and mod and type(mod.index) == "function" then
ffluci.util.updfenv(mod.index, ffluci.dispatcher)
pcall(mod.index)
end
end
end
-- Fetch a dispatching node
function node(...)
local c = tree
for k,v in ipairs(arg) do
if not c.nodes[v] then
c.nodes[v] = {nodes={}}
end
c = c.nodes[v]
end
return c
end
-- Subdispatchers --
function alias(...)
local req = arg
return function()
request = req
dispatch()
end
end
function template(name)
require("ffluci.template")
return function() ffluci.template.render(name) end
end
function cbi(model)
require("ffluci.cbi")
require("ffluci.template")
return function()
local stat, res = pcall(ffluci.cbi.load, model)
if not stat then
error500(res)
return true return true
end end
i18n.loadc(request.category .. "_" .. request.module)
i18n.loadc(request.category .. "_" .. request.module .. "_" .. request.action) local stat, err = pcall(res.parse, res)
tmpl.render("cbi/header") if not stat then
map:render() error500(err)
tmpl.render("cbi/footer") return true
return true end
elseif not stat then
disp.error500(map) ffluci.template.render("cbi/header")
return true res:render()
else ffluci.template.render("cbi/footer")
return false
end end
end
function _simpleview(request)
local i18n = require("ffluci.i18n")
local tmpl = require("ffluci.template")
local path = request.category.."_"..request.module.."/"..request.action
local stat, t = pcall(tmpl.Template, path)
if stat then
i18n.loadc(request.category .. "_" .. request.module)
i18n.loadc(request.category .. "_" .. request.module .. "_" .. request.action)
t:render()
return true
else
return false
end
end
function _submodule(request)
local i18n = require("ffluci.i18n")
local m = "ffluci.controller." .. request.category .. "." ..
request.module .. "." .. request.action
local stat, module = pcall(require, m)
if stat and module.action then
i18n.loadc(request.category .. "_" .. request.module)
i18n.loadc(request.category .. "_" .. request.module .. "_" .. request.action)
return pcall(module.action)
end
return false
end end

View file

@ -10,13 +10,5 @@ apply = "Apply"
changes = "Changes" changes = "Changes"
revert = "Revert" revert = "Revert"
index = "Overview"
system = "System"
services = "Services"
network = "Network"
wifi = "Wifi"
status = "Status"
statistic = "Statistic"
config = "Configuration" config = "Configuration"
path = "Path" path = "Path"

View file

@ -25,5 +25,5 @@ limitations under the License.
]]-- ]]--
module("ffluci", package.seeall) module("ffluci", package.seeall)
__version__ = "0.4" __version__ = "0.5"
__appname__ = "FFLuCI" __appname__ = "FFLuCI"

View file

@ -28,6 +28,7 @@ module("ffluci.menu", package.seeall)
require("ffluci.fs") require("ffluci.fs")
require("ffluci.util") require("ffluci.util")
require("ffluci.sys") require("ffluci.sys")
require("ffluci.dispatcher")
-- Default modelpath -- Default modelpath
modelpattern = ffluci.sys.libpath() .. "/model/menu/*.lua" modelpattern = ffluci.sys.libpath() .. "/model/menu/*.lua"
@ -39,98 +40,7 @@ scope = {
isfile = ffluci.fs.isfile isfile = ffluci.fs.isfile
} }
-- Local menu database
local menu = nil
-- The current pointer
local menuc = {}
-- Adds a menu category to the current menu and selects it
function add(cat, controller, title, order)
order = order or 100
if not menu[cat] then
menu[cat] = {}
end
local entry = {}
entry[".descr"] = title
entry[".order"] = order
entry[".contr"] = controller
menuc = entry
local i = 0
for k,v in ipairs(menu[cat]) do
if v[".order"] > entry[".order"] then
break
end
i = k
end
table.insert(menu[cat], i+1, entry)
return true
end
-- Adds an action to the current menu
function act(action, title)
table.insert(menuc, {action = action, descr = title})
return true
end
-- Selects a menu category
function sel(cat, controller)
if not menu[cat] then
return nil
end
menuc = menu[cat]
local stat = nil
for k,v in ipairs(menuc) do
if v[".contr"] == controller then
menuc = v
stat = true
end
end
return stat
end
-- Collect all menu information provided in the model dir
function collect()
local generators = {}
local m = ffluci.fs.glob(modelpattern) or {}
for k, menu in pairs(m) do
local f = loadfile(menu)
if f then
table.insert(generators, f)
end
end
return generators
end
-- Parse the collected information
function parse(generators)
menu = {}
for i, f in pairs(generators) do
local env = ffluci.util.clone(scope)
env.add = add
env.sel = sel
env.act = act
setfenv(f, env)
f()
end
return menu
end
-- Returns the menu information -- Returns the menu information
function get() function get()
if not menu then
menu = parse(collect())
end
return menu return menu
end end

View file

@ -55,7 +55,7 @@ viewns = {
controller = ffluci.http.dispatcher(), controller = ffluci.http.dispatcher(),
uploadctrl = ffluci.http.dispatcher_upload(), uploadctrl = ffluci.http.dispatcher_upload(),
media = ffluci.config.main.mediaurlbase, media = ffluci.config.main.mediaurlbase,
images = ffluci.config.main.imagebase, resource = ffluci.config.main.resourcebase,
write = io.write, write = io.write,
include = function(name) Template(name):render(getfenv(2)) end, include = function(name) Template(name):render(getfenv(2)) end,
} }

View file

@ -2,6 +2,6 @@
<div class="clear"></div> <div class="clear"></div>
</div></div> </div></div>
<div class="separator magenta bold"><a href="http://luci.freifunk-halle.net">FFLuCI 0.3 - Freifunk Lua Configuration Interface</a></div> <div class="separator magenta bold"><a href="http://luci.freifunk-halle.net"><%=require("ffluci").__appname__ .. " " .. ffluci.__version__%> - Freifunk Lua Configuration Interface</a></div>
</body> </body>
</html> </html>

View file

@ -1,21 +1,33 @@
<% <%
require("ffluci.sys") require("ffluci.sys")
local load1, load5, load15 = ffluci.sys.loadavg() local load1, load5, load15 = ffluci.sys.loadavg()
local req = require("ffluci.dispatcher").request
local menu = require("ffluci.menu").get()[req.category] local request = require("ffluci.dispatcher").request
menu = menu or {} local category = request[1]
local tree = ffluci.dispatcher.node()
local cattree = category and ffluci.dispatcher.node(category)
local node = ffluci.dispatcher.dispatched
local c = tree
for i,r in ipairs(request) do
if c.nodes and c.nodes[r] then
c = c.nodes[r]
c._menu_selected = true
end
end
require("ffluci.i18n").loadc("default") require("ffluci.i18n").loadc("default")
require("ffluci.http").prepare_content("text/html") require("ffluci.http").prepare_content("text/html")
%><?xml version="1.0" encoding="utf-8"?> %><?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<link rel="stylesheet" type="text/css" href="<%=media%>/cascade.css" /> <link rel="stylesheet" type="text/css" href="<%=media%>/cascade.css" />
<link rel="stylesheet" type="text/css" href="<%=media%>/css/<%=req.category%>_<%=req.module%>.css" /> <% if node and node.css then %><link rel="stylesheet" type="text/css" href="<%=resource%>/<%=node.css%>" /><% end %>
<link rel="stylesheet" type="text/css" href="<%=media%>/css/<%=req.category%>_<%=req.module%>_<%=req.action%>.css" />
<meta http-equiv="content-type" content="text/xhtml+xml; charset=utf-8" /> <meta http-equiv="content-type" content="text/xhtml+xml; charset=utf-8" />
<meta http-equiv="content-script-type" content="text/javascript" /> <meta http-equiv="content-script-type" content="text/javascript" />
<title>FFLuCI</title> <title>FFLuCI - Freifunk Lua Configuration Interface</title>
</head> </head>
<body> <body>
<div id="header"> <div id="header">
@ -27,37 +39,82 @@ require("ffluci.http").prepare_content("text/html")
<%:hostname Hostname%>: <%=ffluci.sys.hostname()%> <%:hostname Hostname%>: <%=ffluci.sys.hostname()%>
</div> </div>
<div> <div>
<span class="headertitle">Freifunk Kamikaze</span><br /> <span class="headertitle"><%~luci.main.title%></span><br />
<span class="whitetext bold"><%:batmanedition Fledermausedition%></span> <span class="whitetext bold"><%~luci.main.subtitle%></span>
</div> </div>
</div> </div>
<div class="separator yellow bold"> <div class="separator yellow bold">
<%:path Pfad%>: <a href="<%=controller .. "/" .. req.category%>"><%=translate(req.category, req.category)%></a> <%:path Pfad%>: <%
&#187; <a href="<%=controller .. "/" .. req.category .. "/" .. req.module %>"><%=translate(req.module, req.module)%></a> local c = tree
&#187; <a href="<%=controller .. "/" .. req.category .. "/" .. req.module .. "/" .. req.action %>"><%=translate(req.action, req.action)%></a> local url = controller
for k,v in pairs(request) do
if c.nodes and c.nodes[v] then
c = c.nodes[v]
url = url .. "/" .. v
%><a href="<%=url%>"><%=c.title or v%></a> <% if k ~= #request then %>&#187; <% end
end
end
%>
</div> </div>
<div id="columns"><div id="columnswrapper"> <div id="columns"><div id="columnswrapper">
<div class="sidebar left"> <div class="sidebar left">
<% for k,v in pairs(menu) do %> <%
<div<% if v[".contr"] == req.module then %> class="yellowtext"<% end %>><a href="<%=controller.."/"..req.category.."/"..v[".contr"]%>"><%=translate(v[".contr"], v[".descr"])%></a><% local function submenu(prefix, node)
if v[".contr"] == req.module then %> if not node._menu_selected or not node.nodes then
<ul><% for key,val in ipairs(v) do %> return false
<li<% if val.action == req.action then %> class="yellowtext"<% end %>><a href="<%=controller.."/"..req.category.."/"..req.module.."/"..val.action%>"><%=translate(val.action, val.descr)%></a></li> end
<% end %></ul> local index = {}
<% end %></div> for k, n in pairs(node.nodes) do
table.insert(index, {name=k, order=n.order or 100})
end
table.sort(index, function(a, b) return a.order < b.order end)
%>
<ul>
<% for j, v in pairs(index) do
local nnode = node.nodes[v.name]%>
<li>
<span<% if nnode._menu_selected then %> class="yellowtext"<%end%>><a href="<%=controller .. prefix .. v.name%>"><%=nnode.title%></a></span>
<% submenu(prefix .. v.name .. "/", nnode) %>
</li>
<% end %> <% end %>
</ul>
<%
end
if cattree and cattree.nodes then
local index = {}
for k, node in pairs(cattree.nodes) do
table.insert(index, {name=k, order=node.order or 100})
end
table.sort(index, function(a, b) return a.order < b.order end)
for i, k in ipairs(index) do
node = cattree.nodes[k.name]
if node.title then %>
<div<% if node._menu_selected then %> class="yellowtext"<%end%>><a href="<%=controller%>/<%=category%>/<%=k.name%>"><%=node.title%></a>
<%submenu("/" .. category .. "/" .. k.name .. "/", node)%>
</div>
<% end
end
end
%>
</div> </div>
<div class="sidebar right"> <div class="sidebar right">
<div><%:webif Weboberfläche%> <div><%:webif Weboberfläche%>
<ul> <ul><%
<li<% if "public" == req.category then %> class="yellowtext"<% end %>><a href="<%=controller%>/public"><%:public Öffentlich%></a></li> for k,node in pairs(tree.nodes) do
<li<% if "admin" == req.category then %> class="yellowtext"<% end %>><a href="<%=controller%>/admin"><%:admin Verwaltung%></a></li> if node.title then %>
<li<% if request[1] == k then %> class="yellowtext"<%end%>><a href="<%=controller%>/<%=k%>"><%=node.title%></a></li>
<% end
end%>
</ul> </ul>
</div> </div>
<% <%
if "admin" == req.category then if "admin" == request[1] then
require("ffluci.model.uci") require("ffluci.model.uci")
local ucic = ffluci.model.uci.changes() local ucic = ffluci.model.uci.changes()
if ucic then if ucic then

View file

@ -1 +1,24 @@
module("ffluci.controller.admin.index", package.seeall) module("ffluci.controller.admin.index", package.seeall)
function index()
local root = node()
if not root.target then
root.target = alias("admin")
end
local page = node("admin")
page.target = alias("admin", "index")
page.title = "Administration"
page.order = 10
local page = node("admin", "index")
page.target = template("admin_index/index")
page.title = "Übersicht"
page.order = 10
local page = node("admin", "index", "luci")
page.target = cbi("admin_index/luci")
page.title = "Oberfläche"
end

View file

@ -1 +1,39 @@
module("ffluci.controller.admin.network", package.seeall) module("ffluci.controller.admin.network", package.seeall)
function index()
local page = node("admin", "network")
page.target = template("admin_network/index")
page.title = "Netzwerk"
page.order = 50
local page = node("admin", "network", "vlan")
page.target = cbi("admin_network/vlan")
page.title = "Switch"
page.order = 10
local page = node("admin", "network", "ifaces")
page.target = cbi("admin_network/ifaces")
page.title = "Schnittstellen"
page.order = 20
local page = node("admin", "network", "dhcp")
page.target = cbi("admin_network/dhcp")
page.title = "DHCP-Server"
page.order = 30
local page = node("admin", "network", "ptp")
page.target = cbi("admin_network/ptp")
page.title = "PPPoE / PPTP"
page.order = 40
local page = node("admin", "network", "routes")
page.target = cbi("admin_network/routes")
page.title = "Statische Routen"
page.order = 50
if ffluci.fs.isfile("/etc/config/qos") then
local page = node("admin", "network", "qos")
page.target = cbi("admin_network/qos")
page.title = "Quality of Service"
end
end

View file

@ -1 +1,29 @@
module("ffluci.controller.admin.services", package.seeall) module("ffluci.controller.admin.services", package.seeall)
function index()
local page = node("admin", "services")
page.target = template("admin_services/index")
page.title = "Dienste"
page.order = 40
local page = node("admin", "services", "httpd")
page.target = cbi("admin_services/httpd")
page.title = "HTTP-Server"
page.order = 10
local page = node("admin", "services", "dropbear")
page.target = cbi("admin_services/dropbear")
page.title = "SSH-Server"
page.order = 20
local page = node("admin", "services", "dnsmasq")
page.target = cbi("admin_services/dnsmasq")
page.title = "Dnsmasq"
page.order = 30
if ffluci.fs.isfile("/etc/config/olsr") then
local page = node("admin", "services", "olsr")
page.target = cbi("admin_services/olsrd")
page.title = "OLSR"
end
end

View file

@ -1,5 +1,16 @@
module("ffluci.controller.admin.status", package.seeall) module("ffluci.controller.admin.status", package.seeall)
function index()
local page = node("admin", "status")
page.target = template("admin_status/index")
page.title = "Status"
page.order = 20
local page = node("admin", "status", "syslog")
page.target = action_syslog
page.title = "Systemprotokoll"
end
function action_syslog() function action_syslog()
local syslog = ffluci.sys.syslog() local syslog = ffluci.sys.syslog()
ffluci.template.render("admin_status/syslog", {syslog=syslog}) ffluci.template.render("admin_status/syslog", {syslog=syslog})

View file

@ -7,6 +7,52 @@ require("ffluci.fs")
require("ffluci.model.ipkg") require("ffluci.model.ipkg")
require("ffluci.model.uci") require("ffluci.model.uci")
function index()
local page = node("admin", "system")
page.target = template("admin_system/index")
page.title = "System"
page.order = 30
local page = node("admin", "system", "packages")
page.target = action_packages
page.title = "Paketverwaltung"
page.order = 10
local page = node("admin", "system", "packages", "ipkg")
page.target = action_ipkg
page.title = "IPKG-Konfiguration"
local page = node("admin", "system", "passwd")
page.target = action_passwd
page.title = "Passwort ändern"
page.order = 20
local page = node("admin", "system", "sshkeys")
page.target = action_sshkeys
page.title = "SSH-Schlüssel"
page.order = 30
local page = node("admin", "system", "hostname")
page.target = cbi("admin_system/hostname")
page.title = "Hostname"
page.order = 40
local page = node("admin", "system", "fstab")
page.target = cbi("admin_system/fstab")
page.title = "Einhängepunkte"
page.order = 50
local page = node("admin", "system", "upgrade")
page.target = action_upgrade
page.title = "Firmwareupgrade"
page.order = 60
local page = node("admin", "system", "reboot")
page.target = action_reboot
page.title = "Neu starten"
page.order = 70
end
function action_editor() function action_editor()
local file = ffluci.http.formvalue("file", "") local file = ffluci.http.formvalue("file", "")
local data = ffluci.http.formvalue("data") local data = ffluci.http.formvalue("data")

View file

@ -2,6 +2,12 @@ module("ffluci.controller.admin.uci", package.seeall)
require("ffluci.util") require("ffluci.util")
require("ffluci.sys") require("ffluci.sys")
function index()
node("admin", "uci", "changes").target = template("admin_uci/changes")
node("admin", "uci", "revert").target = action_revert
node("admin", "uci", "apply").target = action_apply
end
-- This function has a higher priority than the admin_uci/apply template -- This function has a higher priority than the admin_uci/apply template
function action_apply() function action_apply()
local changes = ffluci.model.uci.changes() local changes = ffluci.model.uci.changes()

View file

@ -1 +1,18 @@
module("ffluci.controller.admin.wifi", package.seeall) module("ffluci.controller.admin.wifi", package.seeall)
function index()
local page = node("admin", "wifi")
page.target = template("admin_wifi/index")
page.title = "Drahtlos"
page.order = 60
local page = node("admin", "wifi", "devices")
page.target = cbi("admin_wifi/devices")
page.title = "Geräte"
page.order = 10
local page = node("admin", "wifi", "networks")
page.target = cbi("admin_wifi/networks")
page.title = "Netze"
page.order = 20
end

View file

@ -13,10 +13,6 @@ team = "The FFLuCI Team"
luci1 = "Here you can customize the settings and the functionality of FFLuCI." luci1 = "Here you can customize the settings and the functionality of FFLuCI."
language = "Language" language = "Language"
general = "General" general = "General"
catpriv = "Category Privileges"
catpriv1 = [[To secure FFLuCI even further the user and group privileges of
each category can be decreased. Therefore an attacker cannot takeover the whole system
when a security exploit for any publicly available page is found.]]
ucicommit = "Post-commit actions" ucicommit = "Post-commit actions"
ucicommit1 = [[These commands will be executed automatically when a given UCI configuration is committed allowing ucicommit1 = [[These commands will be executed automatically when a given UCI configuration is committed allowing
changes to be applied instantly.]] changes to be applied instantly.]]

View file

@ -19,12 +19,6 @@ for k, v in pairs(ffluci.config.themes) do
end end
end end
p = m:section(NamedSection, "category_privileges", "core", translate("catpriv", "Kategorieprivilegien"),
translate("catpriv1", [[Zur zusätzlichen Sicherung der Oberfläche gegen Angreifer, können hier die
Ausführungsrechte der Seiten für einzelne Kategorien reduziert werden. So können z.B. Sicherheitslücken im
ungeschützten Bereich der Oberfläche nicht mehr zur Übernahme des Routers genutzt werden.]]))
p.dynamic = true
u = m:section(NamedSection, "uci_oncommit", "event", translate("ucicommit", "UCI-Befehle beim Anwenden"), u = m:section(NamedSection, "uci_oncommit", "event", translate("ucicommit", "UCI-Befehle beim Anwenden"),
translate("ucicommit1", [[Beim Anwenden translate("ucicommit1", [[Beim Anwenden
der Konfiguration aus der Oberflächliche heraus können automatisch die relevanten Dienste neugestart werden, der Konfiguration aus der Oberflächliche heraus können automatisch die relevanten Dienste neugestart werden,

View file

@ -1,36 +0,0 @@
add("admin", "index", "Übersicht", 10)
act("luci", "Oberfläche")
add("admin", "status", "Status", 20)
act("syslog", "Systemprotokoll")
add("admin", "system", "System", 30)
act("packages", "Paketverwaltung")
act("passwd", "Passwort ändern")
act("sshkeys", "SSH-Schlüssel")
act("hostname", "Hostname")
act("fstab", "Einhängepunkte")
act("upgrade", "Firmwareupgrade")
act("reboot", "Neu starten")
add("admin", "services", "Dienste", 40)
if isfile("/etc/config/olsr") then
act("olsrd", "OLSR")
end
act("httpd", "HTTP-Server")
act("dropbear", "SSH-Server")
act("dnsmasq", "Dnsmasq")
add("admin", "network", "Netzwerk", 50)
act("vlan", "Switch")
act("ifaces", "Schnittstellen")
act("dhcp", "DHCP-Server")
act("ptp", "PPPoE / PPTP")
act("routes", "Statische Routen")
if isfile("/etc/config/qos") then
act("qos", "Quality of Service")
end
add("admin", "wifi", "Drahtlos", 60)
act("devices", "Geräte")
act("networks", "Netze")

View file

@ -1,6 +1,79 @@
module("ffluci.controller.admin.index.wizard", package.seeall) module("ffluci.controller.freifunk.freifunk", package.seeall)
function action() function index()
local page = node()
page.target = alias("freifunk")
local page = node("freifunk")
page.title = "Freifunk"
page.target = alias("freifunk", "index")
page.order = 5
page.setuser = "nobody"
page.setgroup = "nogroup"
local page = node("freifunk", "index")
page.target = template("freifunk/index")
page.title = "Übersicht"
page.order = 10
local page = node("freifunk", "index", "contact")
page.target = template("freifunk/contact")
page.title = "Kontakt"
local page = node("freifunk", "status")
page.target = action_status
page.title = "Status"
page.order = 20
page.setuser = false
page.setgroup = false
local page = node("freifunk", "status", "routes")
page.target = template("public_status/routes")
page.title = "Routingtabelle"
page.order = 10
local page = node("freifunk", "status", "iwscan")
page.target = template("public_status/iwscan")
page.title = "WLAN-Scan"
page.order = 20
local page = node("admin", "index", "wizard")
page.target = action_wizard
page.title = "Freifunkassistent"
page.order = 20
local page = node("admin", "index", "freifunk")
page.target = cbi("freifunk/freifunk")
page.title = "Freifunk"
page.order = 30
local page = node("admin", "index", "contact")
page.target = cbi("freifunk/contact")
page.title = "Kontakt"
page.order = 40
end
function action_status()
local data = {}
data.s, data.m, data.r = ffluci.sys.sysinfo()
data.wifi = ffluci.sys.wifi.getiwconfig()
data.routes = {}
for i, r in pairs(ffluci.sys.net.routes()) do
if r.Destination == "00000000" then
table.insert(data.routes, r)
end
end
ffluci.template.render("public_status/index", data)
end
function action_wizard()
if ffluci.http.formvalue("ip") then if ffluci.http.formvalue("ip") then
return configure_freifunk() return configure_freifunk()
end end
@ -16,7 +89,7 @@ function action()
end end
end end
ffluci.template.render("admin_index/wizard", {ifaces=ifaces}) ffluci.template.render("freifunk/wizard", {ifaces=ifaces})
end end
function configure_freifunk() function configure_freifunk()

View file

@ -1,4 +1,8 @@
module("ffluci.controller.rpc.luciinfo", package.seeall) module("ffluci.controller.freifunk.luciinfo", package.seeall)
function index()
node("freifunk", "luciinfo").target = action_index
end
function action_index() function action_index()
local uci = ffluci.model.uci.StateSession() local uci = ffluci.model.uci.StateSession()
@ -7,7 +11,7 @@ function action_index()
-- General -- General
print("luciinfo.api=1") print("luciinfo.api=1")
print("luciinfo.version=" .. tostring(ffluci.__version__)) print("luciinfo.version=" .. tostring(require("ffluci").__version__))
-- Sysinfo -- Sysinfo
local s, m, r = ffluci.sys.sysinfo() local s, m, r = ffluci.sys.sysinfo()
@ -28,11 +32,11 @@ function action_index()
-- Freifunk -- Freifunk
local ff = uci:sections("freifunk") or {} local ff = uci:sections("freifunk") or {}
for k, v in pairs(ff) do for k, v in pairs(ff) do
if k:sub(1, 1) ~= "." then
for i, j in pairs(v) do for i, j in pairs(v) do
print("freifunk." .. k .. "." .. i .. "=" .. j) if i:sub(1, 1) ~= "." then
print("freifunk." .. k .. "." .. i .. "=" .. j)
end
end end
end
end end
end end

View file

@ -1,11 +1,38 @@
module("ffluci.controller.public.olsr", package.seeall) module("ffluci.controller.freifunk.olsr", package.seeall)
require("ffluci.sys") require("ffluci.sys")
function index()
local page = node("freifunk", "olsr")
page.target = action_index
page.title = "OLSR"
page.order = 30
local page = node("freifunk", "olsr", "routes")
page.target = action_routes
page.title = "Routen"
page.order = 10
local page = node("freifunk", "olsr", "topology")
page.target = action_topology
page.title = "Topologie"
page.order = 20
local page = node("freifunk", "olsr", "hna")
page.target = action_hna
page.title = "HNA"
page.order = 30
local page = node("freifunk", "olsr", "mid")
page.target = action_mid
page.title = "MID"
page.order = 50
end
function action_index() function action_index()
local data = fetch_txtinfo("links") local data = fetch_txtinfo("links")
if not data or not data.Links then if not data or not data.Links then
ffluci.template.render("public_olsr/error_olsr") ffluci.template.render("freifunk-olsr/error_olsr")
return nil return nil
end end
@ -23,14 +50,14 @@ function action_index()
table.sort(data.Links, compare) table.sort(data.Links, compare)
ffluci.template.render("public_olsr/index", {links=data.Links}) ffluci.template.render("freifunk-olsr/index", {links=data.Links})
end end
function action_routes() function action_routes()
local data = fetch_txtinfo("routes") local data = fetch_txtinfo("routes")
if not data or not data.Routes then if not data or not data.Routes then
ffluci.template.render("public_olsr/error_olsr") ffluci.template.render("freifunk-olsr/error_olsr")
return nil return nil
end end
@ -48,14 +75,14 @@ function action_routes()
table.sort(data.Routes, compare) table.sort(data.Routes, compare)
ffluci.template.render("public_olsr/routes", {routes=data.Routes}) ffluci.template.render("freifunk-olsr/routes", {routes=data.Routes})
end end
function action_topology() function action_topology()
local data = fetch_txtinfo("topology") local data = fetch_txtinfo("topology")
if not data or not data.Topology then if not data or not data.Topology then
ffluci.template.render("public_olsr/error_olsr") ffluci.template.render("freifunk-olsr/error_olsr")
return nil return nil
end end
@ -65,14 +92,14 @@ function action_topology()
table.sort(data.Topology, compare) table.sort(data.Topology, compare)
ffluci.template.render("public_olsr/topology", {routes=data.Topology}) ffluci.template.render("freifunk-olsr/topology", {routes=data.Topology})
end end
function action_hna() function action_hna()
local data = fetch_txtinfo("hna") local data = fetch_txtinfo("hna")
if not data or not data.HNA then if not data or not data.HNA then
ffluci.template.render("public_olsr/error_olsr") ffluci.template.render("freifunk-olsr/error_olsr")
return nil return nil
end end
@ -82,14 +109,14 @@ function action_hna()
table.sort(data.HNA, compare) table.sort(data.HNA, compare)
ffluci.template.render("public_olsr/hna", {routes=data.HNA}) ffluci.template.render("freifunk-olsr/hna", {routes=data.HNA})
end end
function action_mid() function action_mid()
local data = fetch_txtinfo("mid") local data = fetch_txtinfo("mid")
if not data or not data.MID then if not data or not data.MID then
ffluci.template.render("public_olsr/error_olsr") ffluci.template.render("freifunk-olsr/error_olsr")
return nil return nil
end end
@ -99,7 +126,7 @@ function action_mid()
table.sort(data.MID, compare) table.sort(data.MID, compare)
ffluci.template.render("public_olsr/mid", {mids=data.MID}) ffluci.template.render("freifunk-olsr/mid", {mids=data.MID})
end end

View file

@ -1 +0,0 @@
module("ffluci.controller.public.index", package.seeall)

View file

@ -1,21 +0,0 @@
module("ffluci.controller.public.status", package.seeall)
function action_index()
local data = {}
data.s, data.m, data.r = ffluci.sys.sysinfo()
data.wifi = ffluci.sys.wifi.getiwconfig()
data.routes = {}
for i, r in pairs(ffluci.sys.net.routes()) do
if r.Destination == "00000000" then
table.insert(data.routes, r)
end
end
ffluci.template.render("public_status/index", data)
end

View file

@ -1 +0,0 @@
module("ffluci.controller.sudo.status", package.seeall)

View file

@ -1,18 +0,0 @@
add("public", "index", "Übersicht", 10)
act("contact", "Kontakt")
add("public", "status", "Status", 20)
act("routes", "Routingtabelle")
act("iwscan", "WLAN-Scan")
add("public", "olsr", "OLSR", 30)
act("routes", "Routen")
act("topology", "Topologie")
act("hna", "HNA")
act("mid", "MID")
sel("admin", "index")
act("wizard", "Freifunkassistent")
act("contact", "Kontakt")
act("freifunk", "Freifunk")

View file

@ -34,7 +34,25 @@
<th><%:signal Signal%></th> <th><%:signal Signal%></th>
<th><%:noise Rausch%></th> <th><%:noise Rausch%></th>
</tr> </tr>
<%=ffluci.sys.httpget("http://127.0.0.1" .. controller .. "/sudo/status/iwconfig")%> <%for k, v in pairs(ffluci.sys.wifi.getiwconfig()) do
%>
<tr>
<td rowspan="2"><%=k%></td>
<td><%=v[1]%></td>
<td><%=v.Frequency%></td>
<td><%=v["Tx-Power"]%></td>
<td><%=v["Bit Rate"]%></td>
<td><%=v["RTS thr"]%></td>
<td><%=v["Fragment thr"]%></td>
<td><%=v["Link Quality"]%></td>
<td><%=v["Signal level"]%></td>
<td><%=v["Noise level"]%></td>
</tr>
<tr>
<td colspan="4"><strong>ESSID: </strong><%=v.ESSID%></td>
<td colspan="5"><strong>BSSID: </strong><%=(v.Cell or v["Access Point"])%></td>
</tr>
<%end%>
</table> </table>
<br /> <br />
<br /> <br />

View file

@ -15,7 +15,24 @@
<th><%:signal Signal%></th> <th><%:signal Signal%></th>
<th><%:noise Rausch%></th> <th><%:noise Rausch%></th>
</tr> </tr>
<%=ffluci.sys.httpget("http://127.0.0.1" .. controller .. "/sudo/status/iwscan")%> <%for iface, cells in pairs(ffluci.sys.wifi.iwscan()) do
for i, cell in ipairs(cells) do
%>
<tr>
<td><%=iface%></td>
<td><%=cell.ESSID%></td>
<td><%=cell.Address%></td>
<td><%=cell.Mode%></td>
<td><%=(cell.Channel or cell.Frequency or "")%></td>
<td><%=cell["Encryption key"]%></td>
<td><%=cell.Quality%></td>
<td><%=cell["Signal level"]%></td>
<td><%=cell["Noise level"]%></td>
</tr>
<%
end
end
%>
</table> </table>
<br /> <br />
<%+footer%> <%+footer%>

View file

@ -1,21 +0,0 @@
<%
ffluci.http.prepare_content("text/plain")
for k, v in pairs(ffluci.sys.wifi.getiwconfig()) do
%>
<tr>
<td rowspan="2"><%=k%></td>
<td><%=v[1]%></td>
<td><%=v.Frequency%></td>
<td><%=v["Tx-Power"]%></td>
<td><%=v["Bit Rate"]%></td>
<td><%=v["RTS thr"]%></td>
<td><%=v["Fragment thr"]%></td>
<td><%=v["Link Quality"]%></td>
<td><%=v["Signal level"]%></td>
<td><%=v["Noise level"]%></td>
</tr>
<tr>
<td colspan="4"><strong>ESSID: </strong><%=v.ESSID%></td>
<td colspan="5"><strong>BSSID: </strong><%=(v.Cell or v["Access Point"])%></td>
</tr>
<%end%>

View file

@ -1,22 +0,0 @@
<%
ffluci.http.prepare_content("text/plain")
for iface, cells in pairs(ffluci.sys.wifi.iwscan()) do
for i, cell in ipairs(cells) do
%>
<tr>
<td><%=iface%></td>
<td><%=cell.ESSID%></td>
<td><%=cell.Address%></td>
<td><%=cell.Mode%></td>
<td><%=(cell.Channel or cell.Frequency or "")%></td>
<td><%=cell["Encryption key"]%></td>
<td><%=cell.Quality%></td>
<td><%=cell["Signal level"]%></td>
<td><%=cell["Noise level"]%></td>
</tr>
<%
end
end
%>