Move inline documentation into separate files.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
This commit is contained in:
Jo-Philipp Wich 2015-01-29 16:26:15 +01:00
parent cf7e2695cc
commit 84346cd178
31 changed files with 2166 additions and 868 deletions

View file

@ -25,14 +25,9 @@ local char = string.char
local getmetatable = getmetatable local getmetatable = getmetatable
--- LuCI JSON-Library
-- @cstyle instance
module "luci.json" module "luci.json"
--- Directly decode a JSON string
-- @param json JSON-String
-- @return Lua object
function decode(json, ...) function decode(json, ...)
local a = ActiveDecoder(function() return nil end, ...) local a = ActiveDecoder(function() return nil end, ...)
a.chunk = json a.chunk = json
@ -41,9 +36,6 @@ function decode(json, ...)
end end
--- Direcly encode a Lua object into a JSON string.
-- @param obj Lua Object
-- @return JSON string
function encode(obj, ...) function encode(obj, ...)
local out = {} local out = {}
local e = Encoder(obj, 1, ...):source() local e = Encoder(obj, 1, ...):source()
@ -56,19 +48,10 @@ function encode(obj, ...)
end end
--- Null replacement function
-- @return null
function null() function null()
return null return null
end end
--- Create a new JSON-Encoder.
-- @class function
-- @name Encoder
-- @param data Lua-Object to be encoded.
-- @param buffersize Blocksize of returned data source.
-- @param fastescape Use non-standard escaping (don't escape control chars)
-- @return JSON-Encoder
Encoder = util.class() Encoder = util.class()
function Encoder.__init__(self, data, buffersize, fastescape) function Encoder.__init__(self, data, buffersize, fastescape)
@ -80,8 +63,6 @@ function Encoder.__init__(self, data, buffersize, fastescape)
getmetatable(self).__call = Encoder.source getmetatable(self).__call = Encoder.source
end end
--- Create an LTN12 source providing the encoded JSON-Data.
-- @return LTN12 source
function Encoder.source(self) function Encoder.source(self)
local source = coroutine.create(self.dispatch) local source = coroutine.create(self.dispatch)
return function() return function()
@ -208,11 +189,6 @@ Encoder.parsers = {
} }
--- Create a new JSON-Decoder.
-- @class function
-- @name Decoder
-- @param customnull Use luci.json.null instead of nil for decoding null
-- @return JSON-Decoder
Decoder = util.class() Decoder = util.class()
function Decoder.__init__(self, customnull) function Decoder.__init__(self, customnull)
@ -220,8 +196,6 @@ function Decoder.__init__(self, customnull)
getmetatable(self).__call = Decoder.sink getmetatable(self).__call = Decoder.sink
end end
--- Create an LTN12 sink from the decoder object which accepts the JSON-Data.
-- @return LTN12 sink
function Decoder.sink(self) function Decoder.sink(self)
local sink = coroutine.create(self.dispatch) local sink = coroutine.create(self.dispatch)
return function(...) return function(...)
@ -230,8 +204,6 @@ function Decoder.sink(self)
end end
--- Get the decoded data packets after the rawdata has been sent to the sink.
-- @return Decoded data
function Decoder.get(self) function Decoder.get(self)
return self.data return self.data
end end
@ -526,11 +498,6 @@ Decoder.parsers = {
} }
--- Create a new Active JSON-Decoder.
-- @class function
-- @name ActiveDecoder
-- @param customnull Use luci.json.null instead of nil for decoding null
-- @return Active JSON-Decoder
ActiveDecoder = util.class(Decoder) ActiveDecoder = util.class(Decoder)
function ActiveDecoder.__init__(self, source, customnull) function ActiveDecoder.__init__(self, source, customnull)
@ -541,8 +508,6 @@ function ActiveDecoder.__init__(self, source, customnull)
end end
--- Fetches one JSON-object from given source
-- @return Decoded object
function ActiveDecoder.get(self) function ActiveDecoder.get(self)
local chunk, src_err, object local chunk, src_err, object
if not self.chunk then if not self.chunk then

View file

