local serial = require "serialization" local w, lzss = pcall(require,"lzss") if not w then lzss = nil end local tArgs = {...} local fsnames = {"lfs","luafilesystem","filesystem"} local w, fs for k,v in pairs(fsnames) do w,fs = pcall(require,v) if w then break end end if not w then error("luafilesystem not detected") end local function cint(n,l) local t={} for i = 0, 7 do t[i+1] = (n >> (i * 8)) & 0xFF end return string.reverse(string.char(table.unpack(t)):sub(1,l)) end local function genHeader(fname,len) return string.format("%s%s%s",cint(fname:len(),2),fname,cint(len,2)) end local function fnormalize(path) local rt = {} for segment in path:gmatch("[^/]+") do if segment ~= "." and segment ~= ".." then rt[#rt+1] = segment end end return table.concat(rt,"/") end local dirs, files = {tArgs[1]},{} for _,dir in ipairs(dirs) do for file in fs.dir(dir) do if file == "." or file == ".." then elseif fs.attributes(dir.."/"..file).mode == "directory" then dirs[#dirs+1] = dir.."/"..file elseif file ~= "package.cfg" then files[#files+1] = dir.."/"..file end end end local f = io.open(tArgs[1].."/package.cfg","rb") if not f then error("no package.cfg in source") end local pkginfo = serial.unserialize(f:read("*a")) f:close() local outpath = tArgs[2].."/"..tArgs[1]..".mtar" local of = io.open(outpath,"wb") for k,v in ipairs(files) do local f = io.open(v,"rb") if f then local content = f:read("*a") f:close() of:write(genHeader(fnormalize(v:sub(tArgs[1]:len()+1)),content:len())) of:write(content) end end of:write(string.char(0):rep(2)) of:close() if lzss then print("Compressing "..outpath.." to "..outpath..".lss") local f = io.open(outpath,"rb") local of = io.open(outpath..".lss","wb") while true do local b = f:read(4096) if not b or b:len() < 1 then break end b = lzss.compress(b) of:write(b) end f:close() of:close() outpath = outpath .. ".lss" pkginfo.compressed = true end pkginfo.filename = fnormalize(outpath:sub(tArgs[2]:len()+1)) pkginfo.version = tArgs[3] local repo = {} local f = io.open(tArgs[2].."/packages.cfg","rb") if f then repo = serial.unserialize(f:read("*a")) or {} f:close() end repo[tArgs[1]] = pkginfo local f = io.open(tArgs[2].."/packages.cfg","wb") if f then f:write(serial.serialize(repo)) f:close() end