#!/bin/sh
#
# LKRG	Linux Kernel Runtime Guard
#
# chkconfig: 2345 01 99
# description: Linux Kernel Runtime Guard
# config: /etc/lkrg.conf

# Do not load RH compatibility interface.
WITHOUT_RC_COMPAT=1

# Source function library.
. /etc/init.d/functions

NAME="Linux Kernel Runtime Guard"
CONFIG="/etc/lkrg.conf"
LOCKFILE="/run/lock/subsys/lkrg"
RETVAL=0

check_running()
{
	sysctl lkrg.hide >/dev/null 2>&1 ||
		return 1
}

check_nolkrg()
{
	grep -qw nolkrg /proc/cmdline
}

get_modname()
{
	if modinfo p_lkrg >/dev/null 2>&1; then
		MODNAME=p_lkrg
		return 0
	fi

	if modinfo lkrg >/dev/null 2>&1; then
		MODNAME=lkrg
		return 0
	fi

	return 1
}

adjust()
{
	RETVAL=0
	if [ -f "$CONFIG" ]; then
		action "Adjusting kernel parameters for $NAME" \
			sysctl -p "$CONFIG"
		RETVAL=$?
	fi

	return $RETVAL
}

start()
{
	if [ -e "$LOCKFILE" ] && check_running; then
		msg_already_running "$NAME"
		echo
		RETVAL=0
		return $RETVAL
	fi

	if check_nolkrg; then
		echo "$NAME: nolkrg kernel parameter passed, do not load"
		RETVAL=1
		return $RETVAL
	fi

	get_modname
	rc=$?

	if [ "$rc" -ne 0 ]; then
		echo "$NAME: Linux Kernel Runtime Guard kernel module is not installed"
		RETVAL=1
		return $RETVAL
	fi

	RETVAL=0
	echo "Checking whether $NAME is already loaded"
	if check_running; then
		echo "$NAME is already loaded, skipping that part"
	else
		msg_starting "$NAME"

		modprobe "$MODNAME"
		RETVAL=$?

		if [ "$RETVAL" -eq 0 ]; then
			success "$NAME startup"
		else
			failure "$NAME startup"
		fi
	fi

	if [ "$RETVAL" -eq 0 ]; then
		# Adjust message should not erase success message
		echo
		adjust
		RETVAL=$?
		touch "$LOCKFILE"
	fi

	return $RETVAL
}

stop()
{
	if ! check_running; then
		msg_not_running "$NAME"
		echo
		rm -f "$LOCKFILE"
		RETVAL=0
		return $RETVAL
	fi

	echo "$NAME is not supposed to be stopped, reboot the system or invoke 'unload' at your own risk."

	RETVAL=0
	return $RETVAL
}

unload()
{
	if ! check_running; then
		msg_not_running "$NAME"
		echo
		rm -f "$LOCKFILE"
		RETVAL=0
		return $RETVAL
	fi

	get_modname

	msg_stopping "$NAME"
	sysctl lkrg.hide=0
	modprobe -r "$MODNAME"
	RETVAL=$?

	if [ "$RETVAL" -eq 0 ]; then
		success "$NAME stopping"
		rm -f "$LOCKFILE"
	else
		failure "$NAME stopping"
	fi

	return $RETVAL
}

restart()
{
	stop
	start
}

reload()
{
	if ! check_running; then
		msg_not_running "$NAME"
		RETVAL=0
		return $RETVAL
	fi

	adjust
}

# See how we were called.
case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	unload)
		unload
		;;
	reload)
		reload
		;;
	restart)
		restart
		;;
	condstop)
		if check_running; then
			stop
		fi
		;;
	condrestart)
		if check_running; then
			restart
		fi
		;;
	condreload)
		if check_running; then
			reload
			test -e "$LOCKFILE" || touch "$LOCKFILE"
		fi
		;;
	status)
		check_running
		RETVAL=$?
		if [ "$RETVAL" = 0 ]; then
			if [ -e "$LOCKFILE" ]; then
				echo "$NAME is running"
			else
				echo "$NAME is running, but service has not been started"
			fi
		else
			if [ -e "$LOCKFILE" ]; then
				echo "$NAME is not running, but subsystem is locked"
			else
				echo "$NAME is stopped"
			fi
		fi
		;;
	*)
		msg_usage "${0##*/} {start|stop|unload|reload|restart|condstop|condrestart|condreload|status}"
		RETVAL=1
esac

exit $RETVAL
