code wiki / _hdl_build / nx_janitor_dupname.nx

nx_janitor_dupname.nx source

↩ module page · 96 lines · 5379 B

1// nx_janitor_dupname.nx -- the "dup" part of the janitor's X-JAN-002 sprawl half (nx_janitor_sprawl already 2// covers the "dead-organ"/orphaned-.tsv part; this is its sibling). It detects DUPLICATE ORGAN NAMES = 3// SHADOWING collisions: the SAME basename in BOTH runtime/_hdl_build/ AND runtime/. nx_sov_build_run probes 4// _hdl_build/ FIRST, so the _hdl_build copy SHADOWS the runtime one -- you run "nx_foo" by name and get the 5// WRONG organ. This is the exact bug found this session (TWO nx_sovereignty_audit.nx: a per-file in-content 6// checker shadowing the tree-walking debt counter). Sovereign getdents walk of the two dirs, intersect the 7// basenames, flag every shadowed organ. READ-ONLY (never-brick): it FLAGS; renaming/resolving stays operator- 8// gated (build pipelines + callers must be checked first). license_tier: ORIGINAL 9import "nx_syscalls.nx" 10 11func jdn_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 } 12func jdn_is_nx(nm: *u8) -> i64 { var nl: i64=0; while nm[nl]!=(0 as u8){nl=nl+1} if nl>3 { if nm[nl-3]==(46 as u8) { if nm[nl-2]==(110 as u8) { if nm[nl-1]==(120 as u8) { return 1 } } } } return 0 } 13 14// collect .nx basenames from `dir` into fnames (NUL-term each) + fnoff[k]=start-offset; appends from startk. 15func jdn_collect(dir: *u8, fnames: *u8, fnoff: *i64, startk: i64, maxk: i64) -> i64 { 16 let fd: i64 = sys_openat_rd(dir); if fd < 0 { return startk } 17 let dbuf: *u8 = sys_mmap(131072) 18 var k: i64 = startk; var go: i64 = 1 19 while go == 1 { 20 let nb: i64 = sys_getdents64(fd, dbuf, 131072) 21 if nb <= 0 { go = 0 } else { 22 var off: i64 = 0 23 while off < nb { 24 let rec: *u8 = (dbuf as i64 + off) as *u8 25 let rl: i64 = dirent_reclen(rec) 26 if rl <= 0 { off = nb } else { 27 let nm: *u8 = dirent_name(rec) 28 if jdn_is_nx(nm) == 1 { if k < maxk { 29 let start: i64 = fnoff[k] 30 var c: i64 = 0; while nm[c] != (0 as u8) { fnames[start+c] = nm[c]; c = c + 1 } fnames[start+c] = 0 as u8 31 fnoff[k+1] = start + c + 1 32 k = k + 1 33 } } 34 off = off + rl 35 } 36 } 37 } 38 } 39 sys_close(fd) 40 return k 41} 42 43// scan both dirs in the runner's PROBE ORDER: _hdl_build first ([0,hcount)), then runtime ([hcount,NF)). NF. 44func jdn_scan(fnames: *u8, fnoff: *i64, hcount_out: *i64) -> i64 { 45 fnoff[0] = 0 46 let h: i64 = jdn_collect("runtime/_hdl_build\x00" as *u8, fnames, fnoff, 0, 30000) 47 hcount_out[0] = h 48 let nf: i64 = jdn_collect("runtime\x00" as *u8, fnames, fnoff, h, 30000) 49 return nf 50} 51 52// is the runtime entry at idx ([hcount,NF)) shadowed by an _hdl_build entry ([0,hcount))? 53func jdn_is_shadowed(fnames: *u8, fnoff: *i64, idx: i64, hcount: i64) -> i64 { 54 let nm: *u8 = (fnames as i64 + fnoff[idx]) as *u8 55 var j: i64 = 0 56 while j < hcount { if jdn_streq(nm, (fnames as i64 + fnoff[j]) as *u8) == 1 { return 1 } j = j + 1 } 57 return 0 58} 59// count shadowing collisions (runtime organs whose name is ALSO in _hdl_build -> the runtime one is unreachable). 60func jdn_collisions(fnames: *u8, fnoff: *i64, hcount: i64, NF: i64) -> i64 { 61 var c: i64 = 0; var i: i64 = hcount 62 while i < NF { if jdn_is_shadowed(fnames, fnoff, i, hcount) == 1 { c = c + 1 } i = i + 1 } 63 return c 64} 65// is a specific basename present in BOTH dirs (a named collision)? 66func jdn_is_collision(fnames: *u8, fnoff: *i64, hcount: i64, NF: i64, name: *u8) -> i64 { 67 var inh: i64 = 0; var j: i64 = 0 68 while j < hcount { if jdn_streq((fnames as i64 + fnoff[j]) as *u8, name) == 1 { inh = 1 } j = j + 1 } 69 if inh == 0 { return 0 } 70 var i: i64 = hcount 71 while i < NF { if jdn_streq((fnames as i64 + fnoff[i]) as *u8, name) == 1 { return 1 } i = i + 1 } 72 return 0 73} 74 75// ---- content classification: is a collision a dangerous SHADOW (different bytes) or a redundant COPY (same)? ---- 76func jdn_read(path: *u8, buf: *u8, cap: i64) -> i64 { 77 let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 - 1 } 78 var total: i64 = 0; var nrd: i64 = sys_read(fd, buf, cap) 79 while nrd > 0 { total = total + nrd; if total >= cap { nrd = 0 } else { nrd = sys_read(fd, ((buf as i64)+total) as *u8, cap-total) } } 80 sys_close(fd); return total 81} 82func jdn_path(pfx: *u8, name: *u8, out: *u8) -> i64 { var o: i64=0; var i: i64=0; while pfx[i]!=(0 as u8){out[o]=pfx[i];o=o+1;i=i+1} i=0; while name[i]!=(0 as u8){out[o]=name[i];o=o+1;i=i+1} out[o]=0 as u8; return o } 83// do runtime/<name> and runtime/_hdl_build/<name> DIFFER? 1 = SHADOW (different content, wrong organ runs) | 84// 0 = COPY (byte-identical, just redundant) | -1 = read error. Caller provides two reusable read buffers. 85func jdn_pair_differs(name: *u8, br: *u8, bh: *u8, cap: i64) -> i64 { 86 let pr: *u8 = sys_mmap(1024); let ph: *u8 = sys_mmap(1024) 87 jdn_path("runtime/\x00" as *u8, name, pr) 88 jdn_path("runtime/_hdl_build/\x00" as *u8, name, ph) 89 let lr: i64 = jdn_read(pr, br, cap); let lh: i64 = jdn_read(ph, bh, cap) 90 if lr < 0 { return 0 - 1 } 91 if lh < 0 { return 0 - 1 } 92 if lr != lh { return 1 } 93 var i: i64 = 0 94 while i < lr { if br[i] != bh[i] { return 1 } i = i + 1 } 95 return 0 96}