summaryrefslogtreecommitdiffhomepage
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/luci-base/Makefile2
-rw-r--r--modules/luci-base/luasrc/dispatcher.lua84
-rw-r--r--modules/luci-base/luasrc/dispatcher.luadoc220
-rw-r--r--modules/luci-base/luasrc/http.lua90
-rw-r--r--modules/luci-base/luasrc/http.luadoc166
-rw-r--r--modules/luci-base/luasrc/http/protocol.lua62
-rw-r--r--modules/luci-base/luasrc/http/protocol.luadoc142
-rw-r--r--modules/luci-base/luasrc/http/protocol/conditionals.lua31
-rw-r--r--modules/luci-base/luasrc/http/protocol/conditionals.luadoc85
-rw-r--r--modules/luci-base/luasrc/http/protocol/date.lua16
-rw-r--r--modules/luci-base/luasrc/http/protocol/date.luadoc46
-rw-r--r--modules/luci-base/luasrc/http/protocol/mime.lua9
-rw-r--r--modules/luci-base/luasrc/http/protocol/mime.luadoc34
-rw-r--r--modules/luci-base/luasrc/i18n.lua26
-rw-r--r--modules/luci-base/luasrc/i18n.luadoc84
-rw-r--r--modules/luci-base/luasrc/ip.lua661
-rw-r--r--modules/luci-base/luasrc/ltn12.lua76
-rw-r--r--modules/luci-base/luasrc/model/ipkg.lua38
-rw-r--r--modules/luci-base/luasrc/model/ipkg.luadoc109
-rw-r--r--modules/luci-base/luasrc/model/uci.lua179
-rw-r--r--modules/luci-base/luasrc/model/uci.luadoc291
-rw-r--r--modules/luci-base/luasrc/sys.lua199
-rw-r--r--modules/luci-base/luasrc/sys.luadoc396
-rw-r--r--modules/luci-base/luasrc/sys/iptparser.lua24
-rw-r--r--modules/luci-base/luasrc/sys/iptparser.luadoc69
-rw-r--r--modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua8
-rw-r--r--modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua6
-rw-r--r--modules/luci-base/luasrc/tools/webadmin.lua111
-rw-r--r--modules/luci-base/luasrc/util.lua176
-rw-r--r--modules/luci-base/luasrc/util.luadoc378
-rw-r--r--modules/luci-mod-admin-full/luasrc/controller/admin/system.lua8
-rw-r--r--modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua13
-rw-r--r--modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/hosts.lua18
-rw-r--r--modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/ifaces.lua1
-rw-r--r--modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/routes.lua12
-rw-r--r--modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm8
-rw-r--r--modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm117
-rw-r--r--modules/luci-mod-admin-mini/luasrc/model/cbi/mini/dhcp.lua14
-rw-r--r--modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm53
39 files changed, 2282 insertions, 1780 deletions
diff --git a/modules/luci-base/Makefile b/modules/luci-base/Makefile
index 8337fea711..80bbda107a 100644
--- a/modules/luci-base/Makefile
+++ b/modules/luci-base/Makefile
@@ -12,7 +12,7 @@ LUCI_TYPE:=mod
LUCI_BASENAME:=base
LUCI_TITLE:=LuCI core libraries
-LUCI_DEPENDS:=+lua +libuci-lua +luci-lib-nixio +rpcd
+LUCI_DEPENDS:=+lua +libuci-lua +luci-lib-nixio +luci-lib-ip +rpcd
PKG_SOURCE:=LuaSrcDiet-0.12.1.tar.bz2
PKG_SOURCE_URL:=https://luasrcdiet.googlecode.com/files
diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua
index 155d31b10f..795b62bedb 100644
--- a/modules/luci-base/luasrc/dispatcher.lua
+++ b/modules/luci-base/luasrc/dispatcher.lua
@@ -1,7 +1,6 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
---- LuCI web dispatcher.
local fs = require "nixio.fs"
local sys = require "luci.sys"
local util = require "luci.util"
@@ -23,9 +22,6 @@ local index = nil
local fi
---- Build the URL relative to the server webroot from given virtual path.
--- @param ... Virtual path
--- @return Relative URL
function build_url(...)
local path = {...}
local url = { http.getenv("SCRIPT_NAME") or "" }
@@ -49,9 +45,6 @@ function build_url(...)
return table.concat(url, "")
end
---- Check whether a dispatch node shall be visible
--- @param node Dispatch node
--- @return Boolean indicating whether the node should be visible
function node_visible(node)
if node then
return not (
@@ -64,9 +57,6 @@ function node_visible(node)
return false
end
---- Return a sorted table of visible childs within a given node
--- @param node Dispatch node
--- @return Ordered table of child node names
function node_childs(node)
local rv = { }
if node then
@@ -86,9 +76,6 @@ function node_childs(node)
end
---- Send a 404 error code and render the "error404" template if available.
--- @param message Custom error message (optional)
--- @return false
function error404(message)
http.status(404, "Not Found")
message = message or "Not Found"
@@ -101,9 +88,6 @@ function error404(message)
return false
end
---- Send a 500 error code and render the "error500" template if available.
--- @param message Custom error message (optional)#
--- @return false
function error500(message)
util.perror(message)
if not context.template_header_sent then
@@ -128,16 +112,22 @@ function authenticator.htmlauth(validator, accs, default)
return user
end
- require("luci.i18n")
- require("luci.template")
- context.path = {}
- luci.template.render("sysauth", {duser=default, fuser=user})
+ if context.urltoken.stok then
+ context.urltoken.stok = nil
+ http.header("Set-Cookie", "sysauth=; path="..build_url())
+ http.redirect(build_url())
+ else
+ require("luci.i18n")
+ require("luci.template")
+ context.path = {}
+ http.status(403, "Forbidden")
+ luci.template.render("sysauth", {duser=default, fuser=user})
+ end
+
return false
end
---- Dispatch an HTTP request.
--- @param request LuCI HTTP Request object
function httpdispatch(request, prefix)
http.context.request = request
@@ -176,8 +166,6 @@ function httpdispatch(request, prefix)
--context._disable_memtrace()
end
---- Dispatches a LuCI virtual path.
--- @param request Virtual path
function dispatch(request)
--context._disable_memtrace = require "luci.debug".trap_memtrace("l")
local ctx = context
@@ -340,7 +328,6 @@ function dispatch(request)
if not util.contains(accs, user) then
if authen then
- ctx.urltoken.stok = nil
local user, sess = authen(sys.user.checkpasswd, accs, def)
if not user or not util.contains(accs, user) then
return
@@ -364,6 +351,7 @@ function dispatch(request)
if sess then
http.header("Set-Cookie", "sysauth=" .. sess.."; path="..build_url())
+ http.redirect(build_url(unpack(ctx.requestpath)))
ctx.authsession = sess
ctx.authuser = user
end
@@ -445,7 +433,6 @@ function dispatch(request)
end
end
---- Generate the dispatching index using the native file-cache based strategy.
function createindex()
local controllers = { }
local base = "%s/controller/" % util.libpath()
@@ -509,7 +496,6 @@ function createindex()
end
end
---- Create the dispatching tree from the index.
-- Build the index before if it does not exist yet.
function createtree()
if not index then
@@ -548,9 +534,6 @@ function createtree()
return tree
end
---- Register a tree modifier.
--- @param func Modifier function
--- @param order Modifier order value (optional)
function modifier(func, order)
context.modifiers[#context.modifiers+1] = {
func = func,
@@ -560,12 +543,6 @@ function modifier(func, order)
}
end
---- Clone a node of the dispatching tree to another position.
--- @param path Virtual path destination
--- @param clone Virtual path source
--- @param title Destination node title (optional)
--- @param order Destination node order value (optional)
--- @return Dispatching tree node
function assign(path, clone, title, order)
local obj = node(unpack(path))
obj.nodes = nil
@@ -579,12 +556,6 @@ function assign(path, clone, title, order)
return obj
end
---- Create a new dispatching node and define common parameters.
--- @param path Virtual path
--- @param target Target function to call when dispatched.
--- @param title Destination node title
--- @param order Destination node order value (optional)
--- @return Dispatching tree node
function entry(path, target, title, order)
local c = node(unpack(path))
@@ -596,17 +567,11 @@ function entry(path, target, title, order)
return c
end
---- Fetch or create a dispatching node without setting the target module or
-- enabling the node.
--- @param ... Virtual path
--- @return Dispatching tree node
function get(...)
return _create_node({...})
end
---- Fetch or create a new dispatching node.
--- @param ... Virtual path
--- @return Dispatching tree node
function node(...)
local c = _create_node({...})
@@ -666,13 +631,10 @@ function _firstchild()
dispatch(path)
end
---- Alias the first (lowest order) page automatically
function firstchild()
return { type = "firstchild", target = _firstchild }
end
---- Create a redirect to another dispatching node.
--- @param ... Virtual path destination
function alias(...)
local req = {...}
return function(...)
@@ -684,9 +646,6 @@ function alias(...)
end
end
---- Rewrite the first x path values of the request.
--- @param n Number of path values to replace
--- @param ... Virtual path to replace removed path values with
function rewrite(n, ...)
local req = {...}
return function(...)
@@ -725,9 +684,6 @@ local function _call(self, ...)
end
end
---- Create a function-call dispatching target.
--- @param name Target function of local controller
--- @param ... Additional parameters passed to the function
function call(name, ...)
return {type = "call", argv = {...}, name = name, target = _call}
end
@@ -737,8 +693,6 @@ local _template = function(self, ...)
require "luci.template".render(self.view)
end
---- Create a template render dispatching target.
--- @param name Template to be rendered
function template(name)
return {type = "template", view = name, target = _template}
end
@@ -844,8 +798,6 @@ local function _cbi(self, ...)
end
end
---- Create a CBI model dispatching target.
--- @param model CBI model to be rendered
function cbi(model, config)
return {type = "cbi", config = config, model = model, target = _cbi}
end
@@ -858,9 +810,6 @@ local function _arcombine(self, ...)
target:target(unpack(argv))
end
---- Create a combined dispatching target for non argv and argv requests.
--- @param trg1 Overview Target
--- @param trg2 Detail Target
function arcombine(trg1, trg2)
return {type = "arcombine", env = getfenv(), target = _arcombine, targets = {trg1, trg2}}
end
@@ -889,19 +838,12 @@ local function _form(self, ...)
tpl.render("footer")
end
---- Create a CBI form model dispatching target.
--- @param model CBI form model tpo be rendered
function form(model)
return {type = "cbi", model = model, target = _form}
end
---- Access the luci.i18n translate() api.
--- @class function
--- @name translate
--- @param text Text to translate
translate = i18n.translate
---- No-op function used to mark translation entries for menu labels.
-- This function does not actually translate the given argument but
-- is used by build/i18n-scan.pl to find translatable entries.
function _(text)
diff --git a/modules/luci-base/luasrc/dispatcher.luadoc b/modules/luci-base/luasrc/dispatcher.luadoc
new file mode 100644
index 0000000000..743463c74f
--- /dev/null
+++ b/modules/luci-base/luasrc/dispatcher.luadoc
@@ -0,0 +1,220 @@
+---[[
+LuCI web dispatcher.
+]]
+module "luci.dispatcher"
+
+---[[
+Build the URL relative to the server webroot from given virtual path.
+
+@class function
+@name build_url
+@param ... Virtual path
+@return Relative URL
+]]
+
+---[[
+Check whether a dispatch node shall be visible
+
+@class function
+@name node_visible
+@param node Dispatch node
+@return Boolean indicating whether the node should be visible
+]]
+
+---[[
+Return a sorted table of visible childs within a given node
+
+@class function
+@name node_childs
+@param node Dispatch node
+@return Ordered table of child node names
+]]
+
+---[[
+Send a 404 error code and render the "error404" template if available.
+
+@class function
+@name error404
+@param message Custom error message (optional)
+@return false
+]]
+
+---[[
+Send a 500 error code and render the "error500" template if available.
+
+@class function
+@name error500
+@param message Custom error message (optional)#
+@return false
+]]
+
+---[[
+Dispatch an HTTP request.
+
+@class function
+@name httpdispatch
+@param request LuCI HTTP Request object
+]]
+
+---[[
+Dispatches a LuCI virtual path.
+
+@class function
+@name dispatch
+@param request Virtual path
+]]
+
+---[[
+Generate the dispatching index using the native file-cache based strategy.
+
+
+@class function
+@name createindex
+]]
+
+---[[
+Create the dispatching tree from the index.
+
+Build the index before if it does not exist yet.
+
+@class function
+@name createtree
+]]
+
+---[[
+Register a tree modifier.
+
+@class function
+@name modifier
+@param func Modifier function
+@param order Modifier order value (optional)
+]]
+
+---[[
+Clone a node of the dispatching tree to another position.
+
+@class function
+@name assign
+@param path Virtual path destination
+@param clone Virtual path source
+@param title Destination node title (optional)
+@param order Destination node order value (optional)
+@return Dispatching tree node
+]]
+
+---[[
+Create a new dispatching node and define common parameters.
+
+@class function
+@name entry
+@param path Virtual path
+@param target Target function to call when dispatched.
+@param title Destination node title
+@param order Destination node order value (optional)
+@return Dispatching tree node
+]]
+
+---[[
+Fetch or create a dispatching node without setting the target module or
+
+enabling the node.
+@class function
+@name get
+@param ... Virtual path
+@return Dispatching tree node
+]]
+
+---[[
+Fetch or create a new dispatching node.
+
+@class function
+@name node
+@param ... Virtual path
+@return Dispatching tree node
+]]
+
+---[[
+Alias the first (lowest order) page automatically
+
+
+@class function
+@name firstchild
+]]
+
+---[[
+Create a redirect to another dispatching node.
+
+@class function
+@name alias
+@param ... Virtual path destination
+]]
+
+---[[
+Rewrite the first x path values of the request.
+
+@class function
+@name rewrite
+@param n Number of path values to replace
+@param ... Virtual path to replace removed path values with
+]]
+
+---[[
+Create a function-call dispatching target.
+
+@class function
+@name call
+@param name Target function of local controller
+@param ... Additional parameters passed to the function
+]]
+
+---[[
+Create a template render dispatching target.
+
+@class function
+@name template
+@param name Template to be rendered
+]]
+
+---[[
+Create a CBI model dispatching target.
+
+@class function
+@name cbi
+@param model CBI model to be rendered
+]]
+
+---[[
+Create a combined dispatching target for non argv and argv requests.
+
+@class function
+@name arcombine
+@param trg1 Overview Target
+@param trg2 Detail Target
+]]
+
+---[[
+Create a CBI form model dispatching target.
+
+@class function
+@name form
+@param model CBI form model tpo be rendered
+]]
+
+---[[
+Access the luci.i18n translate() api.
+
+@class function
+@name translate
+@param text Text to translate
+]]
+
+---[[
+No-op function used to mark translation entries for menu labels.
+
+This function does not actually translate the given argument but
+is used by build/i18n-scan.pl to find translatable entries.
+
+@class function
+@name _
+]]
+
diff --git a/modules/luci-base/luasrc/http.lua b/modules/luci-base/luasrc/http.lua
index a5329e51d6..a92d8affb6 100644
--- a/modules/luci-base/luasrc/http.lua
+++ b/modules/luci-base/luasrc/http.lua
@@ -11,7 +11,6 @@ local table = require "table"
local ipairs, pairs, next, type, tostring, error =
ipairs, pairs, next, type, tostring, error
---- LuCI Web Framework high-level HTTP functions.
module "luci.http"
context = util.threadlocal()
@@ -101,7 +100,6 @@ function Request._parse_input(self)
self.parsed_input = true
end
---- Close the HTTP-Connection.
function close()
if not context.eoh then
context.eoh = true
@@ -114,52 +112,31 @@ function close()
end
end
---- Return the request content if the request was of unknown type.
--- @return HTTP request body
--- @return HTTP request body length
function content()
return context.request:content()
end
---- Get a certain HTTP input value or a table of all input values.
--- @param name Name of the GET or POST variable to fetch
--- @param noparse Don't parse POST data before getting the value
--- @return HTTP input value or table of all input value
function formvalue(name, noparse)
return context.request:formvalue(name, noparse)
end
---- Get a table of all HTTP input values with a certain prefix.
--- @param prefix Prefix
--- @return Table of all HTTP input values with given prefix
function formvaluetable(prefix)
return context.request:formvaluetable(prefix)
end
---- Get the value of a certain HTTP-Cookie.
--- @param name Cookie Name
--- @return String containing cookie data
function getcookie(name)
return context.request:getcookie(name)
end
---- Get the value of a certain HTTP environment variable
-- or the environment table itself.
--- @param name Environment variable
--- @return HTTP environment value or environment table
function getenv(name)
return context.request:getenv(name)
end
---- Set a handler function for incoming user file uploads.
--- @param callback Handler function
function setfilehandler(callback)
return context.request:setfilehandler(callback)
end
---- Send a HTTP-Header.
--- @param key Header key
--- @param value Header value
function header(key, value)
if not context.headers then
context.headers = {}
@@ -168,8 +145,6 @@ function header(key, value)
coroutine.yield(2, key, value)
end
---- Set the mime type of following content data.
--- @param mime Mimetype of following content
function prepare_content(mime)
if not context.headers or not context.headers["content-type"] then
if mime == "application/xhtml+xml" then
@@ -183,15 +158,10 @@ function prepare_content(mime)
end
end
---- Get the RAW HTTP input source
--- @return HTTP LTN12 source
function source()
return context.request.input
end
---- Set the HTTP status code and status message.
--- @param code Status code
--- @param message Status message
function status(code, message)
code = code or 200
message = message or "OK"
@@ -199,12 +169,8 @@ function status(code, message)
coroutine.yield(1, code, message)
end
---- Send a chunk of content data to the client.
-- This function is as a valid LTN12 sink.
-- If the content chunk is nil this function will automatically invoke close.
--- @param content Content chunk
--- @param src_err Error object from source (optional)
--- @see close
function write(content, src_err)
if not content then
if src_err then
@@ -237,24 +203,16 @@ function write(content, src_err)
end
end
---- Splice data from a filedescriptor to the client.
--- @param fp File descriptor
--- @param size Bytes to splice (optional)
function splice(fd, size)
coroutine.yield(6, fd, size)
end
---- Redirects the client to a new URL and closes the connection.
--- @param url Target URL
function redirect(url)
status(302, "Found")
header("Location", url)
close()
end
---- Create a querystring out of a table of key - value pairs.
--- @param table Query string source table
--- @return Encoded HTTP query string
function build_querystring(q)
local s = { "?" }
@@ -269,56 +227,10 @@ function build_querystring(q)
return table.concat(s, "")
end
---- Return the URL-decoded equivalent of a string.
--- @param str URL-encoded string
--- @param no_plus Don't decode + to " "
--- @return URL-decoded string
--- @see urlencode
urldecode = protocol.urldecode
---- Return the URL-encoded equivalent of a string.
--- @param str Source string
--- @return URL-encoded string
--- @see urldecode
urlencode = protocol.urlencode
---- Send the given data as JSON encoded string.
--- @param data Data to send
function write_json(x)
- if x == nil then
- write("null")
- elseif type(x) == "table" then
- local k, v
- if type(next(x)) == "number" then
- write("[ ")
- for k, v in ipairs(x) do
- write_json(v)
- if next(x, k) then
- write(", ")
- end
- end
- write(" ]")
- else
- write("{ ")
- for k, v in pairs(x) do
- write("%q: " % k)
- write_json(v)
- if next(x, k) then
- write(", ")
- end
- end
- write(" }")
- end
- elseif type(x) == "number" or type(x) == "boolean" then
- if (x ~= x) then
- -- NaN is the only value that doesn't equal to itself.
- write("Number.NaN")
- else
- write(tostring(x))
- end
- else
- write('"%s"' % tostring(x):gsub('["%z\1-\31]', function(c)
- return '\\u%04x' % c:byte(1)
- end))
- end
+ util.serialize_json(x, write)
end
diff --git a/modules/luci-base/luasrc/http.luadoc b/modules/luci-base/luasrc/http.luadoc
new file mode 100644
index 0000000000..4e31216a1e
--- /dev/null
+++ b/modules/luci-base/luasrc/http.luadoc
@@ -0,0 +1,166 @@
+---[[
+LuCI Web Framework high-level HTTP functions.
+
+module "luci.http"
+]]
+
+---[[
+Close the HTTP-Connection.
+
+
+@class function
+@name close
+]]
+
+---[[
+Return the request content if the request was of unknown type.
+
+@class function
+@name content
+@return HTTP request body
+@return HTTP request body length
+]]
+
+---[[
+Get a certain HTTP input value or a table of all input values.
+
+@class function
+@name formvalue
+@param name Name of the GET or POST variable to fetch
+@param noparse Don't parse POST data before getting the value
+@return HTTP input value or table of all input value
+]]
+
+---[[
+Get a table of all HTTP input values with a certain prefix.
+
+@class function
+@name formvaluetable
+@param prefix Prefix
+@return Table of all HTTP input values with given prefix
+]]
+
+---[[
+Get the value of a certain HTTP-Cookie.
+
+@class function
+@name getcookie
+@param name Cookie Name
+@return String containing cookie data
+]]
+
+---[[
+Get the value of a certain HTTP environment variable
+
+or the environment table itself.
+@class function
+@name getenv
+@param name Environment variable
+@return HTTP environment value or environment table
+]]
+
+---[[
+Set a handler function for incoming user file uploads.
+
+@class function
+@name setfilehandler
+@param callback Handler function
+]]
+
+---[[
+Send a HTTP-Header.
+
+@class function
+@name header
+@param key Header key
+@param value Header value
+]]
+
+---[[
+Set the mime type of following content data.
+
+@class function
+@name prepare_content
+@param mime Mimetype of following content
+]]
+
+---[[
+Get the RAW HTTP input source
+
+@class function
+@name source
+@return HTTP LTN12 source
+]]
+
+---[[
+Set the HTTP status code and status message.
+
+@class function
+@name status
+@param code Status code
+@param message Status message
+]]
+
+---[[
+Send a chunk of content data to the client.
+
+This function is as a valid LTN12 sink.
+If the content chunk is nil this function will automatically invoke close.
+@class function
+@name write
+@param content Content chunk
+@param src_err Error object from source (optional)
+@see close
+]]
+
+---[[
+Splice data from a filedescriptor to the client.
+
+@class function
+@name splice
+@param fp File descriptor
+@param size Bytes to splice (optional)
+]]
+
+---[[
+Redirects the client to a new URL and closes the connection.
+
+@class function
+@name redirect
+@param url Target URL
+]]
+
+---[[
+Create a querystring out of a table of key - value pairs.
+
+@class function
+@name build_querystring
+@param table Query string source table
+@return Encoded HTTP query string
+]]
+
+---[[
+Return the URL-decoded equivalent of a string.
+
+@param str URL-encoded string
+@param no_plus Don't decode + to " "
+@return URL-decoded string
+@see urlencode
+]]
+
+---[[
+Return the URL-encoded equivalent of a string.
+
+@param str Source string
+@return URL-encoded string
+@see urldecode
+]]
+
+---[[
+Send the given data as JSON encoded string.
+
+@class function
+@name write_json
+@param data Data to send
+]]
+
diff --git a/modules/luci-base/luasrc/http/protocol.lua b/modules/luci-base/luasrc/http/protocol.lua
index aeb7ea6211..e9efb44cfa 100644
--- a/modules/luci-base/luasrc/http/protocol.lua
+++ b/modules/luci-base/luasrc/http/protocol.lua
@@ -1,7 +1,6 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
---- LuCI http protocol class.
-- This class contains several functions useful for http message- and content
-- decoding and to retrive form data from raw http messages.
module("luci.http.protocol", package.seeall)
@@ -10,12 +9,7 @@ local ltn12 = require("luci.ltn12")
HTTP_MAX_CONTENT = 1024*8 -- 8 kB maximum content size
---- Decode an urlencoded string - optionally without decoding
-- the "+" sign to " " - and return the decoded string.
--- @param str Input string in x-www-urlencoded format
--- @param no_plus Don't decode "+" signs to spaces
--- @return The decoded string
--- @see urlencode
function urldecode( str, no_plus )
local function __chrdec( hex )
@@ -33,15 +27,10 @@ function urldecode( str, no_plus )
return str
end
---- Extract and split urlencoded data pairs, separated bei either "&" or ";"
-- from given url or string. Returns a table with urldecoded values.
-- Simple parameters are stored as string values associated with the parameter
-- name within the table. Parameters with multiple values are stored as array
-- containing the corresponding values.
--- @param url The url or string which contains x-www-urlencoded form data
--- @param tbl Use the given table for storing values (optional)
--- @return Table containing the urldecoded parameters
--- @see urlencode_params
function urldecode_params( url, tbl )
local params = tbl or { }
@@ -73,10 +62,6 @@ function urldecode_params( url, tbl )
return params
end
---- Encode given string to x-www-urlencoded format.
--- @param str String to encode
--- @return String containing the encoded data
--- @see urldecode
function urlencode( str )
local function __chrenc( chr )
@@ -95,12 +80,8 @@ function urlencode( str )
return str
end
---- Encode each key-value-pair in given table to x-www-urlencoded format,
-- separated by "&". Tables are encoded as parameters with multiple values by
-- repeating the parameter name with each value.
--- @param tbl Table with the values
--- @return String containing encoded values
--- @see urldecode_params
function urlencode_params( tbl )
local enc = ""
@@ -122,9 +103,6 @@ end
-- (Internal function)
-- Initialize given parameter and coerce string into table when the parameter
-- already exists.
--- @param tbl Table where parameter should be created
--- @param key Parameter name
--- @return Always nil
local function __initval( tbl, key )
if tbl[key] == nil then
tbl[key] = ""
@@ -138,11 +116,6 @@ end
-- (Internal function)
-- Append given data to given parameter, either by extending the string value
-- or by appending it to the last string in the parameter's value table.
--- @param tbl Table containing the previously initialized parameter value
--- @param key Parameter name
--- @param chunk String containing the data to append
--- @return Always nil
--- @see __initval
local function __appendval( tbl, key, chunk )
if type(tbl[key]) == "table" then
tbl[key][#tbl[key]] = tbl[key][#tbl[key]] .. chunk
@@ -155,12 +128,6 @@ end
-- Finish the value of given parameter, either by transforming the string value
-- or - in the case of multi value parameters - the last element in the
-- associated values table.
--- @param tbl Table containing the previously initialized parameter value
--- @param key Parameter name
--- @param handler Function which transforms the parameter value
--- @return Always nil
--- @see __initval
--- @see __appendval
local function __finishval( tbl, key, handler )
if handler then
if type(tbl[key]) == "table" then
@@ -259,10 +226,7 @@ process_states['headers'] = function( msg, chunk )
end
---- Creates a ltn12 source from the given socket. The source will return it's
-- data line by line with the trailing \r\n stripped of.
--- @param sock Readable network socket
--- @return Ltn12 source function
function header_source( sock )
return ltn12.source.simplify( function()
@@ -289,7 +253,6 @@ function header_source( sock )
end )
end
---- Decode a mime encoded http message body with multipart/form-data
-- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table withing the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
@@ -300,12 +263,6 @@ end
-- o Table containing decoded (name, file) and raw (headers) mime header data
-- o String value containing a chunk of the file data
-- o Boolean which indicates wheather the current chunk is the last one (eof)
--- @param src Ltn12 source function
--- @param msg HTTP message object
--- @param filecb File callback function (optional)
--- @return Value indicating successful operation (not nil means "ok")
--- @return String containing the error if unsuccessful
--- @see parse_message_header
function mimedecode_message_body( src, msg, filecb )
if msg and msg.env.CONTENT_TYPE then
@@ -449,15 +406,9 @@ function mimedecode_message_body( src, msg, filecb )
return ltn12.pump.all( src, snk )
end
---- Decode an urlencoded http message body with application/x-www-urlencoded
-- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table withing the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
--- @param src Ltn12 source function
--- @param msg HTTP message object
--- @return Value indicating successful operation (not nil means "ok")
--- @return String containing the error if unsuccessful
--- @see parse_message_header
function urldecode_message_body( src, msg )
local tlen = 0
@@ -507,12 +458,8 @@ function urldecode_message_body( src, msg )
return ltn12.pump.all( src, snk )
end
---- Try to extract an http message header including information like protocol
-- version, message headers and resulting CGI environment variables from the
-- given ltn12 source.
--- @param src Ltn12 source function
--- @return HTTP message object
--- @see parse_message_body
function parse_message_header( src )
local ok = true
@@ -582,19 +529,12 @@ function parse_message_header( src )
return msg
end
---- Try to extract and decode a http message body from the given ltn12 source.
-- This function will examine the Content-Type within the given message object
-- to select the appropriate content decoder.
-- Currently the application/x-www-urlencoded and application/form-data
-- mime types are supported. If the encountered content encoding can't be
-- handled then the whole message body will be stored unaltered as "content"
-- property within the given message object.
--- @param src Ltn12 source function
--- @param msg HTTP message object
--- @param filecb File data callback (optional, see mimedecode_message_body())
--- @return Value indicating successful operation (not nil means "ok")
--- @return String containing the error if unsuccessful
--- @see parse_message_header
function parse_message_body( src, msg, filecb )
-- Is it multipart/mime ?
if msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE and
@@ -655,8 +595,6 @@ function parse_message_body( src, msg, filecb )
end
end
---- Table containing human readable messages for several http status codes.
--- @class table
statusmsg = {
[200] = "OK",
[206] = "Partial Content",
diff --git a/modules/luci-base/luasrc/http/protocol.luadoc b/modules/luci-base/luasrc/http/protocol.luadoc
new file mode 100644
index 0000000000..67a60d9e7a
--- /dev/null
+++ b/modules/luci-base/luasrc/http/protocol.luadoc
@@ -0,0 +1,142 @@
+---[[
+LuCI http protocol class.
+
+This class contains several functions useful for http message- and content
+decoding and to retrive form data from raw http messages.
+]]
+module "luci.http.protocol"
+
+---[[
+Decode an urlencoded string - optionally without decoding
+
+the "+" sign to " " - and return the decoded string.
+@class function
+@name urldecode
+@param str Input string in x-www-urlencoded format
+@param no_plus Don't decode "+" signs to spaces
+@return The decoded string
+@see urlencode
+]]
+
+---[[
+Extract and split urlencoded data pairs, separated bei either "&" or ";"
+
+from given url or string. Returns a table with urldecoded values.
+Simple parameters are stored as string values associated with the parameter
+name within the table. Parameters with multiple values are stored as array
+containing the corresponding values.
+@class function
+@name urldecode_params
+@param url The url or string which contains x-www-urlencoded form data
+@param tbl Use the given table for storing values (optional)
+@return Table containing the urldecoded parameters
+@see urlencode_params
+]]
+
+---[[
+Encode given string to x-www-urlencoded format.
+
+@class function
+@name urlencode
+@param str String to encode
+@return String containing the encoded data
+@see urldecode
+]]
+
+---[[
+Encode each key-value-pair in given table to x-www-urlencoded format,
+
+separated by "&". Tables are encoded as parameters with multiple values by
+repeating the parameter name with each value.
+@class function
+@name urlencode_params
+@param tbl Table with the values
+@return String containing encoded values
+@see urldecode_params
+]]
+
+---[[
+Creates a ltn12 source from the given socket. The source will return it's
+
+data line by line with the trailing \r\n stripped of.
+@class function
+@name header_source
+@param sock Readable network socket
+@return Ltn12 source function
+]]
+
+---[[
+Decode a mime encoded http message body with multipart/form-data
+
+Content-Type. Stores all extracted data associated with its parameter name
+in the params table withing the given message object. Multiple parameter
+values are stored as tables, ordinary ones as strings.
+If an optional file callback function is given then it is feeded with the
+file contents chunk by chunk and only the extracted file name is stored
+within the params table. The callback function will be called subsequently
+with three arguments:
+ o Table containing decoded (name, file) and raw (headers) mime header data
+ o String value containing a chunk of the file data
+ o Boolean which indicates wheather the current chunk is the last one (eof)
+@class function
+@name mimedecode_message_body
+@param src Ltn12 source function
+@param msg HTTP message object
+@param filecb File callback function (optional)
+@return Value indicating successful operation (not nil means "ok")
+@return String containing the error if unsuccessful
+@see parse_message_header
+]]
+
+---[[
+Decode an urlencoded http message body with application/x-www-urlencoded
+
+Content-Type. Stores all extracted data associated with its parameter name
+in the params table withing the given message object. Multiple parameter
+values are stored as tables, ordinary ones as strings.
+@class function
+@name urldecode_message_body
+@param src Ltn12 source function
+@param msg HTTP message object
+@return Value indicating successful operation (not nil means "ok")
+@return String containing the error if unsuccessful
+@see parse_message_header
+]]
+
+---[[
+Try to extract an http message header including information like protocol
+
+version, message headers and resulting CGI environment variables from the
+given ltn12 source.
+@class function
+@name parse_message_header
+@param src Ltn12 source function
+@return HTTP message object
+@see parse_message_body
+]]
+
+---[[
+Try to extract and decode a http message body from the given ltn12 source.
+
+This function will examine the Content-Type within the given message object
+to select the appropriate content decoder.
+Currently the application/x-www-urlencoded and application/form-data
+mime types are supported. If the encountered content encoding can't be
+handled then the whole message body will be stored unaltered as "content"
+property within the given message object.
+@class function
+@name parse_message_body
+@param src Ltn12 source function
+@param msg HTTP message object
+@param filecb File data callback (optional, see mimedecode_message_body())
+@return Value indicating successful operation (not nil means "ok")
+@return String containing the error if unsuccessful
+@see parse_message_header
+]]
+
+---[[
+Table containing human readable messages for several http status codes.
+
+@class table
+]]
+
diff --git a/modules/luci-base/luasrc/http/protocol/conditionals.lua b/modules/luci-base/luasrc/http/protocol/conditionals.lua
index 1d40425ff9..d31a4e38a4 100644
--- a/modules/luci-base/luasrc/http/protocol/conditionals.lua
+++ b/modules/luci-base/luasrc/http/protocol/conditionals.lua
@@ -1,7 +1,6 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
---- LuCI http protocol implementation - HTTP/1.1 bits.
-- This class provides basic ETag handling and implements most of the
-- conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 .
module("luci.http.protocol.conditionals", package.seeall)
@@ -9,22 +8,14 @@ module("luci.http.protocol.conditionals", package.seeall)
local date = require("luci.http.protocol.date")
---- Implement 14.19 / ETag.
--- @param stat A file.stat structure
--- @return String containing the generated tag suitable for ETag headers
function mk_etag( stat )
if stat ~= nil then
return string.format( '"%x-%x-%x"', stat.ino, stat.size, stat.mtime )
end
end
---- 14.24 / If-Match
-- Test whether the given message object contains an "If-Match" header and
-- compare it against the given stat object.
--- @param req HTTP request message object
--- @param stat A file.stat object
--- @return Boolean indicating whether the precondition is ok
--- @return Alternative status code if the precondition failed
function if_match( req, stat )
local h = req.headers
local etag = mk_etag( stat )
@@ -43,14 +34,8 @@ function if_match( req, stat )
return true
end
---- 14.25 / If-Modified-Since
-- Test whether the given message object contains an "If-Modified-Since" header
-- and compare it against the given stat object.
--- @param req HTTP request message object
--- @param stat A file.stat object
--- @return Boolean indicating whether the precondition is ok
--- @return Alternative status code if the precondition failed
--- @return Table containing extra HTTP headers if the precondition failed
function if_modified_since( req, stat )
local h = req.headers
@@ -72,14 +57,8 @@ function if_modified_since( req, stat )
return true
end
---- 14.26 / If-None-Match
-- Test whether the given message object contains an "If-None-Match" header and
-- compare it against the given stat object.
--- @param req HTTP request message object
--- @param stat A file.stat object
--- @return Boolean indicating whether the precondition is ok
--- @return Alternative status code if the precondition failed
--- @return Table containing extra HTTP headers if the precondition failed
function if_none_match( req, stat )
local h = req.headers
local etag = mk_etag( stat )
@@ -105,26 +84,16 @@ function if_none_match( req, stat )
return true
end
---- 14.27 / If-Range
-- The If-Range header is currently not implemented due to the lack of general
-- byte range stuff in luci.http.protocol . This function will always return
-- false, 412 to indicate a failed precondition.
--- @param req HTTP request message object
--- @param stat A file.stat object
--- @return Boolean indicating whether the precondition is ok
--- @return Alternative status code if the precondition failed
function if_range( req, stat )
-- Sorry, no subranges (yet)
return false, 412
end
---- 14.28 / If-Unmodified-Since
-- Test whether the given message object contains an "If-Unmodified-Since"
-- header and compare it against the given stat object.
--- @param req HTTP request message object
--- @param stat A file.stat object
--- @return Boolean indicating whether the precondition is ok
--- @return Alternative status code if the precondition failed
function if_unmodified_since( req, stat )
local h = req.headers
diff --git a/modules/luci-base/luasrc/http/protocol/conditionals.luadoc b/modules/luci-base/luasrc/http/protocol/conditionals.luadoc
new file mode 100644
index 0000000000..9cfe02dd50
--- /dev/null
+++ b/modules/luci-base/luasrc/http/protocol/conditionals.luadoc
@@ -0,0 +1,85 @@
+---[[
+LuCI http protocol implementation - HTTP/1.1 bits.
+
+This class provides basic ETag handling and implements most of the
+conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 .
+]]
+module "luci.http.protocol.conditionals"
+
+---[[
+Implement 14.19 / ETag.
+
+@class function
+@name mk_etag
+@param stat A file.stat structure
+@return String containing the generated tag suitable for ETag headers
+]]
+
+---[[
+14.24 / If-Match
+
+Test whether the given message object contains an "If-Match" header and
+compare it against the given stat object.
+@class function
+@name if_match
+@param req HTTP request message object
+@param stat A file.stat object
+@return Boolean indicating whether the precondition is ok
+@return Alternative status code if the precondition failed
+]]
+
+---[[
+14.25 / If-Modified-Since
+
+Test whether the given message object contains an "If-Modified-Since" header
+and compare it against the given stat object.
+@class function
+@name if_modified_since
+@param req HTTP request message object
+@param stat A file.stat object
+@return Boolean indicating whether the precondition is ok
+@return Alternative status code if the precondition failed
+@return Table containing extra HTTP headers if the precondition failed
+]]
+
+---[[
+14.26 / If-None-Match
+
+Test whether the given message object contains an "If-None-Match" header and
+compare it against the given stat object.
+@class function
+@name if_none_match
+@param req HTTP request message object
+@param stat A file.stat object
+@return Boolean indicating whether the precondition is ok
+@return Alternative status code if the precondition failed
+@return Table containing extra HTTP headers if the precondition failed
+]]
+
+---[[
+14.27 / If-Range
+
+The If-Range header is currently not implemented due to the lack of general
+byte range stuff in luci.http.protocol . This function will always return
+false, 412 to indicate a failed precondition.
+@class function
+@name if_range
+@param req HTTP request message object
+@param stat A file.stat object
+@return Boolean indicating whether the precondition is ok
+@return Alternative status code if the precondition failed
+]]
+
+---[[
+14.28 / If-Unmodified-Since
+
+Test whether the given message object contains an "If-Unmodified-Since"
+header and compare it against the given stat object.
+@class function
+@name if_unmodified_since
+@param req HTTP request message object
+@param stat A file.stat object
+@return Boolean indicating whether the precondition is ok
+@return Alternative status code if the precondition failed
+]]
+
diff --git a/modules/luci-base/luasrc/http/protocol/date.lua b/modules/luci-base/luasrc/http/protocol/date.lua
index 3105f37f63..e440219a9c 100644
--- a/modules/luci-base/luasrc/http/protocol/date.lua
+++ b/modules/luci-base/luasrc/http/protocol/date.lua
@@ -1,7 +1,6 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
---- LuCI http protocol implementation - date helper class.
-- This class contains functions to parse, compare and format http dates.
module("luci.http.protocol.date", package.seeall)
@@ -13,9 +12,6 @@ MONTHS = {
"Sep", "Oct", "Nov", "Dec"
}
---- Return the time offset in seconds between the UTC and given time zone.
--- @param tz Symbolic or numeric timezone specifier
--- @return Time offset to UTC in seconds
function tz_offset(tz)
if type(tz) == "string" then
@@ -39,9 +35,6 @@ function tz_offset(tz)
return 0
end
---- Parse given HTTP date string and convert it to unix epoch time.
--- @param data String containing the date
--- @return Unix epoch time
function to_unix(date)
local wd, day, mon, yr, hr, min, sec, tz = date:match(
@@ -75,19 +68,10 @@ function to_unix(date)
return 0
end
---- Convert the given unix epoch time to valid HTTP date string.
--- @param time Unix epoch time
--- @return String containing the formatted date
function to_http(time)
return os.date( "%a, %d %b %Y %H:%M:%S GMT", time )
end
---- Compare two dates which can either be unix epoch times or HTTP date strings.
--- @param d1 The first date or epoch time to compare
--- @param d2 The first date or epoch time to compare
--- @return -1 - if d1 is lower then d2
--- @return 0 - if both dates are equal
--- @return 1 - if d1 is higher then d2
function compare(d1, d2)
if d1:match("[^0-9]") then d1 = to_unix(d1) end
diff --git a/modules/luci-base/luasrc/http/protocol/date.luadoc b/modules/luci-base/luasrc/http/protocol/date.luadoc
new file mode 100644
index 0000000000..d6f1c8d658
--- /dev/null
+++ b/modules/luci-base/luasrc/http/protocol/date.luadoc
@@ -0,0 +1,46 @@
+---[[
+LuCI http protocol implementation - date helper class.
+
+This class contains functions to parse, compare and format http dates.
+]]
+module "luci.http.protocol.date"
+
+---[[
+Return the time offset in seconds between the UTC and given time zone.
+
+@class function
+@name tz_offset
+@param tz Symbolic or numeric timezone specifier
+@return Time offset to UTC in seconds
+]]
+
+---[[
+Parse given HTTP date string and convert it to unix epoch time.
+
+@class function
+@name to_unix
+@param data String containing the date
+@return Unix epoch time
+]]
+
+---[[
+Convert the given unix epoch time to valid HTTP date string.
+
+@class function
+@name to_http
+@param time Unix epoch time
+@return String containing the formatted date
+]]
+
+---[[
+Compare two dates which can either be unix epoch times or HTTP date strings.
+
+@class function
+@name compare
+@param d1 The first date or epoch time to compare
+@param d2 The first date or epoch time to compare
+@return -1 - if d1 is lower then d2
+@return 0 - if both dates are equal
+@return 1 - if d1 is higher then d2
+]]
+
diff --git a/modules/luci-base/luasrc/http/protocol/mime.lua b/modules/luci-base/luasrc/http/protocol/mime.lua
index 15da15cf8b..2b99d8e74e 100644
--- a/modules/luci-base/luasrc/http/protocol/mime.lua
+++ b/modules/luci-base/luasrc/http/protocol/mime.lua
@@ -1,15 +1,12 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
---- LuCI http protocol implementation - mime helper class.
-- This class provides functions to guess mime types from file extensions and
-- vice versa.
module("luci.http.protocol.mime", package.seeall)
require("luci.util")
---- MIME mapping table containg extension - mimetype relations.
--- @class table
MIME_TYPES = {
["txt"] = "text/plain";
["js"] = "text/javascript";
@@ -54,10 +51,7 @@ MIME_TYPES = {
["avi"] = "video/x-msvideo";
}
---- Extract extension from a filename and return corresponding mime-type or
-- "application/octet-stream" if the extension is unknown.
--- @param filename The filename for which the mime type is guessed
--- @return String containign the determined mime type
function to_mime(filename)
if type(filename) == "string" then
local ext = filename:match("[^%.]+$")
@@ -70,10 +64,7 @@ function to_mime(filename)
return "application/octet-stream"
end
---- Return corresponding extension for a given mime type or nil if the
-- given mime-type is unknown.
--- @param mimetype The mimetype to retrieve the extension from
--- @return String with the extension or nil for unknown type
function to_ext(mimetype)
if type(mimetype) == "string" then
for ext, type in luci.util.kspairs( MIME_TYPES ) do
diff --git a/modules/luci-base/luasrc/http/protocol/mime.luadoc b/modules/luci-base/luasrc/http/protocol/mime.luadoc
new file mode 100644
index 0000000000..195b5fcc89
--- /dev/null
+++ b/modules/luci-base/luasrc/http/protocol/mime.luadoc
@@ -0,0 +1,34 @@
+---[[
+LuCI http protocol implementation - mime helper class.
+
+This class provides functions to guess mime types from file extensions and
+vice versa.
+]]
+module "luci.http.protocol.mime"
+
+---[[
+MIME mapping table containg extension - mimetype relations.
+
+@class table
+]]
+
+---[[
+Extract extension from a filename and return corresponding mime-type or
+
+"application/octet-stream" if the extension is unknown.
+@class function
+@name to_mime
+@param filename The filename for which the mime type is guessed
+@return String containign the determined mime type
+]]
+
+---[[
+Return corresponding extension for a given mime type or nil if the
+
+given mime-type is unknown.
+@class function
+@name to_ext
+@param mimetype The mimetype to retrieve the extension from
+@return String with the extension or nil for unknown type
+]]
+
diff --git a/modules/luci-base/luasrc/i18n.lua b/modules/luci-base/luasrc/i18n.lua
index dd84a59f84..bcb16d5c04 100644
--- a/modules/luci-base/luasrc/i18n.lua
+++ b/modules/luci-base/luasrc/i18n.lua
@@ -1,7 +1,6 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
---- LuCI translation library.
module("luci.i18n", package.seeall)
require("luci.util")
@@ -13,27 +12,16 @@ loaded = {}
context = luci.util.threadlocal()
default = "en"
---- Clear the translation table.
function clear()
end
---- Load a translation and copy its data into the translation table.
--- @param file Language file
--- @param lang Two-letter language code
--- @param force Force reload even if already loaded (optional)
--- @return Success status
function load(file, lang, force)
end
---- Load a translation file using the default translation language.
-- Alternatively load the translation of the fallback language.
--- @param file Language file
--- @param force Force reload even if already loaded (optional)
function loadc(file, force)
end
---- Set the context default translation language.
--- @param lang Two-letter language code
function setlanguage(lang)
context.lang = lang:gsub("_", "-")
context.parent = (context.lang:match("^([a-z][a-z])_"))
@@ -46,36 +34,22 @@ function setlanguage(lang)
return context.lang
end
---- Return the translated value for a specific translation key.
--- @param key Default translation text
--- @return Translated string
function translate(key)
return tparser.translate(key) or key
end
---- Return the translated value for a specific translation key and use it as sprintf pattern.
--- @param key Default translation text
--- @param ... Format parameters
--- @return Translated and formatted string
function translatef(key, ...)
return tostring(translate(key)):format(...)
end
---- Return the translated value for a specific translation key
-- and ensure that the returned value is a Lua string value.
-- This is the same as calling <code>tostring(translate(...))</code>
--- @param key Default translation text
--- @return Translated string
function string(key)
return tostring(translate(key))
end
---- Return the translated value for a specific translation key and use it as sprintf pattern.
-- Ensure that the returned value is a Lua string value.
-- This is the same as calling <code>tostring(translatef(...))</code>
--- @param key Default translation text
--- @param ... Format parameters
--- @return Translated and formatted string
function stringf(key, ...)
return tostring(translate(key)):format(...)
end
diff --git a/modules/luci-base/luasrc/i18n.luadoc b/modules/luci-base/luasrc/i18n.luadoc
new file mode 100644
index 0000000000..aa38841e17
--- /dev/null
+++ b/modules/luci-base/luasrc/i18n.luadoc
@@ -0,0 +1,84 @@
+---[[
+LuCI translation library.
+]]
+module "luci.i18n"
+
+---[[
+Clear the translation table.
+
+
+@class function
+@name clear
+]]
+
+---[[
+Load a translation and copy its data into the translation table.
+
+@class function
+@name load
+@param file Language file
+@param lang Two-letter language code
+@param force Force reload even if already loaded (optional)
+@return Success status
+]]
+
+---[[
+Load a translation file using the default translation language.
+
+Alternatively load the translation of the fallback language.
+@class function
+@name loadc
+@param file Language file
+@param force Force reload even if already loaded (optional)
+]]
+
+---[[
+Set the context default translation language.
+
+@class function
+@name setlanguage
+@param lang Two-letter language code
+]]
+
+---[[
+Return the translated value for a specific translation key.
+
+@class function
+@name translate
+@param key Default translation text
+@return Translated string
+]]
+
+---[[
+Return the translated value for a specific translation key and use it as sprintf pattern.
+
+@class function
+@name translatef
+@param key Default translation text
+@param ... Format parameters
+@return Translated and formatted string
+]]
+
+---[[
+Return the translated value for a specific translation key
+
+and ensure that the returned value is a Lua string value.
+This is the same as calling <code>tostring(translate(...))</code>
+@class function
+@name string
+@param key Default translation text
+@return Translated string
+]]
+
+---[[
+Return the translated value for a specific translation key and use it as sprintf pattern.
+
+Ensure that the returned value is a Lua string value.
+This is the same as calling <code>tostring(translatef(...))</code>
+@class function
+@name stringf
+@param key Default translation text
+@param ... Format parameters
+@return Translated and formatted string
+]]
+
diff --git a/modules/luci-base/luasrc/ip.lua b/modules/luci-base/luasrc/ip.lua
deleted file mode 100644
index d8aaea91d2..0000000000
--- a/modules/luci-base/luasrc/ip.lua
+++ /dev/null
@@ -1,661 +0,0 @@
--- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
--- Copyright 2008 Steven Barth <steven@midlink.org>
--- Licensed to the public under the Apache License 2.0.
-
---- LuCI IP calculation library.
-module( "luci.ip", package.seeall )
-
-require "nixio"
-local bit = nixio.bit
-local util = require "luci.util"
-
---- Boolean; true if system is little endian
-LITTLE_ENDIAN = not util.bigendian()
-
---- Boolean; true if system is big endian
-BIG_ENDIAN = not LITTLE_ENDIAN
-
---- Specifier for IPv4 address family
-FAMILY_INET4 = 0x04
-
---- Specifier for IPv6 address family
-FAMILY_INET6 = 0x06
-
-
-local function __bless(x)
- return setmetatable( x, {
- __index = luci.ip.cidr,
- __add = luci.ip.cidr.add,
- __sub = luci.ip.cidr.sub,
- __lt = luci.ip.cidr.lower,
- __eq = luci.ip.cidr.equal,
- __le =
- function(...)
- return luci.ip.cidr.equal(...) or luci.ip.cidr.lower(...)
- end
- } )
-end
-
-local function __array16( x, family )
- local list
-
- if type(x) == "number" then
- list = { bit.rshift(x, 16), bit.band(x, 0xFFFF) }
-
- elseif type(x) == "string" then
- if x:find(":") then x = IPv6(x) else x = IPv4(x) end
- if x then
- assert( x[1] == family, "Can't mix IPv4 and IPv6 addresses" )
- list = { unpack(x[2]) }
- end
-
- elseif type(x) == "table" and type(x[2]) == "table" then
- assert( x[1] == family, "Can't mix IPv4 and IPv6 addresses" )
- list = { unpack(x[2]) }
-
- elseif type(x) == "table" then
- list = { unpack(x) }
- end
-
- assert( list, "Invalid operand" )
-
- return list
-end
-
-local function __mask16(bits)
- return bit.lshift( bit.rshift( 0xFFFF, 16 - bits % 16 ), 16 - bits % 16 )
-end
-
-local function __not16(bits)
- return bit.band( bit.bnot( __mask16(bits) ), 0xFFFF )
-end
-
-local function __maxlen(family)
- return ( family == FAMILY_INET4 ) and 32 or 128
-end
-
-local function __sublen(family)
- return ( family == FAMILY_INET4 ) and 30 or 127
-end
-
-
---- Convert given short value to network byte order on little endian hosts
--- @param x Unsigned integer value between 0x0000 and 0xFFFF
--- @return Byte-swapped value
--- @see htonl
--- @see ntohs
-function htons(x)
- if LITTLE_ENDIAN then
- return bit.bor(
- bit.rshift( x, 8 ),
- bit.band( bit.lshift( x, 8 ), 0xFF00 )
- )
- else
- return x
- end
-end
-
---- Convert given long value to network byte order on little endian hosts
--- @param x Unsigned integer value between 0x00000000 and 0xFFFFFFFF
--- @return Byte-swapped value
--- @see htons
--- @see ntohl
-function htonl(x)
- if LITTLE_ENDIAN then
- return bit.bor(
- bit.lshift( htons( bit.band( x, 0xFFFF ) ), 16 ),
- htons( bit.rshift( x, 16 ) )
- )
- else
- return x
- end
-end
-
---- Convert given short value to host byte order on little endian hosts
--- @class function
--- @name ntohs
--- @param x Unsigned integer value between 0x0000 and 0xFFFF
--- @return Byte-swapped value
--- @see htonl
--- @see ntohs
-ntohs = htons
-
---- Convert given short value to host byte order on little endian hosts
--- @class function
--- @name ntohl
--- @param x Unsigned integer value between 0x00000000 and 0xFFFFFFFF
--- @return Byte-swapped value
--- @see htons
--- @see ntohl
-ntohl = htonl
-
-
---- Parse given IPv4 address in dotted quad or CIDR notation. If an optional
--- netmask is given as second argument and the IP address is encoded in CIDR
--- notation then the netmask parameter takes precedence. If neither a CIDR
--- encoded prefix nor a netmask parameter is given, then a prefix length of
--- 32 bit is assumed.
--- @param address IPv4 address in dotted quad or CIDR notation
--- @param netmask IPv4 netmask in dotted quad notation (optional)
--- @return luci.ip.cidr instance or nil if given address was invalid
--- @see IPv6
--- @see Hex
-function IPv4(address, netmask)
- address = address or "0.0.0.0/0"
-
- local obj = __bless({ FAMILY_INET4 })
-
- local data = {}
- local prefix = address:match("/(.+)")
- address = address:gsub("/.+","")
- address = address:gsub("^%[(.*)%]$", "%1"):upper():gsub("^::FFFF:", "")
-
- if netmask then
- prefix = obj:prefix(netmask)
- elseif prefix then
- prefix = tonumber(prefix)
- if not prefix or prefix < 0 or prefix > 32 then return nil end
- else
- prefix = 32
- end
-
- local b1, b2, b3, b4 = address:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
-
- b1 = tonumber(b1)
- b2 = tonumber(b2)
- b3 = tonumber(b3)
- b4 = tonumber(b4)
-
- if b1 and b1 <= 255 and
- b2 and b2 <= 255 and
- b3 and b3 <= 255 and
- b4 and b4 <= 255 and
- prefix
- then
- table.insert(obj, { b1 * 256 + b2, b3 * 256 + b4 })
- table.insert(obj, prefix)
- return obj
- end
-end
-
---- Parse given IPv6 address in full, compressed, mixed or CIDR notation.
--- If an optional netmask is given as second argument and the IP address is
--- encoded in CIDR notation then the netmask parameter takes precedence.
--- If neither a CIDR encoded prefix nor a netmask parameter is given, then a
--- prefix length of 128 bit is assumed.
--- @param address IPv6 address in full/compressed/mixed or CIDR notation
--- @param netmask IPv6 netmask in full/compressed/mixed notation (optional)
--- @return luci.ip.cidr instance or nil if given address was invalid
--- @see IPv4
--- @see Hex
-function IPv6(address, netmask)
- address = address or "::/0"
-
- local obj = __bless({ FAMILY_INET6 })
-
- local data = {}
- local prefix = address:match("/(.+)")
- address = address:gsub("/.+","")
- address = address:gsub("^%[(.*)%]$", "%1")
-
- if netmask then
- prefix = obj:prefix(netmask)
- elseif prefix then
- prefix = tonumber(prefix)
- if not prefix or prefix < 0 or prefix > 128 then return nil end
- else
- prefix = 128
- end
-
- local borderl = address:sub(1, 1) == ":" and 2 or 1
- local borderh, zeroh, chunk, block, i
-
- if #address > 45 then return nil end
-
- repeat
- borderh = address:find(":", borderl, true)
- if not borderh then break end
-
- block = tonumber(address:sub(borderl, borderh - 1), 16)
- if block and block <= 0xFFFF then
- data[#data+1] = block
- else
- if zeroh or borderh - borderl > 1 then return nil end
- zeroh = #data + 1
- end
-
- borderl = borderh + 1
- until #data == 7
-
- chunk = address:sub(borderl)
- if #chunk > 0 and #chunk <= 4 then
- block = tonumber(chunk, 16)
- if not block or block > 0xFFFF then return nil end
-
- data[#data+1] = block
- elseif #chunk > 4 then
- if #data == 7 or #chunk > 15 then return nil end
- borderl = 1
- for i=1, 4 do
- borderh = chunk:find(".", borderl, true)
- if not borderh and i < 4 then return nil end
- borderh = borderh and borderh - 1
-
- block = tonumber(chunk:sub(borderl, borderh))
- if not block or block > 255 then return nil end
-
- if i == 1 or i == 3 then
- data[#data+1] = block * 256
- else
- data[#data] = data[#data] + block
- end
-
- borderl = borderh and borderh + 2
- end
- end
-
- if zeroh then
- if #data == 8 then return nil end
- while #data < 8 do
- table.insert(data, zeroh, 0)
- end
- end
-
- if #data == 8 and prefix then
- table.insert(obj, data)
- table.insert(obj, prefix)
- return obj
- end
-end
-
---- Transform given hex-encoded value to luci.ip.cidr instance of specified
--- address family.
--- @param hex String containing hex encoded value
--- @param prefix Prefix length of CIDR instance (optional, default is 32/128)
--- @param family Address family, either luci.ip.FAMILY_INET4 or FAMILY_INET6
--- @param swap Bool indicating whether to swap byteorder on low endian host
--- @return luci.ip.cidr instance or nil if given value was invalid
--- @see IPv4
--- @see IPv6
-function Hex( hex, prefix, family, swap )
- family = ( family ~= nil ) and family or FAMILY_INET4
- swap = ( swap == nil ) and true or swap
- prefix = prefix or __maxlen(family)
-
- local len = __maxlen(family)
- local tmp = ""
- local data = { }
- local i
-
- for i = 1, (len/4) - #hex do tmp = tmp .. '0' end
-
- if swap and LITTLE_ENDIAN then
- for i = #hex, 1, -2 do tmp = tmp .. hex:sub( i - 1, i ) end
- else
- tmp = tmp .. hex
- end
-
- hex = tmp
-
- for i = 1, ( len / 4 ), 4 do
- local n = tonumber( hex:sub( i, i+3 ), 16 )
- if n then
- data[#data+1] = n
- else
- return nil
- end
- end
-
- return __bless({ family, data, prefix })
-end
-
-
---- LuCI IP Library / CIDR instances
--- @class module
--- @cstyle instance
--- @name luci.ip.cidr
-cidr = util.class()
-
---- Test whether the instance is a IPv4 address.
--- @return Boolean indicating a IPv4 address type
--- @see cidr.is6
-function cidr.is4( self )
- return self[1] == FAMILY_INET4
-end
-
---- Test whether this instance is an IPv4 RFC1918 private address
--- @return Boolean indicating whether this instance is an RFC1918 address
-function cidr.is4rfc1918( self )
- if self[1] == FAMILY_INET4 then
- return ((self[2][1] >= 0x0A00) and (self[2][1] <= 0x0AFF)) or
- ((self[2][1] >= 0xAC10) and (self[2][1] <= 0xAC1F)) or
- (self[2][1] == 0xC0A8)
- end
- return false
-end
-
---- Test whether this instance is an IPv4 link-local address (Zeroconf)
--- @return Boolean indicating whether this instance is IPv4 link-local
-function cidr.is4linklocal( self )
- if self[1] == FAMILY_INET4 then
- return (self[2][1] == 0xA9FE)
- end
- return false
-end
-
---- Test whether the instance is a IPv6 address.
--- @return Boolean indicating a IPv6 address type
--- @see cidr.is4
-function cidr.is6( self )
- return self[1] == FAMILY_INET6
-end
-
---- Test whether this instance is an IPv6 link-local address
--- @return Boolean indicating whether this instance is IPv6 link-local
-function cidr.is6linklocal( self )
- if self[1] == FAMILY_INET6 then
- return (self[2][1] >= 0xFE80) and (self[2][1] <= 0xFEBF)
- end
- return false
-end
-
---- Return a corresponding string representation of the instance.
--- If the prefix length is lower then the maximum possible prefix length for the
--- corresponding address type then the address is returned in CIDR notation,
--- otherwise the prefix will be left out.
-function cidr.string( self )
- local str
- if self:is4() then
- str = string.format(
- "%d.%d.%d.%d",
- bit.rshift(self[2][1], 8), bit.band(self[2][1], 0xFF),
- bit.rshift(self[2][2], 8), bit.band(self[2][2], 0xFF)
- )
- if self[3] < 32 then
- str = str .. "/" .. self[3]
- end
- elseif self:is6() then
- str = string.format( "%X:%X:%X:%X:%X:%X:%X:%X", unpack(self[2]) )
- if self[3] < 128 then
- str = str .. "/" .. self[3]
- end
- end
- return str
-end
-
---- Test whether the value of the instance is lower then the given address.
--- This function will throw an exception if the given address has a different
--- family than this instance.
--- @param addr A luci.ip.cidr instance to compare against
--- @return Boolean indicating whether this instance is lower
--- @see cidr.higher
--- @see cidr.equal
-function cidr.lower( self, addr )
- assert( self[1] == addr[1], "Can't compare IPv4 and IPv6 addresses" )
- local i
- for i = 1, #self[2] do
- if self[2][i] ~= addr[2][i] then
- return self[2][i] < addr[2][i]
- end
- end
- return false
-end
-
---- Test whether the value of the instance is higher then the given address.
--- This function will throw an exception if the given address has a different
--- family than this instance.
--- @param addr A luci.ip.cidr instance to compare against
--- @return Boolean indicating whether this instance is higher
--- @see cidr.lower
--- @see cidr.equal
-function cidr.higher( self, addr )
- assert( self[1] == addr[1], "Can't compare IPv4 and IPv6 addresses" )
- local i
- for i = 1, #self[2] do
- if self[2][i] ~= addr[2][i] then
- return self[2][i] > addr[2][i]
- end
- end
- return false
-end
-
---- Test whether the value of the instance is equal to the given address.
--- This function will throw an exception if the given address is a different
--- family than this instance.
--- @param addr A luci.ip.cidr instance to compare against
--- @return Boolean indicating whether this instance is equal
--- @see cidr.lower
--- @see cidr.higher
-function cidr.equal( self, addr )
- assert( self[1] == addr[1], "Can't compare IPv4 and IPv6 addresses" )
- local i
- for i = 1, #self[2] do
- if self[2][i] ~= addr[2][i] then
- return false
- end
- end
- return true
-end
-
---- Return the prefix length of this CIDR instance.
--- @param mask Override instance prefix with given netmask (optional)
--- @return Prefix length in bit
-function cidr.prefix( self, mask )
- local prefix = self[3]
-
- if mask then
- prefix = 0
-
- local stop = false
- local obj = type(mask) ~= "table"
- and ( self:is4() and IPv4(mask) or IPv6(mask) ) or mask
-
- if not obj then return nil end
-
- local _, word
- for _, word in ipairs(obj[2]) do
- if word == 0xFFFF then
- prefix = prefix + 16
- else
- local bitmask = bit.lshift(1, 15)
- while bit.band(word, bitmask) == bitmask do
- prefix = prefix + 1
- bitmask = bit.lshift(1, 15 - (prefix % 16))
- end
-
- break
- end
- end
- end
-
- return prefix
-end
-
---- Return a corresponding CIDR representing the network address of this
--- instance.
--- @param bits Override prefix length of this instance (optional)
--- @return CIDR instance containing the network address
--- @see cidr.host
--- @see cidr.broadcast
--- @see cidr.mask
-function cidr.network( self, bits )
- local data = { }
- bits = bits or self[3]
-
- local i
- for i = 1, math.floor( bits / 16 ) do
- data[#data+1] = self[2][i]
- end
-
- if #data < #self[2] then
- data[#data+1] = bit.band( self[2][1+#data], __mask16(bits) )
-
- for i = #data + 1, #self[2] do
- data[#data+1] = 0
- end
- end
-
- return __bless({ self[1], data, __maxlen(self[1]) })
-end
-
---- Return a corresponding CIDR representing the host address of this
--- instance. This is intended to extract the host address from larger subnet.
--- @return CIDR instance containing the network address
--- @see cidr.network
--- @see cidr.broadcast
--- @see cidr.mask
-function cidr.host( self )
- return __bless({ self[1], self[2], __maxlen(self[1]) })
-end
-
---- Return a corresponding CIDR representing the netmask of this instance.
--- @param bits Override prefix length of this instance (optional)
--- @return CIDR instance containing the netmask
--- @see cidr.network
--- @see cidr.host
--- @see cidr.broadcast
-function cidr.mask( self, bits )
- local data = { }
- bits = bits or self[3]
-
- for i = 1, math.floor( bits / 16 ) do
- data[#data+1] = 0xFFFF
- end
-
- if #data < #self[2] then
- data[#data+1] = __mask16(bits)
-
- for i = #data + 1, #self[2] do
- data[#data+1] = 0
- end
- end
-
- return __bless({ self[1], data, __maxlen(self[1]) })
-end
-
---- Return CIDR containing the broadcast address of this instance.
--- @return CIDR instance containing the netmask, always nil for IPv6
--- @see cidr.network
--- @see cidr.host
--- @see cidr.mask
-function cidr.broadcast( self )
- -- IPv6 has no broadcast addresses (XXX: assert() instead?)
- if self[1] == FAMILY_INET4 then
- local data = { unpack(self[2]) }
- local offset = math.floor( self[3] / 16 ) + 1
-
- if offset <= #data then
- data[offset] = bit.bor( data[offset], __not16(self[3]) )
- for i = offset + 1, #data do data[i] = 0xFFFF end
-
- return __bless({ self[1], data, __maxlen(self[1]) })
- end
- end
-end
-
---- Test whether this instance fully contains the given CIDR instance.
--- @param addr CIDR instance to test against
--- @return Boolean indicating whether this instance contains the given CIDR
-function cidr.contains( self, addr )
- assert( self[1] == addr[1], "Can't compare IPv4 and IPv6 addresses" )
-
- if self:prefix() <= addr:prefix() then
- return self:network() == addr:network(self:prefix())
- end
-
- return false
-end
-
---- Add specified amount of hosts to this instance.
--- @param amount Number of hosts to add to this instance
--- @param inplace Boolen indicating whether to alter values inplace (optional)
--- @return CIDR representing the new address or nil on overflow error
--- @see cidr.sub
-function cidr.add( self, amount, inplace )
- local pos
- local data = { unpack(self[2]) }
- local shorts = __array16( amount, self[1] )
-
- for pos = #data, 1, -1 do
- local add = ( #shorts > 0 ) and table.remove( shorts, #shorts ) or 0
- if ( data[pos] + add ) > 0xFFFF then
- data[pos] = ( data[pos] + add ) % 0xFFFF
- if pos > 1 then
- data[pos-1] = data[pos-1] + ( add - data[pos] )
- else
- return nil
- end
- else
- data[pos] = data[pos] + add
- end
- end
-
- if inplace then
- self[2] = data
- return self
- else
- return __bless({ self[1], data, self[3] })
- end
-end
-
---- Substract specified amount of hosts from this instance.
--- @param amount Number of hosts to substract from this instance
--- @param inplace Boolen indicating whether to alter values inplace (optional)
--- @return CIDR representing the new address or nil on underflow error
--- @see cidr.add
-function cidr.sub( self, amount, inplace )
- local pos
- local data = { unpack(self[2]) }
- local shorts = __array16( amount, self[1] )
-
- for pos = #data, 1, -1 do
- local sub = ( #shorts > 0 ) and table.remove( shorts, #shorts ) or 0
- if ( data[pos] - sub ) < 0 then
- data[pos] = ( sub - data[pos] ) % 0xFFFF
- if pos > 1 then
- data[pos-1] = data[pos-1] - ( sub + data[pos] )
- else
- return nil
- end
- else
- data[pos] = data[pos] - sub
- end
- end
-
- if inplace then
- self[2] = data
- return self
- else
- return __bless({ self[1], data, self[3] })
- end
-end
-
---- Return CIDR containing the lowest available host address within this subnet.
--- @return CIDR containing the host address, nil if subnet is too small
--- @see cidr.maxhost
-function cidr.minhost( self )
- if self[3] <= __sublen(self[1]) then
- -- 1st is Network Address in IPv4 and Subnet-Router Anycast Adresse in IPv6
- return self:network():add(1, true)
- end
-end
-
---- Return CIDR containing the highest available host address within the subnet.
--- @return CIDR containing the host address, nil if subnet is too small
--- @see cidr.minhost
-function cidr.maxhost( self )
- if self[3] <= __sublen(self[1]) then
- local i
- local data = { unpack(self[2]) }
- local offset = math.floor( self[3] / 16 ) + 1
-
- data[offset] = bit.bor( data[offset], __not16(self[3]) )
- for i = offset + 1, #data do data[i] = 0xFFFF end
- data = __bless({ self[1], data, __maxlen(self[1]) })
-
- -- Last address in reserved for Broadcast Address in IPv4
- if data[1] == FAMILY_INET4 then data:sub(1, true) end
-
- return data
- end
-end
diff --git a/modules/luci-base/luasrc/ltn12.lua b/modules/luci-base/luasrc/ltn12.lua
index b59fb8c48a..3a7268ccae 100644
--- a/modules/luci-base/luasrc/ltn12.lua
+++ b/modules/luci-base/luasrc/ltn12.lua
@@ -39,7 +39,6 @@ local string = require("string")
local table = require("table")
local base = _G
---- Diego Nehab's LTN12 - Filters, sources, sinks and pumps.
-- See http://lua-users.org/wiki/FiltersSourcesAndSinks for design concepts
module("luci.ltn12")
@@ -56,16 +55,8 @@ _VERSION = "LTN12 1.0.1"
-- Filter stuff
-----------------------------------------------------------------------------
---- LTN12 Filter constructors
--- @class module
--- @name luci.ltn12.filter
---- Return a high level filter that cycles a low-level filter
-- by passing it each chunk and updating a context between calls.
--- @param low Low-level filter
--- @param ctx Context
--- @param extra Extra argument passed to the low-level filter
--- @return LTN12 filter
function filter.cycle(low, ctx, extra)
base.assert(low)
return function(chunk)
@@ -75,10 +66,7 @@ function filter.cycle(low, ctx, extra)
end
end
---- Chain a bunch of filters together.
-- (thanks to Wim Couwenberg)
--- @param ... filters to be chained
--- @return LTN12 filter
function filter.chain(...)
local n = table.getn(arg)
local top, index = 1, 1
@@ -112,34 +100,22 @@ end
-- Source stuff
-----------------------------------------------------------------------------
---- LTN12 Source constructors
--- @class module
--- @name luci.ltn12.source
-- create an empty source
local function empty()
return nil
end
---- Create an empty source.
--- @return LTN12 source
function source.empty()
return empty
end
---- Return a source that just outputs an error.
--- @param err Error object
--- @return LTN12 source
function source.error(err)
return function()
return nil, err
end
end
---- Create a file source.
--- @param handle File handle ready for reading
--- @param io_err IO error object
--- @return LTN12 source
function source.file(handle, io_err)
if handle then
return function()
@@ -151,9 +127,6 @@ function source.file(handle, io_err)
else return source.error(io_err or "unable to open file") end
end
---- Turn a fancy source into a simple source.
--- @param src fancy source
--- @return LTN12 source
function source.simplify(src)
base.assert(src)
return function()
@@ -164,9 +137,6 @@ function source.simplify(src)
end
end
---- Create a string source.
--- @param s Data
--- @return LTN12 source
function source.string(s)
if s then
local i = 1
@@ -179,9 +149,6 @@ function source.string(s)
else return source.empty() end
end
---- Creates rewindable source.
--- @param src LTN12 source to be made rewindable
--- @return LTN12 source
function source.rewind(src)
base.assert(src)
local t = {}
@@ -196,10 +163,6 @@ function source.rewind(src)
end
end
---- Chain a source and a filter together.
--- @param src LTN12 source
--- @param f LTN12 filter
--- @return LTN12 source
function source.chain(src, f)
base.assert(src and f)
local last_in, last_out = "", ""
@@ -247,11 +210,8 @@ function source.chain(src, f)
end
end
---- Create a source that produces contents of several sources.
-- Sources will be used one after the other, as if they were concatenated
-- (thanks to Wim Couwenberg)
--- @param ... LTN12 sources
--- @return LTN12 source
function source.cat(...)
local src = table.remove(arg, 1)
return function()
@@ -268,13 +228,7 @@ end
-- Sink stuff
-----------------------------------------------------------------------------
---- LTN12 sink constructors
--- @class module
--- @name luci.ltn12.sink
---- Create a sink that stores into a table.
--- @param t output table to store into
--- @return LTN12 sink
function sink.table(t)
t = t or {}
local f = function(chunk, err)
@@ -284,9 +238,6 @@ function sink.table(t)
return f, t
end
---- Turn a fancy sink into a simple sink.
--- @param snk fancy sink
--- @return LTN12 sink
function sink.simplify(snk)
base.assert(snk)
return function(chunk, err)
@@ -297,10 +248,6 @@ function sink.simplify(snk)
end
end
---- Create a file sink.
--- @param handle file handle to write to
--- @param io_err IO error
--- @return LTN12 sink
function sink.file(handle, io_err)
if handle then
return function(chunk, err)
@@ -317,25 +264,16 @@ local function null()
return 1
end
---- Create a sink that discards data.
--- @return LTN12 sink
function sink.null()
return null
end
---- Create a sink that just returns an error.
--- @param err Error object
--- @return LTN12 sink
function sink.error(err)
return function()
return nil, err
end
end
---- Chain a sink with a filter.
--- @param f LTN12 filter
--- @param snk LTN12 sink
--- @return LTN12 sink
function sink.chain(f, snk)
base.assert(f and snk)
return function(chunk, err)
@@ -356,15 +294,7 @@ end
-- Pump stuff
-----------------------------------------------------------------------------
---- LTN12 pump functions
--- @class module
--- @name luci.ltn12.pump
---- Pump one chunk from the source to the sink.
--- @param src LTN12 source
--- @param snk LTN12 sink
--- @return Chunk of data or nil if an error occured
--- @return Error object
function pump.step(src, snk)
local chunk, src_err = src()
local ret, snk_err = snk(chunk, src_err)
@@ -372,12 +302,6 @@ function pump.step(src, snk)
else return nil, src_err or snk_err end
end
---- Pump all data from a source to a sink, using a step function.
--- @param src LTN12 source
--- @param snk LTN12 sink
--- @param step step function (optional)
--- @return 1 if the operation succeeded otherwise nil
--- @return Error object
function pump.all(src, snk, step)
base.assert(src and snk)
step = step or pump.step
diff --git a/modules/luci-base/luasrc/model/ipkg.lua b/modules/luci-base/luasrc/model/ipkg.lua
index 216caa5cca..587637272d 100644
--- a/modules/luci-base/luasrc/model/ipkg.lua
+++ b/modules/luci-base/luasrc/model/ipkg.lua
@@ -15,7 +15,6 @@ local table = table
local ipkg = "opkg --force-removal-of-dependent-packages --force-overwrite --nocase"
local icfg = "/etc/opkg.conf"
---- LuCI OPKG call abstraction library
module "luci.model.ipkg"
@@ -93,54 +92,31 @@ local function _lookup(act, pkg)
end
---- Return information about installed and available packages.
--- @param pkg Limit output to a (set of) packages
--- @return Table containing package information
function info(pkg)
return _lookup("info", pkg)
end
---- Return the package status of one or more packages.
--- @param pkg Limit output to a (set of) packages
--- @return Table containing package status information
function status(pkg)
return _lookup("status", pkg)
end
---- Install one or more packages.
--- @param ... List of packages to install
--- @return Boolean indicating the status of the action
--- @return OPKG return code, STDOUT and STDERR
function install(...)
return _action("install", ...)
end
---- Determine whether a given package is installed.
--- @param pkg Package
--- @return Boolean
function installed(pkg)
local p = status(pkg)[pkg]
return (p and p.Status and p.Status.installed)
end
---- Remove one or more packages.
--- @param ... List of packages to install
--- @return Boolean indicating the status of the action
--- @return OPKG return code, STDOUT and STDERR
function remove(...)
return _action("remove", ...)
end
---- Update package lists.
--- @return Boolean indicating the status of the action
--- @return OPKG return code, STDOUT and STDERR
function update()
return _action("update")
end
---- Upgrades all installed packages.
--- @return Boolean indicating the status of the action
--- @return OPKG return code, STDOUT and STDERR
function upgrade()
return _action("upgrade")
end
@@ -174,33 +150,19 @@ function _list(action, pat, cb)
end
end
---- List all packages known to opkg.
--- @param pat Only find packages matching this pattern, nil lists all packages
--- @param cb Callback function invoked for each package, receives name, version and description as arguments
--- @return nothing
function list_all(pat, cb)
_list("list", pat, cb)
end
---- List installed packages.
--- @param pat Only find packages matching this pattern, nil lists all packages
--- @param cb Callback function invoked for each package, receives name, version and description as arguments
--- @return nothing
function list_installed(pat, cb)
_list("list_installed", pat, cb)
end
---- Find packages that match the given pattern.
--- @param pat Find packages whose names or descriptions match this pattern, nil results in zero results
--- @param cb Callback function invoked for each patckage, receives name, version and description as arguments
--- @return nothing
function find(pat, cb)
_list("find", pat, cb)
end
---- Determines the overlay root used by opkg.
--- @return String containing the directory path of the overlay root.
function overlay_root()
local od = "/"
local fd = io.open(icfg, "r")
diff --git a/modules/luci-base/luasrc/model/ipkg.luadoc b/modules/luci-base/luasrc/model/ipkg.luadoc
new file mode 100644
index 0000000000..cf0985f94a
--- /dev/null
+++ b/modules/luci-base/luasrc/model/ipkg.luadoc
@@ -0,0 +1,109 @@
+---[[
+LuCI OPKG call abstraction library
+
+module "luci.model.ipkg"
+]]
+
+---[[
+Return information about installed and available packages.
+
+@class function
+@name info
+@param pkg Limit output to a (set of) packages
+@return Table containing package information
+]]
+
+---[[
+Return the package status of one or more packages.
+
+@class function
+@name status
+@param pkg Limit output to a (set of) packages
+@return Table containing package status information
+]]
+
+---[[
+Install one or more packages.
+
+@class function
+@name install
+@param ... List of packages to install
+@return Boolean indicating the status of the action
+@return OPKG return code, STDOUT and STDERR
+]]
+
+---[[
+Determine whether a given package is installed.
+
+@class function
+@name installed
+@param pkg Package
+@return Boolean
+]]
+
+---[[
+Remove one or more packages.
+
+@class function
+@name remove
+@param ... List of packages to install
+@return Boolean indicating the status of the action
+@return OPKG return code, STDOUT and STDERR
+]]
+
+---[[
+Update package lists.
+
+@class function
+@name update
+@return Boolean indicating the status of the action
+@return OPKG return code, STDOUT and STDERR
+]]
+
+---[[
+Upgrades all installed packages.
+
+@class function
+@name upgrade
+@return Boolean indicating the status of the action
+@return OPKG return code, STDOUT and STDERR
+]]
+
+---[[
+List all packages known to opkg.
+
+@class function
+@name list_all
+@param pat Only find packages matching this pattern, nil lists all packages
+@param cb Callback function invoked for each package, receives name, version and description as arguments
+@return nothing
+]]
+
+---[[
+List installed packages.
+
+@class function
+@name list_installed
+@param pat Only find packages matching this pattern, nil lists all packages
+@param cb Callback function invoked for each package, receives name, version and description as arguments
+@return nothing
+]]
+
+---[[
+Find packages that match the given pattern.
+
+@class function
+@name find
+@param pat Find packages whose names or descriptions match this pattern, nil results in zero results
+@param cb Callback function invoked for each patckage, receives name, version and description as arguments
+@return nothing
+]]
+
+---[[
+Determines the overlay root used by opkg.
+
+@class function
+@name overlay_root
+@return String containing the directory path of the overlay root.
+]]
+
diff --git a/modules/luci-base/luasrc/model/uci.lua b/modules/luci-base/luasrc/model/uci.lua
index 8ac82773f3..1659137742 100644
--- a/modules/luci-base/luasrc/model/uci.lua
+++ b/modules/luci-base/luasrc/model/uci.lua
@@ -12,26 +12,18 @@ local require, getmetatable = require, getmetatable
local error, pairs, ipairs = error, pairs, ipairs
local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack
---- LuCI UCI model library.
-- The typical workflow for UCI is: Get a cursor instance from the
-- cursor factory, modify data (via Cursor.add, Cursor.delete, etc.),
-- save the changes to the staging area via Cursor.save and finally
-- Cursor.commit the data to the actual config files.
-- LuCI then needs to Cursor.apply the changes so deamons etc. are
-- reloaded.
--- @cstyle instance
module "luci.model.uci"
---- Create a new UCI-Cursor.
--- @class function
--- @name cursor
--- @return UCI-Cursor
cursor = uci.cursor
APIVERSION = uci.APIVERSION
---- Create a new Cursor initialized to the state directory.
--- @return UCI cursor
function cursor_state()
return cursor(nil, "/var/state")
end
@@ -42,9 +34,6 @@ inst_state = cursor_state()
local Cursor = getmetatable(inst)
---- Applies UCI configuration changes
--- @param configlist List of UCI configurations
--- @param command Don't apply only return the command
function Cursor.apply(self, configlist, command)
configlist = self:_affected(configlist)
if command then
@@ -56,10 +45,6 @@ function Cursor.apply(self, configlist, command)
end
---- Delete all sections of a given type that match certain criteria.
--- @param config UCI config
--- @param type UCI section type
--- @param comparator Function that will be called for each section and
-- returns a boolean whether to delete the current section (optional)
function Cursor.delete_all(self, config, stype, comparator)
local del = {}
@@ -90,12 +75,6 @@ function Cursor.delete_all(self, config, stype, comparator)
end
end
---- Create a new section and initialize it with data.
--- @param config UCI config
--- @param type UCI section type
--- @param name UCI section name (optional)
--- @param values Table of key - value pairs to initialize the section with
--- @return Name of created section
function Cursor.section(self, config, type, name, values)
local stat = true
if name then
@@ -112,10 +91,6 @@ function Cursor.section(self, config, type, name, values)
return stat and name
end
---- Updated the data of a section using data from a table.
--- @param config UCI config
--- @param section UCI section name (optional)
--- @param values Table of key - value pairs to update the section with
function Cursor.tset(self, config, section, values)
local stat = true
for k, v in pairs(values) do
@@ -126,21 +101,11 @@ function Cursor.tset(self, config, section, values)
return stat
end
---- Get a boolean option and return it's value as true or false.
--- @param config UCI config
--- @param section UCI section name
--- @param option UCI option
--- @return Boolean
function Cursor.get_bool(self, ...)
local val = self:get(...)
return ( val == "1" or val == "true" or val == "yes" or val == "on" )
end
---- Get an option or list and return values as table.
--- @param config UCI config
--- @param section UCI section name
--- @param option UCI option
--- @return UCI value
function Cursor.get_list(self, config, section, option)
if config and section and option then
local val = self:get(config, section, option)
@@ -149,12 +114,6 @@ function Cursor.get_list(self, config, section, option)
return nil
end
---- Get the given option from the first section with the given type.
--- @param config UCI config
--- @param type UCI section type
--- @param option UCI option (optional)
--- @param default Default value (optional)
--- @return UCI value
function Cursor.get_first(self, conf, stype, opt, def)
local rv = def
@@ -178,12 +137,6 @@ function Cursor.get_first(self, conf, stype, opt, def)
return rv
end
---- Set given values as list.
--- @param config UCI config
--- @param section UCI section name
--- @param option UCI option
--- @param value UCI value
--- @return Boolean whether operation succeeded
function Cursor.set_list(self, config, section, option, value)
if config and section and option then
return self:set(
@@ -238,10 +191,8 @@ function Cursor._affected(self, configlist)
return reloadlist
end
---- Create a sub-state of this cursor. The sub-state is tied to the parent
-- curser, means it the parent unloads or loads configs, the sub state will
-- do so as well.
--- @return UCI state cursor tied to the parent cursor
function Cursor.substate(self)
Cursor._substates = Cursor._substates or { }
Cursor._substates[self] = Cursor._substates[self] or cursor_state()
@@ -265,118 +216,18 @@ function Cursor.unload(self, ...)
end
---- Add an anonymous section.
--- @class function
--- @name Cursor.add
--- @param config UCI config
--- @param type UCI section type
--- @return Name of created section
-
---- Get a table of saved but uncommitted changes.
--- @class function
--- @name Cursor.changes
--- @param config UCI config
--- @return Table of changes
--- @see Cursor.save
-
---- Commit saved changes.
--- @class function
--- @name Cursor.commit
--- @param config UCI config
--- @return Boolean whether operation succeeded
--- @see Cursor.revert
--- @see Cursor.save
-
---- Deletes a section or an option.
--- @class function
--- @name Cursor.delete
--- @param config UCI config
--- @param section UCI section name
--- @param option UCI option (optional)
--- @return Boolean whether operation succeeded
-
---- Call a function for every section of a certain type.
--- @class function
--- @name Cursor.foreach
--- @param config UCI config
--- @param type UCI section type
--- @param callback Function to be called
--- @return Boolean whether operation succeeded
-
---- Get a section type or an option
--- @class function
--- @name Cursor.get
--- @param config UCI config
--- @param section UCI section name
--- @param option UCI option (optional)
--- @return UCI value
-
---- Get all sections of a config or all values of a section.
--- @class function
--- @name Cursor.get_all
--- @param config UCI config
--- @param section UCI section name (optional)
--- @return Table of UCI sections or table of UCI values
-
---- Manually load a config.
--- @class function
--- @name Cursor.load
--- @param config UCI config
--- @return Boolean whether operation succeeded
--- @see Cursor.save
--- @see Cursor.unload
-
---- Revert saved but uncommitted changes.
--- @class function
--- @name Cursor.revert
--- @param config UCI config
--- @return Boolean whether operation succeeded
--- @see Cursor.commit
--- @see Cursor.save
-
---- Saves changes made to a config to make them committable.
--- @class function
--- @name Cursor.save
--- @param config UCI config
--- @return Boolean whether operation succeeded
--- @see Cursor.load
--- @see Cursor.unload
-
---- Set a value or create a named section.
--- @class function
--- @name Cursor.set
--- @param config UCI config
--- @param section UCI section name
--- @param option UCI option or UCI section type
--- @param value UCI value or nil if you want to create a section
--- @return Boolean whether operation succeeded
-
---- Get the configuration directory.
--- @class function
--- @name Cursor.get_confdir
--- @return Configuration directory
-
---- Get the directory for uncomitted changes.
--- @class function
--- @name Cursor.get_savedir
--- @return Save directory
-
---- Set the configuration directory.
--- @class function
--- @name Cursor.set_confdir
--- @param directory UCI configuration directory
--- @return Boolean whether operation succeeded
-
---- Set the directory for uncommited changes.
--- @class function
--- @name Cursor.set_savedir
--- @param directory UCI changes directory
--- @return Boolean whether operation succeeded
-
---- Discard changes made to a config.
--- @class function
--- @name Cursor.unload
--- @param config UCI config
--- @return Boolean whether operation succeeded
--- @see Cursor.load
--- @see Cursor.save
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/luci-base/luasrc/model/uci.luadoc b/modules/luci-base/luasrc/model/uci.luadoc
new file mode 100644
index 0000000000..1c208669d1
--- /dev/null
+++ b/modules/luci-base/luasrc/model/uci.luadoc
@@ -0,0 +1,291 @@
+---[[
+LuCI UCI model library.
+
+The typical workflow for UCI is: Get a cursor instance from the
+cursor factory, modify data (via Cursor.add, Cursor.delete, etc.),
+save the changes to the staging area via Cursor.save and finally
+Cursor.commit the data to the actual config files.
+LuCI then needs to Cursor.apply the changes so deamons etc. are
+reloaded.
+@cstyle instance
+module "luci.model.uci"
+]]
+
+---[[
+Create a new UCI-Cursor.
+
+@class function
+@name cursor
+@return UCI-Cursor
+]]
+
+---[[
+Create a new Cursor initialized to the state directory.
+
+@class function
+@name cursor_state
+@return UCI cursor
+]]
+
+---[[
+Applies UCI configuration changes
+
+@class function
+@name Cursor.apply
+@param configlist List of UCI configurations
+@param command Don't apply only return the command
+]]
+
+---[[
+Delete all sections of a given type that match certain criteria.
+
+@class function
+@name Cursor.delete_all
+@param config UCI config
+@param type UCI section type
+@param comparator Function that will be called for each section and
+returns a boolean whether to delete the current section (optional)
+]]
+
+---[[
+Create a new section and initialize it with data.
+
+@class function
+@name Cursor.section
+@param config UCI config
+@param type UCI section type
+@param name UCI section name (optional)
+@param values Table of key - value pairs to initialize the section with
+@return Name of created section
+]]
+
+---[[
+Updated the data of a section using data from a table.
+
+@class function
+@name Cursor.tset
+@param config UCI config
+@param section UCI section name (optional)
+@param values Table of key - value pairs to update the section with
+]]
+
+---[[
+Get a boolean option and return it's value as true or false.
+
+@class function
+@name Cursor.get_bool
+@param config UCI config
+@param section UCI section name
+@param option UCI option
+@return Boolean
+]]
+
+---[[
+Get an option or list and return values as table.
+
+@class function
+@name Cursor.get_list
+@param config UCI config
+@param section UCI section name
+@param option UCI option
+@return UCI value
+]]
+
+---[[
+Get the given option from the first section with the given type.
+
+@class function
+@name Cursor.get_first
+@param config UCI config
+@param type UCI section type
+@param option UCI option (optional)
+@param default Default value (optional)
+@return UCI value
+]]
+
+---[[
+Set given values as list.
+
+@class function
+@name Cursor.set_list
+@param config UCI config
+@param section UCI section name
+@param option UCI option
+@param value UCI value
+@return Boolean whether operation succeeded
+]]
+
+---[[
+Create a sub-state of this cursor. The sub-state is tied to the parent
+
+curser, means it the parent unloads or loads configs, the sub state will
+do so as well.
+@class function
+@name Cursor.substate
+@return UCI state cursor tied to the parent cursor
+]]
+
+---[[
+Add an anonymous section.
+
+@class function
+@name Cursor.add
+@param config UCI config
+@param type UCI section type
+@return Name of created section
+]]
+
+---[[
+Get a table of saved but uncommitted changes.
+
+@class function
+@name Cursor.changes
+@param config UCI config
+@return Table of changes
+@see Cursor.save
+]]
+
+---[[
+Commit saved changes.
+
+@class function
+@name Cursor.commit
+@param config UCI config
+@return Boolean whether operation succeeded
+@see Cursor.revert
+@see Cursor.save
+]]
+
+---[[
+Deletes a section or an option.
+
+@class function
+@name Cursor.delete
+@param config UCI config
+@param section UCI section name
+@param option UCI option (optional)
+@return Boolean whether operation succeeded
+]]
+
+---[[
+Call a function for every section of a certain type.
+
+@class function
+@name Cursor.foreach
+@param config UCI config
+@param type UCI section type
+@param callback Function to be called
+@return Boolean whether operation succeeded
+]]
+
+---[[
+Get a section type or an option
+
+@class function
+@name Cursor.get
+@param config UCI config
+@param section UCI section name
+@param option UCI option (optional)
+@return UCI value
+]]
+
+---[[
+Get all sections of a config or all values of a section.
+
+@class function
+@name Cursor.get_all
+@param config UCI config
+@param section UCI section name (optional)
+@return Table of UCI sections or table of UCI values
+]]
+
+---[[
+Manually load a config.
+
+@class function
+@name Cursor.load
+@param config UCI config
+@return Boolean whether operation succeeded
+@see Cursor.save
+@see Cursor.unload
+]]
+
+---[[
+Revert saved but uncommitted changes.
+
+@class function
+@name Cursor.revert
+@param config UCI config
+@return Boolean whether operation succeeded
+@see Cursor.commit
+@see Cursor.save
+]]
+
+---[[
+Saves changes made to a config to make them committable.
+
+@class function
+@name Cursor.save
+@param config UCI config
+@return Boolean whether operation succeeded
+@see Cursor.load
+@see Cursor.unload
+]]
+
+---[[
+Set a value or create a named section.
+
+@class function
+@name Cursor.set
+@param config UCI config
+@param section UCI section name
+@param option UCI option or UCI section type
+@param value UCI value or nil if you want to create a section
+@return Boolean whether operation succeeded
+]]
+
+---[[
+Get the configuration directory.
+
+@class function
+@name Cursor.get_confdir
+@return Configuration directory
+]]
+
+---[[
+Get the directory for uncomitted changes.
+
+@class function
+@name Cursor.get_savedir
+@return Save directory
+]]
+
+---[[
+Set the configuration directory.
+
+@class function
+@name Cursor.set_confdir
+@param directory UCI configuration directory
+@return Boolean whether operation succeeded
+]]
+
+---[[
+Set the directory for uncommited changes.
+
+@class function
+@name Cursor.set_savedir
+@param directory UCI changes directory
+@return Boolean whether operation succeeded
+]]
+
+---[[
+Discard changes made to a config.
+
+@class function
+@name Cursor.unload
+@param config UCI config
+@return Boolean whether operation succeeded
+@see Cursor.load
+@see Cursor.save
+]]
+
diff --git a/modules/luci-base/luasrc/sys.lua b/modules/luci-base/luasrc/sys.lua
index 1e594e1c88..3977da3eda 100644
--- a/modules/luci-base/luasrc/sys.lua
+++ b/modules/luci-base/luasrc/sys.lua
@@ -16,27 +16,14 @@ local tonumber, ipairs, pairs, pcall, type, next, setmetatable, require, select
tonumber, ipairs, pairs, pcall, type, next, setmetatable, require, select
---- LuCI Linux and POSIX system utilities.
module "luci.sys"
---- Execute a given shell command and return the error code
--- @class function
--- @name call
--- @param ... Command to call
--- @return Error code of the command
function call(...)
return os.execute(...) / 256
end
---- Execute a given shell command and capture its standard output
--- @class function
--- @name exec
--- @param command Command to call
--- @return String containg the return the output of the command
exec = luci.util.exec
---- Retrieve information about currently mounted file systems.
--- @return Table containing mount information
function mounts()
local data = {}
local k = {"fs", "blocks", "used", "available", "percent", "mountpoint"}
@@ -82,20 +69,11 @@ function mounts()
return data
end
---- Retrieve environment variables. If no variable is given then a table
-- containing the whole environment is returned otherwise this function returns
-- the corresponding string value for the given name or nil if no such variable
-- exists.
--- @class function
--- @name getenv
--- @param var Name of the environment variable to retrieve (optional)
--- @return String containg the value of the specified variable
--- @return Table containing all variables if no variable name is given
getenv = nixio.getenv
---- Get or set the current hostname.
--- @param String containing a new hostname to set (optional)
--- @return String containing the system hostname
function hostname(newname)
if type(newname) == "string" and #newname > 0 then
fs.writefile( "/proc/sys/kernel/hostname", newname )
@@ -105,11 +83,6 @@ function hostname(newname)
end
end
---- Returns the contents of a documented referred by an URL.
--- @param url The URL to retrieve
--- @param stream Return a stream instead of a buffer
--- @param target Directly write to target file name
--- @return String containing the contents of given the URL
function httpget(url, stream, target)
if not target then
local source = stream and io.popen or luci.util.exec
@@ -120,46 +93,30 @@ function httpget(url, stream, target)
end
end
---- Initiate a system reboot.
--- @return Return value of os.execute()
function reboot()
return os.execute("reboot >/dev/null 2>&1")
end
---- Retrieves the output of the "logread" command.
--- @return String containing the current log buffer
function syslog()
return luci.util.exec("logread")
end
---- Retrieves the output of the "dmesg" command.
--- @return String containing the current log buffer
function dmesg()
return luci.util.exec("dmesg")
end
---- Generates a random id with specified length.
--- @param bytes Number of bytes for the unique id
--- @return String containing hex encoded id
function uniqueid(bytes)
local rand = fs.readfile("/dev/urandom", bytes)
return rand and nixio.bin.hexlify(rand)
end
---- Returns the current system uptime stats.
--- @return String containing total uptime in seconds
function uptime()
return nixio.sysinfo().uptime
end
---- LuCI system utilities / network related functions.
--- @class module
--- @name luci.sys.net
net = {}
---- Returns the current arp-table entries as two-dimensional table.
--- @return Table of table containing the current arp entries.
-- The following fields are defined for arp entry objects:
-- { "IP address", "HW address", "HW type", "Flags", "Mask", "Device" }
function net.arptable(callback)
@@ -269,8 +226,6 @@ local function _nethints(what, callback)
end
end
---- Returns a two-dimensional table of mac address hints.
--- @return Table of table containing known hosts from various sources.
-- Each entry contains the values in the following order:
-- [ "mac", "name" ]
function net.mac_hints(callback)
@@ -293,8 +248,6 @@ function net.mac_hints(callback)
end
end
---- Returns a two-dimensional table of IPv4 address hints.
--- @return Table of table containing known hosts from various sources.
-- Each entry contains the values in the following order:
-- [ "ip", "name" ]
function net.ipv4_hints(callback)
@@ -317,8 +270,6 @@ function net.ipv4_hints(callback)
end
end
---- Returns a two-dimensional table of IPv6 address hints.
--- @return Table of table containing known hosts from various sources.
-- Each entry contains the values in the following order:
-- [ "ip", "name" ]
function net.ipv6_hints(callback)
@@ -341,8 +292,6 @@ function net.ipv6_hints(callback)
end
end
---- Returns conntrack information
--- @return Table with the currently tracked IP connections
function net.conntrack(callback)
local connt = {}
if fs.access("/proc/net/nf_conntrack", "r") then
@@ -387,57 +336,6 @@ function net.conntrack(callback)
return connt
end
---- Determine the current IPv4 default route. If multiple default routes exist,
--- return the one with the lowest metric.
--- @return Table with the properties of the current default route.
--- The following fields are defined:
--- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
--- "flags", "device" }
-function net.defaultroute()
- local route
-
- net.routes(function(rt)
- if rt.dest:prefix() == 0 and (not route or route.metric > rt.metric) then
- route = rt
- end
- end)
-
- return route
-end
-
---- Determine the current IPv6 default route. If multiple default routes exist,
--- return the one with the lowest metric.
--- @return Table with the properties of the current default route.
--- The following fields are defined:
--- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
--- "flags", "device" }
-function net.defaultroute6()
- local route
-
- net.routes6(function(rt)
- if rt.dest:prefix() == 0 and rt.device ~= "lo" and
- (not route or route.metric > rt.metric)
- then
- route = rt
- end
- end)
-
- if not route then
- local global_unicast = luci.ip.IPv6("2000::/3")
- net.routes6(function(rt)
- if rt.dest:equal(global_unicast) and
- (not route or route.metric > rt.metric)
- then
- route = rt
- end
- end)
- end
-
- return route
-end
-
---- Determine the names of available network interfaces.
--- @return Table containing all current interface names
function net.devices()
local devs = {}
for k, v in ipairs(nixio.getifaddrs()) do
@@ -449,8 +347,6 @@ function net.devices()
end
---- Return information about available network interfaces.
--- @return Table containing all current interface names and their information
function net.deviceinfo()
local devs = {}
for k, v in ipairs(nixio.getifaddrs()) do
@@ -479,21 +375,6 @@ function net.deviceinfo()
end
--- Determine the MAC address belonging to the given IP address.
--- @param ip IPv4 address
--- @return String containing the MAC address or nil if it cannot be found
-function net.ip4mac(ip)
- local mac = nil
- net.arptable(function(e)
- if e["IP address"] == ip then
- mac = e["HW address"]
- end
- end)
- return mac
-end
-
---- Returns the current kernel routing table entries.
--- @return Table of tables with properties of the corresponding routes.
-- The following fields are defined for route entry tables:
-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
-- "flags", "device" }
@@ -539,8 +420,6 @@ function net.routes(callback)
return routes
end
---- Returns the current ipv6 kernel routing table entries.
--- @return Table of tables with properties of the corresponding routes.
-- The following fields are defined for route entry tables:
-- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
-- "flags", "device" }
@@ -602,30 +481,18 @@ function net.routes6(callback)
end
end
---- Tests whether the given host responds to ping probes.
--- @param host String containing a hostname or IPv4 address
--- @return Number containing 0 on success and >= 1 on error
function net.pingtest(host)
return os.execute("ping -c1 '"..host:gsub("'", '').."' >/dev/null 2>&1")
end
---- LuCI system utilities / process related functions.
--- @class module
--- @name luci.sys.process
process = {}
---- Get the current process id.
--- @class function
--- @name process.info
--- @return Number containing the current pid
function process.info(key)
local s = {uid = nixio.getuid(), gid = nixio.getgid()}
return not key and s or s[key]
end
---- Retrieve information about currently running processes.
--- @return Table containing process information
function process.list()
local data = {}
local k
@@ -658,51 +525,22 @@ function process.list()
return data
end
---- Set the gid of a process identified by given pid.
--- @param gid Number containing the Unix group id
--- @return Boolean indicating successful operation
--- @return String containing the error message if failed
--- @return Number containing the error code if failed
function process.setgroup(gid)
return nixio.setgid(gid)
end
---- Set the uid of a process identified by given pid.
--- @param uid Number containing the Unix user id
--- @return Boolean indicating successful operation
--- @return String containing the error message if failed
--- @return Number containing the error code if failed
function process.setuser(uid)
return nixio.setuid(uid)
end
---- Send a signal to a process identified by given pid.
--- @class function
--- @name process.signal
--- @param pid Number containing the process id
--- @param sig Signal to send (default: 15 [SIGTERM])
--- @return Boolean indicating successful operation
--- @return Number containing the error code if failed
process.signal = nixio.kill
---- LuCI system utilities / user related functions.
--- @class module
--- @name luci.sys.user
user = {}
---- Retrieve user informations for given uid.
--- @class function
--- @name getuser
--- @param uid Number containing the Unix user id
--- @return Table containing the following fields:
-- { "uid", "gid", "name", "passwd", "dir", "shell", "gecos" }
user.getuser = nixio.getpw
---- Retrieve the current user password hash.
--- @param username String containing the username to retrieve the password for
--- @return String containing the hash or nil if no password is set.
--- @return Password database entry
function user.getpasswd(username)
local pwe = nixio.getsp and nixio.getsp(username) or nixio.getpw(username)
local pwh = pwe and (pwe.pwdp or pwe.passwd)
@@ -713,10 +551,6 @@ function user.getpasswd(username)
end
end
---- Test whether given string matches the password of a given system user.
--- @param username String containing the Unix user name
--- @param pass String containing the password to compare
--- @return Boolean indicating wheather the passwords are equal
function user.checkpasswd(username, pass)
local pwh, pwe = user.getpasswd(username)
if pwe then
@@ -725,10 +559,6 @@ function user.checkpasswd(username, pass)
return false
end
---- Change the password of given user.
--- @param username String containing the Unix user name
--- @param password String containing the password to compare
--- @return Number containing 0 on success and >= 1 on error
function user.setpasswd(username, password)
if password then
password = password:gsub("'", [['"'"']])
@@ -745,14 +575,8 @@ function user.setpasswd(username, password)
end
---- LuCI system utilities / wifi related functions.
--- @class module
--- @name luci.sys.wifi
wifi = {}
---- Get wireless information for given interface.
--- @param ifname String containing the interface name
--- @return A wrapped iwinfo object instance
function wifi.getiwinfo(ifname)
local stat, iwinfo = pcall(require, "iwinfo")
@@ -798,14 +622,9 @@ function wifi.getiwinfo(ifname)
end
---- LuCI system utilities / init related functions.
--- @class module
--- @name luci.sys.init
init = {}
init.dir = "/etc/init.d/"
---- Get the names of all installed init scripts
--- @return Table containing the names of all inistalled init scripts
function init.names()
local names = { }
for name in fs.glob(init.dir.."*") do
@@ -814,9 +633,6 @@ function init.names()
return names
end
---- Get the index of he given init script
--- @param name Name of the init script
--- @return Numeric index value
function init.index(name)
if fs.access(init.dir..name) then
return call("env -i sh -c 'source %s%s enabled; exit ${START:-255}' >/dev/null"
@@ -830,37 +646,22 @@ local function init_action(action, name)
end
end
---- Test whether the given init script is enabled
--- @param name Name of the init script
--- @return Boolean indicating whether init is enabled
function init.enabled(name)
return (init_action("enabled", name) == 0)
end
---- Enable the given init script
--- @param name Name of the init script
--- @return Boolean indicating success
function init.enable(name)
return (init_action("enable", name) == 1)
end
---- Disable the given init script
--- @param name Name of the init script
--- @return Boolean indicating success
function init.disable(name)
return (init_action("disable", name) == 0)
end
---- Start the given init script
--- @param name Name of the init script
--- @return Boolean indicating success
function init.start(name)
return (init_action("start", name) == 0)
end
---- Stop the given init script
--- @param name Name of the init script
--- @return Boolean indicating success
function init.stop(name)
return (init_action("stop", name) == 0)
end
diff --git a/modules/luci-base/luasrc/sys.luadoc b/modules/luci-base/luasrc/sys.luadoc
new file mode 100644
index 0000000000..72a16a1ab0
--- /dev/null
+++ b/modules/luci-base/luasrc/sys.luadoc
@@ -0,0 +1,396 @@
+---[[
+LuCI Linux and POSIX system utilities.
+
+module "luci.sys"
+]]
+
+---[[
+Execute a given shell command and return the error code
+
+@class function
+@name call
+@param ... Command to call
+@return Error code of the command
+]]
+
+---[[
+Execute a given shell command and capture its standard output
+
+@class function
+@name exec
+@param command Command to call
+@return String containg the return the output of the command
+]]
+
+---[[
+Retrieve information about currently mounted file systems.
+
+@class function
+@name mounts
+@return Table containing mount information
+]]
+
+---[[
+Retrieve environment variables. If no variable is given then a table
+
+containing the whole environment is returned otherwise this function returns
+the corresponding string value for the given name or nil if no such variable
+exists.
+@class function
+@name getenv
+@param var Name of the environment variable to retrieve (optional)
+@return String containg the value of the specified variable
+@return Table containing all variables if no variable name is given
+]]
+
+---[[
+Get or set the current hostname.
+
+@class function
+@name hostname
+@param String containing a new hostname to set (optional)
+@return String containing the system hostname
+]]
+
+---[[
+Returns the contents of a documented referred by an URL.
+
+@class function
+@name httpget
+@param url The URL to retrieve
+@param stream Return a stream instead of a buffer
+@param target Directly write to target file name
+@return String containing the contents of given the URL
+]]
+
+---[[
+Initiate a system reboot.
+
+@class function
+@name reboot
+@return Return value of os.execute()
+]]
+
+---[[
+Retrieves the output of the "logread" command.
+
+@class function
+@name syslog
+@return String containing the current log buffer
+]]
+
+---[[
+Retrieves the output of the "dmesg" command.
+
+@class function
+@name dmesg
+@return String containing the current log buffer
+]]
+
+---[[
+Generates a random id with specified length.
+
+@class function
+@name uniqueid
+@param bytes Number of bytes for the unique id
+@return String containing hex encoded id
+]]
+
+---[[
+Returns the current system uptime stats.
+
+@class function
+@name uptime
+@return String containing total uptime in seconds
+]]
+
+---[[
+LuCI system utilities / network related functions.
+
+@class module
+@name luci.sys.net
+]]
+
+---[[
+Returns the current arp-table entries as two-dimensional table.
+
+@class function
+@name net.arptable
+@return Table of table containing the current arp entries.
+-- The following fields are defined for arp entry objects:
+-- { "IP address", "HW address", "HW type", "Flags", "Mask", "Device" }
+]]
+
+---[[
+Returns a two-dimensional table of mac address hints.
+
+@class function
+@name net.mac_hints
+@return Table of table containing known hosts from various sources.
+ Each entry contains the values in the following order:
+ [ "mac", "name" ]
+]]
+
+---[[
+Returns a two-dimensional table of IPv4 address hints.
+
+@class function
+@name net.ipv4_hints
+@return Table of table containing known hosts from various sources.
+ Each entry contains the values in the following order:
+ [ "ip", "name" ]
+]]
+
+---[[
+Returns a two-dimensional table of IPv6 address hints.
+
+@class function
+@name net.ipv6_hints
+@return Table of table containing known hosts from various sources.
+ Each entry contains the values in the following order:
+ [ "ip", "name" ]
+]]
+
+---[[
+Returns conntrack information
+
+@class function
+@name net.conntrack
+@return Table with the currently tracked IP connections
+]]
+
+---[[
+Determine the names of available network interfaces.
+
+@class function
+@name net.devices
+@return Table containing all current interface names
+]]
+
+---[[
+Return information about available network interfaces.
+
+@class function
+@name net.deviceinfo
+@return Table containing all current interface names and their information
+]]
+
+---[[
+Returns the current kernel routing table entries.
+
+@class function
+@name net.routes
+@return Table of tables with properties of the corresponding routes.
+-- The following fields are defined for route entry tables:
+-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
+-- "flags", "device" }
+]]
+
+---[[
+Returns the current ipv6 kernel routing table entries.
+
+@class function
+@name net.routes6
+@return Table of tables with properties of the corresponding routes.
+-- The following fields are defined for route entry tables:
+-- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
+-- "flags", "device" }
+]]
+
+---[[
+Tests whether the given host responds to ping probes.
+
+@class function
+@name net.pingtest
+@param host String containing a hostname or IPv4 address
+@return Number containing 0 on success and >= 1 on error
+]]
+
+---[[
+LuCI system utilities / process related functions.
+
+@class module
+@name luci.sys.process
+]]
+
+---[[
+Get the current process id.
+
+@class function
+@name process.info
+@return Number containing the current pid
+]]
+
+---[[
+Retrieve information about currently running processes.
+
+@class function
+@name process.list
+@return Table containing process information
+]]
+
+---[[
+Set the gid of a process identified by given pid.
+
+@class function
+@name process.setgroup
+@param gid Number containing the Unix group id
+@return Boolean indicating successful operation
+@return String containing the error message if failed
+@return Number containing the error code if failed
+]]
+
+---[[
+Set the uid of a process identified by given pid.
+
+@class function
+@name process.setuser
+@param uid Number containing the Unix user id
+@return Boolean indicating successful operation
+@return String containing the error message if failed
+@return Number containing the error code if failed
+]]
+
+---[[
+Send a signal to a process identified by given pid.
+
+@class function
+@name process.signal
+@param pid Number containing the process id
+@param sig Signal to send (default: 15 [SIGTERM])
+@return Boolean indicating successful operation
+@return Number containing the error code if failed
+]]
+
+---[[
+LuCI system utilities / user related functions.
+
+@class module
+@name luci.sys.user
+]]
+
+---[[
+Retrieve user informations for given uid.
+
+@class function
+@name getuser
+@param uid Number containing the Unix user id
+@return Table containing the following fields:
+-- { "uid", "gid", "name", "passwd", "dir", "shell", "gecos" }
+]]
+
+---[[
+Retrieve the current user password hash.
+
+@class function
+@name user.getpasswd
+@param username String containing the username to retrieve the password for
+@return String containing the hash or nil if no password is set.
+@return Password database entry
+]]
+
+---[[
+Test whether given string matches the password of a given system user.
+
+@class function
+@name user.checkpasswd
+@param username String containing the Unix user name
+@param pass String containing the password to compare
+@return Boolean indicating wheather the passwords are equal
+]]
+
+---[[
+Change the password of given user.
+
+@class function
+@name user.setpasswd
+@param username String containing the Unix user name
+@param password String containing the password to compare
+@return Number containing 0 on success and >= 1 on error
+]]
+
+---[[
+LuCI system utilities / wifi related functions.
+
+@class module
+@name luci.sys.wifi
+]]
+
+---[[
+Get wireless information for given interface.
+
+@class function
+@name wifi.getiwinfo
+@param ifname String containing the interface name
+@return A wrapped iwinfo object instance
+]]
+
+---[[
+LuCI system utilities / init related functions.
+
+@class module
+@name luci.sys.init
+]]
+
+---[[
+Get the names of all installed init scripts
+
+@class function
+@name init.names
+@return Table containing the names of all inistalled init scripts
+]]
+
+---[[
+Get the index of he given init script
+
+@class function
+@name init.index
+@param name Name of the init script
+@return Numeric index value
+]]
+
+---[[
+Test whether the given init script is enabled
+
+@class function
+@name init.enabled
+@param name Name of the init script
+@return Boolean indicating whether init is enabled
+]]
+
+---[[
+Enable the given init script
+
+@class function
+@name init.enable
+@param name Name of the init script
+@return Boolean indicating success
+]]
+
+---[[
+Disable the given init script
+
+@class function
+@name init.disable
+@param name Name of the init script
+@return Boolean indicating success
+]]
+
+---[[
+Start the given init script
+
+@class function
+@name init.start
+@param name Name of the init script
+@return Boolean indicating success
+]]
+
+---[[
+Stop the given init script
+
+@class function
+@name init.stop
+@param name Name of the init script
+@return Boolean indicating success
+]]
+
diff --git a/modules/luci-base/luasrc/sys/iptparser.lua b/modules/luci-base/luasrc/sys/iptparser.lua
index 6715937c69..2b81e0ee38 100644
--- a/modules/luci-base/luasrc/sys/iptparser.lua
+++ b/modules/luci-base/luasrc/sys/iptparser.lua
@@ -21,15 +21,8 @@ luci.ip = require "luci.ip"
local tonumber, ipairs, table = tonumber, ipairs, table
---- LuCI iptables parser and query library
--- @cstyle instance
module("luci.sys.iptparser")
---- Create a new iptables parser object.
--- @class function
--- @name IptParser
--- @param family Number specifying the address family. 4 for IPv4, 6 for IPv6
--- @return IptParser instance
IptParser = luci.util.class()
function IptParser.__init__( self, family )
@@ -50,7 +43,6 @@ function IptParser.__init__( self, family )
self:_parse_rules()
end
---- Find all firewall rules that match the given criteria. Expects a table with
-- search criteria as only argument. If args is nil or an empty table then all
-- rules will be returned.
--
@@ -108,8 +100,6 @@ end
-- This will match all rules with target "-j REJECT",
-- protocol "-p tcp" (or "-p all")
-- and the option "--reject-with tcp-reset".
--- @params args Table containing the search arguments (optional)
--- @return Table of matching rule tables
function IptParser.find( self, args )
local args = args or { }
@@ -205,9 +195,7 @@ function IptParser.find( self, args )
end
---- Rebuild the internal lookup table, for example when rules have changed
-- through external commands.
--- @return nothing
function IptParser.resync( self )
self._rules = { }
self._chain = nil
@@ -215,16 +203,11 @@ function IptParser.resync( self )
end
---- Find the names of all tables.
--- @return Table of table names.
function IptParser.tables( self )
return self._tables
end
---- Find the names of all chains within the given table name.
--- @param table String containing the table name
--- @return Table of chain names in the order they occur.
function IptParser.chains( self, table )
local lookup = { }
local chains = { }
@@ -238,19 +221,12 @@ function IptParser.chains( self, table )
end
---- Return the given firewall chain within the given table name.
--- @param table String containing the table name
--- @param chain String containing the chain name
--- @return Table containing the fields "policy", "packets", "bytes"
-- and "rules". The "rules" field is a table of rule tables.
function IptParser.chain( self, table, chain )
return self._chains[table:lower()] and self._chains[table:lower()][chain]
end
---- Test whether the given target points to a custom chain.
--- @param target String containing the target action
--- @return Boolean indicating whether target is a custom chain.
function IptParser.is_custom_target( self, target )
for _, r in ipairs(self._rules) do
if r.chain == target then
diff --git a/modules/luci-base/luasrc/sys/iptparser.luadoc b/modules/luci-base/luasrc/sys/iptparser.luadoc
new file mode 100644
index 0000000000..071e7d52e4
--- /dev/null
+++ b/modules/luci-base/luasrc/sys/iptparser.luadoc
@@ -0,0 +1,69 @@
+---[[
+LuCI iptables parser and query library
+
+@cstyle instance
+]]
+module "luci.sys.iptparser"
+
+---[[
+Create a new iptables parser object.
+
+@class function
+@name IptParser
+@param family Number specifying the address family. 4 for IPv4, 6 for IPv6
+@return IptParser instance
+]]
+
+---[[
+Find all firewall rules that match the given criteria. Expects a table with
+
+search criteria as only argument. If args is nil or an empty table then all
+rules will be returned.
+]]
+
+---[[
+Rebuild the internal lookup table, for example when rules have changed
+
+through external commands.
+@class function
+@name IptParser.resync
+@return nothing
+]]
+
+---[[
+Find the names of all tables.
+
+@class function
+@name IptParser.tables
+@return Table of table names.
+]]
+
+---[[
+Find the names of all chains within the given table name.
+
+@class function
+@name IptParser.chains
+@param table String containing the table name
+@return Table of chain names in the order they occur.
+]]
+
+---[[
+Return the given firewall chain within the given table name.
+
+@class function
+@name IptParser.chain
+@param table String containing the table name
+@param chain String containing the chain name
+@return Table containing the fields "policy", "packets", "bytes"
+-- and "rules". The "rules" field is a table of rule tables.
+]]
+
+---[[
+Test whether the given target points to a custom chain.
+
+@class function
+@name IptParser.is_custom_target
+@param target String containing the target action
+@return Boolean indicating whether target is a custom chain.
+]]
+
diff --git a/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua b/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
index 6337496692..97a3608ea7 100644
--- a/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
+++ b/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
@@ -86,7 +86,7 @@ TZ = {
{ 'America/Boise', 'MST7MDT,M3.2.0,M11.1.0' },
{ 'America/Cambridge Bay', 'MST7MDT,M3.2.0,M11.1.0' },
{ 'America/Campo Grande', 'AMT4AMST,M10.3.0/0,M2.3.0/0' },
- { 'America/Cancun', 'CST6CDT,M4.1.0,M10.5.0' },
+ { 'America/Cancun', 'EST5' },
{ 'America/Caracas', 'VET4:30' },
{ 'America/Cayenne', 'GFT3' },
{ 'America/Cayman', 'EST5' },
@@ -178,7 +178,7 @@ TZ = {
{ 'America/Rio Branco', 'ACT5' },
{ 'America/Santa Isabel', 'PST8PDT,M4.1.0,M10.5.0' },
{ 'America/Santarem', 'BRT3' },
- { 'America/Santiago', 'CLT4CLST,M9.1.6/24,M4.4.6/24' },
+ { 'America/Santiago', 'CLT3' },
{ 'America/Santo Domingo', 'AST4' },
{ 'America/Sao Paulo', 'BRT3BRST,M10.3.0/0,M2.3.0/0' },
{ 'America/Scoresbysund', 'EGT1EGST,M3.5.0/0,M10.5.0/1' },
@@ -207,7 +207,7 @@ TZ = {
{ 'Antarctica/Macquarie', 'MIST-11' },
{ 'Antarctica/Mawson', 'MAWT-5' },
{ 'Antarctica/McMurdo', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
- { 'Antarctica/Palmer', 'CLT4CLST,M9.1.6/24,M4.4.6/24' },
+ { 'Antarctica/Palmer', 'CLT3' },
{ 'Antarctica/Rothera', 'ROTT3' },
{ 'Antarctica/Syowa', 'SYOT-3' },
{ 'Antarctica/Troll', 'UTC0CEST-2,M3.5.0/1,M10.5.0/3' },
@@ -384,7 +384,7 @@ TZ = {
{ 'Pacific/Bougainville', 'BST-11' },
{ 'Pacific/Chatham', 'CHAST-12:45CHADT,M9.5.0/2:45,M4.1.0/3:45' },
{ 'Pacific/Chuuk', 'CHUT-10' },
- { 'Pacific/Easter', 'EAST6EASST,M9.1.6/22,M4.4.6/22' },
+ { 'Pacific/Easter', 'EAST5' },
{ 'Pacific/Efate', 'VUT-11' },
{ 'Pacific/Enderbury', 'PHOT-13' },
{ 'Pacific/Fakaofo', 'TKT-13' },
diff --git a/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua b/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
index facfd0c8bf..c8c908b6ea 100644
--- a/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
+++ b/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
@@ -45,8 +45,7 @@ OFFSET = {
uyst = -7200, -- UYST
fnt = -7200, -- FNT
srt = -10800, -- SRT
- clt = -14400, -- CLT
- clst = -10800, -- CLST
+ clt = -10800, -- CLT
egt = -3600, -- EGT
egst = 0, -- EGST
nst = -12600, -- NST
@@ -135,8 +134,7 @@ OFFSET = {
chast = 45900, -- CHAST
chadt = 49500, -- CHADT
chut = 36000, -- CHUT
- east = -21600, -- EAST
- easst = -18000, -- EASST
+ east = -18000, -- EAST
vut = 39600, -- VUT
phot = 46800, -- PHOT
tkt = 46800, -- TKT
diff --git a/modules/luci-base/luasrc/tools/webadmin.lua b/modules/luci-base/luasrc/tools/webadmin.lua
index 9adac29bfa..8273175de7 100644
--- a/modules/luci-base/luasrc/tools/webadmin.lua
+++ b/modules/luci-base/luasrc/tools/webadmin.lua
@@ -1,11 +1,12 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
--- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
+-- Copyright 2008-2015 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
module("luci.tools.webadmin", package.seeall)
-local uci = require("luci.model.uci")
-require("luci.sys")
-require("luci.ip")
+
+local util = require "luci.util"
+local uci = require "luci.model.uci"
+local ip = require "luci.ip"
function byte_format(byte)
local suff = {"B", "KB", "MB", "GB", "TB"}
@@ -47,49 +48,6 @@ function date_format(secs)
end
end
-function network_get_addresses(net)
- local state = uci.cursor_state()
- state:load("network")
- local addr = {}
- local ipv4 = state:get("network", net, "ipaddr")
- local mav4 = state:get("network", net, "netmask")
- local ipv6 = state:get("network", net, "ip6addr")
-
- if ipv4 and #ipv4 > 0 then
- if mav4 and #mav4 == 0 then mav4 = nil end
-
- ipv4 = luci.ip.IPv4(ipv4, mav4)
-
- if ipv4 then
- table.insert(addr, ipv4:string())
- end
- end
-
- if ipv6 then
- table.insert(addr, ipv6)
- end
-
- state:foreach("network", "alias",
- function (section)
- if section.interface == net then
- if section.ipaddr and section.netmask then
- local ipv4 = luci.ip.IPv4(section.ipaddr, section.netmask)
-
- if ipv4 then
- table.insert(addr, ipv4:string())
- end
- end
-
- if section.ip6addr then
- table.insert(addr, section.ip6addr)
- end
- end
- end
- )
-
- return addr
-end
-
function cbi_add_networks(field)
uci.cursor():foreach("network", "interface",
function (section)
@@ -102,29 +60,12 @@ function cbi_add_networks(field)
end
function cbi_add_knownips(field)
- for i, dataset in ipairs(luci.sys.net.arptable()) do
- field:value(dataset["IP address"])
- end
-end
-
-function network_get_zones(net)
- local state = uci.cursor_state()
- if not state:load("firewall") then
- return nil
- end
-
- local zones = {}
-
- state:foreach("firewall", "zone",
- function (section)
- local znet = section.network or section.name
- if luci.util.contains(luci.util.split(znet, " "), net) then
- table.insert(zones, section.name)
- end
+ local _, n
+ for _, n in ipairs(ip.neighbors({ family = 4 })) do
+ if n.dest then
+ field:value(n.dest:string())
end
- )
-
- return zones
+ end
end
function firewall_find_zone(name)
@@ -142,21 +83,23 @@ function firewall_find_zone(name)
end
function iface_get_network(iface)
- local state = uci.cursor_state()
- state:load("network")
- local net
-
- state:foreach("network", "interface",
- function (section)
- local ifname = state:get(
- "network", section[".name"], "ifname"
- )
-
- if iface == ifname then
- net = section[".name"]
+ local link = ip.link(tostring(iface))
+ if link.master then
+ iface = link.master
+ end
+
+ local cur = uci.cursor()
+ local dump = util.ubus("network.interface", "dump", { })
+ if dump then
+ local _, net
+ for _, net in ipairs(dump.interface) do
+ if net.l3_device == iface or net.device == iface then
+ -- cross check with uci to filter out @name style aliases
+ local uciname = cur:get("network", net.interface, "ifname")
+ if not uciname or uciname:sub(1, 1) ~= "@" then
+ return net.interface
+ end
end
end
- )
-
- return net
+ end
end
diff --git a/modules/luci-base/luasrc/util.lua b/modules/luci-base/luasrc/util.lua
index 42de3dd729..8b28b1752d 100644
--- a/modules/luci-base/luasrc/util.lua
+++ b/modules/luci-base/luasrc/util.lua
@@ -20,7 +20,6 @@ local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring
local require, pcall, xpcall = require, pcall, xpcall
local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit
---- LuCI utility functions.
module "luci.util"
--
@@ -54,7 +53,6 @@ local function _instantiate(class, ...)
return inst
end
---- Create a Class object (Python-style object model).
-- The class object can be instantiated by calling itself.
-- Any class functions or shared parameters can be attached to this object.
-- Attaching a table to the class object makes this table shared between
@@ -64,10 +62,6 @@ end
-- to the __init__ function of this class - if such a function exists.
-- The __init__ function must be used to set any object parameters that are not shared
-- with other objects of this class. Any return values will be ignored.
--- @param base The base class to inherit from (optional)
--- @return A class object
--- @see instanceof
--- @see clone
function class(base)
return setmetatable({}, {
__call = _instantiate,
@@ -75,12 +69,6 @@ function class(base)
})
end
---- Test whether the given object is an instance of the given class.
--- @param object Object instance
--- @param class Class object to test against
--- @return Boolean indicating whether the object is an instance
--- @see class
--- @see clone
function instanceof(object, class)
local meta = getmetatable(object)
while meta and meta.__index do
@@ -117,10 +105,8 @@ local tl_meta = {
end
}
---- Create a new or get an already existing thread local store associated with
-- the current active coroutine. A thread local store is private a table object
-- whose values can't be accessed from outside of the running coroutine.
--- @return Table value representing the corresponding thread local store
function threadlocal(tbl)
return setmetatable(tbl or {}, tl_meta)
end
@@ -130,17 +116,10 @@ end
-- Debugging routines
--
---- Write given object to stderr.
--- @param obj Value to write to stderr
--- @return Boolean indicating whether the write operation was successful
function perror(obj)
return io.stderr:write(tostring(obj) .. "\n")
end
---- Recursively dumps a table to stdout, useful for testing and debugging.
--- @param t Table value to dump
--- @param maxdepth Maximum depth
--- @return Always nil
function dumptable(t, maxdepth, i, seen)
i = i or 0
seen = seen or setmetatable({}, {__mode="k"})
@@ -163,31 +142,19 @@ end
-- String and data manipulation routines
--
---- Create valid XML PCDATA from given string.
--- @param value String value containing the data to escape
--- @return String value containing the escaped data
function pcdata(value)
return value and tparser.pcdata(tostring(value))
end
---- Strip HTML tags from given string.
--- @param value String containing the HTML text
--- @return String with HTML tags stripped of
function striptags(value)
return value and tparser.striptags(tostring(value))
end
---- Splits given string on a defined separator sequence and return a table
-- containing the resulting substrings. The optional max parameter specifies
-- the number of bytes to process, regardless of the actual length of the given
-- string. The optional last parameter, regex, specifies whether the separator
-- sequence is interpreted as regular expression.
--- @param str String value containing the data to split up
--- @param pat String with separator pattern (optional, defaults to "\n")
--- @param max Maximum times to split (optional)
--- @param regex Boolean indicating whether to interpret the separator
-- pattern as regular expression (optional, default is false)
--- @return Table containing the resulting substrings
function split(str, pat, max, regex)
pat = pat or "\n"
max = max or #str
@@ -221,29 +188,19 @@ function split(str, pat, max, regex)
return t
end
---- Remove leading and trailing whitespace from given string value.
--- @param str String value containing whitespace padded data
--- @return String value with leading and trailing space removed
function trim(str)
return (str:gsub("^%s*(.-)%s*$", "%1"))
end
---- Count the occurences of given substring in given string.
--- @param str String to search in
--- @param pattern String containing pattern to find
--- @return Number of found occurences
function cmatch(str, pat)
local count = 0
for _ in str:gmatch(pat) do count = count + 1 end
return count
end
---- Return a matching iterator for the given value. The iterator will return
-- one token per invocation, the tokens are separated by whitespace. If the
-- input value is a table, it is transformed into a string first. A nil value
-- will result in a valid interator which aborts with the first invocation.
--- @param val The value to scan (table, string or nil)
--- @return Iterator which returns one token per call
function imatch(v)
if type(v) == "table" then
local k = nil
@@ -268,7 +225,6 @@ function imatch(v)
return function() end
end
---- Parse certain units from the given string and return the canonical integer
-- value or 0 if the unit is unknown. Upper- or lower case is irrelevant.
-- Recognized units are:
-- o "y" - one year (60*60*24*366)
@@ -283,8 +239,6 @@ end
-- o "kib" - one si kilobyte (1000)
-- o "mib" - one si megabyte (1000*1000)
-- o "gib" - one si gigabyte (1000*1000*1000)
--- @param ustr String containing a numerical value with trailing unit
--- @return Number containing the canonical value
function parse_units(ustr)
local val = 0
@@ -336,10 +290,6 @@ string.cmatch = cmatch
string.parse_units = parse_units
---- Appends numerically indexed tables or single objects to a given table.
--- @param src Target table
--- @param ... Objects to insert
--- @return Target table
function append(src, ...)
for i, a in ipairs({...}) do
if type(a) == "table" then
@@ -353,19 +303,10 @@ function append(src, ...)
return src
end
---- Combines two or more numerically indexed tables and single objects into one table.
--- @param tbl1 Table value to combine
--- @param tbl2 Table value to combine
--- @param ... More tables to combine
--- @return Table value containing all values of given tables
function combine(...)
return append({}, ...)
end
---- Checks whether the given table contains the given value.
--- @param table Table value
--- @param value Value to search within the given table
--- @return Boolean indicating whether the given value occurs within table
function contains(table, value)
for k, v in pairs(table) do
if value == v then
@@ -375,20 +316,13 @@ function contains(table, value)
return false
end
---- Update values in given table with the values from the second given table.
-- Both table are - in fact - merged together.
--- @param t Table which should be updated
--- @param updates Table containing the values to update
--- @return Always nil
function update(t, updates)
for k, v in pairs(updates) do
t[k] = v
end
end
---- Retrieve all keys of given associative table.
--- @param t Table to extract keys from
--- @return Sorted table containing the keys
function keys(t)
local keys = { }
if t then
@@ -399,10 +333,6 @@ function keys(t)
return keys
end
---- Clones the given object and return it's copy.
--- @param object Table value to clone
--- @param deep Boolean indicating whether to do recursive cloning
--- @return Cloned table value
function clone(object, deep)
local copy = {}
@@ -417,8 +347,6 @@ function clone(object, deep)
end
---- Create a dynamic table which automatically creates subtables.
--- @return Dynamic Table
function dtable()
return setmetatable({}, { __index =
function(tbl, key)
@@ -457,12 +385,7 @@ function _serialize_table(t, seen)
return idata .. ( #data > 0 and #idata > 0 and ", " or "" ) .. data
end
---- Recursively serialize given data to lua code, suitable for restoring
-- with loadstring().
--- @param val Value containing the data to serialize
--- @return String value containing the serialized code
--- @see restore_data
--- @see get_bytecode
function serialize_data(val, seen)
seen = seen or setmetatable({}, {__mode="k"})
@@ -483,11 +406,6 @@ function serialize_data(val, seen)
end
end
---- Restore data previously serialized with serialize_data().
--- @param str String containing the data to restore
--- @return Value containing the restored data structure
--- @see serialize_data
--- @see get_bytecode
function restore_data(str)
return loadstring("return " .. str)()
end
@@ -497,10 +415,7 @@ end
-- Byte code manipulation routines
--
---- Return the current runtime bytecode of the given data. The byte code
-- will be stripped before it is returned.
--- @param val Value to return as bytecode
--- @return String value containing the bytecode of the given data
function get_bytecode(val)
local code
@@ -513,11 +428,8 @@ function get_bytecode(val)
return code -- and strip_bytecode(code)
end
---- Strips unnescessary lua bytecode from given string. Information like line
-- numbers and debugging numbers will be discarded. Original version by
-- Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
--- @param code String value containing the original lua byte code
--- @return String value containing the stripped lua byte code
function strip_bytecode(code)
local version, format, endian, int, size, ins, num, lnum = code:byte(5, 12)
local subint
@@ -607,27 +519,17 @@ function _sortiter( t, f )
end
end
---- Return a key, value iterator which returns the values sorted according to
-- the provided callback function.
--- @param t The table to iterate
--- @param f A callback function to decide the order of elements
--- @return Function value containing the corresponding iterator
function spairs(t,f)
return _sortiter( t, f )
end
---- Return a key, value iterator for the given table.
-- The table pairs are sorted by key.
--- @param t The table to iterate
--- @return Function value containing the corresponding iterator
function kspairs(t)
return _sortiter( t )
end
---- Return a key, value iterator for the given table.
-- The table pairs are sorted by value.
--- @param t The table to iterate
--- @return Function value containing the corresponding iterator
function vspairs(t)
return _sortiter( t, function (a,b) return t[a] < t[b] end )
end
@@ -637,15 +539,10 @@ end
-- System utility functions
--
---- Test whether the current system is operating in big endian mode.
--- @return Boolean value indicating whether system is big endian
function bigendian()
return string.byte(string.dump(function() end), 7) == 0
end
---- Execute given commandline and gather stdout.
--- @param command String containing command to execute
--- @return String containing the command's stdout
function exec(command)
local pp = io.popen(command)
local data = pp:read("*a")
@@ -654,9 +551,6 @@ function exec(command)
return data
end
---- Return a line-buffered iterator over the output of given command.
--- @param command String containing the command to execute
--- @return Iterator
function execi(command)
local pp = io.popen(command)
@@ -687,11 +581,6 @@ function execl(command)
return data
end
---- Issue an ubus call.
--- @param object String containing the ubus object to call
--- @param method String containing the ubus method to call
--- @param values Table containing the values to pass
--- @return Table containin the ubus result
function ubus(object, method, data)
if not _ubus_connection then
_ubus_connection = _ubus.connect()
@@ -710,8 +599,60 @@ function ubus(object, method, data)
end
end
---- Returns the absolute path to LuCI base directory.
--- @return String containing the directory path
+function serialize_json(x, cb)
+ local rv, push = nil, cb
+ if not push then
+ rv = { }
+ push = function(tok) rv[#rv+1] = tok end
+ end
+
+ if x == nil then
+ push("null")
+ elseif type(x) == "table" then
+ -- test if table is array like
+ local k, v
+ local n1, n2 = 0, 0
+ for k in pairs(x) do n1 = n1 + 1 end
+ for k in ipairs(x) do n2 = n2 + 1 end
+
+ if n1 == n2 and n1 > 0 then
+ push("[")
+ for k = 1, n2 do
+ if k > 1 then
+ push(",")
+ end
+ serialize_json(x[k], push)
+ end
+ push("]")
+ else
+ push("{")
+ for k, v in pairs(x) do
+ push("%q:" % tostring(k))
+ serialize_json(v, push)
+ if next(x, k) then
+ push(",")
+ end
+ end
+ push("}")
+ end
+ elseif type(x) == "number" or type(x) == "boolean" then
+ if (x ~= x) then
+ -- NaN is the only value that doesn't equal to itself.
+ push("Number.NaN")
+ else
+ push(tostring(x))
+ end
+ else
+ push('"%s"' % tostring(x):gsub('["%z\1-\31]',
+ function(c) return '\\u%04x' % c:byte(1) end))
+ end
+
+ if not cb then
+ return table.concat(rv, "")
+ end
+end
+
+
function libpath()
return require "nixio.fs".dirname(ldebug.__file__)
end
@@ -751,11 +692,6 @@ local function copcall_id(trace, ...)
return ...
end
---- This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
--- @param f Lua function to be called protected
--- @param err Custom error handler
--- @param ... Parameters passed to the function
--- @return A boolean whether the function call succeeded and the return
-- values of either the function or the error handler
function coxpcall(f, err, ...)
local res, co = oldpcall(coroutine.create, f)
@@ -770,10 +706,6 @@ function coxpcall(f, err, ...)
return performResume(err, co, ...)
end
---- This is a coroutine-safe drop-in replacement for Lua's "pcall"-function
--- @param f Lua function to be called protected
--- @param ... Parameters passed to the function
--- @return A boolean whether the function call succeeded and the returns
-- values of the function or the error object
function copcall(f, ...)
return coxpcall(f, copcall_id, ...)
diff --git a/modules/luci-base/luasrc/util.luadoc b/modules/luci-base/luasrc/util.luadoc
new file mode 100644
index 0000000000..1c09b7a9ab
--- /dev/null
+++ b/modules/luci-base/luasrc/util.luadoc
@@ -0,0 +1,378 @@
+---[[
+LuCI utility functions.
+
+module "luci.util"
+]]
+
+---[[
+Create a Class object (Python-style object model).
+
+The class object can be instantiated by calling itself.
+Any class functions or shared parameters can be attached to this object.
+Attaching a table to the class object makes this table shared between
+all instances of this class. For object parameters use the __init__ function.
+Classes can inherit member functions and values from a base class.
+Class can be instantiated by calling them. All parameters will be passed
+to the __init__ function of this class - if such a function exists.
+The __init__ function must be used to set any object parameters that are not shared
+with other objects of this class. Any return values will be ignored.
+@class function
+@name class
+@param base The base class to inherit from (optional)
+@return A class object
+@see instanceof
+@see clone
+]]
+
+---[[
+Test whether the given object is an instance of the given class.
+
+@class function
+@name instanceof
+@param object Object instance
+@param class Class object to test against
+@return Boolean indicating whether the object is an instance
+@see class
+@see clone
+]]
+
+---[[
+Create a new or get an already existing thread local store associated with
+
+the current active coroutine. A thread local store is private a table object
+whose values can't be accessed from outside of the running coroutine.
+@class function
+@name threadlocal
+@return Table value representing the corresponding thread local store
+]]
+
+---[[
+Write given object to stderr.
+
+@class function
+@name perror
+@param obj Value to write to stderr
+@return Boolean indicating whether the write operation was successful
+]]
+
+---[[
+Recursively dumps a table to stdout, useful for testing and debugging.
+
+@class function
+@name dumptable
+@param t Table value to dump
+@param maxdepth Maximum depth
+@return Always nil
+]]
+
+---[[
+Create valid XML PCDATA from given string.
+
+@class function
+@name pcdata
+@param value String value containing the data to escape
+@return String value containing the escaped data
+]]
+
+---[[
+Strip HTML tags from given string.
+
+@class function
+@name striptags
+@param value String containing the HTML text
+@return String with HTML tags stripped of
+]]
+
+---[[
+Splits given string on a defined separator sequence and return a table
+
+containing the resulting substrings. The optional max parameter specifies
+the number of bytes to process, regardless of the actual length of the given
+string. The optional last parameter, regex, specifies whether the separator
+sequence is interpreted as regular expression.
+@class function
+@name split
+@param str String value containing the data to split up
+@param pat String with separator pattern (optional, defaults to "\n")
+@param max Maximum times to split (optional)
+@param regex Boolean indicating whether to interpret the separator
+-- pattern as regular expression (optional, default is false)
+@return Table containing the resulting substrings
+]]
+
+---[[
+Remove leading and trailing whitespace from given string value.
+
+@class function
+@name trim
+@param str String value containing whitespace padded data
+@return String value with leading and trailing space removed
+]]
+
+---[[
+Count the occurences of given substring in given string.
+
+@class function
+@name cmatch
+@param str String to search in
+@param pattern String containing pattern to find
+@return Number of found occurences
+]]
+
+---[[
+Return a matching iterator for the given value. The iterator will return
+
+one token per invocation, the tokens are separated by whitespace. If the
+input value is a table, it is transformed into a string first. A nil value
+will result in a valid interator which aborts with the first invocation.
+@class function
+@name imatch
+@param val The value to scan (table, string or nil)
+@return Iterator which returns one token per call
+]]
+
+---[[
+Parse certain units from the given string and return the canonical integer
+
+value or 0 if the unit is unknown. Upper- or lower case is irrelevant.
+Recognized units are:
+-- o "y" - one year (60*60*24*366)
+ o "m" - one month (60*60*24*31)
+ o "w" - one week (60*60*24*7)
+ o "d" - one day (60*60*24)
+ o "h" - one hour (60*60)
+ o "min" - one minute (60)
+ o "kb" - one kilobyte (1024)
+ o "mb" - one megabyte (1024*1024)
+ o "gb" - one gigabyte (1024*1024*1024)
+ o "kib" - one si kilobyte (1000)
+ o "mib" - one si megabyte (1000*1000)
+ o "gib" - one si gigabyte (1000*1000*1000)
+@class function
+@name parse_units
+@param ustr String containing a numerical value with trailing unit
+@return Number containing the canonical value
+]]
+
+---[[
+Appends numerically indexed tables or single objects to a given table.
+
+@class function
+@name append
+@param src Target table
+@param ... Objects to insert
+@return Target table
+]]
+
+---[[
+Combines two or more numerically indexed tables and single objects into one table.
+
+@class function
+@name combine
+@param tbl1 Table value to combine
+@param tbl2 Table value to combine
+@param ... More tables to combine
+@return Table value containing all values of given tables
+]]
+
+---[[
+Checks whether the given table contains the given value.
+
+@class function
+@name contains
+@param table Table value
+@param value Value to search within the given table
+@return Boolean indicating whether the given value occurs within table
+]]
+
+---[[
+Update values in given table with the values from the second given table.
+
+Both table are - in fact - merged together.
+@class function
+@name update
+@param t Table which should be updated
+@param updates Table containing the values to update
+@return Always nil
+]]
+
+---[[
+Retrieve all keys of given associative table.
+
+@class function
+@name keys
+@param t Table to extract keys from
+@return Sorted table containing the keys
+]]
+
+---[[
+Clones the given object and return it's copy.
+
+@class function
+@name clone
+@param object Table value to clone
+@param deep Boolean indicating whether to do recursive cloning
+@return Cloned table value
+]]
+
+---[[
+Create a dynamic table which automatically creates subtables.
+
+@class function
+@name dtable
+@return Dynamic Table
+]]
+
+---[[
+Recursively serialize given data to lua code, suitable for restoring
+
+with loadstring().
+@class function
+@name serialize_data
+@param val Value containing the data to serialize
+@return String value containing the serialized code
+@see restore_data
+@see get_bytecode
+]]
+
+---[[
+Restore data previously serialized with serialize_data().
+
+@class function
+@name restore_data
+@param str String containing the data to restore
+@return Value containing the restored data structure
+@see serialize_data
+@see get_bytecode
+]]
+
+---[[
+Return the current runtime bytecode of the given data. The byte code
+
+will be stripped before it is returned.
+@class function
+@name get_bytecode
+@param val Value to return as bytecode
+@return String value containing the bytecode of the given data
+]]
+
+---[[
+Strips unnescessary lua bytecode from given string. Information like line
+
+numbers and debugging numbers will be discarded. Original version by
+Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
+@class function
+@name strip_bytecode
+@param code String value containing the original lua byte code
+@return String value containing the stripped lua byte code
+]]
+
+---[[
+Return a key, value iterator which returns the values sorted according to
+
+the provided callback function.
+@class function
+@name spairs
+@param t The table to iterate
+@param f A callback function to decide the order of elements
+@return Function value containing the corresponding iterator
+]]
+
+---[[
+Return a key, value iterator for the given table.
+
+The table pairs are sorted by key.
+@class function
+@name kspairs
+@param t The table to iterate
+@return Function value containing the corresponding iterator
+]]
+
+---[[
+Return a key, value iterator for the given table.
+
+The table pairs are sorted by value.
+@class function
+@name vspairs
+@param t The table to iterate
+@return Function value containing the corresponding iterator
+]]
+
+---[[
+Test whether the current system is operating in big endian mode.
+
+@class function
+@name bigendian
+@return Boolean value indicating whether system is big endian
+]]
+
+---[[
+Execute given commandline and gather stdout.
+
+@class function
+@name exec
+@param command String containing command to execute
+@return String containing the command's stdout
+]]
+
+---[[
+Return a line-buffered iterator over the output of given command.
+
+@class function
+@name execi
+@param command String containing the command to execute
+@return Iterator
+]]
+
+---[[
+Issue an ubus call.
+
+@class function
+@name ubus
+@param object String containing the ubus object to call
+@param method String containing the ubus method to call
+@param values Table containing the values to pass
+@return Table containin the ubus result
+]]
+
+---[[
+Convert data structure to JSON
+
+@class function
+@name serialize_json
+@param data The data to serialize
+@param writer A function to write a chunk of JSON data (optional)
+@return String containing the JSON if called without write callback
+]]
+
+---[[
+Returns the absolute path to LuCI base directory.
+
+@class function
+@name libpath
+@return String containing the directory path
+]]
+
+---[[
+This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
+
+@class function
+@name coxpcall
+@param f Lua function to be called protected
+@param err Custom error handler
+@param ... Parameters passed to the function
+@return A boolean whether the function call succeeded and the return
+-- values of either the function or the error handler
+]]
+
+---[[
+This is a coroutine-safe drop-in replacement for Lua's "pcall"-function
+
+@class function
+@name copcall
+@param f Lua function to be called protected
+@param ... Parameters passed to the function
+@return A boolean whether the function call succeeded and the returns
+-- values of the function or the error object
+]]
+
diff --git a/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua b/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua
index 055142b53e..52e347d07b 100644
--- a/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua
+++ b/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua
@@ -178,13 +178,7 @@ function action_flashops()
local image_tmp = "/tmp/firmware.img"
local function image_supported()
- -- XXX: yay...
- return ( 0 == os.execute(
- ". /lib/functions.sh; " ..
- "include /lib/upgrade; " ..
- "platform_check_image %q >/dev/null"
- % image_tmp
- ) )
+ return (os.execute("sysupgrade -T %q >/dev/null" % image_tmp) == 0)
end
local function image_checksum()
diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua
index 88e81bb18c..997a9274d2 100644
--- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua
+++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua
@@ -1,7 +1,7 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
-local sys = require "luci.sys"
+local ipc = require "luci.ip"
m = Map("dhcp", translate("DHCP and DNS"),
translate("Dnsmasq is a combined <abbr title=\"Dynamic Host Configuration Protocol" ..
@@ -232,12 +232,11 @@ ip.datatype = "or(ip4addr,'ignore')"
hostid = s:option(Value, "hostid", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Suffix (hex)"))
-sys.net.arptable(function(entry)
- ip:value(entry["IP address"])
- mac:value(
- entry["HW address"],
- entry["HW address"] .. " (" .. entry["IP address"] .. ")"
- )
+ipc.neighbors({ family = 4 }, function(n)
+ if n.mac and n.dest then
+ ip:value(n.dest:string())
+ mac:value(n.mac, "%s (%s)" %{ n.mac, n.dest:string() })
+ end
end)
function ip.validate(self, value, section)
diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/hosts.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/hosts.lua
index da7c1181f7..fafacf35c5 100644
--- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/hosts.lua
+++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/hosts.lua
@@ -1,9 +1,9 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
--- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
+-- Copyright 2010-2015 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
-require("luci.sys")
-require("luci.util")
+local ipc = require "luci.ip"
+
m = Map("dhcp", translate("Hostnames"))
s = m:section(TypedSection, "domain", translate("Host entries"))
@@ -19,12 +19,10 @@ ip = s:option(Value, "ip", translate("IP address"))
ip.datatype = "ipaddr"
ip.rmempty = true
-local arptable = luci.sys.net.arptable() or {}
-for i, dataset in ipairs(arptable) do
- ip:value(
- dataset["IP address"],
- "%s (%s)" %{ dataset["IP address"], dataset["HW address"] }
- )
-end
+ipc.neighbors({ }, function(n)
+ if n.mac and n.dest and not n.dest:is6linklocal() then
+ ip:value(n.dest:string(), "%s (%s)" %{ n.dest:string(), n.mac })
+ end
+end)
return m
diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/ifaces.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/ifaces.lua
index eabb257680..c2e5c72285 100644
--- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/ifaces.lua
+++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/ifaces.lua
@@ -14,6 +14,7 @@ local has_dnsmasq = fs.access("/etc/config/dhcp")
local has_firewall = fs.access("/etc/config/firewall")
m = Map("network", translate("Interfaces") .. " - " .. arg[1]:upper(), translate("On this page you can configure the network interfaces. You can bridge several interfaces by ticking the \"bridge interfaces\" field and enter the names of several network interfaces separated by spaces. You can also use <abbr title=\"Virtual Local Area Network\">VLAN</abbr> notation <samp>INTERFACE.VLANNR</samp> (<abbr title=\"for example\">e.g.</abbr>: <samp>eth0.1</samp>)."))
+m.redirect = luci.dispatcher.build_url("admin", "network", "network")
m:chain("wireless")
if has_firewall then
diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/routes.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/routes.lua
index 01580f1016..ac02b156e9 100644
--- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/routes.lua
+++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/routes.lua
@@ -1,14 +1,14 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
-require("luci.tools.webadmin")
+local wa = require "luci.tools.webadmin"
+local fs = require "nixio.fs"
+
m = Map("network",
translate("Routes"),
translate("Routes specify over which interface and gateway a certain host or network " ..
"can be reached."))
-local routes6 = luci.sys.net.routes6()
-
s = m:section(TypedSection, "route", translate("Static IPv4 Routes"))
s.addremove = true
s.anonymous = true
@@ -16,7 +16,7 @@ s.anonymous = true
s.template = "cbi/tblsection"
iface = s:option(ListValue, "interface", translate("Interface"))
-luci.tools.webadmin.cbi_add_networks(iface)
+wa.cbi_add_networks(iface)
t = s:option(Value, "target", translate("Target"), translate("Host-<abbr title=\"Internet Protocol Address\">IP</abbr> or Network"))
t.datatype = "ip4addr"
@@ -41,7 +41,7 @@ mtu.placeholder = 1500
mtu.datatype = "range(64,9000)"
mtu.rmempty = true
-if routes6 then
+if fs.access("/proc/net/ipv6_route") then
s = m:section(TypedSection, "route6", translate("Static IPv6 Routes"))
s.addremove = true
s.anonymous = true
@@ -49,7 +49,7 @@ if routes6 then
s.template = "cbi/tblsection"
iface = s:option(ListValue, "interface", translate("Interface"))
- luci.tools.webadmin.cbi_add_networks(iface)
+ wa.cbi_add_networks(iface)
t = s:option(Value, "target", translate("Target"), translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Address or Network (CIDR)"))
t.datatype = "ip6addr"
diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm
index ea60a7f078..b7c44f9073 100644
--- a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm
+++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm
@@ -1,12 +1,12 @@
<%#
Copyright 2008-2009 Steven Barth <steven@midlink.org>
- Copyright 2008-2013 Jo-Philipp Wich <jow@openwrt.org>
+ Copyright 2008-2015 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<%-
- local sys = require "luci.sys"
+ local ip = require "luci.ip"
local fs = require "nixio.fs"
local utl = require "luci.util"
local uci = require "luci.model.uci".cursor()
@@ -90,7 +90,9 @@
local devices = ntm:get_wifidevs()
local arpcache = { }
- sys.net.arptable(function(e) arpcache[e["HW address"]:upper()] = e["IP address"] end)
+ ip.neighbors({ family = 4 }, function(n)
+ if n.mac and n.dest then arpcache[n.mac:upper()] = n.dest:string() end
+ end)
local netlist = { }
local netdevs = { }
diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm
index 2d9a4a3dc8..82dd3a7dfe 100644
--- a/modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm
+++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/routes.htm
@@ -1,15 +1,33 @@
<%#
Copyright 2008-2009 Steven Barth <steven@midlink.org>
- Copyright 2008-2009 Jo-Philipp Wich <jow@openwrt.org>
+ Copyright 2008-2015 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<%-
- require "luci.sys"
require "luci.tools.webadmin"
require "nixio.fs"
+ local ip = require "luci.ip"
local style = true
+ local _, v
+
+ local rtn = {
+ [255] = "local",
+ [254] = "main",
+ [253] = "default",
+ [0] = "unspec"
+ }
+
+ if nixio.fs.access("/etc/iproute2/rt_tables") then
+ local ln
+ for ln in io.lines("/etc/iproute2/rt_tables") do
+ local i, n = ln:match("^(%d+)%s+(%S+)")
+ if i and n then
+ rtn[tonumber(i)] = n
+ end
+ end
+ end
-%>
<%+header%>
@@ -18,7 +36,7 @@
<h2><a id="content" name="content"><%:Routes%></a></h2>
<div class="cbi-map-descr"><%:The following rules are currently active on this system.%></div>
- <fieldset class="cbi-section" id="cbi-table-table">
+ <fieldset class="cbi-section">
<legend>ARP</legend>
<div class="cbi-section-node">
<table class="cbi-section-table">
@@ -28,19 +46,26 @@
<th class="cbi-section-table-cell"><%:Interface%></th>
</tr>
- <% luci.sys.net.arptable(function(e) %>
+ <%
+ for _, v in ipairs(ip.neighbors({ family = 4 })) do
+ if v.mac then
+ %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
- <td class="cbi-value-field"><%=e["IP address"]%></td>
- <td class="cbi-value-field"><%=e["HW address"]%></td>
- <td class="cbi-value-field"><%=e["Device"]%></td>
+ <td class="cbi-value-field"><%=v.dest%></td>
+ <td class="cbi-value-field"><%=v.mac%></td>
+ <td class="cbi-value-field"><%=v.dev%></td>
</tr>
- <% style = not style; end) %>
+ <%
+ style = not style
+ end
+ end
+ %>
</table>
</div>
</fieldset>
<br />
- <fieldset class="cbi-section" id="cbi-table-table">
+ <fieldset class="cbi-section">
<legend><%_Active <abbr title="Internet Protocol Version 4">IPv4</abbr>-Routes%></legend>
<div class="cbi-section-node">
@@ -50,25 +75,27 @@
<th class="cbi-section-table-cell"><%:Target%></th>
<th class="cbi-section-table-cell"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Gateway%></th>
<th class="cbi-section-table-cell"><%:Metric%></th>
+ <th class="cbi-section-table-cell"><%:Table%></th>
</tr>
- <% luci.sys.net.routes(function(rt) %>
+ <% for _, v in ipairs(ip.routes({ family = 4, type = 1 })) do %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
- <td class="cbi-value-field"><%=luci.tools.webadmin.iface_get_network(rt.device) or rt.device%></td>
- <td class="cbi-value-field"><%=rt.dest:string()%></td>
- <td class="cbi-value-field"><%=rt.gateway:string()%></td>
- <td class="cbi-value-field"><%=rt.metric%></td>
+ <td class="cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or v.dev%></td>
+ <td class="cbi-value-field"><%=v.dest%></td>
+ <td class="cbi-value-field"><%=v.gw%></td>
+ <td class="cbi-value-field"><%=v.metric or 0%></td>
+ <td class="cbi-value-field"><%=rtn[v.table] or v.table%></td>
</tr>
- <% style = not style; end) %>
+ <% style = not style end %>
</table>
</div>
</fieldset>
<br />
- <% if nixio.fs.access("/proc/net/ipv6_route") then
- style = true
- fe80 = luci.ip.IPv6("fe80::/10")
+ <%
+ if nixio.fs.access("/proc/net/ipv6_route") then
+ style = true
%>
- <fieldset class="cbi-section" id="cbi-table-table">
+ <fieldset class="cbi-section">
<legend><%_Active <abbr title="Internet Protocol Version 6">IPv6</abbr>-Routes%></legend>
<div class="cbi-section-node">
@@ -76,17 +103,55 @@
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Network%></th>
<th class="cbi-section-table-cell"><%:Target%></th>
- <th class="cbi-section-table-cell"><%_<abbr title="Internet Protocol Version 6">IPv6</abbr>-Gateway%></th>
+ <th class="cbi-section-table-cell"><%:Source%></th>
<th class="cbi-section-table-cell"><%:Metric%></th>
+ <th class="cbi-section-table-cell"><%:Table%></th>
+ </tr>
+ <%
+ for _, v in ipairs(ip.routes({ family = 6, type = 1 })) do
+ if v.dest and not v.dest:is6linklocal() then
+ %>
+ <tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
+ <td class="cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></td>
+ <td class="cbi-value-field"><%=v.dest%></td>
+ <td class="cbi-value-field"><%=v.from%></td>
+ <td class="cbi-value-field"><%=v.metric or 0%></td>
+ <td class="cbi-value-field"><%=rtn[v.table] or v.table%></td>
+ </tr>
+ <%
+ style = not style
+ end
+ end
+ %>
+ </table>
+ </div>
+ </fieldset>
+ <br />
+
+ <fieldset class="cbi-section">
+ <legend><%:IPv6 Neighbours%></legend>
+
+ <div class="cbi-section-node">
+ <table class="cbi-section-table">
+ <tr class="cbi-section-table-titles">
+ <th class="cbi-section-table-cell"><%:IPv6-Address%></th>
+ <th class="cbi-section-table-cell"><%:MAC-Address%></th>
+ <th class="cbi-section-table-cell"><%:Interface%></th>
</tr>
- <% luci.sys.net.routes6(function(rt) if fe80:contains(rt.dest) then return end %>
+ <%
+ for _, v in ipairs(ip.neighbors({ family = 6 })) do
+ if v.dest and not v.dest:is6linklocal() and v.mac then
+ %>
<tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
- <td class="cbi-value-field"><%=luci.tools.webadmin.iface_get_network(rt.device) or '(' .. rt.device .. ')'%></td>
- <td class="cbi-value-field"><%=rt.dest:string()%></td>
- <td class="cbi-value-field"><%=rt.source:string()%></td>
- <td class="cbi-value-field"><%=rt.metric_raw:upper()%></td>
+ <td class="cbi-value-field"><%=v.dest%></td>
+ <td class="cbi-value-field"><%=v.mac%></td>
+ <td class="cbi-value-field"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></td>
</tr>
- <% style = not style; end) %>
+ <%
+ style = not style
+ end
+ end
+ %>
</table>
</div>
</fieldset>
diff --git a/modules/luci-mod-admin-mini/luasrc/model/cbi/mini/dhcp.lua b/modules/luci-mod-admin-mini/luasrc/model/cbi/mini/dhcp.lua
index 5d3d8ad22a..9a1c1fea45 100644
--- a/modules/luci-mod-admin-mini/luasrc/model/cbi/mini/dhcp.lua
+++ b/modules/luci-mod-admin-mini/luasrc/model/cbi/mini/dhcp.lua
@@ -3,7 +3,7 @@
-- Licensed to the public under the Apache License 2.0.
local uci = require "luci.model.uci".cursor()
-local sys = require "luci.sys"
+local ipc = require "luci.ip"
local wa = require "luci.tools.webadmin"
local fs = require "nixio.fs"
@@ -86,12 +86,12 @@ s2.template = "cbi/tblsection"
name = s2:option(Value, "name", translate("Hostname"))
mac = s2:option(Value, "mac", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
ip = s2:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
-sys.net.arptable(function(entry)
- ip:value(entry["IP address"])
- mac:value(
- entry["HW address"],
- entry["HW address"] .. " (" .. entry["IP address"] .. ")"
- )
+
+ipc.neighbors({ family = 4 }, function(n)
+ if n.mac and n.dest then
+ ip:value(n.dest:string())
+ mac:value(n.mac, "%s (%s)" %{ n.mac, n.dest:string() })
+ end
end)
return m
diff --git a/modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm b/modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm
index 715ac756fd..72bd136c5e 100644
--- a/modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm
+++ b/modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm
@@ -2,6 +2,7 @@
local utl = require "luci.util"
local sys = require "luci.sys"
local twa = require "luci.tools.webadmin"
+local ip = require "luci.ip"
-- System
@@ -48,27 +49,6 @@ for _, dev in ipairs(devices) do
end
local has_iwinfo = pcall(require, "iwinfo")
--- Routes
-local defroutev4 = sys.net.defaultroute()
-local defroutev6 = sys.net.defaultroute6()
-
-if defroutev4 then
- defroutev4.dest = defroutev4.dest:string()
- defroutev4.gateway = defroutev4.gateway:string()
-else
- -- probably policy routing activated, try olsr-default table
- local dr4 = sys.exec("ip r s t olsr-default")
- if dr4 then
- defroutev4 = { }
- defroutev4.dest, defroutev4.gateway, defroutev4.device, defroutev4.metric = dr4:match("^(%w+) via (%d+.%d+.%d+.%d+) dev ([%w-]+) +metric (%d+)")
- end
-end
-
-if defroutev6 then
- defroutev6.dest = defroutev6.dest:string()
- defroutev6.nexthop = defroutev6.nexthop:string()
-end
-
if luci.http.formvalue("status") == "1" then
local rv = { }
for dev in pairs(netdevs) do
@@ -86,22 +66,29 @@ if luci.http.formvalue("status") == "1" then
rv[#rv+1] = j
end
- if defroutev6 then
- def6 = {
- gateway = defroutev6.nexthop,
- dest = defroutev6.dest,
- dev = defroutev6.device,
- metr = defroutev6.metric
+
+ -- Find default routes
+
+ local _, r, def4, def6
+
+ for _, r in ipairs(ip.routes({ type = 1, dest_exact = "0.0.0.0/0" })) do
+ def4 = {
+ gateway = r.gw:string(),
+ dest = r.dest:string(),
+ dev = r.dev,
+ metr = r.metric or 0
}
+ break
end
- if defroutev4 then
- def4 = {
- gateway = defroutev4.gateway,
- dest = defroutev4.dest,
- dev = defroutev4.device,
- metr = defroutev4.metric
+ for _, r in ipairs(ip.routes({ type = 1, dest_exact = "::/0" })) do
+ def6 = {
+ gateway = r.gw:string(),
+ dest = r.dest:string(),
+ dev = r.dev,
+ metr = r.metric or 0
}
+ break
end
rv[#rv+1] = {