#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
#
# Install VirtualBox Linux Guest Additions
#
# Copyright (c) 2016, Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope 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.
#
# Authors:
# 	Miguel Bernal Marin <miguel.bernal.marin@linux.intel.com>

IS_DIALOG=0
VBOXGA_FOUND=0

TMPDIR=$(mktemp -d)

# Developed againts VirtualBox 5.1.2 Guest Additions installer image

die ()
{
    TITLE="$1"
    shift
    MSG="$*"
    if [ ${IS_DIALOG} -eq 1 ] ; then
        dialog --title "${TITLE}" --msgbox "${MSG}" 0 0
    else
        echo "ERROR: ${TITLE}" >&2
        echo "${MSG}" >&2
    fi
    exit 1
}

check_dialog ()
{
    if dialog &> /dev/null; then
        IS_DIALOG=1
    fi
}

check_root_user ()
{
    if [ $UID -ne 0 ] ; then
        die "NO ROOT USER" "You must be root to execute this script"
    fi
}

check_kernel ()
{
    if [ ! -f /usr/share/clear/bundles/kernel-lts ] ; then
        die "NO KERNEL-LTS BUNDLE FOUND" \
        "Please use:

        swupd bundle-add kernel-lts

        To install kernel-lts bundle."
    fi
    if ! uname -r | grep lts &> /dev/null; then
        die "NO LTS KERNEL FOUND" \
        "Please use LTS kernel to support virtualbox modules."
    fi
    if ! modprobe vboxsf &> /dev/null; then
        die "VBOX KERNEL MODULES NOT FOUND" \
        "Please use

        swupd verify --fix

        to fix your installation."
    fi
}

mount_cdrom ()
{
    HAS_CDROM=$(lsblk | grep sr | cut -c -3)
    if [ -z "${HAS_CDROM}" ] ; then
        die "CDROM NOT FOUND" "Please insert Guest Additions CD image ..."
    fi
    mkdir /mnt/cdrom-vbox
    for cdrom in ${HAS_CDROM}; do
        mount /dev/$cdrom /mnt/cdrom-vbox -t iso9660 -o ro
        if [ -f /mnt/cdrom-vbox/VBoxLinuxAdditions.run ]; then
            VBOXGA_FOUND=1
            return
        fi
        umount /mnt/cdrom-vbox
    done
    rmdir /mnt/cdrom-vbox
    die "CDROM NOT FOUND" "Please insert Guest Additions CD image ..."
}

umount_cdrom ()
{
    if [ ${VBOXGA_FOUND} -eq 1 ] ; then
        umount /mnt/cdrom-vbox
        rmdir /mnt/cdrom-vbox
    fi
}

extract_files ()
{
    /mnt/cdrom-vbox/VBoxLinuxAdditions.run --noexec --keep --nox11 --target ${TMPDIR}
    if [ ! -f ${TMPDIR}/routines.sh ] ; then
        umount_cdrom
        die "VBOX Files not Found" "Can not find VirtualBox install files ..."
    fi
}

patch_systemd ()
{
    # Create a "user" installation instead a "system" installation
    mkdir -p /etc/systemd/system
    sed -i -- 's/lib/etc/g' ${TMPDIR}/routines.sh
    sed -i -- 's/\(\[Service\]\)/\1\nReadOnlyPaths=\/usr\nProtectSystem=true/' ${TMPDIR}/routines.sh
}

run_install ()
{
    if [ ! -x ${TMPDIR}/install.sh ] ; then
        die "VBOX Files not Found" "Can not find VirtualBox install files ..."
    fi

    # Do not build kernel modules
    export INSTALL_NO_MODULE_BUILDS=1

    cd ${TMPDIR}
    sed -i -- 's/\"$INSTALLATION_DIR\/init\/vboxadd.*\"\s*setup/true/g' install.sh
    sed -i -- 's/^\($INSTALLATION_DIR\/$UNINSTALL\)$/\1 "\\$@"/g' install.sh
    sed -i -- 's/^\(\s*\"${PUBLIC_UNINSTALL_HOOK}\"\)/\1 "no_cleanup"/g' install.sh
    sed -iE -- 's/^\s*\/\(usr\|sbin\)\/\S*//g' deffiles
    ./install.sh install --no-setup --no-cleanup
}

setup_install ()
{
    . /var/lib/VBoxGuestAdditions/config
    # Patch some files
    for f in ${INSTALL_DIR}/init/vboxadd ${INSTALL_DIR}/lib/VBoxGuestAdditions/vboxadd
    do
        if ! [[ -f $f ]]; then
            continue
        fi
        # Do not call setup_modules, we ship them already
        sed -i -- 's/setup_modules;/true;/g' ${f}
        # Do not remove old modules, we take care of them
        sed -i -- 's/xargs/true/g' ${f}
        # Do not add new users
        sed -i -- 's/useradd/true/g' ${f}
        # Do not add new group
        sed -i -- 's/groupadd/true/g' ${f}
    done

    # Ensure that support daemons for clipboard sharing, etc. will load
    xclient=$(find ${INSTALL_DIR} -type f -name '[0-9][0-9]vboxadd-xclient' \
        | head -1)
    if [[ -f ${xclient} ]]; then
        find /etc/xdg/autostart ${INSTALL_DIR} -type f -name vboxclient.desktop -exec \
            sed -i \ "s|^Exec=.*|Exec=${xclient}|" {} \;
    fi

    mkdir -p /etc/udev/rules.d
    mkdir -p /etc/ld.so.conf.d
    mkdir -p /etc/xdg/autostart

    echo "Guest Additions installation complete"
}

remove_tmp_files ()
{
    rm -rf ${TMPDIR}
}

####################  main  #################### 

check_dialog
check_root_user
check_kernel
mount_cdrom
extract_files
umount_cdrom
patch_systemd
run_install
setup_install
remove_tmp_files