@ -0,0 +1,94 @@
---[[
LuCI JSON-Library
@cstyle instance
module "luci.json"
]]
---[[
Directly decode a JSON string
@class function
@name decode
@param json JSON-String
@return Lua object
]]
---[[
Direcly encode a Lua object into a JSON string.
@class function
@name encode
@param obj Lua Object
@return JSON string
]]
---[[
Null replacement function
@class function
@name null
@return null
]]
---[[
Create a new JSON-Encoder.
@class function
@name Encoder
@param data Lua-Object to be encoded.
@param buffersize Blocksize of returned data source.
@param fastescape Use non-standard escaping (don't escape control chars)
@return JSON-Encoder
]]
---[[
Create an LTN12 source providing the encoded JSON-Data.
@class function
@name Encoder.source
@return LTN12 source
]]
---[[
Create a new JSON-Decoder.
@class function
@name Decoder
@param customnull Use luci.json.null instead of nil for decoding null
@return JSON-Decoder
]]
---[[
Create an LTN12 sink from the decoder object which accepts the JSON-Data.
@class function
@name Decoder.sink
@return LTN12 sink
]]
---[[
Get the decoded data packets after the rawdata has been sent to the sink.
@class function
@name Decoder.get
@return Decoded data
]]
---[[
Create a new Active JSON-Decoder.
@class function
@name ActiveDecoder
@param customnull Use luci.json.null instead of nil for decoding null
@return Active JSON-Decoder
]]
---[[
Fetches one JSON-object from given source
@class function
@name ActiveDecoder.get
@return Decoded object
]]

View file

@ -9,17 +9,10 @@ local nixio = require "nixio", require "nixio.util"
local tostring, assert, setmetatable = tostring, assert, setmetatable local tostring, assert, setmetatable = tostring, assert, setmetatable
local error = error local error = error
--- LuCI RPC Client.
-- @cstyle instance
module "luci.rpcc" module "luci.rpcc"
RQLIMIT = 32 * nixio.const.buffersize RQLIMIT = 32 * nixio.const.buffersize
--- Create a new JSON-RPC stream client.
-- @class function
-- @param fd File descriptor
-- @param v1 Use protocol version 1.0
-- @return RPC Client
Client = util.class() Client = util.class()
function Client.__init__(self, fd, v1) function Client.__init__(self, fd, v1)
@ -29,11 +22,6 @@ function Client.__init__(self, fd, v1)
self.v1 = v1 self.v1 = v1
end end
--- Request an RP call and get the response.
-- @param method Remote method
-- @param params Parameters
-- @param notification Notification only?
-- @return response
function Client.request(self, method, params, notification) function Client.request(self, method, params, notification)
local oldchunk = self.decoder and self.decoder.chunk local oldchunk = self.decoder and self.decoder.chunk
self.decoder = json.ActiveDecoder(self.fd:blocksource(nil, RQLIMIT)) self.decoder = json.ActiveDecoder(self.fd:blocksource(nil, RQLIMIT))
@ -58,9 +46,6 @@ function Client.request(self, method, params, notification)
end end
end end
--- Create a transparent RPC proxy.
-- @param prefix Method prefix
-- @return RPC Proxy object
function Client.proxy(self, prefix) function Client.proxy(self, prefix)
prefix = prefix or "" prefix = prefix or ""
return setmetatable({}, { return setmetatable({}, {

View file

@ -0,0 +1,36 @@
---[[
LuCI RPC Client.
@cstyle instance
module "luci.rpcc"
]]
---[[
Create a new JSON-RPC stream client.
@class function
@param fd File descriptor
@param v1 Use protocol version 1.0
@return RPC Client
]]
---[[
Request an RP call and get the response.
@class function
@name Client.request
@param method Remote method
@param params Parameters
@param notification Notification only?
@return response
]]
---[[
Create a transparent RPC proxy.
@class function
@name Client.proxy
@param prefix Method prefix
@return RPC Proxy object
]]

View file

@ -5,16 +5,11 @@ local util = require "luci.util"
local rawget, setmetatable = rawget, setmetatable local rawget, setmetatable = rawget, setmetatable
local ipairs = ipairs local ipairs = ipairs
--- Transparent UCI over RPC client.
-- @cstyle instance
module "luci.rpcc.ruci" module "luci.rpcc.ruci"
local Proxy = util.class() local Proxy = util.class()
--- Create a new UCI over RPC proxy.
-- @param rpccl RPC client
-- @return Network transparent UCI module
function factory(rpccl) function factory(rpccl)
return { return {
cursor = function(...) cursor = function(...)

View file

@ -0,0 +1,16 @@
---[[
Transparent UCI over RPC client.
@cstyle instance
module "luci.rpcc.ruci"
]]
---[[
Create a new UCI over RPC proxy.
@class function
@name factory
@param rpccl RPC client
@return Network transparent UCI module
]]

View file

@ -1,7 +1,6 @@
-- Copyright 2008 Steven Barth <steven@midlink.org> -- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0. -- Licensed to the public under the Apache License 2.0.
--- LuCI web dispatcher.
local fs = require "nixio.fs" local fs = require "nixio.fs"
local sys = require "luci.sys" local sys = require "luci.sys"
local util = require "luci.util" local util = require "luci.util"
@ -23,9 +22,6 @@ local index = nil
local fi local fi
--- Build the URL relative to the server webroot from given virtual path.
-- @param ... Virtual path
-- @return Relative URL
function build_url(...) function build_url(...)
local path = {...} local path = {...}
local url = { http.getenv("SCRIPT_NAME") or "" } local url = { http.getenv("SCRIPT_NAME") or "" }
@ -49,9 +45,6 @@ function build_url(...)
return table.concat(url, "") return table.concat(url, "")
end 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) function node_visible(node)
if node then if node then
return not ( return not (
@ -64,9 +57,6 @@ function node_visible(node)
return false return false
end 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) function node_childs(node)
local rv = { } local rv = { }
if node then if node then
@ -86,9 +76,6 @@ function node_childs(node)
end end
--- Send a 404 error code and render the "error404" template if available.
-- @param message Custom error message (optional)
-- @return false
function error404(message) function error404(message)
http.status(404, "Not Found") http.status(404, "Not Found")
message = message or "Not Found" message = message or "Not Found"
@ -101,9 +88,6 @@ function error404(message)
return false return false
end end
--- Send a 500 error code and render the "error500" template if available.
-- @param message Custom error message (optional)#
-- @return false
function error500(message) function error500(message)
util.perror(message) util.perror(message)
if not context.template_header_sent then if not context.template_header_sent then
@ -144,8 +128,6 @@ function authenticator.htmlauth(validator, accs, default)
end end
--- Dispatch an HTTP request.
-- @param request LuCI HTTP Request object
function httpdispatch(request, prefix) function httpdispatch(request, prefix)
http.context.request = request http.context.request = request
@ -184,8 +166,6 @@ function httpdispatch(request, prefix)
--context._disable_memtrace() --context._disable_memtrace()
end end
--- Dispatches a LuCI virtual path.
-- @param request Virtual path
function dispatch(request) function dispatch(request)
--context._disable_memtrace = require "luci.debug".trap_memtrace("l") --context._disable_memtrace = require "luci.debug".trap_memtrace("l")
local ctx = context local ctx = context
@ -453,7 +433,6 @@ function dispatch(request)
end end
end end
--- Generate the dispatching index using the native file-cache based strategy.
function createindex() function createindex()
local controllers = { } local controllers = { }
local base = "%s/controller/" % util.libpath() local base = "%s/controller/" % util.libpath()
@ -517,7 +496,6 @@ function createindex()
end end
end end
--- Create the dispatching tree from the index.
-- Build the index before if it does not exist yet. -- Build the index before if it does not exist yet.
function createtree() function createtree()
if not index then if not index then
@ -556,9 +534,6 @@ function createtree()
return tree return tree
end end
--- Register a tree modifier.
-- @param func Modifier function
-- @param order Modifier order value (optional)
function modifier(func, order) function modifier(func, order)
context.modifiers[#context.modifiers+1] = { context.modifiers[#context.modifiers+1] = {
func = func, func = func,
@ -568,12 +543,6 @@ function modifier(func, order)
} }
end 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) function assign(path, clone, title, order)
local obj = node(unpack(path)) local obj = node(unpack(path))
obj.nodes = nil obj.nodes = nil
@ -587,12 +556,6 @@ function assign(path, clone, title, order)
return obj return obj
end 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) function entry(path, target, title, order)
local c = node(unpack(path)) local c = node(unpack(path))
@ -604,17 +567,11 @@ function entry(path, target, title, order)
return c return c
end end
--- Fetch or create a dispatching node without setting the target module or
-- enabling the node. -- enabling the node.
-- @param ... Virtual path
-- @return Dispatching tree node
function get(...) function get(...)
return _create_node({...}) return _create_node({...})
end end
--- Fetch or create a new dispatching node.
-- @param ... Virtual path
-- @return Dispatching tree node
function node(...) function node(...)
local c = _create_node({...}) local c = _create_node({...})
@ -674,13 +631,10 @@ function _firstchild()
dispatch(path) dispatch(path)
end end
--- Alias the first (lowest order) page automatically
function firstchild() function firstchild()
return { type = "firstchild", target = _firstchild } return { type = "firstchild", target = _firstchild }
end end
--- Create a redirect to another dispatching node.
-- @param ... Virtual path destination
function alias(...) function alias(...)
local req = {...} local req = {...}
return function(...) return function(...)
@ -692,9 +646,6 @@ function alias(...)
end end
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, ...) function rewrite(n, ...)
local req = {...} local req = {...}
return function(...) return function(...)
@ -733,9 +684,6 @@ local function _call(self, ...)
end end
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, ...) function call(name, ...)
return {type = "call", argv = {...}, name = name, target = _call} return {type = "call", argv = {...}, name = name, target = _call}
end end
@ -745,8 +693,6 @@ local _template = function(self, ...)
require "luci.template".render(self.view) require "luci.template".render(self.view)
end end
--- Create a template render dispatching target.
-- @param name Template to be rendered
function template(name) function template(name)
return {type = "template", view = name, target = _template} return {type = "template", view = name, target = _template}
end end
@ -852,8 +798,6 @@ local function _cbi(self, ...)
end end
end end
--- Create a CBI model dispatching target.
-- @param model CBI model to be rendered
function cbi(model, config) function cbi(model, config)
return {type = "cbi", config = config, model = model, target = _cbi} return {type = "cbi", config = config, model = model, target = _cbi}
end end
@ -866,9 +810,6 @@ local function _arcombine(self, ...)
target:target(unpack(argv)) target:target(unpack(argv))
end end
--- Create a combined dispatching target for non argv and argv requests.
-- @param trg1 Overview Target
-- @param trg2 Detail Target
function arcombine(trg1, trg2) function arcombine(trg1, trg2)
return {type = "arcombine", env = getfenv(), target = _arcombine, targets = {trg1, trg2}} return {type = "arcombine", env = getfenv(), target = _arcombine, targets = {trg1, trg2}}
end end
@ -897,19 +838,12 @@ local function _form(self, ...)
tpl.render("footer") tpl.render("footer")
end end
--- Create a CBI form model dispatching target.
-- @param model CBI form model tpo be rendered
function form(model) function form(model)
return {type = "cbi", model = model, target = _form} return {type = "cbi", model = model, target = _form}
end end
--- Access the luci.i18n translate() api.
-- @class function
-- @name translate
-- @param text Text to translate
translate = i18n.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 -- This function does not actually translate the given argument but
-- is used by build/i18n-scan.pl to find translatable entries. -- is used by build/i18n-scan.pl to find translatable entries.
function _(text) function _(text)

View file

@ -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 _
]]

View file

