Files
cell/qopconv.ce
2026-01-19 01:06:45 -06:00

146 lines
3.8 KiB
Plaintext

var fd = use('fd')
var qop = use('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_path) {
var blob = fd.slurp(archive_path)
if (!blob) {
log.console("Could not open archive " + archive_path)
return
}
var archive = null
try {
archive = qop.open(blob)
} catch(e) {
log.console("Could not open archive " + archive_path + ": " + e.message)
return
}
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)
if (!blob) {
log.console("Could not open archive " + archive_path)
return
}
var archive = null
try {
archive = qop.open(blob)
} catch(e) {
log.console("Could not open archive " + archive_path + ": " + e.message)
return
}
var files = archive.list()
arrfor(files, function(f) {
var data = archive.read(f)
if (data) {
// Ensure directory exists
var dir = fd.dirname(f)
if (dir) {
// recursive mkdir
var parts = array(dir, '/')
var curr = "."
arrfor(parts, function(p) {
curr += "/" + p
try { fd.mkdir(curr) } catch(e) {}
})
}
var 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
if (path == ".") full_path = base_dir
if (read_dir == null && path != ".") full_path = path
var st = fd.stat(full_path)
if (!st) {
log.console("Could not stat " + full_path)
return
}
if (st.isDirectory) {
var list = fd.readdir(full_path)
arrfor(list, function(item) {
if (item == "." || item == "..") return
var sub = path == "." ? item : path + "/" + item
add_recursive(sub)
})
} else {
var 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)
}
if (!is_array(arg) || length(arg) < 1) {
print_usage()
} else {
if (arg[0] == "-l") {
if (length(arg) < 2) print_usage()
else list(arg[1])
} else if (arg[0] == "-u") {
if (length(arg) < 2) print_usage()
else unpack(arg[1])
} else {
var sources = []
var archive = null
var read_dir = null
var i = 0
if (arg[0] == "-d") {
read_dir = arg[1]
i = 2
}
for (; i < length(arg) - 1; i++) {
sources.push(arg[i])
}
archive = arg[length(arg) - 1]
if (length(sources) == 0) {
print_usage()
} else {
pack(sources, archive, read_dir)
}
}
}
$stop()