#!/bin/bash
# getvirtualbox
#
# Purpose: install the latest VirtualBox into PCLinuxOS 
# 
# Requirements: 
#  - PCLinuxOS installation 
#  - working apt-get & Internet connection (not for removal)
#  - zenity, wget, libpython-devel
#
# Version: 7.2.4 (2025-10-23) by pinoc <vogtpet@gmail.com>
#############################################################
# Copyright (C) 2025 Bill Reynolds <texstar@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# define some variables
#=================================================
export SKIP_STACK_VALIDATION=1
export TEXTDOMAIN=getvirtualbox
export TEXTDOMAINDIR="/usr/share/locale"
export LC_NUMERIC="en_US.UTF-8"
XUAL=/tmp/xgetvirtualbox; 
WICON='/usr/share/pixmaps/getvirtualbox.png' 
ZEN2="/usr/bin/zenity --window-icon="$WICON
sysarchext="_amd64.run"
VBversion="7.2.4"; VBext="170995"
lic_accept="eb31505e56e9b4d0fbca139104da41ac6f6b98f8e78968bdf01b1f3da3c4f9ae"
TITLE="VirtualBox Manager "$VBversion
TITLE1=$"Downloading current VirtualBox..."
TITLE2=$"Downloading current VirtualBox Extension Pack..."
package=VirtualBox-$VBversion-$VBext-Linux$sysarchext
package2=Oracle_VirtualBox_Extension_Pack-$VBversion.vbox-extpack
bsource1=http://download.virtualbox.org/virtualbox/$VBversion/
bsource2=https://dlc-cdn.sun.com/virtualbox/$VBversion/
bsource3=http://ftp.nluug.nl/os/Linux/distr/pclinuxos/pclinuxos/addlocale/LO/


#set default parameters:
VERBOSE=0
VINFO=0

#read parameters from command line
#=================================================
for i in "$@"
do
  case $i in
     --debug)
     VERBOSE=1
     ;;
     --vinfo)
     VINFO=1
     ;;
     --help)
     echo "usage: $0 --debug --vinfo"
     echo "--debug: verbose output for debugging"
     echo "--vinfo: info on installed and latest version"
     echo "--help: show options"
     exit
     ;;
     *)
     # unknown option
     echo "Error: unknown option"
     echo "usage: $0 --help"
     exit
     ;;
 esac
done

# version testing
#===========================
if [ $VINFO -eq 1 ]; then 
  v_installed=0
  if [ -f /usr/bin/vboxmanage ]; then 
   v_installed=$(virtualbox --help | awk '/Manager/' |awk -F' v' '{print $2}')
  fi
  v_new=$VBversion
  echo 'installed version: ' "$v_installed"
  echo 'current version  : ' "$v_new"
  exit 0
fi


# verbose output for debugging
#=================================================
if [ $VERBOSE -eq 1 ]; then set -xv; fi


# check for kdesu or gksu and setup /or run XUAL
#=================================================
if [ ! -e $XUAL ] && [ "$UID" != "0" ];then
  if [ -r /usr/bin/gksu ]; then WMSUDO="/usr/bin/gksu -l "; fi
  if [ -r /usr/lib/kde4/libexec/kdesu ]; then WMSUDO=/usr/lib/kde4/libexec/kdesu; fi
  if [ -r /usr/lib64/kde4/libexec/kdesu ]; then WMSUDO=/usr/lib64/kde4/libexec/kdesu; fi
  # setup XUAL
  echo "#"'!/bin/bash' > $XUAL
  if [ "$UID" != "0" ]; then echo $WMSUDO getvirtualbox >> $XUAL; else echo getvirtualbox >> $XUAL; fi
  chmod a+x $XUAL
  $XUAL &
  exit 0
fi


# Check if user is still not logged in as root
# then relaunch the script
#=================================================
if [ "$UID" != "0" ]; then
  $XUAL &
  exit 0
fi