@ -11,7 +11,6 @@ local table = require "table"
local ipairs, pairs, next, type, tostring, error = local ipairs, pairs, next, type, tostring, error =
ipairs, pairs, next, type, tostring, error ipairs, pairs, next, type, tostring, error
--- LuCI Web Framework high-level HTTP functions.
module "luci.http" module "luci.http"
context = util.threadlocal() context = util.threadlocal()
@ -101,7 +100,6 @@ function Request._parse_input(self)
self.parsed_input = true self.parsed_input = true
end end
--- Close the HTTP-Connection.
function close() function close()
if not context.eoh then if not context.eoh then
context.eoh = true context.eoh = true
@ -114,52 +112,31 @@ function close()
end end
end end
--- Return the request content if the request was of unknown type.
-- @return HTTP request body
-- @return HTTP request body length
function content() function content()
return context.request:content() return context.request:content()
end 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) function formvalue(name, noparse)
return context.request:formvalue(name, noparse) return context.request:formvalue(name, noparse)
end 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) function formvaluetable(prefix)
return context.request:formvaluetable(prefix) return context.request:formvaluetable(prefix)
end end
--- Get the value of a certain HTTP-Cookie.
-- @param name Cookie Name
-- @return String containing cookie data
function getcookie(name) function getcookie(name)
return context.request:getcookie(name) return context.request:getcookie(name)
end end
--- Get the value of a certain HTTP environment variable
-- or the environment table itself. -- or the environment table itself.
-- @param name Environment variable
-- @return HTTP environment value or environment table
function getenv(name) function getenv(name)
return context.request:getenv(name) return context.request:getenv(name)
end end
--- Set a handler function for incoming user file uploads.
-- @param callback Handler function
function setfilehandler(callback) function setfilehandler(callback)
return context.request:setfilehandler(callback) return context.request:setfilehandler(callback)
end end
--- Send a HTTP-Header.
-- @param key Header key
-- @param value Header value
function header(key, value) function header(key, value)
if not context.headers then if not context.headers then
context.headers = {} context.headers = {}
@ -168,8 +145,6 @@ function header(key, value)
coroutine.yield(2, key, value) coroutine.yield(2, key, value)
end end
--- Set the mime type of following content data.
-- @param mime Mimetype of following content
function prepare_content(mime) function prepare_content(mime)
if not context.headers or not context.headers["content-type"] then if not context.headers or not context.headers["content-type"] then
if mime == "application/xhtml+xml" then if mime == "application/xhtml+xml" then
@ -183,15 +158,10 @@ function prepare_content(mime)
end end
end end
--- Get the RAW HTTP input source
-- @return HTTP LTN12 source
function source() function source()
return context.request.input return context.request.input
end end
--- Set the HTTP status code and status message.
-- @param code Status code
-- @param message Status message
function status(code, message) function status(code, message)
code = code or 200 code = code or 200
message = message or "OK" message = message or "OK"
@ -199,12 +169,8 @@ function status(code, message)
coroutine.yield(1, code, message) coroutine.yield(1, code, message)
end end
--- Send a chunk of content data to the client.
-- This function is as a valid LTN12 sink. -- This function is as a valid LTN12 sink.
-- If the content chunk is nil this function will automatically invoke close. -- 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) function write(content, src_err)
if not content then if not content then
if src_err then if src_err then
@ -237,24 +203,16 @@ function write(content, src_err)
end end
end end
--- Splice data from a filedescriptor to the client.
-- @param fp File descriptor
-- @param size Bytes to splice (optional)
function splice(fd, size) function splice(fd, size)
coroutine.yield(6, fd, size) coroutine.yield(6, fd, size)
end end
--- Redirects the client to a new URL and closes the connection.
-- @param url Target URL
function redirect(url) function redirect(url)
status(302, "Found") status(302, "Found")
header("Location", url) header("Location", url)
close() close()
end 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) function build_querystring(q)
local s = { "?" } local s = { "?" }
@ -269,21 +227,10 @@ function build_querystring(q)
return table.concat(s, "") return table.concat(s, "")
end 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 urldecode = protocol.urldecode
--- Return the URL-encoded equivalent of a string.
-- @param str Source string
-- @return URL-encoded string
-- @see urldecode
urlencode = protocol.urlencode urlencode = protocol.urlencode
--- Send the given data as JSON encoded string.
-- @param data Data to send
function write_json(x) function write_json(x)
util.serialize_json(x, write) util.serialize_json(x, write)
end end

View file

@ -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
]]

View file

@ -1,7 +1,6 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org> -- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0. -- 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 -- This class contains several functions useful for http message- and content
-- decoding and to retrive form data from raw http messages. -- decoding and to retrive form data from raw http messages.
module("luci.http.protocol", package.seeall) 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 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. -- 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 ) function urldecode( str, no_plus )
local function __chrdec( hex ) local function __chrdec( hex )
@ -33,15 +27,10 @@ function urldecode( str, no_plus )
return str return str
end end
--- Extract and split urlencoded data pairs, separated bei either "&" or ";"
-- from given url or string. Returns a table with urldecoded values. -- from given url or string. Returns a table with urldecoded values.
-- Simple parameters are stored as string values associated with the parameter -- Simple parameters are stored as string values associated with the parameter
-- name within the table. Parameters with multiple values are stored as array -- name within the table. Parameters with multiple values are stored as array
-- containing the corresponding values. -- 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 ) function urldecode_params( url, tbl )
local params = tbl or { } local params = tbl or { }
@ -73,10 +62,6 @@ function urldecode_params( url, tbl )
return params return params
end 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 ) function urlencode( str )
local function __chrenc( chr ) local function __chrenc( chr )
@ -95,12 +80,8 @@ function urlencode( str )
return str return str
end 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 -- separated by "&". Tables are encoded as parameters with multiple values by
-- repeating the parameter name with each value. -- 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 ) function urlencode_params( tbl )
local enc = "" local enc = ""
@ -122,9 +103,6 @@ end
-- (Internal function) -- (Internal function)
-- Initialize given parameter and coerce string into table when the parameter -- Initialize given parameter and coerce string into table when the parameter
-- already exists. -- already exists.
-- @param tbl Table where parameter should be created
-- @param key Parameter name
-- @return Always nil
local function __initval( tbl, key ) local function __initval( tbl, key )
if tbl[key] == nil then if tbl[key] == nil then
tbl[key] = "" tbl[key] = ""
@ -138,11 +116,6 @@ end
-- (Internal function) -- (Internal function)
-- Append given data to given parameter, either by extending the string value -- 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. -- 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 ) local function __appendval( tbl, key, chunk )
if type(tbl[key]) == "table" then if type(tbl[key]) == "table" then
tbl[key][#tbl[key]] = tbl[key][#tbl[key]] .. chunk 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 -- 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 -- or - in the case of multi value parameters - the last element in the
-- associated values table. -- 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 ) local function __finishval( tbl, key, handler )
if handler then if handler then
if type(tbl[key]) == "table" then if type(tbl[key]) == "table" then
@ -259,10 +226,7 @@ process_states['headers'] = function( msg, chunk )
end 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. -- data line by line with the trailing \r\n stripped of.
-- @param sock Readable network socket
-- @return Ltn12 source function
function header_source( sock ) function header_source( sock )
return ltn12.source.simplify( function() return ltn12.source.simplify( function()
@ -289,7 +253,6 @@ function header_source( sock )
end ) end )
end end
--- Decode a mime encoded http message body with multipart/form-data
-- Content-Type. Stores all extracted data associated with its parameter name -- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table withing the given message object. Multiple parameter -- in the params table withing the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings. -- 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 Table containing decoded (name, file) and raw (headers) mime header data
-- o String value containing a chunk of the file data -- o String value containing a chunk of the file data
-- o Boolean which indicates wheather the current chunk is the last one (eof) -- 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 ) function mimedecode_message_body( src, msg, filecb )
if msg and msg.env.CONTENT_TYPE then 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 ) return ltn12.pump.all( src, snk )
end end
--- Decode an urlencoded http message body with application/x-www-urlencoded
-- Content-Type. Stores all extracted data associated with its parameter name -- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table withing the given message object. Multiple parameter -- in the params table withing the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings. -- 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 ) function urldecode_message_body( src, msg )
local tlen = 0 local tlen = 0
@ -507,12 +458,8 @@ function urldecode_message_body( src, msg )
return ltn12.pump.all( src, snk ) return ltn12.pump.all( src, snk )
end end
--- Try to extract an http message header including information like protocol
-- version, message headers and resulting CGI environment variables from the -- version, message headers and resulting CGI environment variables from the
-- given ltn12 source. -- given ltn12 source.
-- @param src Ltn12 source function
-- @return HTTP message object
-- @see parse_message_body
function parse_message_header( src ) function parse_message_header( src )
local ok = true local ok = true
@ -582,19 +529,12 @@ function parse_message_header( src )
return msg return msg
end 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 -- This function will examine the Content-Type within the given message object
-- to select the appropriate content decoder. -- to select the appropriate content decoder.
-- Currently the application/x-www-urlencoded and application/form-data -- Currently the application/x-www-urlencoded and application/form-data
-- mime types are supported. If the encountered content encoding can't be -- mime types are supported. If the encountered content encoding can't be
-- handled then the whole message body will be stored unaltered as "content" -- handled then the whole message body will be stored unaltered as "content"
-- property within the given message object. -- 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 ) function parse_message_body( src, msg, filecb )
-- Is it multipart/mime ? -- Is it multipart/mime ?
if msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE and 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
end end
--- Table containing human readable messages for several http status codes.
-- @class table
statusmsg = { statusmsg = {
[200] = "OK", [200] = "OK",
[206] = "Partial Content", [206] = "Partial Content",

View file

@ -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
]]

