sandbox.lua 3.21 KB
Newer Older
1 2 3 4
-- Units
kB = 1024
MB = 1024*1024
GB = 1024*1024
5 6 7 8
-- Time
sec = 1000
minute = 60 * sec
hour = 60 * minute
9 10 11 12 13 14 15 16 17 18

-- Function aliases
-- `env.VAR returns os.getenv(VAR)`
env = {}
setmetatable(env, {
	__index = function (t, k) return os.getenv(k) end
})

-- Quick access to interfaces
-- `net.<iface>` => `net.interfaces()[iface]`
19
-- `net = {addr1, ..}` => `net.listen(name, addr1)`
20 21 22 23 24 25
setmetatable(net, {
	__index = function (t, k)
		local v = rawget(t, k)
		if v then return v
		else return net.interfaces()[k]
		end
26 27 28 29 30 31
	end,
	__newindex = function (t,k,v)
		local iname = rawget(net.interfaces(), v)
		if iname then t.listen(iname)
		else t.listen(v)
		end
32 33 34
	end
})

35 36
-- Syntactic sugar for module loading
-- `modules.<name> = <config>`
37
setmetatable(modules, {
38
	__newindex = function (t,k,v)
39
		if type(k) == 'number' then k = v end
40 41 42
		if not rawget(_G, k) then
			modules.load(k)
			local mod = rawget(_G, k)
43
			if k ~= v and mod and mod['config'] then
44
				mod['config'](v)
45
			end
46

47
		end
48 49 50 51 52 53 54 55 56 57
	end
})

-- Syntactic sugar for cache
-- `cache.{size|storage} = value`
setmetatable(cache, {
	__newindex = function (t,k,v)
		if     k == 'size'    then t.open(v, rawget(t, 'storage'))
		elseif k == 'storage' then t.open(rawget(t, 'size'), v)
		else   rawset(t, k, v) end
58
	end
59 60
})

61 62 63 64 65 66 67
-- Register module in Lua environment
function modules_register(module)
	-- Syntactic sugar for get() and set() properties
	setmetatable(module, {
		__index = function (t, k)
			local  v = rawget(t, k)
			if     v     then return v
68
			elseif rawget(t, 'get') then return t.get(k)
69 70 71 72
			end
		end,
		__newindex = function (t, k, v)
			local  old_v = rawget(t, k)
73
			if not old_v and rawget(t, 'set') then
74 75 76 77 78 79
				t.set(k..' '..v)
			end
		end
	})
end

80
-- Make sandboxed environment
81
local function make_sandbox(defined)
82
	local __protected = { modules = true, cache = true, net = true }
83 84 85 86 87 88 89 90 91 92 93 94 95
	return setmetatable({}, {
		__index = defined,
		__newindex = function (t, k, v)
			if __protected[k] then
				for k2,v2 in pairs(v) do
					defined[k][k2] = v2
				end
			else
				defined[k] = v
			end
		end
	})
end
96

97
-- Compatibility sandbox
98 99 100 101 102 103
if setfenv then -- Lua 5.1 and less
	_G = make_sandbox(getfenv(0))
	setfenv(0, _G)
else -- Lua 5.2+
	_SANDBOX = make_sandbox(_ENV)
end
104

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
-- Interactive command evaluation
function eval_cmd(line)
	-- Compatibility sandbox code loading
	local function load_code(code)
	    if getfenv then -- Lua 5.1
	        return loadstring(code)
	    else            -- Lua 5.2+
	        return load(code, nil, 't', _ENV)
	    end
	end
	local status, err, chunk
	chunk, err = load_code('table_print('..line..')')
	if err then
		chunk, err = load_code(line)
	end
	if not err then
		chunk()
	end
	if err then
		print(err)
	end
end

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
-- Pretty printing
function table_print (tt, indent, done)
	done = done or {}
	indent = indent or 0
	if type(tt) == "table" then
		for key, value in pairs (tt) do
			io.write(string.rep (" ", indent))
			if type (value) == "table" and not done [value] then
				done [value] = true
				io.write(string.format("[%s] => {\n", tostring (key)));
				table_print (value, indent + 4, done)
				io.write(string.rep (" ", indent))
				io.write("}\n");
			else
				io.write(string.format("[%s] => %s\n",
				         tostring (key), tostring(value)))
			end
		end
	else
		io.write(tostring(tt) .. "\n")
	end
end