#!/data/data/com.termux/files/usr/bin/env bash
#
#    dosemu2 - virtual machine for running DOS
#    Copyright (C) 2014-2020, stsp & dosemu2 contributors
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.

license=" \
    dosemu2 - virtual machine for running DOS\n \
    Copyright (C) 2014-2020, stsp & dosemu2 contributors\n \
    \n \
    This program is free software: you can redistribute it and/or modify\n \
    it under the terms of the GNU General Public License as published by\n \
    the Free Software Foundation, either version 2 of the License, or\n \
    (at your option) any later version.\n \
    \n \
    This program is distributed in the hope that it will be useful,\n \
    but WITHOUT ANY WARRANTY; without even the implied warranty of\n \
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n \
    GNU General Public License for more details.\n"

LOCAL_BUILD_PATH=/home/builder/.termux-build/dosemu2/build
LOCAL_BIN_DIR=2.0-pre9/bin
prefix=/data/data/com.termux/files/usr
libexecdir=/data/data/com.termux/files/usr/libexec

# no ldconfig in Termux, so for non-std prefix set explicit lib path
if test -n "$PREFIX" -a "$prefix" != "$PREFIX"; then
  export LD_LIBRARY_PATH=${prefix}/lib
fi

get_binary() {
  BINDIR=$(realpath `dirname "$1"`)
  if [ "$BINDIR" = "$(realpath -q $LOCAL_BUILD_PATH/$LOCAL_BIN_DIR)" ]; then
    BINARY="$BINDIR"/dosemu2.bin
    if [ ! -f "$BINARY" ]; then
      echo "$BINARY does not exist"
      exit 1
    fi
    [ -h ~/.fonts/dosemu2 ] || (mkdir -p ~/.fonts && ln -sf "$LOCAL_BUILD_PATH/etc/ttf" ~/.fonts/dosemu2)
    OPTS="$OPTS --Fcmddir $LOCAL_BUILD_PATH/commands \
        --Flibdir $LOCAL_BUILD_PATH/etc \
        --Fplugindir $BINDIR \
        "
    if [ $(uname -s) == "Darwin" ]; then
      if [ -z "$DYLD_LIBRARY_PATH" ]; then
        export DYLD_LIBRARY_PATH="$BINDIR"
      else
        export DYLD_LIBRARY_PATH="$BINDIR:$DYLD_LIBRARY_PATH"
      fi
    else
      if [ -z "$LD_LIBRARY_PATH" ]; then
        export LD_LIBRARY_PATH="$BINDIR"
      else
        export LD_LIBRARY_PATH="$BINDIR:$LD_LIBRARY_PATH"
      fi
    fi

  else
    BINARY="$libexecdir"/dosemu2/dosemu2.bin
    if [ ! -f "$BINARY" ]; then
      echo "$BINARY does not exist"
      exit 1
    fi
  fi
}
usage () {
  echo "
USAGE:

 dosemu [-dumb] [-home] [-quiet] [-input] [-cdrom path] [-license] [-exec cmd] [-s] [args...]
"
  exit 1
}

THISDIR="$PWD"
ARG0="$0"

unset STRING_I SUDO SUDOOPTS OPTS
if [ -f "/.flatpak-info" ]; then
  UNDER_FLATPAK=1
fi

mkdir -p ~/.dosemu