# welcome screen
#=================================================
if [ -f /opt/VirtualBox/LICENSE ]; then
  VBOPT=$($ZEN2 --title "$TITLE" --list --text $"                         Welcome to VirtualBox Manager\!\n\nPlease select an option and press OK, or press Cancel to quit." --width 450 --height 250  --list  --radiolist  --column $"Select Option" --column $"VirtualBox Action" TRUE $"Install or upgrade, VirtualBox" FALSE $"Completely remove VirtualBox");  
  # Quit if Cancel was pressed
  #===================================================
  if [ "$VBOPT" == "" ]; then 
      $ZEN2 --title "$TITLE" --info --width=400 --text=$"You chose to exit. \nNo changes were applied to your system."
      /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
      exit 0
  fi
  
  # completely remove
  #===================================================
  if [ "$VBOPT" == $"Completely remove VirtualBox" ]; then
    MSG=$"Uninstalling VirtualBox..."
     if rpm -q virtualbox-hot-fix >/dev/null ; then rpm -e virtualbox-hot-fix ; fi
    ( cd /opt/ || exit;./VirtualBox/uninstall.sh ) 2>&1  | $ZEN2 --width 400 --title="$TITLE" --progress --no-cancel --text "$MSG" --pulsate --auto-close
    # remove leftover extension pack
    /bin/rm -fr /opt/VirtualBox /tmp/co_cancel $package $package2 $XUAL
    $ZEN2 --title "$TITLE" --info --width=400 --text=$"VirtualBox has been removed from your system."  
    exit 0
  fi
else
  MSG=$"This program will download and install \nOracle VirtualBox Non-OSE edition\!\n\nDo you wish to continue with the installation?"
  $ZEN2 --question --width 450 --title="$TITLE" --text="$MSG"
  if [ $? = 1 ];then 
    /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
    exit 0
  fi 
fi

 # check for previously installed version
#=================================================
if [ -f /opt/VirtualBox/LICENSE ]; then
  v_installed=0
  if [ -f /usr/bin/vboxmanage ]; then
    v_installed=$(virtualbox --help | awk '/Manager/' |awk -F' v' '{print $2}')
  fi

  if [ "$v_installed" == "$VBversion" ]; then
    MSG=$"Your version of Virtualbox is uptodate.  \n\nExiting.."
    $ZEN2 --info --width 450 --title="$TITLE" --text="$MSG"
     /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
    exit 0
  fi
fi

