#!/bin/sh
# 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

# Initial Stop Signal
STOPSIG=TERM

# The fallback if STOPSIG does not stop a process in time (see KILLDELAY)
FALLBACK=KILL

# Signal sent to running processes to refresh their configuration
RELOADSIG=HUP

# Number of seconds between STOPSIG and FALLBACK when stopping processes
KILLDELAY=3

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

# Width of the Screen
COLUMNS=$(stty size)
COLUMNS=${COLUMNS##* }
# When using remote connections, such as a serial port, stty size returns 0
if [ "$COLUMNS" = "0" ]; then COLUMNS=80; fi

# Measurements for positioning result messages
COL=$(($COLUMNS - 10))
WCOL=$(($COLUMNS - 30))

# Set Cursur Position Commands, used via echo -e
SET_COL="\\033[${COL}G"
SET_WCOL="\\033[${WCOL}G"
CURS_UP="\\033[A"

# Set color commands, used via echo -e
NORMAL="\\033[0;39m"
SUCCESS="\\033[1;32m"
WARNING="\\033[1;33m"
FAILURE="\\033[1;31m"

echo_ok()
{
	echo -e "$CURS_UP$SET_COL"["$SUCCESS""  OK  ""$NORMAL"]
}

echo_failure()
{
	echo -e "$CURS_UP$SET_COL"["$FAILURE"FAILED"$NORMAL"]
}

echo_warning()
{
	echo -e "$CURS_UP$SET_WCOL$@$SET_COL"["$WARNING" WARN  "$NORMAL"]
}

# $i is inherited by the rc script
print_error_msg()
{
	echo -e -n $FAILURE
	echo
	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."
	echo -e -n $NORMAL
	echo
	echo
	echo "Press Enter to continue..."
	read ENTER
}

# $i is inherited by the rc script
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
		sleep 5
	fi

	return 0
	#return $error_value
}

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

        case "$1" in
                success)
                        echo_ok
                ;;
                warning)
                        case "$2" in
                                running)
                                        echo_warning "Already running"
                                ;;
                                not_running)
                                        echo_warning "Not running"
                                ;;
                                not_available)
                                        echo_warning "Not available"
                                ;;
                        esac
                ;;
                failure)
                        echo_failure
                ;;
        esac
}

# Returns all of the pid #'s for $1 process
getpids()
{
	base=${1##*/}
	local lpids=""
	local pid

	pidlist=""
	if [ -n "$PIDFILE" ]; then
		lpids=$(cat $PIDFILE 2>/dev/null)
	else
		lpids=$(pidof $base)
	fi

	for pid in $lpids
	do
		if [ $pid -ne $$ ] && [ $pid -ne $PPID ]
		then
			pidlist="$pidlist $pid"
		fi
	done
}

# Starts a program if it is currently not running
loadproc()
{
	if [ $# = 0 ]; then
		echo "Usage: loadproc {program}"
		exit 1
		fi

	getpids $1

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

# Stops a process if it is running
killproc()
{
	if [ -z "$PIDFILE" -a -z "$#" ]; then
		echo "Usage: killproc [{program}]"
		exit 1	
	fi

	getpids "$1"

	if [ -n "$pidlist" ]; then
		local i=0
		for pid in $pidlist; do
			kill -$STOPSIG $pid 2>/dev/null
			while [ $i -lt $KILLDELAY ]; do
				kill -0 $pid 2>/dev/null || break
				sleep 1
				i=$(($i+1))
			done

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

		getpids "$1"

		base=${1##*/}

		if [ -n "$pidlist" ]; then
			failure=1
		else
			failure=0
			if [ -n "$PIDFILE" ]; then
				rm -f $PIDFILE
			else
				rm -f /var/run/$base.pid
			fi
		fi

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

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

	getpids $1

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

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

                (exit $failure)

		evaluate_retval
        else
                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