SUFFIX=""
while [ $# -gt 0 ] ; do
  case "$1" in
    -dumb)
      OPTS="$OPTS -td -ks"
      exec 4>&2 2>~/.dosemu/stderr.log.$BASHPID
      shift
      ;;
    -exec)
      OPTS="$OPTS -t:e -E $2"
      shift
      shift
      ;;
    -home)
      OPTS="$OPTS -d ${HOME}:R"
      shift
      ;;
    -cdrom)
      CDROM_PATH=`realpath "$2"`
      OPTS="$OPTS -d ${CDROM_PATH}:C"
      CDDEV=`findmnt -n -o SOURCE "$2"`
      shift
      shift
      if test -n "$CDDEV"; then
        STRING_I="$STRING_I cdrom "'{'"$CDDEV"'}'
      fi
      ;;
    -dos)
      shift
      if [ ! -d ~/.dosemu/install/$1 ]; then
        echo "$1 is not installed"
        exit 1
      fi
      OPTS="$OPTS --Flocal_dir %I/install/$1"
      LOG_FILE=~/.dosemu/boot.$1.log
      shift
      ;;
    -quiet)
      # Note: this switches to dumb mode rather than to work with
      # -dumb because -dumb expects to redirect only errors to the
      # log file, not the whole dosemu output of stderr.
      OPTS="$OPTS -tde -ks"
      exec 2>/dev/null
      shift
      ;;
    -input)
      OPTS="$OPTS -i `echo \"$2\" | sed 's/ /\\\\_/g'`"
      shift 2
      ;;
    -license)
      printf "$license"
      shift
      exit
      ;;
    -info)
      echo "prefix: $prefix"
      shift
      exit
      ;;
    -help)
      usage
      shift
      exit
      ;;
    -I)
      if [ -z "$2" -o -z "${2%%-*}" ]; then usage; fi
      if [ -z "$STRING_I" ]; then
        STRING_I="$2"
      else
        STRING_I="$STRING_I $2"
      fi
      shift
      shift
      ;;
    -s)
      SUFFIX="$SUFFIX \"$1\""
      shift
      if [ -n "$UNDER_FLATPAK" ]; then
        echo "Running under flatpak, -s unsupported"
        exit 1
      fi
      SUDO=sudo
      # no-new-privs is needed to bypass suid/sgid bits
      SUDOOPTS="-E --preserve-env=HOME,USER setpriv --no-new-privs"
      # sudo doesn't set SUDO_HOME but maybe it will - use another var
      export DOSEMU_SUDO_HOME="$HOME"
      export DOSEMU_SUDO_TTY=`tty`
      ;;
    -no-priv-sep)
      shift
      if [ -n "$UNDER_FLATPAK" ]; then
        echo "Running under flatpak, priv separation unsupported"
        exit 1
      fi
      SUDO=setpriv
      # no-new-privs is needed to bypass suid/sgid bits
      SUDOOPTS="--no-new-privs"
      OPTS="$OPTS -p"
      ;;
    -l)
      shift
      SUDO=setpriv
      SUDOOPTS="--no-new-privs"
      OPTS="$OPTS -l $1"
      shift
      ;;
    -g)
      shift
      SUDO=setpriv
      SUDOOPTS="--no-new-privs"
      OPTS="$OPTS -g $1"
      shift
      ;;
    -t | -t[a-z] | -t[a-z][a-z] | -t[a-z][a-z][a-z])
      exec 4>&2 2>~/.dosemu/stderr.log.$BASHPID
      SUFFIX="$SUFFIX \"$1\""
      shift
      ;;
    -valgrind)
      DBG="valgrind --error-limit=no"
      # track-origins is incompatible with some flags
      if [ -n "$VG_FLAGS" ]; then
        DBG="$DBG $VG_FLAGS"
      else
        DBG="$DBG --track-origins=yes"
      fi
      STRING_I="$STRING_I cpu_vm emulated cpuemu 1 cpu_vm_dpmi emulated"
      shift
      ;;
    -node)
      DBG="node"
      shift
      ;;
    -gdb)
      DBG="gdb --args"
      shift
      ;;
    -perf)
      DBG="perf record --call-graph dwarf --"
      shift
      ;;
    --)
      break
      ;;
    *)
      # this should avoid avoid resulting substitution odds
      SUFFIX="$SUFFIX \"$1\""
      shift
      ;;
  esac
done
SUFFIX="$SUFFIX $*"

[ -z "$DOSEMU_QUIET" ] || OPTS="$OPTS -q"
[ -z "$DOSEMU_LOG_FILE" ] || LOG_FILE="$DOSEMU_LOG_FILE"

[ -n "$LOG_FILE" ] || LOG_FILE=~/.dosemu/boot.log
MAX_LOGS=3

if [ -f "$LOG_FILE" ]; then
  NL="`ls -1 "$LOG_FILE".[0-9] 2> /dev/null | tail -n 1`"
  NL="${NL##*.}"
  if [ -z "$NL" ]; then
    NL="1"
  elif [ "$NL" -ge "$MAX_LOGS" ]; then
    NL="`ls -t -1 "$LOG_FILE".[0-9] 2> /dev/null | tail -n 1`"
    NL="${NL##*.}"
  else
    NL="`expr $NL + 1`"
  fi
  mv -f "$LOG_FILE" "$LOG_FILE.$NL"
fi

get_binary "$0"

