code wiki / _hdl_build / nx_survey_daemon.nx
nx_survey_daemon.nx source
↩ module page · 60 lines · 2866 B
1// nx_survey_daemon.nx -- the DEPLOYABLE Nishi Pulse survey/poll daemon (ops shell around the gated pure
2// core nx_survey_serve). Binds 0.0.0.0:8031; CWD = nishihost on the NAS. Mounted at nishifamily.com/survey
3// via a proxy_routes.conf row (the /office precedent). Store = seg_store prefix knowledge/survey/pulse_
4// (self-healed on startup: the relate-daemon lesson -- root-owned knowledge/ may lack the subdir).
5// Admin lane reads survey_admin.key from CWD per request (FAIL-CLOSED when absent).
6// SO_REUSEADDR so the reconcile cron can rebind instantly after a crash (the office TIME_WAIT lesson).
7// Build with --build-only; run deliberately. license_tier: ORIGINAL
8import "nx_survey_serve.nx"
9
10const SD_PORT: i64 = 0x1f5f // 8031
11
12func sd_addr(out: *u8, port: i64) -> i64 {
13 out[0] = 2 as u8
14 out[1] = 0 as u8
15 out[2] = ((port >> 8) & 0xff) as u8
16 out[3] = (port & 0xff) as u8
17 var i: i64 = 4
18 while i < 16 { out[i] = 0 as u8; i = i + 1 }
19 return 0
20}
21
22func main() -> i64 {
23 let prefix: *u8 = "knowledge/survey/pulse_" as *u8
24 let base: *u8 = "/survey" as *u8
25 let keypath: *u8 = "survey_admin.key" as *u8
26 // self-heal the store dirs (idempotent; EEXIST ignored -- daemon may run as root under the guard)
27 sys_mkdir("knowledge" as *u8, 493)
28 sys_mkdir("knowledge/survey" as *u8, 493)
29 let addr: *u8 = sys_mmap(16)
30 sd_addr(addr, SD_PORT)
31 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0)
32 if lfd < 0 { sv2_p("NX-SURVEY-DAEMON socket FAILED -- fail loud\n" as *u8); return 1 }
33 let one: *i64 = (sys_mmap(8)) as *i64
34 one[0] = 1
35 sys_setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, one as *u8, 4)
36 if sys_bind(lfd, addr, 16) < 0 { sv2_p("NX-SURVEY-DAEMON bind 0.0.0.0:8031 FAILED (port busy?) -- fail loud\n" as *u8); return 1 }
37 if sys_listen(lfd, 16) < 0 { sv2_p("NX-SURVEY-DAEMON listen FAILED -- fail loud\n" as *u8); return 1 }
38 sv2_p("NX-SURVEY-DAEMON serving http://0.0.0.0:8031/ store=knowledge/survey/pulse_ base=/survey (accept loop)\n" as *u8)
39 let reqb: *u8 = sys_mmap(262144)
40 let resb: *u8 = sys_mmap(1048576)
41 let finb: *u8 = sys_mmap(1048576)
42 var go: i64 = 1
43 while go == 1 {
44 let cfd: i64 = sys_accept(lfd)
45 if cfd >= 0 {
46 let rn: i64 = sv2_read_req(cfd, reqb, 262144)
47 if rn > 0 {
48 let on: i64 = sv2_handle(prefix, base, keypath, reqb, rn, resb, 1048576)
49 if on > 0 {
50 // strict-HTTP/1.1: stamp Content-Length + Connection: close so the sovereign browser
51 // (behind the keep-alive buffered edge) reads the body cleanly, not to the timeout.
52 let fn: i64 = sv2_finalize(resb, on, finb, 1048576)
53 sv2_write_all(cfd, finb, fn)
54 }
55 }
56 sys_close(cfd)
57 }
58 }
59 return 0
60}