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

# Number of seconds between term signal and kill signal 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"
                                ;;
                        esac
                ;;
                failure)
                        echo_failure
                ;;
        esac
}

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

        pidlist=""
        lpids=$(pidof $base)
        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

	if [ -n "$PIDFILE" -a -r "$PIDFILE" ]; then
		pidlist=`cat $PIDFILE`
	else
		getpids $1
	fi

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

# Stops a process if it is running
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

	if [ -n "$PIDFILE" -a -r "$PIDFILE" ]; then
		pidlist=`cat $PIDFILE`
	else
		getpids $1
	fi

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

                for pid in $pidlist
                do
                        kill -$signal $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 [ ! -z $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} [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
                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
