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}