code wiki / _hdl_build / _wiki_cite_gate.nx
_wiki_cite_gate.nx source
↩ module page · 355 lines · 18660 B
1// _wiki_cite_gate.nx -- THE WIKIPEDIA-EXCEED INLINE-CITATION GATE.
2//
3// Re-proves, from a REAL run (no fabricated GREEN), the anti-pushout
4// differentiator: a cited supporting source is rendered INLINE in the wiki
5// (read in place, no leaving for a paywalled/rotted/dead link) -- but ONLY when
6// licensing permits hosting it. Judged on SUBSTRING presence/absence in the
7// actually-rendered HTML (ground truth), never a bare rc==const.
8//
9// inline_ok A CC-BY source S1 ("ALPHA-SUPPORT-EVIDENCE-12345"),
10// archived + license-tagged, rendered via [[cite:<cid>]]
11// -> the HTML CONTAINS the evidence string INSIDE a
12// <details ... nx-cite ...> block (inline reading works).
13// license_respected THE LIAR-KILL: a PROPRIETARY source S2
14// ("PROPRIETARY-SECRET-67890"), archived but NOT hostable,
15// cited -> the HTML CONTAINS a link/license-note for it but
16// does NOT CONTAIN the secret bytes ANYWHERE. Unlicensed
17// content is never inlined -- respected, not merely labeled.
18// pending_ok A random NON-archived cid cited -> the HTML CONTAINS
19// "(source archiving pending)".
20//
21// EXCEED vs Wikipedia: Wikipedia pushes you OUT to a citation that may be dead.
22// Here the supporting source is read IN the page, pulled from the no-link-rot
23// content-addressed archive, gated by a sealed license layer so we never host
24// what we are not licensed to host.
25//
26// Determinism: a FRESH store prefix keyed by the wall-clock epoch => an empty
27// archive each run (idempotent re-run, Rule 10). Production archive prefix is
28// knowledge/store/wikiarchive- (in nx_wiki_archive).
29//
30// Verdict line (judged by this marker; stdout + knowledge/status):
31// WIKICITE inline_ok=<0|1> license_respected=<0|1> pending_ok=<0|1>
32// verdict=GREEN|RED
33//
34// Pure NishiLang, NO SQL, NO .sh/.py/.js, no new .tsv/.conf. nx_sites_daemon
35// UNTOUCHED. Imports the cite-render organ under test (which transitively pulls
36// the license layer + archive + seg_store + canon_cid, each spliced ONCE).
37// license_tier: ORIGINAL
38import "nx_syscalls.nx"
39import "nx_wiki_cite_render.nx"
40// Served-path handler under test: drives the REAL post-markdown render so the
41// inline-card check is judged on the SERVED bytes (closing the measurement
42// artifact -- the old gate only checked the PRE-markdown cite-render buffer,
43// which could pass while the served card was html-escaped). The resolver
44// path-dedups the shared cite/license/archive chain (no rc6 double-import).
45import "wiki/nx_wiki_index_builder.nx"
46import "wiki/nx_wiki_doc_handler.nx"
47import "wiki/nx_artifact_store.nx"
48
49const WCG_LOG: *u8 = "knowledge/status/wiki_cite_gate.log"
50const WCG_RESP_CAP: i64 = 2097152 // 2 MiB served-response buffer
51const WCG_CAP: i64 = 64 // manifest segment-scan cap (>> our few commits)
52const WCG_OUTCAP: i64 = 1048576 // rendered-HTML output buffer (1 MiB headroom)
53
54// ---- io helpers (mirror _wiki_archive_gate.nx) ----
55func wcg_w(fd: i64, s: *u8) -> i64 {
56 var n: i64 = 0
57 while s[n] != (0 as u8) { n = n + 1 }
58 sys_write(fd, s, n)
59 return 0
60}
61func wcg_n(fd: i64, v: i64) -> i64 {
62 let bb: *u8 = sys_mmap(28)
63 var m: i64 = v
64 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }
65 let t: *u8 = sys_mmap(28)
66 var k: i64 = 0
67 if m == 0 { t[0] = 48 as u8; k = 1 }
68 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
69 var i: i64 = 0
70 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
71 sys_write(fd, bb, k)
72 return 0
73}
74// write to BOTH stdout (gate evidence) and the durable log
75func wcg_w2(lfd: i64, s: *u8) -> i64 { wcg_w(1, s); if lfd >= 0 { wcg_w(lfd, s) } return 0 }
76func wcg_n2(lfd: i64, v: i64) -> i64 { wcg_n(1, v); if lfd >= 0 { wcg_n(lfd, v) } return 0 }
77
78func wcg_p(s: *u8) -> i64 { wcg_w(1, s); return 0 }
79func wcg_pn(v: i64) -> i64 { wcg_n(1, v); return 0 }
80func wcg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
81
82// concat NUL-terminated s into dst at off; returns new off
83func wcg_cat(dst: *u8, off: i64, s: *u8) -> i64 {
84 var i: i64 = 0
85 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
86 return off + i
87}
88// append decimal of v into dst at off; returns new off
89func wcg_catn(dst: *u8, off: i64, v: i64) -> i64 {
90 var m: i64 = v
91 var o: i64 = off
92 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m }
93 let t: *u8 = sys_mmap(28)
94 var k: i64 = 0
95 if m == 0 { t[0] = 48 as u8; k = 1 }
96 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
97 var i: i64 = 0
98 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
99 return o + k
100}
101
102// ===== GROUND-TRUTH SUBSTRING SEARCH ==========================================
103// Does buffer hay[0..hn] contain the NUL-terminated needle as a contiguous
104// substring? Returns the start index (>=0) or -1 if absent. THIS is how the
105// gate judges -- on what is actually in the rendered HTML, not a return code.
106func wcg_find(hay: *u8, hn: i64, needle: *u8) -> i64 {
107 let nn: i64 = wcg_slen(needle)
108 if nn == 0 { return 0 - 1 }
109 if nn > hn { return 0 - 1 }
110 var i: i64 = 0
111 let last: i64 = hn - nn
112 while i <= last {
113 var j: i64 = 0
114 var eq: i64 = 1
115 while j < nn {
116 if eq == 1 { if hay[i + j] != needle[j] { eq = 0 } }
117 j = j + 1
118 }
119 if eq == 1 { return i }
120 i = i + 1
121 }
122 return 0 - 1
123}
124// boolean contains
125func wcg_has(hay: *u8, hn: i64, needle: *u8) -> i64 {
126 if wcg_find(hay, hn, needle) >= 0 { return 1 }
127 return 0
128}
129
130func main() -> i64 {
131 wcg_p("WIKICITE-GATE: start (inline supporting source, license-aware anti-pushout)\n" as *u8)
132
133 // ---- FRESH per-run store prefix => empty archive each run (deterministic) ----
134 let prefix: *u8 = sys_mmap(256)
135 var po: i64 = 0
136 po = wcg_cat(prefix, po, "knowledge/store/wikiarchive-citegate-" as *u8)
137 po = wcg_catn(prefix, po, sys_now_realtime_sec())
138 po = wcg_cat(prefix, po, "-" as *u8)
139 prefix[po] = 0 as u8
140 wcg_p(" store prefix = " as *u8); wcg_p(prefix); wcg_p("\n" as *u8)
141
142 // shared rendered-HTML output buffer + a "used length" cell
143 let out: *u8 = sys_mmap(WCG_OUTCAP)
144 let used: *i64 = sys_mmap(16) as *i64
145
146 // distinctive content strings the gate searches for in the HTML
147 let evidence: *u8 = "ALPHA-SUPPORT-EVIDENCE-12345" as *u8
148 let secret: *u8 = "PROPRIETARY-SECRET-67890" as *u8
149
150 // ===== STEP 1: archive S1 (CC-BY) + render a page citing it -> INLINE ======
151 // S1 is a hostable supporting source; its evidence MUST appear inline inside
152 // a <details ... nx-cite> card.
153 let s1_slug: *u8 = "src-s1" as *u8
154 let s1_body: *u8 = "Supporting evidence: ALPHA-SUPPORT-EVIDENCE-12345 (full text of the cited source).\n" as *u8
155 let cid_s1: *u8 = sys_mmap(80)
156 let w1: *i64 = ss_begin()
157 let r1: i64 = war_archive_page(w1, s1_slug, s1_body, wcg_slen(s1_body), cid_s1)
158 let c1: i64 = ss_commit(prefix, w1, 0)
159 wcg_p(" S1 archived rc=" as *u8); wcg_pn(r1); wcg_p(" commit=" as *u8); wcg_pn(c1); wcg_p(" cid=" as *u8); wcg_p(cid_s1); wcg_p("\n" as *u8)
160 // tag S1 as CC-BY (hostable, attribution required)
161 let lset1: i64 = nx_wiki_license_set(prefix, cid_s1, NXLIC_CC_BY, 1)
162 wcg_p(" S1 license set CC_BY rc=" as *u8); wcg_pn(lset1); wcg_p(" (get=" as *u8); wcg_pn(nx_wiki_license_get(prefix, cid_s1)); wcg_p(")\n" as *u8)
163
164 // build a page body: "... [[cite:<cid_s1>]] ..."
165 let pg1: *u8 = sys_mmap(512)
166 var g1: i64 = 0
167 g1 = wcg_cat(pg1, g1, "See the supporting source here: [[cite:" as *u8)
168 g1 = wcg_cat(pg1, g1, cid_s1)
169 g1 = wcg_cat(pg1, g1, "]] -- read it in place.\n" as *u8)
170 pg1[g1] = 0 as u8
171
172 let rr1: i64 = nx_wiki_cite_render(prefix, pg1, g1, out, WCG_OUTCAP, used)
173 let hn1: i64 = used[0]
174 wcg_p(" render1 rc=" as *u8); wcg_pn(rr1); wcg_p(" html_len=" as *u8); wcg_pn(hn1); wcg_p("\n" as *u8)
175
176 // JUDGE inline_ok on GROUND TRUTH, on BOTH the organ output AND the SERVED
177 // (post-markdown) bytes. (1) ORGAN: the cite-render organ emits a <details
178 // nx-cite> card with the evidence inside. (2) SERVED (the artifact-closing
179 // check): render the SAME [[cite:<cid>]] page through the REAL handler
180 // (nx_wiki_doc_handle_cp, cite-prefix-injected) and require the served card be
181 // LIVE -- "<details class=\"nx-cite\"" present, "<details" ABSENT, evidence
182 // inside -- so inline_ok can NO LONGER pass while the served card is escaped.
183 var organ_inline: i64 = 0
184 if rr1 == NXCITE_OK {
185 let det_at: i64 = wcg_find(out, hn1, "<details class=\"nx-cite\">" as *u8)
186 let ev_at: i64 = wcg_find(out, hn1, evidence)
187 let body_at: i64 = wcg_find(out, hn1, "nx-cite-body" as *u8)
188 if det_at >= 0 { if ev_at > det_at { if body_at >= 0 { if ev_at > body_at { organ_inline = 1 } } } }
189 wcg_p(" inline(organ): details@" as *u8); wcg_pn(det_at); wcg_p(" body@" as *u8); wcg_pn(body_at); wcg_p(" evidence@" as *u8); wcg_pn(ev_at); wcg_p("\n" as *u8)
190 }
191 // SERVED: seed a doc store with the cited page, render via the real handler.
192 let cstore: *NxWikiDocStore = sys_mmap(2048) as *NxWikiDocStore
193 let cs_rc: i64 = nx_wiki_doc_store_init(cstore, 16, 4096, 4096, 65536)
194 let cpg: *u8 = sys_mmap(512)
195 var cg: i64 = 0
196 cg = wcg_cat(cpg, cg, "# Cite Gate Page\n\nSee the supporting source here: [[cite:" as *u8)
197 cg = wcg_cat(cpg, cg, cid_s1)
198 cg = wcg_cat(cpg, cg, "]] -- read it in place.\n" as *u8)
199 cpg[cg] = 0 as u8
200 let cpg_rid: i64 = nx_wiki_doc_store_add(cstore,
201 "Cite Gate Page" as *u8, 14, "/wiki/cite-gate-pg" as *u8, 18, cpg, cg)
202 let sresp: *u8 = sys_mmap(WCG_RESP_CAP)
203 let sresp_n: *i64 = sys_mmap(8) as *i64
204 sresp_n[0] = 0
205 let sh_rc: i64 = nx_wiki_doc_handle_cp(cstore, 0 as *NxArtifactStore,
206 "/wiki/cite-gate-pg" as *u8, 18, sresp, WCG_RESP_CAP, sresp_n, prefix)
207 let sn: i64 = sresp_n[0]
208 var served_inline: i64 = 0
209 if sh_rc == NX_WDH_OK {
210 let sdet_at: i64 = wcg_find(sresp, sn, "<details class=\"nx-cite\"" as *u8)
211 let sesc_at: i64 = wcg_find(sresp, sn, "<details" as *u8) // MUST be absent
212 var sev_at: i64 = 0 - 1
213 if sdet_at >= 0 {
214 let stail: *u8 = (sresp as i64 + sdet_at) as *u8
215 let sre: i64 = wcg_find(stail, sn - sdet_at, evidence)
216 if sre >= 0 { sev_at = sdet_at + sre }
217 }
218 if sdet_at >= 0 { if sesc_at < 0 { if sev_at > sdet_at { served_inline = 1 } } }
219 wcg_p(" inline(SERVED): handle_rc=" as *u8); wcg_pn(sh_rc); wcg_p(" rid=" as *u8); wcg_pn(cpg_rid); wcg_p(" resp_len=" as *u8); wcg_pn(sn); wcg_p(" details@" as *u8); wcg_pn(sdet_at); wcg_p(" <details@(should be -1)=" as *u8); wcg_pn(sesc_at); wcg_p(" evidence@" as *u8); wcg_pn(sev_at); wcg_p("\n" as *u8)
220 }
221 var inline_ok: i64 = 0
222 if organ_inline == 1 { if served_inline == 1 { inline_ok = 1 } }
223 wcg_p(" inline_ok = " as *u8); wcg_pn(inline_ok); wcg_p(" (organ=" as *u8); wcg_pn(organ_inline); wcg_p(" served=" as *u8); wcg_pn(served_inline); wcg_p(")\n" as *u8)
224
225 // ===== STEP 2: archive S2 (PROPRIETARY) + cite it -> LINK ONLY, NO BYTES ====
226 // THE LIAR-KILL. S2 is archived (so the bytes ARE in the store) but NOT
227 // hostable; the render MUST emit a link/license-note and MUST NOT leak the
228 // secret bytes anywhere in the HTML.
229 let s2_slug: *u8 = "src-s2" as *u8
230 let s2_body: *u8 = "Confidential: PROPRIETARY-SECRET-67890 must never be inlined without a license.\n" as *u8
231 let cid_s2: *u8 = sys_mmap(80)
232 let w2: *i64 = ss_begin()
233 let r2: i64 = war_archive_page(w2, s2_slug, s2_body, wcg_slen(s2_body), cid_s2)
234 let c2: i64 = ss_commit(prefix, w2, 2)
235 wcg_p(" S2 archived rc=" as *u8); wcg_pn(r2); wcg_p(" commit=" as *u8); wcg_pn(c2); wcg_p(" cid=" as *u8); wcg_p(cid_s2); wcg_p("\n" as *u8)
236 // tag S2 PROPRIETARY (NOT hostable)
237 let lset2: i64 = nx_wiki_license_set(prefix, cid_s2, NXLIC_PROPRIETARY, 3)
238 wcg_p(" S2 license set PROPRIETARY rc=" as *u8); wcg_pn(lset2); wcg_p(" (get=" as *u8); wcg_pn(nx_wiki_license_get(prefix, cid_s2)); wcg_p(" hostable=" as *u8); wcg_pn(nx_wiki_license_hostable(nx_wiki_license_get(prefix, cid_s2))); wcg_p(")\n" as *u8)
239
240 // SANITY: prove the secret bytes ARE retrievable from the archive (so the
241 // absence-from-HTML below is a real suppression, not an archiving miss).
242 let pps: *i64 = sys_mmap(16) as *i64
243 let s2got: i64 = war_get_by_cid(prefix, cid_s2, pps, WCG_CAP)
244 var s2_in_store: i64 = 0
245 if s2got > 0 { if wcg_has(pps[0] as *u8, s2got, secret) == 1 { s2_in_store = 1 } }
246 wcg_p(" S2 secret-in-store = " as *u8); wcg_pn(s2_in_store); wcg_p(" (archive readback len=" as *u8); wcg_pn(s2got); wcg_p(")\n" as *u8)
247
248 let pg2: *u8 = sys_mmap(512)
249 var g2: i64 = 0
250 g2 = wcg_cat(pg2, g2, "Per the proprietary source [[cite:" as *u8)
251 g2 = wcg_cat(pg2, g2, cid_s2)
252 g2 = wcg_cat(pg2, g2, "]], details are restricted.\n" as *u8)
253 pg2[g2] = 0 as u8
254
255 let rr2: i64 = nx_wiki_cite_render(prefix, pg2, g2, out, WCG_OUTCAP, used)
256 let hn2: i64 = used[0]
257 wcg_p(" render2 rc=" as *u8); wcg_pn(rr2); wcg_p(" html_len=" as *u8); wcg_pn(hn2); wcg_p("\n" as *u8)
258
259 // JUDGE license_respected (THE LIAR-KILL) on GROUND TRUTH, on BOTH the organ
260 // output AND the SERVED bytes. (1) ORGAN: link/license-note present + secret
261 // ABSENT in the cite-render output. (2) SERVED (artifact-closing): render an
262 // S2-citing page through the REAL handler and require the secret to be ABSENT
263 // from the served HTML while a link + note are present -- so a served leak can
264 // no longer slip past while the organ-only check is green.
265 var organ_license: i64 = 0
266 if rr2 == NXCITE_OK {
267 let link_at: i64 = wcg_find(out, hn2, "nx-cite-link" as *u8)
268 let note_at: i64 = wcg_find(out, hn2, "licensing restricts inline hosting" as *u8)
269 let leak_at: i64 = wcg_find(out, hn2, secret)
270 if link_at >= 0 { if note_at >= 0 { if leak_at < 0 { organ_license = 1 } } }
271 wcg_p(" license(organ): link@" as *u8); wcg_pn(link_at); wcg_p(" note@" as *u8); wcg_pn(note_at); wcg_p(" SECRET_LEAK@" as *u8); wcg_pn(leak_at); wcg_p(" (-1=absent=GOOD)\n" as *u8)
272 }
273 // SERVED liar-kill: add an S2-citing page to the doc store, render via handler.
274 let cpg2: *u8 = sys_mmap(512)
275 var cg2: i64 = 0
276 cg2 = wcg_cat(cpg2, cg2, "# Proprietary Cite Page\n\nPer the proprietary source [[cite:" as *u8)
277 cg2 = wcg_cat(cpg2, cg2, cid_s2)
278 cg2 = wcg_cat(cpg2, cg2, "]], details are restricted.\n" as *u8)
279 cpg2[cg2] = 0 as u8
280 let cpg2_rid: i64 = nx_wiki_doc_store_add(cstore,
281 "Proprietary Cite Page" as *u8, 21, "/wiki/cite-gate-prop" as *u8, 20, cpg2, cg2)
282 let sresp2: *u8 = sys_mmap(WCG_RESP_CAP)
283 let sresp2_n: *i64 = sys_mmap(8) as *i64
284 sresp2_n[0] = 0
285 let sh2_rc: i64 = nx_wiki_doc_handle_cp(cstore, 0 as *NxArtifactStore,
286 "/wiki/cite-gate-prop" as *u8, 20, sresp2, WCG_RESP_CAP, sresp2_n, prefix)
287 let sn2: i64 = sresp2_n[0]
288 var served_license: i64 = 0
289 if sh2_rc == NX_WDH_OK {
290 let slink_at: i64 = wcg_find(sresp2, sn2, "nx-cite-link" as *u8)
291 let snote_at: i64 = wcg_find(sresp2, sn2, "licensing restricts inline hosting" as *u8)
292 let sleak_at: i64 = wcg_find(sresp2, sn2, secret)
293 if slink_at >= 0 { if snote_at >= 0 { if sleak_at < 0 { served_license = 1 } } }
294 wcg_p(" license(SERVED): handle_rc=" as *u8); wcg_pn(sh2_rc); wcg_p(" rid=" as *u8); wcg_pn(cpg2_rid); wcg_p(" resp_len=" as *u8); wcg_pn(sn2); wcg_p(" link@" as *u8); wcg_pn(slink_at); wcg_p(" note@" as *u8); wcg_pn(snote_at); wcg_p(" SECRET_LEAK@" as *u8); wcg_pn(sleak_at); wcg_p(" (-1=absent=GOOD)\n" as *u8)
295 }
296 var license_respected: i64 = 0
297 if organ_license == 1 { if served_license == 1 { license_respected = 1 } }
298 wcg_p(" license_respected = " as *u8); wcg_pn(license_respected); wcg_p(" (organ=" as *u8); wcg_pn(organ_license); wcg_p(" served=" as *u8); wcg_pn(served_license); wcg_p(")\n" as *u8)
299
300 // ===== STEP 3: cite a NON-archived cid -> pending placeholder ==============
301 let cid_none: *u8 = "nxc1-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" as *u8
302 let pg3: *u8 = sys_mmap(512)
303 var g3: i64 = 0
304 g3 = wcg_cat(pg3, g3, "An as-yet-unarchived claim [[cite:" as *u8)
305 g3 = wcg_cat(pg3, g3, cid_none)
306 g3 = wcg_cat(pg3, g3, "]] is noted.\n" as *u8)
307 pg3[g3] = 0 as u8
308
309 let rr3: i64 = nx_wiki_cite_render(prefix, pg3, g3, out, WCG_OUTCAP, used)
310 let hn3: i64 = used[0]
311 var pending_ok: i64 = 0
312 if rr3 == NXCITE_OK {
313 if wcg_has(out, hn3, "(source archiving pending)" as *u8) == 1 { pending_ok = 1 }
314 }
315 wcg_p(" render3 rc=" as *u8); wcg_pn(rr3); wcg_p(" html_len=" as *u8); wcg_pn(hn3); wcg_p(" pending_ok=" as *u8); wcg_pn(pending_ok); wcg_p("\n" as *u8)
316
317 // ===== EVIDENCE: print the inline card HTML + a CSS sample =================
318 // (re-render S1 so `out` holds the inline card, then echo it for judging.)
319 let rr1b: i64 = nx_wiki_cite_render(prefix, pg1, g1, out, WCG_OUTCAP, used)
320 if rr1b == NXCITE_OK {
321 wcg_p(" ---- rendered inline card (S1, CC-BY) ----\n" as *u8)
322 sys_write(1, out, used[0])
323 wcg_p("\n ---- /card ----\n" as *u8)
324 }
325 let cssbuf: *u8 = sys_mmap(4096)
326 let cssn: i64 = nx_wiki_cite_css(cssbuf, 4096)
327 if cssn > 0 {
328 wcg_p(" ---- sovereign-emitted card CSS ----\n" as *u8)
329 sys_write(1, cssbuf, cssn)
330 wcg_p(" ---- /CSS ----\n" as *u8)
331 }
332
333 // ===== VERDICT =====
334 var green: i64 = 1
335 if inline_ok != 1 { green = 0 }
336 if license_respected != 1 { green = 0 }
337 if pending_ok != 1 { green = 0 }
338 // belt-and-suspenders: the secret must truly have been in the store, so the
339 // suppression we measured was real (not an archiving miss masquerading).
340 if s2_in_store != 1 { green = 0 }
341
342 let lfd: i64 = sys_openat_append(WCG_LOG, 420)
343 wcg_w2(lfd, "WIKICITE inline_ok=" as *u8); wcg_n2(lfd, inline_ok)
344 wcg_w2(lfd, " license_respected=" as *u8); wcg_n2(lfd, license_respected)
345 wcg_w2(lfd, " pending_ok=" as *u8); wcg_n2(lfd, pending_ok)
346 if green == 1 { wcg_w2(lfd, " verdict=GREEN\n" as *u8) } else { wcg_w2(lfd, " verdict=RED\n" as *u8) }
347 if lfd >= 0 { sys_close(lfd) }
348
349 if green == 1 {
350 sys_exit(0)
351 return 0
352 }
353 sys_exit(1)
354 return 1
355}