util.lua 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. -- Copyright 2008 Steven Barth <steven@midlink.org>
  2. -- Licensed to the public under the Apache License 2.0.
  3. local io = require "io"
  4. local math = require "math"
  5. local table = require "table"
  6. local debug = require "debug"
  7. local ldebug = require "luci.debug"
  8. local string = require "string"
  9. local coroutine = require "coroutine"
  10. local tparser = require "luci.template.parser"
  11. local _ubus = require "ubus"
  12. local _ubus_connection = nil
  13. local getmetatable, setmetatable = getmetatable, setmetatable
  14. local rawget, rawset, unpack = rawget, rawset, unpack
  15. local tostring, type, assert = tostring, type, assert
  16. local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring
  17. local require, pcall, xpcall = require, pcall, xpcall
  18. local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit
  19. module "luci.util"
  20. --
  21. -- Pythonic string formatting extension
  22. --
  23. getmetatable("").__mod = function(a, b)
  24. if not b then
  25. return a
  26. elseif type(b) == "table" then
  27. for k, _ in pairs(b) do if type(b[k]) == "userdata" then b[k] = tostring(b[k]) end end
  28. return a:format(unpack(b))
  29. else
  30. if type(b) == "userdata" then b = tostring(b) end
  31. return a:format(b)
  32. end
  33. end
  34. --
  35. -- Class helper routines
  36. --
  37. -- Instantiates a class
  38. local function _instantiate(class, ...)
  39. local inst = setmetatable({}, {__index = class})
  40. if inst.__init__ then
  41. inst:__init__(...)
  42. end
  43. return inst
  44. end
  45. -- The class object can be instantiated by calling itself.
  46. -- Any class functions or shared parameters can be attached to this object.
  47. -- Attaching a table to the class object makes this table shared between
  48. -- all instances of this class. For object parameters use the __init__ function.
  49. -- Classes can inherit member functions and values from a base class.
  50. -- Class can be instantiated by calling them. All parameters will be passed
  51. -- to the __init__ function of this class - if such a function exists.
  52. -- The __init__ function must be used to set any object parameters that are not shared
  53. -- with other objects of this class. Any return values will be ignored.
  54. function class(base)
  55. return setmetatable({}, {
  56. __call = _instantiate,
  57. __index = base
  58. })
  59. end
  60. function instanceof(object, class)
  61. local meta = getmetatable(object)
  62. while meta and meta.__index do
  63. if meta.__index == class then
  64. return true
  65. end
  66. meta = getmetatable(meta.__index)
  67. end
  68. return false
  69. end
  70. --
  71. -- Scope manipulation routines
  72. --
  73. local tl_meta = {
  74. __mode = "k",
  75. __index = function(self, key)
  76. local t = rawget(self, coxpt[coroutine.running()]
  77. or coroutine.running() or 0)
  78. return t and t[key]
  79. end,
  80. __newindex = function(self, key, value)
  81. local c = coxpt[coroutine.running()] or coroutine.running() or 0
  82. local r = rawget(self, c)
  83. if not r then
  84. rawset(self, c, { [key] = value })
  85. else
  86. r[key] = value
  87. end
  88. end
  89. }
  90. -- the current active coroutine. A thread local store is private a table object
  91. -- whose values can't be accessed from outside of the running coroutine.
  92. function threadlocal(tbl)
  93. return setmetatable(tbl or {}, tl_meta)
  94. end
  95. --
  96. -- Debugging routines
  97. --
  98. function perror(obj)
  99. return io.stderr:write(tostring(obj) .. "\n")
  100. end
  101. function dumptable(t, maxdepth, i, seen)
  102. i = i or 0
  103. seen = seen or setmetatable({}, {__mode="k"})
  104. for k,v in pairs(t) do
  105. perror(string.rep("\t", i) .. tostring(k) .. "\t" .. tostring(v))
  106. if type(v) == "table" and (not maxdepth or i < maxdepth) then
  107. if not seen[v] then
  108. seen[v] = true
  109. dumptable(v, maxdepth, i+1, seen)
  110. else
  111. perror(string.rep("\t", i) .. "*** RECURSION ***")
  112. end
  113. end
  114. end
  115. end
  116. --
  117. -- String and data manipulation routines
  118. --
  119. function pcdata(value)
  120. return value and tparser.pcdata(tostring(value))
  121. end
  122. function striptags(value)
  123. return value and tparser.striptags(tostring(value))
  124. end
  125. -- containing the resulting substrings. The optional max parameter specifies
  126. -- the number of bytes to process, regardless of the actual length of the given
  127. -- string. The optional last parameter, regex, specifies whether the separator
  128. -- sequence is interpreted as regular expression.
  129. -- pattern as regular expression (optional, default is false)
  130. function split(str, pat, max, regex)
  131. pat = pat or "\n"
  132. max = max or #str
  133. local t = {}
  134. local c = 1
  135. if #str == 0 then
  136. return {""}
  137. end
  138. if #pat == 0 then
  139. return nil
  140. end
  141. if max == 0 then
  142. return str
  143. end
  144. repeat
  145. local s, e = str:find(pat, c, not regex)
  146. max = max - 1
  147. if s and max < 0 then
  148. t[#t+1] = str:sub(c)
  149. else
  150. t[#t+1] = str:sub(c, s and s - 1)
  151. end
  152. c = e and e + 1 or #str + 1
  153. until not s or max < 0
  154. return t
  155. end
  156. function trim(str)
  157. return (str:gsub("^%s*(.-)%s*$", "%1"))
  158. end
  159. function cmatch(str, pat)
  160. local count = 0
  161. for _ in str:gmatch(pat) do count = count + 1 end
  162. return count
  163. end
  164. -- one token per invocation, the tokens are separated by whitespace. If the
  165. -- input value is a table, it is transformed into a string first. A nil value
  166. -- will result in a valid interator which aborts with the first invocation.
  167. function imatch(v)
  168. if type(v) == "table" then
  169. local k = nil
  170. return function()
  171. k = next(v, k)
  172. return v[k]
  173. end
  174. elseif type(v) == "number" or type(v) == "boolean" then
  175. local x = true
  176. return function()
  177. if x then
  178. x = false
  179. return tostring(v)
  180. end
  181. end
  182. elseif type(v) == "userdata" or type(v) == "string" then
  183. return tostring(v):gmatch("%S+")
  184. end
  185. return function() end
  186. end
  187. -- value or 0 if the unit is unknown. Upper- or lower case is irrelevant.
  188. -- Recognized units are:
  189. -- o "y" - one year (60*60*24*366)
  190. -- o "m" - one month (60*60*24*31)
  191. -- o "w" - one week (60*60*24*7)
  192. -- o "d" - one day (60*60*24)
  193. -- o "h" - one hour (60*60)
  194. -- o "min" - one minute (60)
  195. -- o "kb" - one kilobyte (1024)
  196. -- o "mb" - one megabyte (1024*1024)
  197. -- o "gb" - one gigabyte (1024*1024*1024)
  198. -- o "kib" - one si kilobyte (1000)
  199. -- o "mib" - one si megabyte (1000*1000)
  200. -- o "gib" - one si gigabyte (1000*1000*1000)
  201. function parse_units(ustr)
  202. local val = 0
  203. -- unit map
  204. local map = {
  205. -- date stuff
  206. y = 60 * 60 * 24 * 366,
  207. m = 60 * 60 * 24 * 31,
  208. w = 60 * 60 * 24 * 7,
  209. d = 60 * 60 * 24,
  210. h = 60 * 60,
  211. min = 60,
  212. -- storage sizes
  213. kb = 1024,
  214. mb = 1024 * 1024,
  215. gb = 1024 * 1024 * 1024,
  216. -- storage sizes (si)
  217. kib = 1000,
  218. mib = 1000 * 1000,
  219. gib = 1000 * 1000 * 1000
  220. }
  221. -- parse input string
  222. for spec in ustr:lower():gmatch("[0-9%.]+[a-zA-Z]*") do
  223. local num = spec:gsub("[^0-9%.]+$","")
  224. local spn = spec:gsub("^[0-9%.]+", "")
  225. if map[spn] or map[spn:sub(1,1)] then
  226. val = val + num * ( map[spn] or map[spn:sub(1,1)] )
  227. else
  228. val = val + num
  229. end
  230. end
  231. return val
  232. end
  233. -- also register functions above in the central string class for convenience
  234. string.pcdata = pcdata
  235. string.striptags = striptags
  236. string.split = split
  237. string.trim = trim
  238. string.cmatch = cmatch
  239. string.parse_units = parse_units
  240. function append(src, ...)
  241. for i, a in ipairs({...}) do
  242. if type(a) == "table" then
  243. for j, v in ipairs(a) do
  244. src[#src+1] = v
  245. end
  246. else
  247. src[#src+1] = a
  248. end
  249. end
  250. return src
  251. end
  252. function combine(...)
  253. return append({}, ...)
  254. end
  255. function contains(table, value)
  256. for k, v in pairs(table) do
  257. if value == v then
  258. return k
  259. end
  260. end
  261. return false
  262. end
  263. -- Both table are - in fact - merged together.
  264. function update(t, updates)
  265. for k, v in pairs(updates) do
  266. t[k] = v
  267. end
  268. end
  269. function keys(t)
  270. local keys = { }
  271. if t then
  272. for k, _ in kspairs(t) do
  273. keys[#keys+1] = k
  274. end
  275. end
  276. return keys
  277. end
  278. function clone(object, deep)
  279. local copy = {}
  280. for k, v in pairs(object) do
  281. if deep and type(v) == "table" then
  282. v = clone(v, deep)
  283. end
  284. copy[k] = v
  285. end
  286. return setmetatable(copy, getmetatable(object))
  287. end
  288. function dtable()
  289. return setmetatable({}, { __index =
  290. function(tbl, key)
  291. return rawget(tbl, key)
  292. or rawget(rawset(tbl, key, dtable()), key)
  293. end
  294. })
  295. end
  296. -- Serialize the contents of a table value.
  297. function _serialize_table(t, seen)
  298. assert(not seen[t], "Recursion detected.")
  299. seen[t] = true
  300. local data = ""
  301. local idata = ""
  302. local ilen = 0
  303. for k, v in pairs(t) do
  304. if type(k) ~= "number" or k < 1 or math.floor(k) ~= k or ( k - #t ) > 3 then
  305. k = serialize_data(k, seen)
  306. v = serialize_data(v, seen)
  307. data = data .. ( #data > 0 and ", " or "" ) ..
  308. '[' .. k .. '] = ' .. v
  309. elseif k > ilen then
  310. ilen = k
  311. end
  312. end
  313. for i = 1, ilen do
  314. local v = serialize_data(t[i], seen)
  315. idata = idata .. ( #idata > 0 and ", " or "" ) .. v
  316. end
  317. return idata .. ( #data > 0 and #idata > 0 and ", " or "" ) .. data
  318. end
  319. -- with loadstring().
  320. function serialize_data(val, seen)
  321. seen = seen or setmetatable({}, {__mode="k"})
  322. if val == nil then
  323. return "nil"
  324. elseif type(val) == "number" then
  325. return val
  326. elseif type(val) == "string" then
  327. return "%q" % val
  328. elseif type(val) == "boolean" then
  329. return val and "true" or "false"
  330. elseif type(val) == "function" then
  331. return "loadstring(%q)" % get_bytecode(val)
  332. elseif type(val) == "table" then
  333. return "{ " .. _serialize_table(val, seen) .. " }"
  334. else
  335. return '"[unhandled data type:' .. type(val) .. ']"'
  336. end
  337. end
  338. function restore_data(str)
  339. return loadstring("return " .. str)()
  340. end
  341. --
  342. -- Byte code manipulation routines
  343. --
  344. -- will be stripped before it is returned.
  345. function get_bytecode(val)
  346. local code
  347. if type(val) == "function" then
  348. code = string.dump(val)
  349. else
  350. code = string.dump( loadstring( "return " .. serialize_data(val) ) )
  351. end
  352. return code -- and strip_bytecode(code)
  353. end
  354. -- numbers and debugging numbers will be discarded. Original version by
  355. -- Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
  356. function strip_bytecode(code)
  357. local version, format, endian, int, size, ins, num, lnum = code:byte(5, 12)
  358. local subint
  359. if endian == 1 then
  360. subint = function(code, i, l)
  361. local val = 0
  362. for n = l, 1, -1 do
  363. val = val * 256 + code:byte(i + n - 1)
  364. end
  365. return val, i + l
  366. end
  367. else
  368. subint = function(code, i, l)
  369. local val = 0
  370. for n = 1, l, 1 do
  371. val = val * 256 + code:byte(i + n - 1)
  372. end
  373. return val, i + l
  374. end
  375. end
  376. local function strip_function(code)
  377. local count, offset = subint(code, 1, size)
  378. local stripped = { string.rep("\0", size) }
  379. local dirty = offset + count
  380. offset = offset + count + int * 2 + 4
  381. offset = offset + int + subint(code, offset, int) * ins
  382. count, offset = subint(code, offset, int)
  383. for n = 1, count do
  384. local t
  385. t, offset = subint(code, offset, 1)
  386. if t == 1 then
  387. offset = offset + 1
  388. elseif t == 4 then
  389. offset = offset + size + subint(code, offset, size)
  390. elseif t == 3 then
  391. offset = offset + num
  392. elseif t == 254 or t == 9 then
  393. offset = offset + lnum
  394. end
  395. end
  396. count, offset = subint(code, offset, int)
  397. stripped[#stripped+1] = code:sub(dirty, offset - 1)
  398. for n = 1, count do
  399. local proto, off = strip_function(code:sub(offset, -1))
  400. stripped[#stripped+1] = proto
  401. offset = offset + off - 1
  402. end
  403. offset = offset + subint(code, offset, int) * int + int
  404. count, offset = subint(code, offset, int)
  405. for n = 1, count do
  406. offset = offset + subint(code, offset, size) + size + int * 2
  407. end
  408. count, offset = subint(code, offset, int)
  409. for n = 1, count do
  410. offset = offset + subint(code, offset, size) + size
  411. end
  412. stripped[#stripped+1] = string.rep("\0", int * 3)
  413. return table.concat(stripped), offset
  414. end
  415. return code:sub(1,12) .. strip_function(code:sub(13,-1))
  416. end
  417. --
  418. -- Sorting iterator functions
  419. --
  420. function _sortiter( t, f )
  421. local keys = { }
  422. local k, v
  423. for k, v in pairs(t) do
  424. keys[#keys+1] = k
  425. end
  426. local _pos = 0
  427. table.sort( keys, f )
  428. return function()
  429. _pos = _pos + 1
  430. if _pos <= #keys then
  431. return keys[_pos], t[keys[_pos]], _pos
  432. end
  433. end
  434. end
  435. -- the provided callback function.
  436. function spairs(t,f)
  437. return _sortiter( t, f )
  438. end
  439. -- The table pairs are sorted by key.
  440. function kspairs(t)
  441. return _sortiter( t )
  442. end
  443. -- The table pairs are sorted by value.
  444. function vspairs(t)
  445. return _sortiter( t, function (a,b) return t[a] < t[b] end )
  446. end
  447. --
  448. -- System utility functions
  449. --
  450. function bigendian()
  451. return string.byte(string.dump(function() end), 7) == 0
  452. end
  453. function exec(command)
  454. local pp = io.popen(command)
  455. local data = pp:read("*a")
  456. pp:close()
  457. return data
  458. end
  459. function execi(command)
  460. local pp = io.popen(command)
  461. return pp and function()
  462. local line = pp:read()
  463. if not line then
  464. pp:close()
  465. end
  466. return line
  467. end
  468. end
  469. -- Deprecated
  470. function execl(command)
  471. local pp = io.popen(command)
  472. local line = ""
  473. local data = {}
  474. while true do
  475. line = pp:read()
  476. if (line == nil) then break end
  477. data[#data+1] = line
  478. end
  479. pp:close()
  480. return data
  481. end
  482. function ubus(object, method, data)
  483. if not _ubus_connection then
  484. _ubus_connection = _ubus.connect()
  485. assert(_ubus_connection, "Unable to establish ubus connection")
  486. end
  487. if object and method then
  488. if type(data) ~= "table" then
  489. data = { }
  490. end
  491. return _ubus_connection:call(object, method, data)
  492. elseif object then
  493. return _ubus_connection:signatures(object)
  494. else
  495. return _ubus_connection:objects()
  496. end
  497. end
  498. function serialize_json(x, cb)
  499. local rv, push = nil, cb
  500. if not push then
  501. rv = { }
  502. push = function(tok) rv[#rv+1] = tok end
  503. end
  504. if x == nil then
  505. push("null")
  506. elseif type(x) == "table" then
  507. -- test if table is array like
  508. local k, v
  509. local n1, n2 = 0, 0
  510. for k in pairs(x) do n1 = n1 + 1 end
  511. for k in ipairs(x) do n2 = n2 + 1 end
  512. if n1 == n2 and n1 > 0 then
  513. push("[")
  514. for k = 1, n2 do
  515. if k > 1 then
  516. push(",")
  517. end
  518. serialize_json(x[k], push)
  519. end
  520. push("]")
  521. else
  522. push("{")
  523. for k, v in pairs(x) do
  524. push("%q:" % tostring(k))
  525. serialize_json(v, push)
  526. if next(x, k) then
  527. push(",")
  528. end
  529. end
  530. push("}")
  531. end
  532. elseif type(x) == "number" or type(x) == "boolean" then
  533. if (x ~= x) then
  534. -- NaN is the only value that doesn't equal to itself.
  535. push("Number.NaN")
  536. else
  537. push(tostring(x))
  538. end
  539. else
  540. push('"%s"' % tostring(x):gsub('["%z\1-\31\\]',
  541. function(c) return '\\u%04x' % c:byte(1) end))
  542. end
  543. if not cb then
  544. return table.concat(rv, "")
  545. end
  546. end
  547. function libpath()
  548. return require "nixio.fs".dirname(ldebug.__file__)
  549. end
  550. --
  551. -- Coroutine safe xpcall and pcall versions modified for Luci
  552. -- original version:
  553. -- coxpcall 1.13 - Copyright 2005 - Kepler Project (www.keplerproject.org)
  554. --
  555. -- Copyright © 2005 Kepler Project.
  556. -- Permission is hereby granted, free of charge, to any person obtaining a
  557. -- copy of this software and associated documentation files (the "Software"),
  558. -- to deal in the Software without restriction, including without limitation
  559. -- the rights to use, copy, modify, merge, publish, distribute, sublicense,
  560. -- and/or sell copies of the Software, and to permit persons to whom the
  561. -- Software is furnished to do so, subject to the following conditions:
  562. --
  563. -- The above copyright notice and this permission notice shall be
  564. -- included in all copies or substantial portions of the Software.
  565. --
  566. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  567. -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  568. -- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  569. -- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  570. -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  571. -- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  572. -- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  573. local performResume, handleReturnValue
  574. local oldpcall, oldxpcall = pcall, xpcall
  575. coxpt = {}
  576. setmetatable(coxpt, {__mode = "kv"})
  577. -- Identity function for copcall
  578. local function copcall_id(trace, ...)
  579. return ...
  580. end
  581. -- values of either the function or the error handler
  582. function coxpcall(f, err, ...)
  583. local res, co = oldpcall(coroutine.create, f)
  584. if not res then
  585. local params = {...}
  586. local newf = function() return f(unpack(params)) end
  587. co = coroutine.create(newf)
  588. end
  589. local c = coroutine.running()
  590. coxpt[co] = coxpt[c] or c or 0
  591. return performResume(err, co, ...)
  592. end
  593. -- values of the function or the error object
  594. function copcall(f, ...)
  595. return coxpcall(f, copcall_id, ...)
  596. end
  597. -- Handle return value of protected call
  598. function handleReturnValue(err, co, status, ...)
  599. if not status then
  600. return false, err(debug.traceback(co, (...)), ...)
  601. end
  602. if coroutine.status(co) ~= 'suspended' then
  603. return true, ...
  604. end
  605. return performResume(err, co, coroutine.yield(...))
  606. end
  607. -- Resume execution of protected function call
  608. function performResume(err, co, ...)
  609. return handleReturnValue(err, co, coroutine.resume(co, ...))
  610. end