#!/bin/sh

#
# Copyright (C) 2007-2010 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
# you can redistribute it and/or modify it under the terms of the GNU
# General Public License (GPL) as published by the Free Software
# Foundation, in version 2 as it comes in the "COPYING" file of the
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#

. /etc/rc.common


StartService()
{
    VBOX_RC=0
    VBOXDRV="VBoxDrv"
    VBOXUSB="VBoxUSB"

    #
    # Switch the binaries to the right architecture.
    #
    VBOX_ARCH=`uname -m`
    if test "$VBOX_ARCH" = "x86_64"; then
        VBOX_ARCH="amd64"
    else
        VBOX_ARCH="x86"
    fi
    for VBOX_TRG in `ls /Applications/VirtualBox.app/Contents/MacOS/*-${VBOX_ARCH}`;
    do
        VBOX_LINKNAME=`echo "$VBOX_TRG" | sed -e 's|-'"${VBOX_ARCH}"'$||' `
        if test "$VBOX_LINKNAME" != "$VBOX_TRG"; then
            rm -f "$VBOX_LINKNAME"
            if ! ln -vh "$VBOX_TRG" "$VBOX_LINKNAME"; then
                ConsoleMessage "Error: ln -vh $VBOX_TRG $VBOX_LINKNAME failed"
                VBOX_RC=1
            fi
        else
            ConsoleMessage "Error: Script error VBOX_TRG=$VBOX_TRG"
            VBOX_RC=1
        fi
    done

    #
    # Check that all the directories exist first.
    #
    if [ ! -d /Library/Extensions/${VBOXDRV}.kext ]; then
        ConsoleMessage "Error: /Library/Extensions/${VBOXDRV}.kext is missing"
        VBOX_RC=1
    fi
    if [ ! -d /Library/Extensions/${VBOXUSB}.kext ]; then
        ConsoleMessage "Error: /Library/Extensions/${VBOXUSB}.kext is missing"
        VBOX_RC=1
    fi
    if [ ! -d /Library/Extensions/VBoxNetFlt.kext ]; then
        ConsoleMessage "Error: /Library/Extensions/VBoxNetFlt.kext is missing"
        VBOX_RC=1
    fi
    if [ ! -d /Library/Extensions/VBoxNetAdp.kext ]; then
        ConsoleMessage "Error: /Library/Extensions/VBoxNetAdp.kext is missing"
        VBOX_RC=1
    fi

    #
    # Check that no drivers are currently running.
    # (Try stop the service if this is the case.)
    #
    if [ $VBOX_RC -eq 0 ]; then
        if kextstat -lb org.virtualbox.kext.VBoxDrv 2>&1 | grep -q org.virtualbox.kext.VBoxDrv; then
            ConsoleMessage -v "Error: ${VBOXDRV}.kext is already loaded"
            VBOX_RC=1
        fi
        if kextstat -lb org.virtualbox.kext.VBoxUSB 2>&1 | grep -q org.virtualbox.kext.VBoxUSB; then
            ConsoleMessage -v "Error: ${VBOXUSB}.kext is already loaded"
            VBOX_RC=1
        fi
        if kextstat -lb org.virtualbox.kext.VBoxNetFlt 2>&1 | grep -q org.virtualbox.kext.VBoxNetFlt; then
            ConsoleMessage -v "Error: VBoxNetFlt.kext is already loaded"
            VBOX_RC=1
        fi
        if kextstat -lb org.virtualbox.kext.VBoxNetAdp 2>&1 | grep -q org.virtualbox.kext.VBoxNetAdp; then
            ConsoleMessage -v "Error: VBoxNetAdp.kext is already loaded"
            VBOX_RC=1
        fi
    fi

    #
    # Load the drivers.
    #
    if [ $VBOX_RC -eq 0 ]; then
        ConsoleMessage "Loading ${VBOXDRV}.kext"
        if ! kextload /Library/Extensions/${VBOXDRV}.kext; then
            ConsoleMessage "Error: Failed to load /Library/Extensions/${VBOXDRV}.kext"
            VBOX_RC=1
        fi

        ConsoleMessage "Loading ${VBOXUSB}.kext"
        if ! kextload -d /Library/Extensions/${VBOXDRV}.kext /Library/Extensions/${VBOXUSB}.kext; then
            ConsoleMessage "Error: Failed to load /Library/Extensions/${VBOXUSB}.kext"
            VBOX_RC=1
        fi

        ConsoleMessage "Loading VBoxNetFlt.kext"
        if ! kextload -d /Library/Extensions/${VBOXDRV}.kext /Library/Extensions/VBoxNetFlt.kext; then
            ConsoleMessage "Error: Failed to load /Library/Extensions/VBoxNetFlt.kext"
            VBOX_RC=1
        fi

        ConsoleMessage "Loading VBoxNetAdp.kext"
        if ! kextload -d /Library/Extensions/${VBOXDRV}.kext /Library/Extensions/VBoxNetAdp.kext; then
            ConsoleMessage "Error: Failed to load /Library/Extensions/VBoxNetAdp.kext"
            VBOX_RC=1
        fi

        if [ $VBOX_RC -ne 0 ]; then
            # unload the drivers (ignoring failures)
            kextunload -b org.virtualbox.kext.VBoxNetAdp
            kextunload -b org.virtualbox.kext.VBoxNetFlt
            kextunload -b org.virtualbox.kext.VBoxUSB
            kextunload -b org.virtualbox.kext.VBoxDrv
        fi
    fi

    #
    # Set the error on failure.
    #
    if [ "$VBOX_RC" -ne "0" ]; then
        ConsoleMessage -f VirtualBox
        exit $VBOX_RC
    fi
}


