⬢ DragonFlyBSD Kernel Audit
DF-5732 / drive.py
← back to finding ↓ download raw
#!/usr/bin/env python3
"""DF-5732 live-pass driver — socket-backed serial console (adapted from the
proven DF-5728 driver). One persistent connection; lines sent in <=8-byte
chunks with pacing (guest UART RX FIFO is 16 bytes).

    drive.py "cmd1" wait1 "cmd2" wait2 ...      (alternating cmd, wait seconds)

Env:
    DF5732_SOCK   serial console unix socket (default /tmp/opencode/df-5732-ser.sock)
    DF5732_DRAIN  drain capture file (default /tmp/opencode/df-5732-drain.log)
"""
import os, socket, sys, threading, time

SOCK = os.environ.get("DF5732_SOCK", "/tmp/opencode/df-5732-ser.sock")
DRAIN = os.environ.get("DF5732_DRAIN", "/tmp/opencode/df-5732-drain.log")

def connect():
    while True:
        try:
            s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            s.connect(SOCK)
            return s
        except (FileNotFoundError, ConnectionRefusedError) as e:
            print(f"connect failed: {e}; retrying...", flush=True)
            time.sleep(2)

_drained = threading.Event()
def drainer(s):
    with open(DRAIN, "ab", buffering=0) as d:
        _drained.set()
        while True:
            try:
                b = s.recv(65536)
            except OSError:
                return
            if not b:
                return
            d.write(b)
            sys.stdout.buffer.write(b); sys.stdout.buffer.flush()

def send_line(s, line):
    data = (line if line.endswith("\n") else line + "\n").encode()
    for i in range(0, len(data), 8):
        s.sendall(data[i:i+8])
        time.sleep(0.15)

def main():
    args = sys.argv[1:]
    if not args or len(args) % 2 != 0:
        print("usage: drive.py \"cmd\" wait \"cmd\" wait ...", file=sys.stderr)
        return 2
    s = connect()
    t = threading.Thread(target=drainer, args=(s,), daemon=True)
    t.start(); _drained.wait()
    print("connected; drain ->", DRAIN, flush=True)
    time.sleep(2)
    for i in range(0, len(args), 2):
        cmd, wait = args[i], float(args[i+1])
        print(f">>> {cmd} (wait {wait}s)", flush=True)
        send_line(s, cmd)
        time.sleep(wait)
    print("session script complete", flush=True)
    time.sleep(2)
    return 0

if __name__ == "__main__":
    sys.exit(main())