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}