# functions	This file contains functions to be used by most or all
#		shell scripts in the /etc/init.d directory.
#
# $Id: functions,v 1.47 2000/04/01 10:24:30 waszi Exp $
#
# Author:	Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Hacked by:    Greg Galloway and Marc Ewing
# Modified for PLD by:
#		Marek Obuchowicz <elephant@pld.org.pl>
#		Arkadiusz Mikiewicz <misiek@pld.org.pl> 

# First set up a default search path.
export PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin"

# Set defaults
INIT_COL=67

# Source configuration if available - may override default values
[ -f /etc/sysconfig/system ] && . /etc/sysconfig/system

[ -z "$COLUMNS" ] && COLUMNS=80

# Colors workaround
termput() 
{
	if [ "$COLOR_INIT" = "no" ]; then
        	:
	elif [ ! -d /usr/share/terminfo ] || \
	     ! ( [ -x /usr/bin/tput ] || [ -x /bin/tput ] ) ; then
		case "$1" in
		  hpa)
		  	echo -ne "\033[$(($2+1))G"
			;;
		  cuu*)
		  	echo -ne "\033[${2}A"
			;;
		  el)
		  	echo -ne "\033[0K"
			;;
		  setaf)
		  	echo -ne "\033[0;3${2}m"
		  	;;
		  esac
	else
		tput "$@"
	fi
}

# printf equivalent
printf_()
{
	text="$1" ;
	shift ;
	if [ -n "$1" ]; then
		m="$1";
        	shift;
		while [ -n "$1" ]; do
			m="$m\",\"$1" ;
			shift ;
		done
	fi
	awk "BEGIN {printf \"$text\", \"$m\"; }"
}
			    
# National language support function
nls()
{
if [ -x /bin/gettext -o -x /usr/bin/gettext ]; then
	OLD_NLS_DOMAIN="$NLS_DOMAIN"
	if [ "$1" = "--nls-domain" ]; then
		shift
		NLS_DOMAIN="$1"
		shift
	fi
	if [ -z "$NLS_DOMAIN" ]; then
		NLS_DOMAIN="rc-scripts"
	fi
	MESSAGE="$1"
	# avoid translating empty text. --misiek
	if [ -n "$MESSAGE" ]; then
		text="`TEXTDOMAINDIR="/etc/sysconfig/locale" gettext -e --domain="$NLS_DOMAIN" "$MESSAGE"`"
	else
		text="$MESSAGE"
	fi
	shift
	printf_ "$text" "$@"
	echo
	NLS_DOMAIN="$OLD_NLS_DOMAIN"
else
	echo "$@"
fi
}

msg_Network_Down()
{
	nls "ERROR: Networking is down. %s can't be run.\n" "$1"
}

msg_starting()
{
	show "Starting %s service" "$1"
}

msg_Already_Running()
{
	nls "%s service is already running.\n" "$1"
}

msg_stopping()
{
	show "Stopping %s service" "$1"
}

msg_Not_Running()
{
	nls "%s service is not running.\n" "$1"
}

msg_reloading()
{
	show "Reloading %s service" "$1"
}

msg_Usage()
{
	nls "Usage: %s" "$*\n"
}

