162 lines
3.6 KiB
Lua
162 lines
3.6 KiB
Lua
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
|