31 Commity 9d0c484aa0 ... 8aa01958ff

Autor SHA1 Wiadomość Data
  bryan 8aa01958ff 1.34.1 release 1 miesiąc temu
  bryan dc0eaed0f6 Use internal package name 1 miesiąc temu
  bryan f227050f6c Fix rpm --query lookup for --reinstall 1 miesiąc temu
  bryan d3c049818a Make install_mesa_freeworld fedora-specific 1 miesiąc temu
  bryan 17512a2c00 Improve recommends for freeworld packages on fedora 1 miesiąc temu
  bryan 444ebbfa25 Improve recommends for freeworld packages on fedora 1 miesiąc temu
  bryan 8de1608a77 Also remove /usr/lib/jriver 1 miesiąc temu
  bryan 361dcb8ce3 Return successfully 1 miesiąc temu
  bryan 8af309488d Re-enable dnf reinstalls 1 miesiąc temu
  bryan d5aecc6902 Disable CoW recursively in ~/.jriver 1 miesiąc temu
  bryan 82b31361d4 Only disable CoW for ~/.jriver 1 miesiąc temu
  bryan 96d6044c85 Make temp repos more prolific 1 miesiąc temu
  bryan 71c21bf084 Simplify legacy checks 1 miesiąc temu
  bryan 8388a3ab26 Streamline version check 1 miesiąc temu
  bryan 9b978e43b7 Clobber repo file 1 miesiąc temu
  bryan 4b166fd025 use a single suite 1 miesiąc temu
  bryan de2032d389 Add temp debug 1 miesiąc temu
  bryan f21e162177 Selectively remove repo files for --uninstall 1 miesiąc temu
  bryan 768e00dff3 Ask to backup and reset library on --uninstall 1 miesiąc temu
  bryan 5e890900f2 Ask to backup and reset library on --uninstall 1 miesiąc temu
  bryan 18a3ae02fa Narrow --uninstall output 1 miesiąc temu
  bryan c729f1fb9b Allow --uninstall to be used seamlessly before other operations 1 miesiąc temu
  bryan cc7c1d4c5f Also uninstall installJRMC output 1 miesiąc temu
  bryan 36548581d3 Return on successful license restore 1 miesiąc temu
  bryan 605dc78cf8 Cleanup documentation 1 miesiąc temu
  bryan 8b464fffc7 Add README.bbcode 1 miesiąc temu
  bryan eb9c9fbf9d Rollup for new minor version, may be buggy 1 miesiąc temu
  bryan afb9ff6ed5 Make createrepo noisier 1 miesiąc temu
  bryan dfac619e9d Append dev to version name 2 miesięcy temu
  bryan 005fe17298 Pass --mcrepo to createrepo service 2 miesięcy temu
  bryan 190a6e7b10 Move UID check after parse 2 miesięcy temu
4 zmienionych plików z 389 dodań i 184 usunięć
  1. 0 1
      .gitignore
  2. 136 0
      README.bbcode
  3. 24 15
      README.md
  4. 229 168
      installJRMC

+ 0 - 1
.gitignore

@@ -1,6 +1,5 @@
 .old/
 .vscode/
-README.bbcode
 installJRMC.zip
 README.shdoc.md
 output/

+ 136 - 0
README.bbcode

