mirror of
https://github.com/Adorable-Catgirl/Zorya-NEO.git
synced 2024-11-23 18:58:06 +11:00
118 lines
2.6 KiB
Lua
118 lines
2.6 KiB
Lua
local comp = component
|
|
local cpio = {}
|
|
local arc = {}
|
|
|
|
local function read(f, h, n)
|
|
local d = f.read(h, n)
|
|
return d
|
|
end
|
|
|
|
local function readint(f, h, amt, rev)
|
|
local tmp = 0
|
|
for i=(rev and amt) or 1, (rev and 1) or amt, (rev and -1) or 1 do
|
|
tmp = tmp | (read(f, h, 1):byte() << ((i-1)*8))
|
|
end
|
|
return tmp
|
|
end
|
|
|
|
function cpio.read(drive, path)
|
|
local f = comp.proxy(drive)
|
|
local h = f.open(path)
|
|
local tbl = {}
|
|
while true do
|
|
local dent = {}
|
|
dent.magic = readint(f, h, 2)
|
|
local rev = false
|
|
if (dent.magic ~= tonumber("070707", 8)) then rev = true end
|
|
dent.dev = readint(f, h, 2)
|
|
dent.ino = readint(f, h, 2)
|
|
dent.mode = readint(f, h, 2)
|
|
dent.uid = readint(f, h, 2)
|
|
dent.gid = readint(f, h, 2)
|
|
dent.nlink = readint(f, h, 2)
|
|
dent.rdev = readint(f, h, 2)
|
|
dent.mtime = (readint(f, h, 2) << 16) | readint(f, h, 2)
|
|
dent.namesize = readint(f, h, 2)
|
|
dent.filesize = (readint(f, h, 2) << 16) | readint(f, h, 2)
|
|
local name = read(f, h, dent.namesize):sub(1, dent.namesize-1)
|
|
if (name == "TRAILER!!!") then break end
|
|
--for k, v in pairs(dent) do
|
|
-- print(k, v)
|
|
--end
|
|
dent.name = name
|
|
if (dent.namesize % 2 ~= 0) then
|
|
f.seek(h, "cur", 1)
|
|
end
|
|
if (dent.mode & 32768 ~= 0) then
|
|
--fwrite()
|
|
end
|
|
dent.pos = f.seek(h, "cur", 0)
|
|
f.seek(h, "cur", dent.filesize)
|
|
if (dent.filesize % 2 ~= 0) then
|
|
f.seek(h, "cur", 1)
|
|
end
|
|
tbl[#tbl+1] = dent
|
|
end
|
|
return setmetatable({
|
|
tbl = tbl,
|
|
fs = f,
|
|
handle = h
|
|
}, {__index=arc})
|
|
end
|
|
|
|
function arc:fetch(path)
|
|
for i=1, #self.tbl do
|
|
if (self.tbl[i].name == path and self.tbl[i].mode &32768 > 0) then
|
|
self.fs.seek(self.handle, "set", self.tbl[i].pos)
|
|
return self.fs.read(self.handle, self.tbl[i].filesize)
|
|
end
|
|
end
|
|
return nil, "file not found"
|
|
end
|
|
|
|
function arc:exists(path)
|
|
for i=1, #self.tbl do
|
|
if (self.tbl[i].name == path) then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function arc:close()
|
|
self.fs.close(self.handle)
|
|
self.tbl = {}
|
|
end
|
|
|
|
function arc:list_dir(path)
|
|
if path:sub(#path) ~= "/" then path = path .. "/" end
|
|
local ent = {}
|
|
for i=1, #self.tbl do
|
|
if (self.tbl[i].name:sub(1, #path) == path and not self.tbl[i].name:find("/", #path+1, false)) then
|
|
ent[#ent+1] = self.tbl[i].name
|
|
end
|
|
end
|
|
return ent
|
|
end
|
|
|
|
function arc:stream()
|
|
for i=1, #self.tbl do
|
|
if (self.tbl[i].name == path and self.tbl[i].mode & 32768 > 0) then
|
|
local pos = 1
|
|
local function read(amt)
|
|
self.seek(self.tbl[i].pos-self.seek(0)+pos-1)
|
|
pos = pos + amt
|
|
return self.read(amt)
|
|
end
|
|
local function seek(amt)
|
|
pos = pos + amt
|
|
return pos
|
|
end
|
|
local function close()end
|
|
return read, seek, close
|
|
end
|
|
end
|
|
return nil, "file not found"
|
|
end
|
|
|
|
return cpio |