diff --git a/indra/newview/linux_tools/chrome_sandboxing_permissions_setup.sh b/indra/newview/linux_tools/chrome_sandboxing_permissions_setup.sh index 54c4864192cf97db076dbe4db1d74923d0c3aa70..0be69710b0d6272a94829ed8d8fba3bdc99acbb4 100755 --- a/indra/newview/linux_tools/chrome_sandboxing_permissions_setup.sh +++ b/indra/newview/linux_tools/chrome_sandboxing_permissions_setup.sh @@ -1,7 +1,7 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +SCRIPT_DIR=$(dirname "$0") SANDBOX_BIN="$SCRIPT_DIR/../bin/llplugin/chrome-sandbox" -chown root:root $SANDBOX_BIN -chmod 4755 $SANDBOX_BIN +chown root:root "$SANDBOX_BIN" +chmod 4755 "$SANDBOX_BIN" diff --git a/indra/newview/linux_tools/handle_secondlifeprotocol.sh b/indra/newview/linux_tools/handle_secondlifeprotocol.sh index 6038e259f850410ca5253c04fe694f66edc90fc7..fd2a0e5cf263d210623dd31ff04e9542f08a2afe 100755 --- a/indra/newview/linux_tools/handle_secondlifeprotocol.sh +++ b/indra/newview/linux_tools/handle_secondlifeprotocol.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env sh # Send a URL of the form secondlife://... to any running viewer, if not, launch Alchemy viewer. # diff --git a/indra/newview/linux_tools/install.sh b/indra/newview/linux_tools/install.sh index 1801abf1463ebdec23a5080893b774c6a67d3b70..4a1810df2087ffe423c3d40d2f9614ccc79ee20d 100755 --- a/indra/newview/linux_tools/install.sh +++ b/indra/newview/linux_tools/install.sh @@ -1,23 +1,34 @@ -#!/bin/bash +#!/usr/bin/env sh # Install Alchemy Viewer. This script can install the viewer both # system-wide and for an individual user. +build_data_file="build_data.json" +if [ -f "${build_data_file}" ]; then + version=$(sed -n 's/.*"Version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${build_data_file}") + channel=$(sed -n 's/.*"Channel"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${build_data_file}") + installdir_name=$(echo "$channel" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' )-install +else + echo "Error: File ${build_data_file} not found." >&2 + exit 1 +fi + +echo "Installing ${channel} version ${version}" + VT102_STYLE_NORMAL='\E[0m' VT102_COLOR_RED='\E[31m' -SCRIPTSRC=`readlink -f "$0" || echo "$0"` -RUN_PATH=`dirname "${SCRIPTSRC}" || echo .` +SCRIPTSRC=$(readlink -f "$0" || echo "$0") +RUN_PATH=$(dirname "${SCRIPTSRC}" || echo .) tarball_path=${RUN_PATH} -function prompt() +prompt() { - local prompt=$1 - local input + prompt=$1 - echo -n "$prompt" + printf "%s" "$prompt" - while read input; do + while read -r input; do case $input in [Yy]* ) return 1 @@ -27,25 +38,24 @@ function prompt() ;; * ) echo "Please enter yes or no." - echo -n "$prompt" + printf "%s" "$prompt" esac done } -function die() +die() { - warn $1 + warn "$1" exit 1 } -function warn() +warn() { - echo -n -e $VT102_COLOR_RED - echo $1 - echo -n -e $VT102_STYLE_NORMAL + printf "%b%b%b\n" "$VT102_COLOR_RED" "$1" "$VT102_STYLE_NORMAL" } -function homedir_install() + +homedir_install() { warn "You are not running as a privileged user, so you will only be able" warn "to install Alchemy Viewer in your home directory. If you" @@ -54,33 +64,34 @@ function homedir_install() echo prompt "Proceed with the installation? [Y/N]: " - if [[ $? == 0 ]]; then - exit 0 + if [ $? -eq 0 ]; then + exit 0 fi - install_to_prefix "$HOME/.local/share/alchemy-install" - $HOME/.local/share/alchemy-install/etc/refresh_desktop_app_entry.sh + install_to_prefix "$HOME/.local/share/${installdir_name}" + "$HOME/.local/share/${installdir_name}/etc/refresh_desktop_app_entry.sh" } -function root_install() +root_install() { - local default_prefix="/opt/alchemy-install" + + default_prefix="/opt/${installdir_name}" - echo -n "Enter the desired installation directory [${default_prefix}]: "; - read - if [[ "$REPLY" = "" ]] ; then - local install_prefix=$default_prefix + printf "Enter the desired installation directory [%s]: " "${default_prefix}" + read -r REPLY + if [ "$REPLY" = "" ] ; then + install_prefix=$default_prefix else - local install_prefix=$REPLY + install_prefix=$REPLY fi install_to_prefix "$install_prefix" mkdir -p /usr/local/share/applications - ${install_prefix}/etc/refresh_desktop_app_entry.sh + "${install_prefix}"/etc/refresh_desktop_app_entry.sh } -function install_to_prefix() +install_to_prefix() { test -e "$1" && backup_previous_installation "$1" mkdir -p "$1" || die "Failed to create installation directory!" @@ -88,9 +99,8 @@ function install_to_prefix() echo " - Installing to $1" cp -a "${tarball_path}"/* "$1/" || die "Failed to complete the installation!" - - SANDBOX_BIN="$1/bin/llplugin/chrome-sandbox" - if [ "$UID" == "0" ]; then + + if [ "$(id -u)" = "0" ]; then "$1/etc/chrome_sandboxing_permissions_setup.sh" else echo " â•â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•®" @@ -115,7 +125,7 @@ function install_to_prefix() echo "" warn "By refusing this step, you accept this risk." prompt "Proceed with enabling web media process sandboxing? [Y/N]: " - if [[ $? == 0 ]]; then + if [ $? = 0 ]; then # Save this choice so that we don't ask for creds on every viewer launch touch "$1/bin/llplugin/.user_does_not_want_chrome_sandboxing_and_accepts_the_risks" exit 0 @@ -126,16 +136,16 @@ function install_to_prefix() fi } -function backup_previous_installation() +backup_previous_installation() { - local backup_dir="$1".backup-$(date -I) + backup_dir="$1".backup-$(date -I) echo " - Backing up previous installation to $backup_dir" mv "$1" "$backup_dir" || die "Failed to create backup of existing installation!" } -if [ "$UID" == "0" ]; then +if [ "$(id -u)" = "0" ]; then root_install else homedir_install diff --git a/indra/newview/linux_tools/refresh_desktop_app_entry.sh b/indra/newview/linux_tools/refresh_desktop_app_entry.sh index c65b58d4c9e7d4ba3297040889935eb677f6ba50..820a847fcb25eeb3dc471134f668c5e368a3216b 100755 --- a/indra/newview/linux_tools/refresh_desktop_app_entry.sh +++ b/indra/newview/linux_tools/refresh_desktop_app_entry.sh @@ -1,18 +1,36 @@ -#!/bin/bash +#!/usr/bin/env sh SCRIPTSRC="$(readlink -f "$0" || echo "$0")" RUN_PATH="$(dirname "${SCRIPTSRC}" || echo .)" install_prefix="${RUN_PATH}"/.. -function install_desktop_entry() +build_data_file="${install_prefix}/build_data.json" +if [ -f "${build_data_file}" ]; then + version=$(sed -n 's/.*"Version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${build_data_file}") + channel_base=$(sed -n 's/.*"Channel Base"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${build_data_file}") + channel=$(sed -n 's/.*"Channel"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${build_data_file}") + desktopfilename=$(echo "$channel" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' )-viewer.desktop +else + echo "Error: File ${build_data_file} not found." >&2 + exit 1 +fi + +# Check for the Release channel. This channel should not have the channel name in its launcher. +if [ "$channel" = "Alchemy Release" ]; then + launcher_name="Alchemy" +else + launcher_name=$channel +fi + +install_desktop_entry() { - local installation_prefix="${1}" - local desktop_entries_dir="${2}" + installation_prefix="${1}" + desktop_entries_dir="${2}" - local desktop_entry="\ + desktop_entry="\ [Desktop Entry]\n\ -Name=Alchemy\n\ +Name=${launcher_name}\n\ Comment=Client for the On-line Virtual World, Second Life\n\ Exec=${installation_prefix}/alchemy\n\ Icon=${installation_prefix}/alchemy_icon.png\n\ @@ -20,18 +38,18 @@ Terminal=false\n\ Type=Application\n\ Categories=Game;Simulation;\n\ StartupNotify=true\n\ -StartupWMClass=Alchemy\n\ +StartupWMClass=${channel}\n\ X-Desktop-File-Install-Version=3.0" - echo " - Installing menu entries in ${desktop_entries_dir}" - mkdir -vp "${desktop_entries_dir}" - echo -e "${desktop_entry}" > "${desktop_entries_dir}/alchemy-viewer.desktop" || "Failed to install application menu!" + printf " - Installing menu entries in %s\n" "${desktop_entries_dir}" + mkdir -vp "${desktop_entries_dir}" + printf "%b" "${desktop_entry}" > "${desktop_entries_dir}/${desktopfilename}" || echo "Failed to install application menu!" } -if [ "$UID" == "0" ]; then - # system-wide - install_desktop_entry "${install_prefix}" /usr/local/share/applications +if [ "$(id -u)" = "0" ]; then + # system-wide + install_desktop_entry "${install_prefix}" /usr/local/share/applications else - # user-specific - install_desktop_entry "${install_prefix}" "${HOME}/.local/share/applications" + # user-specific + install_desktop_entry "${install_prefix}" "${HOME}/.local/share/applications" fi diff --git a/indra/newview/linux_tools/register_secondlifeprotocol.sh b/indra/newview/linux_tools/register_secondlifeprotocol.sh index e1e3e9395ecead956212fc79f61086e6b08eabb1..d33143cd810b578aa2850fb3fe8869babf7709b5 100755 --- a/indra/newview/linux_tools/register_secondlifeprotocol.sh +++ b/indra/newview/linux_tools/register_secondlifeprotocol.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/env sh # Register a protocol handler (default: handle_secondlifeprotocol.sh) for # URLs of the form secondlife://... @@ -7,26 +7,26 @@ desired_handler="${1}" print() { - log_prefix="RegisterSLProtocol:" - echo -e "${log_prefix} $*" + log_prefix="RegisterSLProtocol:" + printf "%s %s\n" "${log_prefix}" "$*" } run_path=$(dirname "$0" || echo .) cd "${run_path}/.." || exit if [ -z "${desired_handler}" ]; then - desired_handler="$(pwd)/etc/handle_secondlifeprotocol.sh" + desired_handler="$(pwd)/etc/handle_secondlifeprotocol.sh" fi # Ensure the handle_secondlifeprotocol.sh file is executeable (otherwise, xdg-mime won't work) chmod +x "$desired_handler" # Check if xdg-mime is present, if so, use it to register new protocol. -if command -v xdg-mime query default x-scheme-handler/secondlife >/dev/null 2>&1; then - urlhandler=$(xdg-mime query default x-scheme-handler/secondlife) - localappdir="${HOME}/.local/share/applications" - newhandler="secondlifeprotocol_$(basename "$(dirname "${desired_handler}")").desktop" - handlerpath="${localappdir}/${newhandler}" - cat >"${handlerpath}" <<EOFnew || print "Warning: Did not register secondlife:// handler with xdg-mime: Could not write $newhandler"s +if command -v xdg-mime >/dev/null 2>&1; then + urlhandler=$(xdg-mime query default x-scheme-handler/secondlife) + localappdir="${HOME}/.local/share/applications" + newhandler="secondlifeprotocol_$(basename "$(dirname "${desired_handler}")").desktop" + handlerpath="${localappdir}/${newhandler}" + cat >"${handlerpath}" <<EOFnew || print "Warning: Did not register secondlife:// handler with xdg-mime: Could not write $newhandler" [Desktop Entry] Version=1.4 Name="Second Life URL handler" @@ -39,39 +39,39 @@ NoDisplay=true MimeType=x-scheme-handler/secondlife EOFnew - # TODO: use absolute path for the desktop file - # TODO: Ensure that multiple channels behave properly due to different desktop file names in /usr/share/applications/ - # TODO: Better detection of what the handler actually is, as other viewer projects may use the same filename - if [ -z "${urlhandler}" ]; then - print No SLURL handler currently registered, creating new... - else - #xdg-mime uninstall $localappdir/$urlhandler - #Clean up handlers from other viewers - if [ "${urlhandler}" != "${newhandler}" ]; then - print "Current SLURL Handler: ${urlhandler} - Setting ${newhandler} as the new default..." - mv "${localappdir}"/"${urlhandler}" "${localappdir}"/"${urlhandler}".bak - else - print "SLURL Handler has not changed, leaving as-is." - fi - fi - xdg-mime default "${newhandler}" x-scheme-handler/secondlife - if command -v update-desktop-database >/dev/null 2>&1; then - update-desktop-database "${localappdir}" - print "Registered ${desired_handler} as secondlife:// protocol handler with xdg-mime." - else - print "Warning: Cannot update desktop database, command missing - installation may be incomplete." - fi + # TODO: use absolute path for the desktop file + # TODO: Ensure that multiple channels behave properly due to different desktop file names in /usr/share/applications/ + # TODO: Better detection of what the handler actually is, as other viewer projects may use the same filename + if [ -z "${urlhandler}" ]; then + print "No SLURL handler currently registered, creating new..." + else + #xdg-mime uninstall $localappdir/$urlhandler + #Clean up handlers from other viewers + if [ "${urlhandler}" != "${newhandler}" ]; then + print "Current SLURL Handler: ${urlhandler} - Setting ${newhandler} as the new default..." + mv "${localappdir}"/"${urlhandler}" "${localappdir}"/"${urlhandler}".bak + else + print "SLURL Handler has not changed, leaving as-is." + fi + fi + xdg-mime default "${newhandler}" x-scheme-handler/secondlife + if command -v update-desktop-database >/dev/null 2>&1; then + update-desktop-database "${localappdir}" + print "Registered ${desired_handler} as secondlife:// protocol handler with xdg-mime." + else + print "Warning: Cannot update desktop database, command missing - installation may be incomplete." + fi else - print "Warning: Did not register secondlife:// handler with xdg-mime: Package not found." - # TODO: use dconf or another modern alternative - gconftool=$(command -v "${LLGCONFTOOL:=gconftool-2}") - if [[ -n "${gconftool}" ]]; then - print "=== USING DEPRECATED GCONF API ===" - if "${gconftool}" -s -t string /desktop/gnome/url-handlers/secondlife/command "${desired_handler} \"%s\"" && - ${gconftool} -s -t bool /desktop/gnome/url-handlers/secondlife/enabled true; then - print "Registered ${desired_handler} as secondlife:// handler with (deprecated) gconf." - else - print "Failed to register secondlife:// handler with (deprecated) gconf." - fi - fi -fi + print "Warning: Did not register secondlife:// handler with xdg-mime: Package not found." + # TODO: use dconf or another modern alternative + gconftool=$(command -v "${LLGCONFTOOL:=gconftool-2}") + if [ -n "${gconftool}" ]; then + print "=== USING DEPRECATED GCONF API ===" + if "${gconftool}" -s -t string /desktop/gnome/url-handlers/secondlife/command "${desired_handler} \"%s\"" && + ${gconftool} -s -t bool /desktop/gnome/url-handlers/secondlife/enabled true; then + print "Registered ${desired_handler} as secondlife:// handler with (deprecated) gconf." + else + print "Failed to register secondlife:// handler with (deprecated) gconf." + fi + fi +fi \ No newline at end of file diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index cdd4a08171a20b009abdb256c1c263ea6fe7d8d2..1f0b6763f9dc18f8adf47821793b3d26d80e530a 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -1,4 +1,4 @@ -#! /usr/bin/env bash +#! /usr/bin/env sh ## Here are some configuration options for Linux Client Users. @@ -24,25 +24,34 @@ ## you're building your own viewer, bear in mind that the executable ## in the bin directory will be stripped: you should replace it with ## an unstripped binary before you run. -if [[ -v AL_GDB ]]; then +if [ -n "${AL_GDB}" ]; then export LL_WRAPPER='gdb --args' fi -if [[ -v AL_VALGRIND ]]; then +if [ -n "${AL_VALGRIND}" ]; then export LL_WRAPPER='valgrind --smc-check=all --error-limit=no --log-file=secondlife.vg --leak-check=full --suppressions=/usr/lib/valgrind/glibc-2.5.supp --suppressions=secondlife-i686.supp' fi -if [[ -v AL_MANGO ]]; then - export LL_WRAPPER='mangohud --dlsym' +if [ -n "${AL_MANGO}" ]; then + export LL_WRAPPER='mangohud --dlsym' fi ## For controlling various sanitizer options #export ASAN_OPTIONS="halt_on_error=0 detect_leaks=1 symbolize=1" #export UBSAN_OPTIONS="print_stacktrace=1 print_summary=1 halt_on_error=0" +install_dir=$(dirname "$0") +build_data_file="${install_dir}/build_data.json" +if [ -f "${build_data_file}" ]; then + channel=$(sed -n 's/.*"Channel"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${build_data_file}") +else + echo "Error: File ${build_data_file} not found." >&2 + channel="Alchemy" # Fail safely if we're unable to determine the channel +fi + ## Allow Gnome 3 to properly display window title in app bar -export SDL_VIDEO_WAYLAND_WMCLASS=Alchemy -export SDL_VIDEO_X11_WMCLASS=Alchemy +export SDL_VIDEO_WAYLAND_WMCLASS=$channel +export SDL_VIDEO_X11_WMCLASS=$channel ## - Enable threaded mesa GL impl export mesa_glthread=true @@ -59,10 +68,12 @@ echo "Running from ${RUN_PATH}" cd "${RUN_PATH}" || return # Re-register the secondlife:// protocol handler every launch, for now. -./etc/register_secondlifeprotocol.sh +# NOTE: this should no longer be required with the new desktop shortcut, combined with XDG integration. +#./etc/register_secondlifeprotocol.sh # Re-register the application with the desktop system every launch, for now. -./etc/refresh_desktop_app_entry.sh +# NOTE: this should no longer be required with XDG integration. App icon should be created at install time, not run time. +#./etc/refresh_desktop_app_entry.sh ## Before we mess with LD_LIBRARY_PATH, save the old one to restore for ## subprocesses that care. @@ -71,13 +82,14 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" # Add our library directory export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}" -# Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch. +# Copy "$@" to ARGS string specifically to delete the --skip-gridargs switch. # The gridargs.dat file is no more, but we still want to avoid breaking # scripts that invoke this one with --skip-gridargs. -ARGS=() +# Note: In sh, we don't have arrays like in Bash. So, we use a string instead to store the arguments. +ARGS="" for ARG in "$@"; do if [ "--skip-gridargs" != "$ARG" ]; then - ARGS[${#ARGS[*]}]="$ARG" + ARGS="$ARGS \"$ARG\"" fi done @@ -85,16 +97,16 @@ done SANDBOX_BIN=bin/llplugin/chrome-sandbox # if set-user-id = false || is writable || executable = false || read is false || is owned by effective uid || is owned by effective gid OPTOUT_FILE="bin/llplugin/.user_does_not_want_chrome_sandboxing_and_accepts_the_risks" -if [[ ! (-u $SANDBOX_BIN) || (-w $SANDBOX_BIN) || ! (-x $SANDBOX_BIN) || ! (-r $SANDBOX_BIN) || ( -O $SANDBOX_BIN) || (-G $SANDBOX_BIN) ]]; then +if [ ! -u "$SANDBOX_BIN" ] || [ -w "$SANDBOX_BIN" ] || [ ! -x "$SANDBOX_BIN" ] || [ ! -r "$SANDBOX_BIN" ] || [ -O "$SANDBOX_BIN" ] || [ -G "$SANDBOX_BIN" ]; then echo "$SANDBOX_BIN permissions are not set properly to run under sandboxing." if [ ! -f "$OPTOUT_FILE" ]; then - SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) pkexec "$SCRIPT_DIR/etc/chrome_sandboxing_permissions_setup.sh" fi fi #setup wine voice -if [ -x "$(command -v wine)" ]; then +if command -v wine >/dev/null 2>&1; then export WINEDEBUG=-all # disable all debug output for wine export WINEPREFIX="$HOME/.alchemynext/wine" if [ ! -d "$WINEPREFIX" ]; then @@ -105,22 +117,27 @@ else echo "Please install wine to enable full voice functionality." fi +# Check if switcheroo is needed +if [[ -d /sys/class/drm/card1 ]] && command -v switcherooctl >/dev/null 2>&1 && [[ "$(switcherooctl)" == "" ]]; then + notify-send "Automatic GPU selection is not available" "Please enable switcheroo-control.service" +fi + # Run the program. # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the -# command line. But DO quote "${ARGS[@]}": preserve separate args as +# command line. But DO quote "$ARGS": preserve separate args as # individually quoted. -$LL_WRAPPER bin/do-not-directly-run-alchemy-bin "${ARGS[@]}" +# Note: In sh, we don't have arrays like in Bash. So, we use a string instead to store the arguments. +eval "$LL_WRAPPER bin/do-not-directly-run-alchemy-bin $ARGS" LL_RUN_ERR=$? # Handle any resulting errors if [ $LL_RUN_ERR -ne 0 ]; then - # generic error running the binary - echo "*** Bad shutdown ($LL_RUN_ERR). ***" - if [ "$(uname -m)" = "x86_64" ]; then - echo - cat << EOFMARKER + # generic error running the binary + echo "*** Bad shutdown ($LL_RUN_ERR). ***" + if [ "$(uname -m)" = "x86_64" ]; then + echo + cat << EOFMARKER You are running Alchemy Viewer on a x86_64 platform. EOFMARKER - fi + fi fi -