# Some functions to handle PLD-style messages
show() 
{	
	what="`nls --nls-domain rc-scripts "DONE"`"; typeset -i offset=${#what}
	text="`nls "$@"`"
	echo -n "$text"
	awk "BEGIN { for (j=length(\"$text\"); j<$INIT_COL; j++) printf \".\" }"
}

busy() 
{
	termput hpa $INIT_COL
	echo -n "`termput setaf 6`[`termput setaf 5` `nls --nls-domain rc-scripts "BUSY"` `termput setaf 6`]`termput setaf 7`"
}

ok() 
{
	termput hpa $INIT_COL
	echo  "`termput setaf 6`[`termput setaf 2` `nls --nls-domain rc-scripts "DONE"` `termput setaf 6`]`termput setaf 7`"
}

started()
{
	termput hpa $INIT_COL
	echo  "`termput setaf 6`[`termput setaf 2` `nls --nls-domain rc-scripts "WORK"` `termput setaf 6`]`termput setaf 7`"
}

fail() 
{
	termput hpa $INIT_COL
	echo  "`termput setaf 6`[`termput setaf 1` `nls --nls-domain rc-scripts "FAIL"` `termput setaf 6`]`termput setaf 7`"
}

died() 
{
	termput hpa $INIT_COL
	echo  "`termput setaf 6`[`termput setaf 1` `nls --nls-domain rc-scripts "DIED"` `termput setaf 6`]`termput setaf 7`"
}

deltext() 
{
	echo -ne "`nls "\b\b\b\b\b\b\b\b"`"	
}

# Usage run_cmd Message command_to_run
run_cmd()
{
	exit_code=0
	_ERRORS=""
	MESSAGE=$1
	show "$MESSAGE"; busy
	shift
	if _ERRORS="`initlog -c \"$*\" 2>&1`"; then
		deltext; ok
	else
		deltext; fail;  [ -n "$_ERRORS" ] && echo $_ERRORS
		exit_code=1
	fi
	unset _ERRORS
	return $exit_code
}

# compatibility functions
action()
{
        STRING=$1
	shift
	run_cmd "$STRING" "$*"
}
			
# A function to start a program (now it's usefull on read-only filesystem too)
daemon() 
{
	nicelevel=0
	exit_code=0
	_ERRORS=""
	[ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
	# Test syntax.
	case $1 in
	'')	msg_Usage " daemon [+/-nicelevel] {program}\n"
		return 1;;
	-*|+*) SERVICE_RUN_NICE_LEVEL=$1
		shift;;
	esac

	# make sure it doesn't core dump anywhere; while this could mask
	# problems with the daemon, it also closes some security problems
	ulimit -c 0

	# And start it up.
	busy
	if _ERRORS="`nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} initlog -c "$*" 2>&1`"; then
		deltext
		ok
	else
		exit_code=1
		deltext
		fail
		[ -n "$_ERRORS" ] && echo $_ERRORS
	fi
	unset _ERRORS
	return $exit_code
}

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

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

        # Save basename.
        base=`basename $1`

        # Find pid.
        pid=`pidofproc $base`

        # Kill it.
        if [ "$pid" != "" ] ; then
		if [ "$notset" = "1" ] ; then
			if ps h $pid>/dev/null 2>&1; then
				# TERM first, then KILL if not dead
				kill -TERM $pid >/dev/null 2>&1
				usleep 100000
				if ps h $pid >/dev/null 2>&1 ; then
					sleep 1
					if ps h $pid >/dev/null 2>&1 ; then
						sleep 3
						if ps h $pid >/dev/null 2>&1 ; then
							kill -KILL $pid >/dev/null 2>&1
						fi
					fi
				fi
				ps h $pid >/dev/null 2>&1 && (deltext; fail) || (deltext; ok)
			else
				deltext; died
			fi
		# use specified level only
		else
			if ps h $pid >/dev/null 2>&1; then
				kill $killlevel $pid && (deltext; ok) || (deltext; fail)
			else
				deltext; died
			fi
		fi
	else
		deltext
		died
	fi

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

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

	# First try "/var/run/*.pid" files
	if [ -f /var/run/$1.pid ] ; then
	        pid=`head -1 /var/run/$1.pid`
	        if [ "$pid" != "" ] ; then
	                echo $pid
	                return 0
	        fi
	fi

	# Next try "pidof"
	pid=`pidof $1`
	if [ "$pid" != "" ] ; then
	        echo $pid
	        return 0
	fi

        # Finally try to extract it from ps
        ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
                           { if ((prog == $5) || (("(" prog ")") == $5) ||
                             (("[" prog "]") == $5) ||
                           ((prog ":") == $5)) { print $1 ; exit 0 } }' $1
}

status() 
{
	# Test syntax.
	if [ $# = 0 ] ; then
		msg_Usage " status {program}\n"
		return 1
	fi

	# First try "pidof"
	pid=`pidof $1`
	if [ "$pid" != "" ] ; then
	        nls "%s (pid %s) is running...\n" "$1" "$pid"
	        return 0
        else
                pid=`ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
                           { if ((prog == $5) || (("(" prog ")") == $5) ||
                             (("[" prog "]") == $5) ||
                           ((prog ":") == $5)) { print $1 ; exit 0 } }' $1`
                if [ "$pid" != "" ] ; then
                        nls "%s (pid %s) is running...\n" "$1" "$pid"
                        return 0
                fi
	fi

	# Next try "/var/run/*.pid" files
	if [ -f /var/run/$1.pid ] ; then
	        pid=`head -1 /var/run/$1.pid`
	        if [ "$pid" != "" ] ; then
	                nls "%s dead but pid file exists\n" "$1"
	                return 1
	        fi
	fi
	# See if /var/lock/subsys/$1 exists
	if [ -f /var/lock/subsys/$1 ]; then
		nls "%s dead but subsys locked\n" "$1"
		return 2
	fi
	nls "%s is stopped\n" "$1"
	return 3
}

# Confirm whether we really want to run this service
confirm() {
	echo -n "`nls "Start service"` $1 `nls "(Y)es/(N)o/(C)ontinue? [Y] "`"
	read answer
	case $answer in
		y|Y|t|T|"")
			return 0
		;;
		c|C|k|K)
			return 2
		;;
		n|N)
			return 1
		;;
		*)
			confirm $1
			return $?
		;;
	esac
}

is_yes()
{
	# Test syntax	
	if [ $# = 0 ] ; then
		msg_Usage " is_yes {value}\n"
		return 2
	fi

	# Check value
	[ "$1" = "yes" ] ||\
	[ "$1" = "Yes" ] ||\
	[ "$1" = "YES" ] ||\
	[ "$1" = "true" ] ||\
	[ "$1" = "True" ] ||\
	[ "$1" = "TRUE" ] ||\
	[ "$1" = "1" ] ||\
		return 1
	return 0
}

is_no()
{
	# Test syntax
	if [ $# = 0 ] ; then
		msg_Usage " is_no {value}\n"
		return 2
	fi
	
	# Check value
	[ "$1" = "no" ] ||\
	[ "$1" = "No" ] ||\
	[ "$1" = "NO" ] ||\
	[ "$1" = "false" ] ||\
	[ "$1" = "False" ] ||\
	[ "$1" = "FALSE" ] ||\
	[ "$1" = "0" ] ||\
	[ "$1" = "" ] ||\
		return 1
	return 0
}
