diff --git a/build.sh b/build.sh index 2509b80..87c5dc7 100755 --- a/build.sh +++ b/build.sh @@ -3,7 +3,7 @@ rm -r target/* mkdir target &>/dev/null mkdir target/cfg 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 mv target/tinit.lua target/init.lua cp -r exec/ service/ lib/ target/ diff --git a/exec/cat.lua b/exec/cat.lua deleted file mode 100644 index 3107761..0000000 --- a/exec/cat.lua +++ /dev/null @@ -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 diff --git a/exec/df.lua b/exec/df.lua deleted file mode 100644 index 265fedc..0000000 --- a/exec/df.lua +++ /dev/null @@ -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 diff --git a/exec/ed.lua b/exec/ed.lua deleted file mode 100644 index 1273948..0000000 --- a/exec/ed.lua +++ /dev/null @@ -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 diff --git a/exec/exportfs.lua b/exec/exportfs.lua deleted file mode 100644 index 0182620..0000000 --- a/exec/exportfs.lua +++ /dev/null @@ -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 diff --git a/exec/fget.lua b/exec/fget.lua deleted file mode 100644 index b4e1eb4..0000000 --- a/exec/fget.lua +++ /dev/null @@ -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() diff --git a/exec/free.lua b/exec/free.lua deleted file mode 100644 index 6cefc09..0000000 --- a/exec/free.lua +++ /dev/null @@ -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))) diff --git a/exec/importfs.lua b/exec/importfs.lua deleted file mode 100644 index 6bb5a76..0000000 --- a/exec/importfs.lua +++ /dev/null @@ -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) diff --git a/exec/init.lua b/exec/init.lua deleted file mode 100644 index 42d3cab..0000000 --- a/exec/init.lua +++ /dev/null @@ -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 diff --git a/exec/ls.lua b/exec/ls.lua deleted file mode 100644 index db111f6..0000000 --- a/exec/ls.lua +++ /dev/null @@ -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 diff --git a/exec/mkarchive.lua b/exec/mkarchive.lua deleted file mode 100644 index ce860a5..0000000 --- a/exec/mkarchive.lua +++ /dev/null @@ -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() diff --git a/exec/mount.lua b/exec/mount.lua deleted file mode 100644 index 6f5f727..0000000 --- a/exec/mount.lua +++ /dev/null @@ -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 diff --git a/exec/nc.lua b/exec/nc.lua deleted file mode 100644 index 03db4a6..0000000 --- a/exec/nc.lua +++ /dev/null @@ -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" diff --git a/exec/ping.lua b/exec/ping.lua deleted file mode 100644 index d84ed4c..0000000 --- a/exec/ping.lua +++ /dev/null @@ -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 diff --git a/exec/ps.lua b/exec/ps.lua deleted file mode 100644 index c006080..0000000 --- a/exec/ps.lua +++ /dev/null @@ -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 diff --git a/exec/shell.lua b/exec/shell.lua deleted file mode 100644 index c039315..0000000 --- a/exec/shell.lua +++ /dev/null @@ -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)) diff --git a/exec/unarchive.lua b/exec/unarchive.lua deleted file mode 100644 index d734727..0000000 --- a/exec/unarchive.lua +++ /dev/null @@ -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() diff --git a/exec/wget.lua b/exec/wget.lua deleted file mode 100644 index 3dbb923..0000000 --- a/exec/wget.lua +++ /dev/null @@ -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() diff --git a/lib/netutil.lua b/lib/netutil.lua new file mode 100644 index 0000000..7aca7d2 --- /dev/null +++ b/lib/netutil.lua @@ -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 diff --git a/lib/shell.lua b/lib/shell.lua new file mode 100644 index 0000000..f012718 --- /dev/null +++ b/lib/shell.lua @@ -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 diff --git a/lib/shutil.lua b/lib/shutil.lua new file mode 100644 index 0000000..f7abd4f --- /dev/null +++ b/lib/shutil.lua @@ -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 diff --git a/module/init.lua b/module/init.lua index 9631452..7d09b36 100644 --- a/module/init.lua +++ b/module/init.lua @@ -6,8 +6,8 @@ --#include "module/io.lua" --#include "module/devfs.lua" --#include "module/devfs/syslog.lua" ---#include "module/vt-task.lua" --#include "module/loadfile.lua" +--#include "module/vt-task.lua" os.spawnfile("/boot/exec/init.lua") os.sched() diff --git a/module/loadfile.lua b/module/loadfile.lua index cb5acc1..35454ea 100644 --- a/module/loadfile.lua +++ b/module/loadfile.lua @@ -11,20 +11,21 @@ function os.spawnfile(p,n,...) -- spawns a new process from file *p* with name * local tA = {...} 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 -_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 - if not _G.libs[f] then + if not package.loaded[f] then local lib = os.getenv("LIB") or "/boot/lib" for d in lib:gmatch("[^\n]+") do 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 - _G.libs[f] = runfile(d.."/"..f..".lua") + package.loaded[f] = runfile(d.."/"..f..".lua") end end end - if _G.libs[f] then - return _G.libs[f] + if package.loaded[f] then + return package.loaded[f] end error("library not found: "..f) end diff --git a/module/newio.lua b/module/newio.lua deleted file mode 100644 index 6c04164..0000000 --- a/module/newio.lua +++ /dev/null @@ -1,34 +0,0 @@ -io = {} -function io.input(fd) - if type(fd) == "string" then - fd=fs.open(fd,"rb") - end - if fd then - os.setenv("STDIN",fd) - end - return os.getenv("STDIN") -end -function io.output(fd) - if type(fd) == "string" then - fd=fs.open(fd,"wb") - end - if fd then - os.setenv("STDOUT",fd) - end - return os.getenv("STDOUT") -end - -io.open = fs.open - -function io.read(...) - return io.input():read() -end -function io.write(...) - io.output():write(...) -end - -function print(...) - for k,v in ipairs({...}) do - io.write(tostring(v).."\n") - end -end diff --git a/service/getty.lua b/service/getty.lua index 91c9ce4..df2467f 100644 --- a/service/getty.lua +++ b/service/getty.lua @@ -1,4 +1,5 @@ local gpus,screens,ttyn,pids = {}, {}, 0, {} +local shell = require "shell" local function scan() local w,di = pcall(computer.getDeviceInfo) if w then @@ -34,7 +35,7 @@ local function spawnShell(fin,fout) io.input(fin) io.output(fout):setvbuf("no") 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 local function allocate()