|
|
@@ -5,19 +5,34 @@ local rpc = {} |
|
|
|
_G.rpcf = {} |
|
|
|
rpc.port = 111 |
|
|
|
|
|
|
|
local function setacl(self, fname, host) |
|
|
|
self[fname] = self[fname] or {} |
|
|
|
self[fname][host] = true |
|
|
|
end |
|
|
|
rpc.allow = setmetatable({},{__call=setacl}) |
|
|
|
rpc.deny = setmetatable({},{__call=setacl}) |
|
|
|
|
|
|
|
local function isPermitted(host,fn) |
|
|
|
if rpc.allow[fn] then |
|
|
|
return rpc.allow[fn][host] or false |
|
|
|
end |
|
|
|
if rpc.deny[fn] and rpc.deny[fn][host] then |
|
|
|
return false |
|
|
|
end |
|
|
|
return true |
|
|
|
end |
|
|
|
|
|
|
|
local function rpcexec(_, from, port, data) |
|
|
|
if port == rpc.port then |
|
|
|
local rpcrq = serial.unserialize(data) |
|
|
|
local rpcn, rpcid = table.remove(rpcrq,1), table.remove(rpcrq,1) |
|
|
|
if rpcf[rpcn] then |
|
|
|
local rt = {pcall(rpcf[rpcn],table.unpack(rpcrq))} |
|
|
|
if rt[1] == true then |
|
|
|
table.remove(rt,1) |
|
|
|
os.spawn(function() |
|
|
|
if port == rpc.port then |
|
|
|
local rpcrq = serial.unserialize(data) or {} |
|
|
|
if rpcf[rpcrq[1]] and isPermitted(from,rpcrq[1]) then |
|
|
|
minitel.send(from,port,serial.serialize({rpcrq[2],pcall(rpcf[rpcrq[1]],table.unpack(rpcrq,3))})) |
|
|
|
elseif type(rpcrq[2]) == "string" then |
|
|
|
minitel.send(from,port,serial.serialize({rpcrq[2],false,"function unavailable"})) |
|
|
|
end |
|
|
|
minitel.send(from,port,serial.serialize({rpcid,table.unpack(rt)})) |
|
|
|
else |
|
|
|
end |
|
|
|
end |
|
|
|
end,"rpc worker for "..tostring(from)) |
|
|
|
end |
|
|
|
function rpcf.list() |
|
|
|
local rt = {} |
|
|
@@ -39,10 +54,13 @@ function rpc.call(hostname,fn,...) -- string string -- boolean -- Calls exported |
|
|
|
local _, from, port, data = event.pull(30, "net_msg", hostname, rpc.port) |
|
|
|
rt = serial.unserialize(tostring(data)) or {} |
|
|
|
until (type(rt) == "table" and rt[1] == rv) or computer.uptime() > st + 30 |
|
|
|
if table.remove(rt,1) == rv then |
|
|
|
return table.unpack(rt) |
|
|
|
if rt[1] == rv then |
|
|
|
if rt[2] then |
|
|
|
return table.unpack(rt,3) |
|
|
|
end |
|
|
|
error(rt[3]) |
|
|
|
end |
|
|
|
return false |
|
|
|
error("timed out") |
|
|
|
end |
|
|
|
function rpc.proxy(hostname,filter) -- string string -- table -- Returns a component.proxy()-like table from the functions on *hostname* with names matching *filter*. |
|
|
|
filter=(filter or "").."(.+)" |
|
|
@@ -69,7 +87,7 @@ function rpc.register(name,fn) -- string function -- -- Registers a function to |
|
|
|
if not rpcrunning then |
|
|
|
os.spawn(function() |
|
|
|
while true do |
|
|
|
rpcexec(event.pull("net_msg")) |
|
|
|
pcall(rpcexec,event.pull("net_msg")) |
|
|
|
end |
|
|
|
end,"rpc daemon") |
|
|
|
end |
|
|
|