|
- 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
|