Compare commits
2 Commits
ab604c84f7
...
8920c074c4
Author | SHA1 | Date | |
---|---|---|---|
8920c074c4 | |||
201aa20c5a |
2
build.sh
2
build.sh
@ -3,7 +3,7 @@ rm -r target/*
|
|||||||
mkdir target &>/dev/null
|
mkdir target &>/dev/null
|
||||||
mkdir target/cfg
|
mkdir target/cfg
|
||||||
lua luapreproc.lua module/init.lua target/init.lua
|
lua luapreproc.lua module/init.lua target/init.lua
|
||||||
echo _OSVERSION=\"PsychOS 2.0a1-$(git rev-parse --short HEAD)\" > target/version.lua
|
echo _OSVERSION=\"PsychOS 2.0a2-$(git rev-parse --short HEAD)\" > target/version.lua
|
||||||
cat target/version.lua target/init.lua > target/tinit.lua
|
cat target/version.lua target/init.lua > target/tinit.lua
|
||||||
mv target/tinit.lua target/init.lua
|
mv target/tinit.lua target/init.lua
|
||||||
cp -r exec/ service/ lib/ target/
|
cp -r exec/ service/ lib/ target/
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
local tA = {...}
|
|
||||||
for _,fn in ipairs(tA) do
|
|
||||||
local f = io.open(fn,"rb")
|
|
||||||
io.write(f:read("*a"))
|
|
||||||
f:close()
|
|
||||||
end
|
|
23
exec/df.lua
23
exec/df.lua
@ -1,23 +0,0 @@
|
|||||||
local mt = fs.mounts()
|
|
||||||
local ml = 0
|
|
||||||
for k,v in pairs(mt) do
|
|
||||||
if v:len() > ml then
|
|
||||||
ml = v:len()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local scale = {"K","M","G","T","P"}
|
|
||||||
local function wrapUnits(n)
|
|
||||||
local count = 0
|
|
||||||
while n > 1024 do
|
|
||||||
count = count + 1
|
|
||||||
if not scale[count] then return "inf" end
|
|
||||||
n = n / 1024
|
|
||||||
end
|
|
||||||
return tostring(math.floor(n))..(scale[count] or "")
|
|
||||||
end
|
|
||||||
local fstr = "%-"..tostring(ml).."s %5s %5s"
|
|
||||||
print("fs"..(" "):rep(ml-2).." size used")
|
|
||||||
for k,v in pairs(mt) do
|
|
||||||
local st, su = fs.spaceTotal(v), fs.spaceUsed(v)
|
|
||||||
print(string.format(fstr,v,wrapUnits(st),wrapUnits(su)))
|
|
||||||
end
|
|
129
exec/ed.lua
129
exec/ed.lua
@ -1,129 +0,0 @@
|
|||||||
local tA = {...}
|
|
||||||
local ft, p, fp, ct, il, it, c, C = {}, 1, fp or tA[1] or "", {}, "", {}, "", C -- file table, pointer, filename, command table, input line, input table, command, content
|
|
||||||
function ct.readfile(fp,rp)
|
|
||||||
if not fp then return end
|
|
||||||
if not rp then ft = {} end
|
|
||||||
local f=io.open(fp,"rb")
|
|
||||||
if f then
|
|
||||||
C=f:read("*a")
|
|
||||||
f:close()
|
|
||||||
for l in C:gmatch("[^\n]+") do
|
|
||||||
ft[#ft+1] = l
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ct.writefile(nfp)
|
|
||||||
if not nfp then nfp = fp end
|
|
||||||
print(nfp)
|
|
||||||
f=io.open(nfp,"wb")
|
|
||||||
if f then
|
|
||||||
for k,v in ipairs(ft) do
|
|
||||||
print(v)
|
|
||||||
f:write(v.."\n")
|
|
||||||
end
|
|
||||||
coroutine.yield()
|
|
||||||
f:close()
|
|
||||||
coroutine.yield()
|
|
||||||
print(f.b)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ct.list(s,e)
|
|
||||||
s,e = s or 1, e or #ft
|
|
||||||
for i = s,e do
|
|
||||||
if ft[i] then
|
|
||||||
print(string.format("%4d\t %s",i,ft[i]))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ct.sp(np)
|
|
||||||
np=tonumber(np)
|
|
||||||
if np then
|
|
||||||
if np > #ft then
|
|
||||||
np = #ft
|
|
||||||
elseif np < 1 then
|
|
||||||
np = 0
|
|
||||||
end
|
|
||||||
p=np
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ct.pointer(np)
|
|
||||||
ct.sp(np)
|
|
||||||
print(string.format("%4d\t %s",p,ft[p]))
|
|
||||||
end
|
|
||||||
function ct.insert(np)
|
|
||||||
ct.sp(np)
|
|
||||||
while true do
|
|
||||||
io.write(string.format("%4d\t ",p))
|
|
||||||
local l=io.read()
|
|
||||||
if l == "." then break end
|
|
||||||
table.insert(ft,p,l)
|
|
||||||
p=p+1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ct.append(np)
|
|
||||||
ct.sp(np)
|
|
||||||
p=p+1
|
|
||||||
if #ft < 1 then p = 1 end
|
|
||||||
ct.insert()
|
|
||||||
end
|
|
||||||
function ct.delete(np,n)
|
|
||||||
ct.sp(np)
|
|
||||||
_G.clip = ""
|
|
||||||
for i = 1, (n or 1) do
|
|
||||||
_G.clip = _G.clip .. table.remove(ft,p) .. "\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ct.substitute(np,n)
|
|
||||||
ct.delete(np,n)
|
|
||||||
ct.insert(np)
|
|
||||||
end
|
|
||||||
function ct.filename(np)
|
|
||||||
if np then fp = np end
|
|
||||||
print(fp)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function rawpaste()
|
|
||||||
for line in string.gmatch(_G.clip,"[^\n]") do
|
|
||||||
print(string.format("%4d\t %s",p,line))
|
|
||||||
table.insert(ft,p,line)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ct.pasteprevious(np)
|
|
||||||
ct.sp(np)
|
|
||||||
rawpaste()
|
|
||||||
end
|
|
||||||
function ct.paste(np)
|
|
||||||
ct.sp(np)
|
|
||||||
p = p + 1
|
|
||||||
rawpaste()
|
|
||||||
end
|
|
||||||
|
|
||||||
ct.o = ct.readfile
|
|
||||||
ct.w = ct.writefile
|
|
||||||
ct.l = ct.list
|
|
||||||
ct.p = ct.pointer
|
|
||||||
ct.i = ct.insert
|
|
||||||
ct.a = ct.append
|
|
||||||
ct.s = ct.substitute
|
|
||||||
ct.d = ct.delete
|
|
||||||
ct.f = ct.filename
|
|
||||||
ct.PP = ct.pasteprevious
|
|
||||||
ct.P = ct.paste
|
|
||||||
|
|
||||||
ct.readfile(fp)
|
|
||||||
|
|
||||||
while true do
|
|
||||||
io.write("skex2> ")
|
|
||||||
il,it=io.read(),{}
|
|
||||||
for w in il:gmatch("%S+") do
|
|
||||||
it[#it+1] = w
|
|
||||||
end
|
|
||||||
c=table.remove(it,1)
|
|
||||||
if c == "quit" or c == "q" then
|
|
||||||
break
|
|
||||||
elseif c:sub(1,1) == "!" then
|
|
||||||
print(pcall(load(c:sub(2))))
|
|
||||||
elseif ct[c] ~= nil then
|
|
||||||
ct[c](table.unpack(it))
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,11 +0,0 @@
|
|||||||
local rpcs = require "rpc"
|
|
||||||
local ufs = require "unionfs"
|
|
||||||
|
|
||||||
local tA = {...}
|
|
||||||
local path = "/"..table.concat(fs.segments(tA[1]),"/")
|
|
||||||
|
|
||||||
local px = ufs.create(path)
|
|
||||||
for k,v in pairs(px) do
|
|
||||||
rpcs.register(path.."_"..k,v)
|
|
||||||
print(path.."_"..k)
|
|
||||||
end
|
|
@ -1,40 +0,0 @@
|
|||||||
local minitel = require "minitel"
|
|
||||||
|
|
||||||
local tA = {...}
|
|
||||||
|
|
||||||
local function parseURL(url)
|
|
||||||
local proto,addr = url:match("(.-)://(.+)")
|
|
||||||
addr = addr or url
|
|
||||||
local hp, path = addr:match("(.-)(/.*)")
|
|
||||||
hp, path = hp or addr, path or "/"
|
|
||||||
local host, port = hp:match("(.+):(.+)")
|
|
||||||
host = host or hp
|
|
||||||
return proto, host, port, path
|
|
||||||
end
|
|
||||||
|
|
||||||
local proto, host, port, path = parseURL(tA[1])
|
|
||||||
proto,port = proto or "fget", port or 70
|
|
||||||
local fname, rtype = tA[2] or "-", tA[3] or "t"
|
|
||||||
|
|
||||||
local sock = minitel.open(host,port)
|
|
||||||
local f = nil
|
|
||||||
if fname ~= "-" then
|
|
||||||
f = io.open(fname,"w")
|
|
||||||
if not f then error("couldn't open file for writing") end
|
|
||||||
else
|
|
||||||
f = io.open(os.getenv("t"))
|
|
||||||
f.close = function() end
|
|
||||||
end
|
|
||||||
if not sock then error("couldn't open connection to host") end
|
|
||||||
sock:write(string.format("%s%s\n",rtype,path))
|
|
||||||
local rtype, buf = "", ""
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
rtype = sock:read(1)
|
|
||||||
until rtype ~= ""
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
buf = sock:read("*a")
|
|
||||||
f:write(buf)
|
|
||||||
until sock.state == "closed" and buf == ""
|
|
||||||
f:close()
|
|
@ -1,2 +0,0 @@
|
|||||||
print("Total Used Free")
|
|
||||||
print(string.format("%4iK %4iK %4iK",math.floor(computer.totalMemory()/1024),math.floor((computer.totalMemory()-computer.freeMemory())/1024),math.floor(computer.freeMemory()/1024)))
|
|
@ -1,9 +0,0 @@
|
|||||||
local rpc = require "rpc"
|
|
||||||
local tA = {...}
|
|
||||||
local host, rpath, lpath = tA[1], tA[2], tA[3]
|
|
||||||
|
|
||||||
local px = rpc.proxy(host,rpath.."_")
|
|
||||||
function px.getLabel()
|
|
||||||
return host..":"..rpath
|
|
||||||
end
|
|
||||||
fs.mount(lpath,px)
|
|
@ -1,33 +0,0 @@
|
|||||||
if os.taskInfo(1) and os.pid() ~= 1 then
|
|
||||||
return false, "init already started"
|
|
||||||
end
|
|
||||||
os.setenv("PWD","/boot")
|
|
||||||
io.input("/dev/null")
|
|
||||||
io.output("/dev/syslog")
|
|
||||||
local f = io.open("/boot/cfg/hostname","rb")
|
|
||||||
local hostname = computer.address():sub(1,8)
|
|
||||||
if f then
|
|
||||||
hostname = f:read("*l")
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
os.setenv("HOSTNAME",hostname)
|
|
||||||
syslog(string.format("Hostname set to %s",hostname))
|
|
||||||
local pids = {}
|
|
||||||
local function loadlist()
|
|
||||||
local f = io.open("/boot/cfg/init.txt","rb")
|
|
||||||
if not f then return false end
|
|
||||||
for line in f:read("*a"):gmatch("[^\r\n]+") do
|
|
||||||
pids[line] = -1
|
|
||||||
end
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
loadlist()
|
|
||||||
while true do
|
|
||||||
for k,v in pairs(pids) do
|
|
||||||
if not os.taskInfo(v) then
|
|
||||||
syslog("Starting service "..k)
|
|
||||||
pids[k] = os.spawnfile("/boot/service/"..k)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
10
exec/ls.lua
10
exec/ls.lua
@ -1,10 +0,0 @@
|
|||||||
local tA = {...}
|
|
||||||
tA[1] = tA[1] or "."
|
|
||||||
for _,d in ipairs(tA) do
|
|
||||||
if #tA > 1 then
|
|
||||||
print(d..":")
|
|
||||||
end
|
|
||||||
for _,f in ipairs(fs.list(d)) do
|
|
||||||
print(" "..f)
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,44 +0,0 @@
|
|||||||
local tArgs = {...}
|
|
||||||
local output = table.remove(tArgs,#tArgs)
|
|
||||||
local of = io.open(output,"wb")
|
|
||||||
local files, dirs = {}, {tArgs[1] or "."}
|
|
||||||
|
|
||||||
local function cint(n,l)
|
|
||||||
local t={}
|
|
||||||
for i = 0, 7 do
|
|
||||||
t[i+1] = (n >> (i * 8)) & 0xFF
|
|
||||||
end
|
|
||||||
return string.reverse(string.char(table.unpack(t)):sub(1,l))
|
|
||||||
end
|
|
||||||
|
|
||||||
local function genHeader(fname,len)
|
|
||||||
return string.format("%s%s%s",cint(fname:len(),2),fname,cint(len,2))
|
|
||||||
end
|
|
||||||
|
|
||||||
for k,v in pairs(dirs) do
|
|
||||||
local dir = fs.list(v)
|
|
||||||
for _,file in ipairs(dir) do
|
|
||||||
if fs.isDirectory(file) then
|
|
||||||
dirs[#dirs+1] = v.."/"..file
|
|
||||||
else
|
|
||||||
files[#files+1] = v.."/"..file
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for k,v in ipairs(files) do
|
|
||||||
io.write(v)
|
|
||||||
local f = io.open(v,"rb")
|
|
||||||
if f then
|
|
||||||
of:write(genHeader(v,fs.size(v)))
|
|
||||||
while true do
|
|
||||||
local c = f:read(1024)
|
|
||||||
if not c or c == "" then break end
|
|
||||||
of:write(c)
|
|
||||||
end
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
print("... done")
|
|
||||||
end
|
|
||||||
of:write(string.char(0):rep(2))
|
|
||||||
of:close()
|
|
@ -1,24 +0,0 @@
|
|||||||
local tA = {...}
|
|
||||||
if #tA < 1 then
|
|
||||||
local mt = fs.mounts()
|
|
||||||
for k,v in pairs(mt) do
|
|
||||||
print(tostring(fs.address(v)).." on "..tostring(v).." type "..fs.type(v))
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local addr,path = tA[1],tA[2]
|
|
||||||
local fscomp = component.list("filesystem")
|
|
||||||
if not fscomp[addr] then
|
|
||||||
for k,v in pairs(fscomp) do
|
|
||||||
if k:find(addr) then
|
|
||||||
print(tostring(addr).." not found, assuming you meant "..k)
|
|
||||||
addr = k
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local proxy = component.proxy(addr)
|
|
||||||
if not proxy then
|
|
||||||
return false, "no such filesystem component"
|
|
||||||
end
|
|
||||||
print(fs.mount(path,proxy))
|
|
||||||
end
|
|
23
exec/nc.lua
23
exec/nc.lua
@ -1,23 +0,0 @@
|
|||||||
local minitel = require "minitel"
|
|
||||||
local tA = {...}
|
|
||||||
|
|
||||||
host, port = tA[1], tA[2] or 22
|
|
||||||
|
|
||||||
local socket = minitel.open(host,port)
|
|
||||||
if not socket then return false end
|
|
||||||
local b = ""
|
|
||||||
os.spawn(function()
|
|
||||||
repeat
|
|
||||||
local b = socket:read("*a")
|
|
||||||
if b and b:len() > 0 then
|
|
||||||
io.write(b)
|
|
||||||
end
|
|
||||||
coroutine.yield()
|
|
||||||
until socket.state ~= "open"
|
|
||||||
end)
|
|
||||||
repeat
|
|
||||||
local b = io.read()
|
|
||||||
if b and b:len() > 0 then
|
|
||||||
socket:write(b.."\n")
|
|
||||||
end
|
|
||||||
until socket.state ~= "open"
|
|
@ -1,17 +0,0 @@
|
|||||||
local minitel = require "minitel"
|
|
||||||
local event = require "event"
|
|
||||||
local tArgs = {...}
|
|
||||||
local addr = tArgs[1]
|
|
||||||
local times = tonumber(tArgs[2]) or 5
|
|
||||||
local timeout = tonumber(tArgs[3]) or 30
|
|
||||||
for i = 1, times do
|
|
||||||
local ipt = computer.uptime()
|
|
||||||
local pid = minitel.genPacketID()
|
|
||||||
computer.pushSignal("net_send",1,addr,0,"ping",pid)
|
|
||||||
local t,a = event.pull(timeout,"net_ack")
|
|
||||||
if t == "net_ack" and a == pid then
|
|
||||||
print("Ping reply: "..tostring(computer.uptime()-ipt).." seconds.")
|
|
||||||
else
|
|
||||||
print("Timed out.")
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,5 +0,0 @@
|
|||||||
print("PID# Parent | Name")
|
|
||||||
for k,v in pairs(os.tasks()) do
|
|
||||||
local t = os.taskInfo(v)
|
|
||||||
print(string.format("%4d %4d | %s",v,t.parent,t.name))
|
|
||||||
end
|
|
@ -1,57 +0,0 @@
|
|||||||
local serial = require "serialization"
|
|
||||||
local event = require "event"
|
|
||||||
print(pcall(function()
|
|
||||||
local shenv = {}
|
|
||||||
function shenv.quit()
|
|
||||||
os.setenv("run",nil)
|
|
||||||
end
|
|
||||||
shenv.cd = os.chdir
|
|
||||||
shenv.mkdir = fs.makeDirectory
|
|
||||||
shenv.cp = fs.copy
|
|
||||||
local function findPath(name)
|
|
||||||
path = os.getenv("PATH") or "/boot/exec"
|
|
||||||
for l in path:gmatch("[^\n]+") do
|
|
||||||
if fs.exists(l.."/"..name) then
|
|
||||||
return l.."/"..name
|
|
||||||
elseif fs.exists(l.."/"..name..".lua") then
|
|
||||||
return l.."/"..name..".lua"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
setmetatable(shenv,{__index=function(_,k)
|
|
||||||
local fp = findPath(k)
|
|
||||||
if _G[k] then
|
|
||||||
return _G[k]
|
|
||||||
elseif _G.libs[k] then
|
|
||||||
return _G.libs[k]
|
|
||||||
elseif fp then
|
|
||||||
return function(...)
|
|
||||||
local tA = {...}
|
|
||||||
local pid = os.spawnfile(fp,fp,table.unpack(tA))
|
|
||||||
local tE = {event.pull("process_finished",pid)}
|
|
||||||
if tE[1] == true then
|
|
||||||
table.remove(tE,1)
|
|
||||||
end
|
|
||||||
return table.unpack(tE)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end})
|
|
||||||
print(_VERSION)
|
|
||||||
os.setenv("run",true)
|
|
||||||
while os.getenv("run") do
|
|
||||||
io.write(string.format("%s:%s> ",os.getenv("HOSTNAME") or "localhost",(os.getenv("PWD") or _VERSION)))
|
|
||||||
local input=io.read()
|
|
||||||
if input:sub(1,1) == "=" then
|
|
||||||
input = "return "..input:sub(2)
|
|
||||||
end
|
|
||||||
tResult = {pcall(load(input,"shell","t",shenv))}
|
|
||||||
if tResult[1] == true then table.remove(tResult,1) end
|
|
||||||
for k,v in pairs(tResult) do
|
|
||||||
if type(v) == "table" then
|
|
||||||
print(serial.serialize(v,true))
|
|
||||||
else
|
|
||||||
print(v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end))
|
|
@ -1,52 +0,0 @@
|
|||||||
local tArgs = {...}
|
|
||||||
|
|
||||||
local function toint(s)
|
|
||||||
s=s or ""
|
|
||||||
local n = 0
|
|
||||||
local i = 1
|
|
||||||
while true do
|
|
||||||
local p = s:sub(i,i)
|
|
||||||
if p == "" then break end
|
|
||||||
local b = string.byte(p)
|
|
||||||
n = n << 8
|
|
||||||
n = n | b
|
|
||||||
i=i+1
|
|
||||||
end
|
|
||||||
return n
|
|
||||||
end
|
|
||||||
|
|
||||||
local fi = io.open(tArgs[1])
|
|
||||||
while true do
|
|
||||||
local nlen = toint(fi:read(2))
|
|
||||||
if nlen == 0 then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
local name = fi:read(nlen)
|
|
||||||
local fsize = toint(fi:read(2))
|
|
||||||
io.write(string.format("%s: %d... ",name,fsize))
|
|
||||||
if not tArgs[2] then
|
|
||||||
local dir = name:match("(.+)/.*%.?.+")
|
|
||||||
if (dir) then
|
|
||||||
fs.makeDirectory(dir)
|
|
||||||
end
|
|
||||||
local f = io.open(name,"wb")
|
|
||||||
local rsize,buf = fsize, ""
|
|
||||||
if f then
|
|
||||||
repeat
|
|
||||||
buf = fi:read(math.min(rsize,1024))
|
|
||||||
f:write(buf)
|
|
||||||
rsize = rsize - buf:len()
|
|
||||||
until rsize <= 1
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local rsize = fsize
|
|
||||||
repeat
|
|
||||||
buf = fi:read(math.min(rsize,1024))
|
|
||||||
rsize = rsize - buf:len()
|
|
||||||
until rsize <= 1
|
|
||||||
end
|
|
||||||
print(fsize)
|
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
||||||
fi:close()
|
|
@ -1,20 +0,0 @@
|
|||||||
local tA = {...}
|
|
||||||
local url = tA[1]
|
|
||||||
local path = tA[2]
|
|
||||||
local R=component.invoke(component.list("internet")(),"request",url)
|
|
||||||
if not R then return false end
|
|
||||||
local f=io.open(path,"wb")
|
|
||||||
if not f then return false end
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
until R.finishConnect()
|
|
||||||
local code, message, headers = R.response()
|
|
||||||
if code > 299 or code < 200 then
|
|
||||||
return false, code, message
|
|
||||||
end
|
|
||||||
repeat
|
|
||||||
coroutine.yield()
|
|
||||||
ns = R.read(2048)
|
|
||||||
f:write(ns or "")
|
|
||||||
until not ns
|
|
||||||
f:close()
|
|
38
lib/netutil.lua
Normal file
38
lib/netutil.lua
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
local computer = require "computer"
|
||||||
|
local minitel = require "minitel"
|
||||||
|
local rpc = require "rpc"
|
||||||
|
local netutil = {}
|
||||||
|
|
||||||
|
function netutil.importfs(host,rpath,lpath)
|
||||||
|
local px = rpc.proxy(host,rpath.."_")
|
||||||
|
function px.getLabel()
|
||||||
|
return host..":"..rpath
|
||||||
|
end
|
||||||
|
fs.mount(lpath,px)
|
||||||
|
end
|
||||||
|
|
||||||
|
function netutil.exportfs(path)
|
||||||
|
local path = "/"..table.concat(fs.segments(path),"/")
|
||||||
|
local px = ufs.create(path)
|
||||||
|
for k,v in pairs(px) do
|
||||||
|
rpcs.register(path.."_"..k,v)
|
||||||
|
print(path.."_"..k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ping(addr,times,timeout)
|
||||||
|
local times, timeout = times or 5, timeout or 30
|
||||||
|
for i = 1, times do
|
||||||
|
local ipt = computer.uptime()
|
||||||
|
local pid = minitel.genPacketID()
|
||||||
|
computer.pushSignal("net_send",1,addr,0,"ping",pid)
|
||||||
|
local t,a = event.pull(timeout,"net_ack")
|
||||||
|
if t == "net_ack" and a == pid then
|
||||||
|
print("Ping reply: "..tostring(computer.uptime()-ipt).." seconds.")
|
||||||
|
else
|
||||||
|
print("Timed out.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return netutil
|
34
lib/shell.lua
Normal file
34
lib/shell.lua
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
local shell = {}
|
||||||
|
shell.include = {"shutil"}
|
||||||
|
local function shindex(self,k)
|
||||||
|
if rawget(self,k) then return rawget(self,k) end
|
||||||
|
for _,v in pairs(os.getenv("INCLUDE") or shell.include) do
|
||||||
|
if require(v)[k] then return require(v)[k] end
|
||||||
|
end
|
||||||
|
if package.loaded[k] then return package.loaded[k] end
|
||||||
|
return _G[k]
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.interactive()
|
||||||
|
local shenv = setmetatable({}, {__index=shindex})
|
||||||
|
local run = true
|
||||||
|
while run do
|
||||||
|
io.write(string.format("%s:%s> ",os.getenv("HOSTNAME") or "localhost",(os.getenv("PWD") or _VERSION)))
|
||||||
|
local input = io.read()
|
||||||
|
if input:sub(1,1) == "=" then
|
||||||
|
input = "return "..input:sub(2)
|
||||||
|
end
|
||||||
|
local f, r = load(input, "shell", "t", shenv)
|
||||||
|
if not f then
|
||||||
|
print(r)
|
||||||
|
else
|
||||||
|
local rt = {pcall(f)}
|
||||||
|
local rs = table.remove(rt,1)
|
||||||
|
for k,v in pairs(rt) do
|
||||||
|
print(tostring(v))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return shell
|
101
lib/shutil.lua
Normal file
101
lib/shutil.lua
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
local component = require "component"
|
||||||
|
local fs = require "fs"
|
||||||
|
local shell = require "shell"
|
||||||
|
local shutil = {}
|
||||||
|
|
||||||
|
function shutil.import(lib)
|
||||||
|
local cE = os.getenv("INCLUDE") or shell.include
|
||||||
|
local nE = {}
|
||||||
|
for k,v in pairs(cE) do
|
||||||
|
nE[#nE+1] = v
|
||||||
|
end
|
||||||
|
require(lib)
|
||||||
|
nE[#nE+1] = lib
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function shutil.ls(...)
|
||||||
|
local tA = {...}
|
||||||
|
if not tA[1] then tA[1] = "." end
|
||||||
|
for _,d in ipairs(tA) do
|
||||||
|
if #tA > 1 then
|
||||||
|
print(d..":")
|
||||||
|
end
|
||||||
|
for _,f in ipairs(fs.list(d)) do
|
||||||
|
print(" "..f)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function shutil.cat(...)
|
||||||
|
for _,fn in ipairs({...}) do
|
||||||
|
local f = io.open(fn,"rb")
|
||||||
|
io.write(f:read("*a"))
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function shutil.ps()
|
||||||
|
print("PID# Parent | Name")
|
||||||
|
for k,v in pairs(os.tasks()) do
|
||||||
|
local t = os.taskInfo(v)
|
||||||
|
print(string.format("%4d %4d | %s",v,t.parent,t.name))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function shutil.df()
|
||||||
|
local mt = fs.mounts()
|
||||||
|
local ml = 0
|
||||||
|
for k,v in pairs(mt) do
|
||||||
|
if v:len() > ml then
|
||||||
|
ml = v:len()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local scale = {"K","M","G","T","P"}
|
||||||
|
local function wrapUnits(n)
|
||||||
|
local count = 0
|
||||||
|
while n > 1024 do
|
||||||
|
count = count + 1
|
||||||
|
if not scale[count] then return "inf" end
|
||||||
|
n = n / 1024
|
||||||
|
end
|
||||||
|
return tostring(math.floor(n))..(scale[count] or "")
|
||||||
|
end
|
||||||
|
local fstr = "%-"..tostring(ml).."s %5s %5s"
|
||||||
|
print("fs"..(" "):rep(ml-2).." size used")
|
||||||
|
for k,v in pairs(mt) do
|
||||||
|
local st, su = fs.spaceTotal(v), fs.spaceUsed(v)
|
||||||
|
print(string.format(fstr,v,wrapUnits(st),wrapUnits(su)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function shutil.mount(addr,path)
|
||||||
|
if not addr then
|
||||||
|
local mt = fs.mounts()
|
||||||
|
for k,v in pairs(mt) do
|
||||||
|
print(tostring(fs.address(v)).." on "..tostring(v).." type "..fs.type(v))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local fscomp = component.list("filesystem")
|
||||||
|
if not fscomp[addr] then
|
||||||
|
for k,v in pairs(fscomp) do
|
||||||
|
if k:find(addr) then
|
||||||
|
print(tostring(addr).." not found, assuming you meant "..k)
|
||||||
|
addr = k
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local proxy = component.proxy(addr)
|
||||||
|
if not proxy then
|
||||||
|
return false, "no such filesystem component"
|
||||||
|
end
|
||||||
|
print(fs.mount(path,proxy))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
shutil.cd = os.chdir
|
||||||
|
shutil.mkdir = fs.makeDirectory
|
||||||
|
shutil.cp = fs.copy
|
||||||
|
|
||||||
|
return shutil
|
429
module/buffer.lua
Normal file
429
module/buffer.lua
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
-- shamelessly stolen from plan9k
|
||||||
|
|
||||||
|
buffer = {}
|
||||||
|
|
||||||
|
function buffer.new(mode, stream)
|
||||||
|
local result = {
|
||||||
|
mode = {},
|
||||||
|
stream = stream,
|
||||||
|
bufferRead = "",
|
||||||
|
bufferWrite = "",
|
||||||
|
bufferSize = math.max(512, math.min(8 * 1024, computer.freeMemory() / 8)),
|
||||||
|
bufferMode = "full",
|
||||||
|
readTimeout = math.huge
|
||||||
|
}
|
||||||
|
mode = mode or "r"
|
||||||
|
for i = 1, unicode.len(mode) do
|
||||||
|
result.mode[unicode.sub(mode, i, i)] = true
|
||||||
|
end
|
||||||
|
local metatable = {
|
||||||
|
__index = buffer,
|
||||||
|
__metatable = "file"
|
||||||
|
}
|
||||||
|
return setmetatable(result, metatable)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function badFileDescriptor()
|
||||||
|
return nil, "bad file descriptor"
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:close()
|
||||||
|
if self.mode.w or self.mode.a then
|
||||||
|
self:flush()
|
||||||
|
end
|
||||||
|
self.closed = true
|
||||||
|
return self.stream:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:flush()
|
||||||
|
local result, reason = self.stream:write(self.bufferWrite)
|
||||||
|
if result then
|
||||||
|
self.bufferWrite = ""
|
||||||
|
else
|
||||||
|
if reason then
|
||||||
|
return nil, reason
|
||||||
|
else
|
||||||
|
return nil, "bad file descriptor"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:lines(...)
|
||||||
|
local args = table.pack(...)
|
||||||
|
return function()
|
||||||
|
local result = table.pack(self:read(table.unpack(args, 1, args.n)))
|
||||||
|
if not result[1] and result[2] then
|
||||||
|
error(result[2])
|
||||||
|
end
|
||||||
|
return table.unpack(result, 1, result.n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:read(...)
|
||||||
|
local timeout = computer.uptime() + self.readTimeout
|
||||||
|
|
||||||
|
local function readChunk()
|
||||||
|
if computer.uptime() > timeout then
|
||||||
|
error("timeout")
|
||||||
|
end
|
||||||
|
local result, reason = self.stream:read(self.bufferSize)
|
||||||
|
if result then
|
||||||
|
self.bufferRead = self.bufferRead .. result
|
||||||
|
return self
|
||||||
|
else -- error or eof
|
||||||
|
return nil, reason
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readBytesOrChars(n)
|
||||||
|
n = math.max(n, 0)
|
||||||
|
local len, sub
|
||||||
|
if self.mode.b then
|
||||||
|
len = rawlen
|
||||||
|
sub = string.sub
|
||||||
|
else
|
||||||
|
len = unicode.len
|
||||||
|
sub = unicode.sub
|
||||||
|
end
|
||||||
|
local buffer = ""
|
||||||
|
repeat
|
||||||
|
if len(self.bufferRead) == 0 then
|
||||||
|
local result, reason = readChunk()
|
||||||
|
if not result then
|
||||||
|
if reason then
|
||||||
|
return nil, reason
|
||||||
|
else -- eof
|
||||||
|
return #buffer > 0 and buffer or nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local left = n - len(buffer)
|
||||||
|
buffer = buffer .. sub(self.bufferRead, 1, left)
|
||||||
|
self.bufferRead = sub(self.bufferRead, left + 1)
|
||||||
|
until len(buffer) == n
|
||||||
|
|
||||||
|
--kernel.io.println("buffer read: "..tostring(buffer))
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readNumber()
|
||||||
|
local len, sub
|
||||||
|
if self.mode.b then
|
||||||
|
len = rawlen
|
||||||
|
sub = string.sub
|
||||||
|
else
|
||||||
|
len = unicode.len
|
||||||
|
sub = unicode.sub
|
||||||
|
end
|
||||||
|
local buffer = ""
|
||||||
|
local first = true
|
||||||
|
local decimal = false
|
||||||
|
local last = false
|
||||||
|
local hex = false
|
||||||
|
local pat = "^[0-9]+"
|
||||||
|
local minbuf = 3 -- "+0x" (sign + hexadecimal tag)
|
||||||
|
-- this function is used to read trailing numbers (1e2, 0x1p2, etc)
|
||||||
|
local function readnum(checksign)
|
||||||
|
local _buffer = ""
|
||||||
|
local sign = ""
|
||||||
|
while true do
|
||||||
|
if len(self.bufferRead) == 0 then
|
||||||
|
local result, reason = readChunk()
|
||||||
|
if not result then
|
||||||
|
if reason then
|
||||||
|
return nil, reason
|
||||||
|
else -- eof
|
||||||
|
return #_buffer > 0 and (sign .. _buffer) or nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if checksign then
|
||||||
|
local _sign = sub(self.bufferRead, 1, 1)
|
||||||
|
if _sign == "+" or _sign == "-" then
|
||||||
|
-- "eat" the sign (Rio Lua behaviour)
|
||||||
|
sign = sub(self.bufferRead, 1, 1)
|
||||||
|
self.bufferRead = sub(self.bufferRead, 2)
|
||||||
|
end
|
||||||
|
checksign = false
|
||||||
|
else
|
||||||
|
local x,y = string.find(self.bufferRead, pat)
|
||||||
|
if not x then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
_buffer = _buffer .. sub(self.bufferRead, 1, y)
|
||||||
|
self.bufferRead = sub(self.bufferRead, y + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return #_buffer > 0 and (sign .. _buffer) or nil
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
if len(self.bufferRead) == 0 or len(self.bufferRead) < minbuf then
|
||||||
|
local result, reason = readChunk()
|
||||||
|
if not result then
|
||||||
|
if reason then
|
||||||
|
return nil, reason
|
||||||
|
else -- eof
|
||||||
|
return #buffer > 0 and tonumber(buffer) or nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- these ifs are here so we run the buffer check above
|
||||||
|
if first then
|
||||||
|
local sign = sub(self.bufferRead, 1, 1)
|
||||||
|
if sign == "+" or sign == "-" then
|
||||||
|
-- "eat" the sign (Rio Lua behaviour)
|
||||||
|
buffer = buffer .. sub(self.bufferRead, 1, 1)
|
||||||
|
self.bufferRead = sub(self.bufferRead, 2)
|
||||||
|
end
|
||||||
|
local hextag = sub(self.bufferRead, 1, 2)
|
||||||
|
if hextag == "0x" or hextag == "0X" then
|
||||||
|
pat = "^[0-9A-Fa-f]+"
|
||||||
|
-- "eat" the 0x, see https://gist.github.com/SoniEx2/570a363d81b743353151
|
||||||
|
buffer = buffer .. sub(self.bufferRead, 1, 2)
|
||||||
|
self.bufferRead = sub(self.bufferRead, 3)
|
||||||
|
hex = true
|
||||||
|
end
|
||||||
|
minbuf = 0
|
||||||
|
first = false
|
||||||
|
elseif decimal then
|
||||||
|
local sep = sub(self.bufferRead, 1, 1)
|
||||||
|
if sep == "." then
|
||||||
|
buffer = buffer .. sep
|
||||||
|
self.bufferRead = sub(self.bufferRead, 2)
|
||||||
|
local temp = readnum(false) -- no sign
|
||||||
|
if temp then
|
||||||
|
buffer = buffer .. temp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not tonumber(buffer) then break end
|
||||||
|
decimal = false
|
||||||
|
last = true
|
||||||
|
minbuf = 1
|
||||||
|
elseif last then
|
||||||
|
local tag = sub(self.bufferRead, 1, 1)
|
||||||
|
if hex and (tag == "p" or tag == "P") then
|
||||||
|
local temp = sub(self.bufferRead, 1, 1)
|
||||||
|
self.bufferRead = sub(self.bufferRead, 2)
|
||||||
|
local temp2 = readnum(true) -- this eats the next sign if any
|
||||||
|
if temp2 then
|
||||||
|
buffer = buffer .. temp .. temp2
|
||||||
|
end
|
||||||
|
elseif tag == "e" or tag == "E" then
|
||||||
|
local temp = sub(self.bufferRead, 1, 1)
|
||||||
|
self.bufferRead = sub(self.bufferRead, 2)
|
||||||
|
local temp2 = readnum(true) -- this eats the next sign if any
|
||||||
|
if temp2 then
|
||||||
|
buffer = buffer .. temp .. temp2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
break
|
||||||
|
else
|
||||||
|
local x,y = string.find(self.bufferRead, pat)
|
||||||
|
if not x then
|
||||||
|
minbuf = 1
|
||||||
|
decimal = true
|
||||||
|
else
|
||||||
|
buffer = buffer .. sub(self.bufferRead, 1, y)
|
||||||
|
self.bufferRead = sub(self.bufferRead, y + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return tonumber(buffer)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readLine(chop)
|
||||||
|
local start = 1
|
||||||
|
while true do
|
||||||
|
local l = self.bufferRead:find("\n", start, true)
|
||||||
|
if l then
|
||||||
|
local result = self.bufferRead:sub(1, l + (chop and -1 or 0))
|
||||||
|
self.bufferRead = self.bufferRead:sub(l + 1)
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
start = #self.bufferRead
|
||||||
|
local result, reason = readChunk()
|
||||||
|
if not result then
|
||||||
|
if reason then
|
||||||
|
return nil, reason
|
||||||
|
else -- eof
|
||||||
|
local result = #self.bufferRead > 0 and self.bufferRead or nil
|
||||||
|
self.bufferRead = ""
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readAll()
|
||||||
|
repeat
|
||||||
|
local result, reason = readChunk()
|
||||||
|
if not result and reason then
|
||||||
|
return nil, reason
|
||||||
|
end
|
||||||
|
until not result -- eof
|
||||||
|
local result = self.bufferRead
|
||||||
|
self.bufferRead = ""
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read(n, format)
|
||||||
|
if type(format) == "number" then
|
||||||
|
return readBytesOrChars(format)
|
||||||
|
else
|
||||||
|
if type(format) ~= "string" or unicode.sub(format, 1, 1) ~= "*" then
|
||||||
|
error("bad argument #" .. n .. " (invalid option)")
|
||||||
|
end
|
||||||
|
format = unicode.sub(format, 2, 2)
|
||||||
|
if format == "n" then
|
||||||
|
return readNumber()
|
||||||
|
elseif format == "l" then
|
||||||
|
return readLine(true)
|
||||||
|
elseif format == "L" then
|
||||||
|
return readLine(false)
|
||||||
|
elseif format == "a" then
|
||||||
|
return readAll()
|
||||||
|
else
|
||||||
|
error("bad argument #" .. n .. " (invalid format)")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.mode.w or self.mode.a then
|
||||||
|
self:flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
local results = {}
|
||||||
|
local formats = table.pack(...)
|
||||||
|
if formats.n == 0 then
|
||||||
|
return readLine(true)
|
||||||
|
end
|
||||||
|
for i = 1, formats.n do
|
||||||
|
local result, reason = read(i, formats[i])
|
||||||
|
if result then
|
||||||
|
results[i] = result
|
||||||
|
elseif reason then
|
||||||
|
return nil, reason
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.unpack(results, 1, formats.n)
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:seek(whence, offset)
|
||||||
|
whence = tostring(whence or "cur")
|
||||||
|
assert(whence == "set" or whence == "cur" or whence == "end",
|
||||||
|
"bad argument #1 (set, cur or end expected, got " .. whence .. ")")
|
||||||
|
offset = offset or 0
|
||||||
|
checkArg(2, offset, "number")
|
||||||
|
assert(math.floor(offset) == offset, "bad argument #2 (not an integer)")
|
||||||
|
|
||||||
|
if self.mode.w or self.mode.a then
|
||||||
|
self:flush()
|
||||||
|
elseif whence == "cur" then
|
||||||
|
offset = offset - #self.bufferRead
|
||||||
|
end
|
||||||
|
local result, reason = self.stream:seek(whence, offset)
|
||||||
|
if result then
|
||||||
|
self.bufferRead = ""
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
return nil, reason
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:setvbuf(mode, size)
|
||||||
|
mode = mode or self.bufferMode
|
||||||
|
size = size or self.bufferSize
|
||||||
|
|
||||||
|
assert(mode == "no" or mode == "full" or mode == "line",
|
||||||
|
"bad argument #1 (no, full or line expected, got " .. tostring(mode) .. ")")
|
||||||
|
assert(mode == "no" or type(size) == "number",
|
||||||
|
"bad argument #2 (number expected, got " .. type(size) .. ")")
|
||||||
|
|
||||||
|
self.bufferMode = mode
|
||||||
|
self.bufferSize = size
|
||||||
|
|
||||||
|
return self.bufferMode, self.bufferSize
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:getTimeout()
|
||||||
|
return self.readTimeout
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:setTimeout(value)
|
||||||
|
self.readTimeout = tonumber(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
function buffer:write(...)
|
||||||
|
if self.closed then
|
||||||
|
return nil, "bad file descriptor"
|
||||||
|
end
|
||||||
|
local args = table.pack(...)
|
||||||
|
for i = 1, args.n do
|
||||||
|
if type(args[i]) == "number" then
|
||||||
|
args[i] = tostring(args[i])
|
||||||
|
end
|
||||||
|
checkArg(i, args[i], "string")
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, args.n do
|
||||||
|
local arg = args[i]
|
||||||
|
local result, reason
|
||||||
|
|
||||||
|
if self.bufferMode == "full" then
|
||||||
|
if self.bufferSize - #self.bufferWrite < #arg then
|
||||||
|
result, reason = self:flush()
|
||||||
|
if not result then
|
||||||
|
return nil, reason
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #arg > self.bufferSize then
|
||||||
|
result, reason = self.stream:write(arg)
|
||||||
|
else
|
||||||
|
self.bufferWrite = self.bufferWrite .. arg
|
||||||
|
result = self
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif self.bufferMode == "line" then
|
||||||
|
local l
|
||||||
|
repeat
|
||||||
|
local idx = arg:find("\n", (l or 0) + 1, true)
|
||||||
|
if idx then
|
||||||
|
l = idx
|
||||||
|
end
|
||||||
|
until not idx
|
||||||
|
if l or #arg > self.bufferSize then
|
||||||
|
result, reason = self:flush()
|
||||||
|
if not result then
|
||||||
|
return nil, reason
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if l then
|
||||||
|
result, reason = self.stream:write(arg:sub(1, l))
|
||||||
|
if not result then
|
||||||
|
return nil, reason
|
||||||
|
end
|
||||||
|
arg = arg:sub(l + 1)
|
||||||
|
end
|
||||||
|
if #arg > self.bufferSize then
|
||||||
|
result, reason = self.stream:write(arg)
|
||||||
|
else
|
||||||
|
self.bufferWrite = self.bufferWrite .. arg
|
||||||
|
result = self
|
||||||
|
end
|
||||||
|
|
||||||
|
else -- self.bufferMode == "no"
|
||||||
|
result, reason = self.stream:write(arg)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not result then
|
||||||
|
return nil, reason
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
@ -32,37 +32,16 @@ for k,v in pairs({"makeDirectory","exists","isDirectory","list","lastModified","
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function fread(self,length)
|
local function fread(self,length)
|
||||||
if length == "*a" then
|
|
||||||
length = math.huge
|
|
||||||
end
|
|
||||||
if type(length) == "number" then
|
|
||||||
local rstr, lstr = "", ""
|
|
||||||
repeat
|
|
||||||
lstr = fsmounts[self.fs].read(self.fid,math.min(2^16,length-rstr:len())) or ""
|
|
||||||
rstr = rstr .. lstr
|
|
||||||
until rstr:len() == length or lstr == ""
|
|
||||||
return rstr
|
|
||||||
elseif type(length) == "string" then
|
|
||||||
local buf = ""
|
|
||||||
if length == "*l" then
|
|
||||||
length = "\n"
|
|
||||||
end
|
|
||||||
repeat
|
|
||||||
local rb = fsmounts[self.fs].read(self.fid,1) or ""
|
|
||||||
buf = buf .. rb
|
|
||||||
until buf:match(length) or rb == ""
|
|
||||||
return buf:match("(.*)"..length)
|
|
||||||
end
|
|
||||||
return fsmounts[self.fs].read(self.fid,length)
|
return fsmounts[self.fs].read(self.fid,length)
|
||||||
end
|
end
|
||||||
local function fwrite(self,data)
|
local function fwrite(self,data)
|
||||||
fsmounts[self.fs].write(self.fid,data)
|
return fsmounts[self.fs].write(self.fid,data)
|
||||||
end
|
end
|
||||||
local function fseek(self,dist)
|
local function fseek(self,dist)
|
||||||
fsmounts[self.fs].seek(self.fid,dist)
|
return fsmounts[self.fs].seek(self.fid,dist)
|
||||||
end
|
end
|
||||||
local function fclose(self)
|
local function fclose(self)
|
||||||
fsmounts[self.fs].close(self.fid)
|
return fsmounts[self.fs].close(self.fid)
|
||||||
end
|
end
|
||||||
|
|
||||||
function fs.open(path,mode) -- opens file *path* with mode *mode*
|
function fs.open(path,mode) -- opens file *path* with mode *mode*
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
--#include "module/syslog.lua"
|
--#include "module/syslog.lua"
|
||||||
--#include "module/sched.lua"
|
--#include "module/sched.lua"
|
||||||
|
--#include "module/buffer.lua"
|
||||||
--#include "module/osutil.lua"
|
--#include "module/osutil.lua"
|
||||||
--#include "module/fs.lua"
|
--#include "module/fs.lua"
|
||||||
--#include "module/newio.lua"
|
--#include "module/io.lua"
|
||||||
--#include "module/devfs.lua"
|
--#include "module/devfs.lua"
|
||||||
--#include "module/devfs/syslog.lua"
|
--#include "module/devfs/syslog.lua"
|
||||||
--#include "module/vt-task.lua"
|
|
||||||
--#include "module/loadfile.lua"
|
--#include "module/loadfile.lua"
|
||||||
|
--#include "module/vt-task.lua"
|
||||||
os.spawnfile("/boot/exec/init.lua")
|
os.spawnfile("/boot/exec/init.lua")
|
||||||
|
|
||||||
os.sched()
|
os.sched()
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
io = {}
|
io = {}
|
||||||
|
|
||||||
|
function io.open(path,mode)
|
||||||
|
local f,e = fs.open(path, mode)
|
||||||
|
if not f then return false, e end
|
||||||
|
return buffer.new(mode,f)
|
||||||
|
end
|
||||||
|
|
||||||
function io.input(fd)
|
function io.input(fd)
|
||||||
if type(fd) == "string" then
|
if type(fd) == "string" then
|
||||||
fd=fs.open(fd,"rb")
|
fd=io.open(fd,"rb")
|
||||||
end
|
end
|
||||||
if fd then
|
if fd then
|
||||||
os.setenv("STDIN",fd)
|
os.setenv("STDIN",fd)
|
||||||
@ -10,7 +17,7 @@ function io.input(fd)
|
|||||||
end
|
end
|
||||||
function io.output(fd)
|
function io.output(fd)
|
||||||
if type(fd) == "string" then
|
if type(fd) == "string" then
|
||||||
fd=fs.open(fd,"wb")
|
fd=io.open(fd,"wb")
|
||||||
end
|
end
|
||||||
if fd then
|
if fd then
|
||||||
os.setenv("STDOUT",fd)
|
os.setenv("STDOUT",fd)
|
||||||
@ -18,8 +25,6 @@ function io.output(fd)
|
|||||||
return os.getenv("STDOUT")
|
return os.getenv("STDOUT")
|
||||||
end
|
end
|
||||||
|
|
||||||
io.open = fs.open
|
|
||||||
|
|
||||||
function io.read(...)
|
function io.read(...)
|
||||||
return io.input():read()
|
return io.input():read()
|
||||||
end
|
end
|
@ -1,5 +1,5 @@
|
|||||||
function loadfile(p) -- reads file *p* and returns a function if possible
|
function loadfile(p) -- reads file *p* and returns a function if possible
|
||||||
local f = fs.open(p,"rb")
|
local f = io.open(p,"rb")
|
||||||
local c = f:read("*a")
|
local c = f:read("*a")
|
||||||
f:close()
|
f:close()
|
||||||
return load(c,p,"t")
|
return load(c,p,"t")
|
||||||
@ -9,22 +9,23 @@ function runfile(p,...) -- runs file *p* with arbitrary arguments in the current
|
|||||||
end
|
end
|
||||||
function os.spawnfile(p,n,...) -- spawns a new process from file *p* with name *n*, with arguments following *n*.
|
function os.spawnfile(p,n,...) -- spawns a new process from file *p* with name *n*, with arguments following *n*.
|
||||||
local tA = {...}
|
local tA = {...}
|
||||||
return os.spawn(function() computer.pushSignal("process_finished", os.pid(), pcall(loadfile(p), table.unpack(tA))) end,n or p)
|
return os.spawn(function() local res={pcall(loadfile(p), table.unpack(tA))} computer.pushSignal("process_finished", os.pid(), table.unpack(res)) dprint(table.concat(res)) end,n or p)
|
||||||
end
|
end
|
||||||
_G.libs = {computer=computer,component=component}
|
_G.package = {}
|
||||||
|
package.loaded = {computer=computer,component=component,fs=fs}
|
||||||
function require(f) -- searches for a library with name *f* and returns what the library returns, if possible
|
function require(f) -- searches for a library with name *f* and returns what the library returns, if possible
|
||||||
if not _G.libs[f] then
|
if not package.loaded[f] then
|
||||||
local lib = os.getenv("LIB") or "/boot/lib"
|
local lib = os.getenv("LIB") or "/boot/lib"
|
||||||
for d in lib:gmatch("[^\n]+") do
|
for d in lib:gmatch("[^\n]+") do
|
||||||
if fs.exists(d.."/"..f) then
|
if fs.exists(d.."/"..f) then
|
||||||
_G.libs[f] = runfile(d.."/"..f)
|
package.loaded[f] = runfile(d.."/"..f)
|
||||||
elseif fs.exists(d.."/"..f..".lua") then
|
elseif fs.exists(d.."/"..f..".lua") then
|
||||||
_G.libs[f] = runfile(d.."/"..f..".lua")
|
package.loaded[f] = runfile(d.."/"..f..".lua")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if _G.libs[f] then
|
if package.loaded[f] then
|
||||||
return _G.libs[f]
|
return package.loaded[f]
|
||||||
end
|
end
|
||||||
error("library not found: "..f)
|
error("library not found: "..f)
|
||||||
end
|
end
|
||||||
|
@ -31,7 +31,7 @@ function vtemu(gpua,scra) -- creates a process to handle the GPU and screen addr
|
|||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
end
|
end
|
||||||
local n = buf:find("\n")
|
local n = buf:find("\n")
|
||||||
r, buf = buf:sub(1,n-1), buf:sub(n+1)
|
r, buf = buf:sub(1,n), buf:sub(n+1)
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
return bread, write, function() io.write("\27[2J\27[H") end
|
return bread, write, function() io.write("\27[2J\27[H") end
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
local gpus,screens,ttyn,pids = {}, {}, 0, {}
|
local gpus,screens,ttyn,pids = {}, {}, 0, {}
|
||||||
|
local shell = require "shell"
|
||||||
local function scan()
|
local function scan()
|
||||||
local w,di = pcall(computer.getDeviceInfo)
|
local w,di = pcall(computer.getDeviceInfo)
|
||||||
if w then
|
if w then
|
||||||
@ -32,9 +33,9 @@ end
|
|||||||
|
|
||||||
local function spawnShell(fin,fout)
|
local function spawnShell(fin,fout)
|
||||||
io.input(fin)
|
io.input(fin)
|
||||||
io.output(fout)
|
io.output(fout):setvbuf("no")
|
||||||
print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
||||||
return os.spawnfile("/boot/exec/shell.lua")
|
return os.spawn(shell.interactive, "shell: "..tostring(fin))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function allocate()
|
local function allocate()
|
||||||
|
Loading…
Reference in New Issue
Block a user