# check for working internet connection
#=================================================
cd /tmp || exit
/bin/rm -f index.html* inet.log*
MSG=$"Testing your Internet connection..."
( wget --timeout=15 http://www.google.com/index.html -o inet.log ) 2>&1 | $ZEN2 --title="$TITLE" --progress --text "$MSG" --pulsate --auto-close --no-cancel --width 300

if [ ! -f /tmp/index.html ]; then
  MSG=$"No Internet connection found.\n\nExiting..."
  $ZEN2 --title="$TITLE" --error --text "$MSG"
  /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
  exit 1
fi

# clean up and make sure no partial downloads exist in /tmp
/bin/rm -f index.html* inet.log* ./*VirtualBox* co_cancel $package $package2


# check for running vbox processes,
#=========================================================
if [ "$(ps -ef |grep -c '/opt/VirtualBox')" -gt 1 ]; then
  MSG=$"VirtualBox seems to be running right now.\nPlease close any related process, wait for 10 secs\nand then restart VirtualBox Manager.\n\nExiting..."
  $ZEN2 --title="$TITLE" --error --text "$MSG"
  exit 0
fi

# let user select vbox server for download
#=========================================================
###SSELECT=$($ZEN2 --title "$TITLE" --list --text $"Please select the download server" --width 300 --height 200  --list  --radiolist  --column $"Select" --column $"Download server" TRUE "Virtualbox" FALSE "Oracle Sun" FALSE "NLUUG");
###SSELECT=$($ZEN2 --title "$TITLE" --list --text $"Please select the download server" --width 300 --height 200  --list  --radiolist  --column $"Select" --column $"Download server" TRUE "Oracle Sun" FALSE "NLUUG");
SSELECT=$($ZEN2 --title "$TITLE" --list --text $"Please select the download server" --width 300 --height 200  --list  --radiolist  --column $"Select" --column $"Download server" TRUE "Virtualbox" FALSE "NLUUG");

# Quit if Cancel was pressed
if [ "$SSELECT" == "" ]; then 
  $ZEN2 --title "$TITLE" --info --text=$"You chose to exit. \nNo changes were applied to your system."
  /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
  exit 0
fi

if [ "$SSELECT" == "Virtualbox" ];  then bsource=$bsource1  ;fi
if [ "$SSELECT" == "Oracle Sun" ];  then bsource=$bsource2  ;fi
if [ "$SSELECT" == "NLUUG" ];  then bsource=$bsource3  ;fi
source=$bsource$package
source2=$bsource$package2


# download VirtualBox
#=================================================
cd /tmp || exit
dl_txt=$"Download speed:"; eta_txt=$"Estimated time:"; /bin/rm -f /tmp/co_cancel
SCRIPT_PID=$$
wget -nc --compression=none $source 2>&1 \
  | sed -u "s/.* \([0-9]\+%\)\ \+\([0-9.]\+.\) \(.*\)/\1\n# ${dl_txt} \\\t\\\t\2\/s\\\n${eta_txt}\\\t\\\t\3/" \
  | ( if $ZEN2 --width 600 --progress --title="$TITLE1" --auto-close; then
	echo 'Job completed'
      else
	kill "$(ps axo ucmd,pid,ppid | grep wget | awk "{ if ( \\$3 == $SCRIPT_PID ) { print \\$2 }}")"
	$ZEN2 --width 500 --title="$TITLE" --error --text=$"Download and installation canceled."
	touch /tmp/co_cancel
      fi )
if [ -e /tmp/co_cancel ];then 
  /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
  exit 1
fi


# download VirtualBox Extension Pack
#=================================================
cd /tmp || exit
dl_txt=$"Download speed:"; eta_txt=$"Estimated time:"; /bin/rm -f /tmp/co_cancel
SCRIPT_PID=$$
wget -nc --compression=none $source2 2>&1 \
  | sed -u "s/.* \([0-9]\+%\)\ \+\([0-9.]\+.\) \(.*\)/\1\n# ${dl_txt} \\\t\\\t\2\/s\\\n${eta_txt}\\\t\\\t\3/" \
  | ( if $ZEN2 --width 600 --progress --title="$TITLE2" --auto-close; then
	echo 'Job completed'
      else
	kill "$(ps axo ucmd,pid,ppid | grep wget | awk "{ if ( \\$3 == $SCRIPT_PID ) { print \\$2 }}")"
	$ZEN2 --width 500 --title="$TITLE" --error --text=$"Download and installation canceled."
	touch /tmp/co_cancel
      fi )
if [ -e /tmp/co_cancel ];then
  /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
  exit 1
fi

#make files executable
#=================================================
chmod a+x $package
chmod a+x $package2

vbold="0"
# check for previously installed version, if found uninstall it
#=================================================================
if [ -f /opt/VirtualBox/LICENSE ]; then
  MSG=$"Previous version detected. I need to uninstall\nit prior to proceeding.\n\nDo you wish to continue?"
  $ZEN2 --question --width 450 --title="$TITLE" --text="$MSG"
  if [ $? = 1 ]; then 
    /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
    exit 1
  fi
  MSG=$"Uninstalling previous VirtualBox..."
  if rpm -q virtualbox-hot-fix >/dev/null ; then rpm -e virtualbox-hot-fix ; fi
  ( cd /opt/  || exit;./VirtualBox/uninstall.sh ) 2>&1  | $ZEN2 --width 400 --title="$TITLE" --progress --no-cancel --text "$MSG" --pulsate --auto-close
  # remove leftover extension pack
  /bin/rm -fr /opt/VirtualBox
  vbold="1"
fi


# 1) run the VBox installer
#=================================================
cd /tmp || exit
./$package --nox11 2>&1 |tee /tmp/vb_install.log &
(
res=0;resinfo="#";sleep 3
while [ $res -ne 100 ]
  do
    cd /tmp || exit
    NL=$(wc -l /tmp/vb_install.log|awk '{print $1}')
    VB1done=$(< /tmp/vb_install.log grep -c 'VirtualBox has been installed successfully')
    if [ "$NL" -lt 2 ];then
      res=2; resinfo=$"# Verifying archive integrity..."
    fi
    if [ "$NL" -lt 3 ];then
      res=5; resinfo=$"Uncompressing VirtualBox..."
    fi
    if [ "$NL" -lt 5 ];then # increase indicator up to kernel modules are build
      res=$(( res + 2 )); resinfo=$"# Installing VirtualBox..."
    fi 
    if [ "$NL" -lt 6 ];then # increase indicator
      res=$(( res + 2 )); resinfo=$"# Installing VirtualBox..."
    fi
    if [  "$NL" -lt 7 ];then # increase indicator
      res=$(( res + 2 )); resinfo=$"# Installing VirtualBox..."
    fi
    if [ "$NL" -lt 9 ];then # increase indicator
      res=$(( res + 3 )); resinfo=$"# Installing VirtualBox..."
    fi
    if [ "$NL" -lt 10 ];then # increase indicator
      res=$(( res + 3 )); resinfo=$"# Installing VirtualBox..."
    fi
    
    if [ "$res" -gt 98 ];then # ensure it doesn't go over 100 before the next condition is met
      res=98; resinfo=$"# Just some more moments, please wait..."
    fi 
    if [ "$VB1done" -eq 1 ];then
      res=100;resinfo="$#Finished"
    fi
    echo "$res"; sleep 1
    echo $resinfo 2>/dev/null; sleep 1
  done
)| $ZEN2 --width 700 --progress --no-cancel --title="$TITLE" --auto-close 

if [ -e /opt/VirtualBox/postinst-common.sh ]; then 
  sed -i "28i export SKIP_STACK_VALIDATION=1" /opt/VirtualBox/postinst-common.sh
  MSG=$"Finalizing installation..."
  /opt/VirtualBox/postinst-common.sh | $ZEN2 --width 400 --title="$TITLE" --progress --no-cancel --text "$MSG" --pulsate --auto-close
fi

# check for installation failure
VB1done=$(< /tmp/vb_install.log grep -c 'VirtualBox has been installed successfully.')
if [ "$VB1done" -eq 0 ];then
  $ZEN2 --title="$TITLE" --error --text=$"Installation of VirtualBox failed."
  /bin/rm -f /tmp/co_cancel $package $package2 $XUAL
  exit 1
fi

# 2) install the VBox extension pack
#====================================
MSG=$"installing VirtualBox Extension Pack..."
( VBoxManage extpack install --replace --accept-license=$lic_accept $package2 | tee /tmp/vb_install2.log ) 2>&1  | $ZEN2 --width 400 --title="$TITLE" --progress --no-cancel --text "$MSG" --pulsate --auto-close

# check for installation failure
VB2done=$(< /tmp/vb_install2.log grep -c 'Successfully installed')
if [ "$VB2done" -eq 0 ];then
  $ZEN2 --title="$TITLE" --error --text=$"Installation of VirtualBox Extension Pack failed./nTry installing it manually."
fi


# Create usb group if it doesn't exist
#=================================================
groupadd usb


# Virtualbox installer automatically adds vboxusers group
#=================================================


# add existing users to group vboxusers and usb upon new installation
#=================================================
if [ "$vbold" -eq "0" ];then
  SYSUSERS=$(grep "[0-9][0-9][0-9]:.*/home" /etc/passwd | grep -f /etc/shells | cut -d: -f1)
  for idx in $SYSUSERS; do usermod -a -G vboxusers,usb "$idx"; done
fi

# Remove created symlink and make actual desktop file
#=================================================
if [ -f /usr/share/applications/virtualbox.desktop ]; then
  /bin/rm -rf /usr/share/applications/virtualbox.desktop 
fi

# create menu entry for PCLinuxOS
#=================================================
cat >/usr/share/applications/virtualbox.desktop << EOF
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Name=Oracle VM VirtualBox
GenericName=Virtual Machine
Type=Application
Exec=VirtualBox
TryExec=VirtualBox
DocPath=file:///opt/VirtualBox/UserManual.pdf
Icon=VBox
Categories=Emulator;System;X-MandrivaLinux-MoreApplications-Emulators;
Comment=Run several virtual systems on a single host computer
EOF


# clean up
#=================================================
cd /tmp || exit
/bin/rm -f co_cancel $package $package2 $XUAL vb_install*

# amend LD_LIBRARY_PATH for using our QT5
#=================================================
LDNEW="export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/VirtualBox"
VBOXSH='/opt/VirtualBox/VBox.sh'
pathline=$(grep -n 'PATH="/usr/bin' $VBOXSH|grep -Eo '^[^:]+')
sed -i "${pathline}i ${LDNEW}" $VBOXSH

# show the final info of the installation log-file 
# to let the user know about the VBox documentation
# add info to reboot
MSG=$"               <span color='blue'><b>VirtualBox is now installed.</b></span>\n\nYou will find useful information about using VirtualBox\n\nin the user manual:\n        /opt/VirtualBox/UserManual.pdf\n\nand in the user FAQ:\n        http://www.virtualbox.org/wiki/User_FAQ\n\n<span color='red'><b>IMPORTANT:</b></span>\n<span color='red'><b>Please reboot so the proper kernel drivers can load\!</b></span>\n\nHave fun\!"
$ZEN2 --title="$TITLE" --info --width=500 --text "$MSG" #--timeout 6 


exit 0
