nx_untar.nx
buildroot/runtime/nx_untar.nx
about
nx_untar.nx -- extract files from a USTAR archive (.tar or .tar.gz) into a directory INSIDE the sovereign
write boundary. The missing verb between nx_research_fetch (which mirrors a tarball into
knowledge/fetched/ with a pinned sha) and every organ that needs one of the files inside it.
nx_untar <archive.tar|archive.tar.gz> <outdir> [name-substring]
Composes the incumbents, never re-implements them: nx_inflate (inf_gunzip) for the .gz layer and
nx_tar (nxtar_read) for the entries. The decompressed size is DERIVED from the gzip ISIZE trailer --
the format's own declaration -- so there is no reserve to guess and no cap to raise. Entries are
written FLAT (basename only, 0644) into <outdir>, which must begin with knowledge/ or /tmp/ (the same
boundary nx_mkdirp enforces); anything else is refused before a byte is written. A substring filter
selects entries by name; with none, every regular file is written.
Every written file is announced with its byte count so absence is visible in normal output, and the
summary partition (entries = files + dirs + other) is printed and must sum. Exit: 0 written>0 |
2 usage/boundary | 3 archive unreadable | 4 nothing matched (EMPTY is not a pass).
First use 2026-09-02: landing LiberationSans-Regular.ttf on the NAS for the browser face (BR26).
license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_inflate.nxnx_tar.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 22 | const UT_MODE_644: i64 = 420 |
| 23 | const UT_MODE_DIR: i64 = 493 |
| 24 | const UT_GZ_TRAILER: i64 = 8 // gzip: CRC32 + ISIZE, little-endian, at the very end |
| 25 | const UT_PATH_CAP: i64 = 4096 |
| 26 | const UT_FLD_SLOTS: i64 = 8 |
| 27 | const UT_EXIT_USAGE: i64 = 2 |
| 28 | const UT_EXIT_UNREADABLE: i64 = 3 |
| 29 | const UT_EXIT_EMPTY: i64 = 4 |
functions
| 31 | func ut_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 32 | func ut_e(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } |
| 33 | func ut_num(v: i64) -> i64 |
| 46 | func ut_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 47 | func ut_starts(s: *u8, p: *u8) -> i64 called by 1: main |
| 52 | func ut_ends_gz(s: *u8) -> i64 |
| 61 | func ut_contains(d: *u8, off: i64, len: i64, sub: *u8) -> i64 |
| 75 | func ut_rd32le(b: *u8, o: i64) -> i64 { return (b[o] as i64) + (b[o+1] as i64)*256 + (b[o+2] as i64)*65536 + (b[o+3] as i64)*16777216 } called by 1: main |
| 77 | func main(argc: i64, argv: *i64) -> i64 |