diff --git a/RPC/OpenOS/usr/bin/exportall.lua b/RPC/OpenOS/usr/bin/exportall.lua new file mode 100644 index 0000000..e62db2e --- /dev/null +++ b/RPC/OpenOS/usr/bin/exportall.lua @@ -0,0 +1,12 @@ +local component = require "component" +local r2r = require "r2r" +local tA = {...} + + +for k,v in component.list() do + local px = component.proxy(component.get(k)) + print(px.type.."_"..px.address) + for l,m in pairs(px) do + r2r.register(px.type.."_"..px.address.."_"..l,m) + end +end diff --git a/RPC/OpenOS/usr/bin/exportcomponent.lua b/RPC/OpenOS/usr/bin/exportcomponent.lua index 1a662cf..eaadadf 100644 --- a/RPC/OpenOS/usr/bin/exportcomponent.lua +++ b/RPC/OpenOS/usr/bin/exportcomponent.lua @@ -1,5 +1,5 @@ local component = require "component" -local rpc = require "rpc" +local r2r = require "r2r" local tA = {...} if #tA < 1 then @@ -10,6 +10,6 @@ for k,v in ipairs(tA) do local px = component.proxy(component.get(v)) print(px.type.."_"..px.address) for l,m in pairs(px) do - rpc.register(px.type.."_"..px.address.."_"..l,m) + r2r.register(px.type.."_"..px.address.."_"..l,m) end end diff --git a/RPC/OpenOS/usr/bin/importall.lua b/RPC/OpenOS/usr/bin/importall.lua new file mode 100644 index 0000000..5dd7060 --- /dev/null +++ b/RPC/OpenOS/usr/bin/importall.lua @@ -0,0 +1,36 @@ +local vcomponent = require "vcomponent" +local r2r = require "r2r" +local tA = {...} +local host = tA[1] + +if #tA < 1 then + print("Usage: importcomponent ") + return +end + +local components = r2r.call(host,"listcomponents") + +for k,v in pairs(components) do + ctype = k + addr = v + local saddr = addr:gsub("%-","%%-") + if addr:len() < 36 then + local flist = r2r.call(host,"list") + for k,v in pairs(flist) do + faddr = v:match(ctype.."_("..saddr..".*)_") or faddr + end + end + print(faddr) + saddr = (faddr or addr):gsub("%-","%%-") + local px = r2r.proxy(host,ctype.."_"..saddr..".*_") + local mc = 0 + for k,v in pairs(px) do + mc = mc + 1 + end + if mc < 1 then + error("no such remote component: "..addr) + end + vcomponent.register(faddr or addr, ctype, px) + +end + diff --git a/RPC/OpenOS/usr/bin/importcomponent.lua b/RPC/OpenOS/usr/bin/importcomponent.lua index d049b89..0f93190 100644 --- a/RPC/OpenOS/usr/bin/importcomponent.lua +++ b/RPC/OpenOS/usr/bin/importcomponent.lua @@ -1,5 +1,5 @@ local vcomponent = require "vcomponent" -local rpc = require "rpc" +local r2r = require "r2r" local tA = {...} local host, ctype, addr = tA[1], tA[2], tA[3] @@ -11,14 +11,14 @@ end local saddr = addr:gsub("%-","%%-") if addr:len() < 36 then - local flist = rpc.call(host,"list") + local flist = r2r.call(host,"list") for k,v in pairs(flist) do faddr = v:match(ctype.."_("..saddr..".*)_") or faddr end end print(faddr) saddr = (faddr or addr):gsub("%-","%%-") -local px = rpc.proxy(host,ctype.."_"..saddr..".*_") +local px = r2r.proxy(host,ctype.."_"..saddr..".*_") local mc = 0 for k,v in pairs(px) do mc = mc + 1 diff --git a/RPC/OpenOS/usr/lib/r2r.lua b/RPC/OpenOS/usr/lib/r2r.lua new file mode 100644 index 0000000..8573574 --- /dev/null +++ b/RPC/OpenOS/usr/lib/r2r.lua @@ -0,0 +1,115 @@ +r2r = {} +r2r.buffer = {} +r2r.chunksize = 4000 +r2r.initalized = false +r2r.fn = {} + +local rpc = require("rpc") +local serial = require "serialization" +local component = require("component") + +function r2r.fn.list() + local rt = {} + for k,v in pairs(r2r.fn) do + rt[#rt + 1] = k + end + return rt +end + +function r2r.fn.listcomponents() + return component.list() +end + +function r2r.init() + rpc.register("createendpoint", function() + local key = require("uuid").next() + r2r.buffer[key] = {} + return key + end) + + rpc.register("record", function(data, key) + r2r.buffer[key][#r2r.buffer[key] + 1] = data + return true + end) + + rpc.register("call", function(function_name, key) + local data = "" + for i = 1, #r2r.buffer[key] do + data = data .. r2r.buffer[key][i] + end + local deserialized = serial.unserialize(data) + local result = r2r.fn[function_name](table.unpack(deserialized)) + local serialized_result = serial.serialize({result}) + local chunk_count = #serialized_result // r2r.chunksize + if #serialized_result % r2r.chunksize ~= 0 then + chunk_count = chunk_count + 1 + end + r2r.buffer[key]["result"] = {} + for i = 1, chunk_count do + r2r.buffer[key]["result"][i] = serialized_result:sub((i - 1) * r2r.chunksize + 1, i * r2r.chunksize) + end + return true + end) + + rpc.register("getresultpart", function(key, id) + return r2r.buffer[key]["result"][id] + end) + + rpc.register("getchunkcount", function(key) + return #r2r.buffer[key]["result"] + end) + + rpc.register("removeendpoint", function(key) + r2r.buffer[key] = nil + end) + + r2r.initalized = true +end + +function r2r.call(host,function_name, ...) + local key = rpc.call(host,"createendpoint") + local serialized_args = serial.serialize({...}) + local chunk_count = #serialized_args // r2r.chunksize + if #serialized_args % r2r.chunksize ~= 0 then + chunk_count = chunk_count + 1 + end + for i = 1, chunk_count do + local chunk = serialized_args:sub((i - 1) * r2r.chunksize + 1, i * r2r.chunksize) + rpc.call(host,"record", chunk, key) + end + rpc.call(host,"call", function_name, key) + local result_chunk_count = rpc.call(host,"getchunkcount", key) + local result = "" + for i = 1, result_chunk_count do + result = result .. rpc.call(host,"getresultpart", key, i) + end + rpc.call(host,"removeendpoint", key) + return table.unpack(serial.unserialize(result)) +end + + +function r2r.proxy(hostname,filter) + filter=(filter or "").."(.+)" + local fnames = r2r.call(hostname,"list") + if not fnames then return false end + local rt = {} + for k,v in pairs(fnames) do + fv = v:match(filter) + if fv then + rt[fv] = function(...) + return r2r.call(hostname,v,...) + end + end + end + return rt +end + + +function r2r.register(name,fn) + if not r2r.initalized then + r2r.init() + end + r2r.fn[name] = fn +end + +return r2r \ No newline at end of file diff --git a/RPC/OpenOS/usr/lib/rpc.lua b/RPC/OpenOS/usr/lib/rpc.lua index 764d359..d4b8985 100644 --- a/RPC/OpenOS/usr/lib/rpc.lua +++ b/RPC/OpenOS/usr/lib/rpc.lua @@ -11,7 +11,7 @@ function rpc.call(hostname,fn,...) if hostname == "localhost" then return rpcf[fn](...) end - local rv = minitel.genPacketID() + local rv = "42return!" .. minitel.genPacketID() minitel.rsend(hostname,rpc.port,serial.serialize({fn,rv,...}),true) local st = computer.uptime() local rt = {} @@ -58,35 +58,36 @@ local function isPermitted(host,fn) end function rpc.register(name,fn) - if not rpcrunning then - event.listen("net_msg",function(_, from, port, data) - if port == rpc.port then - local rpcrq = serial.unserialize(data) - if #rpcrq ~= 3 then - return - end - local rpcn, rpcid = table.remove(rpcrq,1), table.remove(rpcrq,1) - if rpcf[rpcn] and isPermitted(from,rpcn) then - local rt = {pcall(rpcf[rpcn],table.unpack(rpcrq))} - if rt[1] == true then - table.remove(rt,1) + if not rpcrunning then + event.listen("net_msg",function(_, from, port, data) + if port == rpc.port then + local rpcrq = serial.unserialize(data) + if string.sub(rpcrq[1],1,2) == "42" then + return + end + local rpcn, rpcid = table.remove(rpcrq,1), table.remove(rpcrq,1) + if rpcf[rpcn] and isPermitted(from,rpcn) then + local rt = {pcall(rpcf[rpcn],table.unpack(rpcrq))} + if rt[1] == true then + table.remove(rt,1) + end + minitel.send(from,port,serial.serialize({rpcid,table.unpack(rt)})) + else + minitel.send(from,port,serial.serialize({rpcid,false,"function unavailable"})) + end + end + end) + function rpcf.list() + local rt = {} + for k,v in pairs(rpcf) do + rt[#rt+1] = k + end + return rt end - minitel.send(from,port,serial.serialize({rpcid,table.unpack(rt)})) - else - minitel.send(from,port,serial.serialize({rpcid,false,"function unavailable"})) + rpcrunning = true end + rpcf[name] = fn end - end) - function rpcf.list() - local rt = {} - for k,v in pairs(rpcf) do - rt[#rt+1] = k - end - return rt - end - rpcrunning = true - end - rpcf[name] = fn -end - -return rpc + + return rpc + \ No newline at end of file