local magic = 0x5f7d local magic_rev = 0x7d5f local header_fmt = "I2I2I2I2I2I6I6" local en = string.unpack("=I2", string.char(0x7d, 0x5f)) == magic -- true = LE, false = BE local function get_end(e) return (e and "<") or ">" end local function read_header(dat) local e = get_end(en) local m = string.unpack(e.."I2", dat) if m ~= magic and m ~= magic_rev then return nil, "bad magic" end if m ~= magic then e = get_end(not en) end local ent = {} ent.magic, ent.namesize, ent.mode, ent.uid, ent.gid, ent.filesize, ent.mtime = string.unpack(e..header_fmt, dat) return ent end local arc = {} 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.seek(self.tbl[i].pos-self.seek(0)) return self.read(self.tbl[i].filesize), self.tbl[i] 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:list(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:close() self.close() end function load_tsar(addr, path) local fs = component.proxy(addr) local h = fs.open(path) status("loading initramfs... "..lsc()) local dat = "" local buf = "" repeat buf = fs.read(h, math.huge) if (buf) then dat = dat .. buf end y = y - 1 status("loading initramfs... "..lsc()) until not buf or buf == "" local idx = 1 local function read(a) local dat = buf:sub(idx, idx+a-1) idx = idx + a return dat end local function seek(a) idx = idx + a return idx end local function close()end local tbl = {} local lname = "" while lname ~= "TRAILER!!!" do y = y - 1 status("loading initramfs... "..lsc()) local dat = read(22) local et = read_header(dat) et.name = read(et.namesize) et.pos = seek(et.namesize & 1) seek(et.filesize + (et.filesize & 1)) lname = et.name if lname ~= "TRAILER!!!" then tbl[#tbl+1] = et end end return setmetatable({tbl = tbl, read = read, seek = seek, close = close}, {__index=arc}) end