elks-enhanced
public
Read
Owner: themaster
Branch: master
Commits: 6893
Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
elks-enhanced
/
qemu-uip-slip-test.sh
File editor
#!/bin/sh set -eu SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) MFS=${MFS:-"$SCRIPT_DIR/elks/tools/bin/mfs"} IMAGE=${IMAGE:-"$SCRIPT_DIR/image/fd1440.img"} HOST_IP=${HOST_IP:-192.168.7.1} GUEST_IP=${GUEST_IP:-192.168.7.2} NETMASK=${NETMASK:-255.255.255.0} BAUD=${BAUD:-38400} MTU=${MTU:-296} HTTP_PORT=${HTTP_PORT:-} WORKDIR=${WORKDIR:-$(mktemp -d /tmp/elks-uip-slip.XXXXXX)} QEMU_PID= QEMU_LOG= QEMU_PTY= SLATTACH_PID= SL_IFACE= HTTP_PID= HTTP_ROOT= HTTP_LOG= usage() { echo "Usage: $0 [slip|cslip|both]" exit 1 } find_qemu() { if [ -n "${QEMU:-}" ]; then printf '%s\n' "$QEMU" return fi for bin in qemu-system-i386 qemu-system-x86_64; do if command -v "$bin" >/dev/null 2>&1; then command -v "$bin" return fi done echo "QEMU system emulator not found" >&2 exit 1 } QEMU_BIN=$(find_qemu) list_sl_ifaces() { ip -o link show 2>/dev/null | awk -F': ' '/^[0-9]+: sl[0-9]+:/{print $2}' } cleanup_phase() { if [ -n "${HTTP_PID:-}" ]; then kill "$HTTP_PID" >/dev/null 2>&1 || true wait "$HTTP_PID" 2>/dev/null || true HTTP_PID= fi HTTP_LOG= HTTP_PORT= if [ -n "${SLATTACH_PID:-}" ]; then sudo -n kill "$SLATTACH_PID" >/dev/null 2>&1 || true wait "$SLATTACH_PID" 2>/dev/null || true SLATTACH_PID= fi if [ -n "${SL_IFACE:-}" ]; then sudo -n ip addr flush dev "$SL_IFACE" >/dev/null 2>&1 || true sudo -n ip link set dev "$SL_IFACE" down >/dev/null 2>&1 || true SL_IFACE= fi if [ -n "${QEMU_PID:-}" ]; then kill "$QEMU_PID" >/dev/null 2>&1 || true wait "$QEMU_PID" 2>/dev/null || true QEMU_PID= fi QEMU_PTY= QEMU_LOG= } cleanup_all() { cleanup_phase } trap cleanup_all EXIT INT TERM require_host_tools() { if ! command -v sudo >/dev/null 2>&1; then echo "sudo not found" >&2 exit 1 fi if ! sudo -n true >/dev/null 2>&1; then echo "passwordless sudo is required for slattach/ip setup" >&2 exit 1 fi if ! command -v ip >/dev/null 2>&1; then echo "ip command not found" >&2 exit 1 fi if ! command -v python3 >/dev/null 2>&1; then echo "python3 not found" >&2 exit 1 fi if [ ! -x "$MFS" ]; then echo "mfs tool not found at $MFS" >&2 exit 1 fi if [ ! -f "$IMAGE" ]; then echo "image not found at $IMAGE" >&2 exit 1 fi } render_rc() { rcfile=$1 protocol=$2 mode=$3 cat >"$rcfile" <<EOF # System initialization script for qemu $protocol testing exec > /boot.log 2>&1 umask 022 export PATH=/bin export UIP_TRACE=/tmp/uip.trace source /etc/profile clock -s -u uip -b -p $protocol -m $MTU -s $BAUD -l /dev/ttyS0 $GUEST_IP $HOST_IP $NETMASK || exit 1 sleep 6 EOF case "$mode" in inbound) cat >>"$rcfile" <<'EOF' telnetd & while true do sync sleep 10 done EOF ;; outbound) cat >>"$rcfile" <<EOF urlget http://$HOST_IP:$HTTP_PORT/ > /url.out 2>&1 echo \$? > /url.status sync sleep 20 EOF ;; *) echo "unknown rc mode: $mode" >&2 exit 1 ;; esac } prepare_image() { base_image=$1 out_image=$2 protocol=$3 mode=$4 rcfile=$WORKDIR/rc.${protocol}.${mode} cp "$base_image" "$out_image" render_rc "$rcfile" "$protocol" "$mode" "$MFS" "$out_image" rm /etc/rc.sys >/dev/null 2>&1 || true "$MFS" "$out_image" cp "$rcfile" /etc/rc.sys } pick_http_port() { if [ -n "${HTTP_PORT:-}" ]; then return fi HTTP_PORT=$(python3 - <<'PY' import socket with socket.socket() as sock: sock.bind(("0.0.0.0", 0)) print(sock.getsockname()[1]) PY ) } start_qemu() { image_file=$1 name=$2 QEMU_LOG=$WORKDIR/${name}.qemu.log "$QEMU_BIN" \ -nodefaults \ -machine isapc \ -cpu 486,tsc \ -m 8M \ -rtc base=utc \ -display none \ -monitor none \ -serial none \ -chardev pty,id=slip0 \ -device isa-serial,chardev=slip0,id=ser0 \ -drive file="$image_file",if=floppy,format=raw \ -boot a >"$QEMU_LOG" 2>&1 & QEMU_PID=$! for _ in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do QEMU_PTY=$(grep -o '/dev/pts/[0-9][0-9]*' "$QEMU_LOG" | tail -n 1 || true) if [ -n "$QEMU_PTY" ]; then return fi sleep 1 done echo "failed to locate qemu pty for $name" >&2 exit 1 } attach_slip() { protocol=$1 before_ifaces=$(list_sl_ifaces | tr '\n' ' ') sudo -n /sbin/slattach -p "$protocol" -L -s "$BAUD" "$QEMU_PTY" >/dev/null 2>&1 & SLATTACH_PID=$! for _ in 1 2 3 4 5 6 7 8 9 10; do for iface in $(list_sl_ifaces); do case " $before_ifaces " in *" $iface "*) ;; *) SL_IFACE=$iface break ;; esac done if [ -n "${SL_IFACE:-}" ]; then break fi sleep 1 done if [ -z "${SL_IFACE:-}" ]; then SL_IFACE=$(list_sl_ifaces | tail -n 1 || true) fi if [ -z "${SL_IFACE:-}" ]; then echo "failed to create slip interface for $protocol" >&2 exit 1 fi sudo -n ip addr flush dev "$SL_IFACE" >/dev/null 2>&1 || true sudo -n ip link set dev "$SL_IFACE" mtu "$MTU" up sudo -n ip addr add "$HOST_IP" peer "$GUEST_IP" dev "$SL_IFACE" } extract_guest_file() { image_file=$1 guest_path=$2 host_path=$3 if "$MFS" -f "$image_file" cat "$guest_path" >"$host_path" 2>/dev/null; then return 0 fi : >"$host_path" return 1 } collect_phase_artifacts() { image_file=$1 protocol=$2 mode=$3 extract_guest_file "$image_file" /boot.log "$WORKDIR/${protocol}.${mode}.boot.log" || true extract_guest_file "$image_file" /tmp/uip.trace "$WORKDIR/${protocol}.${mode}.trace" || true } fail_phase() { message=$1 image_file=$2 protocol=$3 mode=$4 cleanup_phase collect_phase_artifacts "$image_file" "$protocol" "$mode" echo "$message" >&2 exit 1 } start_http_server() { HTTP_ROOT=$WORKDIR/http-root HTTP_LOG=$WORKDIR/$1.httpd.log mkdir -p "$HTTP_ROOT" printf 'uip %s outbound test\n' "$1" >"$HTTP_ROOT/index.html" python3 -m http.server "$HTTP_PORT" --bind "$HOST_IP" --directory "$HTTP_ROOT" >"$HTTP_LOG" 2>&1 & HTTP_PID=$! sleep 1 if ! kill -0 "$HTTP_PID" >/dev/null 2>&1; then wait "$HTTP_PID" 2>/dev/null || true return 1 fi } probe_telnet() { host=$1 outfile=$2 python3 - "$host" "$outfile" <<'PY' import socket import sys host, outfile = sys.argv[1], sys.argv[2] s = socket.create_connection((host, 23), timeout=5) try: data = s.recv(8) finally: s.close() with open(outfile, "wb") as f: f.write(data) if not data.startswith(b"\xff\xfb"): raise SystemExit(1) PY } wait_for_http() { host=$1 outfile=$2 for _ in 1 2 3 4 5 6 7 8 9 10 \ 11 12 13 14 15 16 17 18 19 20 \ 21 22 23 24 25 26 27 28 29 30 \ 31 32 33 34 35 36 37 38 39 40 \ 41 42 43 44 45 46 47 48 49 50 \ 51 52 53 54 55 56 57 58 59 60; do if curl --silent --fail --noproxy '*' "http://$host/" >"$outfile" 2>/dev/null; then return 0 fi sleep 1 done return 1 } run_outbound() { protocol=$1 image_file=$WORKDIR/${protocol}.outbound.img status_file=$WORKDIR/${protocol}.url.status output_file=$WORKDIR/${protocol}.url.out pick_http_port prepare_image "$IMAGE" "$image_file" "$protocol" outbound start_qemu "$image_file" "${protocol}.outbound" attach_slip "$protocol" if ! start_http_server "$protocol"; then fail_phase "$protocol outbound failed: host HTTP server did not start on $HOST_IP:$HTTP_PORT" \ "$image_file" "$protocol" outbound fi sleep 25 cleanup_phase extract_guest_file "$image_file" /url.status "$status_file" extract_guest_file "$image_file" /url.out "$output_file" collect_phase_artifacts "$image_file" "$protocol" outbound if [ "$(tr -d '\r\n' <"$status_file")" != "0" ]; then echo "$protocol outbound failed: expected status 0" >&2 exit 1 fi if ! grep -q "uip $protocol outbound test" "$output_file"; then echo "$protocol outbound failed: missing expected response body" >&2 exit 1 fi echo "$protocol outbound: ok" } run_inbound() { protocol=$1 image_file=$WORKDIR/${protocol}.inbound.img telnet_file=$WORKDIR/${protocol}.telnet.out prepare_image "$IMAGE" "$image_file" "$protocol" inbound start_qemu "$image_file" "${protocol}.inbound" attach_slip "$protocol" sleep 10 if ! probe_telnet "$GUEST_IP" "$telnet_file"; then fail_phase "$protocol inbound telnet probe failed" \ "$image_file" "$protocol" inbound fi cleanup_phase collect_phase_artifacts "$image_file" "$protocol" inbound echo "$protocol inbound: ok" } run_protocol() { protocol=$1 echo "Testing $protocol in $WORKDIR" run_outbound "$protocol" run_inbound "$protocol" } require_host_tools case "${1:-both}" in slip) run_protocol slip ;; cslip) run_protocol cslip ;; both) run_protocol slip run_protocol cslip ;; *) usage ;; esac echo "Artifacts saved in $WORKDIR"
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
master
Visibility
public
Your access
Read
Remote
Configured
File activity
View file history