View file

@ -1,7 +1,6 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org> -- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0. -- 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 -- This class provides basic ETag handling and implements most of the
-- conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 . -- conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 .
module("luci.http.protocol.conditionals", package.seeall) 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") 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 ) function mk_etag( stat )
if stat ~= nil then if stat ~= nil then
return string.format( '"%x-%x-%x"', stat.ino, stat.size, stat.mtime ) return string.format( '"%x-%x-%x"', stat.ino, stat.size, stat.mtime )
end end
end end
--- 14.24 / If-Match
-- Test whether the given message object contains an "If-Match" header and -- Test whether the given message object contains an "If-Match" header and
-- compare it against the given stat object. -- 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 ) function if_match( req, stat )
local h = req.headers local h = req.headers
local etag = mk_etag( stat ) local etag = mk_etag( stat )
@ -43,14 +34,8 @@ function if_match( req, stat )
return true return true
end end
--- 14.25 / If-Modified-Since
-- Test whether the given message object contains an "If-Modified-Since" header -- Test whether the given message object contains an "If-Modified-Since" header
-- and compare it against the given stat object. -- 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 ) function if_modified_since( req, stat )
local h = req.headers local h = req.headers
@ -72,14 +57,8 @@ function if_modified_since( req, stat )
return true return true
end end
--- 14.26 / If-None-Match
-- Test whether the given message object contains an "If-None-Match" header and -- Test whether the given message object contains an "If-None-Match" header and
-- compare it against the given stat object. -- 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 ) function if_none_match( req, stat )
local h = req.headers local h = req.headers
local etag = mk_etag( stat ) local etag = mk_etag( stat )
@ -105,26 +84,16 @@ function if_none_match( req, stat )
return true return true
end end
--- 14.27 / If-Range
-- The If-Range header is currently not implemented due to the lack of general -- 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 -- byte range stuff in luci.http.protocol . This function will always return
-- false, 412 to indicate a failed precondition. -- 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 ) function if_range( req, stat )
-- Sorry, no subranges (yet) -- Sorry, no subranges (yet)
return false, 412 return false, 412
end end
--- 14.28 / If-Unmodified-Since
-- Test whether the given message object contains an "If-Unmodified-Since" -- Test whether the given message object contains an "If-Unmodified-Since"
-- header and compare it against the given stat object. -- 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 ) function if_unmodified_since( req, stat )
local h = req.headers local h = req.headers

View file

@ -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
]]

View file

@ -1,7 +1,6 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org> -- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0. -- 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. -- This class contains functions to parse, compare and format http dates.
module("luci.http.protocol.date", package.seeall) module("luci.http.protocol.date", package.seeall)
@ -13,9 +12,6 @@ MONTHS = {
"Sep", "Oct", "Nov", "Dec" "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) function tz_offset(tz)
if type(tz) == "string" then if type(tz) == "string" then
@ -39,9 +35,6 @@ function tz_offset(tz)
return 0 return 0
end 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) function to_unix(date)
local wd, day, mon, yr, hr, min, sec, tz = date:match( local wd, day, mon, yr, hr, min, sec, tz = date:match(
@ -75,19 +68,10 @@ function to_unix(date)
return 0 return 0
end 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) function to_http(time)
return os.date( "%a, %d %b %Y %H:%M:%S GMT", time ) return os.date( "%a, %d %b %Y %H:%M:%S GMT", time )
end 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) function compare(d1, d2)
if d1:match("[^0-9]") then d1 = to_unix(d1) end if d1:match("[^0-9]") then d1 = to_unix(d1) end

View file

@ -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
]]

View file

@ -1,15 +1,12 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org> -- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0. -- 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 -- This class provides functions to guess mime types from file extensions and
-- vice versa. -- vice versa.
module("luci.http.protocol.mime", package.seeall) module("luci.http.protocol.mime", package.seeall)
require("luci.util") require("luci.util")
--- MIME mapping table containg extension - mimetype relations.
-- @class table
MIME_TYPES = { MIME_TYPES = {
["txt"] = "text/plain"; ["txt"] = "text/plain";
["js"] = "text/javascript"; ["js"] = "text/javascript";
@ -54,10 +51,7 @@ MIME_TYPES = {
["avi"] = "video/x-msvideo"; ["avi"] = "video/x-msvideo";
} }
--- Extract extension from a filename and return corresponding mime-type or
-- "application/octet-stream" if the extension is unknown. -- "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) function to_mime(filename)
if type(filename) == "string" then if type(filename) == "string" then
local ext = filename:match("[^%.]+$") local ext = filename:match("[^%.]+$")
@ -70,10 +64,7 @@ function to_mime(filename)
return "application/octet-stream" return "application/octet-stream"
end end
--- Return corresponding extension for a given mime type or nil if the
-- given mime-type is unknown. -- 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) function to_ext(mimetype)
if type(mimetype) == "string" then if type(mimetype) == "string" then
for ext, type in luci.util.kspairs( MIME_TYPES ) do for ext, type in luci.util.kspairs( MIME_TYPES ) do

View file

@ -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
]]

View file

@ -1,7 +1,6 @@
-- Copyright 2008 Steven Barth <steven@midlink.org> -- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0. -- Licensed to the public under the Apache License 2.0.
--- LuCI translation library.
module("luci.i18n", package.seeall) module("luci.i18n", package.seeall)
require("luci.util") require("luci.util")
@ -13,27 +12,16 @@ loaded = {}
context = luci.util.threadlocal() context = luci.util.threadlocal()
default = "en" default = "en"
--- Clear the translation table.
function clear() function clear()
end 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) function load(file, lang, force)
end end
--- Load a translation file using the default translation language.
-- Alternatively load the translation of the fallback 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) function loadc(file, force)
end end
--- Set the context default translation language.
-- @param lang Two-letter language code
function setlanguage(lang) function setlanguage(lang)
context.lang = lang:gsub("_", "-") context.lang = lang:gsub("_", "-")
context.parent = (context.lang:match("^([a-z][a-z])_")) context.parent = (context.lang:match("^([a-z][a-z])_"))
@ -46,36 +34,22 @@ function setlanguage(lang)
return context.lang return context.lang
end end
--- Return the translated value for a specific translation key.
-- @param key Default translation text
-- @return Translated string
function translate(key) function translate(key)
return tparser.translate(key) or key return tparser.translate(key) or key
end 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, ...) function translatef(key, ...)
return tostring(translate(key)):format(...) return tostring(translate(key)):format(...)
end end
--- Return the translated value for a specific translation key
-- and ensure that the returned value is a Lua string value. -- and ensure that the returned value is a Lua string value.
-- This is the same as calling <code>tostring(translate(...))</code> -- This is the same as calling <code>tostring(translate(...))</code>
-- @param key Default translation text
-- @return Translated string
function string(key) function string(key)
return tostring(translate(key)) return tostring(translate(key))
end 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. -- Ensure that the returned value is a Lua string value.
-- This is the same as calling <code>tostring(translatef(...))</code> -- 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, ...) function stringf(key, ...)
return tostring(translate(key)):format(...) return tostring(translate(key)):format(...)
end end

View file

@ -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
]]

View file

