local shell = require "shell" local mtar = require "libmtar" local args, opts = shell.parse(...) local w, lz16 = pcall(require, "liblz16") if not w then lz16 = nil end local function toint(s) s = s or "\0" local n = 0 local i = 1 for p in s:gmatch(".") do n = n << 8 n = n | string.byte(p) i=i+1 end return n end local function vw(s) if opts.v and s then io.write(tostring(s)) end end local function vp(...) for k,v in ipairs({...}) do vw(tostring(v).."\n") end end if opts.x then local f if opts.z then f = lz16.open(args[1],"rb") else f = io.open(args[1],"rb") end if not f then error("unable to open file") end local w, r = mtar.unarchive(f,args[2] or ".",opts.v) f:close() elseif opts.t then local f if opts.z then f = lz16.open(args[1],"rb") else f = io.open(args[1],"rb") end if not f then error("unable to open file") end while true do local nlen = toint(f:read(2)) if nlen == 0 then break end local name = f:read(nlen) local fsize = toint(f:read(2) or "\0\0") f:read(fsize) print(name..": "..tostring(fsize)) end f:close() elseif opts.c then local mode = (opts.r and "ab") or "wb" local f if opts.z then f = lz16.open(args[1],mode) else f = io.open(args[1],mode) end if not f then error("unable to open file") end table.remove(args,1) local fs = require "filesystem" for k,v in pairs(args) do local ap = true if v:sub(1,1) ~= "/" then ap = false v = os.getenv("PWD") .. "/" .. v end v=fs.canonical(v) vw(v.."... ") if fs.isDirectory(v) then vp("directory.") for file in fs.list(v) do if ap then args[#args+1] = v.."/"..file else args[#args+1] = v:sub(os.getenv("PWD"):len()+2).."/"..file end end else local fsize = fs.size(v) local inputf = io.open(v,"rb") if fsize and inputf then local c = 0 if ap then f:write(mtar.genHeader(v,fsize)) else f:write(mtar.genHeader(v:sub(os.getenv("PWD"):len()+2),fsize)) end while true do local ib = inputf:read(4096) if ib then c=c+ib:len() f:write(ib) else break end end vp(c) else vp("failed to open.") end end end f:close() else print([[Usage: mtar -[crtxvz] [otherfile] [otherfile] Operations: x: extract archive c: create archive t: list contents of archive Flags: v: be verbose z: use LZSS compression (requires liblz16)]]) end