147 lines
3.4 KiB
Lua
147 lines
3.4 KiB
Lua
local mtar = require "libmtar"
|
|
local w, lz16 = pcall(require, "liblz16")
|
|
if not w then lz16 = nil end
|
|
|
|
pkgfs = {}
|
|
pkgfs.files = {}
|
|
local findex = {}
|
|
local handles = {}
|
|
local hc = 0
|
|
|
|
local function rfalse()
|
|
return false
|
|
end
|
|
local function rzero()
|
|
return 0
|
|
end
|
|
|
|
pkgfs.component = {seek = rfalse, makeDirectory = rfalse, write = rfalse, rename = rfalse, setlabel = rfalse, spaceUsed = rzero, spaceTotal = rzero, lastModified = rzero, address = "pkgfs"}
|
|
|
|
local function fopen(path,comp)
|
|
local f
|
|
if comp and lz16 then
|
|
f = lz16.open(path,"rb")
|
|
else
|
|
f = io.open(path,"rb")
|
|
end
|
|
return f
|
|
end
|
|
|
|
local function fnormalize(s)
|
|
return table.concat(fs.segments(s),"/")
|
|
end
|
|
|
|
function pkgfs.component.exists(path)
|
|
path = fnormalize(path)
|
|
return findex[path] and true
|
|
end
|
|
|
|
function pkgfs.component.list(path)
|
|
path = fnormalize(path).."/"
|
|
local ft,rt = {},{}
|
|
for k,v in pairs(findex) do
|
|
k="/"..k
|
|
if k:match(path.."([^/]+)/.+") then
|
|
ft[k:match(path.."([^/]+)/.+").."/"] = true
|
|
elseif k:match(path.."([^/]+)") then
|
|
ft[k:match(path.."([^/]+)")] = true
|
|
end
|
|
end
|
|
for k,v in pairs(ft) do
|
|
rt[#rt+1] = k
|
|
end
|
|
return rt
|
|
end
|
|
function pkgfs.component.isDirectory(path)
|
|
path = fnormalize(path).."/"
|
|
for k,v in pairs(findex) do
|
|
k="/"..k
|
|
if k:match(path.."([^/]+)/.+") then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
function pkgfs.component.size(path)
|
|
path=fnormalize(path)
|
|
if not findex[path] then return false end
|
|
local f = fopen(findex[path][1], findex[path][2])
|
|
for fname, read, fsize in mtar.iter(f) do
|
|
if fname == path then
|
|
return fsize
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function pkgfs.component.open(path,mode)
|
|
path=fnormalize(path)
|
|
if mode:find("w") or mode:find("a") or not findex[path] then
|
|
return false
|
|
end
|
|
local f = fopen(findex[path][1],findex[path][2])
|
|
for fname,read,fsize in mtar.iter(f) do
|
|
if fname == path then
|
|
hc = hc + 1
|
|
handles[hc] = {read, f}
|
|
return hc
|
|
end
|
|
end
|
|
end
|
|
|
|
function pkgfs.component.read(handle, n)
|
|
if not handles[handle] then return false end
|
|
local rv = handles[handle][1](n)
|
|
if not rv then return nil end
|
|
if rv:len() < 1 then return nil end
|
|
return rv
|
|
end
|
|
|
|
function pkgfs.component.close(handle)
|
|
if not handles[handle] then return false end
|
|
handles[handle][2]:close()
|
|
handles[handle] = nil
|
|
return true
|
|
end
|
|
|
|
local function index()
|
|
findex = {}
|
|
for k,v in pairs(pkgfs.files) do
|
|
fname, comp = v[1], v[2]
|
|
if fname:sub(1,1) ~= "/" then
|
|
fname = "/"..fnormalize(os.getenv("PWD").."/"..fname)
|
|
end
|
|
local f = fopen(fname,comp)
|
|
if not f then error("unable to open file "..fname) end
|
|
for name, read, fsize in mtar.iter(f) do
|
|
findex[fnormalize(name)] = {fname,comp}
|
|
end
|
|
f:close()
|
|
end
|
|
return true
|
|
end
|
|
|
|
function pkgfs.add(fname,comp) -- string boolean -- boolean -- Add a package as specified in *fname* to the pkgfs component. If *comp* is true, read it as a LZ16-compressed package.
|
|
pkgfs.files[#pkgfs.files+1] = {fname,comp}
|
|
return index()
|
|
end
|
|
function pkgfs.remove(fname) -- string -- boolean -- Removes the package specified by *fname* from the pkgfs index.
|
|
for k,v in pairs(pkgfs.files) do
|
|
if v[1] == fname then
|
|
table.remove(pkgfs.files,k)
|
|
end
|
|
end
|
|
return index()
|
|
end
|
|
|
|
fs.makeDirectory("/pkg")
|
|
fs.mount("/pkg",pkgfs.component)
|
|
for _,file in ipairs(fs.list("/boot/pkg/")) do
|
|
if file:sub(-5) == ".mtar" then
|
|
pcall(pkgfs.add,"/boot/pkg/"..file)
|
|
elseif file:sub(-9) == ".mtar.lss" then
|
|
pcall(pkgfs.add,"/boot/pkg/"..file,true)
|
|
end
|
|
end
|
|
return pkgfs
|