@ -39,7 +39,6 @@ local string = require("string")
local table = require("table") local table = require("table")
local base = _G local base = _G
--- Diego Nehab's LTN12 - Filters, sources, sinks and pumps.
-- See http://lua-users.org/wiki/FiltersSourcesAndSinks for design concepts -- See http://lua-users.org/wiki/FiltersSourcesAndSinks for design concepts
module("luci.ltn12") module("luci.ltn12")
@ -56,16 +55,8 @@ _VERSION = "LTN12 1.0.1"
-- Filter stuff -- 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. -- 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) function filter.cycle(low, ctx, extra)
base.assert(low) base.assert(low)
return function(chunk) return function(chunk)
@ -75,10 +66,7 @@ function filter.cycle(low, ctx, extra)
end end
end end
--- Chain a bunch of filters together.
-- (thanks to Wim Couwenberg) -- (thanks to Wim Couwenberg)
-- @param ... filters to be chained
-- @return LTN12 filter
function filter.chain(...) function filter.chain(...)
local n = table.getn(arg) local n = table.getn(arg)
local top, index = 1, 1 local top, index = 1, 1
@ -112,34 +100,22 @@ end
-- Source stuff -- Source stuff
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
--- LTN12 Source constructors
-- @class module
-- @name luci.ltn12.source
-- create an empty source -- create an empty source
local function empty() local function empty()
return nil return nil
end end
--- Create an empty source.
-- @return LTN12 source
function source.empty() function source.empty()
return empty return empty
end end
--- Return a source that just outputs an error.
-- @param err Error object
-- @return LTN12 source
function source.error(err) function source.error(err)
return function() return function()
return nil, err return nil, err
end end
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) function source.file(handle, io_err)
if handle then if handle then
return function() return function()
@ -151,9 +127,6 @@ function source.file(handle, io_err)
else return source.error(io_err or "unable to open file") end else return source.error(io_err or "unable to open file") end
end end
--- Turn a fancy source into a simple source.
-- @param src fancy source
-- @return LTN12 source
function source.simplify(src) function source.simplify(src)
base.assert(src) base.assert(src)
return function() return function()
@ -164,9 +137,6 @@ function source.simplify(src)
end end
end end
--- Create a string source.
-- @param s Data
-- @return LTN12 source
function source.string(s) function source.string(s)
if s then if s then
local i = 1 local i = 1
@ -179,9 +149,6 @@ function source.string(s)
else return source.empty() end else return source.empty() end
end end
--- Creates rewindable source.
-- @param src LTN12 source to be made rewindable
-- @return LTN12 source
function source.rewind(src) function source.rewind(src)
base.assert(src) base.assert(src)
local t = {} local t = {}
@ -196,10 +163,6 @@ function source.rewind(src)
end end
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) function source.chain(src, f)
base.assert(src and f) base.assert(src and f)
local last_in, last_out = "", "" local last_in, last_out = "", ""
@ -247,11 +210,8 @@ function source.chain(src, f)
end end
end end
--- Create a source that produces contents of several sources.
-- Sources will be used one after the other, as if they were concatenated -- Sources will be used one after the other, as if they were concatenated
-- (thanks to Wim Couwenberg) -- (thanks to Wim Couwenberg)
-- @param ... LTN12 sources
-- @return LTN12 source
function source.cat(...) function source.cat(...)
local src = table.remove(arg, 1) local src = table.remove(arg, 1)
return function() return function()
@ -268,13 +228,7 @@ end
-- Sink stuff -- 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) function sink.table(t)
t = t or {} t = t or {}
local f = function(chunk, err) local f = function(chunk, err)
@ -284,9 +238,6 @@ function sink.table(t)
return f, t return f, t
end end
--- Turn a fancy sink into a simple sink.
-- @param snk fancy sink
-- @return LTN12 sink
function sink.simplify(snk) function sink.simplify(snk)
base.assert(snk) base.assert(snk)
return function(chunk, err) return function(chunk, err)
@ -297,10 +248,6 @@ function sink.simplify(snk)
end end
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) function sink.file(handle, io_err)
if handle then if handle then
return function(chunk, err) return function(chunk, err)
@ -317,25 +264,16 @@ local function null()
return 1 return 1
end end
--- Create a sink that discards data.
-- @return LTN12 sink
function sink.null() function sink.null()
return null return null
end end
--- Create a sink that just returns an error.
-- @param err Error object
-- @return LTN12 sink
function sink.error(err) function sink.error(err)
return function() return function()
return nil, err return nil, err
end end
end end
--- Chain a sink with a filter.
-- @param f LTN12 filter
-- @param snk LTN12 sink
-- @return LTN12 sink
function sink.chain(f, snk) function sink.chain(f, snk)
base.assert(f and snk) base.assert(f and snk)
return function(chunk, err) return function(chunk, err)
@ -356,15 +294,7 @@ end
-- Pump stuff -- 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) function pump.step(src, snk)
local chunk, src_err = src() local chunk, src_err = src()
local ret, snk_err = snk(chunk, src_err) 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 else return nil, src_err or snk_err end
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) function pump.all(src, snk, step)
base.assert(src and snk) base.assert(src and snk)
step = step or pump.step step = step or pump.step

View file

@ -15,7 +15,6 @@ local table = table
local ipkg = "opkg --force-removal-of-dependent-packages --force-overwrite --nocase" local ipkg = "opkg --force-removal-of-dependent-packages --force-overwrite --nocase"
local icfg = "/etc/opkg.conf" local icfg = "/etc/opkg.conf"
--- LuCI OPKG call abstraction library
module "luci.model.ipkg" module "luci.model.ipkg"
@ -93,54 +92,31 @@ local function _lookup(act, pkg)
end 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) function info(pkg)
return _lookup("info", pkg) return _lookup("info", pkg)
end 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) function status(pkg)
return _lookup("status", pkg) return _lookup("status", pkg)
end 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(...) function install(...)
return _action("install", ...) return _action("install", ...)
end end
--- Determine whether a given package is installed.
-- @param pkg Package
-- @return Boolean
function installed(pkg) function installed(pkg)
local p = status(pkg)[pkg] local p = status(pkg)[pkg]
return (p and p.Status and p.Status.installed) return (p and p.Status and p.Status.installed)
end 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(...) function remove(...)
return _action("remove", ...) return _action("remove", ...)
end end
--- Update package lists.
-- @return Boolean indicating the status of the action
-- @return OPKG return code, STDOUT and STDERR
function update() function update()
return _action("update") return _action("update")
end end
--- Upgrades all installed packages.
-- @return Boolean indicating the status of the action
-- @return OPKG return code, STDOUT and STDERR
function upgrade() function upgrade()
return _action("upgrade") return _action("upgrade")
end end
@ -174,33 +150,19 @@ function _list(action, pat, cb)
end end
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) function list_all(pat, cb)
_list("list", pat, cb) _list("list", pat, cb)
end 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) function list_installed(pat, cb)
_list("list_installed", pat, cb) _list("list_installed", pat, cb)
end 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) function find(pat, cb)
_list("find", pat, cb) _list("find", pat, cb)
end end
--- Determines the overlay root used by opkg.
-- @return String containing the directory path of the overlay root.
function overlay_root() function overlay_root()
local od = "/" local od = "/"
local fd = io.open(icfg, "r") local fd = io.open(icfg, "r")

View file

@ -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.
]]

View file

