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