#!/bin/sh

KAV_DIR="/Library/Application Support/Kaspersky Lab/KAV"
KAV_DATA_DIR="$KAV_DIR/Data"
DRIVERS_PKG_DIR="$KAV_DATA_DIR"


split_driver_version()
{
    local MAJOR=$(echo $1 | sed -n "s/\([0-9]*\).*/\1/p")
    local MINOR=$(echo $1 | sed -n "s/\([0-9]*\)\.\([0-9]*\).*/\2/p")
    local BUGFIX=$(echo $1 | sed -n "s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\3/p")
    local STAGE=$(echo $1 | sed -n "s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\([a-z]*\).*/\4/p")
    local BUILD=$(echo $1 | sed -n "s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\([a-z]*\)\([0-9]*\)/\5/p")
    echo "$MAJOR $MINOR $BUGFIX $STAGE $BUILD"
}

get_driver_version_component()
{
    echo "$1" | cut -f $2 -d " "
}

get_driver_version_stage_priority()
{
    local PRIORITIZED_LIST=$(echo ":d"; echo ":a"; echo ":b"; echo ":fc"; echo ":")
    echo "$PRIORITIZED_LIST" | grep -n "^:$1" | sed "s/\([0-9]*\).*/\1/"
}

compare_driver_versions()
{
    V1=$(split_driver_version $1)
    V2=$(split_driver_version $3)

    N1=$(echo "$V1" | awk '{ print NF }')
    N2=$(echo "$V2" | awk '{ print NF }')

    local N
    if [ $N1 -gt $N2 ]; then
        N=$N1
    else
        N=$N2
    fi

    for i in `seq 1 $N`; do
	local NUMBER1=$(get_driver_version_component "$V1" $i);
	local NUMBER2=$(get_driver_version_component "$V2" $i);

	if [ $i -eq 4 ]; then
	    NUMBER1=$(get_driver_version_stage_priority ${NUMBER1})
	    NUMBER2=$(get_driver_version_stage_priority ${NUMBER2})
        fi

	if [ ${NUMBER1:=0} -ne ${NUMBER2:=0} ]; then
	    [ ${NUMBER1:=0} $2 ${NUMBER2:=0} ]
	    return
	fi
    done

    [ 0 $2 0 ]
}

update_driver()
{
    [ ! -f "$5/$3" ] && return 1

    DRIVER_REFERENCES_PATH="/Library/Application Support/Kaspersky Lab/Shared/$1.references"
    DRIVER_REFERENCES_LEGACY_PATH="$4/$1.kext/Contents/.References.plist"
    
    if [ "$4" == "/Library/Extensions" ] && [ -f "$DRIVER_REFERENCES_LEGACY_PATH" ] && [ ! -f "$DRIVER_REFERENCES_PATH" ]; then
	DRIVER_REFERENCES_DIR=$(dirname "$DRIVER_REFERENCES_PATH")
	mkdir -p "$DRIVER_REFERENCES_DIR"
	mv "$DRIVER_REFERENCES_LEGACY_PATH" "$DRIVER_REFERENCES_PATH" || return 1
    fi

    if [ "$4" == "/System/Library/Extensions" ] && [ -f "$DRIVER_REFERENCES_LEGACY_PATH" ]; then
	rm -rvf "$DRIVER_REFERENCES_LEGACY_PATH"
    fi

    DRIVER_PATH="$4/$1.kext"

    if [ -d "$DRIVER_PATH" ]; then
	INSTALLED_DRIVER_VERSION=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$DRIVER_PATH/Contents/Info.plist")
	compare_driver_versions $2 -gt $INSTALLED_DRIVER_VERSION || return 1
    fi

    rm -rvf "$DRIVER_PATH"
    tar -xzvf "$5/$3" -C "$4"
    chown -R root:wheel "$DRIVER_PATH"
    echo "Driver $1 updated to version $2"
}

update_drivers()
{
    echo "Updating drivers..."

    SHOULD_RESET_DRIVER_CACHE=0
    update_driver klif 3.6.15a55 klif.notarized.tar.gz /Library/Extensions "$DRIVERS_PKG_DIR" && SHOULD_RESET_DRIVER_CACHE=1

    if [ "$SHOULD_RESET_DRIVER_CACHE" == "1" ]; then
        echo "Reseting driver cache..."
        touch "/Library/Extensions"
        /usr/sbin/kextcache -update-volume / -Installer -verbose 4 || (/usr/sbin/kextcache -system-prelinked-kernel && /usr/sbin/kextcache -invalidate /)
    fi
}

finishing_and_housekeeping()
{
    echo "Deleting Cert directory..."
    rm -rfv "/Library/Application Support/Kaspersky Lab/KAV/Data/Cert"

    chmod -R o+r "/Library/Application Support/Kaspersky Lab/KAV/Bases/"

    echo "Deleting kav crash logs"
    rm -rfv /Library/Logs/DiagnosticReports/kav_*
    echo "Deleting kav_app crash logs"
    rm -rfv ~/Library/Logs/DiagnosticReports/kav_app*
    echo "Deleting kav_agent crash logs"
    rm -rfv ~/Library/Logs/DiagnosticReports/kav_agent*
    echo "Deleting appex crash logs"
    rm -rfv ~/Library/Logs/DiagnosticReports/KasperskySecurity*
}

update_drivers
finishing_and_housekeeping