StopService()
{
    VBOX_RC=0
    VBOXDRV="VBoxDrv"
    VBOXUSB="VBoxUSB"

    if kextstat -lb org.virtualbox.kext.VBoxUSB 2>&1 | grep -q org.virtualbox.kext.VBoxUSB; then
        ConsoleMessage "Unloading ${VBOXUSB}.kext"
        if ! kextunload -m org.virtualbox.kext.VBoxUSB; then
            ConsoleMessage -v "Error: Failed to unload VBoxUSB.kext"
            VBOX_RC=1
        fi
    fi

    if kextstat -lb org.virtualbox.kext.VBoxNetFlt 2>&1 | grep -q org.virtualbox.kext.VBoxNetFlt; then
        ConsoleMessage "Unloading VBoxNetFlt.kext"
        if ! kextunload -m org.virtualbox.kext.VBoxNetFlt; then
            ConsoleMessage -v "Error: Failed to unload VBoxNetFlt.kext"
            VBOX_RC=1
        fi
    fi

    if kextstat -lb org.virtualbox.kext.VBoxNetAdp 2>&1 | grep -q org.virtualbox.kext.VBoxNetAdp; then
        ConsoleMessage "Unloading VBoxNetAdp.kext"
        if ! kextunload -m org.virtualbox.kext.VBoxNetAdp; then
            ConsoleMessage -v "Error: Failed to unload VBoxNetAdp.kext"
            VBOX_RC=1
        fi
    fi

    # This must come last because of dependencies.
    if kextstat -lb org.virtualbox.kext.VBoxDrv 2>&1 | grep -q org.virtualbox.kext.VBoxDrv; then
        ConsoleMessage "Unloading ${VBOXDRV}.kext"
        if ! kextunload -m org.virtualbox.kext.VBoxDrv; then
            ConsoleMessage -v "Error: Failed to unload VBoxDrv.kext"
            VBOX_RC=1
        fi
    fi

    # Set the error on failure.
    if [ "$VBOX_RC" -ne "0" ]; then
        ConsoleMessage -f VirtualBox
        exit $VBOX_RC
    fi
}


RestartService()
{
    StopService
    StartService
}


RunService "$1"

