#!/bin/sh

KAV_APP_PKG="/Library/Application Support/Kaspersky Lab/KAV/Data/kav_app.tar.gz"
KAV_AGENT_APP_PATH="/Library/Application Support/Kaspersky Lab/KAV/Applications/Kaspersky Anti-Virus Agent.app"
DEFAULT_KAVAPP_PATH="/Applications/Kaspersky Anti-Virus For Mac.app"

stop_kav_app()
{
	KAVAPP_RECORD=$(ps -axwo pid,command | grep -v grep | grep "Contents/MacOS/kav_app")
	KAVPID=$(/bin/echo -n "$KAVAPP_RECORD" | awk '{print $1}')
	if [ "$KAVPID" != "" ]
	then
		RELAUNCH_KAVAPP_PATH=$(/bin/echo -n "$KAVAPP_RECORD" | sed 's/[ ]*'"$KAVPID"'[ ]*\(.*\.app\).*/\1/')
		kill -s KILL "$KAVPID"
	fi
}

if [ "$KAV_APP_PKG" != "" ]
then
	if [ -e "$KAV_APP_PKG" ]
	then
		echo ""
		echo "Deploying application resources..."

		KAVAPP_PATHS=$(mdfind "kMDItemCFBundleIdentifier == 'com.kaspersky.kav'" | grep -v "^/Volumes/")
		if [ "$KAVAPP_PATHS" == "" ]
		then
			KAVAPP_PATHS="$DEFAULT_KAVAPP_PATH"
		fi

		OLD_IFS="$IFS"
		IFS=$'\n'
		for KAVAPP_PATH in $KAVAPP_PATHS
		do
			echo ""
			echo "Extracting application resources to $KAVAPP_PATH..."
			tar -xzvf "$KAV_APP_PKG" -C "$KAVAPP_PATH"
			touch "$KAVAPP_PATH"
		done
		IFS="$OLD_IFS"

		echo ""
		echo "Stopping application..."
		stop_kav_app
	fi
fi

touch "$KAV_AGENT_APP_PATH"

rm -rf /Library/Caches/com.kaspersky.kav/PersonalCertificates/*

KAV_BIN_DIR="/Library/Application Support/Kaspersky Lab/KAV/Binaries/"

driver_info[0]="klif	3.4.0d25	3.0		3.4"
driver_info[1]="klnke	2.3.0d7	1.6		2.1"

get_driver_references_path()
{
	echo /Library/Application Support/Kaspersky Lab/Shared/"$1".references
}

add_product_dependency_for_driver()
{
	local driver_path="$2"/"$1".kext
	local references_path=$(get_driver_references_path "$1")
    
    echo "driver_path = $driver_path"
    echo "references_path = $references_path"    
	
	if [ ! -d "${driver_path}" ]; then
	    echo "Path ${driver_path} does not exist"
	    return 0
	fi

	local references_dir=$(dirname "$references_path")

	if [ ! -d "${references_dir}" ]; then
		mkdir -p "${references_dir}"
	fi

    if [ ! -f "${references_path}" ]; then
        /usr/libexec/PlistBuddy -c "Add :KLProducts dict" "${references_path}" &> /dev/null || return 1
    fi

    chmod 644 "${references_path}" || return 1

    /usr/libexec/PlistBuddy -c "Add :KLProducts:$3 dict" "${references_path}" &> /dev/null
    /usr/libexec/PlistBuddy -c "Add :KLProducts:$3:KLAPILevel string" "${references_path}" &> /dev/null

    local min_required_driver_api_level=$(get_min_required_driver_api_level $1)
    /usr/libexec/PlistBuddy -c "Set :KLProducts:$3:KLAPILevel ${min_required_driver_api_level}" "${references_path}" || return 1
    return 0
}

get_driver_api_level()
{
	local info
	for info in "${driver_info[@]}"
	do
		if [ $(echo $info | cut -f 1 -d ' ') == "$1" ]; then
		   echo $info | awk '{print $3}'
		   return
		fi
	done
}

get_min_required_driver_api_level()
{
	local info
	for info in "${driver_info[@]}"
	do
		if [ $(echo $info | cut -f 1 -d ' ') == "$1" ]; then
			echo $info | awk '{print $4}'
			return
		fi
	done
}

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/"
}

get_driver_version()
{
	local info
	for info in "${driver_info[@]}"
	do
		if [ $(echo $info | cut -f 1 -d ' ') == "$1" ]; then
		   echo $info | awk '{print $2}'
		   return
		fi
	done
}

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}"
}

compare_driver_versions()
{
    local v1=$(split_driver_version $1)
    local v2=$(split_driver_version $3)

    local n1=$(echo "${v1}" | awk '{ print NF }')
    local 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
        
        echo "$number1, $number2"

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

	[ 0 $2 0 ]
}

check_driver_compatibility()
{
	local driver_path="$3"/"$1".kext
    local patch_driver_archive="$KAV_BIN_DIR/$1.signed.tar.gz"
    
    echo "driver_path = $driver_path"
    echo "patch_driver_path = $patch_driver_path"    
    
    local installed_driver_version=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${driver_path}/Contents/Info.plist")
    local installed_driver_api_level=$(/usr/libexec/PlistBuddy -c "Print :KLAPILevel" "${driver_path}/Contents/Info.plist")
    local bundled_driver_version=$2
    local bundled_driver_api_level=$(get_driver_api_level $1)
    local min_required_driver_api_level=$(get_min_required_driver_api_level $1)

    echo "installed_driver_version = $installed_driver_version"
    echo "installed_driver_api_level = $installed_driver_api_level"
    echo "bundled_driver_version = $bundled_driver_version"
    echo "bundled_driver_api_level = $bundled_driver_api_level"
    echo "min_required_driver_api_level = $min_required_driver_api_level"    

    compare_driver_versions ${bundled_driver_version} -eq ${installed_driver_version}
    [ $? -eq 0 ] && return 0

    compare_driver_versions ${bundled_driver_version} -lt ${installed_driver_version}
    if [ $? -eq 0 ]; then
        compare_driver_versions ${min_required_driver_api_level} -ge ${installed_driver_api_level}
        return 0
    fi
    
    echo "Updating $1 driver"
    rm -rvf "$driver_path"
    tar -xzvf "$patch_driver_archive" -C "$3"
    chown -R root:wheel "$driver_path"
    
	add_product_dependency_for_driver $1 "$3" $4
        
    return 1
}

if [ -f "$KAV_BIN_DIR"/klif.signed.tar.gz ]; then
    check_driver_compatibility "klif" $(get_driver_version "klif" | sed 's/d/a/') "/Library/Extensions" "com.kaspersky.kav"
    rm -rvf "$KAV_BIN_DIR/klif.signed.tar.gz"
fi
if [ -f "$KAV_BIN_DIR"/klnke.signed.tar.gz ]; then
    check_driver_compatibility "klnke" $(get_driver_version "klnke" | sed 's/d/a/') "/Library/Extensions" "com.kaspersky.kav"
    rm -rvf "$KAV_BIN_DIR/klnke.signed.tar.gz"
fi
