Files
cell/qopconv.ce

165 lines
4.2 KiB
Plaintext

// cell qopconv - Convert QOP archive formats
var fd = use('fd')
var qop = use('internal/qop')
function print_usage() {
log.console("Usage: qopconv [OPTION...] FILE...")
log.console(" -u <archive> .. unpack archive")
log.console(" -l <archive> .. list contents of archive")
log.console(" -d <dir> ....... change read dir when creating archives")
log.console(" <sources...> <archive> .. create archive from sources")
}
function list_archive(archive_path) {
var blob = fd.slurp(archive_path)
var archive = null
if (!blob) {
log.console("Could not open archive " + archive_path)
return
}
var _open = function() {
archive = qop.open(blob)
} disruption {
log.console("Could not open archive " + archive_path)
return
}
_open()
var files = archive.list()
arrfor(files, function(f) {
var s = archive.stat(f)
// Format: index hash size path
// We don't have index/hash easily available in JS binding yet, just size/path
log.console(`${f} (${s.size} bytes)`)
})
archive.close()
}
function unpack(archive_path) {
var blob = fd.slurp(archive_path)
var archive = null
if (!blob) {
log.console("Could not open archive " + archive_path)
return
}
var _open = function() {
archive = qop.open(blob)
} disruption {
log.console("Could not open archive " + archive_path)
return
}
_open()
var files = archive.list()
arrfor(files, function(f) {
var data = archive.read(f)
var dir = null
var parts = null
var curr = null
var fh = null
var _mk = null
if (data) {
// Ensure directory exists
dir = fd.dirname(f)
if (dir) {
// recursive mkdir
parts = array(dir, '/')
curr = "."
arrfor(parts, function(p) {
curr += "/" + p
_mk = function() { fd.mkdir(curr) } disruption {}
_mk()
})
}
fh = fd.open(f, "w")
fd.write(fh, data)
fd.close(fh)
log.console("Extracted " + f)
}
})
archive.close()
}
function pack(sources, archive_path, read_dir) {
var writer = qop.write(archive_path)
var base_dir = read_dir || "."
function add_recursive(path) {
var full_path = base_dir + "/" + path
var st = null
var list = null
var data = null
if (path == ".") full_path = base_dir
if (read_dir == null && path != ".") full_path = path
st = fd.stat(full_path)
if (!st) {
log.console("Could not stat " + full_path)
return
}
if (st.isDirectory) {
list = fd.readdir(full_path)
arrfor(list, function(item) {
if (item == "." || item == "..") return
var sub = path == "." ? item : path + "/" + item
add_recursive(sub)
})
} else {
data = fd.slurp(full_path)
if (data) {
writer.add_file(path, data)
log.console("Added " + path)
}
}
}
arrfor(sources, function(s) {
add_recursive(s)
})
writer.finalize()
log.console("Created " + archive_path)
}
var sources = null
var archive = null
var read_dir = null
var i = 0
if (!is_array(args) || length(args) < 1) {
print_usage()
} else {
if (args[0] == "-l") {
if (length(args) < 2) print_usage()
else list_archive(args[1])
} else if (args[0] == "-u") {
if (length(args) < 2) print_usage()
else unpack(args[1])
} else {
sources = []
archive = null
read_dir = null
i = 0
if (args[0] == "-d") {
read_dir = args[1]
i = 2
}
for (; i < length(args) - 1; i++) {
push(sources, args[i])
}
archive = args[length(args) - 1]
if (length(sources) == 0) {
print_usage()
} else {
pack(sources, archive, read_dir)
}
}
}
$stop()