#!/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=".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_MARKER="${DOSEMU_DIR}/${INSTALL_SENTINEL}" DOSEMU_ARGS=(-dumb -K "${C_DRIVE}") allowed_entries=() mkdir -p "${DOSEMU_DIR}" "${C_DRIVE}" if [ "$(id -u)" -eq 0 ] && [ ! -d "${ENV_DIR}" ]; then mkdir -p "${ENV_DIR}" fi set_install_marker() { touch "${INSTALL_MARKER}" if [ "$(id -u)" -eq 0 ]; then chown "${DOS_USER}:${DOS_USER}" "${INSTALL_MARKER}" fi } has_svardos_installation() { if [ -f "${C_DRIVE}/COMMAND.COM" ] || [ -f "${C_DRIVE}/command.com" ]; then return 0 fi if [ -d "${C_DRIVE}/SVARDOS/BIN" ] || [ -d "${C_DRIVE}/svardos/bin" ]; then return 0 fi return 1 } needs_install() { if [ "${DOS_FORCE_INSTALL:-0}" = "1" ]; then return 0 fi if [ -f "${INSTALL_MARKER}" ]; then return 1 fi if has_svardos_installation; then set_install_marker return 1 fi return 0 } stage_initial_install() { 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}" } run_headless_install() { local log_file="${DOSEMU_DIR}/install.log" local comspec='' if [ -f "${C_DRIVE}/CMD.COM" ]; then comspec='C:\CMD.COM' elif [ -f "${C_DRIVE}/COMMAND.COM" ]; then comspec='C:\COMMAND.COM' else echo "SvarDOS provisioning failed: no command interpreter found on ${C_DRIVE}." >&2 return 1 fi local command="${comspec} /C AUTOEXEC.BAT" local status if [ "$(id -u)" -eq 0 ]; then runuser -u "${DOS_USER}" -- dosemu -dumb -K "${C_DRIVE}" -E "${command}" >"${log_file}" 2>&1 status=$? else dosemu -dumb -K "${C_DRIVE}" -E "${command}" >"${log_file}" 2>&1 status=$? fi if [ "${status}" -ne 0 ]; then echo "SvarDOS provisioning failed (dosemu exit ${status}). See ${log_file} for details." >&2 return 1 fi if [ -f "${C_DRIVE}/INSTALL.BAT" ]; then echo "SvarDOS provisioning did not complete successfully (INSTALL.BAT still present). See ${log_file}." >&2 return 1 fi return 0 } 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 } if needs_install; then stage_initial_install echo "Running initial SvarDOS provisioning..." if run_headless_install; then set_install_marker echo "SvarDOS provisioning complete." else exit 1 fi 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