From 0f6d126eaf6dcf0d2250667e72fb716f8b956f93 Mon Sep 17 00:00:00 2001 From: XeonSquared Date: Fri, 4 Aug 2017 14:01:55 +1000 Subject: [PATCH] added a heap of tape-related functionality. I'm not really happy with it yet. --- build.cfg | 1 + modules/util/fs-automount.lua | 25 +++++- modules/util/tape.lua | 161 ++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 modules/util/tape.lua diff --git a/build.cfg b/build.cfg index 641665d..549d14a 100755 --- a/build.cfg +++ b/build.cfg @@ -15,6 +15,7 @@ modules/net/net-ext.lua modules/applications/luash.lua modules/applications/genkernel.lua modules/applications/skex2.lua +modules/util/tape.lua modules/util/fs-automount.lua modules/setup.lua modules/base/footer.lua diff --git a/modules/util/fs-automount.lua b/modules/util/fs-automount.lua index 4a845f0..28be868 100644 --- a/modules/util/fs-automount.lua +++ b/modules/util/fs-automount.lua @@ -1,9 +1,5 @@ do local C=0 - if component.type(computer.getBootAddress()) == "tape_drive" then - fs.mount("boot",computer.tmpAddress()) - print(computer.tmpAddress():sub(1,8).." mounted as boot") - end for c in component.list("filesystem") do if c == computer.tmpAddress() then fs.mount("tmp",component.proxy(c)) @@ -21,4 +17,25 @@ do print(c:sub(1,8).." mounted as fs"..string.format("%02d",C)) C=C+1 end + if component.type(computer.getBootAddress()) == "tape_drive" then + fs.mount("boot",component.proxy(computer.tmpAddress())) + print(computer.tmpAddress():sub(1,8).." mounted as boot") + if tape then + tape.rewind() + local pt = tape.records() + for k,v in ipairs(pt) do + if v[1] == "D" then + print(tostring(k).."\t"..v[1].."\t/boot/"..tape.rrecord(k)) + fs.mkdir("/boot/"..tape.rrecord(k)) + elseif v[1] == "f" then + local fn,fc = tape.parsefile(tape.rrecord(k)) + print(tostring(k).."\t"..v[1].."\t/boot/"..fn) + local f=io.open("/boot/"..fn,"wb") + f:write(fc) + f:close() + end + computer.beep() + end + end + end end diff --git a/modules/util/tape.lua b/modules/util/tape.lua new file mode 100644 index 0000000..028718f --- /dev/null +++ b/modules/util/tape.lua @@ -0,0 +1,161 @@ +tape = {} +tape.types = {} +tape.types["!"] = "executable" +tape.types["t"] = "tar" +tape.types["d"] = "data" +tape.types["D"] = "directory" +tape.types["f"] = "file" +function tape.records(addr) -- { { type, start, end, length } } + local tp,ct = {},0 + addr = addr or component.list("tape_drive")() + local t = component.proxy(addr) + local function read(n) + n=n or 1 + ct=ct+n + return t.read(n) + end + local function seek(n) + n=n or 1 + ct=ct+n + return t.seek(n) + end + while true do + local ty = read() + if not tape.types[ty] then break end + tp[#tp+1] = {ty,ct+8} -- type, start, + local ln = tonumber(read(8)) or 0 + tp[#tp][#tp[#tp]+1] = ct+ln -- end + tp[#tp][#tp[#tp]+1] = ln -- length + seek(ln) + end + return tp +end +function tape.precords(addr) + tape.rewind(addr) + local pt = tape.records(addr) + for k,v in ipairs(pt) do + print(k.."\t"..v[1].."\t"..v[2].."\t"..v[3].."\t"..v[4]) + end +end +function tape.drecord(n,addr) + addr = addr or component.list("tape_drive")() + tape.rewind(addr) + local pt = tape.records(addr) + tape.rewind(addr) + local t = component.proxy(addr) + print(pt[n][2]-9) + t.seek(pt[n][2]-9) + t.write("\0") + tape.rewind() +end +function tape.wrecord(c,ty,s,addr) + ty = ty or "!" + addr = addr or component.list("tape_drive")() + local t = component.proxy(addr) + if s then + t.seek(-math.huge) + t.seek(s) + end + local fh=ty:sub(1,1)..string.format("%8d",c:len()) + print("Header: "..fh) + t.write(fh) + t.write(c) +end +function tape.rrecord(pn,addr) + addr = addr or component.list("tape_drive")() + pn = pn or 1 + local t = component.proxy(addr) + local pP = t.seek(-math.huge) + local pt = tape.records(addr) + t.seek(-math.huge) + local pstart,plen = pt[pn][2],pt[pn][4] + t.seek(pstart) + C=t.read(plen) + t.seek(-math.huge) + t.seek(pP) + return C +end +function tape.nrecord(addr) + addr = addr or component.list("tape_drive")() + local t = component.proxy(addr) + local pP = t.seek(-math.huge) + local pt = tape.records(addr) + t.seek(-math.huge) + t.seek(pP) + return pt[#pt][3] +end +function tape.rewind(addr) + addr = addr or component.list("tape_drive")() + local t = component.proxy(addr) + t.seek(-math.huge) +end +function tape.parsefile(str) + return str:sub(1,64):gsub("\0",""), str:sub(65) +end +function tape.unparsefile(fname,str) + local nul = "\0" + nul=nul:rep(64-#fname) + fname=nul..fname + return fname..str +end +function tape.mkdir(str,addr) + tape.wrecord(str,"D",tape.nrecord(),addr) +end +function tape.wfile(fname,fcont,addr) + tape.wrecord(str,"f",tape.nrecord(),addr) +end +function tape.wtree(addr) + local ft = {""} + local rft = {} + addr = addr or component.list("tape_drive")() + local t = component.proxy(addr) + for _,d in ipairs(ft) do + local ls = fs.list(d) + for k,v in ipairs(ls) do + v=d..v + if fs.isdir(v) then + ft[#ft+1] = v + else + rft[#rft+1] = v + end + end + end + tape.rewind(addr) + t.seek(tape.nrecord(addr)) + for k,v in ipairs(ft) do + if v ~= "" then + print(v) + local fh="D"..string.format("%8d",v:len()) + t.write(fh) + t.write(v) + end + end + for k,v in ipairs(rft) do + print(v) + local f=io.open(v,"rb") + local fc = f:read("*a") + local fc = tape.unparsefile(v,fc) + f:close() + local fh="f"..string.format("%8d",fc:len()) + t.write(fh) + t.write(fc) + end +end +function tape.rtree(pref,addr) + tape.rewind() + local pt = tape.records() + for k,v in ipairs(pt) do + if v[1] == "D" then + print(tostring(k).."\t"..v[1].."\t"..pref..tape.rrecord(k)) + fs.mkdir(pref..tape.rrecord(k)) + elseif v[1] == "f" then + local fn,fc = tape.parsefile(tape.rrecord(k)) + print(tostring(k).."\t"..v[1].."\t"..pref..fn) + local f=io.open(pref..fn,"wb") + f:write(fc) + f:close() + end + computer.beep() + coroutine.yield() + end +end