@ -12,26 +12,18 @@ local require, getmetatable = require, getmetatable
local error, pairs, ipairs = error, pairs, ipairs local error, pairs, ipairs = error, pairs, ipairs
local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack 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 -- The typical workflow for UCI is: Get a cursor instance from the
-- cursor factory, modify data (via Cursor.add, Cursor.delete, etc.), -- cursor factory, modify data (via Cursor.add, Cursor.delete, etc.),
-- save the changes to the staging area via Cursor.save and finally -- save the changes to the staging area via Cursor.save and finally
-- Cursor.commit the data to the actual config files. -- Cursor.commit the data to the actual config files.
-- LuCI then needs to Cursor.apply the changes so deamons etc. are -- LuCI then needs to Cursor.apply the changes so deamons etc. are
-- reloaded. -- reloaded.
-- @cstyle instance
module "luci.model.uci" module "luci.model.uci"
--- Create a new UCI-Cursor.
-- @class function
-- @name cursor
-- @return UCI-Cursor
cursor = uci.cursor cursor = uci.cursor
APIVERSION = uci.APIVERSION APIVERSION = uci.APIVERSION
--- Create a new Cursor initialized to the state directory.
-- @return UCI cursor
function cursor_state() function cursor_state()
return cursor(nil, "/var/state") return cursor(nil, "/var/state")
end end
@ -42,9 +34,6 @@ inst_state = cursor_state()
local Cursor = getmetatable(inst) 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) function Cursor.apply(self, configlist, command)
configlist = self:_affected(configlist) configlist = self:_affected(configlist)
if command then if command then
@ -56,10 +45,6 @@ function Cursor.apply(self, configlist, command)
end 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) -- returns a boolean whether to delete the current section (optional)
function Cursor.delete_all(self, config, stype, comparator) function Cursor.delete_all(self, config, stype, comparator)
local del = {} local del = {}
@ -90,12 +75,6 @@ function Cursor.delete_all(self, config, stype, comparator)
end end
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) function Cursor.section(self, config, type, name, values)
local stat = true local stat = true
if name then if name then
@ -112,10 +91,6 @@ function Cursor.section(self, config, type, name, values)
return stat and name return stat and name
end 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) function Cursor.tset(self, config, section, values)
local stat = true local stat = true
for k, v in pairs(values) do for k, v in pairs(values) do
@ -126,21 +101,11 @@ function Cursor.tset(self, config, section, values)
return stat return stat
end 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, ...) function Cursor.get_bool(self, ...)
local val = self:get(...) local val = self:get(...)
return ( val == "1" or val == "true" or val == "yes" or val == "on" ) return ( val == "1" or val == "true" or val == "yes" or val == "on" )
end 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) function Cursor.get_list(self, config, section, option)
if config and section and option then if config and section and option then
local val = self:get(config, section, option) local val = self:get(config, section, option)
@ -149,12 +114,6 @@ function Cursor.get_list(self, config, section, option)
return nil return nil
end 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) function Cursor.get_first(self, conf, stype, opt, def)
local rv = def local rv = def
@ -178,12 +137,6 @@ function Cursor.get_first(self, conf, stype, opt, def)
return rv return rv
end 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) function Cursor.set_list(self, config, section, option, value)
if config and section and option then if config and section and option then
return self:set( return self:set(
@ -238,10 +191,8 @@ function Cursor._affected(self, configlist)
return reloadlist return reloadlist
end 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 -- curser, means it the parent unloads or loads configs, the sub state will
-- do so as well. -- do so as well.
-- @return UCI state cursor tied to the parent cursor
function Cursor.substate(self) function Cursor.substate(self)
Cursor._substates = Cursor._substates or { } Cursor._substates = Cursor._substates or { }
Cursor._substates[self] = Cursor._substates[self] or cursor_state() Cursor._substates[self] = Cursor._substates[self] or cursor_state()
@ -265,118 +216,18 @@ function Cursor.unload(self, ...)
end 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

View file

@ -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
]]

View file

