1 -- Copyright 2008 Steven Barth <steven@midlink.org>
2 -- Licensed to the public under the Apache License 2.0.
4 local io = require "io"
5 local math = require "math"
6 local table = require "table"
7 local debug = require "debug"
8 local ldebug = require "luci.debug"
9 local string = require "string"
10 local coroutine = require "coroutine"
11 local tparser = require "luci.template.parser"
13 local _ubus = require "ubus"
14 local _ubus_connection = nil
16 local getmetatable, setmetatable = getmetatable, setmetatable
17 local rawget, rawset, unpack = rawget, rawset, unpack
18 local tostring, type, assert = tostring, type, assert
19 local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring
20 local require, pcall, xpcall = require, pcall, xpcall
21 local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit
26 -- Pythonic string formatting extension
28 getmetatable("").__mod = function(a, b)
31 elseif type(b) == "table" then
32 for k, _ in pairs(b) do if type(b[k]) == "userdata" then b[k] = tostring(b[k]) end end
33 return a:format(unpack(b))
35 if type(b) == "userdata" then b = tostring(b) end
42 -- Class helper routines
45 -- Instantiates a class
46 local function _instantiate(class, ...)
47 local inst = setmetatable({}, {__index = class})
56 -- The class object can be instantiated by calling itself.
57 -- Any class functions or shared parameters can be attached to this object.
58 -- Attaching a table to the class object makes this table shared between
59 -- all instances of this class. For object parameters use the __init__ function.
60 -- Classes can inherit member functions and values from a base class.
61 -- Class can be instantiated by calling them. All parameters will be passed
62 -- to the __init__ function of this class - if such a function exists.
63 -- The __init__ function must be used to set any object parameters that are not shared
64 -- with other objects of this class. Any return values will be ignored.
66 return setmetatable({}, {
67 __call = _instantiate,
72 function instanceof(object, class)
73 local meta = getmetatable(object)
74 while meta and meta.__index do
75 if meta.__index == class then
78 meta = getmetatable(meta.__index)
85 -- Scope manipulation routines
91 __index = function(self, key)
92 local t = rawget(self, coxpt[coroutine.running()]
93 or coroutine.running() or 0)
97 __newindex = function(self, key, value)
98 local c = coxpt[coroutine.running()] or coroutine.running() or 0
99 local r = rawget(self, c)
101 rawset(self, c, { [key] = value })
108 -- the current active coroutine. A thread local store is private a table object
109 -- whose values can't be accessed from outside of the running coroutine.
110 function threadlocal(tbl)
111 return setmetatable(tbl or {}, tl_meta)
116 -- Debugging routines
120 return io.stderr:write(tostring(obj) .. "\n")
123 function dumptable(t, maxdepth, i, seen)
125 seen = seen or setmetatable({}, {__mode="k"})
127 for k,v in pairs(t) do
128 perror(string.rep("\t", i) .. tostring(k) .. "\t" .. tostring(v))
129 if type(v) == "table" and (not maxdepth or i < maxdepth) then
132 dumptable(v, maxdepth, i+1, seen)
134 perror(string.rep("\t", i) .. "*** RECURSION ***")
142 -- String and data manipulation routines
145 function pcdata(value)
146 return value and tparser.pcdata(tostring(value))
149 function striptags(value)
150 return value and tparser.striptags(tostring(value))
153 -- containing the resulting substrings. The optional max parameter specifies
154 -- the number of bytes to process, regardless of the actual length of the given
155 -- string. The optional last parameter, regex, specifies whether the separator
156 -- sequence is interpreted as regular expression.
157 -- pattern as regular expression (optional, default is false)
158 function split(str, pat, max, regex)
178 local s, e = str:find(pat, c, not regex)
180 if s and max < 0 then
183 t[#t+1] = str:sub(c, s and s - 1)
185 c = e and e + 1 or #str + 1
186 until not s or max < 0
192 return (str:gsub("^%s*(.-)%s*$", "%1"))
195 function cmatch(str, pat)
197 for _ in str:gmatch(pat) do count = count + 1 end
201 -- one token per invocation, the tokens are separated by whitespace. If the
202 -- input value is a table, it is transformed into a string first. A nil value
203 -- will result in a valid interator which aborts with the first invocation.
205 if type(v) == "table" then
212 elseif type(v) == "number" or type(v) == "boolean" then
221 elseif type(v) == "userdata" or type(v) == "string" then
222 return tostring(v):gmatch("%S+")
225 return function() end
228 -- value or 0 if the unit is unknown. Upper- or lower case is irrelevant.
229 -- Recognized units are:
230 -- o "y" - one year (60*60*24*366)
231 -- o "m" - one month (60*60*24*31)
232 -- o "w" - one week (60*60*24*7)
233 -- o "d" - one day (60*60*24)
234 -- o "h" - one hour (60*60)
235 -- o "min" - one minute (60)
236 -- o "kb" - one kilobyte (1024)
237 -- o "mb" - one megabyte (1024*1024)
238 -- o "gb" - one gigabyte (1024*1024*1024)
239 -- o "kib" - one si kilobyte (1000)
240 -- o "mib" - one si megabyte (1000*1000)
241 -- o "gib" - one si gigabyte (1000*1000*1000)
242 function parse_units(ustr)
249 y = 60 * 60 * 24 * 366,
250 m = 60 * 60 * 24 * 31,
251 w = 60 * 60 * 24 * 7,
259 gb = 1024 * 1024 * 1024,
261 -- storage sizes (si)
264 gib = 1000 * 1000 * 1000
267 -- parse input string
268 for spec in ustr:lower():gmatch("[0-9%.]+[a-zA-Z]*") do
270 local num = spec:gsub("[^0-9%.]+$","")
271 local spn = spec:gsub("^[0-9%.]+", "")
273 if map[spn] or map[spn:sub(1,1)] then
274 val = val + num * ( map[spn] or map[spn:sub(1,1)] )
284 -- also register functions above in the central string class for convenience
285 string.pcdata = pcdata
286 string.striptags = striptags
289 string.cmatch = cmatch
290 string.parse_units = parse_units
293 function append(src, ...)
294 for i, a in ipairs({...}) do
295 if type(a) == "table" then
296 for j, v in ipairs(a) do
306 function combine(...)
307 return append({}, ...)
310 function contains(table, value)
311 for k, v in pairs(table) do
319 -- Both table are - in fact - merged together.
320 function update(t, updates)
321 for k, v in pairs(updates) do
329 for k, _ in kspairs(t) do
336 function clone(object, deep)
339 for k, v in pairs(object) do
340 if deep and type(v) == "table" then
346 return setmetatable(copy, getmetatable(object))
351 return setmetatable({}, { __index =
353 return rawget(tbl, key)
354 or rawget(rawset(tbl, key, dtable()), key)
360 -- Serialize the contents of a table value.
361 function _serialize_table(t, seen)
362 assert(not seen[t], "Recursion detected.")
369 for k, v in pairs(t) do
370 if type(k) ~= "number" or k < 1 or math.floor(k) ~= k or ( k - #t ) > 3 then
371 k = serialize_data(k, seen)
372 v = serialize_data(v, seen)
373 data = data .. ( #data > 0 and ", " or "" ) ..
374 '[' .. k .. '] = ' .. v
381 local v = serialize_data(t[i], seen)
382 idata = idata .. ( #idata > 0 and ", " or "" ) .. v
385 return idata .. ( #data > 0 and #idata > 0 and ", " or "" ) .. data
388 -- with loadstring().
389 function serialize_data(val, seen)
390 seen = seen or setmetatable({}, {__mode="k"})
394 elseif type(val) == "number" then
396 elseif type(val) == "string" then
398 elseif type(val) == "boolean" then
399 return val and "true" or "false"
400 elseif type(val) == "function" then
401 return "loadstring(%q)" % get_bytecode(val)
402 elseif type(val) == "table" then
403 return "{ " .. _serialize_table(val, seen) .. " }"
405 return '"[unhandled data type:' .. type(val) .. ']"'
409 function restore_data(str)
410 return loadstring("return " .. str)()
415 -- Byte code manipulation routines
418 -- will be stripped before it is returned.
419 function get_bytecode(val)
422 if type(val) == "function" then
423 code = string.dump(val)
425 code = string.dump( loadstring( "return " .. serialize_data(val) ) )
428 return code -- and strip_bytecode(code)
431 -- numbers and debugging numbers will be discarded. Original version by
432 -- Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
433 function strip_bytecode(code)
434 local version, format, endian, int, size, ins, num, lnum = code:byte(5, 12)
437 subint = function(code, i, l)
440 val = val * 256 + code:byte(i + n - 1)
445 subint = function(code, i, l)
448 val = val * 256 + code:byte(i + n - 1)
454 local function strip_function(code)
455 local count, offset = subint(code, 1, size)
456 local stripped = { string.rep("\0", size) }
457 local dirty = offset + count
458 offset = offset + count + int * 2 + 4
459 offset = offset + int + subint(code, offset, int) * ins
460 count, offset = subint(code, offset, int)
463 t, offset = subint(code, offset, 1)
467 offset = offset + size + subint(code, offset, size)
469 offset = offset + num
470 elseif t == 254 or t == 9 then
471 offset = offset + lnum
474 count, offset = subint(code, offset, int)
475 stripped[#stripped+1] = code:sub(dirty, offset - 1)
477 local proto, off = strip_function(code:sub(offset, -1))
478 stripped[#stripped+1] = proto
479 offset = offset + off - 1
481 offset = offset + subint(code, offset, int) * int + int
482 count, offset = subint(code, offset, int)
484 offset = offset + subint(code, offset, size) + size + int * 2
486 count, offset = subint(code, offset, int)
488 offset = offset + subint(code, offset, size) + size
490 stripped[#stripped+1] = string.rep("\0", int * 3)
491 return table.concat(stripped), offset
494 return code:sub(1,12) .. strip_function(code:sub(13,-1))
499 -- Sorting iterator functions
502 function _sortiter( t, f )
506 for k, v in pairs(t) do
512 table.sort( keys, f )
516 if _pos <= #keys then
517 return keys[_pos], t[keys[_pos]], _pos
522 -- the provided callback function.
524 return _sortiter( t, f )
527 -- The table pairs are sorted by key.
529 return _sortiter( t )
532 -- The table pairs are sorted by value.
534 return _sortiter( t, function (a,b) return t[a] < t[b] end )
539 -- System utility functions
543 return string.byte(string.dump(function() end), 7) == 0
546 function exec(command)
547 local pp = io.popen(command)
548 local data = pp:read("*a")
554 function execi(command)
555 local pp = io.popen(command)
557 return pp and function()
558 local line = pp:read()
569 function execl(command)
570 local pp = io.popen(command)
576 if (line == nil) then break end
584 function ubus(object, method, data)
585 if not _ubus_connection then
586 _ubus_connection = _ubus.connect()
587 assert(_ubus_connection, "Unable to establish ubus connection")
590 if object and method then
591 if type(data) ~= "table" then
594 return _ubus_connection:call(object, method, data)
596 return _ubus_connection:signatures(object)
598 return _ubus_connection:objects()
602 function serialize_json(x, cb)
603 local rv, push = nil, cb
606 push = function(tok) rv[#rv+1] = tok end
611 elseif type(x) == "table" then
612 -- test if table is array like
615 for k in pairs(x) do n1 = n1 + 1 end
616 for k in ipairs(x) do n2 = n2 + 1 end
618 if n1 == n2 and n1 > 0 then
624 serialize_json(x[k], push)
629 for k, v in pairs(x) do
630 push("%q:" % tostring(k))
631 serialize_json(v, push)
638 elseif type(x) == "number" or type(x) == "boolean" then
640 -- NaN is the only value that doesn't equal to itself.
646 push('"%s"' % tostring(x):gsub('["%z\1-\31]',
647 function(c) return '\\u%04x' % c:byte(1) end))
651 return table.concat(rv, "")
657 return require "nixio.fs".dirname(ldebug.__file__)
662 -- Coroutine safe xpcall and pcall versions modified for Luci
664 -- coxpcall 1.13 - Copyright 2005 - Kepler Project (www.keplerproject.org)
666 -- Copyright © 2005 Kepler Project.
667 -- Permission is hereby granted, free of charge, to any person obtaining a
668 -- copy of this software and associated documentation files (the "Software"),
669 -- to deal in the Software without restriction, including without limitation
670 -- the rights to use, copy, modify, merge, publish, distribute, sublicense,
671 -- and/or sell copies of the Software, and to permit persons to whom the
672 -- Software is furnished to do so, subject to the following conditions:
674 -- The above copyright notice and this permission notice shall be
675 -- included in all copies or substantial portions of the Software.
677 -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
678 -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
679 -- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
680 -- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
681 -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
682 -- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
683 -- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
685 local performResume, handleReturnValue
686 local oldpcall, oldxpcall = pcall, xpcall
688 setmetatable(coxpt, {__mode = "kv"})
690 -- Identity function for copcall
691 local function copcall_id(trace, ...)
695 -- values of either the function or the error handler
696 function coxpcall(f, err, ...)
697 local res, co = oldpcall(coroutine.create, f)
700 local newf = function() return f(unpack(params)) end
701 co = coroutine.create(newf)
703 local c = coroutine.running()
704 coxpt[co] = coxpt[c] or c or 0
706 return performResume(err, co, ...)
709 -- values of the function or the error object
710 function copcall(f, ...)
711 return coxpcall(f, copcall_id, ...)
714 -- Handle return value of protected call
715 function handleReturnValue(err, co, status, ...)
717 return false, err(debug.traceback(co, (...)), ...)
720 if coroutine.status(co) ~= 'suspended' then
724 return performResume(err, co, coroutine.yield(...))
727 -- Resume execution of protected function call
728 function performResume(err, co, ...)
729 return handleReturnValue(err, co, coroutine.resume(co, ...))