#!/bin/bash # /usr/local/bin/dos-shell # Prepare the SvarDOS environment and launch dosemu. set -euo pipefail ALLOWED_LIST="/etc/dos_allowed" ALLOWED_REPO="/opt/allowed_repo" ENV_DIR="/etc/dos_env" AUTOEXEC_TEMPLATE="${ENV_DIR}/AUTOEXEC.BAT" CONFIG_TEMPLATE="${ENV_DIR}/CONFIG.SYS" SVARDOS_ROOT="${SVARDOS_ROOT:-/opt/svardos}" SVARDOS_BASE="${SVARDOS_BASE:-${SVARDOS_ROOT}/base}" ALLOW_MODE="${DOS_ALLOW_MODE:-all}" DEFAULT_DOS_USER="dosuser" INSTALL_SENTINEL_NAME=".svardos_installed" if [ "$(id -u)" -eq 0 ]; then DOS_USER="${DEFAULT_DOS_USER}" DOS_HOME="$(getent passwd "${DOS_USER}" | cut -d: -f6)" else DOS_USER="$(id -un)" DOS_HOME="${HOME}" fi if [ -z "${DOS_HOME}" ]; then echo "Unable to determine home directory for ${DOS_USER}" >&2 exit 1 fi DOSEMU_DIR="${DOS_HOME}/.dosemu" C_DRIVE="${DOSEMU_DIR}/drive_c" INSTALL_SENTINEL_PATH="${DOSEMU_DIR}/${INSTALL_SENTINEL_NAME}" DOSEMU_ARGS=() detect_dosemu_args() { local mode="${DOS_TERMINAL_MODE:-auto}" if [ "${mode}" = "auto" ]; then if [ -n "${DISPLAY:-}" ]; then mode="x" else mode="terminal" fi fi case "${mode,,}" in x|sdl|window|gui) DOSEMU_ARGS=(-X -K "${C_DRIVE}") ;; terminal|tty|text) DOSEMU_ARGS=(-td -K "${C_DRIVE}") ;; dumb) DOSEMU_ARGS=(-dumb -K "${C_DRIVE}") ;; *) echo "Unknown DOS_TERMINAL_MODE '${mode}', defaulting to terminal mode." >&2 DOSEMU_ARGS=(-td -K "${C_DRIVE}") ;; esac } allowed_entries=() mkdir -p "${DOSEMU_DIR}" "${C_DRIVE}" if [ "$(id -u)" -eq 0 ] && [ ! -d "${ENV_DIR}" ]; then mkdir -p "${ENV_DIR}" fi reset_drive_c() { if [ ! -d "${SVARDOS_BASE}" ] || [ -z "$(ls -A "${SVARDOS_BASE}")" ]; then echo "SvarDOS base directory ${SVARDOS_BASE} is empty. Aborting." >&2 exit 1 fi rm -rf "${C_DRIVE:?}/"* cp -a "${SVARDOS_BASE}/." "${C_DRIVE}/" if [ "$(id -u)" -eq 0 ]; then chown -R "${DOS_USER}:${DOS_USER}" "${DOSEMU_DIR}" fi if [ -f "${DOS_HOME}/.dosemurc" ]; then rm -f "${DOS_HOME}/.dosemurc" fi echo "SvarDOS base staged to ${C_DRIVE}" } sync_allowed_content() { allowed_entries=() local mode="${ALLOW_MODE}" if [ "${mode}" = "all" ]; then if [ -d "${ALLOWED_REPO}" ] && [ "$(ls -A "${ALLOWED_REPO}" 2>/dev/null)" ]; then cp -a "${ALLOWED_REPO}/." "${C_DRIVE}/" allowed_entries+=("ALL") fi return fi if [ "${mode}" != "list" ] && [ "${mode}" != "allowlist" ]; then echo "Unknown DOS_ALLOW_MODE '${mode}', defaulting to allowlist mode." >&2 mode="list" ALLOW_MODE="${mode}" fi if [ -f "${ALLOWED_LIST}" ]; then while IFS= read -r line || [ -n "$line" ]; do line="$(printf '%s' "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" case "$line" in ''|\#*) continue ;; esac allowed_entries+=("$line") done < "${ALLOWED_LIST}" fi for entry in "${allowed_entries[@]}"; do src="${ALLOWED_REPO}/${entry}" if [ -e "$src" ]; then dst_dir="$(dirname "${entry}")" mkdir -p "${C_DRIVE}/${dst_dir}" cp -a "$src" "${C_DRIVE}/${dst_dir}/" else echo "Warning: allowed file not found: $src" >&2 fi done } apply_templates() { if [ -f "${AUTOEXEC_TEMPLATE}" ]; then cp "${AUTOEXEC_TEMPLATE}" "${C_DRIVE}/AUTOEXEC.BAT" fi if [ -f "${CONFIG_TEMPLATE}" ]; then cp "${CONFIG_TEMPLATE}" "${C_DRIVE}/CONFIG.SYS" fi } detect_dosemu_args if [ "${DOS_FORCE_INSTALL:-0}" = "1" ] || [ ! -f "${INSTALL_SENTINEL_PATH}" ]; then reset_drive_c touch "${INSTALL_SENTINEL_PATH}" if [ "$(id -u)" -eq 0 ]; then chown "${DOS_USER}:${DOS_USER}" "${INSTALL_SENTINEL_PATH}" fi else echo "Reusing existing SvarDOS installation on ${C_DRIVE}" >&2 fi sync_allowed_content apply_templates if [ "$(id -u)" -eq 0 ]; then chown -R "${DOS_USER}:${DOS_USER}" "${DOSEMU_DIR}" fi if [ "${ALLOW_MODE}" = "all" ] && [ "${#allowed_entries[@]}" -gt 0 ]; then echo "All files in ${ALLOWED_REPO} are available on drive C:." elif [ "${#allowed_entries[@]}" -gt 0 ]; then echo "Allowlisted files copied to C: from ${ALLOWED_REPO}:" for entry in "${allowed_entries[@]}"; do echo " ${entry}" done fi if [ "$(id -u)" -eq 0 ]; then exec runuser -u "${DOS_USER}" -- dosemu "${DOSEMU_ARGS[@]}" else exec dosemu "${DOSEMU_ARGS[@]}" fi