@ -16,27 +16,14 @@ local tonumber, ipairs, pairs, pcall, type, next, setmetatable, require, select
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" 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(...) function call(...)
return os.execute(...) / 256 return os.execute(...) / 256
end 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 exec = luci.util.exec
--- Retrieve information about currently mounted file systems.
-- @return Table containing mount information
function mounts() function mounts()
local data = {} local data = {}
local k = {"fs", "blocks", "used", "available", "percent", "mountpoint"} local k = {"fs", "blocks", "used", "available", "percent", "mountpoint"}
@ -82,20 +69,11 @@ function mounts()
return data return data
end end
--- Retrieve environment variables. If no variable is given then a table
-- containing the whole environment is returned otherwise this function returns -- containing the whole environment is returned otherwise this function returns
-- the corresponding string value for the given name or nil if no such variable -- the corresponding string value for the given name or nil if no such variable
-- exists. -- 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 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) function hostname(newname)
if type(newname) == "string" and #newname > 0 then if type(newname) == "string" and #newname > 0 then
fs.writefile( "/proc/sys/kernel/hostname", newname ) fs.writefile( "/proc/sys/kernel/hostname", newname )
@ -105,11 +83,6 @@ function hostname(newname)
end end
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) function httpget(url, stream, target)
if not target then if not target then
local source = stream and io.popen or luci.util.exec local source = stream and io.popen or luci.util.exec
@ -120,46 +93,30 @@ function httpget(url, stream, target)
end end
end end
--- Initiate a system reboot.
-- @return Return value of os.execute()
function reboot() function reboot()
return os.execute("reboot >/dev/null 2>&1") return os.execute("reboot >/dev/null 2>&1")
end end
--- Retrieves the output of the "logread" command.
-- @return String containing the current log buffer
function syslog() function syslog()
return luci.util.exec("logread") return luci.util.exec("logread")
end end
--- Retrieves the output of the "dmesg" command.
-- @return String containing the current log buffer
function dmesg() function dmesg()
return luci.util.exec("dmesg") return luci.util.exec("dmesg")
end 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) function uniqueid(bytes)
local rand = fs.readfile("/dev/urandom", bytes) local rand = fs.readfile("/dev/urandom", bytes)
return rand and nixio.bin.hexlify(rand) return rand and nixio.bin.hexlify(rand)
end end
--- Returns the current system uptime stats.
-- @return String containing total uptime in seconds
function uptime() function uptime()
return nixio.sysinfo().uptime return nixio.sysinfo().uptime
end end
--- LuCI system utilities / network related functions.
-- @class module
-- @name luci.sys.net
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: -- The following fields are defined for arp entry objects:
-- { "IP address", "HW address", "HW type", "Flags", "Mask", "Device" } -- { "IP address", "HW address", "HW type", "Flags", "Mask", "Device" }
function net.arptable(callback) function net.arptable(callback)
@ -269,8 +226,6 @@ local function _nethints(what, callback)
end end
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: -- Each entry contains the values in the following order:
-- [ "mac", "name" ] -- [ "mac", "name" ]
function net.mac_hints(callback) function net.mac_hints(callback)
@ -293,8 +248,6 @@ function net.mac_hints(callback)
end end
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: -- Each entry contains the values in the following order:
-- [ "ip", "name" ] -- [ "ip", "name" ]
function net.ipv4_hints(callback) function net.ipv4_hints(callback)
@ -317,8 +270,6 @@ function net.ipv4_hints(callback)
end end
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: -- Each entry contains the values in the following order:
-- [ "ip", "name" ] -- [ "ip", "name" ]
function net.ipv6_hints(callback) function net.ipv6_hints(callback)
@ -341,8 +292,6 @@ function net.ipv6_hints(callback)
end end
end end
--- Returns conntrack information
-- @return Table with the currently tracked IP connections
function net.conntrack(callback) function net.conntrack(callback)
local connt = {} local connt = {}
if fs.access("/proc/net/nf_conntrack", "r") then if fs.access("/proc/net/nf_conntrack", "r") then
@ -387,8 +336,6 @@ function net.conntrack(callback)
return connt return connt
end end
--- Determine the names of available network interfaces.
-- @return Table containing all current interface names
function net.devices() function net.devices()
local devs = {} local devs = {}
for k, v in ipairs(nixio.getifaddrs()) do for k, v in ipairs(nixio.getifaddrs()) do
@ -400,8 +347,6 @@ function net.devices()
end end
--- Return information about available network interfaces.
-- @return Table containing all current interface names and their information
function net.deviceinfo() function net.deviceinfo()
local devs = {} local devs = {}
for k, v in ipairs(nixio.getifaddrs()) do for k, v in ipairs(nixio.getifaddrs()) do
@ -430,8 +375,6 @@ function net.deviceinfo()
end 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: -- The following fields are defined for route entry tables:
-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt", -- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
-- "flags", "device" } -- "flags", "device" }
@ -477,8 +420,6 @@ function net.routes(callback)
return routes return routes
end 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: -- The following fields are defined for route entry tables:
-- { "source", "dest", "nexthop", "metric", "refcount", "usecount", -- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
-- "flags", "device" } -- "flags", "device" }
@ -540,30 +481,18 @@ function net.routes6(callback)
end end
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) function net.pingtest(host)
return os.execute("ping -c1 '"..host:gsub("'", '').."' >/dev/null 2>&1") return os.execute("ping -c1 '"..host:gsub("'", '').."' >/dev/null 2>&1")
end end
--- LuCI system utilities / process related functions.
-- @class module
-- @name luci.sys.process
process = {} process = {}
--- Get the current process id.
-- @class function
-- @name process.info
-- @return Number containing the current pid
function process.info(key) function process.info(key)
local s = {uid = nixio.getuid(), gid = nixio.getgid()} local s = {uid = nixio.getuid(), gid = nixio.getgid()}
return not key and s or s[key] return not key and s or s[key]
end end
--- Retrieve information about currently running processes.
-- @return Table containing process information
function process.list() function process.list()
local data = {} local data = {}
local k local k
@ -596,51 +525,22 @@ function process.list()
return data return data
end 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) function process.setgroup(gid)
return nixio.setgid(gid) return nixio.setgid(gid)
end 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) function process.setuser(uid)
return nixio.setuid(uid) return nixio.setuid(uid)
end 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 process.signal = nixio.kill
--- LuCI system utilities / user related functions.
-- @class module
-- @name luci.sys.user
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" } -- { "uid", "gid", "name", "passwd", "dir", "shell", "gecos" }
user.getuser = nixio.getpw 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) function user.getpasswd(username)
local pwe = nixio.getsp and nixio.getsp(username) or nixio.getpw(username) local pwe = nixio.getsp and nixio.getsp(username) or nixio.getpw(username)
local pwh = pwe and (pwe.pwdp or pwe.passwd) local pwh = pwe and (pwe.pwdp or pwe.passwd)
@ -651,10 +551,6 @@ function user.getpasswd(username)
end end
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) function user.checkpasswd(username, pass)
local pwh, pwe = user.getpasswd(username) local pwh, pwe = user.getpasswd(username)
if pwe then if pwe then
@ -663,10 +559,6 @@ function user.checkpasswd(username, pass)
return false return false
end 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) function user.setpasswd(username, password)
if password then if password then
password = password:gsub("'", [['"'"']]) password = password:gsub("'", [['"'"']])
@ -683,14 +575,8 @@ function user.setpasswd(username, password)
end end
--- LuCI system utilities / wifi related functions.
-- @class module
-- @name luci.sys.wifi
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) function wifi.getiwinfo(ifname)
local stat, iwinfo = pcall(require, "iwinfo") local stat, iwinfo = pcall(require, "iwinfo")
@ -736,14 +622,9 @@ function wifi.getiwinfo(ifname)
end end
--- LuCI system utilities / init related functions.
-- @class module
-- @name luci.sys.init
init = {} init = {}
init.dir = "/etc/init.d/" 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() function init.names()
local names = { } local names = { }
for name in fs.glob(init.dir.."*") do for name in fs.glob(init.dir.."*") do
@ -752,9 +633,6 @@ function init.names()
return names return names
end end
--- Get the index of he given init script
-- @param name Name of the init script
-- @return Numeric index value
function init.index(name) function init.index(name)
if fs.access(init.dir..name) then if fs.access(init.dir..name) then
return call("env -i sh -c 'source %s%s enabled; exit ${START:-255}' >/dev/null" return call("env -i sh -c 'source %s%s enabled; exit ${START:-255}' >/dev/null"
@ -768,37 +646,22 @@ local function init_action(action, name)
end end
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) function init.enabled(name)
return (init_action("enabled", name) == 0) return (init_action("enabled", name) == 0)
end end
--- Enable the given init script
-- @param name Name of the init script
-- @return Boolean indicating success
function init.enable(name) function init.enable(name)
return (init_action("enable", name) == 1) return (init_action("enable", name) == 1)
end end
--- Disable the given init script
-- @param name Name of the init script
-- @return Boolean indicating success
function init.disable(name) function init.disable(name)
return (init_action("disable", name) == 0) return (init_action("disable", name) == 0)
end end
--- Start the given init script
-- @param name Name of the init script
-- @return Boolean indicating success
function init.start(name) function init.start(name)
return (init_action("start", name) == 0) return (init_action("start", name) == 0)
end end
--- Stop the given init script
-- @param name Name of the init script
-- @return Boolean indicating success
function init.stop(name) function init.stop(name)
return (init_action("stop", name) == 0) return (init_action("stop", name) == 0)
end end

View file

@ -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
]]

View file

@ -21,15 +21,8 @@ luci.ip = require "luci.ip"
local tonumber, ipairs, table = tonumber, ipairs, table local tonumber, ipairs, table = tonumber, ipairs, table
--- LuCI iptables parser and query library
-- @cstyle instance
module("luci.sys.iptparser") 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() IptParser = luci.util.class()
function IptParser.__init__( self, family ) function IptParser.__init__( self, family )
@ -50,7 +43,6 @@ function IptParser.__init__( self, family )
self:_parse_rules() self:_parse_rules()
end 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 -- search criteria as only argument. If args is nil or an empty table then all
-- rules will be returned. -- rules will be returned.
-- --
@ -108,8 +100,6 @@ end
-- This will match all rules with target "-j REJECT", -- This will match all rules with target "-j REJECT",
-- protocol "-p tcp" (or "-p all") -- protocol "-p tcp" (or "-p all")
-- and the option "--reject-with tcp-reset". -- 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 ) function IptParser.find( self, args )
local args = args or { } local args = args or { }
@ -205,9 +195,7 @@ function IptParser.find( self, args )
end end
--- Rebuild the internal lookup table, for example when rules have changed
-- through external commands. -- through external commands.
-- @return nothing
function IptParser.resync( self ) function IptParser.resync( self )
self._rules = { } self._rules = { }
self._chain = nil self._chain = nil
@ -215,16 +203,11 @@ function IptParser.resync( self )
end end
--- Find the names of all tables.
-- @return Table of table names.
function IptParser.tables( self ) function IptParser.tables( self )
return self._tables return self._tables
end 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 ) function IptParser.chains( self, table )
local lookup = { } local lookup = { }
local chains = { } local chains = { }
@ -238,19 +221,12 @@ function IptParser.chains( self, table )
end 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. -- and "rules". The "rules" field is a table of rule tables.
function IptParser.chain( self, table, chain ) function IptParser.chain( self, table, chain )
return self._chains[table:lower()] and self._chains[table:lower()][chain] return self._chains[table:lower()] and self._chains[table:lower()][chain]
end 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 ) function IptParser.is_custom_target( self, target )
for _, r in ipairs(self._rules) do for _, r in ipairs(self._rules) do
if r.chain == target then if r.chain == target then

View file

@ -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.
]]

View file

