mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-29 23:27:19 -05:00
The PortMaster port now starts install.py --tui on the console (or in foot or xterm under a compositor), with gptokeyb in kill mode on the installer's path, retrobios.gptk, TERM=linux and a Terminus font, and puts the console, font and mapper back on exit. pugwash screens stay as the fallback where no terminal can show, and start in no-check mode so PortMaster's A/B fix applies. Without a network, every launcher installs from a pack found on the card or names the pack and the folder. Adds launchers for Batocera and Knulli (Ports, evmapy .keys), muOS (.muxapp in muxterm with gptokeyb2) and the Tools menu of ArkOS, dArkOS, ROCKNIX, JELOS and AmberELEC, built by build_port.py with the pinned installer and tested on a simulated device.
503 lines
16 KiB
Plaintext
503 lines
16 KiB
Plaintext
#!/bin/bash
|
|
# shellcheck shell=bash
|
|
# RetroBIOS on a handheld: runs install.py --tui on a terminal the player can
|
|
# see, with the controller mapped to the keys the interface reads.
|
|
#
|
|
# Sourced by every launcher (the PortMaster port, the Batocera and Knulli
|
|
# port, the muOS app, the Tools entry), each of which sets the inputs below
|
|
# and calls rb_select_python, then rb_launch. Run as `bash tui.txt here`, it
|
|
# is the part that runs inside a terminal app the launcher opened.
|
|
#
|
|
# Inputs, all optional:
|
|
# RB_ROUTES where to look for a terminal, in order: here (this
|
|
# script's own stdin and stdout), app (foot or xterm in the
|
|
# graphical session), vt (a Linux console). Default "app vt".
|
|
# RB_CONSOLE the console of the vt route (default /dev/tty0)
|
|
# RB_VT_SWITCH a console number to switch to when a graphical session
|
|
# covers the current one (Batocera, Knulli)
|
|
# RB_MAPPER the command that starts gptokeyb, kill flag included
|
|
# ("$GPTOKEYB" in a PortMaster port), empty for none
|
|
# RB_GPTK its mapping (default retrobios.gptk next to this file)
|
|
# RB_PACK_PATH folders searched for a pack when there is no network,
|
|
# separated by ":", the first one named to the player
|
|
# RB_FALLBACK 1 when the launcher has screens of its own to fall back to
|
|
# ESUDO sudo where the launcher needs it, as PortMaster sets it
|
|
|
|
RB_LIB="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
|
|
RB_DIR="${RB_DIR:-$(dirname "$RB_LIB")}"
|
|
RB_INSTALL="${RB_INSTALL:-$RB_DIR/install.py}"
|
|
RB_EVENTS="${RB_EVENTS:-$RB_DIR/rbevents.py}"
|
|
RB_GPTK="${RB_GPTK:-$RB_DIR/retrobios.gptk}"
|
|
RB_STATE="${RB_STATE:-$RB_DIR/run}"
|
|
RB_LOG="${RB_LOG:-$RB_DIR/log.txt}"
|
|
RB_ROUTES="${RB_ROUTES:-app vt}"
|
|
RB_CONSOLE="${RB_CONSOLE:-/dev/tty0}"
|
|
RB_PACK_PATH="${RB_PACK_PATH:-$RB_DIR}"
|
|
RB_FONTS="${RB_FONTS:-/usr/share/consolefonts}"
|
|
RB_FB="${RB_FB:-/sys/class/graphics/fb0/virtual_size}"
|
|
RB_ROUTE_TABLE="${RB_ROUTE_TABLE:-/proc/net/route}"
|
|
RB_VT_ACTIVE="${RB_VT_ACTIVE:-/sys/class/tty/tty0/active}"
|
|
RB_PROBE_URL="${RETROBIOS_BASE_URL:-https://raw.githubusercontent.com/Abdess/retrobios/}"
|
|
RB_RUNTIME="python_3.11"
|
|
RB_RELEASES="github.com/Abdess/retrobios/releases/latest"
|
|
RB_PC_ROUTE="On a computer, with this SD card mounted, the same installer fills the card: install.py --platform NAME --dest BIOS-FOLDER-ON-THE-CARD. Instructions: abdess.github.io/retrobios/wiki/installer"
|
|
RB_PYTHON="${RB_PYTHON:-}"
|
|
RB_PYTHONHOME="${RB_PYTHONHOME:-}"
|
|
RB_PYTHON_PROBLEM="${RB_PYTHON_PROBLEM:-}"
|
|
RB_MOUNTED=""
|
|
RB_MAPPER_PID=""
|
|
RB_TTY=""
|
|
RB_STTY=""
|
|
RB_FONT_BACK=""
|
|
RB_VT_BACK=""
|
|
RB_ROUTE=""
|
|
RB_TERMAPP=()
|
|
|
|
rb_arch() {
|
|
uname -m
|
|
}
|
|
|
|
rb_py() {
|
|
if [ -n "$RB_PYTHONHOME" ]; then
|
|
PYTHONHOME="$RB_PYTHONHOME" "$RB_PYTHON" "$@"
|
|
else
|
|
"$RB_PYTHON" "$@"
|
|
fi
|
|
}
|
|
|
|
# --- Python ---------------------------------------------------------------
|
|
|
|
rb_python_ok() {
|
|
"$@" -c 'import sys; sys.exit(0 if sys.version_info >= (3, 8) else 1)' >/dev/null 2>&1
|
|
}
|
|
|
|
# The OS python3 when it is 3.8 or newer, else PortMaster's python_3.11
|
|
# runtime on aarch64, mounted as PortMaster's own Python ports do. A launcher
|
|
# that can download the runtime defines rb_fetch_runtime. Sets
|
|
# RB_PYTHON_PROBLEM when neither can run install.py.
|
|
rb_select_python() {
|
|
if command -v python3 >/dev/null 2>&1 && rb_python_ok python3; then
|
|
RB_PYTHON="python3"
|
|
return 0
|
|
fi
|
|
if [ "$(rb_arch)" != "aarch64" ]; then
|
|
RB_PYTHON_PROBLEM="old"
|
|
return 1
|
|
fi
|
|
rb_runtime
|
|
}
|
|
|
|
rb_runtime() {
|
|
local python_dir="$HOME/$RB_RUNTIME"
|
|
local squashfs="${controlfolder:-/nonexistent}/libs/$RB_RUNTIME.squashfs"
|
|
if [ ! -f "$squashfs" ]; then
|
|
if ! declare -F rb_fetch_runtime >/dev/null; then
|
|
RB_PYTHON_PROBLEM="runtime_missing"
|
|
return 1
|
|
fi
|
|
rb_fetch_runtime "$squashfs" || return 1
|
|
fi
|
|
mkdir -p "$python_dir"
|
|
if [ "${PM_CAN_MOUNT:-Y}" != "N" ]; then
|
|
$ESUDO umount "$python_dir" >/dev/null 2>&1
|
|
fi
|
|
if ! $ESUDO mount "$squashfs" "$python_dir"; then
|
|
RB_PYTHON_PROBLEM="runtime_failed"
|
|
return 1
|
|
fi
|
|
RB_MOUNTED="$python_dir"
|
|
RB_PYTHON="$python_dir/bin/python3"
|
|
RB_PYTHONHOME="$python_dir"
|
|
if ! PYTHONHOME="$python_dir" rb_python_ok "$RB_PYTHON"; then
|
|
RB_PYTHON=""
|
|
RB_PYTHON_PROBLEM="runtime_failed"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
rb_release_python() {
|
|
if [ -n "$RB_MOUNTED" ] && [ "${PM_CAN_MOUNT:-Y}" != "N" ]; then
|
|
$ESUDO umount "$RB_MOUNTED" >/dev/null 2>&1
|
|
fi
|
|
RB_MOUNTED=""
|
|
}
|
|
|
|
rb_python_text() {
|
|
local found
|
|
found=$(python3 --version 2>&1 | awk '{print $2}')
|
|
case "$RB_PYTHON_PROBLEM" in
|
|
old) printf '%s\n' "Python 3.8 or newer is needed. This system has ${found:-none}, and PortMaster's Python runtime exists for aarch64 only, and this device is $(rb_arch). $RB_PC_ROUTE" ;;
|
|
runtime_offline) printf '%s\n' "Python 3.8 or newer is needed. This system has ${found:-none}, and PortMaster's $RB_RUNTIME runtime needs a connection to download. $RB_PC_ROUTE" ;;
|
|
runtime_missing) printf '%s\n' "Python 3.8 or newer is needed. This system has ${found:-none}. The RetroBIOS port from PortMaster downloads PortMaster's $RB_RUNTIME runtime, which this entry then uses too. $RB_PC_ROUTE" ;;
|
|
*) printf '%s\n' "Python 3.8 or newer is needed. This system has ${found:-none}, and PortMaster's $RB_RUNTIME runtime could not be installed or run. $RB_PC_ROUTE" ;;
|
|
esac
|
|
}
|
|
|
|
# --- Network and packs ----------------------------------------------------
|
|
|
|
# Whether the file list can be reached. Only a failure to resolve or to
|
|
# connect counts as offline: a certificate refused by an old curl still means
|
|
# a network, and install.py names that problem itself.
|
|
rb_online() {
|
|
local code
|
|
if command -v curl >/dev/null 2>&1; then
|
|
curl -sSI --max-time 8 "$RB_PROBE_URL" >/dev/null 2>&1
|
|
code=$?
|
|
case "$code" in
|
|
5|6|7|28) return 1 ;;
|
|
*) return 0 ;;
|
|
esac
|
|
fi
|
|
if command -v wget >/dev/null 2>&1; then
|
|
wget -q --spider -T 8 "$RB_PROBE_URL" >/dev/null 2>&1
|
|
[ $? -ne 4 ]
|
|
return
|
|
fi
|
|
# Neither tool: a default route is the best guess there is.
|
|
awk 'NR > 1 && $2 == "00000000" { found = 1 } END { exit !found }' "$RB_ROUTE_TABLE" 2>/dev/null
|
|
}
|
|
|
|
# The system and BIOS folder install.py finds here, read without a network:
|
|
# detection is local, and the run stops where the file list would download.
|
|
rb_detect() {
|
|
RB_PLATFORM=""
|
|
RB_PLATFORM_NAME=""
|
|
RB_BIOS_DIR=""
|
|
mkdir -p "$RB_STATE"
|
|
rb_py "$RB_INSTALL" --check --events > "$RB_STATE/detect.jsonl" 2>> "$RB_LOG"
|
|
local kind a b c
|
|
while IFS=$'\t' read -r kind a b c; do
|
|
if [ "$kind" = "platform" ]; then
|
|
RB_PLATFORM="$a"
|
|
RB_PLATFORM_NAME="$b"
|
|
RB_BIOS_DIR="$c"
|
|
[ "$RB_BIOS_DIR" = "-" ] && RB_BIOS_DIR=""
|
|
break
|
|
fi
|
|
done < <(rb_py "$RB_EVENTS" status "$RB_STATE/detect.jsonl" 2>> "$RB_LOG")
|
|
}
|
|
|
|
# The first pack in RB_PACK_PATH, one whose name spells this system first:
|
|
# install.py reads the platform from the same spelling (Name_With_Underscores
|
|
# between two underscores).
|
|
rb_find_pack() {
|
|
local dir file base stem first="" want=""
|
|
if [ -n "${RB_PLATFORM_NAME:-}" ]; then
|
|
want="_${RB_PLATFORM_NAME// /_}_"
|
|
fi
|
|
local IFS=":"
|
|
for dir in $RB_PACK_PATH; do
|
|
[ -d "$dir" ] || continue
|
|
for file in "$dir"/*_BIOS_Pack.zip "$dir"/*_BIOS_Pack.part1of*.zip; do
|
|
[ -f "$file" ] || continue
|
|
base="${file##*/}"
|
|
stem="_${base%%_BIOS_Pack*}_"
|
|
if [ -n "$want" ] && [[ "$stem" == *"$want"* ]]; then
|
|
printf '%s\n' "$file"
|
|
return 0
|
|
fi
|
|
[ -z "$first" ] && first="$file"
|
|
done
|
|
done
|
|
[ -n "$first" ] && printf '%s\n' "$first"
|
|
return 0
|
|
}
|
|
|
|
rb_pack_text() {
|
|
local dir="${RB_PACK_PATH%%:*}" pack
|
|
if [ -n "${RB_PLATFORM_NAME:-}" ]; then
|
|
pack="the BIOS pack whose name contains ${RB_PLATFORM_NAME// /_}"
|
|
else
|
|
pack="the BIOS pack for this system (a file whose name ends in _BIOS_Pack.zip)"
|
|
fi
|
|
printf '%s\n' "No network connection. To install without one, download $pack from $RB_RELEASES on a computer, copy it into $dir on the SD card, then start RetroBIOS again. Or connect to Wi-Fi and start again."
|
|
}
|
|
|
|
# --- Terminal -------------------------------------------------------------
|
|
|
|
rb_graphical() {
|
|
[ -n "${WAYLAND_DISPLAY:-}" ] || [ -n "${DISPLAY:-}" ] \
|
|
|| pgrep -x 'sway|weston|labwc|cage|gamescope|Xorg|X' >/dev/null 2>&1
|
|
}
|
|
|
|
# A terminal app the graphical session can show, full screen. A launcher
|
|
# that knows its own (muOS's muxterm) sets RB_TERMAPP after sourcing this.
|
|
rb_terminal_app() {
|
|
if [ "${#RB_TERMAPP[@]}" -gt 0 ]; then
|
|
return 0
|
|
fi
|
|
if [ -z "${WAYLAND_DISPLAY:-}" ] && [ -z "${DISPLAY:-}" ]; then
|
|
return 1
|
|
fi
|
|
if command -v foot >/dev/null 2>&1; then
|
|
RB_TERMAPP=(foot -F --)
|
|
elif command -v xterm >/dev/null 2>&1; then
|
|
RB_TERMAPP=(xterm -fullscreen -e)
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Sets RB_ROUTE to the first of RB_ROUTES that can show text: here, app,
|
|
# vt, or none.
|
|
rb_route() {
|
|
local route
|
|
RB_ROUTE="none"
|
|
for route in $RB_ROUTES; do
|
|
case "$route" in
|
|
here)
|
|
if [ -t 0 ] && [ -t 1 ]; then
|
|
RB_ROUTE="here"
|
|
return 0
|
|
fi
|
|
;;
|
|
app)
|
|
if rb_terminal_app; then
|
|
RB_ROUTE="app"
|
|
return 0
|
|
fi
|
|
;;
|
|
vt)
|
|
# A compositor or X server holds the console it runs on: text
|
|
# written there is never seen, so the console needs a switch.
|
|
if rb_graphical; then
|
|
if [ -n "${RB_VT_SWITCH:-}" ] && command -v chvt >/dev/null 2>&1 \
|
|
&& [ -n "$(rb_active_vt)" ]; then
|
|
RB_ROUTE="vt"
|
|
return 0
|
|
fi
|
|
elif [ -c "$RB_CONSOLE" ]; then
|
|
RB_ROUTE="vt"
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# The largest Terminus font that keeps 56 columns and 20 rows, the way
|
|
# dArkOS's own tools pick one per screen (Lat7-Terminus16 on 480x320,
|
|
# TerminusBold22x11 on 640x480, 32x16 on 1024x768). Only changed when the
|
|
# font in place can be put back: saved with setfont -O, or the
|
|
# Lat7-Terminus20x10 ArkOS tools restore.
|
|
rb_font_set() {
|
|
command -v setfont >/dev/null 2>&1 || return 0
|
|
local size width height spec fh fw name file="" fallback
|
|
size=$(cat "$RB_FB" 2>/dev/null) || return 0
|
|
width="${size%%,*}"
|
|
height="${size##*,}"
|
|
case "$width$height" in
|
|
''|*[!0-9]*) return 0 ;;
|
|
esac
|
|
for spec in "32 16 Lat7-TerminusBold32x16" "28 14 Lat7-TerminusBold28x14" \
|
|
"22 11 Lat7-TerminusBold22x11" "20 10 Lat7-TerminusBold20x10" \
|
|
"16 8 Lat7-Terminus16"; do
|
|
read -r fh fw name <<< "$spec"
|
|
if [ $((width / fw)) -ge 56 ] && [ $((height / fh)) -ge 20 ] \
|
|
&& [ -f "$RB_FONTS/$name.psf.gz" ]; then
|
|
file="$RB_FONTS/$name.psf.gz"
|
|
break
|
|
fi
|
|
done
|
|
if [ -z "$file" ] && [ $((width / 8)) -ge 40 ] && [ $((height / 16)) -ge 12 ] \
|
|
&& [ -f "$RB_FONTS/Lat7-Terminus16.psf.gz" ]; then
|
|
file="$RB_FONTS/Lat7-Terminus16.psf.gz"
|
|
fi
|
|
[ -n "$file" ] || return 0
|
|
if $ESUDO setfont -C "$RB_TTY" -O "$RB_STATE/font.psf" "$file" >> "$RB_LOG" 2>&1 \
|
|
&& [ -s "$RB_STATE/font.psf" ]; then
|
|
RB_FONT_BACK="$RB_STATE/font.psf"
|
|
return 0
|
|
fi
|
|
fallback="$RB_FONTS/Lat7-Terminus20x10.psf.gz"
|
|
if [ -f "$fallback" ] && $ESUDO setfont -C "$RB_TTY" "$file" >> "$RB_LOG" 2>&1; then
|
|
RB_FONT_BACK="$fallback"
|
|
fi
|
|
}
|
|
|
|
rb_font_restore() {
|
|
if [ -n "$RB_FONT_BACK" ]; then
|
|
$ESUDO setfont -C "$RB_TTY" "$RB_FONT_BACK" >> "$RB_LOG" 2>&1
|
|
fi
|
|
RB_FONT_BACK=""
|
|
}
|
|
|
|
# The number of the console in front, which a switch has to come back to.
|
|
rb_active_vt() {
|
|
local active
|
|
active=$(cat "$RB_VT_ACTIVE" 2>/dev/null)
|
|
active="${active#tty}"
|
|
case "$active" in
|
|
''|*[!0-9]*) active=$(fgconsole 2>/dev/null) ;;
|
|
esac
|
|
case "$active" in
|
|
''|*[!0-9]*) return 1 ;;
|
|
esac
|
|
printf '%s\n' "$active"
|
|
}
|
|
|
|
rb_vt_enter() {
|
|
RB_TTY="$RB_CONSOLE"
|
|
if rb_graphical && [ -n "${RB_VT_SWITCH:-}" ]; then
|
|
RB_VT_BACK=$(rb_active_vt)
|
|
RB_TTY="${RB_VT_PREFIX:-/dev/tty}$RB_VT_SWITCH"
|
|
$ESUDO chvt "$RB_VT_SWITCH" >> "$RB_LOG" 2>&1
|
|
fi
|
|
if [ ! -r "$RB_TTY" ] || [ ! -w "$RB_TTY" ]; then
|
|
$ESUDO chmod 666 "$RB_TTY" >> "$RB_LOG" 2>&1
|
|
fi
|
|
RB_STTY=$(stty -g < "$RB_TTY" 2>/dev/null)
|
|
printf '\033c' > "$RB_TTY"
|
|
rb_font_set
|
|
}
|
|
|
|
rb_vt_leave() {
|
|
[ -n "$RB_TTY" ] || return 0
|
|
rb_font_restore
|
|
printf '\033c' > "$RB_TTY" 2>/dev/null
|
|
if [ -n "$RB_STTY" ]; then
|
|
stty "$RB_STTY" < "$RB_TTY" 2>/dev/null
|
|
fi
|
|
if [ -n "$RB_VT_BACK" ]; then
|
|
$ESUDO chvt "$RB_VT_BACK" >> "$RB_LOG" 2>&1
|
|
fi
|
|
RB_TTY=""
|
|
RB_STTY=""
|
|
RB_VT_BACK=""
|
|
}
|
|
|
|
# gptokeyb on a name only this installer's processes carry: kill mode runs
|
|
# pkill -f on it, and the path of install.py is in the command line of the
|
|
# interface and of every run it starts, never in python3's alone.
|
|
rb_mapper_start() {
|
|
[ -n "${RB_MAPPER:-}" ] || return 0
|
|
# shellcheck disable=SC2086 # RB_MAPPER is a command and its flags, as $GPTOKEYB is
|
|
$RB_MAPPER "$RB_INSTALL" -c "$RB_GPTK" >> "$RB_LOG" 2>&1 &
|
|
RB_MAPPER_PID=$!
|
|
}
|
|
|
|
rb_mapper_stop() {
|
|
[ -n "$RB_MAPPER_PID" ] || return 0
|
|
$ESUDO kill "$RB_MAPPER_PID" >/dev/null 2>&1
|
|
wait "$RB_MAPPER_PID" 2>/dev/null
|
|
RB_MAPPER_PID=""
|
|
}
|
|
|
|
# A screen of text on the current terminal, closed by any button.
|
|
rb_message() {
|
|
local cols
|
|
cols=$(stty size 2>/dev/null | awk '{print $2}')
|
|
case "$cols" in
|
|
''|*[!0-9]*) cols=40 ;;
|
|
esac
|
|
[ "$cols" -ge 20 ] || cols=40
|
|
printf '\033[2J\033[H'
|
|
printf 'RetroBIOS\n\n'
|
|
printf '%s\n' "$1" | fold -s -w $((cols - 1))
|
|
printf '\n%s\n' "Press A or Enter to close."
|
|
read -r -s -n 1 -t "${RB_MESSAGE_WAIT:-300}" _
|
|
printf '\033[2J\033[H'
|
|
}
|
|
|
|
# --- The run --------------------------------------------------------------
|
|
|
|
# The interface on the current terminal: install.py --tui, from a pack on the
|
|
# card when there is no network. The status also goes to RB_STATE/status,
|
|
# since a terminal app does not always pass its child's on.
|
|
rb_here() {
|
|
local status pack args=()
|
|
mkdir -p "$RB_STATE"
|
|
rm -f "$RB_STATE/status"
|
|
case "${TERM:-}" in
|
|
''|dumb|unknown) export TERM=xterm ;;
|
|
esac
|
|
if [ -z "$RB_PYTHON" ]; then
|
|
rb_message "$(rb_python_text)"
|
|
printf '1\n' > "$RB_STATE/status"
|
|
return 1
|
|
fi
|
|
if ! rb_online; then
|
|
rb_detect
|
|
pack=$(rb_find_pack)
|
|
if [ -z "$pack" ]; then
|
|
rb_message "$(rb_pack_text)"
|
|
printf '1\n' > "$RB_STATE/status"
|
|
return 1
|
|
fi
|
|
args=(--from-pack "$pack")
|
|
if [ -n "$RB_PLATFORM" ]; then
|
|
args+=(--platform "$RB_PLATFORM")
|
|
fi
|
|
fi
|
|
rb_py "$RB_INSTALL" --tui "${args[@]}" "$@" 2> "$RB_STATE/tui.err"
|
|
status=$?
|
|
cat "$RB_STATE/tui.err" >> "$RB_LOG" 2>/dev/null
|
|
if [ "$status" = "2" ] && grep -q -- "--tui cannot open" "$RB_STATE/tui.err"; then
|
|
status=125
|
|
if [ "${RB_FALLBACK:-0}" != "1" ]; then
|
|
rb_message "$(tail -n 1 "$RB_STATE/tui.err") The messages are in $RB_LOG."
|
|
fi
|
|
elif [ "$status" != "0" ] && [ -s "$RB_STATE/tui.err" ]; then
|
|
rb_message "$(tail -n 1 "$RB_STATE/tui.err") The messages are in $RB_LOG."
|
|
fi
|
|
printf '%s\n' "$status" > "$RB_STATE/status"
|
|
return "$status"
|
|
}
|
|
|
|
rb_cleanup() {
|
|
rb_vt_leave
|
|
rb_mapper_stop
|
|
}
|
|
|
|
# The whole session: the terminal, the mapper, the interface, then the
|
|
# console, its font and the mapper put back. Returns the interface's status,
|
|
# 125 when no terminal could show it.
|
|
rb_launch() {
|
|
local status
|
|
mkdir -p "$RB_STATE"
|
|
if ! rb_route; then
|
|
printf '%s\n' "RetroBIOS: no terminal to show the interface on (routes: $RB_ROUTES)" >> "$RB_LOG"
|
|
return 125
|
|
fi
|
|
export RB_DIR RB_INSTALL RB_EVENTS RB_STATE RB_LOG RB_PACK_PATH RB_FALLBACK
|
|
export RB_PYTHON RB_PYTHONHOME RB_PYTHON_PROBLEM RB_MESSAGE_WAIT RB_ROUTE_TABLE
|
|
trap 'rb_cleanup; exit 143' TERM HUP
|
|
rb_mapper_start
|
|
case "$RB_ROUTE" in
|
|
here)
|
|
rb_here "$@"
|
|
status=$?
|
|
;;
|
|
app)
|
|
"${RB_TERMAPP[@]}" bash "$RB_LIB" here "$@" 2>> "$RB_LOG"
|
|
status=$(cat "$RB_STATE/status" 2>/dev/null)
|
|
;;
|
|
vt)
|
|
rb_vt_enter
|
|
export TERM=linux
|
|
# shellcheck disable=SC2094 # a console is read and written at once by design
|
|
rb_here "$@" < "$RB_TTY" > "$RB_TTY" 2>> "$RB_LOG"
|
|
status=$?
|
|
;;
|
|
esac
|
|
rb_cleanup
|
|
trap - TERM HUP
|
|
return "${status:-1}"
|
|
}
|
|
|
|
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
|
|
case "${1:-}" in
|
|
here)
|
|
shift
|
|
rb_here "$@"
|
|
exit $?
|
|
;;
|
|
*)
|
|
printf '%s\n' "usage: bash tui.txt here [install.py options]" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
fi
|