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