@ -20,7 +20,6 @@ local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring
local require, pcall, xpcall = require, pcall, xpcall local require, pcall, xpcall = require, pcall, xpcall
local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit
--- LuCI utility functions.
module "luci.util" module "luci.util"
-- --
@ -54,7 +53,6 @@ local function _instantiate(class, ...)
return inst return inst
end end
--- Create a Class object (Python-style object model).
-- The class object can be instantiated by calling itself. -- The class object can be instantiated by calling itself.
-- Any class functions or shared parameters can be attached to this object. -- Any class functions or shared parameters can be attached to this object.
-- Attaching a table to the class object makes this table shared between -- 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. -- 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 -- 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. -- 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) function class(base)
return setmetatable({}, { return setmetatable({}, {
__call = _instantiate, __call = _instantiate,
@ -75,12 +69,6 @@ function class(base)
}) })
end 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) function instanceof(object, class)
local meta = getmetatable(object) local meta = getmetatable(object)
while meta and meta.__index do while meta and meta.__index do
@ -117,10 +105,8 @@ local tl_meta = {
end 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 -- 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. -- whose values can't be accessed from outside of the running coroutine.
-- @return Table value representing the corresponding thread local store
function threadlocal(tbl) function threadlocal(tbl)
return setmetatable(tbl or {}, tl_meta) return setmetatable(tbl or {}, tl_meta)
end end
@ -130,17 +116,10 @@ end
-- Debugging routines -- 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) function perror(obj)
return io.stderr:write(tostring(obj) .. "\n") return io.stderr:write(tostring(obj) .. "\n")
end 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) function dumptable(t, maxdepth, i, seen)
i = i or 0 i = i or 0
seen = seen or setmetatable({}, {__mode="k"}) seen = seen or setmetatable({}, {__mode="k"})
@ -163,31 +142,19 @@ end
-- String and data manipulation routines -- 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) function pcdata(value)
return value and tparser.pcdata(tostring(value)) return value and tparser.pcdata(tostring(value))
end end
--- Strip HTML tags from given string.
-- @param value String containing the HTML text
-- @return String with HTML tags stripped of
function striptags(value) function striptags(value)
return value and tparser.striptags(tostring(value)) return value and tparser.striptags(tostring(value))
end end
--- Splits given string on a defined separator sequence and return a table
-- containing the resulting substrings. The optional max parameter specifies -- containing the resulting substrings. The optional max parameter specifies
-- the number of bytes to process, regardless of the actual length of the given -- the number of bytes to process, regardless of the actual length of the given
-- string. The optional last parameter, regex, specifies whether the separator -- string. The optional last parameter, regex, specifies whether the separator
-- sequence is interpreted as regular expression. -- 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) -- pattern as regular expression (optional, default is false)
-- @return Table containing the resulting substrings
function split(str, pat, max, regex) function split(str, pat, max, regex)
pat = pat or "\n" pat = pat or "\n"
max = max or #str max = max or #str
@ -221,29 +188,19 @@ function split(str, pat, max, regex)
return t return t
end 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) function trim(str)
return (str:gsub("^%s*(.-)%s*$", "%1")) return (str:gsub("^%s*(.-)%s*$", "%1"))
end 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) function cmatch(str, pat)
local count = 0 local count = 0
for _ in str:gmatch(pat) do count = count + 1 end for _ in str:gmatch(pat) do count = count + 1 end
return count return count
end 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 -- 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 -- 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. -- 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) function imatch(v)
if type(v) == "table" then if type(v) == "table" then
local k = nil local k = nil
@ -268,7 +225,6 @@ function imatch(v)
return function() end return function() end
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. -- value or 0 if the unit is unknown. Upper- or lower case is irrelevant.
-- Recognized units are: -- Recognized units are:
-- o "y" - one year (60*60*24*366) -- o "y" - one year (60*60*24*366)
@ -283,8 +239,6 @@ end
-- o "kib" - one si kilobyte (1000) -- o "kib" - one si kilobyte (1000)
-- o "mib" - one si megabyte (1000*1000) -- o "mib" - one si megabyte (1000*1000)
-- o "gib" - one si gigabyte (1000*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) function parse_units(ustr)
local val = 0 local val = 0
@ -336,10 +290,6 @@ string.cmatch = cmatch
string.parse_units = parse_units 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, ...) function append(src, ...)
for i, a in ipairs({...}) do for i, a in ipairs({...}) do
if type(a) == "table" then if type(a) == "table" then
@ -353,19 +303,10 @@ function append(src, ...)
return src return src
end 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(...) function combine(...)
return append({}, ...) return append({}, ...)
end 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) function contains(table, value)
for k, v in pairs(table) do for k, v in pairs(table) do
if value == v then if value == v then
@ -375,20 +316,13 @@ function contains(table, value)
return false return false
end end
--- Update values in given table with the values from the second given table.
-- Both table are - in fact - merged together. -- 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) function update(t, updates)
for k, v in pairs(updates) do for k, v in pairs(updates) do
t[k] = v t[k] = v
end end
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) function keys(t)
local keys = { } local keys = { }
if t then if t then
@ -399,10 +333,6 @@ function keys(t)
return keys return keys
end 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) function clone(object, deep)
local copy = {} local copy = {}
@ -417,8 +347,6 @@ function clone(object, deep)
end end
--- Create a dynamic table which automatically creates subtables.
-- @return Dynamic Table
function dtable() function dtable()
return setmetatable({}, { __index = return setmetatable({}, { __index =
function(tbl, key) function(tbl, key)
@ -457,12 +385,7 @@ function _serialize_table(t, seen)
return idata .. ( #data > 0 and #idata > 0 and ", " or "" ) .. data return idata .. ( #data > 0 and #idata > 0 and ", " or "" ) .. data
end end
--- Recursively serialize given data to lua code, suitable for restoring
-- with loadstring(). -- 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) function serialize_data(val, seen)
seen = seen or setmetatable({}, {__mode="k"}) seen = seen or setmetatable({}, {__mode="k"})
@ -483,11 +406,6 @@ function serialize_data(val, seen)
end end
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) function restore_data(str)
return loadstring("return " .. str)() return loadstring("return " .. str)()
end end
@ -497,10 +415,7 @@ end
-- Byte code manipulation routines -- Byte code manipulation routines
-- --
--- Return the current runtime bytecode of the given data. The byte code
-- will be stripped before it is returned. -- 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) function get_bytecode(val)
local code local code
@ -513,11 +428,8 @@ function get_bytecode(val)
return code -- and strip_bytecode(code) return code -- and strip_bytecode(code)
end end
--- Strips unnescessary lua bytecode from given string. Information like line
-- numbers and debugging numbers will be discarded. Original version by -- numbers and debugging numbers will be discarded. Original version by
-- Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html) -- 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) function strip_bytecode(code)
local version, format, endian, int, size, ins, num, lnum = code:byte(5, 12) local version, format, endian, int, size, ins, num, lnum = code:byte(5, 12)
local subint local subint
@ -607,27 +519,17 @@ function _sortiter( t, f )
end end
end end
--- Return a key, value iterator which returns the values sorted according to
-- the provided callback function. -- 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) function spairs(t,f)
return _sortiter( t, f ) return _sortiter( t, f )
end end
--- Return a key, value iterator for the given table.
-- The table pairs are sorted by key. -- The table pairs are sorted by key.
-- @param t The table to iterate
-- @return Function value containing the corresponding iterator
function kspairs(t) function kspairs(t)
return _sortiter( t ) return _sortiter( t )
end end
--- Return a key, value iterator for the given table.
-- The table pairs are sorted by value. -- The table pairs are sorted by value.
-- @param t The table to iterate
-- @return Function value containing the corresponding iterator
function vspairs(t) function vspairs(t)
return _sortiter( t, function (a,b) return t[a] < t[b] end ) return _sortiter( t, function (a,b) return t[a] < t[b] end )
end end
@ -637,15 +539,10 @@ end
-- System utility functions -- 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() function bigendian()
return string.byte(string.dump(function() end), 7) == 0 return string.byte(string.dump(function() end), 7) == 0
end end
--- Execute given commandline and gather stdout.
-- @param command String containing command to execute
-- @return String containing the command's stdout
function exec(command) function exec(command)
local pp = io.popen(command) local pp = io.popen(command)
local data = pp:read("*a") local data = pp:read("*a")
@ -654,9 +551,6 @@ function exec(command)
return data return data
end 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) function execi(command)
local pp = io.popen(command) local pp = io.popen(command)
@ -687,11 +581,6 @@ function execl(command)
return data return data
end 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) function ubus(object, method, data)
if not _ubus_connection then if not _ubus_connection then
_ubus_connection = _ubus.connect() _ubus_connection = _ubus.connect()
@ -710,10 +599,6 @@ function ubus(object, method, data)
end end
end end
--- Convert data structure to 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
function serialize_json(x, cb) function serialize_json(x, cb)
local rv, push = nil, cb local rv, push = nil, cb
if not push then if not push then
@ -768,8 +653,6 @@ function serialize_json(x, cb)
end end
--- Returns the absolute path to LuCI base directory.
-- @return String containing the directory path
function libpath() function libpath()
return require "nixio.fs".dirname(ldebug.__file__) return require "nixio.fs".dirname(ldebug.__file__)
end end
@ -809,11 +692,6 @@ local function copcall_id(trace, ...)
return ... return ...
end 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 -- values of either the function or the error handler
function coxpcall(f, err, ...) function coxpcall(f, err, ...)
local res, co = oldpcall(coroutine.create, f) local res, co = oldpcall(coroutine.create, f)
@ -828,10 +706,6 @@ function coxpcall(f, err, ...)
return performResume(err, co, ...) return performResume(err, co, ...)
end 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 -- values of the function or the error object
function copcall(f, ...) function copcall(f, ...)
return coxpcall(f, copcall_id, ...) return coxpcall(f, copcall_id, ...)

View file

@ -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
]]