@@ -0,0 +1,136 @@
+[size=20pt]installJRMC[/size]
+
+This program will install [url=https://www.jriver.com/]JRiver Media Center[/url] and associated services on most Linux distributions.
+
+You can find the latest version of installJRMC, changelog, and documentation in [url=https://git.bryanroessler.com/bryan/installJRMC]my repository[/url].
+
+[size=18pt]tl;dr One-line MC install[/size] 
+[code]curl https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC|bash[/code]
+
+[size=18pt]Instructions[/size]
+
+Download and unzip installJRMC from the attachment below or grab the latest stable version directly:
+[code]curl -O https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC && 
+chmod +x ./installJRMC && 
+./installJRMC [--option [ARGUMENT]]
+[/code]
+
+[tt]installJRMC[/tt] defaults to [tt]--install=repo[/tt] on distros with MC repositories and [tt]--install=local[/tt] on all others.
+Specifying [tt]--build[/tt], [tt]--createrepo[/tt], [tt]--service[/tt], or [tt]--uninstall[/tt] disables the default install method.
+
+[size=18pt]Options[/size]
+
+[code]
+$ installJRMC --help
+--install, -i repo|local
+    repo: Install MC from repository, future updates will be handled by the system package manager
+    local: Build and install MC package from official source package
+--build[=suse|fedora|centos]
+    Build RPM from source DEB but do not install
+    Optionally, specify a target distro for cross-building (ex. --build=suse, note the '=')
+--compat
+    Build/install MC without minimum dependency version requirements
+--mcversion VERSION
+    Specify the MC version, ex. "33", "34.0.31", or "34.0.31-1" (default: latest)
+--arch ARCH
+    Specify the target MC architecture, ex. "amd64", "arm64", etc (default: host architecture)
+--mcrepo REPO
+    Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: host or official)
+--outputdir PATH
+    Generate reusable installJRMC output in this PATH (default: ./output)
+--restorefile RESTOREFILE
+    Restore file location for automatic license registration
+--betapass PASSWORD
+    Enter beta team password for access to beta builds
+--service, -s SERVICE
+    See SERVICES section below for the list of services to deploy
+  --service-type user|system
+      Starts services at boot (system) or user login (user) (default: per-service, see SERVICES)
+--container, -c CONTAINER (TODO: Under construction)
+    See CONTAINERS section below for a list of containers to deploy
+--createrepo[=suse|fedora|centos]
+    Build rpm, copy to webroot, and run createrepo.
+    Optionally, specify a target distro for non-native repo (ex. --createrepo=fedora, note the '=')
+  --createrepo-webroot PATH
+      The webroot directory to install the repo (default: /var/www/jriver/)
+  --createrepo-user USER
+      The web server user if different from the current user
+--no-update
+    Disable the installJRMC update check
+--yes, -y, --auto
+    Always assumes yes for questions
+--version, -v
+    Print installJRMC version and exit
+--debug, -d
+    Print debug output
+--help, -h
+    Print help dialog and exit
+--uninstall, -u
+    Uninstall JRiver MC, service files, and firewall rules (does not remove library or media files)
+[/code]
+
+[size=18pt]Services[/size]
+
+[code]jriver-mediaserver (user)
+    Enable and start a mediaserver systemd service (requires an existing X server)
+jriver-mediacenter (user)
+    Enable and start a mediacenter systemd service (requires an existing X server)
+jriver-x11vnc (user)
+    Enable and start x11vnc for the local desktop (requires an existing X server, does NOT support Wayland)
+  --vncpass and --display are also valid options (see below)
+jriver-xvnc (system)
+    Enable and start a new Xvnc session running JRiver Media Center
+  --vncpass PASSWORD
+    Set vnc password for x11vnc/Xvnc access. If no password is set, the script will either use existing password stored in ~/.vnc/jrmc_passwd or else no password
+  --display DISPLAY
+    Manually specify display to use for x11vnc/Xvnc (ex. ':1')
+jriver-createrepo (system)
+    Install hourly service to build latest MC RPM and run createrepo
+[/code]
+
+Services use a sane default [tt]--service-type[/tt] listed next to the service name in the Services description. 
+User services can be manipulated as an unprivileged user, for example: [tt]systemctl --user stop jriver-mediacenter[/tt] and begin at user login.
+System services are manipulable as root, for example: [tt]sudo systemctl stop jriver-servicename@username.service[/tt] and begin at system boot.
+Note that it is possible to run all services of a particular user at boot using [tt][url=https://www.freedesktop.org/software/systemd/man/loginctl.html]sudo loginctl enable-linger username[/url][/tt].
+
+Multiple services (but not [tt]--service-types[/tt]) can be installed at one time using multiple [tt]--service[/tt] blocks:
+[code]installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter[/code]
+
+[size=14pt][tt]jriver-x11vnc[/tt] versus [tt]jriver-xvnc[/tt][/size]
+
+[url=http://www.karlrunge.com/x11vnc/]jriver-x11vnc[/url] shares your existing X display via VNC and can be combined with additional services to start Media Center or Media Server. Conversely, [url=https://tigervnc.org/doc/Xvnc.html]jriver-xvnc[/url] creates a new Xvnc display and starts a JRiver Media Center service in the foreground of the new VNC display.
+
+[size=18pt]Containers[/size]
+
+[b]Coming soon![/b]
+
+[size=18pt]Firewall[/size]
+
+installJRMC automatically creates port forwarding firewall rules for remote access to Media Network (52100-52200/tcp, 1900/udp DLNA) and Xvnc/x11vnc (if selected), using firewall-cmd or ufw.
+
+[size=18pt]Examples[/size]
+
+[code]installJRMC[/code]
+Install the latest version of MC from the best available repository.
+[code]installJRMC --mcversion 33 --debug[/code]
+Install the latest version of MC33 from the best available repository with debugging output.
+[code]installJRMC --install local --compat[/code]
+Install a more widely-compatible version of the latest MC version.
+[code]installJRMC --install repo --service jriver-mediacenter --service-type user[/code]
+Install MC from the repository and start/enable jriver-mediacenter.service as a user service.
+[code]installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 34.0.31[/code]
+Build and install an MC 34.0.31 comptability RPM locally and activate it using the /path/to/license.mjr
+[code]installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user[/code]
+Build an RPM locally for the current distro, move it to the webroot, and run createrepo as www-user.
+[code]installJRMC --service jriver-createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user[/code]
+Install the jriver-createrepo timer and service to build the RPM, move it to the webroot, and run createrepo as www-user hourly.
+[code]installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"[/code]
+Install services to share the existing local desktop via VNC and automatically run MC on startup.
+[code]installJRMC --install repo --service jriver-xvnc --display ":2"[/code]
+Install an Xvnc server on display ':2' that starts MC.
+[code]installJRMC --uninstall[/code]
+Uninstall MC, services, and firewall rules. This will [b]not[/b] remove your media, media library/database, or library backups.
+
+[size=18pt]Additional Info[/size]
+
+Did you find installJRMC useful? [url=https://paypal.me/bryanroessler]Buy me a coffee![/url]

+ 24 - 15
README.md

@@ -1,6 +1,6 @@
 # installJRMC
 
-This self-contained program will install [JRiver Media Center](https://www.jriver.com/) and associated services on most Linux distributions.
+This program will install [JRiver Media Center](https://www.jriver.com/) and associated services on most Linux distributions.
 
 You can find the latest version of installJRMC, changelog, and documentation in [my repository](https://git.bryanroessler.com/bryan/installJRMC).
 
@@ -8,11 +8,10 @@ You can find the latest version of installJRMC, changelog, and documentation in
 
 `installJRMC [--option [ARGUMENT]]`
 
-Running `installJRMC` without any options implies `--install repo` (on SUSE: `--install local`) and will install the latest version of Media Center from the official JRiver repository (Ubuntu/Debian) or my [unofficial repository](https://repos.bryanroessler.com/jriver/) (Fedora/CentOS) using the system package manager. If `--service` or `--container` is passed then the default install method (`--install repo` or `--install local`) must be specified (to allow services and containers to be installed independent of MC).
+`installJRMC` defaults to `--install=repo` on distros with MC repositories and `--install=local` on all others.
+Specifying `--build`, `--createrepo`, `--service`, or `--uninstall` disables the default install method.
 
-Recent versions of installJRMC will automatically self-update to the latest installJRMC release.
-
-## tl;dr
+### tl;dr
 
 `curl https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC|bash`
 
@@ -29,7 +28,7 @@ $ installJRMC --help
 --compat
     Build/install MC without minimum dependency version requirements
 --mcversion VERSION
-    Build or install a specific MC version, ex. "34.0.20" or "33" (default: latest)
+    Build or install a specific MC version, ex. "34.0.31" or "33" (default: latest)
 --mcrepo REPO
     Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: latest official)
 --arch ARCH
@@ -58,7 +57,7 @@ $ installJRMC --help
 --yes, -y, --auto
     Always assume yes for questions
 --version, -v
-    Print this script version and exit
+    Print installJRMC version and exit
 --debug, -d
     Print debug output
 --help, -h
@@ -85,14 +84,13 @@ jriver-xvnc [--service-type=system]
     Manually specify display to use for x11vnc/Xvnc (ex. ':1')
 jriver-createrepo [--service-type=system]
     Install hourly service to build latest MC RPM and run createrepo
-    By default installs as root service to handle www permissions more gracefully
 ```
 
 #### `--service-type=`
 
-By default, MC services use a sane `--service-type` listed next to the service name in the [`--service=`](#--service) section. User services begin at user login and are managed by the unprivileged user, for example: `systemctl --user stop jriver-mediacenter`. System services begin at boot and are managed by root, for example: `sudo systemctl stop jriver-servicename@username.service`. It is possible to run all services of a particular user at boot using [`sudo loginctl enable-linger username`](https://www.freedesktop.org/software/systemd/man/loginctl.html).
+Services use a sane default `--service-type` listed next to the service name in the [`--service=`](#--service) section. User services begin at user login and are managed by the unprivileged user, for example: `systemctl --user stop jriver-mediacenter`. System services begin at boot and are managed by root, for example: `sudo systemctl stop jriver-servicename@username.service`. It is possible to run all services of a particular user at boot using [`sudo loginctl enable-linger username`](https://www.freedesktop.org/software/systemd/man/loginctl.html).
 
-Multiple services (but not `--service-types`) can be installed at one time using multiple `--service` blocks: `installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter`
+Multiple services (but not `--service-types`) can be installed at one time using multiple `--service` blocks: `installJRMC --install=repo --service=jriver-x11vnc --service=jriver-mediacenter`
 
 #### `jriver-x11vnc` versus `jriver-xvnc`
 
@@ -108,15 +106,26 @@ Multiple services (but not `--service-types`) can be installed at one time using
 
 **Note:** `ufw` is not installed by default on Debian but will be installed by `installJRMC`. To prevent SSH lock-out, Debian users that have not already enabled `ufw` will need to `sudo ufw enable` after running `installJRMC` and inspecting their configuration.
 
+## Nicities
+
+Depending on the distribution, `installJRMC` also performs the following tasks during MC installation:
+
+* Automatically updates `installJRMC` to the latest release
+* Activates external third-party repositories for improved media playback (hardware decoding, etc.)
+* Adds temporary legacy repositories to provide deprecated libraries
+* Links non-standard SSL certs
+* Disables BTRFS CoW for MC database directories
+* Activates MC if a valid license file is found in common locations
+
 ## Examples
 
 * `installJRMC`
 
     Install the latest version of MC from the best available repository.
 
-* `installJRMC --mcversion 32 --debug`
+* `installJRMC --mcversion 33 --debug`
 
-    Install the latest version of MC32 from the best available repository with debugging output.
+    Install the latest version of MC33 from the best available repository with debugging output.
 
 * `installJRMC --install local --compat`
 
@@ -126,9 +135,9 @@ Multiple services (but not `--service-types`) can be installed at one time using
 
     Install MC from the repository and start/enable `jriver-mediacenter.service` as a user service.
 
-* `installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 34.0.20`
+* `installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 34.0.31`
 
-    Build and install an MC 34.0.20 compatibility RPM locally and activate it using the `/path/to/license.mjr`
+    Build and install an MC 34.0.31 compatibility RPM locally and activate it using the `/path/to/license.mjr`
 
 * `installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user`
 
@@ -154,4 +163,4 @@ Multiple services (but not `--service-types`) can be installed at one time using
 
 Did you find `installJRMC` useful? [Buy me a coffee!](https://paypal.me/bryanroessler)
 
-Did you find a bug? Let me know on [Interact!](https://yabb.jriver.com/interact/index.php/topic,134152.0.html)
+Did you find a bug? [Let me know on Interact!](https://yabb.jriver.com/interact/index.php/topic,141168.0.html)

+ 229 - 168
installJRMC

@@ -1,5 +1,4 @@
 #!/usr/bin/env bash
-# shellcheck disable=SC2317
 # @file installJRMC
 # @brief Installs JRiver Media Center and associated services
 # @description See installJRMC --help or print_help() below for usage
@@ -17,10 +16,13 @@
 # NOTES
 # * Be careful with tabs in heredocs
 # * Avoid execute() for stdout
+#
+# We use indirection to match service names to their functions
+# shellcheck disable=SC2317
 shopt -s extglob
 
-declare -g SCRIPT_VERSION="1.6.5"
-declare -g MC_VERSION="34.0.20" # do find all replace
+declare -g SCRIPT_VERSION="1.34.1"
+declare -g MC_VERSION="34.0.31" # do find all replace
 declare -g MC_REPO="bookworm" # should match the MC_VERSION
 declare -g BOARD_ID="89.0" # MC34
 declare -gi UPDATE_SWITCH=1 # set to 0 to disable automatic self-update
@@ -33,28 +35,32 @@ print_help() {
   debug "${FUNCNAME[0]}()"
 
   cat <<-EOF
+		SEE:
+		  README.md for more information
+
 		USAGE:
 		  installJRMC [[OPTION] [VALUE]]...
 
-		  If no options (excluding -d or --debug) are provided installJRMC defaults to '--install repo'.
+		  installJRMC defaults to --install=repo on platforms with a JRiver repository and --install=local on all others.
+		  Specifying --build, --createrepo, --service, or --uninstall disables the default install method.
 
 		OPTIONS
 		  --install, -i repo|local
 		    repo: Install MC from repository, updates are handled by the system package manager
-		    local: Build and install MC package locally from official source release
+		    local: Build and install MC locally from official source package
 		  --build[=suse|fedora|centos]
 		    Build RPM from source DEB but do not install
 		    Optionally, specify a target distro for cross-building (ex. --build=suse, note the '=')
 		  --compat
 		    Build/install MC locally without minimum dependency version requirements
 		  --mcversion VERSION
-		    Specify the MC version, ex. "$MC_VERSION" or "${MC_VERSION%%.*}"
+		    Specify the MC version, ex. "$MC_VERSION" or "${MC_VERSION%%.*}" (default: latest release)
 		  --arch VERSION
 		    Specify the target MC architecture, ex. "amd64", "arm64", etc (default: host)
 		  --mcrepo REPO
 		    Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: auto)
 		  --outputdir PATH
-		    Generate rpmbuild output in this directory (default: ./output)
+		    Generate reusable installJRMC output in this PATH (default: ./output)
 		  --restorefile MJR_FILE
 		    Restore file location for automatic license registration
 		  --betapass PASSWORD
@@ -80,7 +86,7 @@ print_help() {
 		  --yes, -y, --auto
 		    Assume yes response to questions
 		  --version, -v
-		    Print this script version and exit
+		    Print installJRMC version and exit
 		  --debug, -d
 		    Print debug output
 		  --help, -h
@@ -99,16 +105,12 @@ print_help() {
 		    Enable and start a new Xvnc session running JRiver Media Center
 		    --vncpass PASSWORD
 		      Set the vnc password for x11vnc/Xvnc access. If no password is set, installJRMC
-		      will either use existing password stored in \$HOME/.vnc/jrmc_passwd or use no password
+		      will either use existing password stored in \$HOME/.vnc/jrmc_passwd or else no password
 		    --display DISPLAY
 		      Display to use for x11vnc/Xvnc (default: The current display (x11vnc) or the
 		      current display incremented by 1 (Xvnc))
 		  jriver-createrepo (system)
 		    Install hourly service to build latest MC RPM and run createrepo
-
-		CONTAINERS (TODO: Under construction)
-		  mediacenter-xvnc
-		  createrepo
 	EOF
 }
 
@@ -134,8 +136,7 @@ parse_input() {
     eval set -- "$input"
     while true; do
       case $1 in
-        --install|-i)
-          shift
+        --install|-i) shift;
           case $1 in
             local|rpm|deb) BUILD_SWITCH=1 LOCAL_INSTALL_SWITCH=1 ;;
             repo|remote) REPO_INSTALL_SWITCH=1 ;;
@@ -151,11 +152,11 @@ parse_input() {
           if [[ $1 =~ ^([0-9]+)(\.[0-9]+\.[0-9]+)?(-([0-9]+))?$ ]]; then
             # Major version is required
             USER_MC_MVERSION="${BASH_REMATCH[1]}"
-            # If we get the full version, use it
-            [[ -n ${BASH_REMATCH[2]} ]] && USER_MC_VERSION="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
             # Set default release to 1 if not provided
             USER_MC_RELEASE="${BASH_REMATCH[4]:-1}"
-            
+            # If we get the full version, use it
+            [[ -n ${BASH_REMATCH[2]} ]] && USER_MC_VERSION="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
+
             # Set major version defaults
             case "$USER_MC_MVERSION" in
               34) MC_VERSION="${USER_MC_VERSION:-$MC_VERSION}" MC_REPO="bookworm" BOARD_ID="89.0" ;;
@@ -181,7 +182,7 @@ parse_input() {
           ;;
         --arch) shift; USER_ARCH="$1" ;;
         --mcrepo) shift; USER_MC_REPO="$1" ;;
-        --restorefile) shift; MJR_FILE="$1" ;;
+        --restorefile) shift; MJR_FILE="$1"; [[ -f $MJR_FILE ]] || err "Specified license $MJR_FILE missing." ;;
         --betapass) shift; BETAPASS="$1" ;;
         --service-type) shift; SERVICE_TYPE="$1" ;;
         --service|-s|--services) shift; SERVICES+=("$1") ;;
@@ -207,12 +208,11 @@ parse_input() {
     err "Incorrect option provided, see installJRMC --help"; exit 1
   fi
 
-  # Fallback to default install method in some scenarios
-  if ! ((UNINSTALL_SWITCH + BUILD_SWITCH + CREATEREPO_SWITCH + 
-    LOCAL_INSTALL_SWITCH + CONTAINER_INSTALL_SWITCH + SNAP_INSTALL_SWITCH +
-    APPIMAGE_INSTALL_SWITCH)) &&
-    [[ ${#SERVICES[@]} -eq 0 && ${#CONTAINERS[@]} -eq 0 ]]; then
-    debug "Automatically using --install=repo"
+  # Set some default conditions
+  if ! ((UNINSTALL_SWITCH || BUILD_SWITCH || CREATEREPO_SWITCH || LOCAL_INSTALL_SWITCH
+  || CONTAINER_INSTALL_SWITCH || SNAP_INSTALL_SWITCH || APPIMAGE_INSTALL_SWITCH)) &&
+  [[ ${#SERVICES[@]} -eq 0 && ${#CONTAINERS[@]} -eq 0 ]]; then
+    debug "Defaulting to --install=repo"
     REPO_INSTALL_SWITCH=1
   fi
 
@@ -220,16 +220,12 @@ parse_input() {
     echo "Warning: not all repositories have beta channels"
     echo "If the MC package is unavailable, try using --mcrepo to select another repository"
   fi
-
-  # if [[ -n $CONTAINER_INSTALL_SWITCH ]] && ((LOCAL_INSTALL_SWITCH || REPO_INSTALL_SWITCH)); then
-  #   err "Some --install methods are incompatible"
-  # fi
 }
 
 # @description Perform OS detection and generate OS-specific functions
 # @see parse_input
 init() {
-  debug "${FUNCNAME[0]}()"
+  debug "${FUNCNAME[0]}()" "$@"
   declare -g USER
   declare -g SCRIPT_PATH; SCRIPT_PATH=$(readlink -f "${BASH_SOURCE[0]}")
   declare -g SCRIPT_DIR; SCRIPT_DIR=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
@@ -241,20 +237,18 @@ init() {
   declare -ga PKG_INSTALL PKG_REMOVE PKG_UPDATE PKG_QUERY
   declare -ga SERVICES CONTAINERS
 
+  parse_input "$@"
+
   # Try to save users from themselves
-  if ((EUID == 0)); then
+  if [[ $EUID -eq 0 ]]; then
     err "Running as root but attempting to continue"
-    ask_ok "Continue as root user?" || exit 1
-  fi
-
-  if [[ -n $SUDO_USER ]]; then
+    ask_ok "Continue as root user (not recommended)?" || exit 1
+  elif [[ -n $SUDO_USER ]]; then
     err "Sudo detected, installJRMC should not be run with sudo but attempting to continue"
     ask_ok "Continue as user $SUDO_USER (unsupported and may result in permission issues)?" || exit 1
     USER="${SUDO_USER:-$USER}"
   fi
 
-  parse_input "$@"
-
   # Run the self-updater if enabled
   ((UPDATE_SWITCH)) && update "$@"
 
@@ -293,7 +287,7 @@ init() {
     raspbian) ID="debian" ;;
     manjaro|arch) ID="arch"
       if ((REPO_INSTALL_SWITCH)); then
-        debug "Automatically using --install=local for SUSE"
+        debug "Automatically using --install=local for Arch"
         REPO_INSTALL_SWITCH=0
         BUILD_SWITCH=1
         LOCAL_INSTALL_SWITCH=1
@@ -384,7 +378,7 @@ init() {
   fi
   MC_REPO="${USER_MC_REPO:-$MC_REPO}" # allow user override
 
-  echo "MC target: $MC_REPO $MC_ARCH -> $BUILD_TARGET $ARCH"
+  echo "MC source -> target: $MC_REPO $MC_ARCH -> $BUILD_TARGET $ARCH"
 
   # Retrieves the latest MC version number if we need it
   if ((BUILD_SWITCH || LOCAL_INSTALL_SWITCH || CREATEREPO_SWITCH)); then
@@ -433,7 +427,7 @@ get_latest_mc_version() {
     err "Warning! Using hardcoded version number"
   fi
     
-  echo "Determined MC version $MC_VERSION from the $MC_REPO repo (via $mc_version_source)"
+  echo "Selected MC version $MC_VERSION from the $MC_REPO repo (via $mc_version_source)"
 }
 
 # @description Installs a package using the system package manager
@@ -449,6 +443,7 @@ install_package() {
   local input pkg _pkg
   local -i no_install_check=0 allow_downgrades=0 silent=0 refresh=0 no_gpg_check=0 reinstall=0
   local long_opts="no-install-check,allow-downgrades,no-gpg-check,refresh,reinstall,silent"
+  local -a pkg_install=("${PKG_INSTALL[@]}")
 
   input=$(getopt -o +s -l "$long_opts" -- "$@") || { err "Incorrect options provided"; exit 1; }
   eval set -- "$input"
@@ -482,27 +477,20 @@ install_package() {
 
   # Filter out already installed packages to create pkg_array
   for pkg in "$@"; do
+    # Use alias if present, otherwise just pkg itself
+    pkg_names=("$pkg")
     if [[ -v pkg_aliases[$pkg] ]]; then
       debug "Aliasing $pkg to ${pkg_aliases[$pkg]}"
-      IFS=' ' read -ra pkgs <<< "${pkg_aliases[$pkg]}"
-      for _pkg in "${pkgs[@]}"; do
-        if ((no_install_check)) ||
-        ! { command -v "$_pkg" &>/dev/null ||
-        "${PKG_QUERY[@]}" "$_pkg" &>/dev/null; }; then
-          pkg_array+=("$_pkg")
-        else
-          debug "$_pkg is already installed, skipping installation"
-        fi
-      done
-    else
-      if ((no_install_check)) ||
-      ! { command -v "$pkg" &>/dev/null ||
-      "${PKG_QUERY[@]}" "$pkg" &>/dev/null; }; then
-        pkg_array+=("$pkg")
+      IFS=' ' read -ra pkg_names <<< "${pkg_aliases[$pkg]}"
+    fi
+    for p in "${pkg_names[@]}"; do
+      if (( no_install_check )) ||
+      ! { command -v "$p" &>/dev/null || "${PKG_QUERY[@]}" "$p" &>/dev/null; }; then
+        pkg_array+=("$p")
       else
-        debug "$pkg is already installed, skipping installation"
+        debug "$p is already installed, skipping installation"
       fi
-    fi
+    done
   done
 
   # Generate installation flags based on the distribution
@@ -514,17 +502,18 @@ install_package() {
       ((allow_downgrades)) && install_flags+=(--allowerasing)
       ((no_gpg_check)) && install_flags+=(--nogpgcheck)
       ((refresh)) && install_flags+=(--refresh)
-      # if ((reinstall)) && [[ ${#pkg_array[@]} -eq 1 ]] && "${PKG_QUERY[@]}" "${pkg_array[0]}" &>/dev/null; then
-      #   PKG_INSTALL=("${PKG_INSTALL[@]/install/reinstall}")
-      # fi
+      # Only add reinstall flag for mediacenter package
+      if ((reinstall)) && [[ ${#pkg_array[@]} -eq 1 ]] && "${PKG_QUERY[@]}" "mediacenter$MC_MVERSION" &>/dev/null; then
+        pkg_install=("${pkg_install[@]/install/reinstall}")
+      fi
       ;;
     suse)
       ((no_gpg_check)) && install_flags+=(--allow-unsigned-rpm) ;;
   esac
 
-  # Install packages if any need installation
+  # Install packages
   if [[ ${#pkg_array[@]} -gt 0 ]]; then
-    if ! execute "${PKG_INSTALL[@]}" "${install_flags[@]}" "${pkg_array[@]}"; then     
+    if ! execute "${pkg_install[@]}" "${install_flags[@]}" "${pkg_array[@]}"; then     
       ((silent)) || err "Failed to install ${pkg_array[*]}"
       return 1
     fi
@@ -568,10 +557,8 @@ install_external_repos() {
         install_package --no-install-check \
           "https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$VERSION_ID.noarch.rpm"
       fi
-      # Install mesa-va-drivers-freeworld separately from the RPM using dnf swap
-      install_mesa_freeworld
       ;;
-    suse) : # TODO may be needed if X11_XOrg is unavailable in default repos
+    suse) : # TODO may be needed if X11_XOrg is made unavailable in default repos
       # if ! zypper repos | grep -q "X11_XOrg"; then
       #   echo "Installing the X11 repository"
       #   execute sudo zypper  --non-interactive --quiet addrepo \
@@ -582,22 +569,26 @@ install_external_repos() {
   esac
 }
 
-# @description Installs mesa-va-drivers-freeworld
+# @description Installs mesa-va-drivers-freeworld on Fedora
 install_mesa_freeworld() {
   debug "${FUNCNAME[0]}()"
   local pkg freeworld_pkg
-  for pkg in mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers; do
-    freeworld_pkg="${pkg}-freeworld"
-    if ! "${PKG_QUERY[@]}" "$freeworld_pkg" &>/dev/null; then
-      if "${PKG_QUERY[@]}" "$pkg" &>/dev/null; then
-        if ! execute sudo dnf swap -y "$pkg" "$freeworld_pkg"; then
-          err "Package swap failed for $pkg!"
+  case $ID in
+    fedora)
+      for pkg in mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers; do
+        freeworld_pkg="${pkg}-freeworld"
+        if ! "${PKG_QUERY[@]}" "$freeworld_pkg" &>/dev/null; then
+          if "${PKG_QUERY[@]}" "$pkg" &>/dev/null; then
+            if ! execute sudo dnf swap -y "$pkg" "$freeworld_pkg"; then
+              err "Package swap failed for $pkg!"
+            fi
+          else
+            "${PKG_INSTALL[@]}" "$freeworld_pkg"
+          fi
         fi
-      else
-        "${PKG_INSTALL[@]}" "$freeworld_pkg"
-      fi
-    fi
-  done
+      done
+      ;;
+  esac
 }
 
 # @description Installs JRiver Media Center from a remote repository
@@ -627,7 +618,7 @@ install_mc_repo() {
           repo_file="/etc/apt/sources.list.d/jriver.sources"
         fi
 
-        # Remove old repo
+        # Remove deprecated repo files
         old_repo_files=(
           "/etc/apt/sources.list.d/jriver.list"
           "/etc/apt/sources.list.d/jriver-beta.list"
@@ -642,9 +633,9 @@ install_mc_repo() {
 					Types: deb
 					URIs: https://dist.jriver.com/$channel/mediacenter/
 					Signed-By: $keyfile
-					Suites: $MC_REPO trixie bookworm bullseye oracular noble jammy focal
+					Suites: $MC_REPO
 					Components: main
-					Architectures: amd64 i386 armhf arm64
+					Architectures: amd64 armhf arm64
 				EOF
       else
         if [[ $channel == "beta" ]]; then
@@ -653,7 +644,7 @@ install_mc_repo() {
         else
           repo_file="/etc/apt/sources.list.d/jriver.list"
         fi
-        repo_text="deb [signed-by=$keyfile arch=amd64,i386,armhf,arm64] https://dist.jriver.com/$channel/mediacenter/ $MC_REPO main"
+        repo_text="deb [signed-by=$keyfile arch=amd64,armhf,arm64] https://dist.jriver.com/$channel/mediacenter/ $MC_REPO main"
       fi
       echo "Installing JRiver Media Center GPG key"
       download "https://dist.jriver.com/mediacenter@jriver.com.gpg.key" "-" | 
@@ -666,12 +657,24 @@ install_mc_repo() {
       ;;
   esac
 
+  if [[ -f $repo_file ]]; then
+    ask_ok "Replace existing $repo_file repository file" && execute sudo rm -f "$repo_file" 
+  fi
+
   echo "Adding MC repository file: $repo_file"
-  debug "repo_text: $repo_text"
+  debug "$repo_text"
   sudo tee "$repo_file" &>/dev/null <<< "$repo_text"
 
+  # Add older repository for libwebkit2gtk-4.0-37, etc, on newer Debian/Ubuntu
+  if add_temp_repo; then
+    trap 'execute sudo rm -f "$TEMP_REPO_FILE"' EXIT
+  else
+    err "Failed to add temporary repository"
+    return 1
+  fi
   "${PKG_UPDATE[@]}" || { err "Package update failed!"; return 1; }
 
+  echo "Installing $MC_PKG package"
   if ! install_package \
     --no-install-check \
     --allow-downgrades \
@@ -681,6 +684,11 @@ install_mc_repo() {
     err "Package install failed!"
     return 1
   fi
+
+  # Unset the trap and remove temporary legacy repository
+  trap - EXIT
+  [[ -f $TEMP_REPO_FILE ]] && execute sudo rm -f "$TEMP_REPO_FILE"
+  return 0
 }
 
 # @description Acquires the source DEB package from JRiver
@@ -815,7 +823,9 @@ build_rpm() {
       requires=("${requires[@]/python/python3}")
       requires=("${requires[@]/libwebkit2gtk-4.0*/webkit2gtk4.0}")
       requires=("${requires[@]/libwebkit2gtk-4.1*/webkit2gtk4.1}")
-      recommends+=(mesa-va-drivers-freeworld)
+      recommends+=("mesa-va-drivers-freeworld|mesa-va-drivers")
+      recommends+=("mesa-vulkan-drivers-freeworld|mesa-vulkan-drivers")
+      recommends+=("mesa-vdpau-driver-freeworld|mesa-vdpau-driver")
       ;;
     suse)
       requires=("${requires[@]/python*/python313}")
@@ -912,7 +922,7 @@ build_rpm() {
 	EOF
 
   # Run rpmbuild
-  echo "Building MC $MC_VERSION RPM, this may take some time"
+  echo "Building $MC_RPM, this may take some time"
   rpmbuild_cmd=(
     rpmbuild 
       --define="_topdir $OUTPUT_DIR" 
@@ -925,15 +935,20 @@ build_rpm() {
     echo "Build successful. The RPM file is located at: $MC_RPM"
   else
     err "Build failed"
-    # After failire, remove the source DEB and reaquire it on next run
-    [[ -f $MC_DEB ]] && echo "Removing source DEB" && execute sudo rm -f "$MC_DEB"
-    exit 1
+    # After failure, remove the source DEB and reaquire it on next run
+    if [[ -f $MC_DEB ]]; then
+      echo "Removing source DEB"
+      if ! execute rm -f "$MC_DEB"; then
+        execute sudo rm -f "$MC_DEB"
+      fi
+    fi
+    return 1
   fi
 }
 
 # @description Installs Media Center via DEB package w/ optional compatability fixes
 install_mc_deb() {
-  debug "${FUNCNAME[0]}()"  
+  debug "${FUNCNAME[0]}()" "$@"
 
   if ((COMPAT_SWITCH)); then
     local extract_dir; extract_dir="$(mktemp -d)"
@@ -959,44 +974,14 @@ install_mc_deb() {
     execute rm -rf "$extract_dir"
   fi
 
-  # Helper function to add repository
-  add_temp_repo() {
-    local repo_name="$1"
-    local repo_uri="$2"
-    local repo_suite="$3"
-    local repo_key="$4"
-    declare -g TEMP_REPO_FILE="/etc/apt/sources.list.d/${repo_name}.sources"
-
-    echo "Creating temporary repository file $TEMP_REPO_FILE for $repo_suite"
-    sudo bash -c "cat <<-EOF > $TEMP_REPO_FILE
-			Types: deb
-			URIs: $repo_uri
-			Suites: $repo_suite
-			Components: main
-			Architectures: $MC_ARCH
-			Signed-By: $repo_key
-		EOF"
-    "${PKG_UPDATE[@]}" || { err "Package update failed!"; return 1; }
-  }
-
   # Add older repository for libwebkit2gtk-4.0-37, etc, on newer Debian/Ubuntu
-  local -i remove_temp_repo=0
-  if [[ "$ID" == "ubuntu" ]]; then
-    local major_version="${VERSION_ID%%.*}"
-    local minor_version="${VERSION_ID##*.}"
-    if [[ $major_version -gt 24 || ($major_version == 24 && minor_version -ge 4) ]]; then
-      echo "Temporarily adding jammy repository for libwebkit2gtk-4.0-37, etc."
-      remove_temp_repo=1
-      add_temp_repo "jammy" "https://archive.ubuntu.com/ubuntu" "jammy" "/usr/share/keyrings/ubuntu-archive-keyring.gpg"
-    fi
-  elif [[ "$ID" == "debian" ]]; then
-    local major_version="${VERSION_ID%%.*}"
-    if [[ $major_version -ge 13 || -z $major_version ]]; then
-      echo "Temporarily adding bookworm repository for libwebkit2gtk-4.0-37, etc."
-      remove_temp_repo=1
-      add_temp_repo "bookworm" "https://deb.debian.org/debian" "bookworm" "/usr/share/keyrings/debian-archive-keyring.gpg"
-    fi
+  if add_temp_repo; then
+    trap 'execute sudo rm -f "$TEMP_REPO_FILE"' EXIT
+  else
+    err "Failed to add temporary repository"
+    return 1
   fi
+  "${PKG_UPDATE[@]}" || { err "Package update failed!"; return 1; }
 
   # Copy the DEB to a temporary file so _apt can read it
   debug "Creating temporary deb file owned by _apt"
@@ -1013,16 +998,17 @@ install_mc_deb() {
     --reinstall \
     "$temp_deb"; then
     err "Local MC DEB installation failed"
-    ((remove_temp_repo)) && { echo "Removing temporary repo"; execute sudo rm -f "$TEMP_REPO_FILE"; }
     if ask_ok "Remove source DEB and retry"; then
       execute sudo rm -f "$MC_DEB" "$temp_deb"
       exec "$SCRIPT_PATH" "$@" "--no-update"
     fi
   fi
 
-  # Cleanup temporary repository and temporary DEB file
-  ((remove_temp_repo)) && { echo "Removing temporary repo"; execute sudo rm -f "$TEMP_REPO_FILE"; }
+  # Unset the trap and remove temporary legacy repository
+  trap - EXIT
+  [[ -f $TEMP_REPO_FILE ]] && execute sudo rm -f "$TEMP_REPO_FILE"
   execute sudo rm -f "$temp_deb"
+  return 0
 }
 
 # @description Installs MC via RPM package
@@ -1111,7 +1097,6 @@ install_mc_arch() {
 # @description Copy the RPM to createrepo-webroot and run createrepo as the createrepo-user
 run_createrepo() {
   debug "${FUNCNAME[0]}()"
-  local -a cr_cmd
 
   install_package createrepo_c
 
@@ -1136,15 +1121,10 @@ run_createrepo() {
   fi
 
   # Run createrepo
-  cr_cmd=(sudo -u "$CREATEREPO_USER" createrepo -q "$CREATEREPO_WEBROOT")
-  [[ -d $CREATEREPO_WEBROOT/repodata ]] && cr_cmd+=(--update)
-  
-  if ! execute "${cr_cmd[@]}"; then
-    cr_cmd=(sudo createrepo -q "$CREATEREPO_WEBROOT")
-    [[ -d $CREATEREPO_WEBROOT/repodata ]] && cr_cmd+=(--update)
-    
-    if ! (execute "${cr_cmd[@]}" ||
-    execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"); then
+  local -a cr_opts=(-q "$CREATEREPO_WEBROOT")
+  # [[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_opts+=(--update) # TODO temporarily disabled for legacy createrepo
+  if ! execute sudo -u "$CREATEREPO_USER" createrepo "${cr_opts[@]}"; then
+    if ! (execute sudo createrepo "${cr_opts[@]}" && execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"); then
       err "createrepo failed"
       return 1
     fi
@@ -1207,7 +1187,12 @@ restore_license() {
 
     for f in "$MJR_FILE" "$newest"; do
       if [[ -f $f ]]; then
-        execute "mediacenter$MC_MVERSION" "/RestoreFromFile" "$f"
+        if execute "mediacenter$MC_MVERSION" "/RestoreFromFile" "$f"; then
+          echo "Restored license from $f"
+          return 0
+        else
+          err "Failed to restore license from $f"
+        fi
       fi
     done
   fi
@@ -1534,7 +1519,7 @@ service_jriver-createrepo() {
 		[Service]
 		$USER_STRING
 		ExecStart=$SCRIPT_DIR/installJRMC --outputdir=$OUTPUT_DIR --createrepo=$CREATEREPO_TARGET \
-      --createrepo-webroot=$CREATEREPO_WEBROOT --createrepo-user=$CREATEREPO_USER --yes --no-update
+      --createrepo-webroot=$CREATEREPO_WEBROOT --createrepo-user=$CREATEREPO_USER --mcrepo=$MC_REPO --yes --no-update
 
 		[Install]
 		WantedBy=multi-user.target
@@ -1559,17 +1544,15 @@ service_jriver-createrepo() {
 # @description Detects if MC is installed on btrfs and disables CoW
 disable_btrfs_cow() {
   debug "${FUNCNAME[0]}()"
-  local dir 
   local mc_user_path="$HOME/.jriver"
+  [[ -d "$mc_user_path" ]] || execute mkdir -p "$mc_user_path"
 
-  for dir in "$MC_ROOT" "$mc_user_path"; do
-    [[ -d $mc_user_path ]] || execute mkdir -p "$mc_user_path"
-    if [[ $(stat -f -c %T "$dir") == "btrfs" ]] &&
-    ! lsattr -d "$dir" | cut -f1 -d" " | grep -q C &&
-    execute sudo chattr +C "$dir"; then
-      echo "Disabled btrfs CoW for $dir directory"
+  # Disable btrfs CoW
+  if [[ $(stat -f -c %T "$mc_user_path") == "btrfs" ]]; then
+    if execute chattr -R +C "$mc_user_path"; then
+      echo "Disabled btrfs CoW for $mc_user_path"
     fi
-  done
+  fi
 }
 
 # @description Completely uninstalls MC, services, and firewall rules
@@ -1577,6 +1560,11 @@ uninstall() {
   debug "${FUNCNAME[0]}()"
   local service type unit f
 
+  if ! ask_ok "Do you really want to uninstall JRiver Media Center?"; then
+    echo "Uninstall cancelled"
+    return 1
+  fi
+
   echo "Stopping and removing all Media Center services"
   for service in $(compgen -A "function" "service"); do
     service="${service##service_}"
@@ -1595,13 +1583,15 @@ uninstall() {
     done
   done
 
-  echo "Removing MC repositories"
-  execute sudo rm -rf \
-    "/etc/yum.repos.d/jriver.repo" \
-    /etc/apt/sources.list.d/{jriver,mediacenter}*.{list,sources} # also remove legacy repo files
+  # Remove the repository files
+  for file in "/etc/yum.repos.d/jriver.repo" /etc/apt/sources.list.d/{jriver,mediacenter}*.{list,sources}; do
+    if [[ -e $file ]]; then
+      echo "Removing repository file: $file"
+      execute sudo rm -f "$file"
+    fi
+  done
 
-  [[ $ID == "suse" ]] &&
-    execute sudo zypper --non-interactive removerepo jriver
+  [[ $ID == "suse" ]] && execute sudo zypper --non-interactive removerepo jriver
 
   echo "Removing firewall rules"
   for service in jriver-mediacenter jriver-xvnc jriver-x11vnc; do
@@ -1616,18 +1606,21 @@ uninstall() {
     fi
   done
 
-  echo "Uninstalling JRiver Media Center package"
+  echo "Uninstalling the JRiver Media Center package"
   if "${PKG_REMOVE[@]}" "${MC_PKG%%=*}"; then # remove version specifier
-    echo "JRiver Media Center has been completely uninstalled"
+    echo "Successfully uninstalled the ${MC_PKG%%=*} package"
   elif [[ $? -eq 100 ]]; then
     err "JRiver Media Center package '${MC_PKG%%=*}' is not present and was not uninstalled"
   else
     err "Could not remove Media Center package"
   fi
 
-  echo "Uninstalling JRiver Media Center GPG key"
+  # Remove the JRiver GPG keyfile
   local keyfile="/usr/share/keyrings/jriver-com-archive-keyring.gpg"
-  [[ -f $keyfile ]] && execute sudo rm -f "$keyfile"
+  if [[ -f $keyfile ]]; then
+    echo "Removing the JRiver Media Center GPG key"
+    execute sudo rm -f "$keyfile"
+  fi
 
   if [[ -f $SCRIPT_DIR/.uninstall ]]; then
     echo "Removing files from .uninstall log"
@@ -1637,9 +1630,28 @@ uninstall() {
     mv "$SCRIPT_DIR/.uninstall" "$SCRIPT_DIR/.uninstall.bk"
   fi
 
-  echo "To remove installJRMC output: rm -rf $OUTPUT_DIR"
-  echo "To remove your MC library: rm -rf $HOME/.jriver"
-  return 0
+  if [[ -d $OUTPUT_DIR ]]; then
+    if ask_ok "Remove installJRMC output directory $OUTPUT_DIR?"; then
+      execute sudo rm -rf "$OUTPUT_DIR"
+    fi
+  fi
+
+  if [[ -d $MC_ROOT ]]; then
+    if ask_ok "Remove MC installation directory $MC_ROOT?"; then
+      execute sudo rm -rf "$MC_ROOT"
+    fi
+  fi
+
+  if [[ -d $HOME/.jriver ]]; then
+    if ask_ok "Backup and reset your MC library?"; then
+      execute mv "$HOME/.jriver" "$HOME/.jriver.bk"
+      echo "Your MC library has been backed up to $HOME/.jriver.bk and reset"
+      echo "To restore your MC library backup: mv $HOME/.jriver.bk $HOME/.jriver"
+      return
+    fi
+    echo "To backup and reset your MC library: mv $HOME/.jriver $HOME/.jriver.bk"
+    echo "To remove your MC library: rm -rf $HOME/.jriver"
+  fi
 }
 
 # @description Checks for installJRMC update and re-executes, if necessary
@@ -1728,9 +1740,10 @@ update() {
 
 # @description installJRMC main function
 main() {
-  debug "${FUNCNAME[0]}()" "$@"
+  debug "${FUNCNAME[0]}()" "$@" # prints function name and arguments
 
   echo "Starting installJRMC $SCRIPT_VERSION"
+
   if ((DEBUG)); then
     echo "Debugging on"
   else
@@ -1740,13 +1753,13 @@ main() {
   # Parse input, set default/host variables, and MC version
   init "$@"
 
-  if ((UNINSTALL_SWITCH)); then
-    if ask_ok "Do you really want to uninstall JRiver Media Center?"; then
-      uninstall
-    else
-      echo "Uninstall canceled"
-    fi
-    exit
+  ((UNINSTALL_SWITCH)) && uninstall
+
+  # Exit now if only --uninstall is passed
+  if ! (( BUILD_SWITCH || CREATEREPO_SWITCH || REPO_INSTALL_SWITCH || LOCAL_INSTALL_SWITCH ||
+  CONTAINER_INSTALL_SWITCH || SNAP_INSTALL_SWITCH || APPIMAGE_INSTALL_SWITCH )) &&
+  [[ ${#SERVICES[@]} -eq 0 && ${#CONTAINERS[@]} -eq 0 ]]; then
+    exit 0
   fi
 
   install_external_repos
@@ -1755,6 +1768,7 @@ main() {
     echo "Installing JRiver Media Center from remote repository"
     if install_mc_repo; then
       echo "JRiver Media Center installed successfully from remote repository"
+      install_mesa_freeworld
       link_ssl_certs
       restore_license
       open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp"
@@ -1776,12 +1790,14 @@ main() {
   fi
 
   if ((LOCAL_INSTALL_SWITCH)); then
+    echo "Installing JRiver Media Center from local package"
     if PKG_INSTALL_LOCAL "$@"; then
       echo "JRiver Media Center installed successfully from local package"
     else
       err "JRiver Media Center local package installation failed"
       return 1
     fi
+    install_mesa_freeworld
     link_ssl_certs
     restore_license
     open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp"
@@ -1877,6 +1893,51 @@ create_mc_apt_container() {
     sudo buildah run "$CNT" -- sh -c "$cmd" || { err "$cmd failed"; return 1; }
   done
 }
+add_temp_repo() {
+  debug "${FUNCNAME[0]}()"
+  local repo_name repo_uri repo_suite repo_key
+
+  if [[ "$ID" == "ubuntu" ]]; then
+    local major_version="${VERSION_ID%%.*}"
+    local minor_version="${VERSION_ID##*.}"
+    minor_version="${minor_version#0}"  # strip leading zero
+    if [[ $major_version -gt 24 || ( $major_version -eq 24 && minor_version -ge 4 ) ]]; then
+      echo "Temporarily adding jammy repository for libwebkit2gtk-4.0-37, etc."
+      repo_name="ubuntu-jammy-temp"
+      repo_uri="https://archive.ubuntu.com/ubuntu"
+      repo_suite="jammy"
+      repo_key="/usr/share/keyrings/ubuntu-archive-keyring.gpg"
+    else
+      return 0
+    fi
+  elif [[ "$ID" == "debian" ]]; then
+    local major_version="${VERSION_ID%%.*}"
+    if [[ $major_version -ge 13 ]]; then
+      echo "Temporarily adding bookworm repository for libwebkit2gtk-4.0-37, etc."
+      repo_name="debian-bookworm-temp"
+      repo_uri="https://deb.debian.org/debian"
+      repo_suite="bookworm"
+      repo_key="/usr/share/keyrings/debian-archive-keyring.gpg"
+    else
+      return 0
+    fi
+  else
+    # For other distributions, do nothing.
+    return 0
+  fi
+
+  declare -g TEMP_REPO_FILE="/etc/apt/sources.list.d/${repo_name}.sources"
+
+  echo "Creating temporary repository file $TEMP_REPO_FILE for $repo_suite"
+  sudo bash -c "cat <<-EOF > $TEMP_REPO_FILE
+		Types: deb
+		URIs: $repo_uri
+		Suites: $repo_suite
+		Components: main
+		Architectures: $MC_ARCH
+		Signed-By: $repo_key
+	EOF"
+}
 
 # Roughly turn debugging on for pre-init
 # Reset and reparse in parse_input() with getopt