#!/usr/bin/env bash # Grand Prix Legends Linux Install tool # ## Desc: # Creates wine prefix, mounts iso, downloads and runs the GPL, GEM+ # ## Works on: # - Ubuntu # - Maybe Debian/Ubuntu derivatives. try it and let me know # - MacOS # - WSL (partially) # ## Tested on: # - Ubuntu 20.4 # - MacOS Monterrey 12.3.1 # - Windows 10 Wsl Ubuntu 20.4 # ## Requires: # - bash 'on mac may require `brew install bash`' # - wget # - wine # - shasum # - udisksctl # - file # - grep # - [innoextract](https://constexpr.org/innoextract/) # - xdg-open # ## Downloads: # - GrandPrixLegends.iso from archive.org # - gplinstall_beta_1.08.exe from grandprixlegends.info # - GEMPackage_2.5.0.32.exe from gem.grandprixlegends.info # ## Notes: # - on 'wsl' you will need get display working, see [gwsl](https://opticos.github.io/gwsl/) # - uninstall doesn't uninstall but nukes the wine prefix # Meta VERSION=0.0.1 _filename=$(basename $0) URL="https://github.com/D10221/$_filename" SRC="https://raw.githubusercontent.com/D10221/$_filename/main/$_filename" # # debug # Set debug to glob * to see all , or enable by func name # debug() { local caller="${FUNCNAME[1]}" # caller function name case "$caller" in $DEBUG) echo -e "\e[35m$_filename/$caller: $@\e[0m" >&2 ;; esac } # # error echoes to stderr # error() { echo -e "\e[31m$_filename/${FUNCNAME[1]}: $@\e[0m" >&2; } # # warn # warn() { echo -e "\e[33m$_filename/${FUNCNAME[1]}: $@\e[0m" >&2; } # # info # info() { echo -e "\e[32m$_filename/${FUNCNAME[1]}: $@\e[0m" >&2; } # debug "GPL_HOME=${GPL_HOME:="$HOME/.local/share/GPL"}" # target installation root debug "CACHE=${CACHE:="$HOME/.cache/GPL"}" # where to save the downloads # GPL disc ISO debug "GPL_ISO_URL=${GPL_ISO_URL:="https://archive.org/download/grand-prix-legends/GrandPrixLegends.iso"}" debug "GPL_ISO=${GPL_ISO:=$CACHE/GrandPrixLegends.iso}" debug "GPL_ISO_SHA=${GPL_ISO_SHA:="082542e01a9e63c914a8f34f77ee306531a2aa13 $GPL_ISO"}" debug "GPL_ISO_MNT_POINT=${GPL_ISO_MNT_POINT:="/mnt/$(basename $GPL_ISO)"}" # Global mounting point, to use by 'mount', NOT by 'udisksctl' debug "GPL_ISO_LABEL=${GPL_ISO_LABEL:="GPL"}" # GPL installer debug "GPL_INSTALLER_URL=${GPL_INSTALLER_URL:="http://gem.grandprixlegends.info/gplinstall_beta_1.08.exe"}" debug "GPL_INSTALLER_EXE=${GPL_INSTALLER_EXE:="$CACHE/gplinstall_beta_1.08.exe"}" debug "GPL_INSTALLER_EXE_SHASUM=${GPL_INSTALLER_EXE_SHASUM:="5223d8e8c577ec4504fc8c9491b03c61710af263 $GPL_INSTALLER_EXE"}" # GEM+ Installer debug "GEM_PACKAGE_URL=${GEM_PACKAGE_URL:="http://gem.grandprixlegends.info/GEM/GEMPackage_2.5.0.32.exe"}" debug "GEM_PACKAGE_EXE=${GEM_PACKAGE_EXE:="$CACHE/GEMPackage_2.5.0.32.exe"}" debug "GEM_PACKAGE_EXE_SHA=${GEM_PACKAGE_EXE_SHA:="e8ce456a6db5c2440cb0501accc553730e2ed321 $GEM_PACKAGE_EXE"}" # wine debug "WINE=${WINE:="$(which wine)"}" debug "WINEPREFIX=${WINEPREFIX:="$GPL_HOME/pfx"}" debug "WIN_VERSION=${WIN_VERSION:="win7"}" DRIVE_C="$WINEPREFIX/drive_c" # OSTYPE OS_LINUX='linux' OS_DARWIN='darwin' OS_WSL='wsl' OS='' case "$OSTYPE" in linux*) # linux variants if [ ! -z "$WSL_DISTRO_NAME" ] || [[ $(uname -r) =~ "-microsoft-" ]]; then OS=$OS_WSL else OS=$OS_LINUX fi ;; darwin*) OS=$OS_DARWIN ;; *) echo "OSTYPE $OSTYPE Not Implemented" >&2 exit 1 ;; esac # WSL if [ $OS == $OS_WSL ]; then debug "WSLDRIVE=${WSLDRIVE:="d"}" fi # Globals UNMOUNT=0 # # Download url # creates target directory # args: # $1 'file' local name, full path # $2 'url' # download() { if [ ! -f "$1" ]; then mkdir -p "$(dirname $1)" debug "Downloading $2 as $1" return $(wget $2 -O "$1") fi return 0 } # # Args: # $1 'file' # $2 'shasum sha' # verify() { if [ -z "$2" ]; then return 0 # disabled fi local actual="" if [ ! -z "$(which shasum)" ]; then actual="$(shasum $1)" expected=$2 else error "Can't find shasum to verify $1" return 1 fi if [ "$actual" != "$expected" ]; then debug "Expected $expected" debug "Actual $actual" error "Bad hash: $(basename $1)" return 1 fi return 0 } # # try find backing file used by udisksctl for device # Args: # $1 'label' # Returns: # string or error # udisksctl:info:BackingFile() { local UDISKSCTL_INFO_BACKING_FILE=$(udisksctl info -b "/dev/disk/by-label/$1" | grep BackingFile) local r="\s+BackingFile:\s+(.*)" if [[ "$UDISKSCTL_INFO_BACKING_FILE" =~ $r ]]; then echo "${BASH_REMATCH[1]}" else return 1 fi } # # mount ISO without sudo # Args: # $1 'ISO' # $2 'LABEL' # mount:udisksctl() { if [[ $NOUSERMOUNT -eq 1 ]]; then # debug return 1 # not unmounted fi # get the device backing file local USER_MOUNT_BACKING_FILE="$(udisksctl:info:BackingFile $2)" # already mounted? if [ -f "$USER_MOUNT_BACKING_FILE" ] && [ $USER_MOUNT_BACKING_FILE == $1 ]; then UNMOUNT=0 return 0 elif udisksctl loop-setup -f $1; then UNMOUNT=1 debug "Mounted '$1'" return 0 # mounted else return 1 # failed fi } # # Args: # $1 'Drive Letter' # wsl:drive:valid() { if [ -z "$1" ]; then return 1 # failed fi if ! [[ "$1" =~ ^[a-zA-Z]$ ]]; then error "'$1' is not a valid drive letter, see --help for more" return 1 # failed fi } # # Mounting in WSL is different # Args: # $1 'ISO' # $2 'mount point' # $3 'wsl drive' # mount:mnt:wsl() { if ! wsl:drive:valid $3; then warn "wsl drive '$3' is not valid, using 'd:'" return 1 # failed fi if ! sudo mkdir -p "$2"; then return 1 # failed fi if ! sudo mount -t drvfs "$3:" "$2"; then error "Did you load the ISO on the Windows side?" warn "To stop trying to mount the iso pass the --no-mount switch or set the var NOMOUNT=1" return 1 # failed fi # create simlink in pfx/dosdevices/d: # or wine doesn't see it if ! ln -s "$2" "$WINEPREFIX/dosdevices/$3:"; then warn "failed to link "$2" to "$WINEPREFIX/dosdevices/$3:"" fi debug "mounted '$1'" } # # mount ISO with 'mount' , needs root # Args: # $1 'ISO' # $2 'mount point' # mount:mnt:linux() { # mounting on linux if [ ! -d "$2" ]; then if ! mkdir -p "$2"; then debug "mount point '$2' is not a directory .. trying with sudo" if ! sudo mkdir -p "$2"; then error "failed to create mount point '$2'" return 1 fi fi fi if ! mount -o ro,loop "$1" "$2"; then # try mount debug "trying to mount '$1' with sudo" if ! sudo mount -o ro,loop "$1" "$2"; then # try mount with superuser error "Failed to mount '$1'" return 1 fi #OK debug "mounted $1" fi } # # Args: # $1 ISO # mount:mnt:ismounted() { local r="$(mount | grep $(basename $1))" if [ -z "$r" ]; then return 1 fi } # # try un mount iso if it was mounted # by $OS # Args: # $1 'ISO' # $2 'Label' # $3 'GPL_ISO_MNT_POINT' # $4 'WSLDRIVE' # mount:try() { if [[ $NOMOUNT -eq 1 ]]; then # --nomount? return 0 fi debug "Mounting '$(basename $1)'" # by os case $OS in $OS_DARWIN) if hdiutil mount "$1"; then UNMOUNT=1 debug "mounted $1" return 0 fi ;; $OS_LINUX) # try to mount with udisksctl in user space if mount:udisksctl "$1" "$2"; then return 0 fi # mount using mount, may need root if mount:mnt:ismounted "$1"; then # OK: but do not set UNMOUNT return 0 fi mount:mnt:linux "$1" "$3" UNMOUNT=1 # flag unmountMount return $? ;; $OS_WSL) # mount using mount, may need root if mount:mnt:ismounted "$1"; then # OK: but do not unmount debug "already mounted '$1'?" return 0 fi if mount:mnt:wsl "$1" "$3" "$4"; then local ret=$? UNMOUNT=1 return $ret fi ;; *) error "mount '$1' on '$OS' in not implemented" return 1 #failed ;; esac } # # unmount ISO without sudo # Args: # $1 'label' # unmount:udisksctl() { if [[ $NOUSERMOUNT -eq 1 ]]; then return 1 fi if ! udisksctl unmount -b "/dev/disk/by-label/$1"; then return 1 fi debug "unmounted '$1" } # # unmount mount point , needs root # Args: # $1 'GPL_ISO_MNT_POINT' # unmount:mnt() { if ! umount "$1"; then # try , maybe you have rights if ! sudo umount "$1"; then # try with sudo error "'$SUDO umount $1' failed" return 1 # fail fi fi debug "Unmounted $1" } # # Args: # $1 'ISO' # $2 'label' # $3 'GPL_ISO_MNT_POINT' # $4 'WSL drive' # unmount:wsl() { if ! mount:mnt:ismounted "$1"; then return 1 # fi if ! unmount:mnt "$3"; then return 1 fi if [ -e "$WINEPREFIX/dosdevices/$4:" ] && ! rm "$WINEPREFIX/dosdevices/$4:"; then warn "Failed to remove wine drive '$4' from '$WINEPREFIX/dosdevices'" return 1 # failed fi } # # try un unmount iso if it was mounted # by $OS # Args: # $1 'ISO' # $2 'label' # $3 'GPL_ISO_MNT_POINT' # $4 'WSL DRIVE' # unmount:try() { debug "unmounting $(basename "$1")" if [ $OS == $OS_DARWIN ]; then hdiutil unmount /Volumes/$2 # debug "'$OS' '$(basename $GPL_ISO)' unmounted by 'hdiutil'" elif [ $OS == $OS_LINUX ]; then if unmount:udisksctl "$2"; then return 0 fi if ! mount:mnt:ismounted "$1"; then return 1 # fi if unmount:mnt "$3"; then return 0 fi return 1 elif [ $OS == $OS_WSL ]; then if ! unmount:wsl "$1" "$2" "$3" "$4"; then return 1 fi else error "Unmounting $1 on $OS is not implemented" fi } # # Download and verify # Args: # $1 'file' local name, full path # $2 'url' # $3 'sha' # get() { if ! download $1 $2; then error "failed to download '$(basename $1)' from '$2'" return 1 fi # verify if ! verify $1 "$3"; then error "failed to verify '$(basename $1)'" return 1 fi } # # $1: GPLSecrets/sys | GPLSecrets/syswow64 # source # $2: windows/system | windows/syswow64 # target # install:dll() { for f in $(ls $1/*); do if [ -f "$f" ] && [[ ${f,,} =~ \.dll$ ]] || [[ ${f,,} =~ \.ocx$ ]]; then local target="$DRIVE_C"/$2/"$(basename $f)" if ! cp "$f" "$DRIVE_C"/$2; then error "Failed to copy $f to '$DRIVE_C/$2'" else local dll="$(WINEPREFIX=$WINEPREFIX PATH=$PATH winepath -w $target)" if ! WINEPREFIX=$WINEPREFIX PATH=$PATH wine regsvr32.exe "$dll"; then warn "failed to register $dll" fi fi fi done } # # Unpacks GEM+ into drive c: # prefix breaks when installing GEM+ with the installer # unpack:gem() { debug "Unpacking GEM+ into drive c:" if get "$GEM_PACKAGE_EXE" "$GEM_PACKAGE_URL" "$GEM_PACKAGE_EXE_SHA"; then # get GEM+ installer download if not in cache if [ ! -d "$DRIVE_C" ]; then # crete prefix if not exists if ! create:pfx; then debug "Failed to create prefix: $WINEPREFIX" return 1 fi fi if [ -z "$(which innoextract)" ]; then error "Can't find 'innoextract', install innoextract and try again" return 1 fi local GPLSecrets="$DRIVE_C/GPLSecrets" if ! innoextract "$GEM_PACKAGE_EXE" -d "$GPLSecrets" -s; then error "failed to extract '$GEM_PACKAGE_EXE'" return 1 fi info "Extracted '$GEM_PACKAGE_EXE' into '$GPLSecrets'" install:dll "$GPLSecrets/sys" 'windows/system' install:dll "$GPLSecrets/syswow64" 'windows/syswow64' fi } # # Installs GEM+ # Args: # none # Options: # -i Use/run the installer # -u Unpack the installer # -h show usage # install:gem() { # show usage show:install:gem:usage() { echo "Installs GEM+" echo "$_filename install gem [options] [args]" echo "Options: " echo " -i Runs GEM+ installer" echo " -u Unpacks GEM+ installer into c:\GPLSecrets , find GEM+ in c:\GPLSecrets\app" echo " -h Shows this" } while getopts ":iuh" arg; do case ${arg} in i) debug "Running GEM+ installer" # get GEM installer download if not in cache if get "$GEM_PACKAGE_EXE" "$GEM_PACKAGE_URL" "$GEM_PACKAGE_EXE_SHA"; then debug "Runnig GEM+ installer" if run:exe "$GEM_PACKAGE_EXE"; then GEM_INSTALLED=1 debug "installed GEM+?" else return 1 debug "failed to install GEM+" fi fi ;; u) if ! unpack:gem; then debug "failed to unpack GEM+" return 1 fi ;; h) show:install:gem:usage ;; *) error "Unknown option '$OPTARG'" return 1 ;; esac done if [[ $# -lt 1 ]]; then if ! unpack:gem; then debug "failed to unpack GEM+" return 1 fi fi } # # install GPL # install:gpl() { # get GPL ISO installer, download if not in cache if ! get "$GPL_ISO" "$GPL_ISO_URL" "$GPL_ISO_SHA"; then return 1 fi # get GPL installer, download if not in cache if ! get "$GPL_INSTALLER_EXE" "$GPL_INSTALLER_URL" "$GPL_INSTALLER_EXE_SHASUM"; then return 1 fi # try mount ISO, required by GPL installer if ! mount:try "$GPL_ISO" "$GPL_ISO_LABEL" "$GPL_ISO_MNT_POINT" "$WSLDRIVE"; then # Failed msg="'$OS': Unable to mount '$(basename $1)'\n" msg+=" You will need to mount '$1'\n" msg+=" Or load the Disc your self.\n" msg+=" Relaunch with '--nomount' to skip mounting '$1'" error "$msg" return 1 fi # GPL installer needs the CD debug "Running GPL installer" if run:exe "$GPL_INSTALLER_EXE"; then GPL_INSTALLED=1 debug "installed GPL" else error "Failed to install GPL" fi # try unmount:mnt ISO if [[ $UNMOUNT -eq 1 ]]; then if ! unmount:try "$GPL_ISO" "$GPL_ISO_LABEL" "$GPL_ISO_MNT_POINT" "$WSLDRIVE"; then error "Failed to unmount "$GPL_ISO_LABEL" "$GPL_ISO"" fi fi } # # Usage: # install:selected [options] [...selection] # Opts: # -h 'shows usage'' # Example # 'install # gpl' # 'install gpl gem' # install:selected() { install:selected:h() { echo "Usage: " echo " 'install [options] [targets]'" echo "Options:" echo " -h shows this" echo "Targets:" echo " gpl gem" echo "Example:" echo " '$_filename install gpl gem vbr'" } while getopts ":h" arg; do case ${arg} in h) h ;; *) error "Unknown option '$OPTARG'" return 1 ;; esac done if [[ $# -lt 1 ]]; then # if no arguments start default install:gpl $@ debug "install:gpl completed with status $?" install:gem $@ debug `install:gem completed with status $?` else for a in $@; do case "$a" in -*) ;; # skip options gpl) shift install:gpl $@ ;; gem) shift install:gem $@ ;; *) error "Don't know how to install '$a'" exit 1 ;; esac done fi } # # # create:pfx() { if ! run:on:prefix wine winecfg -v "$WIN_VERSION"; then return 1 else debug "Created prefix as '$WIN_VERSION'" fi } # # Run exe on WINEPREFIX, log to ~/.log # Args: # $1 file # run:exe() { if [ ! -f "$WINE" ]; then error "can't find wine, get wine on the \$PATH and try again" return 1 fi if ! mkdir -p "$WINEPREFIX" || ! WINEPREFIX="$WINEPREFIX" $WINE "$1" >~/"$(basename "$1").log" 2>&1; then return 1 fi } # # Run cmd on WINEPREFIX # run:on:prefix() { if [ ! -f "$WINE" ]; then error "can't find wine, get wine on the \$PATH and try again" return 1 fi if ! mkdir -p "$WINEPREFIX" || ! WINEPREFIX="$WINEPREFIX" $@; then error "Failed to run '$@' on WINEPREFIX="$WINEPREFIX"" return 1 fi } # # Args: # $1 'label' # $2 'target' # $3 'YES'==1 # remove() { if [ ! -d "$2" ]; then error "$2 is not a directory" return 1 fi warn "Removing '$1' '$2' YES=$3" if [[ $3 -ne 1 ]]; then read -p "Cannot be undone (y/n)? " a else a="y" fi case $a in y) rm -rf "$2" return $? ;; n) info "Cancelled." ;; *) error "Unknown option '$u', Cancelled!" return 1 ;; esac } # # Uninstall removes cache, prefix, gpl or GEM+ # Args: # '$@' gpl gem pfx # uninstall:selected() { uninstall:selected:h() { echo "$_filename uninstall [options] [selection]" echo "Removes cache, prefix, gpl or GEM+" echo "Options:" echo " -h 'shows this" echo " -y 'answer yes" echo "selection:" echo " cache, pfx, gpl , gem" } local YES=0 while getopts ":hy" arg; do case $arg in h) uninstall:selected:h return 0 ;; y) YES=1 ;; *) error "Unkown option '$arg'" uninstall:selected:h return 1 ;; esac done if [[ $# -lt 1 ]]; then error "expected args" uninstall:selected:h return 1 else for a in $@; do case "$a" in -*) # skip options ;; gpl) local GPL_EXE="$WINEPREFIX/drive_c/Sierra/GPL/gpl.exe" local DIR=$(dirname $GPL_EXE) remove 'GPL' "$DIR" $YES ;; gem) local GEM_EXE="$WINEPREFIX/drive_c/GPLSecrets/GEM+/GEMP2.exe" local DIR=$(dirname $GEM_EXE) remove 'GEM+' "$DIR" $YES ;; pfx) remove 'prefix' "$WINEPREFIX" $YES ;; prefix) remove 'prefix' "$WINEPREFIX" $YES ;; cache) remove 'cache' "$CACHE" $YES ;; *) error "Can't remove '$a'" uninstall:selected:h return 1 ;; esac done fi } # # wineprefix sub path # Args: # $1 'sub path' # unix or windows # windows path must be absolute # can be empty # returns: wineprefix/sub | or unix path of windows path # pfx:path() { if [ ! -z "$1" ]; then if [[ "$1" =~ ^[a-zA-Z]: ]]; then # debug "is wine path" local p="$(WINEPREFIX=$WINEPREFIX winepath "$1")" else # debug "Not wine path $1" local p="$WINEPREFIX/$1" if [ ! -e "$p" ]; then error "Can't find '$p'" exit 1 fi fi fi if [ ! -z "$1" ]; then echo $p else echo $WINEPREFIX fi } # # open $WINEPREFIX/$1 in terminal # Args: # $1 'path' # open:terminal() { if ! p="$(pfx:path $1)"; then return 1 fi debug "opening '$p'" case $OS in $OS_DARWIN) open -a Terminal "$p" return 1 ;; $OS_WSL) if cd "$p"; then x-terminal-emulator & else return 1 fi ;; $OS_LINUX) if cd "$p"; then x-terminal-emulator & else return 1 fi ;; *) error "'$OS' '${FUNCNAME[0]}' Not implemented" return 1 ;; esac } open:x() { p="$(pfx:path $1)" debug "opening '$p'" case $OS in $OS_DARWIN) open $p return 1 ;; $OS_LINUX) if [ -z "$(which xdg-open)" ]; then error "Can't find xdg-open" exit 1 fi if cd "$p"; then xdg-open "$p" & else return 1 fi ;; $OS_WSL) if [ -z "$(which xdg-open)" ]; then error "Can't find xdg-open" exit 1 fi if cd "$p"; then xdg-open "$p" & else return 1 fi ;; esac } # # open WINEPREFIX/? # Args: # $1? path # Options: # -h # -x open in terminal # open:pfx() { while getopts ':xth' arg; do case "$arg" in h) echo "$_filename open [options] [path]" echo " options:" echo " -h 'shows this'" echo " -t 'open with default terminal'" echo " -x 'open with default file manager'" return 0 ;; t) shift echo "$@" open:terminal "$@" return $? ;; x) shift open:x "$@" return $? ;; *) error "Unknown option '$arg'" return 1 ;; esac done open:x "$@" } # # # start:exe() { debug "finding $1" local f=$(find $DRIVE_C -name "$1".exe) if [ -f "$f" ]; then local p="$(WINEPREFIX=$WINEPREFIX winepath -w "$f")" echo "winepath=$p" run:on:prefix "$WINE" start "$p" /d "c:\Sierra\GPL" # start always on gpl.exe's path ? return 0 fi return 1 } # # # start:app() { local x="${1,,}" if [[ $x =~ ^gem(\+)?$ ]]; then # match "Gem gem GEM gem+ GEM+ etc" start:exe "GEMP2" elif [[ $x =~ ^gpl[a-z]?[0-9]+?$ ]]; then # match gplc67, gpl gpl18 start:exe $x else error "Don't how to open '$1'" return 1 fi } # # show usage # usage() { echo "Grand Prix Legends wine Installer v$VERSION" echo "Usage: '$_filename [verb] [options]'" echo "Verbs: " echo " install [options?] [target]? 'run GPL installers'" echo " options:" echo " -h help" echo " target:" echo " gpl gem vbr" echo " example:" echo " \$gpli install -r gpl # REINSTALL gpl" echo " \$gpli install -r gpl gem vbr # reinstall gpl gem -u vbr" echo " Notes: gem target has options see install gem -h for details" echo " uninstall [options?] 'remove cache,GPL,GEM and wine Prefix'" echo " options: " echo " 'gpl' remove 'c:\Sierra\gpl'" echo " 'geml' remove 'c:\Sierra\gpl'" echo " 'pfx' remove 'prefix' (default)" echo " run [cmd]" echo " \"run something on gpl's WINEPREFIX\"" echo " examples:" echo " '\$$_filename run wine winecfg'" echo " wine [cmd]" echo " \"run wine 'something' on gpl's WINEPREFIX\"" echo " examples:" echo " '\$$_filename wine winecfg'" echo " open [options] [path]" echo " opens \$WINEPREFIX location or sub location with default file manager or terminal" echo " options:" echo " -x with default filemanager" echo " -t with default terminal" echo " -h shows this" echo " examples:" echo " '\$$_filename open' # opens \$WINEPREFIX" echo " '\$$_filename open dirve_c ' # opens \$WINEPREFIX/drive_c" echo " '\$$_filename open 'c:\Sierra' ' # opens \$WINEPREFIX/drive_c/Sierra" echo " start [what]" echo " starts GPL or GEM+" echo " examples:" echo " '\$$_filename start gpl' # starts wine 'c:\Sierra\GPL\gpl.exe'" echo " '\$$_filename start gem+' # starts wine 'c:\GPLSecrets\GEM+\GEMP2.exe'" echo "" echo "Options:" echo " -h --help 'Show this'" echo " -v --version 'Show '$_filename' version'" echo " --nomount 'Do not try to mount ISO'" if [ $OS == $OS_WSL ]; then echo " --wsldrive=''" echo " desc: 'drive letter to mount in wsl environment'" echo " 'required on WSL'" echo " : [az-AZ]" echo " example '--wsldrive=d'" fi echo "" echo "Vars:" echo " NOMOUNT 'Do not try to mount ISO'" echo " NOUSERMOUNT 'Do not try to mount ISO in userspace'" echo " NOROOTMOUNT 'Do not try to mount ISO if requires root access" echo " DEBUG 'show debug info'" echo " example '\$ DEBUG='*' ./gpli.local install'" if [ $OS == $OS_WSL ]; then echo " WSLDRIVE 'show debug info'" echo " desc: 'drive letter to mount in wsl environment'" echo " 'required to install GPL on WSL'" echo " : [az-AZ]" echo " example '\$ WSLDRIVE=d ./gpli.local install'" fi } # if [[ $# -lt 1 ]]; then usage exit 1 fi # # Args: # $1 'option' ex, 'x=1' # Returns: # $2 'value' # option:value() { local r="\w+=(.*)" if [[ "$1" =~ $r ]]; then echo "${BASH_REMATCH[1]}" else return 1 fi } # # Exec Opts # option() { case $1 in help) OPTKEY='h' usage exit ;; version) OPTKEY='v' echo "v$VERSION" exit ;; nomount) NOMOUNT=1 ;; wsldrive) WSLDRIVE="$2" if ! wsl:drive:valid $WSLDRIVE; then exit 1 fi ;; *) error "Invalid option '$1'" exit 1 ;; esac } # parse opts while getopts ":hvu-:" o; do case "${o}" in -) case "${OPTARG}" in help) option 'help' ;; version) option 'version' ;; nomount) shift option 'nomount' ;; wsldrive=*) shift option 'wsldrive' "$(option:value $OPTARG)" ;; *) error "Unknown option --${OPTARG}" exit 1 ;; esac ;; h) option "help" ;; v) option "version" ;; ?) if [ "$OPTERR" != 1 ] || [ "${OPTSPEC:0:1}" = ":" ]; then error "bad optiont: '-${OPTARG}'" fi error "Unknown option -${OPTARG}" exit 1 ;; esac done # verbs case $1 in install) shift if install:selected "$@"; then debug "done" else error "done with error" fi ;; uninstall) shift uninstall:selected "$@" ;; run) shift run:on:prefix $@ ;; wine) shift run:on:prefix "$WINE" $@ ;; open) shift open:pfx $@ ;; start) shift start:app "$1" ;; unmount) #undocumented debug "unmount $GPL_ISO" unmount:try "$GPL_ISO" "$GPL_ISO_LABEL" "$GPL_ISO_MNT_POINT" "$WSLDRIVE" ret=$([[ "$?" -gt 0 ]] && echo "NO" || echo "YES") echo "unmounted: $ret" ;; mount) #undocumented debug "mount $GPL_ISO" if mount:try "$GPL_ISO" "$GPL_ISO_LABEL" "$GPL_ISO_MNT_POINT" "$WSLDRIVE" && [[ $UNMOUNT -eq 1 ]]; then info mounted else info NOT mounted fi ;; *) error "Unkown verb:'$1'" exit 1 ;; esac