added an mtar utility for OpenOS
This commit is contained in:
parent
7e41ce6ee2
commit
9e7d778e21
126
mtar/OpenOS/usr/bin/mtar.lua
Normal file
126
mtar/OpenOS/usr/bin/mtar.lua
Normal file
@ -0,0 +1,126 @@
|
||||
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] <archivefile> [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
|
30
mtar/OpenOS/usr/man/mtar
Normal file
30
mtar/OpenOS/usr/man/mtar
Normal file
@ -0,0 +1,30 @@
|
||||
# mtar - Minitel Archiver
|
||||
## Usage
|
||||
|
||||
mtar -[crtxvz] <archivefile> [otherfile] [otherfile]
|
||||
|
||||
## Operations
|
||||
|
||||
x: extract archive
|
||||
c: create archive
|
||||
t: list contents of archive
|
||||
|
||||
## Flags
|
||||
|
||||
v: be verbose
|
||||
z: use LZSS compression (requires liblz16)]])
|
||||
|
||||
## Examples
|
||||
|
||||
Extract archive *example.mtar*
|
||||
|
||||
mtar -x example.mtar
|
||||
|
||||
Show the files in compressed archive *example.mtar.lss*
|
||||
|
||||
mtar -tz example.mtar.lss
|
||||
|
||||
Create a compressed archive *example.mtar.lss* from file *fun* and folder *junk*
|
||||
|
||||
mtar -cz example.mtar.lss fun junk/
|
||||
|
@ -20,15 +20,11 @@ local function mkdir(dir)
|
||||
end
|
||||
|
||||
local function toint(s)
|
||||
s=s or ""
|
||||
local n = 0
|
||||
local i = 1
|
||||
while true do
|
||||
local p = s:sub(i,i)
|
||||
if p == "" then break end
|
||||
local b = string.byte(p)
|
||||
for p in s:gmatch(".") do
|
||||
n = n << 8
|
||||
n = n | b
|
||||
n = n | string.byte(p)
|
||||
i=i+1
|
||||
end
|
||||
return n
|
||||
@ -58,17 +54,18 @@ function mtar.genHeader(fname,len) -- generate a header for file *fname* when pr
|
||||
return string.format("%s%s%s",cint(fname:len(),2),fname,cint(len,2))
|
||||
end
|
||||
|
||||
function mtar.unarchive(stream,dest)
|
||||
function mtar.unarchive(stream,dest,verbose) -- Extract mtar archive read from *stream* to *dest*. If *verbose*, print status.
|
||||
dest = dest or "."
|
||||
mkdir(dest)
|
||||
while true do
|
||||
local nlen = toint(stream:read(2))
|
||||
local nlen = toint(stream:read(2) or "\0\0")
|
||||
if nlen == 0 then
|
||||
break
|
||||
end
|
||||
local name = cleanPath(stream:read(nlen))
|
||||
local fsize = toint(stream:read(2))
|
||||
print(name,fsize)
|
||||
if verbose then
|
||||
io.write(name.." "..tostring(fsize).."... ")
|
||||
end
|
||||
local dir = name:match("(.+)/.*%.?.+")
|
||||
if (dir) then
|
||||
mkdir(dir)
|
||||
@ -77,12 +74,18 @@ function mtar.unarchive(stream,dest)
|
||||
local rsize,buf = fsize, ""
|
||||
if f then
|
||||
repeat
|
||||
buf = stream:read(math.min(rsize,1024))
|
||||
buf = stream:read(math.min(rsize,2048))
|
||||
f:write(buf)
|
||||
rsize = rsize - buf:len()
|
||||
if verbose then
|
||||
io.write(tostring(rsize).." ")
|
||||
end
|
||||
until rsize <= 1
|
||||
f:close()
|
||||
end
|
||||
if verbose then
|
||||
print("done.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user