if [ "`id -ur`" -eq 0 ]; then
  if [ -z "$SUDO" ]; then
    echo "Running dosemu2 with root privs is recommended with: $(basename $0) -s"
  else
    # we still need to pass -s so just don't use sudo
    unset SUDO
  fi
  if [ -n "$SUDO_USER" -a -z "$SUDO_HOME" ]; then
    export SUDO_HOME=`getent passwd "$SUDO_USER" | cut -d: -f6`
  fi
fi

# for address sanitizer
[ -z "$ASAN_OPTIONS" ] || ASAN_OPTIONS="$ASAN_OPTIONS:"
export ASAN_OPTIONS="${ASAN_OPTIONS}handle_segv=0:abort_on_error=1:detect_leaks=0"
[ -z "$LSAN_OPTIONS" ] || LSAN_OPTIONS="$LSAN_OPTIONS:"
export LSAN_OPTIONS="${LSAN_OPTIONS}report_objects=1:fast_unwind_on_malloc=0:exitcode=0"
[ -z "$TSAN_OPTIONS" ] || TSAN_OPTIONS="$TSAN_OPTIONS:"
export TSAN_OPTIONS="${TSAN_OPTIONS}second_deadlock_stack=1"
[ -z "$UBSAN_OPTIONS" ] || UBSAN_OPTIONS="$UBSAN_OPTIONS:"
export UBSAN_OPTIONS="${UBSAN_OPTIONS}print_stacktrace=1"

# this is needed to show dosemu icon
export SDL_VIDEO_X11_WMCLASS=dosemu

eval "set -- $SUFFIX"
COMMAND="$SUDO $SUDOOPTS $DBG $BINARY -o $LOG_FILE $OPTS"
if [ -n "$STRING_I" ] ; then
  COMMAND="$COMMAND -I '$STRING_I'"
fi

exec 3>&1
# in a non-bash case, $BASHPID won't work and we fail the cleanup - no problem
DPID="$(echo "$BASHPID"; exec 1<&3; exec $COMMAND -L "Command line: `echo $COMMAND $* | tr -s ' '`" "$@")"
EC=$?
exec 3>&-
if [ -f ~/.dosemu/stderr.log.$BASHPID ]; then
  cat ~/.dosemu/stderr.log.$BASHPID >&4
  rm -f ~/.dosemu/stderr.log.$BASHPID
fi
[ -z "$XDG_RUNTIME_DIR" ] || RUNDIR="$XDG_RUNTIME_DIR/dosemu2"
if [ -n "$RUNDIR" -a -d "$RUNDIR" ]; then
  if [ -z "$DBG" ]; then
    STALE="`ls $RUNDIR/*.$DPID 2>/dev/null`"
  else
    STALE="`ls $RUNDIR/dosemu.* 2>/dev/null`"
  fi
  if [ -n "$STALE" ]; then
    echo "removing stale files:"
    echo "$STALE"
    rm -f $STALE
    stty sane
    kbd_mode -a 2>/dev/null
    # disable xterm mouse tracking
    printf "\033[?1006l\033[?1003l\033[?1002l\033[?1000l\033[?9l"
    # disable xterm cursor keys
    printf "\033[?1l"
  fi
fi
exec 4>&-

if [ $EC -gt 128 ]; then
  SIG=`expr $EC - 128`
  echo "Terminated with signal $SIG"
fi

if [ -f "$LOG_FILE" -a -x "/usr/bin/dpkg-query" ]; then
  echo "Package info:" >>$LOG_FILE
  dpkg-query --show --showformat='dosemu2: ${db:Status-Status}\n' dosemu2 >>$LOG_FILE 2>/dev/null
  dpkg-query -W dosemu2 >>$LOG_FILE 2>/dev/null
  dpkg-query --show --showformat='fdpp: ${db:Status-Status}\n' fdpp >>$LOG_FILE 2>/dev/null
  dpkg-query -W fdpp >>$LOG_FILE 2>/dev/null
  dpkg-query --show --showformat='dj64: ${db:Status-Status}\n' dj64 >>$LOG_FILE 2>/dev/null
  dpkg-query -W dj64 >>$LOG_FILE 2>/dev/null
  dpkg-query --show --showformat='comcom64: ${db:Status-Status}\n' comcom64 >>$LOG_FILE 2>/dev/null
  dpkg-query -W comcom64 >>$LOG_FILE 2>/dev/null
fi

exit $EC
