From e9a37eecc9bfaa86dae7fc3892937d3b16028d22 Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Fri, 28 Apr 2023 16:37:12 -0400 Subject: [PATCH 01/11] Fix #169. --- LogosLinuxInstaller.sh | 148 ++++++++++++++++++++++++++++++++--------- 1 file changed, 118 insertions(+), 30 deletions(-) diff --git a/LogosLinuxInstaller.sh b/LogosLinuxInstaller.sh index b399b0d..ada9573 100755 --- a/LogosLinuxInstaller.sh +++ b/LogosLinuxInstaller.sh @@ -513,45 +513,132 @@ make_skel() { } ## BEGIN CHECK DEPENDENCIES FUNCTIONS +getOS() { + if [ -f /etc/os-release ]; then + # freedesktop.org and systemd + source /etc/os-release + OS="${ID}" + OS_RELEASE="${VERSION_ID}" + elif type lsb_release >/dev/null 2>&1; then + # linuxbase.org + OS="$(lsb_release -si)" + OS_RELEASE="$(lsb_release -sr)" + elif [ -f /etc/lsb-release ]; then + # For some versions of Debian/Ubuntu without lsb_release command + source /etc/lsb-release + OS="${DISTRIB_ID}" + OS_RELEASE="${DISTRIB_RELEASE}" + elif [ -f /etc/debian_version ]; then + OS=Debian + OS_RELEASE="$(cat /etc/debian_version)" + elif [ -f /etc/SuSe-release ]; then + : + elif [ -f /etc/redhat-release ]; then + : + else + OS="$(uname -s)" + OS_RELEASE="$(uname -r)" + fi +} + +getPackageManager() { + if [ -x "$(command -v sudo)" ]; then + SUPERUSERDO="sudo" + elif [ -x "$(command -v doas)" ]; then + SUPERUSERDO="doas" + else + : + fi + + if [ -x "$(command -v apt)" ]; then + PACKAGE_MANAGER="apt install" + PACKAGES="mktemp patch lsof wget find sed grep gawk tr winbind cabextract x11-apps bc libxml2-utils curl" + LIBRARYPACKAGES="fuse3" + elif [ -x "$(command -v dnf)" ]; then + PACKAGE_MANAGER="dnf install" + PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" + elif [ -x "$(command -v yum)" ]; then + PACKAGE_MANAGER="yum install" + PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" + elif [ -x "$(command -v pamac)" ]; then + PACKAGE_MANAGER="pamac install --no-upgrade" + PACKAGES="patch lsof wget sed grep gawk cabextract samba bc libxml2 curl" + elif [ -x "$(command -v pacman)" ]; then + PACKAGE_MANAGER="pacman -S" + PACKAGES="patch lsof wget sed grep gawk cabextract samba bc libxml2 curl" + elif [ -x "$(command -v apk)" ]; then + # PACKAGE_MANAGER="apk add" + # PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" + : + elif [ -x "$(command -v zypper)" ]; then + # PACKAGE_MANAGER="zypper install" + # PACKAGES="" + : + elif [ -x "$(command -v pkg)" ]; then + # PACKAGE_MANAGER="pkg install" + # PACKAGES="" + : + else + verbose && echo "Your distribution's package manager could not be determined." + fi + if [ -n "${SUPERUSERDO}" ]; then export SUPERUSERDO; fi + if [ -n "${PACKAGE_MANAGER}" ]; then export PACKAGE_MANAGER; fi + if [ -n "${PACKAGES}" ]; then export PACKAGES; fi + if [ -n "${LIBRARYPACKAGES}" ]; then export LIBRARYPACKAGES; fi +} + +installPackages() { + "${SUPERUSERDO}" "${PACKAGE_MANAGER}" "$@" +} + check_commands() { - for cmd in "$@"; do - if have_dep "${cmd}"; then - verbose && echo "* command ${cmd} is installed!" - else + if [ -z "${SUPERUSERDO}" ]; then logos_error "Your distribution appears to be missing the ability to escalate privileges (e.g., sudo, doas). Please install either sudo or doas."; fi + for cmd in "$@"; do + if have_dep "${cmd}"; then + verbose && echo "* command ${cmd} is installed!" + else verbose && echo "* command ${cmd} not installed!" MISSING_CMD+=("${cmd}") - fi - done + fi + done if [ "${#MISSING_CMD[@]}" -ne 0 ]; then - logos_error "Your system is missing ${MISSING_CMD[*]}. Please install your distro's ${MISSING_CMD[*]} package(s).\n ${EXTRA_INFO}" + if [ -n "${PACKAGE_MANGER}" ]; then + logos_continue_question "Your ${OS} install is missing the command(s): ${MISSING_CMD[*]}. To continue, the script will attempt to install the package(s): ${PACKAGES} by using (${PACKAGE_MANAGER}). Proceed?" "Your system is missing the command(s) ${MISSING_CMD[*]}. Please install your distro's package(s) associated with ${MISSING_CMD[*]} for ${OS}.\n ${EXTRA_INFO}" + installPackages ${PACKAGES} + else + logos_error "The script could not determine your ${OS} install's package manager or it is unsupported. Your computer is missing the command(s) ${MISSING_CMD[*]}. Please install your distro's package(s) associated with ${MISSING_CMD[*]} for ${OS}.\n${EXTRA_INFO}" + fi fi } # shellcheck disable=SC2001 check_libs() { - for lib in "$@"; do - HAVE_LIB="$(ldconfig -N -v "$(sed 's/:/ /g' <<< "${LD_LIBRARY_PATH}")" 2>/dev/null | grep "${lib}")" - if [ -n "${HAVE_LIB}" ]; then - verbose && echo "* ${lib} is installed!" - else - logos_error "Your system does not have lib: ${lib}. Please install ${lib} package.\n ${EXTRA_INFO}" - fi - done + if [ -z "${SUPERUSERDO}" ]; then logos_error "Your distribution appears to be missing the ability to escalate privileges (e.g., sudo, doas). Please install either sudo or doas."; fi + for lib in "$@"; do + HAVE_LIB="$(ldconfig -N -v "$(sed 's/:/ /g' <<< "${LD_LIBRARY_PATH}")" 2>/dev/null | grep "${lib}")" + if [ -n "${HAVE_LIB}" ]; then + verbose && echo "* ${lib} is installed!" + else + if [ -n "${PACKAGE_MANGER}" ]; then + logos_continue_question "Your ${OS} install is missing the library: ${lib}. To continue, the script will attempt to install the library by using ${PACKAGE_MANAGER}. Proceed?" "Your system does not have lib: ${lib}. Please install the package associated with ${lib} for ${OS}.\n ${EXTRA_INFO}" + installPackages ${LIBRARYPACKAGES} + else + logos_error "The script could not determine your ${OS} install's package manager or it is unsupported. Your computer is missing the library: ${lib}. Please install the package associated with ${lib} for ${OS}.\n ${EXTRA_INFO}" + fi + fi + done } checkDependencies() { - verbose && echo "Checking system's for dependencies:" - check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl; -} - -checkDependenciesLogos10() { + verbose && echo "Checking system for dependencies…" + if [ "TARGETVERSION" = "10" ]; then + check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl; + elif [ "TARGETVERSION" = "9" ]; then + check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl xwd cabextract; + else logos_error "Unknown Logos version." + fi verbose && echo "All dependencies found. Continuing…" } -checkDependenciesLogos9() { - verbose && echo "Checking dependencies for Logos 9." - check_commands xwd cabextract; - verbose && echo "All dependencies found. Continuing…" -} ## END CHECK DEPENDENCIES FUNCTIONS ## BEGIN INSTALL OPTIONS FUNCTIONS @@ -614,11 +701,9 @@ chooseVersion() { fi case "${versionChoice}" in *"10") - checkDependenciesLogos10; export TARGETVERSION="10"; ;; *"9") - checkDependenciesLogos9; export TARGETVERSION="9"; ;; "Exit.") @@ -627,7 +712,9 @@ chooseVersion() { *) logos_error "Unknown version. Installation canceled!" esac +} +logosSetup() { LOGOS_RELEASE_VERSION=$(curl -s "https://clientservices.logos.com/update/v1/feed/logos${TARGETVERSION}/stable.xml" | xmllint --format - | sed -e 's/ xmlns.*=".*"//g' | sed -e 's@logos:minimum-os-version@minimum-os-version@g' | sed -e 's@logos:version@version@g' | xmllint --xpath "/feed/entry[1]/version/text()" -); export LOGOS_RELEASE_VERSION; if [ -z "${LOGOS64_URL}" ]; then export LOGOS64_URL="https://downloads.logoscdn.com/LBS${TARGETVERSION}/${VERBUM_PATH}Installer/${LOGOS_RELEASE_VERSION}/${FLPRODUCT}-x64.msi" ; fi @@ -728,7 +815,6 @@ getAppImage() { } chooseInstallMethod() { - if [ -z "$WINEPREFIX" ]; then export WINEPREFIX="${APPDIR}/wine64_bottle" fi @@ -791,7 +877,6 @@ chooseInstallMethod() { fi done < "${WORKDIR}/winebinaries" - BACKTITLE="Choose Wine Binary Menu" TITLE="Choose Wine Binary" QUESTION_TEXT="Which Wine binary and install method should the script use to install ${FLPRODUCT} v${LOGOS_VERSION} in ${INSTALLDIR}?" @@ -1243,9 +1328,12 @@ postInstall() { main() { { echo "$LOGOS_SCRIPT_TITLE, $LOGOS_SCRIPT_VERSION by $LOGOS_SCRIPT_AUTHOR."; # BEGIN PREPARATION - verbose && date; checkDependencies; # We verify the user is running a graphical UI and has majority of required dependencies. + verbose && date; getOS; + verbose && date; getPackageManager; verbose && date; chooseProduct; # We ask user for his Faithlife product's name and set variables. verbose && date; chooseVersion; # We ask user for his Faithlife product's version, set variables, and create project skeleton. + verbose && date; checkDependencies; # We check for most of the required dependencies by product version. + verbose && date; logosSetup; # We set some basic variables for the install, including retrieving the product's latest release. verbose && date; chooseInstallMethod; # We ask user for his desired install method. # END PREPARATION if [ -z "${REGENERATE}" ]; then From 585a126d1f39b49b8e177764d699c7cee21b1bfb Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 16:32:55 -0500 Subject: [PATCH 02/11] Fix #210. --- LogosLinuxInstaller.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/LogosLinuxInstaller.sh b/LogosLinuxInstaller.sh index ada9573..bb6e209 100755 --- a/LogosLinuxInstaller.sh +++ b/LogosLinuxInstaller.sh @@ -630,9 +630,9 @@ check_libs() { checkDependencies() { verbose && echo "Checking system for dependencies…" - if [ "TARGETVERSION" = "10" ]; then + if [ "${TARGETVERSION}" = "10" ]; then check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl; - elif [ "TARGETVERSION" = "9" ]; then + elif [ "${TARGETVERSION}" = "9" ]; then check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl xwd cabextract; else logos_error "Unknown Logos version." fi @@ -688,7 +688,7 @@ chooseVersion() { QUESTION_TEXT="Which version of ${FLPRODUCT} should the script install?" if [ -z "$TARGETVERSION" ]; then if [[ "${DIALOG}" == "whiptail" ]] || [[ "${DIALOG}" == "dialog" ]]; then - versionChoice="$($DIALOG --backtitle "${BACKTITLE}" --title "${TITLE}" --radiolist "${QUESTION_TEXT}" 0 0 0 "${FLPRODUCT} 10" "10" ON "${FLPRODUCT} 9" "9" OFF "Exit." "Exit." OFF 3>&1 1>&2 2>&3 3>&-)" + versionChoice="$(${DIALOG} --backtitle "${BACKTITLE}" --title "${TITLE}" --radiolist "${QUESTION_TEXT}" 0 0 0 "${FLPRODUCT} 10" "10" ON "${FLPRODUCT} 9" "9" OFF "Exit." "Exit." OFF 3>&1 1>&2 2>&3 3>&-)" elif [[ "${DIALOG}" == "zenity" ]]; then versionChoice="$(zenity --width="700" --height="310" --title="${TITLE}" --text="${QUESTION_TEXT}" --list --radiolist --column "S" --column "Description" TRUE "${FLPRODUCT} 10" FALSE "${FLPRODUCT} 9" FALSE "Exit")" elif [[ "${DIALOG}" == "kdialog" ]]; then @@ -699,6 +699,7 @@ chooseVersion() { else versionChoice="$TARGETVERSION" fi + echo "versionChoice is $versionChoice." case "${versionChoice}" in *"10") export TARGETVERSION="10"; @@ -785,7 +786,7 @@ checkPath() { createWineBinaryList() { logos_info "Creating binary list." #TODO: Make optarg to add custom path to this array. - WINEBIN_PATH_ARRAY=( "/usr/local/bin" "$HOME/bin" "$HOME/PlayOnLinux/wine/linux-amd64/*/bin" "$HOME/.steam/steam/steamapps/common/Proton - Experimental/files/bin" "${CUSTOMBINPATH}" ) + WINEBIN_PATH_ARRAY=( "/usr/local/bin" "${HOME}/bin" "${HOME}/PlayOnLinux/wine/linux-amd64/*/bin" "${HOME}/.steam/steam/steamapps/common/Proton*/files/bin" "${CUSTOMBINPATH}" ) # Temporarily modify PATH for additional WINE64 binaries. for p in "${WINEBIN_PATH_ARRAY[@]}"; do From bfefb3c05c7a9989e81372d77fa785fc75bd4e94 Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 19:06:31 -0500 Subject: [PATCH 03/11] Partial fix for #211. --- LogosLinuxInstaller.sh | 58 +++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/LogosLinuxInstaller.sh b/LogosLinuxInstaller.sh index bb6e209..11c7b6d 100755 --- a/LogosLinuxInstaller.sh +++ b/LogosLinuxInstaller.sh @@ -11,11 +11,11 @@ export LOGOS_SCRIPT_VERSION="3.7.5" # Script version for this Installer Script ##### # BEGIN ENVIRONMENT -if [ -z "${WINE64_APPIMAGE_FULL_VERSION}" ]; then WINE64_APPIMAGE_FULL_VERSION="v7.18-staging"; export WINE64_APPIMAGE_FULL_VERSION; fi +if [ -z "${WINE64_APPIMAGE_FULL_VERSION}" ]; then WINE64_APPIMAGE_FULL_VERSION="v8.19-devel"; export WINE64_APPIMAGE_FULL_VERSION; fi if [ -z "${WINE64_APPIMAGE_FULL_URL}" ]; then WINE64_APPIMAGE_FULL_URL="https://github.com/ferion11/LogosLinuxInstaller/releases/download/wine-devel-8.19/wine-devel_8.19-x86_64.AppImage"; export WINE64_APPIMAGE_FULL_URL; fi if [ -z "${WINE64_APPIMAGE_FULL_FILENAME}" ]; then WINE64_APPIMAGE_FULL_FILENAME="$(basename "${WINE64_APPIMAGE_FULL_URL}")"; export WINE64_APPIMAGE_FULL_FILENAME; fi -if [ -z "${WINE64_APPIMAGE_VERSION}" ]; then WINE64_APPIMAGE_VERSION="v7.18-staging"; export WINE64_APPIMAGE_VERSION; fi -if [ -z "${WINE64_APPIMAGE_URL}" ]; then WINE64_APPIMAGE_URL="https://github.com/ferion11/LogosLinuxInstaller/releases/download/v10.0-1/wine-staging_7.18-x86_64.AppImage"; export WINE64_APPIMAGE_URL; fi +if [ -z "${WINE64_APPIMAGE_VERSION}" ]; then WINE64_APPIMAGE_VERSION="v8.19-devel"; export WINE64_APPIMAGE_VERSION; fi +if [ -z "${WINE64_APPIMAGE_URL}" ]; then WINE64_APPIMAGE_URL="https://github.com/ferion11/LogosLinuxInstaller/releases/download/wine-devel-8.19/wine-devel_8.19-x86_64.AppImage"; export WINE64_APPIMAGE_URL; fi if [ -z "${WINE64_BOTTLE_TARGZ_URL}" ]; then WINE64_BOTTLE_TARGZ_URL="https://github.com/ferion11/wine64_bottle_dotnet/releases/download/v5.11b/wine64_bottle.tar.gz"; export WINE64_BOTTLE_TARGZ_URL; fi if [ -z "${WINE64_BOTTLE_TARGZ_NAME}" ]; then WINE64_BOTTLE_TARGZ_NAME="wine64_bottle.tar.gz"; export WINE64_BOTTLE_TARGZ_NAME; fi if [ -z "${WINE64_APPIMAGE_FILENAME}" ]; then WINE64_APPIMAGE_FILENAME="$(basename "${WINE64_APPIMAGE_URL}" .AppImage)"; export WINE64_APPIMAGE_FILENAME; fi @@ -25,6 +25,7 @@ if [ -z "${LAUNCHER_TEMPLATE_URL}" ]; then LAUNCHER_TEMPLATE_URL="https://raw.gi if [ -z "${CONTROL_PANEL_TEMPLATE_URL}" ]; then CONTROL_PANEL_TEMPLATE_URL="https://raw.githubusercontent.com/ferion11/LogosLinuxInstaller/master/controlPanel-Template.sh"; export CONTROL_PANEL_TEMPLATE_URL; fi if [ -z "${WINETRICKS_DOWNLOADER+x}" ]; then WINETRICKS_DOWNLOADER="wget" ; export WINETRICKS_DOWNLOADER; fi if [ -z "${WINETRICKS_UNATTENDED+x}" ]; then WINETRICKS_UNATTENDED="" ; export WINETRICKS_UNATTENDED; fi +if [ -z "${MYDOWNLOADS}" ]; then MYDOWNLOADS="${HOME}/Downloads"; export MYDOWNLOADS; fi if [ -z "${WORKDIR}" ]; then WORKDIR="$(mktemp -d /tmp/LBS.XXXXXXXX)"; export WORKDIR ; fi if [ -z "${PRESENT_WORKING_DIRECTORY}" ]; then PRESENT_WORKING_DIRECTORY="${PWD}" ; export PRESENT_WORKING_DIRECTORY; fi if [ -z "${LOGOS_FORCE_ROOT+x}" ]; then export LOGOS_FORCE_ROOT="" ; fi @@ -440,11 +441,10 @@ logos_reuse_download() { SOURCEURL="${1}" FILE="${2}" TARGETDIR="${3}" - DOWNLOADS="${HOME}/Downloads" DIRS=( "${INSTALLDIR}" "${PRESENT_WORKING_DIRECTORY}" - "${DOWNLOADS}" + "${MYDOWNLOADS}" ) FOUND=1 for i in "${DIRS[@]}"; do @@ -457,8 +457,8 @@ logos_reuse_download() { done if [[ "${FOUND}" == 1 ]]; then logos_info "${FILE} does not exist. Downloading…" - logos_download "${SOURCEURL}" "${DOWNLOADS}/${FILE}" - cp "${DOWNLOADS}/${FILE}" "${TARGETDIR}/" | logos_progress "Copying…" "Copying: ${FILE}\ninto: ${TARGETDIR}" + logos_download "${SOURCEURL}" "${MYDOWNLOADS}/${FILE}" + cp "${MYDOWNLOADS}/${FILE}" "${TARGETDIR}/" | logos_progress "Copying…" "Copying: ${FILE}\ninto: ${TARGETDIR}" fi } ## END DIALOG FUNCTIONS @@ -516,6 +516,8 @@ make_skel() { getOS() { if [ -f /etc/os-release ]; then # freedesktop.org and systemd + # The following line is needed for SC1091: + # shellcheck source=/dev/null source /etc/os-release OS="${ID}" OS_RELEASE="${VERSION_ID}" @@ -525,11 +527,15 @@ getOS() { OS_RELEASE="$(lsb_release -sr)" elif [ -f /etc/lsb-release ]; then # For some versions of Debian/Ubuntu without lsb_release command + # The following line is needed for SC1091: + # shellcheck source=/dev/null source /etc/lsb-release OS="${DISTRIB_ID}" + # shellcheck disable=SC2034 OS_RELEASE="${DISTRIB_RELEASE}" elif [ -f /etc/debian_version ]; then OS=Debian + # shellcheck disable=SC2034 OS_RELEASE="$(cat /etc/debian_version)" elif [ -f /etc/SuSe-release ]; then : @@ -537,6 +543,7 @@ getOS() { : else OS="$(uname -s)" + # shellcheck disable=SC2034 OS_RELEASE="$(uname -r)" fi } @@ -604,7 +611,7 @@ check_commands() { if [ "${#MISSING_CMD[@]}" -ne 0 ]; then if [ -n "${PACKAGE_MANGER}" ]; then logos_continue_question "Your ${OS} install is missing the command(s): ${MISSING_CMD[*]}. To continue, the script will attempt to install the package(s): ${PACKAGES} by using (${PACKAGE_MANAGER}). Proceed?" "Your system is missing the command(s) ${MISSING_CMD[*]}. Please install your distro's package(s) associated with ${MISSING_CMD[*]} for ${OS}.\n ${EXTRA_INFO}" - installPackages ${PACKAGES} + installPackages "${PACKAGES}" else logos_error "The script could not determine your ${OS} install's package manager or it is unsupported. Your computer is missing the command(s) ${MISSING_CMD[*]}. Please install your distro's package(s) associated with ${MISSING_CMD[*]} for ${OS}.\n${EXTRA_INFO}" fi @@ -620,7 +627,7 @@ check_libs() { else if [ -n "${PACKAGE_MANGER}" ]; then logos_continue_question "Your ${OS} install is missing the library: ${lib}. To continue, the script will attempt to install the library by using ${PACKAGE_MANAGER}. Proceed?" "Your system does not have lib: ${lib}. Please install the package associated with ${lib} for ${OS}.\n ${EXTRA_INFO}" - installPackages ${LIBRARYPACKAGES} + installPackages "${LIBRARYPACKAGES}" else logos_error "The script could not determine your ${OS} install's package manager or it is unsupported. Your computer is missing the library: ${lib}. Please install the package associated with ${lib} for ${OS}.\n ${EXTRA_INFO}" fi @@ -783,6 +790,18 @@ checkPath() { } +checkAppImages() { + DIR="${1}" + readarray -t APPIMAGESARR < <(find "${DIR}" -iname "wine*x86_64*AppImage") + for appimage in "${APPIMAGESARR[@]}"; do + if [ -x "${appimage}" ]; then + echo "${appimage}" >> "${WORKDIR}/winebinaries" + else + : # Not executable" + fi + done +} + createWineBinaryList() { logos_info "Creating binary list." #TODO: Make optarg to add custom path to this array. @@ -797,6 +816,13 @@ createWineBinaryList() { # Check each directory in PATH for wine64; add to list checkPath wine64 > "${WORKDIR}/winebinaries" + + APPIMAGEDIR="$(grep "destination" "${HOME}/.config/appimagelauncher.cfg" | awk -F'=' '{print $2}' | sed "s/^\s//")" + APPIMAGEDIR="${APPIMAGEDIR/#\~/$HOME}" + export APPIMAGEDIR + + checkAppImages "${APPIMAGEDIR}" + checkAppImages "${MYDOWNLOADS}" cp "${WORKDIR}/winebinaries" "${WORKDIR}/winebinaries.bak" @@ -847,18 +873,26 @@ chooseInstallMethod() { WINEOPT="$line" fi - if [[ "$WINEOPT" == *"/usr/bin/"* ]]; then + if [[ "${WINEOPT}" == *"/usr/bin/"* ]]; then WINEOPT_CODE="System" WINEOPT_DESCRIPTION="\"Use the system binary (i.e., /usr/bin/wine64). WINE must be 7.18-staging or later. Stable or Devel do not work.\"" WINEOPT_PATH="${line}" - elif [[ "$WINEOPT" == *"Proton"* ]]; then + elif [[ "${WINEOPT}" == *"Proton"* ]]; then WINEOPT_CODE="Proton" WINEOPT_DESCRIPTION="\"Install using the Steam Proton fork of WINE.\"" WINEOPT_PATH="${line}" - elif [[ "$WINEOPT" == *"PlayOnLinux"* ]]; then + elif [[ "${WINEOPT}" == *"PlayOnLinux"* ]]; then WINEOPT_CODE="PlayOnLinux" WINEOPT_DESCRIPTION="\"Install using a PlayOnLinux WINE64 binary.\"" WINEOPT_PATH="${line}" + elif [[ "${WINEOPT}" == *"Downloads"* ]]; then + WINEOPT_CODE="AppImage" + WINEOPT_DESCRIPTION="\"Install using a non-default AppImage.\"" + WINEOPT_PATH="${line}" + elif [[ "${WINEOPT}" == *"${APPIMAGEDIR}"* ]]; then + WINEOPT_CODE="AppImage" + WINEOPT_DESCRIPTION="\"Install using an integrated non-default AppImage.\"" + WINEOPT_PATH="${line}" else WINEOPT_CODE="Custom" WINEOPT_DESCRIPTION="\"Use a WINE64 binary from another directory.\"" From cfb7dbd5b78a038b657e1fd2faf7a4dca75a1361 Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 19:34:21 -0500 Subject: [PATCH 04/11] SteamOS support --- LogosLinuxInstaller.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/LogosLinuxInstaller.sh b/LogosLinuxInstaller.sh index 11c7b6d..8777a37 100755 --- a/LogosLinuxInstaller.sh +++ b/LogosLinuxInstaller.sh @@ -571,8 +571,8 @@ getPackageManager() { PACKAGE_MANAGER="pamac install --no-upgrade" PACKAGES="patch lsof wget sed grep gawk cabextract samba bc libxml2 curl" elif [ -x "$(command -v pacman)" ]; then - PACKAGE_MANAGER="pacman -S" - PACKAGES="patch lsof wget sed grep gawk cabextract samba bc libxml2 curl" + PACKAGE_MANAGER='pacman -Syu --overwrite \* --noconfirm --needed' + PACKAGES="patch lsof wget sed grep gawk cabextract samba bc libxml2 curl print-manager system-config-printer cups-filters nss-mdns foomatic-db-engine foomatic-db-ppds foomatic-db-nonfree-ppds ghostscript glibc samba extra-rel/apparmor core-rel/libcurl-gnutls winetricks cabextract appmenu-gtk-module patch bc lib32-libjpeg-turbo qt5-virtualkeyboard wine-staging giflib lib32-giflib libpng lib32-libpng libldap lib32-libldap gnutls lib32-gnutls mpg123 lib32-mpg123 openal lib32-openal v4l-utils lib32-v4l-utils libpulse lib32-libpulse libgpg-error lib32-libgpg-error alsa-plugins lib32-alsa-plugins alsa-lib lib32-alsa-lib libjpeg-turbo lib32-libjpeg-turbo sqlite lib32-sqlite libxcomposite lib32-libxcomposite libxinerama lib32-libgcrypt libgcrypt lib32-libxinerama ncurses lib32-ncurses ocl-icd lib32-ocl-icd libxslt lib32-libxslt libva lib32-libva gtk3 lib32-gtk3 gst-plugins-base-libs lib32-gst-plugins-base-libs vulkan-icd-loader lib32-vulkan-icd-loader" elif [ -x "$(command -v apk)" ]; then # PACKAGE_MANAGER="apk add" # PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" @@ -611,7 +611,19 @@ check_commands() { if [ "${#MISSING_CMD[@]}" -ne 0 ]; then if [ -n "${PACKAGE_MANGER}" ]; then logos_continue_question "Your ${OS} install is missing the command(s): ${MISSING_CMD[*]}. To continue, the script will attempt to install the package(s): ${PACKAGES} by using (${PACKAGE_MANAGER}). Proceed?" "Your system is missing the command(s) ${MISSING_CMD[*]}. Please install your distro's package(s) associated with ${MISSING_CMD[*]} for ${OS}.\n ${EXTRA_INFO}" + if [ "${OS}" = "Steam" ]; then + "${SUPERUSERDO}" steamos-readonly disable + "${SUPERUSERDO}" pacman-key --init + "${SUPERUSERDO}" pacman-key --populate archlinux + fi installPackages "${PACKAGES}" + if [ "$OS" = "Steam" ]; then + "${SUPERUSERDO}" sed -i 's/mymachines resolve/mymachines mdns_minimal [NOTFOUND=return] resolve/' /etc/nsswitch.conf + "${SUPERUSERDO}" locale-gen + "${SUPERUSERDO}" systemctl enable --now avahi-daemon + "${SUPERUSERDO}" systemctl enable --now cups + "${SUPERUSERDO}" steamos-readonly enable + fi else logos_error "The script could not determine your ${OS} install's package manager or it is unsupported. Your computer is missing the command(s) ${MISSING_CMD[*]}. Please install your distro's package(s) associated with ${MISSING_CMD[*]} for ${OS}.\n${EXTRA_INFO}" fi From 0ee9c2fc98e55f917bd3214bab838fea5ef33db6 Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 20:30:48 -0500 Subject: [PATCH 05/11] Add "yes" flags. Remove LIBRARYPACKAGES as redundant. --- LogosLinuxInstaller.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/LogosLinuxInstaller.sh b/LogosLinuxInstaller.sh index 8777a37..4c34996 100755 --- a/LogosLinuxInstaller.sh +++ b/LogosLinuxInstaller.sh @@ -558,17 +558,16 @@ getPackageManager() { fi if [ -x "$(command -v apt)" ]; then - PACKAGE_MANAGER="apt install" - PACKAGES="mktemp patch lsof wget find sed grep gawk tr winbind cabextract x11-apps bc libxml2-utils curl" - LIBRARYPACKAGES="fuse3" + PACKAGE_MANAGER="apt install -y" + PACKAGES="mktemp patch lsof wget find sed grep gawk tr winbind cabextract x11-apps bc libxml2-utils curl fuse3" elif [ -x "$(command -v dnf)" ]; then - PACKAGE_MANAGER="dnf install" + PACKAGE_MANAGER="dnf install -y" PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" elif [ -x "$(command -v yum)" ]; then - PACKAGE_MANAGER="yum install" + PACKAGE_MANAGER="yum install -y" PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" elif [ -x "$(command -v pamac)" ]; then - PACKAGE_MANAGER="pamac install --no-upgrade" + PACKAGE_MANAGER="pamac install --no-upgrade --no-confirm" PACKAGES="patch lsof wget sed grep gawk cabextract samba bc libxml2 curl" elif [ -x "$(command -v pacman)" ]; then PACKAGE_MANAGER='pacman -Syu --overwrite \* --noconfirm --needed' @@ -591,7 +590,6 @@ getPackageManager() { if [ -n "${SUPERUSERDO}" ]; then export SUPERUSERDO; fi if [ -n "${PACKAGE_MANAGER}" ]; then export PACKAGE_MANAGER; fi if [ -n "${PACKAGES}" ]; then export PACKAGES; fi - if [ -n "${LIBRARYPACKAGES}" ]; then export LIBRARYPACKAGES; fi } installPackages() { @@ -639,7 +637,7 @@ check_libs() { else if [ -n "${PACKAGE_MANGER}" ]; then logos_continue_question "Your ${OS} install is missing the library: ${lib}. To continue, the script will attempt to install the library by using ${PACKAGE_MANAGER}. Proceed?" "Your system does not have lib: ${lib}. Please install the package associated with ${lib} for ${OS}.\n ${EXTRA_INFO}" - installPackages "${LIBRARYPACKAGES}" + installPackages "${PACKAGES}" else logos_error "The script could not determine your ${OS} install's package manager or it is unsupported. Your computer is missing the library: ${lib}. Please install the package associated with ${lib} for ${OS}.\n ${EXTRA_INFO}" fi From 1a862856460809fd90dc76099ad591baf82e965f Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 21:08:12 -0500 Subject: [PATCH 06/11] Add controlPanel: --reinstall-dependencies --- README.md | 23 +++--- controlPanel-Template.sh | 168 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 171 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index c3364b6..d175e46 100644 --- a/README.md +++ b/README.md @@ -69,17 +69,18 @@ Options: Usage: ./controlPanel.sh Interact with Logos Bible Software in Wine on Linux. -Options:x - -h --help Prints this help message and exit. - -v --version Prints version information and exit. - -D --debug Makes Wine print out additional info. - -f --force-root Sets LOGOS_FORCE_ROOT to true, which permits - the root user to run the script. - --wine64 Run the script's wine64 binary. - --wineserver Run the script's wineserver binary. - --winetricks Run winetricks. - --setAppImage Set the script's AppImage file. NOTE: - Currently broken. Disabled until fixed. +Options: + -h --help Prints this help message and exit. + -v --version Prints version information and exit. + -D --debug Makes Wine print out additional info. + -f --force-root Sets LOGOS_FORCE_ROOT to true, which permits + the root user to run the script. + --wine64 Run the script's wine64 binary. + --wineserver Run the script's wineserver binary. + --winetricks Run winetricks. + --reinstall-dependencies Reinstall your distro's dependencies required + to run Logos. + --selectAppImage Set the script's AppImage file. ``` # Installation [WIP] diff --git a/controlPanel-Template.sh b/controlPanel-Template.sh index 4a81d7e..8d4b8d6 100644 --- a/controlPanel-Template.sh +++ b/controlPanel-Template.sh @@ -55,18 +55,163 @@ Usage: ./\$TITLE Interact with ${FLPRODUCT} Bible Software in Wine on Linux. Options: - -h --help Prints this help message and exit. - -v --version Prints version information and exit. - -D --debug Makes Wine print out additional info. - -f --force-root Sets LOGOS_FORCE_ROOT to true, which permits - the root user to run the script. - --wine64 Run the script's wine64 binary. - --wineserver Run the script's wineserver binary. - --winetricks Run winetricks. - --selectAppImage Set the script's AppImage file. + -h --help Prints this help message and exit. + -v --version Prints version information and exit. + -D --debug Makes Wine print out additional info. + -f --force-root Sets LOGOS_FORCE_ROOT to true, which permits + the root user to run the script. + --wine64 Run the script's wine64 binary. + --wineserver Run the script's wineserver binary. + --winetricks Run winetricks. + --reinstall-dependencies Reinstall your distro's dependencies required + to run Logos. + --selectAppImage Set the script's AppImage file. EEOF } +## BEGIN CHECK DEPENDENCIES FUNCTIONS +getOS() { + if [ -f /etc/os-release ]; then + # freedesktop.org and systemd + # The following line is needed for SC1091: + # shellcheck source=/dev/null + source /etc/os-release + OS="\${ID}" + OS_RELEASE="\${VERSION_ID}" + elif type lsb_release >/dev/null 2>&1; then + # linuxbase.org + OS="\$(lsb_release -si)" + OS_RELEASE="\$(lsb_release -sr)" + elif [ -f /etc/lsb-release ]; then + # For some versions of Debian/Ubuntu without lsb_release command + # The following line is needed for SC1091: + # shellcheck source=/dev/null + source /etc/lsb-release + OS="\${DISTRIB_ID}" + # shellcheck disable=SC2034 + OS_RELEASE="\${DISTRIB_RELEASE}" + elif [ -f /etc/debian_version ]; then + OS=Debian + # shellcheck disable=SC2034 + OS_RELEASE="\$(cat /etc/debian_version)" + elif [ -f /etc/SuSe-release ]; then + : + elif [ -f /etc/redhat-release ]; then + : + else + OS="\$(uname -s)" + # shellcheck disable=SC2034 + OS_RELEASE="\$(uname -r)" + fi +} + +getPackageManager() { + if [ -x "\$(command -v sudo)" ]; then + SUPERUSERDO="sudo" + elif [ -x "\$(command -v doas)" ]; then + SUPERUSERDO="doas" + else + : + fi + + if [ -x "\$(command -v apt)" ]; then + PACKAGE_MANAGER="apt install -y" + PACKAGES="mktemp patch lsof wget find sed grep gawk tr winbind cabextract x11-apps bc libxml2-utils curl fuse3" + elif [ -x "\$(command -v dnf)" ]; then + PACKAGE_MANAGER="dnf install -y" + PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" + elif [ -x "\$(command -v yum)" ]; then + PACKAGE_MANAGER="yum install -y" + PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" + elif [ -x "\$(command -v pamac)" ]; then + PACKAGE_MANAGER="pamac install --no-upgrade --no-confirm" + PACKAGES="patch lsof wget sed grep gawk cabextract samba bc libxml2 curl" + elif [ -x "\$(command -v pacman)" ]; then + PACKAGE_MANAGER='pacman -Syu --overwrite \* --noconfirm --needed' + PACKAGES="patch lsof wget sed grep gawk cabextract samba bc libxml2 curl print-manager system-config-printer cups-filters nss-mdns foomatic-db-engine foomatic-db-ppds foomatic-db-nonfree-ppds ghostscript glibc samba extra-rel/apparmor core-rel/libcurl-gnutls winetricks cabextract appmenu-gtk-module patch bc lib32-libjpeg-turbo qt5-virtualkeyboard wine-staging giflib lib32-giflib libpng lib32-libpng libldap lib32-libldap gnutls lib32-gnutls mpg123 lib32-mpg123 openal lib32-openal v4l-utils lib32-v4l-utils libpulse lib32-libpulse libgpg-error lib32-libgpg-error alsa-plugins lib32-alsa-plugins alsa-lib lib32-alsa-lib libjpeg-turbo lib32-libjpeg-turbo sqlite lib32-sqlite libxcomposite lib32-libxcomposite libxinerama lib32-libgcrypt libgcrypt lib32-libxinerama ncurses lib32-ncurses ocl-icd lib32-ocl-icd libxslt lib32-libxslt libva lib32-libva gtk3 lib32-gtk3 gst-plugins-base-libs lib32-gst-plugins-base-libs vulkan-icd-loader lib32-vulkan-icd-loader" + elif [ -x "\$(command -v apk)" ]; then + # PACKAGE_MANAGER="apk add" + # PACKAGES="patch mod_auth_ntlm_winbind samba-winbind cabextract bc libxml2 curl" + : + elif [ -x "\$(command -v zypper)" ]; then + # PACKAGE_MANAGER="zypper install" + # PACKAGES="" + : + elif [ -x "\$(command -v pkg)" ]; then + # PACKAGE_MANAGER="pkg install" + # PACKAGES="" + : + else + verbose && echo "Your distribution's package manager could not be determined." + fi + if [ -n "\${SUPERUSERDO}" ]; then export SUPERUSERDO; fi + if [ -n "\${PACKAGE_MANAGER}" ]; then export PACKAGE_MANAGER; fi + if [ -n "\${PACKAGES}" ]; then export PACKAGES; fi +} + +installPackages() { + "\${SUPERUSERDO}" "\${PACKAGE_MANAGER}" "$@" +} + +check_commands() { + if [ -z "\${SUPERUSERDO}" ]; then logos_error "Your distribution appears to be missing the ability to escalate privileges (e.g., sudo, doas). Please install either sudo or doas."; fi + for cmd in "\$@"; do + if have_dep "\${cmd}"; then + verbose && echo "* command \${cmd} is installed!" + else + verbose && echo "* command \${cmd} not installed!" + MISSING_CMD+=("\${cmd}") + fi + done + if [ "\${#MISSING_CMD[@]}" -ne 0 ]; then + if [ -n "\${PACKAGE_MANGER}" ]; then + logos_continue_question "Your \${OS} install is missing the command(s): \${MISSING_CMD[*]}. To continue, the script will attempt to install the package(s): \${PACKAGES} by using (\${PACKAGE_MANAGER}). Proceed?" "Your system is missing the command(s) \${MISSING_CMD[*]}. Please install your distro's package(s) associated with \${MISSING_CMD[*]} for \${OS}.\n \${EXTRA_INFO}" + if [ "\${OS}" = "Steam" ]; then + "\${SUPERUSERDO}" steamos-readonly disable + "\${SUPERUSERDO}" pacman-key --init + "\${SUPERUSERDO}" pacman-key --populate archlinux + fi + installPackages "${PACKAGES}" + if [ "\$OS" = "Steam" ]; then + "\${SUPERUSERDO}" sed -i 's/mymachines resolve/mymachines mdns_minimal [NOTFOUND=return] resolve/' /etc/nsswitch.conf + "\${SUPERUSERDO}" locale-gen + "\${SUPERUSERDO}" systemctl enable --now avahi-daemon + "\${SUPERUSERDO}" systemctl enable --now cups + "\${SUPERUSERDO}" steamos-readonly enable + fi + else + logos_error "The script could not determine your \${OS} install's package manager or it is unsupported. Your computer is missing the command(s) \${MISSING_CMD[*]}. Please install your distro's package(s) associated with \${MISSING_CMD[*]} for \${OS}.\n\${EXTRA_INFO}" + fi + fi +} +# shellcheck disable=SC2001 +check_libs() { + if [ -z "\${SUPERUSERDO}" ]; then logos_error "Your distribution appears to be missing the ability to escalate privileges (e.g., sudo, doas). Please install either sudo or doas."; fi + for lib in "\$@"; do + HAVE_LIB="\$(ldconfig -N -v "$(sed 's/:/ /g' <<< "\${LD_LIBRARY_PATH}")" 2>/dev/null | grep "\${lib}")" + if [ -n "\${HAVE_LIB}" ]; then + verbose && echo "* \${lib} is installed!" + else + if [ -n "\${PACKAGE_MANGER}" ]; then + logos_continue_question "Your \${OS} install is missing the library: \${lib}. To continue, the script will attempt to install the library by using \${PACKAGE_MANAGER}. Proceed?" "Your system does not have lib: \${lib}. Please install the package associated with \${lib} for \${OS}.\n \${EXTRA_INFO}" + installPackages "\${PACKAGES}" + else + logos_error "The script could not determine your \${OS} install's package manager or it is unsupported. Your computer is missing the library: \${lib}. Please install the package associated with \${lib} for \${OS}.\n \${EXTRA_INFO}" + fi + fi + done +} + +checkDependencies() { + verbose && echo "Checking system for dependencies…" + if [ "${TARGETVERSION}" = "10" ]; then + check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl; + elif [ "${TARGETVERSION}" = "9" ]; then + check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl xwd cabextract; + else logos_error "Unknown Logos version." + fi + verbose && echo "All dependencies found." +} cli_download() { URI="\${1}" @@ -210,6 +355,11 @@ while getopts "\$OPTSTRING" opt; do shift runWinetricks; exit 0 ;; + reinstall-dependencies) + getOS; + getPackageManager; + checkDependencies; + exit 0 ;; selectAppImage) selectAppImage; exit 0;; From c438db60dcdc9c2ac0fd6c1b6935081b0fec7ce5 Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 21:34:26 -0500 Subject: [PATCH 07/11] Lay foundation for #206 for controlPanel.sh --- README.md | 3 +- controlPanel-Template.sh | 436 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 410 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index d175e46..f65ccae 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,8 @@ Options: --winetricks Run winetricks. --reinstall-dependencies Reinstall your distro's dependencies required to run Logos. - --selectAppImage Set the script's AppImage file. + --updateAppImage Update to the latest stable Wine AppImage. + --selectAppImage Set the script's Wine AppImage file. ``` # Installation [WIP] diff --git a/controlPanel-Template.sh b/controlPanel-Template.sh index 8d4b8d6..9e3a776 100644 --- a/controlPanel-Template.sh +++ b/controlPanel-Template.sh @@ -6,6 +6,7 @@ AUTHOR="${LOGOS_SCRIPT_AUTHOR}" # BEGIN ENVIRONMENT HERE="\$(dirname "\$(readlink -f "\${0}")")" +if [ -z "${LOGOS_LOG}" ]; then LOGOS_LOG="${HOME}/.local/state/Logos_on_Linux/controlpanel.log"; mkdir -p "${HOME}/.local/state/Logos_on_Linux"; touch "${LOGOS_LOG}"; export LOGOS_LOG; fi # Save IFS IFS_TMP=\${IFS} @@ -65,10 +66,387 @@ Options: --winetricks Run winetricks. --reinstall-dependencies Reinstall your distro's dependencies required to run Logos. - --selectAppImage Set the script's AppImage file. + --updateAppImage Update to the latest stable Wine AppImage. + --selectAppImage Set the script's Wine AppImage file. EEOF } + +verbose() { [[ \$VERBOSE = true ]] && return 0 || return 1; }; + +debug() { + [[ \$DEBUG = true ]] && return 0 || return 1 +} + +setDebug() { + DEBUG="true"; + VERBOSE="true"; + WINEDEBUG=""; + set -x; + echo "Debug mode enabled." >> "\${LOGOS_LOG}"; +} + +die() { echo >&2 "\$*"; exit 1; }; + +die-if-running() { + \PIDF=/tmp/LogosLinuxInstaller.pid + + if [ -f "\${PIDF}" ]; then + if logos_continue_question "The script is already running on PID $(cat "\${PIDF}"). Should it be killed to allow this instance to run?" "The script is already running. Exiting." "1"; then + kill -9 "$(cat "\${PIDF}")" + fi + fi + trap 'rm -f -- "\${PIDF}"' EXIT + echo \$$ > "\${PIDF}" +} + +die-if-root() { + if [ "\$(id -u)" -eq '0' ] && [ -z "\${LOGOS_FORCE_ROOT}" ]; then + logos_error "Running Wine/winetricks as root is highly discouraged. Use -f|--force-root if you must run as root. See https://wiki.winehq.org/FAQ#Should_I_run_Wine_as_root.3F" + fi +} + +have_dep() { + command -v "\$1" >/dev/null 2>&1 +} + +# Sources: +# https://askubuntu.com/a/1021548/680649 +# https://unix.stackexchange.com/a/77138/123999 +getDialog() { + if [ -z "\${DISPLAY}" ]; then + logos_error "The Control Panel does not work unless you are running a display" + exit 1 + fi + + DIALOG="" + DIALOG_ESCAPE="" + + if [[ -t 0 ]]; then + verbose && echo "Running in terminal." + while :; do + t whiptail && DIALOG=whiptail && break + t dialog && DIALOG=dialog && DIALOG_ESCAPE=-- && export DIALOG_ESCAPE && break + if test "\${XDG_CURRENT_DESKTOP}" != "KDE"; then + t zenity && DIALOG=zenity && GUI=true && break + #t kdialog && DIALOG=kdialog && GUI=true && break + elif test "${XDG_CURRENT_DESKTOP}" == "KDE"; then + #t kdialog && DIALOG=kdialog && GUI=true && break + t zenity && DIALOG=zenity && GUI=true && break + else + echo "No dialog program found. Please install either dialog, whiptail, zenity, or kdialog"; + fi + done; + else + verbose && echo "Running by double click." >> "${LOGOS_LOG}" + while :; do + if test "\${XDG_CURRENT_DESKTOP}" != "KDE"; then + t zenity && DIALOG=zenity && GUI=true && break + #t kdialog && DIALOG=kdialog && GUI=true && break + elif test "\${XDG_CURRENT_DESKTOP}" == "KDE"; then + #t kdialog && DIALOG=kdialog && GUI=true && break + t zenity && DIALOG=zenity && GUI=true && break + else + no-diag-msg "No dialog program found. Please install either zenity or kdialog." + fi + done; + fi; export DIALOG; export GUI; +} +## BEGIN DIALOG FUNCTIONS +no-diag-msg() { + echo "\${1}" >> "\${LOGOS_LOG}"; + xterm -hold -e printf "%s\n" "\${1}"; + die; +} +cli_msg() { + printf "%s\n" "\${1}" +} +gtk_info() { + zenity --info --width=300 --height=200 --text="\$*" --title='Information' +} +gtk_progress() { + zenity --progress --title="\${1}" --text="\${2}" --pulsate --auto-close --no-cancel +} +gtk_warn() { + zenity --warning --width=300 --height=200 --text="\$*" --title='Warning!' +} +gtk_error() { + zenity --error --width=300 --height=200 --text="\$*" --title='Error!' +} +logos_info() { + INFO_MESSAGE="\${1}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_msg "\${INFO_MESSAGE}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_info "\${INFO_MESSAGE}"; + echo "\$(date) \${INFO_MESSAGE}" >> "\${LOGOS_LOG}"; + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +logos_progress() { + PROGRESS_TITLE="\${1}" + PROGRESS_TEXT="\${2}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_msg "\${PROGRESS_TEXT}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_progress "\${PROGRESS_TITLE}" "\${PROGRESS_TEXT}" + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +logos_warn() { + WARN_MESSAGE="\${1}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_msg "\${WARN_MESSAGE}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_warn "\${WARN_MESSAGE}" + echo "\$(date) \${WARN_MESSAGE}" >> "\${LOGOS_LOG}"; + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +logos_error() { + WIKI_LINK="https://github.com/ferion11/LogosLinuxInstaller/wiki" + TELEGRAM_LINK="https://t.me/linux_logos" + MATRIX_LINK="https://matrix.to/#/#logosbible:matrix.org" + ERROR_MESSAGE="\${1}" + SECONDARY="\${2}" + HELP_MESSAGE="If you need help, please consult:\n\n\${WIKI_LINK}\n\${TELEGRAM_LINK}\n\${MATRIX_LINK}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_msg "\${ERROR_MESSAGE}\n\n\${HELP_MESSAGE}"; + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_error "\${ERROR_MESSAGE}\n\n\${HELP_MESSAGE}"; + echo "\$(date) \${ERROR_MESSAGE}" >> "\${LOGOS_LOG}"; + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi + if [ -z "\${SECONDARY}" ]; then + rm /tmp/LogosLinuxInstaller.pid + kill -SIGKILL "-\$((\$(ps -o pgid= -p "\${\$}")))" + fi + exit 1; +} +cli_question() { + QUESTION_TEXT=\${1} + while true; do + read -rp "\${QUESTION_TEXT} [Y/n]: " yn + + case \$yn in + [yY]* ) return 0; break;; + [nN]* ) return 1; break;; + * ) echo "Type Y[es] or N[o].";; + esac + done +} +cli_continue_question() { + QUESTION_TEXT="\${1}" + NO_TEXT="\${2}" + SECONDARY="\${3}" + if ! cli_question "\${QUESTION_TEXT}"; then logos_error "\${NO_TEXT}" "\${SECONDARY}"; fi +} +cli_acknowledge_question() { + QUESTION_TEXT=\${1} + NO_TEXT="\${2}" + if ! cli_question "\${QUESTION_TEXT}"; then logos_info "\${NO_TEXT}"; fi +} +gtk_question() { + if zenity --question --width=300 --height=200 --text "\$@" --title='Question:' + then return 0 + else return 1 + fi +} +gtk_continue_question() { + QUESTION_TEXT="\${1}" + NO_TEXT="\${2}" + SECONDARY="\${3}" + if ! gtk_question "\${QUESTION_TEXT}"; then logos_error "The installation was cancelled!" "\${SECONDARY}"; fi +} +gtk_acknowledge_question() { + QUESTION_TEXT="\${1}" + NO_TEXT=\${2} + if ! gtk_question "\${QUESTION_TEXT}"; then logos_info "\${NO_TEXT}"; fi +} +logos_continue_question() { + QUESTION_TEXT="\${1}" + NO_TEXT=\${2} + SECONDARY="\${3}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_continue_question "\${QUESTION_TEXT}" "\${NO_TEXT}" "\${SECONDARY}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_continue_question "\${QUESTION_TEXT}" "\${NO_TEXT}" "\${SECONDARY}" + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +logos_acknowledge_question() { + QUESTION_TEXT="\${1}" + NO_TEXT="\${2}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_acknowledge_question "\${QUESTION_TEXT}" "\${NO_TEXT}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_acknowledge_question "\${QUESTION_TEXT}" "\${NO_TEXT}" + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +cli_download() { + # NOTE: here must be a limitation to handle it easily. \$2 can be dir if it already exists or if it ends with '/' + URI="\${1}" + DESTINATION="\${2}" + # extract last field of URI as filename: + FILENAME="\${URI##*/}" + + if [ "\${DESTINATION}" != "\${DESTINATION%/}" ]; then + # it has '/' at the end or it is existing directory + TARGET="\${DESTINATION}/\${1##*/}" + [ -d "\${DESTINATION}" ] || mkdir -p "\${DESTINATION}" || logos_error "Cannot create \${DESTINATION}" + elif [ -d "\${DESTINATION}" ]; then + # it's existing directory + TARGET="\${DESTINATION}/\${1##*/}" + else + TARGET="\${DESTINATION}" + # ensure that the directory where the target file will be exists + [ -d "\${DESTINATION%/*}" ] || mkdir -p "\${DESTINATION%/*}" || logos_error "Cannot create directory \${DESTINATION%/*}" + fi + wget -c "\${URI}" -O "\${TARGET}" +} +# shellcheck disable=SC2028 +gtk_download() { + # NOTE: here must be a limitation to handle it easily. \$2 can be dir if it already exists or if it ends with '/' + URI="\${1}" + DESTINATION="\${2}" + # extract last field of URI as filename: + FILENAME="\${URI##*/}" + + if [ "\${DESTINATION}" != "\${DESTINATION%/}" ]; then + # it has '/' at the end or it is existing directory + TARGET="\${DESTINATION}/\${1##*/}" + [ -d "\${DESTINATION}" ] || mkdir -p "\${DESTINATION}" || logos_error "Cannot create \${DESTINATION}" + elif [ -d "\${DESTINATION}" ]; then + # it's existing directory + TARGET="\${DESTINATION}/\${1##*/}" + else + TARGET="\${DESTINATION}" + # ensure that the directory where the target file will be exists + [ -d "\${DESTINATION%/*}" ] || mkdir -p "\${DESTINATION%/*}" || logos_error "Cannot create directory \${DESTINATION%/*}" + fi + + pipe_progress="\$(mktemp)" + rm -rf "\${pipe_progress}" + mkfifo "\${pipe_progress}" + + pipe_wget="\$(mktemp)" + rm -rf "\${pipe_wget}" + mkfifo "\${pipe_wget}" + + # zenity GUI feedback + # NOTE: Abstracting this progress dialog to a function breaks download capabilities due to the pipe. + zenity --progress --title "Downloading \${FILENAME}..." --text="Downloading: \${FILENAME}\ninto: \${DESTINATION}\n" --percentage=0 --auto-close < "\${pipe_progress}" & + ZENITY_PID="\${!}" + + # download the file with wget: + wget -c "\${URI}" -O "\${TARGET}" > "\${pipe_wget}" 2>&1 & + WGET_PID="\${!}" + + # process the dialog progress bar + total_size="Starting…" + percent="0" + current="Starting…" + speed="Starting…" + remain="Starting…" + while read -r data; do + if echo "\${data}" | grep -q '^Length:' ; then + result="\$(echo "\${data}" | grep "^Length:" | sed 's/.*\((.*)\).*/\1/' | tr -d '()')" + if [ \${#result} -le 10 ]; then total_size=\${result} ; fi + fi + + if echo "\${data}" | grep -q '[0-9]*%' ;then + result="\$(echo "\${data}" | grep -o "[0-9]*%" | tr -d '%')" + if [ \${#result} -le 3 ]; then percent=\${result} ; fi + + result="\$(echo "\${data}" | grep "[0-9]*%" | sed 's/\([0-9BKMG]\+\).*/\1/' )" + if [ \${#result} -le 10 ]; then current=\${result} ; fi + + result="\$(echo "\${data}" | grep "[0-9]*%" | sed 's/.*\(% [0-9BKMG.]\+\).*/\1/' | tr -d ' %')" + if [ \${#result} -le 10 ]; then speed=\${result} ; fi + + result="\$(echo "\${data}" | grep -o "[0-9A-Za-z]*\$" )" + if [ \${#result} -le 10 ]; then remain=\${result} ; fi + fi + + if [ -z "\$(pgrep -P "\${\$}" zenity)" ]; then + WGET_PID_CURRENT="\$(pgrep -P "\${\$}" wget)" + [ -n "\${WGET_PID_CURRENT}" ] && kill -SIGKILL "\${WGET_PID_CURRENT}" + fi + + [ "\${percent}" == "100" ] && break + + # Update zenity's progress bar + echo "\${percent}" + echo "#Downloading: \${FILENAME}\ninto: \${DESTINATION}\n\n\${current} of \${total_size} \(\${percent}%\)\nSpeed : \${speed}/Sec\nEstimated time : \${remain}" + done < "\${pipe_wget}" > "\${pipe_progress}" + + wait "\${WGET_PID}" + WGET_RETURN="\${?}" + + wait "\${ZENITY_PID}" + ZENITY_RETURN="\${?}" + + fuser -TERM -k -w "\${pipe_progress}" + rm -rf "\${pipe_progress}" + + fuser -TERM -k -w "\${pipe_wget}" + rm -rf "\${pipe_wget}" + + # NOTE: sometimes the process finishes before the wait command, giving the error code 127 + if [ "\${ZENITY_RETURN}" == "0" ] || [ "\${ZENITY_RETURN}" == "127" ] ; then + if [ "\${WGET_RETURN}" != "0" ] && [ "\${WGET_RETURN}" != "127" ] ; then + logos_error "ERROR: The installation was cancelled because of an error while attempting a download.\n\nAttmpted Downloading: \${URI}\n\nTarget Destination: \${DESTINATION}\n\n File Name: \${FILENAME}\n\n - Error Code: WGET_RETURN: \${WGET_RETURN}" + fi + else + logos_error "The installation was cancelled!\n * ZENITY_RETURN: \${ZENITY_RETURN}" + fi + verbose && echo "\${FILENAME} download finished!" +} +logos_download() { + URI="\${1}" + DESTINATION="\${2}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_download "\${URI}" "\${DESTINATION}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_download "\${URI}" "\${DESTINATION}" + elif [[ "\${DIALOG}" == "kdialog" ]]; then + no-diag-msg "kdialog not implemented." + else + no-diag-msg "No dialog tool found." + fi +} +logos_reuse_download() { + SOURCEURL="\${1}" + FILE="\${2}" + TARGETDIR="\${3}" + DIRS=( + "\${INSTALLDIR}" + "\${PRESENT_WORKING_DIRECTORY}" + "\${MYDOWNLOADS}" + ) + FOUND=1 + for i in "\${DIRS[@]}"; do + if [ -f "\${i}/\${FILE}" ]; then + logos_info "\${FILE} exists in \${i}. Using it…" + cp "\${i}/\${FILE}" "\${TARGETDIR}/" | logos_progress "Copying…" "Copying \${FILE}\ninto \${TARGETDIR}" + FOUND=0 + break + fi + done + if [[ "\${FOUND}" == 1 ]]; then + logos_info "\${FILE} does not exist. Downloading…" + logos_download "\${SOURCEURL}" "\${MYDOWNLOADS}/\${FILE}" + cp "\${MYDOWNLOADS}/\${FILE}" "\${TARGETDIR}/" | logos_progress "Copying…" "Copying: \${FILE}\ninto: \${TARGETDIR}" + fi +} +## END DIALOG FUNCTIONS ## BEGIN CHECK DEPENDENCIES FUNCTIONS getOS() { if [ -f /etc/os-release ]; then @@ -213,23 +591,6 @@ checkDependencies() { verbose && echo "All dependencies found." } -cli_download() { - URI="\${1}" - DESTINATION="\${2}" - FILENAME="\${URI##*/}" - - if [ "\${DESTINATION}" != "\${DESTINATION%/}" ]; then - TARGET="\${DESTINATION}/\${1##*/}" - [ -d "\${DESTINATION}" ] || mkdir -p "\${DESTINATION}" || echo "Cannot create \${DESTINATION}" && exit 1 - elif [ -d "\${DESTINATION}" ]; then - TARGET="\${DESTINATION}/${1##*/}" - else - TARGET="\${DESTINATION}" - [ -d "\${DESTINATION%/*}" ] || mkdir -p "\${DESTINATION%/*}" || echo "Cannot create directory \${DESTINATION%/*}" && exit 1 - fi - echo "\${URI}" - wget --inet4-only -c "\${URI}" -O "\${TARGET}" -} setWinetricks() { if [ -f "\${APPDIR_BINDIR}/winetricks" ]; then WINETRICKSBIN="\${APPDIR_BINDIR}/winetricks" @@ -252,6 +613,7 @@ setWinetricks() { fi export WINETRICKSBIN } + runWinetricks() { if [ ! -z "\${WINETRICKSBIN}" ] && [ -f "\${WINETRICKSBIN}" ]; then : @@ -262,6 +624,10 @@ runWinetricks() { "\${WINESERVER_EXE}" -w } +updateAppImage() { + +} + selectAppImage() { echo "======= Running AppImage Selection only: =======" APPIMAGE_FILENAME="" @@ -305,6 +671,26 @@ selectAppImage() { exit 0 } # END FUNCTION DECLARATIONS +# BEGIN SCRIPT EXECUTION +if [ -z "\${DIALOG}" ]; then + getDialog; + if test "\${GUI}" == "true"; then + echo "Running in a GUI. Enabling logging." >> "\${LOGOS_LOG}" + setDebug; + fi +fi + +die-if-running; +die-if-root; + +main() { + { echo "$LOGOS_SCRIPT_TITLE, $LOGOS_SCRIPT_VERSION by $LOGOS_SCRIPT_AUTHOR."; + # BEGIN PREPARATION + verbose && date; getOS; + verbose && date; getPackageManager; + } | tee -a "\$LOGOS_LOG" +} + # BEGIN OPTARGS RESET_OPTARGS=true for arg in "\$@" @@ -360,6 +746,9 @@ while getopts "\$OPTSTRING" opt; do getPackageManager; checkDependencies; exit 0 ;; + updateAppImage) + updateAppImage; + exit 0;; selectAppImage) selectAppImage; exit 0;; @@ -378,16 +767,7 @@ fi shift \$((OPTIND-1)) # END OPTARGS -# BEGIN DIE IF ROOT -if [ "\$(id -u)" -eq '0' ] && [ -z "\${LOGOS_FORCE_ROOT}" ]; then - echo "* Running Wine/winetricks as root is highly discouraged. Use -f|--force-root if you must run as root. See https://wiki.winehq.org/FAQ#Should_I_run_Wine_as_root.3F" - exit 1; -fi -# END DIE IF ROOT - -debug() { - [[ \$DEBUG = true ]] && return 0 || return 1 -} +main; debug && echo "Debug mode enabled." From b1712184ca73e8be0a138fbc5e4d3286514cfcb9 Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 21:38:43 -0500 Subject: [PATCH 08/11] Prepare script for #211 --- LogosLinuxInstaller.sh | 10 +++++----- controlPanel-Template.sh | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/LogosLinuxInstaller.sh b/LogosLinuxInstaller.sh index 4c34996..215f0f5 100755 --- a/LogosLinuxInstaller.sh +++ b/LogosLinuxInstaller.sh @@ -11,6 +11,11 @@ export LOGOS_SCRIPT_VERSION="3.7.5" # Script version for this Installer Script ##### # BEGIN ENVIRONMENT +if [ -z "${DEFAULT_CONFIG_PATH}" ]; then DEFAULT_CONFIG_PATH="${HOME}/.config/Logos_on_Linux/Logos_on_Linux.conf"; export DEFAULT_CONFIG_PATH; fi +if [ -z "${LOGOS_LOG}" ]; then LOGOS_LOG="${HOME}/.local/state/Logos_on_Linux/install.log"; mkdir -p "${HOME}/.local/state/Logos_on_Linux"; touch "${LOGOS_LOG}"; export LOGOS_LOG; fi +if [ -z "${WINEDEBUG}" ]; then WINEDEBUG="fixme-all,err-all"; fi; export WINEDEBUG # Make wine output less verbose +if [ -z "${DEBUG}" ]; then DEBUG="FALSE"; fi; export DEBUG +if [ -z "${VERBOSE}" ]; then VERBOSE="FALSE"; fi; export VERBOSE if [ -z "${WINE64_APPIMAGE_FULL_VERSION}" ]; then WINE64_APPIMAGE_FULL_VERSION="v8.19-devel"; export WINE64_APPIMAGE_FULL_VERSION; fi if [ -z "${WINE64_APPIMAGE_FULL_URL}" ]; then WINE64_APPIMAGE_FULL_URL="https://github.com/ferion11/LogosLinuxInstaller/releases/download/wine-devel-8.19/wine-devel_8.19-x86_64.AppImage"; export WINE64_APPIMAGE_FULL_URL; fi if [ -z "${WINE64_APPIMAGE_FULL_FILENAME}" ]; then WINE64_APPIMAGE_FULL_FILENAME="$(basename "${WINE64_APPIMAGE_FULL_URL}")"; export WINE64_APPIMAGE_FULL_FILENAME; fi @@ -31,11 +36,6 @@ if [ -z "${PRESENT_WORKING_DIRECTORY}" ]; then PRESENT_WORKING_DIRECTORY="${PWD} if [ -z "${LOGOS_FORCE_ROOT+x}" ]; then export LOGOS_FORCE_ROOT="" ; fi if [ -z "${WINEBOOT_GUI+x}" ]; then export WINEBOOT_GUI="" ; fi if [ -z "${EXTRA_INFO}" ]; then EXTRA_INFO="The following packages are usually necessary: winbind cabextract libjpeg8."; export EXTRA_INFO; fi -if [ -z "${DEFAULT_CONFIG_PATH}" ]; then DEFAULT_CONFIG_PATH="${HOME}/.config/Logos_on_Linux/Logos_on_Linux.conf"; export DEFAULT_CONFIG_PATH; fi -if [ -z "${LOGOS_LOG}" ]; then LOGOS_LOG="${HOME}/.local/state/Logos_on_Linux/install.log"; mkdir -p "${HOME}/.local/state/Logos_on_Linux"; touch "${LOGOS_LOG}"; export LOGOS_LOG; fi -if [ -z "${WINEDEBUG}" ]; then WINEDEBUG="fixme-all,err-all"; fi; export WINEDEBUG # Make wine output less verbose -if [ -z "${DEBUG}" ]; then DEBUG="FALSE"; fi; export DEBUG -if [ -z "${VERBOSE}" ]; then VERBOSE="FALSE"; fi; export VERBOSE # END ENVIRONMENT # BEGIN FUNCTION DECLARATIONS diff --git a/controlPanel-Template.sh b/controlPanel-Template.sh index 9e3a776..c8020cb 100644 --- a/controlPanel-Template.sh +++ b/controlPanel-Template.sh @@ -6,7 +6,15 @@ AUTHOR="${LOGOS_SCRIPT_AUTHOR}" # BEGIN ENVIRONMENT HERE="\$(dirname "\$(readlink -f "\${0}")")" -if [ -z "${LOGOS_LOG}" ]; then LOGOS_LOG="${HOME}/.local/state/Logos_on_Linux/controlpanel.log"; mkdir -p "${HOME}/.local/state/Logos_on_Linux"; touch "${LOGOS_LOG}"; export LOGOS_LOG; fi +if [ -z "\${LOGOS_LOG}" ]; then LOGOS_LOG="${HOME}/.local/state/Logos_on_Linux/controlpanel.log"; mkdir -p "${HOME}/.local/state/Logos_on_Linux"; touch "${LOGOS_LOG}"; export LOGOS_LOG; fi +if [ -z "\${WINEDEBUG}" ]; then WINEDEBUG="fixme-all,err-all"; fi; export WINEDEBUG # Make wine output less verbose +if [ -z "\${DEBUG}" ]; then DEBUG="FALSE"; fi; export DEBUG +if [ -z "\${VERBOSE}" ]; then VERBOSE="FALSE"; fi; export VERBOSE +if [ -z "\${WINE64_APPIMAGE_FULL_VERSION}" ]; then WINE64_APPIMAGE_FULL_VERSION="v8.19-devel"; export WINE64_APPIMAGE_FULL_VERSION; fi +if [ -z "\${WINE64_APPIMAGE_FULL_URL}" ]; then WINE64_APPIMAGE_FULL_URL="https://github.com/ferion11/LogosLinuxInstaller/releases/download/wine-devel-8.19/wine-devel_8.19-x86_64.AppImage"; export WINE64_APPIMAGE_FULL_URL; fi +if [ -z "\${WINE64_APPIMAGE_FULL_FILENAME}" ]; then WINE64_APPIMAGE_FULL_FILENAME="$(basename "${WINE64_APPIMAGE_FULL_URL}")"; export WINE64_APPIMAGE_FULL_FILENAME; fi +if [ -z "\${WINE64_APPIMAGE_VERSION}" ]; then WINE64_APPIMAGE_VERSION="v8.19-devel"; export WINE64_APPIMAGE_VERSION; fi +if [ -z "\${WINE64_APPIMAGE_URL}" ]; then WINE64_APPIMAGE_URL="https://github.com/ferion11/LogosLinuxInstaller/releases/download/wine-devel-8.19/wine-devel_8.19-x86_64.AppImage"; export WINE64_APPIMAGE_URL; fi # Save IFS IFS_TMP=\${IFS} @@ -43,9 +51,7 @@ else export APPDIR_BINDIR="${APPDIR_BINDIR}"; export APPDIR_BINDIR export APPIMAGE_LINK_SELECTION_NAME="${APPIMAGE_LINK_SELECTION_NAME}"; export APPIMAGE_LINK_SELECTION_NAME; fi -if [ -z "${WINETRICKS_URL}" ]; then WINETRICKS_URL="https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks"; export WINETRICKS_URL; fi - -if [ -z "\${WINEDEBUG}" ]; then WINEDEBUG="fixme-all,err-all"; export WINEDEBUG; fi # Make wine output less verbose +if [ -z "\${WINETRICKS_URL}" ]; then WINETRICKS_URL="https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks"; export WINETRICKS_URL; fi # END ENVIRONMENT # BEGIN FUNCTION DECLARATIONS usage() { @@ -582,9 +588,9 @@ check_libs() { checkDependencies() { verbose && echo "Checking system for dependencies…" - if [ "${TARGETVERSION}" = "10" ]; then + if [ "\${TARGETVERSION}" = "10" ]; then check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl; - elif [ "${TARGETVERSION}" = "9" ]; then + elif [ "\${TARGETVERSION}" = "9" ]; then check_commands mktemp patch lsof wget find sed grep ntlm_auth awk tr bc xmllint curl xwd cabextract; else logos_error "Unknown Logos version." fi @@ -625,7 +631,7 @@ runWinetricks() { } updateAppImage() { - + : } selectAppImage() { From 0d335952abc0f89f2896215f7205ec803230ba4d Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 21:42:25 -0500 Subject: [PATCH 09/11] Lay foundation for #206 for launcher.sh --- Launcher-Template.sh | 386 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 385 insertions(+), 1 deletion(-) diff --git a/Launcher-Template.sh b/Launcher-Template.sh index ec4eee5..b463634 100644 --- a/Launcher-Template.sh +++ b/Launcher-Template.sh @@ -6,6 +6,15 @@ AUTHOR="${LOGOS_SCRIPT_AUTHOR}" # BEGIN ENVIRONMENT HERE="\$(dirname "\$(readlink -f "\${0}")")" +if [ -z "\${LOGOS_LOG}" ]; then LOGOS_LOG="${HOME}/.local/state/Logos_on_Linux/launcher.log"; mkdir -p "${HOME}/.local/state/Logos_on_Linux"; touch "${LOGOS_LOG}"; export LOGOS_LOG; fi +if [ -z "\${WINEDEBUG}" ]; then WINEDEBUG="fixme-all,err-all"; fi; export WINEDEBUG # Make wine output less verbose +if [ -z "\${DEBUG}" ]; then DEBUG="FALSE"; fi; export DEBUG +if [ -z "\${VERBOSE}" ]; then VERBOSE="FALSE"; fi; export VERBOSE +if [ -z "\${WINE64_APPIMAGE_FULL_VERSION}" ]; then WINE64_APPIMAGE_FULL_VERSION="v8.19-devel"; export WINE64_APPIMAGE_FULL_VERSION; fi +if [ -z "\${WINE64_APPIMAGE_FULL_URL}" ]; then WINE64_APPIMAGE_FULL_URL="https://github.com/ferion11/LogosLinuxInstaller/releases/download/wine-devel-8.19/wine-devel_8.19-x86_64.AppImage"; export WINE64_APPIMAGE_FULL_URL; fi +if [ -z "\${WINE64_APPIMAGE_FULL_FILENAME}" ]; then WINE64_APPIMAGE_FULL_FILENAME="$(basename "${WINE64_APPIMAGE_FULL_URL}")"; export WINE64_APPIMAGE_FULL_FILENAME; fi +if [ -z "\${WINE64_APPIMAGE_VERSION}" ]; then WINE64_APPIMAGE_VERSION="v8.19-devel"; export WINE64_APPIMAGE_VERSION; fi +if [ -z "\${WINE64_APPIMAGE_URL}" ]; then WINE64_APPIMAGE_URL="https://github.com/ferion11/LogosLinuxInstaller/releases/download/wine-devel-8.19/wine-devel_8.19-x86_64.AppImage"; export WINE64_APPIMAGE_URL; fi # Save IFS IFS_TMP=\${IFS} @@ -55,7 +64,6 @@ fi [ -z "\${LOGOS_ICON_URL}" ] && export LOGOS_ICON_URL="${LOGOS_ICON_URL}" LOGOS_ICON_FILENAME="\$(basename "\${LOGOS_ICON_URL}")"; export LOGOS_ICON_FILENAME; -if [ -z "\${WINEDEBUG}" ]; then WINEDEBUG="fixme-all,err-all"; export WINEDEBUG; fi # Make wine output less verbose # END ENVIRONMENT # BEGIN FUNCTION DECLARATIONS usage() { @@ -92,6 +100,382 @@ Options: UEOF } +verbose() { [[ \$VERBOSE = true ]] && return 0 || return 1; }; + +debug() { + [[ \$DEBUG = true ]] && return 0 || return 1 +} + +setDebug() { + DEBUG="true"; + VERBOSE="true"; + WINEDEBUG=""; + set -x; + echo "Debug mode enabled." >> "\${LOGOS_LOG}"; +} + +die() { echo >&2 "\$*"; exit 1; }; + +die-if-running() { + \PIDF=/tmp/LogosLinuxInstaller.pid + + if [ -f "\${PIDF}" ]; then + if logos_continue_question "The script is already running on PID $(cat "\${PIDF}"). Should it be killed to allow this instance to run?" "The script is already running. Exiting." "1"; then + kill -9 "$(cat "\${PIDF}")" + fi + fi + trap 'rm -f -- "\${PIDF}"' EXIT + echo \$$ > "\${PIDF}" +} + +die-if-root() { + if [ "\$(id -u)" -eq '0' ] && [ -z "\${LOGOS_FORCE_ROOT}" ]; then + logos_error "Running Wine/winetricks as root is highly discouraged. Use -f|--force-root if you must run as root. See https://wiki.winehq.org/FAQ#Should_I_run_Wine_as_root.3F" + fi +} + +have_dep() { + command -v "\$1" >/dev/null 2>&1 +} + +# Sources: +# https://askubuntu.com/a/1021548/680649 +# https://unix.stackexchange.com/a/77138/123999 +getDialog() { + if [ -z "\${DISPLAY}" ]; then + logos_error "The Control Panel does not work unless you are running a display" + exit 1 + fi + + DIALOG="" + DIALOG_ESCAPE="" + + if [[ -t 0 ]]; then + verbose && echo "Running in terminal." + while :; do + t whiptail && DIALOG=whiptail && break + t dialog && DIALOG=dialog && DIALOG_ESCAPE=-- && export DIALOG_ESCAPE && break + if test "\${XDG_CURRENT_DESKTOP}" != "KDE"; then + t zenity && DIALOG=zenity && GUI=true && break + #t kdialog && DIALOG=kdialog && GUI=true && break + elif test "${XDG_CURRENT_DESKTOP}" == "KDE"; then + #t kdialog && DIALOG=kdialog && GUI=true && break + t zenity && DIALOG=zenity && GUI=true && break + else + echo "No dialog program found. Please install either dialog, whiptail, zenity, or kdialog"; + fi + done; + else + verbose && echo "Running by double click." >> "${LOGOS_LOG}" + while :; do + if test "\${XDG_CURRENT_DESKTOP}" != "KDE"; then + t zenity && DIALOG=zenity && GUI=true && break + #t kdialog && DIALOG=kdialog && GUI=true && break + elif test "\${XDG_CURRENT_DESKTOP}" == "KDE"; then + #t kdialog && DIALOG=kdialog && GUI=true && break + t zenity && DIALOG=zenity && GUI=true && break + else + no-diag-msg "No dialog program found. Please install either zenity or kdialog." + fi + done; + fi; export DIALOG; export GUI; +} +## BEGIN DIALOG FUNCTIONS +no-diag-msg() { + echo "\${1}" >> "\${LOGOS_LOG}"; + xterm -hold -e printf "%s\n" "\${1}"; + die; +} +cli_msg() { + printf "%s\n" "\${1}" +} +gtk_info() { + zenity --info --width=300 --height=200 --text="\$*" --title='Information' +} +gtk_progress() { + zenity --progress --title="\${1}" --text="\${2}" --pulsate --auto-close --no-cancel +} +gtk_warn() { + zenity --warning --width=300 --height=200 --text="\$*" --title='Warning!' +} +gtk_error() { + zenity --error --width=300 --height=200 --text="\$*" --title='Error!' +} +logos_info() { + INFO_MESSAGE="\${1}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_msg "\${INFO_MESSAGE}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_info "\${INFO_MESSAGE}"; + echo "\$(date) \${INFO_MESSAGE}" >> "\${LOGOS_LOG}"; + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +logos_progress() { + PROGRESS_TITLE="\${1}" + PROGRESS_TEXT="\${2}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_msg "\${PROGRESS_TEXT}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_progress "\${PROGRESS_TITLE}" "\${PROGRESS_TEXT}" + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +logos_warn() { + WARN_MESSAGE="\${1}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_msg "\${WARN_MESSAGE}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_warn "\${WARN_MESSAGE}" + echo "\$(date) \${WARN_MESSAGE}" >> "\${LOGOS_LOG}"; + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +logos_error() { + WIKI_LINK="https://github.com/ferion11/LogosLinuxInstaller/wiki" + TELEGRAM_LINK="https://t.me/linux_logos" + MATRIX_LINK="https://matrix.to/#/#logosbible:matrix.org" + ERROR_MESSAGE="\${1}" + SECONDARY="\${2}" + HELP_MESSAGE="If you need help, please consult:\n\n\${WIKI_LINK}\n\${TELEGRAM_LINK}\n\${MATRIX_LINK}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_msg "\${ERROR_MESSAGE}\n\n\${HELP_MESSAGE}"; + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_error "\${ERROR_MESSAGE}\n\n\${HELP_MESSAGE}"; + echo "\$(date) \${ERROR_MESSAGE}" >> "\${LOGOS_LOG}"; + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi + if [ -z "\${SECONDARY}" ]; then + rm /tmp/LogosLinuxInstaller.pid + kill -SIGKILL "-\$((\$(ps -o pgid= -p "\${\$}")))" + fi + exit 1; +} +cli_question() { + QUESTION_TEXT=\${1} + while true; do + read -rp "\${QUESTION_TEXT} [Y/n]: " yn + + case \$yn in + [yY]* ) return 0; break;; + [nN]* ) return 1; break;; + * ) echo "Type Y[es] or N[o].";; + esac + done +} +cli_continue_question() { + QUESTION_TEXT="\${1}" + NO_TEXT="\${2}" + SECONDARY="\${3}" + if ! cli_question "\${QUESTION_TEXT}"; then logos_error "\${NO_TEXT}" "\${SECONDARY}"; fi +} +cli_acknowledge_question() { + QUESTION_TEXT=\${1} + NO_TEXT="\${2}" + if ! cli_question "\${QUESTION_TEXT}"; then logos_info "\${NO_TEXT}"; fi +} +gtk_question() { + if zenity --question --width=300 --height=200 --text "\$@" --title='Question:' + then return 0 + else return 1 + fi +} +gtk_continue_question() { + QUESTION_TEXT="\${1}" + NO_TEXT="\${2}" + SECONDARY="\${3}" + if ! gtk_question "\${QUESTION_TEXT}"; then logos_error "The installation was cancelled!" "\${SECONDARY}"; fi +} +gtk_acknowledge_question() { + QUESTION_TEXT="\${1}" + NO_TEXT=\${2} + if ! gtk_question "\${QUESTION_TEXT}"; then logos_info "\${NO_TEXT}"; fi +} +logos_continue_question() { + QUESTION_TEXT="\${1}" + NO_TEXT=\${2} + SECONDARY="\${3}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_continue_question "\${QUESTION_TEXT}" "\${NO_TEXT}" "\${SECONDARY}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_continue_question "\${QUESTION_TEXT}" "\${NO_TEXT}" "\${SECONDARY}" + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +logos_acknowledge_question() { + QUESTION_TEXT="\${1}" + NO_TEXT="\${2}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_acknowledge_question "\${QUESTION_TEXT}" "\${NO_TEXT}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_acknowledge_question "\${QUESTION_TEXT}" "\${NO_TEXT}" + elif [[ "\${DIALOG}" == "kdialog" ]]; then + : + fi +} +cli_download() { + # NOTE: here must be a limitation to handle it easily. \$2 can be dir if it already exists or if it ends with '/' + URI="\${1}" + DESTINATION="\${2}" + # extract last field of URI as filename: + FILENAME="\${URI##*/}" + + if [ "\${DESTINATION}" != "\${DESTINATION%/}" ]; then + # it has '/' at the end or it is existing directory + TARGET="\${DESTINATION}/\${1##*/}" + [ -d "\${DESTINATION}" ] || mkdir -p "\${DESTINATION}" || logos_error "Cannot create \${DESTINATION}" + elif [ -d "\${DESTINATION}" ]; then + # it's existing directory + TARGET="\${DESTINATION}/\${1##*/}" + else + TARGET="\${DESTINATION}" + # ensure that the directory where the target file will be exists + [ -d "\${DESTINATION%/*}" ] || mkdir -p "\${DESTINATION%/*}" || logos_error "Cannot create directory \${DESTINATION%/*}" + fi + wget -c "\${URI}" -O "\${TARGET}" +} +# shellcheck disable=SC2028 +gtk_download() { + # NOTE: here must be a limitation to handle it easily. \$2 can be dir if it already exists or if it ends with '/' + URI="\${1}" + DESTINATION="\${2}" + # extract last field of URI as filename: + FILENAME="\${URI##*/}" + + if [ "\${DESTINATION}" != "\${DESTINATION%/}" ]; then + # it has '/' at the end or it is existing directory + TARGET="\${DESTINATION}/\${1##*/}" + [ -d "\${DESTINATION}" ] || mkdir -p "\${DESTINATION}" || logos_error "Cannot create \${DESTINATION}" + elif [ -d "\${DESTINATION}" ]; then + # it's existing directory + TARGET="\${DESTINATION}/\${1##*/}" + else + TARGET="\${DESTINATION}" + # ensure that the directory where the target file will be exists + [ -d "\${DESTINATION%/*}" ] || mkdir -p "\${DESTINATION%/*}" || logos_error "Cannot create directory \${DESTINATION%/*}" + fi + + pipe_progress="\$(mktemp)" + rm -rf "\${pipe_progress}" + mkfifo "\${pipe_progress}" + + pipe_wget="\$(mktemp)" + rm -rf "\${pipe_wget}" + mkfifo "\${pipe_wget}" + + # zenity GUI feedback + # NOTE: Abstracting this progress dialog to a function breaks download capabilities due to the pipe. + zenity --progress --title "Downloading \${FILENAME}..." --text="Downloading: \${FILENAME}\ninto: \${DESTINATION}\n" --percentage=0 --auto-close < "\${pipe_progress}" & + ZENITY_PID="\${!}" + + # download the file with wget: + wget -c "\${URI}" -O "\${TARGET}" > "\${pipe_wget}" 2>&1 & + WGET_PID="\${!}" + + # process the dialog progress bar + total_size="Starting…" + percent="0" + current="Starting…" + speed="Starting…" + remain="Starting…" + while read -r data; do + if echo "\${data}" | grep -q '^Length:' ; then + result="\$(echo "\${data}" | grep "^Length:" | sed 's/.*\((.*)\).*/\1/' | tr -d '()')" + if [ \${#result} -le 10 ]; then total_size=\${result} ; fi + fi + + if echo "\${data}" | grep -q '[0-9]*%' ;then + result="\$(echo "\${data}" | grep -o "[0-9]*%" | tr -d '%')" + if [ \${#result} -le 3 ]; then percent=\${result} ; fi + + result="\$(echo "\${data}" | grep "[0-9]*%" | sed 's/\([0-9BKMG]\+\).*/\1/' )" + if [ \${#result} -le 10 ]; then current=\${result} ; fi + + result="\$(echo "\${data}" | grep "[0-9]*%" | sed 's/.*\(% [0-9BKMG.]\+\).*/\1/' | tr -d ' %')" + if [ \${#result} -le 10 ]; then speed=\${result} ; fi + + result="\$(echo "\${data}" | grep -o "[0-9A-Za-z]*\$" )" + if [ \${#result} -le 10 ]; then remain=\${result} ; fi + fi + + if [ -z "\$(pgrep -P "\${\$}" zenity)" ]; then + WGET_PID_CURRENT="\$(pgrep -P "\${\$}" wget)" + [ -n "\${WGET_PID_CURRENT}" ] && kill -SIGKILL "\${WGET_PID_CURRENT}" + fi + + [ "\${percent}" == "100" ] && break + + # Update zenity's progress bar + echo "\${percent}" + echo "#Downloading: \${FILENAME}\ninto: \${DESTINATION}\n\n\${current} of \${total_size} \(\${percent}%\)\nSpeed : \${speed}/Sec\nEstimated time : \${remain}" + done < "\${pipe_wget}" > "\${pipe_progress}" + + wait "\${WGET_PID}" + WGET_RETURN="\${?}" + + wait "\${ZENITY_PID}" + ZENITY_RETURN="\${?}" + + fuser -TERM -k -w "\${pipe_progress}" + rm -rf "\${pipe_progress}" + + fuser -TERM -k -w "\${pipe_wget}" + rm -rf "\${pipe_wget}" + + # NOTE: sometimes the process finishes before the wait command, giving the error code 127 + if [ "\${ZENITY_RETURN}" == "0" ] || [ "\${ZENITY_RETURN}" == "127" ] ; then + if [ "\${WGET_RETURN}" != "0" ] && [ "\${WGET_RETURN}" != "127" ] ; then + logos_error "ERROR: The installation was cancelled because of an error while attempting a download.\n\nAttmpted Downloading: \${URI}\n\nTarget Destination: \${DESTINATION}\n\n File Name: \${FILENAME}\n\n - Error Code: WGET_RETURN: \${WGET_RETURN}" + fi + else + logos_error "The installation was cancelled!\n * ZENITY_RETURN: \${ZENITY_RETURN}" + fi + verbose && echo "\${FILENAME} download finished!" +} +logos_download() { + URI="\${1}" + DESTINATION="\${2}" + if [[ "\${DIALOG}" == "whiptail" ]] || [[ "\${DIALOG}" == "dialog" ]]; then + cli_download "\${URI}" "\${DESTINATION}" + elif [[ "\${DIALOG}" == "zenity" ]]; then + gtk_download "\${URI}" "\${DESTINATION}" + elif [[ "\${DIALOG}" == "kdialog" ]]; then + no-diag-msg "kdialog not implemented." + else + no-diag-msg "No dialog tool found." + fi +} +logos_reuse_download() { + SOURCEURL="\${1}" + FILE="\${2}" + TARGETDIR="\${3}" + DIRS=( + "\${INSTALLDIR}" + "\${PRESENT_WORKING_DIRECTORY}" + "\${MYDOWNLOADS}" + ) + FOUND=1 + for i in "\${DIRS[@]}"; do + if [ -f "\${i}/\${FILE}" ]; then + logos_info "\${FILE} exists in \${i}. Using it…" + cp "\${i}/\${FILE}" "\${TARGETDIR}/" | logos_progress "Copying…" "Copying \${FILE}\ninto \${TARGETDIR}" + FOUND=0 + break + fi + done + if [[ "\${FOUND}" == 1 ]]; then + logos_info "\${FILE} does not exist. Downloading…" + logos_download "\${SOURCEURL}" "\${MYDOWNLOADS}/\${FILE}" + cp "\${MYDOWNLOADS}/\${FILE}" "\${TARGETDIR}/" | logos_progress "Copying…" "Copying: \${FILE}\ninto: \${TARGETDIR}" + fi +} +## END DIALOG FUNCTIONS + resourceSnapshot() { if [[ \$(which pidstat) ]]; then PIDSTR=\$(ps faux | grep "\${FLPRODUCT}" | grep "\${LOGOS_USER}" | grep -vE "(grep)" | awk '{printf "%s%s",sep, \$2; sep=" -p "} END{print ""}'); From ae170d75e002d06bbfe2c5dd9cd9b064e52800fc Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 21:11:01 -0500 Subject: [PATCH 10/11] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5028abf..911a183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ # Changelog +* 3.8.0 + - Fix #169. [T. H. Wright, J. Bernard] + - Fix #203. [T. H. Wright, J. Goodman] + - Fix #210. [T. H. Wright] * 3.7.5 - Fix #131. [T. H. Wright] - Fix #132. [T. H. Wright] From 235d632e99dfcd9fa2cf711b74b605d6aafa41be Mon Sep 17 00:00:00 2001 From: "T. H. Wright" Date: Mon, 6 Nov 2023 21:12:19 -0500 Subject: [PATCH 11/11] Update Version: 3.8.0 --- LogosLinuxInstaller.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogosLinuxInstaller.sh b/LogosLinuxInstaller.sh index 215f0f5..71fd29e 100755 --- a/LogosLinuxInstaller.sh +++ b/LogosLinuxInstaller.sh @@ -2,7 +2,7 @@ # shellcheck disable=SC2317 export LOGOS_SCRIPT_TITLE="Logos Linux Installer" # From https://github.com/ferion11/LogosLinuxInstaller export LOGOS_SCRIPT_AUTHOR="Ferion11, John Goodman, T. H. Wright" -export LOGOS_SCRIPT_VERSION="3.7.5" # Script version for this Installer Script +export LOGOS_SCRIPT_VERSION="3.8.0" # Script version for this Installer Script ##### # Originally written by Ferion11.