#!/bin/sh
#
# Functions defined in this file are still used by many rc scripts;
# they offer some RedHat/Mandrake compatibility.

# Check if $pid (could be plural) are running
checkpid()
{
	while [ -n "$1" ]; do
		[ -d "/proc/$1" ] && shift || return 1
	done
	return 0
}

# A function to start a program.
daemon()
{
	# Test syntax.
	local base=
	local bg=
	local gotbase=
	local checkname=
	local force=
	local user=
	local daemon_user=
	local nicelevel=0
	while [ "$1" != "${1##[-+]}" ]; do
		case $1 in
			--check)
				shift
				base=$1
				checkname="$base"
				gotbase=yes
				shift
				;;
			--check=?*)
				base=${1#--check=}
				checkname="$base"
				gotbase=yes
				shift
				;;
			--force)
				force=1
				shift
				;;
			--user)
				shift
				daemon_user=$1
				shift
				;;
			--user=?*)
				daemon_user=${1#--user=}
				shift
				;;
			--bg|--background)
				bg='&'
				shift
				;;
			[-+][0-9]*)
				nicelevel=$1
				shift
				;;
			*)
				msg_usage "daemon [options]... {program}..."
				return 1
				;;
		esac
	done

	# Save basename.
	if [ -z "$gotbase" ]; then
		base="${1##*/}"
		checkname="$1"
	fi

	# Echo daemon
	if [ "$BOOTUP" = verbose ]; then echo -n "$base "; fi

	# See if it's already running.
	if [ -z "$force" ] && pidfileofproc "$base" >/dev/null 2>&1; then
		echo_passed
		return 1
	fi

	# Use a safe umask
	#umask 077

	# And start it up.
	if [ -z "$daemon_user" ]; then
		nice -n $nicelevel initlog $INITLOG_ARGS -n "$base" -c "limited -n $base -- sh -c '$*$bg'"
	else
		nice -n $nicelevel initlog $INITLOG_ARGS -n "$base" -c "limited -n $base -- su -s /bin/sh -l $daemon_user -c '$*$bg'"
	fi
	[ $? = 0 ] && success "$base startup" || failure "$base startup"
}

# usage: wait_pid <w_times> <w_delay> pidlist
wait_pid()
{
	local w_times w_delay
	w_times="$1"
	shift
	w_delay="$1"
	shift

	local i=0
	while [ $i -lt "$w_times" ]; do
		checkpid "$@" >/dev/null 2>&1 || return 0
		usleep "$w_delay"
		i=$[1+i]
	done
	! checkpid "$@"
}

# A function to stop a program.
killproc()
{
	local rc=0
	# Test syntax.
	if [ $# = 0 ]; then
		msg_usage "killproc {program} [signal]"
		return 1
	fi

	local notset=0
	local killlevel='-9'
	# check for second arg to be kill level
	if [ -n "$2" ]; then
		killlevel=$2
	else
		notset=1
	fi

	# Save basename.
	local base
	base="${1##*/}"

	# Find pid.
	local pidlist
	pidlist=`pidofproc "$1"`

	local pid= p
	for p in $pidlist; do
		if checkpid "$p"; then
			[ -z "$pid" ] && pid="$p" || pid="$pid $p"
		fi
	done

	# Kill it.
	if [ -n "$pid" ]; then
		[ "$BOOTUP" != "verbose" ] || echo -n "$base "
		if [ "$notset" = 1 ]; then
			if checkpid $pid >/dev/null 2>&1; then
				# TERM first, then KILL if not dead
				kill -TERM -- $pid
				if ! wait_pid 30 100000 $pid; then
					kill -KILL -- $pid
					usleep 100000
				fi
			fi
			checkpid $pid >/dev/null 2>&1
			rc=$?
			[ $rc -eq 0 ] && failure "$base shutdown" || success "$base shutdown"
			rc=$((! $rc))
		# use specified level only
		else
			if checkpid $pid >/dev/null 2>&1; then
				kill "$killlevel" -- $pid
				rc=$?
				[ $rc -eq 0 ] && success "$base kill $killlevel" || failure "$base kill $killlevel"
			fi
		fi
	else
		if [ "$notset" = 1 ]; then 
			failure "$base shutdown" 
		else 
			failure "$base kill $killlevel" 
		fi 
		rc=1
	fi

	# Remove pid file if any.
	if [ "$notset" = 1 ]; then
		rm -f "/var/run/$base.pid"
	fi
	return $rc
}

# A function to find the pid of a program.
pidfileofproc()
{
	local base
	base="${1##*/}"

	# Test syntax.
	if [ $# != 1 ]; then
		msg_usage "pidfileofproc {program}"
		return 1
	fi

	# Check "/var/run/*.pid" files
	if [ -s "/var/run/$base.pid" ]; then
		local line p pid=
		read line <"/var/run/$base.pid"
		for p in $line; do
			if [ "$p" -gt 1 ] 2>/dev/null && [ -d "/proc/$p" ]; then
				pid="$pid $p"
			fi
		done
		if [ -n "$pid" ]; then
			echo "$pid"
			return 0
		fi
	fi

	return 1
}

# A function to find the pid of a program.
pidofproc()
{
	# Test syntax.
	if [ $# != 1 ]; then
		msg_usage "pidofproc {program}"
		return 1
	fi

	local base
	base="${1##*/}"

	# First try "/var/run/*.pid" files.
	if [ -s "/var/run/$base.pid" ]; then
		local line p pid=
		read line <"/var/run/$base.pid"
		for p in $line; do
			if [ "$p" -gt 1 ] 2>/dev/null && [ -d "/proc/$p" ]; then
				pid="$pid $p"
			fi
		done
		if [ -n "$pid" ]; then
			echo "$pid"
			return 0
		fi
	fi

	# Next try "pidof".
	local PIDOF=/bin/pidof
	if [ -x "$PIDOF" ]; then
		"$PIDOF" -o $$ -o $PPID -o %PPID -x "$1" ||
			"$PIDOF" -o $$ -o $PPID -o %PPID -x "$base"
	fi
}
