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