feat(userland): NipBox LITE subject binary, ARM64 init support
This commit is contained in:
parent
47f1078748
commit
dfe9135b8a
86
nipbox.nim
86
nipbox.nim
|
|
@ -12,10 +12,50 @@ import strutils, parseutils, tables, sequtils, json
|
||||||
import kdl
|
import kdl
|
||||||
import ../../libs/membrane/libc as lb
|
import ../../libs/membrane/libc as lb
|
||||||
import ../../libs/membrane/libc_net as lnet
|
import ../../libs/membrane/libc_net as lnet
|
||||||
|
when not defined(NIPBOX_LITE):
|
||||||
import ../../libs/membrane/fs/sfs_user as sfs
|
import ../../libs/membrane/fs/sfs_user as sfs
|
||||||
import editor
|
import editor
|
||||||
|
when not defined(NIPBOX_LITE):
|
||||||
import ../../libs/membrane/term # Phase 26: Visual Cortex
|
import ../../libs/membrane/term # Phase 26: Visual Cortex
|
||||||
|
|
||||||
|
# --- M4.4: BKDL Capability Manifest (SPEC-071) ---
|
||||||
|
{.emit: """
|
||||||
|
__attribute__((section(".nexus.manifest"), used))
|
||||||
|
static const unsigned char nexus_manifest[166] = {
|
||||||
|
/* BkdlHeader (118 bytes) */
|
||||||
|
0x53, 0x55, 0x58, 0x4E, /* magic: "NXUS" (LE) */
|
||||||
|
0x01, 0x00, /* version: 1 */
|
||||||
|
0x00, 0x00, /* flags: 0 */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* signature[0..63]: zeros */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* pubkey_hash[0..31]: zeros */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, /* cap_count: 4 */
|
||||||
|
0x00, 0x00, 0x00, 0x00, /* blob_size: 0 */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* entry_point: 0 */
|
||||||
|
/* CapDescriptor[0]: console.output (0x1001) WRITE */
|
||||||
|
0x02, 0x02, 0x00, 0x00,
|
||||||
|
0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
/* CapDescriptor[1]: VFS (0x2000) READ */
|
||||||
|
0x02, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
/* CapDescriptor[2]: NET_TX (0x0500) WRITE */
|
||||||
|
0x02, 0x02, 0x00, 0x00,
|
||||||
|
0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
/* CapDescriptor[3]: NET_RX (0x0501) READ */
|
||||||
|
0x02, 0x01, 0x00, 0x00,
|
||||||
|
0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
""".}
|
||||||
|
|
||||||
# Phase 30: Pledge Constants
|
# Phase 30: Pledge Constants
|
||||||
const
|
const
|
||||||
PLEDGE_STDIO* = 0x0001'u64
|
PLEDGE_STDIO* = 0x0001'u64
|
||||||
|
|
@ -291,6 +331,7 @@ proc cmd_cat*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
proc cmd_write*(args: seq[string], input: PipelineData): PipelineData =
|
proc cmd_write*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
## write <filename> <content>
|
## write <filename> <content>
|
||||||
## Uses USERLAND SFS (Block Valve architecture)
|
## Uses USERLAND SFS (Block Valve architecture)
|
||||||
|
when not defined(NIPBOX_LITE):
|
||||||
if args.len < 2:
|
if args.len < 2:
|
||||||
print("Usage: write <filename> <content>\n")
|
print("Usage: write <filename> <content>\n")
|
||||||
return @[]
|
return @[]
|
||||||
|
|
@ -308,10 +349,14 @@ proc cmd_write*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
else:
|
else:
|
||||||
print("Error: Could not write to " & filename & "\n")
|
print("Error: Could not write to " & filename & "\n")
|
||||||
return @[]
|
return @[]
|
||||||
|
else:
|
||||||
|
print("[nipbox] 'write' requires SFS (not available in lite mode)\n")
|
||||||
|
return @[]
|
||||||
|
|
||||||
proc cmd_read*(args: seq[string], input: PipelineData): PipelineData =
|
proc cmd_read*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
## read <filename>
|
## read <filename>
|
||||||
## Uses USERLAND SFS (Block Valve architecture)
|
## Uses USERLAND SFS (Block Valve architecture)
|
||||||
|
when not defined(NIPBOX_LITE):
|
||||||
if args.len == 0:
|
if args.len == 0:
|
||||||
print("Usage: read <filename>\n")
|
print("Usage: read <filename>\n")
|
||||||
return @[]
|
return @[]
|
||||||
|
|
@ -330,6 +375,9 @@ proc cmd_read*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
else:
|
else:
|
||||||
print("Error: Could not open " & filename & "\n")
|
print("Error: Could not open " & filename & "\n")
|
||||||
return @[]
|
return @[]
|
||||||
|
else:
|
||||||
|
print("[nipbox] 'read' requires SFS (not available in lite mode)\n")
|
||||||
|
return @[]
|
||||||
|
|
||||||
proc cmd_edit*(args: seq[string], input: PipelineData): PipelineData =
|
proc cmd_edit*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
if args.len == 0:
|
if args.len == 0:
|
||||||
|
|
@ -482,6 +530,7 @@ proc cmd_http_get*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
return @[node]
|
return @[node]
|
||||||
|
|
||||||
proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
|
when not defined(NIPBOX_LITE):
|
||||||
if args.len < 2:
|
if args.len < 2:
|
||||||
print("Usage: http.download <ip:port/path> <outfile>\n")
|
print("Usage: http.download <ip:port/path> <outfile>\n")
|
||||||
return @[]
|
return @[]
|
||||||
|
|
@ -561,7 +610,6 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
var timeout = 0
|
var timeout = 0
|
||||||
|
|
||||||
while timeout < 10000:
|
while timeout < 10000:
|
||||||
# Use libc shim which pumps stack
|
|
||||||
let n = lb.recv(cint(fd), addr buf[0], 4096, 0)
|
let n = lb.recv(cint(fd), addr buf[0], 4096, 0)
|
||||||
|
|
||||||
if n > 0:
|
if n > 0:
|
||||||
|
|
@ -572,8 +620,6 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
if sep != -1:
|
if sep != -1:
|
||||||
header_parsed = true
|
header_parsed = true
|
||||||
|
|
||||||
# Try to find Content-Length
|
|
||||||
# Quick hacky parse
|
|
||||||
let lower_head = header_acc.toLowerAscii()
|
let lower_head = header_acc.toLowerAscii()
|
||||||
let cl_idx = lower_head.find("content-length:")
|
let cl_idx = lower_head.find("content-length:")
|
||||||
if cl_idx != -1:
|
if cl_idx != -1:
|
||||||
|
|
@ -595,13 +641,10 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
print("Error: Headers too large.\n")
|
print("Error: Headers too large.\n")
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# Stream directly to SFS
|
|
||||||
sfs.sfs_write_chunk(sfs_h, addr buf[0], int(n))
|
sfs.sfs_write_chunk(sfs_h, addr buf[0], int(n))
|
||||||
total_bytes += int(n)
|
total_bytes += int(n)
|
||||||
|
|
||||||
# Progress Bar
|
|
||||||
if content_len > 0:
|
if content_len > 0:
|
||||||
# let pct = (total_bytes * 100) div content_len
|
|
||||||
if total_bytes mod 10240 < int(n): print(".")
|
if total_bytes mod 10240 < int(n): print(".")
|
||||||
else:
|
else:
|
||||||
if total_bytes mod 10240 < int(n): print(".")
|
if total_bytes mod 10240 < int(n): print(".")
|
||||||
|
|
@ -609,28 +652,20 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
elif n == 0:
|
elif n == 0:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
timeout += 1
|
|
||||||
# Busy wait / pump handled in recv?
|
|
||||||
# Recv calls pump_membrane_stack loop
|
|
||||||
# But if we return -1 (EAGAIN), we need to retry.
|
|
||||||
# My libc.libc_recv returns 0 on closed?
|
|
||||||
# Actually libc_recv in step 945 waits until data or closed.
|
|
||||||
# So n==0 means closed.
|
|
||||||
# Wait, libc.nim recv implementation:
|
|
||||||
# while true: pump; if data return n; if closed return 0.
|
|
||||||
# So it blocks until data.
|
|
||||||
# Thus n > 0 always unless closed.
|
|
||||||
break
|
break
|
||||||
|
|
||||||
sfs.sfs_close_write(sfs_h)
|
sfs.sfs_close_write(sfs_h)
|
||||||
discard lb.close(cint(fd))
|
discard lb.close(cint(fd))
|
||||||
print("\n[Download] Complete. " & $total_bytes & " bytes written to " & outfile & " (Glass Vault).\n")
|
print("\n[Download] Complete. " & $total_bytes & " bytes written to " & outfile & " (Glass Vault).\n")
|
||||||
return @[]
|
return @[]
|
||||||
|
else:
|
||||||
|
print("[nipbox] 'http.download' requires SFS (not available in lite mode)\n")
|
||||||
|
return @[]
|
||||||
|
|
||||||
# Phase 37: HTTP Verification Tool
|
# Phase 37: HTTP Verification Tool
|
||||||
proc cmd_http_test*(args: seq[string], input: PipelineData): PipelineData =
|
proc cmd_http_test*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
if args.len < 1:
|
if args.len < 1:
|
||||||
print("Usage: http <host>\n")
|
print("Usage: http.test <host>\n")
|
||||||
return @[]
|
return @[]
|
||||||
|
|
||||||
let host = args[0]
|
let host = args[0]
|
||||||
|
|
@ -646,16 +681,13 @@ proc cmd_http_test*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
|
|
||||||
print("Waiting for response...\n")
|
print("Waiting for response...\n")
|
||||||
|
|
||||||
# Simple read loop
|
|
||||||
var total = 0
|
var total = 0
|
||||||
while true:
|
while true:
|
||||||
# lb.pump_membrane_stack()
|
|
||||||
let resp = lnet.net_recv(fd, 512)
|
let resp = lnet.net_recv(fd, 512)
|
||||||
if resp.len > 0:
|
if resp.len > 0:
|
||||||
print(resp)
|
print(resp)
|
||||||
total += resp.len
|
total += resp.len
|
||||||
else:
|
else:
|
||||||
# End of stream or empty poll
|
|
||||||
break
|
break
|
||||||
|
|
||||||
print("\n[HTTP] Closed. Total bytes: " & $total & "\n")
|
print("\n[HTTP] Closed. Total bytes: " & $total & "\n")
|
||||||
|
|
@ -774,8 +806,18 @@ proc cmd_set*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
|
|
||||||
|
|
||||||
proc cmd_help*(args: seq[string], input: PipelineData): PipelineData =
|
proc cmd_help*(args: seq[string], input: PipelineData): PipelineData =
|
||||||
|
when defined(NIPBOX_LITE):
|
||||||
|
print("NipBox " & NIPBOX_VERSION & " [LITE] (Phase 34: Orbital Drop)\n")
|
||||||
|
print("Commands: ls, cat, cp, mv, touch, edit, echo, where, http, http.get,\n")
|
||||||
|
print(" http.test, http.serve, from_json, mount, matrix, crash,\n")
|
||||||
|
print(" sys.upgrade, set, if, while, help, exit\n")
|
||||||
|
print("Disabled: write, read, http.download (requires SFS)\n")
|
||||||
|
else:
|
||||||
print("NipBox " & NIPBOX_VERSION & " (Phase 34: Orbital Drop)\n")
|
print("NipBox " & NIPBOX_VERSION & " (Phase 34: Orbital Drop)\n")
|
||||||
print("Commands: ls, cat, echo, where, http, http.get, http.download, from_json, mount, matrix, set, if, while, help, exit\n")
|
print("Commands: ls, cat, cp, mv, touch, edit, echo, where, write, read,\n")
|
||||||
|
print(" http, http.get, http.download, http.test, http.serve,\n")
|
||||||
|
print(" from_json, mount, matrix, crash, sys.upgrade,\n")
|
||||||
|
print(" set, if, while, help, exit\n")
|
||||||
return @[]
|
return @[]
|
||||||
|
|
||||||
# --- DISPATCHER ---
|
# --- DISPATCHER ---
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue