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}