forked from izaya/OC-PsychOS2
find, filter, skeletons
This commit is contained in:
parent
50cfb2bbf2
commit
76de8ca302
@ -1 +1 @@
|
|||||||
{enabled={"getty","minitel"}}
|
{enabled={"getty","minitel","clipboard","fsmanager"}}
|
||||||
|
128
lib/doc.lua
128
lib/doc.lua
@ -1,128 +0,0 @@
|
|||||||
local _,serial = pcall(require,"serialization")
|
|
||||||
local doc = {}
|
|
||||||
doc.searchers = {}
|
|
||||||
doc.tctab = {
|
|
||||||
["string"] = 31,
|
|
||||||
["table"] = 32,
|
|
||||||
["number"] = 33,
|
|
||||||
["boolean"] = 35,
|
|
||||||
["function"] = 36
|
|
||||||
}
|
|
||||||
|
|
||||||
function doc.parsefile(path) -- string -- table -- parses file from *path* to return a documentation table
|
|
||||||
local fdoc = {}
|
|
||||||
local f = io.open(path)
|
|
||||||
local lines = {}
|
|
||||||
for l in f:read("*a"):gmatch("[^\n]+") do
|
|
||||||
if l:find("function") and not l:find("local") then
|
|
||||||
lines[#lines+1] = l
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for k,v in pairs(lines) do
|
|
||||||
local name, args, desc = v:match("function%s+(.+)%s*%((.*)%)%s*%-%-%s*(.+)")
|
|
||||||
if name and args and desc then
|
|
||||||
local fd = {["description"]=desc or desc,["args"]={},["atypes"]={}}
|
|
||||||
for word in args:gmatch("[^%s,]+") do
|
|
||||||
fd.args[#fd.args+1] = {word}
|
|
||||||
fd.atypes[word] = "unknown"
|
|
||||||
end
|
|
||||||
local argtypes, outtypes, description = desc:match("(.-)%-%-(.-)%-%-%s*(.+)")
|
|
||||||
if argtypes and outtypes and description then
|
|
||||||
local wc = 1
|
|
||||||
for word in argtypes:gmatch("%S+") do
|
|
||||||
fd.args[wc][2] = word
|
|
||||||
fd.atypes[fd.args[wc][1]] = word
|
|
||||||
wc = wc + 1
|
|
||||||
end
|
|
||||||
local wc = 1
|
|
||||||
for word in outtypes:gmatch("%S+") do
|
|
||||||
fd.outtypes = fd.outtypes or {}
|
|
||||||
fd.outtypes[#fd.outtypes+1] = word
|
|
||||||
end
|
|
||||||
fd.description = description
|
|
||||||
end
|
|
||||||
fdoc[name] = fd
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return fdoc
|
|
||||||
end
|
|
||||||
|
|
||||||
function doc.format(fdoc) -- table -- string -- returns VT100 formatted documentation from documentation table *fdoc*
|
|
||||||
local rs = "" -- string to return
|
|
||||||
for fname,finfo in pairs(fdoc) do
|
|
||||||
if rs:len() > 0 then rs = rs .. "\n\n" end
|
|
||||||
local as = "" -- string containing arguments for a given function, with colours for type
|
|
||||||
for k,v in ipairs(finfo.args) do
|
|
||||||
local c = doc.tctab[v[2]] or 0
|
|
||||||
if k > 1 then
|
|
||||||
as = as .. ", "
|
|
||||||
end
|
|
||||||
if v[2] then
|
|
||||||
as = string.format("%s%s: \27[%im%s\27[0m",as,v[2],c,v[1])
|
|
||||||
else
|
|
||||||
as = string.format("%s\27[%im%s\27[0m",as,c,v[1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local rv = ""
|
|
||||||
if finfo.outtypes then
|
|
||||||
rv = ": "
|
|
||||||
for k,v in ipairs(finfo.outtypes) do
|
|
||||||
if k > 1 then
|
|
||||||
rv = rv .. ", "
|
|
||||||
end
|
|
||||||
local c = doc.tctab[v] or 0
|
|
||||||
rv = string.format("%s\27[%im%s\27[0m",rv,c,v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local nd = finfo.description
|
|
||||||
for k,v in pairs(finfo.atypes) do
|
|
||||||
local c = doc.tctab[v] or 7
|
|
||||||
nd=nd:gsub("%*"..k.."%*","\27["..tostring(c).."m"..k.."\27[0m")
|
|
||||||
end
|
|
||||||
rs = string.format("%s\27[36m%s\27[0m(%s)%s\n%s",rs,fname,as,rv,nd)
|
|
||||||
end
|
|
||||||
return rs
|
|
||||||
end
|
|
||||||
|
|
||||||
function doc.searchers.lib(name) -- string -- string string -- Tries to find a documentation from a library with *name*. Returns either a string of documentation, or false and a reason.
|
|
||||||
local lib = os.getenv("LIB") or "/boot/lib"
|
|
||||||
local dt
|
|
||||||
for d in lib:gmatch("[^\n]+") do
|
|
||||||
if fs.exists(d.."/"..name) then
|
|
||||||
dt = doc.parsefile(d.."/"..name)
|
|
||||||
elseif fs.exists(d.."/"..name..".lua") then
|
|
||||||
dt = doc.parsefile(d.."/"..name..".lua")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not dt then return false, "unable to find documentation for "..tostring(name) end
|
|
||||||
return doc.format(dt)
|
|
||||||
end
|
|
||||||
function doc.searchers.cdoc(topic) -- string -- string string -- Searches for documentation labelled as *topic* in .dict files under /boot/doc/
|
|
||||||
if not serial then return end
|
|
||||||
for k,v in ipairs(fs.list("/boot/doc")) do
|
|
||||||
if v:sub(-5) == ".dict" then
|
|
||||||
local f=io.open("/boot/doc/"..v,"rb")
|
|
||||||
for line in f:lines() do
|
|
||||||
local mname, docs = line:match("^(.-)\t(.+)$")
|
|
||||||
if mname == topic or mname == topic..".lua" then
|
|
||||||
return doc.format(serial.unserialize(docs))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function doc.docs(topic) -- string -- boolean -- Displays the documentation for *topic*, returning true, or errors. Also callable as just doc().
|
|
||||||
local lib = os.getenv("LIB") or "/boot/lib"
|
|
||||||
local dt
|
|
||||||
for k,v in pairs(doc.searchers) do
|
|
||||||
dt=v(topic)
|
|
||||||
if dt then
|
|
||||||
print(dt)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
error("unable to find documentation for "..tostring(name))
|
|
||||||
end
|
|
||||||
|
|
||||||
return setmetatable(doc,{__call=function(_,topic) return doc.docs(topic) end})
|
|
0
lib/foxfs.lua
Normal file
0
lib/foxfs.lua
Normal file
@ -1,63 +0,0 @@
|
|||||||
local imt = {}
|
|
||||||
|
|
||||||
imt.ttypes = {}
|
|
||||||
imt.ttypes.string=1
|
|
||||||
imt.ttypes.number=2
|
|
||||||
|
|
||||||
imt.ftypes = {tostring,tonumber}
|
|
||||||
|
|
||||||
function imt.to16bn(n)
|
|
||||||
return string.char(math.floor(n/256))..string.char(math.floor(n%256))
|
|
||||||
end
|
|
||||||
function imt.from16bn(s)
|
|
||||||
return (string.byte(s,1,1)*256)+string.byte(s,2,2)
|
|
||||||
end
|
|
||||||
|
|
||||||
function imt.encodePacket(...)
|
|
||||||
local tArgs = {...}
|
|
||||||
local packet = string.char(#tArgs%256)
|
|
||||||
for _,segment in ipairs(tArgs) do
|
|
||||||
local segtype = type(segment)
|
|
||||||
segment = tostring(segment)
|
|
||||||
packet = packet .. imt.to16bn(segment:len()) .. string.char(imt.ttypes[segtype]) .. tostring(segment)
|
|
||||||
end
|
|
||||||
packet = imt.to16bn(packet:len()) .. packet
|
|
||||||
return packet
|
|
||||||
end
|
|
||||||
|
|
||||||
function imt.decodePacket(s)
|
|
||||||
local function getfirst(n)
|
|
||||||
local ns = s:sub(1,n)
|
|
||||||
s=s:sub(n+1)
|
|
||||||
return ns
|
|
||||||
end
|
|
||||||
if s:len() < 2 then return false end
|
|
||||||
local plen = imt.from16bn(getfirst(2))
|
|
||||||
local segments = {}
|
|
||||||
if s:len() < plen then return false end
|
|
||||||
local nsegments = string.byte(getfirst(1))
|
|
||||||
--print(tostring(plen).." bytes, "..tostring(nsegments).." segments")
|
|
||||||
for i = 1, nsegments do
|
|
||||||
local seglen = imt.from16bn(getfirst(2))
|
|
||||||
local segtype = imt.ftypes[string.byte(getfirst(1))]
|
|
||||||
local segment = segtype(getfirst(seglen))
|
|
||||||
--print(seglen,segtype,segment,type(segment))
|
|
||||||
segments[#segments+1] = segment
|
|
||||||
end
|
|
||||||
return table.unpack(segments)
|
|
||||||
end
|
|
||||||
function imt.getRemainder(s)
|
|
||||||
local function getfirst(n)
|
|
||||||
local ns = s:sub(1,n)
|
|
||||||
s=s:sub(n+1)
|
|
||||||
return ns
|
|
||||||
end
|
|
||||||
local plen = imt.from16bn(getfirst(2))
|
|
||||||
if s:len() > plen then
|
|
||||||
getfirst(plen)
|
|
||||||
return s
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return imt
|
|
0
lib/osdi.lua
Normal file
0
lib/osdi.lua
Normal file
@ -2,7 +2,6 @@ local component = require "component"
|
|||||||
local fs = require "fs"
|
local fs = require "fs"
|
||||||
local shell = require "shell"
|
local shell = require "shell"
|
||||||
local ed = require "ed"
|
local ed = require "ed"
|
||||||
local doc = require "doc"
|
|
||||||
local shutil = {}
|
local shutil = {}
|
||||||
shutil.ed = ed.interactive
|
shutil.ed = ed.interactive
|
||||||
shutil.vi = ed.visual
|
shutil.vi = ed.visual
|
||||||
@ -124,4 +123,42 @@ shutil.mkdir = fs.makeDirectory
|
|||||||
shutil.cp = fs.copy
|
shutil.cp = fs.copy
|
||||||
shutil.rm = fs.remove
|
shutil.rm = fs.remove
|
||||||
|
|
||||||
|
local function find_dir(t, dir)
|
||||||
|
local f = fs.list(dir)
|
||||||
|
for i=1, #f do
|
||||||
|
if (f[i]:sub(#f[i]) == "/") then
|
||||||
|
find_dir(t, dir..f[i])
|
||||||
|
end
|
||||||
|
t[#t+1] = dir..f[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function shutil.find(...)
|
||||||
|
local paths = {...}
|
||||||
|
if not paths[1] then paths = {"."} end
|
||||||
|
for i=1, #paths do
|
||||||
|
if (paths[i]:sub(#paths[i]) ~= "/") then
|
||||||
|
paths[i] = paths[i] .. "/"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local t = {}
|
||||||
|
for i=1, #paths do
|
||||||
|
if fs.isDirectory(paths[i]) then
|
||||||
|
find_dir(t, paths[i])
|
||||||
|
end
|
||||||
|
t[#t+1] = paths[i]
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
function shutil.filter(t, func)
|
||||||
|
local t2 = {}
|
||||||
|
for i=1, #t do
|
||||||
|
if (func(t[i])) then
|
||||||
|
t2[#t2+1] = t[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return t2
|
||||||
|
end
|
||||||
|
|
||||||
return shutil
|
return shutil
|
||||||
|
13
lib/tsar.lua
Normal file
13
lib/tsar.lua
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
local tsar = package.loaded.tsar or {}
|
||||||
|
|
||||||
|
function tsar.extract(fd, path, ...)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function tsar.create(paths, fd)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function tsar.list(fd)
|
||||||
|
|
||||||
|
end
|
14
lib/tsuki.lua
Normal file
14
lib/tsuki.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
local foxfs = require "foxfs"
|
||||||
|
local tsuki = {}
|
||||||
|
|
||||||
|
function tsuki.reset_security_node(path)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function tsuki.reset_dev_permissions(path)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function tsuki.make_security_node(path)
|
||||||
|
|
||||||
|
end
|
7
lib/velx.lua
Normal file
7
lib/velx.lua
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
local velx = package.loaded.velx or {}
|
||||||
|
|
||||||
|
function velx.parse(fd)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return velx
|
BIN
psychos.tsar
BIN
psychos.tsar
Binary file not shown.
@ -1,95 +0,0 @@
|
|||||||
local minitel = require "minitel"
|
|
||||||
local serial = require "serialization"
|
|
||||||
|
|
||||||
local cfg = {["path"]="/boot/srv/frequest",["port"]=70}
|
|
||||||
|
|
||||||
f=io.open("/boot/cfg/fserv.cfg","rb")
|
|
||||||
if f then
|
|
||||||
local ncfg = serial.unserialize(f:read("*a"))
|
|
||||||
f:close()
|
|
||||||
for k,v in pairs(ncfg) do
|
|
||||||
cfg[k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function fileHandler(socket,rtype,path)
|
|
||||||
syslog(string.format("[%s:%d] %s %s",socket.addr,socket.port,rtype,path),syslog.info,"fserv")
|
|
||||||
if rtype == "t" then
|
|
||||||
if fs.exists(path) and fs.isDirectory(path) then
|
|
||||||
socket:write("d")
|
|
||||||
for _,file in ipairs(fs.list(path)) do
|
|
||||||
socket:write(file.."\n")
|
|
||||||
end
|
|
||||||
elseif fs.exists(path) and not fs.isDirectory(path) then
|
|
||||||
local f,err = io.open(path,"rb")
|
|
||||||
if f then
|
|
||||||
socket:write("y")
|
|
||||||
while true do
|
|
||||||
local c = f:read(4096)
|
|
||||||
if not c or c == "" then break end
|
|
||||||
socket:write(c)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
socket:write("fFailed to open file: "..err)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
socket:write("nFile not found")
|
|
||||||
end
|
|
||||||
elseif rtype == "s" then
|
|
||||||
if fs.exists(path) then
|
|
||||||
local ftype = "f"
|
|
||||||
if fs.isDirectory(path) then
|
|
||||||
ftype = "d"
|
|
||||||
end
|
|
||||||
socket:write(string.format("y%s\n%d",ftype,fs.size(path)))
|
|
||||||
else
|
|
||||||
socket:write("nFile not found.")
|
|
||||||
end
|
|
||||||
else
|
|
||||||
socket:write("fUnknown request type")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local function httpHandler(socket,rtype,path)
|
|
||||||
local tPath = fs.segments(path)
|
|
||||||
local proto = table.remove(tPath,1)
|
|
||||||
local url = string.format("%s://%s",proto,table.concat(tPath,"/"))
|
|
||||||
local request = component.invoke(component.list("internet")(),"request",url)
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
until request.finishConnect()
|
|
||||||
local code, message, headers = request.response()
|
|
||||||
if code < 200 or code > 299 then
|
|
||||||
socket:write(string.format("f%d\n%s",code,message))
|
|
||||||
else
|
|
||||||
local data = ""
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
data = request.read()
|
|
||||||
if data then
|
|
||||||
socket:write(data)
|
|
||||||
end
|
|
||||||
until not data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function socketHandler(socket)
|
|
||||||
return function()
|
|
||||||
local line = nil
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
line = socket:read()
|
|
||||||
until line
|
|
||||||
local rtype, path = line:match("(.)(.+)")
|
|
||||||
if fs.segments(path)[1] == "http" or fs.segments(path)[1] == "https" then
|
|
||||||
httpHandler(socket,rtype,path)
|
|
||||||
else
|
|
||||||
path = (cfg.path .. "/" .. path:gsub("../","")):gsub("/+","/")
|
|
||||||
fileHandler(socket,rtype,path)
|
|
||||||
end
|
|
||||||
socket:close()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
while true do
|
|
||||||
os.spawn(socketHandler(minitel.listen(70)),"fserv worker process")
|
|
||||||
end
|
|
@ -1,25 +0,0 @@
|
|||||||
local lastkey = computer.uptime()
|
|
||||||
local state = true
|
|
||||||
local delay = 60
|
|
||||||
function start()
|
|
||||||
return os.spawn(function()
|
|
||||||
while true do
|
|
||||||
tEv = {coroutine.yield()}
|
|
||||||
if tEv[1] == "key_down" then
|
|
||||||
lastkey = computer.uptime()
|
|
||||||
if not state then
|
|
||||||
for addr in component.list("screen") do
|
|
||||||
component.invoke(addr,"turnOn")
|
|
||||||
end
|
|
||||||
state = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if computer.uptime() > lastkey + delay and state then
|
|
||||||
for addr in component.list("screen") do
|
|
||||||
component.invoke(addr,"turnOff")
|
|
||||||
end
|
|
||||||
state = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,"screenblank")
|
|
||||||
end
|
|
@ -1,28 +0,0 @@
|
|||||||
local counter = 0
|
|
||||||
local td = {}
|
|
||||||
local function addNode(addr)
|
|
||||||
devfs.register("tape"..tonumber(counter),function()
|
|
||||||
local tape = component.proxy(addr)
|
|
||||||
tape.seek(-math.huge)
|
|
||||||
return tape.read, tape.write, function() end, tape.seek
|
|
||||||
end)
|
|
||||||
devfs.register("tapen"..tonumber(counter),function()
|
|
||||||
local tape = component.proxy(addr)
|
|
||||||
return tape.read, tape.write, function() end, tape.seek
|
|
||||||
end)
|
|
||||||
td[addr] = counter
|
|
||||||
counter = counter + 1
|
|
||||||
end
|
|
||||||
for addr in component.list("tape_drive") do
|
|
||||||
addNode(addr)
|
|
||||||
end
|
|
||||||
while true do
|
|
||||||
local tE = {coroutine.yield()}
|
|
||||||
if tE[1] == "component_added" and tE[3] == "tape_drive" then
|
|
||||||
addNode(tE[2])
|
|
||||||
elseif tE[1] == "component_removed" and tE[3] == "tape_drive" then
|
|
||||||
if td[tE[2]] then
|
|
||||||
fs.remove("/dev/tape"..tostring(td[tE[2]]))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,63 +0,0 @@
|
|||||||
local minitel = require "minitel"
|
|
||||||
local shell = require "shell"
|
|
||||||
local port = 22
|
|
||||||
|
|
||||||
local function sread(self, len)
|
|
||||||
while true do
|
|
||||||
local d=self.sock:read(len)
|
|
||||||
if d then
|
|
||||||
return d
|
|
||||||
end
|
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local function swrite(self, data)
|
|
||||||
while self.flushing do
|
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
||||||
if data and data:len() > 0 then
|
|
||||||
self.wb = self.wb .. (data or "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local function sclose(self)
|
|
||||||
self.sock:close()
|
|
||||||
end
|
|
||||||
local function sflush(self)
|
|
||||||
self.flushing = true
|
|
||||||
self.sock:write(self.wb)
|
|
||||||
self.wb = ""
|
|
||||||
self.flushing = false
|
|
||||||
end
|
|
||||||
|
|
||||||
function start()
|
|
||||||
return os.spawn(function()
|
|
||||||
local oout = io.output()
|
|
||||||
local pname = os.taskInfo(os.pid()).name
|
|
||||||
while true do
|
|
||||||
local sock = minitel.listen(port)
|
|
||||||
print(string.format("Connection from %s:%d",sock.addr,sock.port))
|
|
||||||
os.spawn(function() _G.worked = {pcall(function()
|
|
||||||
local fh = {}
|
|
||||||
fh.sock = sock
|
|
||||||
fh.read = sread
|
|
||||||
fh.write = swrite
|
|
||||||
fh.close = sclose
|
|
||||||
fh.flush = sflush
|
|
||||||
fh.wb = ""
|
|
||||||
io.input(fh)
|
|
||||||
io.output(fh)
|
|
||||||
print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
|
||||||
local pid = os.spawn(shell.interactive,string.format(pname.." shell [%s:%d]",sock.addr,sock.port))
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
if fh.wb:len() > 0 then
|
|
||||||
fh:flush()
|
|
||||||
end
|
|
||||||
until sock.state ~= "open" or not os.taskInfo(pid)
|
|
||||||
sock:close()
|
|
||||||
os.kill(pid)
|
|
||||||
oout:write(string.format("Session %s:%d ended",sock.addr,sock.port))
|
|
||||||
end)} end,string.format(pname.." [%s:%d]",sock.addr,sock.port))
|
|
||||||
end
|
|
||||||
end,"termsrv")
|
|
||||||
end
|
|
@ -1,162 +0,0 @@
|
|||||||
local vcomponent = require "vcomponent"
|
|
||||||
local serial = require "serialization"
|
|
||||||
local component = require "component"
|
|
||||||
local computer = require "computer"
|
|
||||||
local event = require "event"
|
|
||||||
local imt = require "interminitel"
|
|
||||||
|
|
||||||
local cfg = {}
|
|
||||||
cfg.peers = {}
|
|
||||||
cfg.rtimer = 5
|
|
||||||
cfg.katimer = 30
|
|
||||||
local listeners = {}
|
|
||||||
local proxies = {}
|
|
||||||
|
|
||||||
local function loadcfg()
|
|
||||||
local f = io.open("/boot/cfg/vtunnel.cfg","rb")
|
|
||||||
if not f then return false end
|
|
||||||
for k,v in pairs(serial.unserialize(f:read("*a")) or {}) do
|
|
||||||
cfg[k] = v
|
|
||||||
end
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
local function savecfg()
|
|
||||||
local f = io.open("/boot/cfg/vtunnel.cfg","wb")
|
|
||||||
if not f then
|
|
||||||
print("Warning: unable to save configuration.")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
f:write(serial.serialize(cfg))
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
|
|
||||||
local function createTunnel(host,port,addr,raddr)
|
|
||||||
local proxy = {address=addr,buffer=""}
|
|
||||||
function proxy.connect()
|
|
||||||
if proxy.socket then
|
|
||||||
proxy.socket.close()
|
|
||||||
end
|
|
||||||
proxy.socket = component.invoke(component.list("internet")(),"connect",host,port)
|
|
||||||
local st = computer.uptime()
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
until proxy.socket.finishConnect() or computer.uptime() > st+5
|
|
||||||
end
|
|
||||||
function proxy.send(...)
|
|
||||||
rt = 0
|
|
||||||
while not proxy.socket.write(imt.encodePacket(...)) and rt < 10 do
|
|
||||||
proxy.connect()
|
|
||||||
rt = rt + 1
|
|
||||||
end
|
|
||||||
proxy.last = computer.uptime()
|
|
||||||
end
|
|
||||||
function proxy.read()
|
|
||||||
local rb, r
|
|
||||||
local rt = 0
|
|
||||||
while true do
|
|
||||||
rb,r = proxy.socket.read(4096)
|
|
||||||
if rb or rt > 10 then break end
|
|
||||||
if type(rb) == "nil" then
|
|
||||||
proxy.connect()
|
|
||||||
end
|
|
||||||
rt = rt + 1
|
|
||||||
end
|
|
||||||
proxy.buffer = proxy.buffer .. rb
|
|
||||||
while imt.decodePacket(proxy.buffer) do
|
|
||||||
computer.pushSignal("modem_message",addr,raddr,0,0,imt.decodePacket(proxy.buffer))
|
|
||||||
proxy.buffer = imt.getRemainder(proxy.buffer) or ""
|
|
||||||
end
|
|
||||||
if computer.uptime() > proxy.last + cfg.katimer then
|
|
||||||
proxy.socket.write("\0\1\0")
|
|
||||||
proxy.last = computer.uptime()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function proxy.getWakeMessage()
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
proxy.setWakeMessage = proxy.getWakeMessage
|
|
||||||
function proxy.maxPacketSize()
|
|
||||||
return 8192
|
|
||||||
end
|
|
||||||
function proxy.getChannel()
|
|
||||||
return host..":"..tostring(port)
|
|
||||||
end
|
|
||||||
proxy.connect()
|
|
||||||
proxy.last = computer.uptime()
|
|
||||||
return proxy
|
|
||||||
end
|
|
||||||
|
|
||||||
vt = {}
|
|
||||||
function start()
|
|
||||||
loadcfg()
|
|
||||||
for k,v in pairs(cfg.peers) do
|
|
||||||
print(string.format("Connecting to %s:%d",v.host,v.port))
|
|
||||||
v.addr = v.addr or vcomponent.uuid()
|
|
||||||
v.raddr = v.raddr or vcomponent.uuid()
|
|
||||||
local px = createTunnel(v.host, v.port, v.addr, v.raddr)
|
|
||||||
vcomponent.register(v.addr, "tunnel", px)
|
|
||||||
proxies[v.addr] = px
|
|
||||||
end
|
|
||||||
for k,v in pairs(os.tasks()) do
|
|
||||||
if os.taskInfo(v).name:match("minitel") then
|
|
||||||
os.kill(v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function vt.stop()
|
|
||||||
for k,v in pairs(proxies) do
|
|
||||||
vcomponent.unregister(k)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function vt.listpeers()
|
|
||||||
for k,v in pairs(cfg.peers) do
|
|
||||||
print(string.format("#%d (%s:%d)\n Local address: %s\n Remote address: %s",k,v.host,v.port,v.addr,v.raddr))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function vt.addpeer(host,port)
|
|
||||||
port = tonumber(port) or 4096
|
|
||||||
local t = {}
|
|
||||||
t.host = host
|
|
||||||
t.port = port
|
|
||||||
t.addr = vcomponent.uuid()
|
|
||||||
t.raddr = vcomponent.uuid()
|
|
||||||
cfg.peers[#cfg.peers+1] = t
|
|
||||||
print(string.format("Added peer #%d (%s:%d) to the configuration.\nRestart to apply changes.",#cfg.peers,host,port))
|
|
||||||
savecfg()
|
|
||||||
end
|
|
||||||
function vt.delpeer(n)
|
|
||||||
n=tonumber(n)
|
|
||||||
if not n then
|
|
||||||
print("delpeer requires a number, representing the peer number, as an argument.")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
local dp = table.remove(cfg.peers, n)
|
|
||||||
savecfg()
|
|
||||||
print(string.format("Removed peer %s:%d",dp.host, dp.port))
|
|
||||||
end
|
|
||||||
|
|
||||||
function vt.settimer(time)
|
|
||||||
time = tonumber(time)
|
|
||||||
if not time then
|
|
||||||
print("Timer must be a number.")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
cfg.rtime = time
|
|
||||||
savecfg()
|
|
||||||
end
|
|
||||||
|
|
||||||
vt.start = start
|
|
||||||
_G.libs.vtunnel = vt
|
|
||||||
|
|
||||||
start()
|
|
||||||
local last = computer.uptime()
|
|
||||||
while true do
|
|
||||||
local tE = {coroutine.yield()}
|
|
||||||
if computer.uptime() > last + cfg.rtimer then
|
|
||||||
for k,v in pairs(proxies) do
|
|
||||||
v.read()
|
|
||||||
end
|
|
||||||
last = computer.uptime()
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,18 +0,0 @@
|
|||||||
local delay = 60
|
|
||||||
local port = 3442
|
|
||||||
local message = "WoLBeacon"
|
|
||||||
|
|
||||||
for modem in component.list("modem") do
|
|
||||||
component.invoke(modem,"setWakeMessage",message)
|
|
||||||
end
|
|
||||||
|
|
||||||
local ltime = computer.uptime()
|
|
||||||
while true do
|
|
||||||
if computer.uptime() > ltime+delay then
|
|
||||||
for modem in component.list("modem") do
|
|
||||||
component.invoke(modem,"broadcast",port,message)
|
|
||||||
end
|
|
||||||
ltime=computer.uptime()
|
|
||||||
end
|
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
Loading…
Reference in New Issue
Block a user