code wiki / (root) / nx_sevenz.nx

nx_sevenz.nx source

↩ module page · 162 lines · 8325 B

1// nx_sevenz.nx -- THE 7z ARCHIVE COMMAND (/compare/modding MD29 sz_walk, 2026-09-06). A thin caller of nx_sevenz_lib so the 2// command line and the bundle walker read a 7z through ONE container reader and ONE decoder (nx_lzma_lib), and every member's 3// bytes are checked against the archive's OWN CRC-32 digest -- the container is the oracle for the decoder. 4// usage: nx_sevenz list <archive.7z> one MEMBER row per non-directory file, then one SEVENZ summary row 5// nx_sevenz extract <archive.7z> <idx> <out_path> write member idx (its decode must be OK or STORED) 6// exits: 0 every data member decoded and CRC-verified | 2 usage | 3 REFUSED (unreadable, not a 7z, truncated, a CRC or the 7// header refused -- the reason is on the line) | 4 walked, but a member failed or its coder is unsupported (named per row) 8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_sevenz_lib.nx" 11 12const SZC_EXIT_USAGE: i64 = 2 13const SZC_EXIT_REFUSE: i64 = 3 14const SZC_EXIT_MEMBER: i64 = 4 15const SZC_OUTFD: i64 = 1 16const SZC_MODE_0644: i64 = 420 17const SZC_NAMES_HEADROOM: i64 = 4096 18const SZC_ST_N: i64 = 8 19 20func szc_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 21func szc_w(s: *u8) -> i64 { sys_write(SZC_OUTFD, s, szc_len(s)); return 0 } 22func szc_wn(v: i64) -> i64 { 23 let t: *u8 = sys_mmap(32) 24 var m: i64 = v 25 var w: i64 = 0 26 if m < 0 { t[0] = 45 as u8; sys_write(SZC_OUTFD, t, 1); m = 0 - m } 27 if m == 0 { t[0] = 48 as u8; sys_write(SZC_OUTFD, t, 1); return 0 } 28 let d: *u8 = sys_mmap(32) 29 var k: i64 = 0 30 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 31 var j: i64 = 0 32 while j < k { t[w] = d[k - 1 - j]; w = w + 1; j = j + 1 } 33 sys_write(SZC_OUTFD, t, w) 34 return 0 35} 36func szc_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 } 37func szc_atoi(s: *u8) -> i64 { var v: i64 = 0; var i: i64 = 0; while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c < 48 { return 0 - 1 } if c > 57 { return 0 - 1 } v = v * 10 + (c - 48); i = i + 1 } if i == 0 { return 0 - 1 } return v } 38// on a refusal, the parse detail the error name alone cannot carry: what the header's first coder was 39func szc_detail(b: *u8, n: i64) -> i64 { 40 let m: *i64 = sys_mmap(8 * SZ_M_N) as *i64 41 sz_parse(b, n, m) 42 szc_w(" folders=" as *u8); szc_wn(m[SZ_M_NFOLD]) 43 szc_w(" hdr_coders=" as *u8); szc_wn(m[SZ_M_HDR_NCODERS]) 44 szc_w(" hdr_coder_id=" as *u8); szc_wn(m[SZ_M_HDR_CODERID]) 45 szc_w(" encoded=" as *u8); szc_wn(m[SZ_M_ENCODED]) 46 return 0 47} 48func szc_usage() -> i64 { szc_w("usage: nx_sevenz list <archive.7z> | extract <archive.7z> <idx> <out_path>\n" as *u8); return SZC_EXIT_USAGE } 49 50// walk once; returns the row count or a named negative error already printed 51func szc_walk(path: *u8, out_tbl: *i64, out_names: *i64, st: *i64) -> i64 { 52 let lp: *i64 = sys_mmap(16) as *i64 53 let b: *u8 = sys_read_file(path, lp) 54 if (b as i64) == 0 { szc_w("SEVENZ-REFUSE unreadable: " as *u8); szc_w(path); szc_w("\n" as *u8); return 0 - 1 } 55 let n: i64 = lp[0] 56 let total: i64 = sz_count(b, n) 57 if total < 0 { szc_w("SEVENZ-REFUSE " as *u8); szc_w(sz_err_name(total)); szc_w(" bytes=" as *u8); szc_wn(n); szc_detail(b, n); szc_w("\n" as *u8); return 0 - 1 } 58 let tbl: *i64 = sys_mmap(8 * BI_F_N * (total + 1)) as *i64 59 let ncap: i64 = n * 2 + SZC_NAMES_HEADROOM 60 let names: *u8 = sys_mmap(ncap) 61 let m: i64 = sz_walk(b, n, tbl, total, names, ncap, st) 62 if m < 0 { szc_w("SEVENZ-REFUSE walk " as *u8); szc_w(sz_err_name(m)); szc_w("\n" as *u8); return 0 - 1 } 63 out_tbl[0] = tbl as i64 64 out_names[0] = names as i64 65 st[4] = n 66 return m 67} 68 69func szc_row(tbl: *i64, names: *u8, i: i64) -> i64 { 70 let r: *i64 = bi_rec(tbl, i) 71 szc_w("MEMBER idx=" as *u8); szc_wn(i) 72 szc_w(" name=" as *u8); sys_write(SZC_OUTFD, names + r[BI_F_NAMEOFF], r[BI_F_NAMELEN]) 73 szc_w(" coder=" as *u8); szc_w(sz_coder_name(r[BI_F_METHOD])) 74 szc_w(" folder_pack=" as *u8); szc_wn(r[BI_F_CSIZE]) 75 szc_w(" usize=" as *u8); szc_wn(r[BI_F_USIZE]) 76 szc_w(" crc=" as *u8); szc_wn(r[BI_F_CRC]) 77 szc_w(" decode=" as *u8); szc_w(bi_inflate_name(r[BI_F_INFLATE])) 78 szc_w(" magic=" as *u8); szc_w(ap_name(r[BI_F_MAGIC])) 79 szc_w(" category=" as *u8); szc_w(ap_catname(r[BI_F_CAT])) 80 szc_w(" claim=" as *u8); szc_w(ap_name(r[BI_F_CLAIM])) 81 szc_w(" verdict=" as *u8); szc_w(bi_verdict_name(r[BI_F_VERDICT])) 82 szc_w("\n" as *u8) 83 return 0 84} 85 86func main(argc: i64, argv: *i64) -> i64 { 87 if argc < 3 { return szc_usage() } 88 let verb: *u8 = argv[1] as *u8 89 let path: *u8 = argv[2] as *u8 90 let ot: *i64 = sys_mmap(16) as *i64 91 let on: *i64 = sys_mmap(16) as *i64 92 let st: *i64 = sys_mmap(8 * SZC_ST_N) as *i64 93 if szc_streq(verb, "list" as *u8) == 1 { 94 let m: i64 = szc_walk(path, ot, on, st) 95 if m < 0 { return SZC_EXIT_REFUSE } 96 let tbl: *i64 = ot[0] as *i64 97 let names: *u8 = on[0] as *u8 98 var ok: i64 = 0 99 var stored: i64 = 0 100 var failed: i64 = 0 101 var unsupported: i64 = 0 102 var empty: i64 = 0 103 var i: i64 = 0 104 while i < m { 105 let r: *i64 = bi_rec(tbl, i) 106 szc_row(tbl, names, i) 107 if r[BI_F_USIZE] == 0 { if r[BI_F_INFLATE] == BI_INF_STORED { empty = empty + 1 } } 108 else { 109 if r[BI_F_INFLATE] == BI_INF_OK { ok = ok + 1 } 110 else { if r[BI_F_INFLATE] == BI_INF_STORED { stored = stored + 1 } 111 else { if r[BI_F_INFLATE] == BI_INF_UNSUPPORTED { unsupported = unsupported + 1 } else { failed = failed + 1 } } } 112 } 113 i = i + 1 114 } 115 let data: i64 = m - empty 116 var verdict: *u8 = "GREEN" as *u8 117 var rc: i64 = 0 118 if failed + unsupported > 0 { verdict = "RED" as *u8; rc = SZC_EXIT_MEMBER } 119 if ok + stored + failed + unsupported != data { verdict = "RED-partition-does-not-sum" as *u8; rc = SZC_EXIT_MEMBER } 120 szc_w("SEVENZ members=" as *u8); szc_wn(m) 121 szc_w(" data=" as *u8); szc_wn(data) 122 szc_w(" empty=" as *u8); szc_wn(empty) 123 szc_w(" dirs=" as *u8); szc_wn(st[0]) 124 szc_w(" folders=" as *u8); szc_wn(st[2]) 125 szc_w(" encoded_header=" as *u8); szc_wn(st[3]) 126 szc_w(" bytes=" as *u8); szc_wn(st[4]) 127 szc_w(" ok=" as *u8); szc_wn(ok) 128 szc_w(" stored=" as *u8); szc_wn(stored) 129 szc_w(" failed=" as *u8); szc_wn(failed) 130 szc_w(" unsupported=" as *u8); szc_wn(unsupported) 131 szc_w(" verdict=" as *u8); szc_w(verdict); szc_w("\n" as *u8) 132 return rc 133 } 134 if szc_streq(verb, "extract" as *u8) == 1 { 135 if argc < 5 { return szc_usage() } 136 let idx: i64 = szc_atoi(argv[3] as *u8) 137 if idx < 0 { return szc_usage() } 138 let m: i64 = szc_walk(path, ot, on, st) 139 if m < 0 { return SZC_EXIT_REFUSE } 140 if idx >= m { szc_w("SEVENZ-REFUSE idx out of range members=" as *u8); szc_wn(m); szc_w("\n" as *u8); return SZC_EXIT_REFUSE } 141 let tbl: *i64 = ot[0] as *i64 142 let r: *i64 = bi_rec(tbl, idx) 143 var readable: i64 = 0 144 if r[BI_F_INFLATE] == BI_INF_OK { readable = 1 } 145 if r[BI_F_INFLATE] == BI_INF_STORED { readable = 1 } 146 if readable == 0 { szc_w("SEVENZ-REFUSE member not decodable: " as *u8); szc_w(bi_inflate_name(r[BI_F_INFLATE])); szc_w("\n" as *u8); return SZC_EXIT_MEMBER } 147 let outp: *u8 = argv[4] as *u8 148 let fd: i64 = sys_openat_wr(outp, SZC_MODE_0644) 149 if fd < 0 { szc_w("SEVENZ-REFUSE out not writable: " as *u8); szc_w(outp); szc_w("\n" as *u8); return SZC_EXIT_REFUSE } 150 var wrote: i64 = 0 151 if r[BI_F_DLEN] > 0 { wrote = sys_write(fd, r[BI_F_DATA] as *u8, r[BI_F_DLEN]) } 152 sys_close(fd) 153 szc_w("SEVENZ-EXTRACT idx=" as *u8); szc_wn(idx) 154 szc_w(" bytes=" as *u8); szc_wn(wrote) 155 szc_w(" of=" as *u8); szc_wn(r[BI_F_DLEN]) 156 szc_w(" crc=" as *u8); szc_wn(r[BI_F_CRC]) 157 szc_w(" out=" as *u8); szc_w(outp); szc_w("\n" as *u8) 158 if wrote != r[BI_F_DLEN] { return SZC_EXIT_REFUSE } 159 return 0 160 } 161 return szc_usage() 162}