code wiki / _hdl_build / nx_reader_diag.nx
nx_reader_diag.nx source
↩ module page · 86 lines · 5638 B
1// nx_reader_diag.nx -- run the EXACT live manga-download command ON THE NAS (from the reader daemon's own working
2// directory) over our sovereign SSH, streaming the real output back. Ends the "worked locally, failed live" guessing:
3// shows whether knowledge/staging/media/reader/ exists, whether certdata resolves, and whether the fork actually
4// downloads+writes -- exactly what the daemon's /api/manga/add fork does. Reuses the nx_aw_hostctl SSH spine.
5import "nx_syscalls.nx"
6import "nx_ssh_lib.nx"
7const DG_MAGIC_1000000: i64 = 1000000
8const DG_MAGIC_65536: i64 = 65536
9const DG_MAGIC_1048576: i64 = 1048576
10const DG_MAGIC_16384: i64 = 16384
11const DG_MAGIC_4096: i64 = 4096
12
13const DG_VAULT_NV: *u8 = "/home/elderwesto/.nishi/secrets/nas.nv" as *u8
14const DG_SECRET_OUT:*u8 = "/tmp/nxsecret.out" as *u8
15
16func dg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
17func dg_unlink(p: *u8) -> i64 { __syscall(263, AT_FDCWD, p, 0, 0, 0, 0) return 0 }
18func dg_napms(ms: i64) -> i64 { let ts: *i64 = sys_mmap(16) as *i64; ts[0]=0; ts[1]=ms*DG_MAGIC_1000000; __syscall(35, ts as i64, 0,0,0,0,0); return 0 }
19func dg_run(path: *u8, a1: *u8, a2: *u8) -> i64 {
20 let pid: i64 = sys_fork()
21 if pid == 0 {
22 let argv: *i64 = sys_mmap(64) as *i64; argv[0]=path as i64; var ai: i64=1
23 if (a1 as i64)!=0 { argv[ai]=a1 as i64; ai=ai+1 }
24 if (a2 as i64)!=0 { argv[ai]=a2 as i64; ai=ai+1 }
25 argv[ai]=0
26 let envp: *i64 = sys_mmap(16) as *i64; envp[0]="PATH=/usr/bin:/bin" as *u8 as i64; envp[1]=0
27 sys_execve(path, argv, envp); sys_exit(127)
28 }
29 let st: *i64 = sys_mmap(16) as *i64; sys_wait4(pid, st, 0); return (st[0]>>8)&0xff
30}
31func dg_drain(st: *SshState) -> i64 {
32 let pfd: *u8 = sys_mmap(8); let fdv: i64 = st.fd
33 pfd[0]=(fdv&0xff) as u8; pfd[1]=((fdv>>8)&0xff) as u8; pfd[2]=((fdv>>16)&0xff) as u8; pfd[3]=((fdv>>24)&0xff) as u8
34 pfd[4]=1 as u8; pfd[5]=0 as u8
35 let buf: *u8 = sys_mmap(DG_MAGIC_65536); var run: i64=1
36 while run==1 { let r: i64=sys_poll(pfd,1,0); if r<=0 {run=0} else { if ssh_enc_recv(st,buf)<0 {run=0} } }
37 return 0
38}
39// exec `wcmd` on the NAS, print its output to fd 1 until channel close. datalen=0 => no stdin. Waits for a LONG
40// quiet gap (60 * 500ms = 30s) so a slow download that streams per-image lines is not cut off mid-run.
41func dg_exec(st: *SshState, wcmd: *u8, wcmdlen: i64) -> i64 {
42 let co: *u8 = sys_mmap(64); var c: i64=0
43 c=ssh_put_byte(co,c,90); c=ssh_put_str(co,c,"session" as *u8,7)
44 c=ssh_put_u32(co,c,0); c=ssh_put_u32(co,c,DG_MAGIC_1048576); c=ssh_put_u32(co,c,DG_MAGIC_16384)
45 ssh_enc_send(st,co,c)
46 let rep: *u8 = sys_mmap(DG_MAGIC_65536); var rcid: i64=0-1; var guard: i64=0
47 while rcid<0 { if guard>16 {return 0-1} let rl: i64=ssh_enc_recv(st,rep); if rl<0 {return 0-1} if rep[0]==91 as u8 {rcid=ssh_u32be(rep,5)} if rep[0]==92 as u8 {return 0-2} guard=guard+1 }
48 let cr: *u8 = sys_mmap(DG_MAGIC_4096); var q: i64=0
49 q=ssh_put_byte(cr,q,98); q=ssh_put_u32(cr,q,rcid); q=ssh_put_str(cr,q,"exec" as *u8,4); q=ssh_put_byte(cr,q,1); q=ssh_put_str(cr,q,wcmd,wcmdlen)
50 ssh_enc_send(st,cr,q)
51 let eo: *u8 = sys_mmap(16); var e: i64=0; e=ssh_put_byte(eo,e,96); e=ssh_put_u32(eo,e,rcid); ssh_enc_send(st,eo,e)
52 let pfd2: *u8 = sys_mmap(8); let fdv2: i64=st.fd
53 pfd2[0]=(fdv2&0xff) as u8; pfd2[1]=((fdv2>>8)&0xff) as u8; pfd2[2]=((fdv2>>16)&0xff) as u8; pfd2[3]=((fdv2>>24)&0xff) as u8
54 pfd2[4]=1 as u8; pfd2[5]=0 as u8
55 var done: i64=0; var quiet: i64=0
56 while done==0 {
57 let pr: i64=sys_poll(pfd2,1,500)
58 if pr<=0 { quiet=quiet+1; if quiet>=60 {done=1} }
59 else { quiet=0; let rl: i64=ssh_enc_recv(st,rep); if rl<0 {done=1} else {
60 if rep[0]==94 as u8 { let dl: i64=ssh_u32be(rep,5); sys_write(1,(rep as i64+9) as *u8,dl) }
61 if rep[0]==97 as u8 {done=1} } }
62 }
63 return 0
64}
65
66func main() -> i64 {
67 // sovereign credential (machine-bound), retry-tolerant
68 var ok: i64 = 0; var att: i64 = 0
69 while att < 12 { if dg_run("_offc/nx_machine_key.elf" as *u8, 0 as *u8, 0 as *u8)==0 { if dg_run("_offc/nx_vault.elf" as *u8, "open" as *u8, DG_VAULT_NV)==0 { ok=1; att=1000 } } if att<1000 { att=att+1; dg_napms(150) } }
70 dg_unlink("/tmp/nxpass" as *u8)
71 if ok==0 { ssh_puts("nx_reader_diag: credential derive FAILED\n" as *u8); return 1 }
72 let pwbox: *i64 = sys_mmap(16) as *i64
73 let pw: *u8 = sys_read_file(DG_SECRET_OUT, pwbox)
74 if (pw as i64)==0 { ssh_puts("nx_reader_diag: cannot read secret\n" as *u8); return 2 }
75 var pwlen: i64 = pwbox[0]
76 while pwlen > 0 { if pw[pwlen-1] == 10 as u8 { pwlen = pwlen - 1 } else { if pw[pwlen-1] == 13 as u8 { pwlen = pwlen - 1 } else { break } } }
77 let st: *SshState = sys_mmap(SSH_STATE_BYTES) as *SshState
78 if ssh_open_session(st, (192<<24)|(168<<16)|(8<<8)|227) != 0 { ssh_puts("nx_reader_diag: SSH session FAILED\n" as *u8); dg_unlink(DG_SECRET_OUT); return 5 }
79 if ssh_userauth_password(st, "elderwesto" as *u8, 10, pw, pwlen) != 1 { ssh_puts("nx_reader_diag: SSH auth FAILED\n" as *u8); sys_close(st.fd); dg_unlink(DG_SECRET_OUT); return 6 }
80 dg_unlink(DG_SECRET_OUT)
81 ssh_puts("---- LIVE NAS reader-download diagnostic ----\n" as *u8)
82 let cmd: *u8 = "cd /volume1/homes/elderwesto/nishi-reader; echo LIBRARY:; ./_offc/nx_loop_http.elf 8791 /library 2>&1 | head -1; echo HEALTH-LINK:; ./_offc/nx_loop_http.elf 8791 /library 2>&1 | grep -o 'href=.health' | head -1; echo HEALTH-PAGE:; ./_offc/nx_loop_http.elf 8791 /library/health 2>&1 | head -1; echo END" as *u8
83 dg_exec(st, cmd, dg_slen(cmd))
84 sys_close(st.fd)
85 return 0
86}