#!/bin/bash
# Begin $rc_base/init.d/functions - Run Level Control Functions

# Based on functions script from LFS-3.1 and earlier.
# Rewritten by Gerard Beekmans  - gerard@linuxfromscratch.org

# With code based on Matthias Benkmann's simpleinit-msb @
# http://winterdrache.de/linux/newboot/index.html

umask 022

export PATH="/bin:/usr/bin:/sbin:/usr/sbin"

KILLDELAY=3

COLUMNS=$(stty size)
COLUMNS=${COLUMNS##* }
COL=$[ $COLUMNS - 10 ]
WCOL=$[ $COLUMNS - 30 ]
SET_COL="echo -en \\033[${COL}G"
SET_WCOL="echo -en \\033[${WCOL}G"
CURS_UP="echo -en \\033[A"

NORMAL="echo -en \\033[0;39m"
SUCCESS="echo -en \\033[1;32m"
WARNING="echo -en \\033[1;33m"
FAILURE="echo -en \\033[1;31m"

print_error_msg()
{
	echo
	$FAILURE
	echo "You should not be reading this error message. It means"
	echo "that an unforseen error took place in $i,"
	echo "which exited with a return value of $error_value"
	echo
	echo "If you're able to track this error down to a bug in one"
	echo "of the files provided by the LFS book, please be so kind"
	echo "to inform us at lfs-dev@linuxfromscratch.org"
	$NORMAL
	echo
	echo
	echo "Press Enter to continue..."
	read
}

check_script_status()
{
	if [ ! -f $i ]
	then
		echo "$i is not a valid symlink"
		continue
	fi

	if [ ! -x $i ]
	then
		echo "$i is not executable, skipping"
		continue
	fi
}

evaluate_retval()
{
	error_value=$?

	if [ $error_value = 0 ]
	then
		print_status success
	else
		print_status failure
	fi

	return $error_value
}

print_status()
{
	if [ $# = 0 ]
	then
		echo "Usage: $0 {success|warning|failure}"
		return 1
	fi

	$CURS_UP

	case "$1" in
		success)
			$SET_COL
			echo -n "[  "
			$SUCCESS
			echo -n "OK"
			$NORMAL
			echo "  ]"
			;;
		warning)
			case "$2" in
				running)
					$SET_WCOL
					echo "Already running"
					$CURS_UP
					;;
				not_running)
					$SET_WCOL
					echo "Not running"
					$CURS_UP
					;;
			esac
			$SET_COL
			echo -n "[ "
			$WARNING
			echo -n "ATTN"
			$NORMAL
			echo " ]"
			;;
		failure)
			$SET_COL
			echo -n "["
			$FAILURE
			echo -n "FAILED"
			$NORMAL
			echo "]"
			;;
	esac
}

getpids()
{
	base=${1##*/}
	pidlist=$(pidof -o $$ -o $PPID -x $base)
}

loadproc()
{
	if [ $# = 0 ]
	then
		echo "Usage: loadproc {program}"
		exit 1
	fi

	getpids $1

	if [ -z "$pidlist" ]
	then
		"$@"
		evaluate_retval
	else
		$SET_WCOL
		print_status warning running
	fi
}

killproc()
{
	if [ $# = 0 ]
	then
		echo "Usage: killproc {program} [signal]"
		exit 1
	fi

	if [ -z "$2" ]; then
		signal=TERM
		fallback=KILL
	else
		signal=${2##-}
		signal=${signal##SIG}
		fallback=""
	fi

	getpids $1

	if [ -n "$pidlist" ]; then
		failure=0

		for pid in $pidlist
		do
			kill -$signal $pid 2>/dev/null

			for ((i=0; $i<5000; i=$i+1)); do :; done

			for ((i=0; $i<$KILLDELAY; i=$i+1)); do
				kill -0 $pid 2>/dev/null || break
				sleep 1
			done

			if [ -n "$fallback" ]; then kill -$fallback $pid 2>/dev/null; fi

			kill -0 $pid 2>/dev/null && failure=1
		done

		base=${1##*/}
		if [ $failure = 0 ]; then rm -f /var/run/$base.pid; fi

		(exit $failure)
		evaluate_retval
	else
		$SET_WCOL
		print_status warning not_running
	fi
}

reloadproc()
{
	if [ $# = 0 ]
	then
		echo "Usage: reloadproc {program} [signal]"
		exit 1
	fi

	if [ -z "$2" ]; then
		signal=HUP
	else
		signal=${2##-}
		signal=${signal##SIG}

	fi

	getpids $1

	if [ -n "$pidlist" ]
	then
		failure=0

		for pid in $pidlist
		do
			kill -$signal $pid || failure=1
		done

		(exit $failure)
		evaluate_retval
	else
		$SET_WCOL
		print_status warning not_running
	fi
}

statusproc()
{
	if [ $# = 0 ]
	then
		echo "Usage: statusproc {program}"
		exit 1
	fi

	base=${1##*/}
	getpids $base

	if [ -n "$pidlist" ]
	then
		echo "$base is running with Process ID(s) $pidlist"
	else
		if [ -s /var/run/$base.pid ]
		then
			echo "$1 is not running but /var/run/$base.pid exists"
			return 1
		else
			echo "$1 is not running"
	 	fi
	fi
}

# End $rc_base/init.d/functions

