nx_printer_dump.nx source
↩ module page · 130 lines · 5328 B
1// nx_printer_dump.nx -- full-transparency IPP attribute dumper. Queries a printer and decodes EVERY
2// attribute it reports (name, type, value), 1setOf values listed individually. This is both a useful
3// sovereign tool ("show me everything, no vendor filtering") and the schema-first grounding for the R4
4// waste layer: it reveals the printer's real marker-*/sides-*/print-quality attributes.
5// READ-ONLY -> never-brick. license_tier: ORIGINAL
6
7import "nx_syscalls.nx"
8import "nx_ipp_codec.nx"
9import "nx_ipp_transport.nx"
10const K_MAGIC_262144: i64 = 262144
11
12func p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
13func pn(v: i64) -> i64 {
14 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
15 var m: i64 = v
16 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
17 let t: *u8 = sys_mmap(24); var k: i64 = 0
18 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
19 let b: *u8 = sys_mmap(24); var i: i64 = 0
20 while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
21 sys_write(1, b, k); return 0
22}
23func phex2(v: i64) -> i64 {
24 let hx: *u8 = "0123456789abcdef"
25 sys_write(1, ((hx as i64) + ((v >> 4) & 0xf)) as *u8, 1)
26 sys_write(1, ((hx as i64) + (v & 0xf)) as *u8, 1)
27 return 0
28}
29
30func group_label(tag: i64) -> *u8 {
31 if tag == NX_IPP_GRP_OPERATION { return "operation-attributes" as *u8 }
32 if tag == NX_IPP_GRP_JOB { return "job-attributes" as *u8 }
33 if tag == NX_IPP_GRP_PRINTER { return "printer-attributes" as *u8 }
34 if tag == NX_IPP_GRP_UNSUPPORTED { return "unsupported-attributes" as *u8 }
35 return "group" as *u8
36}
37
38func is_string_tag(tag: i64) -> i64 {
39 if tag == NX_IPP_VT_KEYWORD { return 1 }
40 if tag == NX_IPP_VT_URI { return 1 }
41 if tag == NX_IPP_VT_CHARSET { return 1 }
42 if tag == NX_IPP_VT_NATLANG { return 1 }
43 if tag == NX_IPP_VT_MIMETYPE { return 1 }
44 if tag == NX_IPP_VT_NAME { return 1 }
45 if tag == NX_IPP_VT_TEXT { return 1 }
46 if tag == 0x4a { return 1 } // memberAttrName
47 return 0
48}
49
50func print_value(body: *u8, tag: i64, val_off: i64, vlen: i64) -> i64 {
51 if tag == NX_IPP_VT_INTEGER { if vlen == 4 { pn(nx_ipp_get_u32(body, val_off)); return 0 } }
52 if tag == NX_IPP_VT_ENUM { if vlen == 4 { pn(nx_ipp_get_u32(body, val_off)); p(" (enum)"); return 0 } }
53 if tag == NX_IPP_VT_BOOLEAN {
54 if vlen >= 1 {
55 if (body[val_off] as i64) == 0 { p("false") } else { p("true") }
56 return 0
57 }
58 }
59 if is_string_tag(tag) == 1 { sys_write(1, ((body as i64) + val_off) as *u8, vlen); return 0 }
60 p("<tag 0x"); phex2(tag); p(", "); pn(vlen); p("B>")
61 return 0
62}
63
64func dump(body: *u8, n: i64) -> i64 {
65 if n < 8 { return 0 }
66 var off: i64 = 8
67 var keep: i64 = 1
68 while keep == 1 {
69 if off >= n { keep = 0 }
70 else {
71 let tag: i64 = body[off] as i64
72 if tag == NX_IPP_TAG_END { keep = 0 }
73 else {
74 if tag <= 0x0f {
75 p("["); p(group_label(tag)); p("]\n")
76 off = off + 1
77 } else {
78 if (off + 3) > n { keep = 0 }
79 else {
80 let nlen: i64 = nx_ipp_get_u16(body, off + 1)
81 let name_off: i64 = off + 3
82 if (name_off + nlen + 2) > n { keep = 0 }
83 else {
84 let vlen_off: i64 = name_off + nlen
85 let vlen: i64 = nx_ipp_get_u16(body, vlen_off)
86 let val_off: i64 = vlen_off + 2
87 if (val_off + vlen) > n { keep = 0 }
88 else {
89 if nlen > 0 {
90 p(" ")
91 sys_write(1, ((body as i64) + name_off) as *u8, nlen)
92 p(" = ")
93 } else {
94 p(" , ")
95 }
96 print_value(body, tag, val_off, vlen)
97 p("\n")
98 off = val_off + vlen
99 }
100 }
101 }
102 }
103 }
104 }
105 }
106 return 0
107}
108
109func main() -> i64 {
110 let a: i64 = 192
111 let b: i64 = 168
112 let c: i64 = 8
113 let d: i64 = 127
114 let resp: *u8 = sys_mmap(K_MAGIC_262144)
115 let body: *u8 = sys_mmap(K_MAGIC_262144)
116 let out2: *i64 = sys_mmap(16) as *i64
117 var path: *u8 = "/ipp/print"
118 var v: i64 = nx_ipt_query_printer(a, b, c, d, 631, path, resp, K_MAGIC_262144, body, K_MAGIC_262144, 5, out2)
119 var ok: i64 = 0
120 if v == NX_IPT_OK { if out2[0] == 200 { ok = 1 } }
121 if ok == 0 {
122 path = "/ipp/port1"
123 v = nx_ipt_query_printer(a, b, c, d, 631, path, resp, K_MAGIC_262144, body, K_MAGIC_262144, 5, out2)
124 }
125 p("=== IPP ATTRIBUTE DUMP ipp://"); pn(a); p("."); pn(b); p("."); pn(c); p("."); pn(d)
126 p(" path="); p(path); p(" bytes="); pn(out2[1]); p(" ===\n")
127 if v != NX_IPT_OK { p("transport="); p(nx_ipt_verdict_name(v)); p("\n"); sys_exit(1); return 1 }
128 dump(body, out2[1])
129 sys_exit(0); return 0
130}