#!/bin/sh
#
# userscripts:	Executes user-defined events.
#
# Version:	$Revision: 1.8 $
#
# chkconfig:	345 99 01
# description:	Executes $HOME/.config/init.d/* start on startup,
#		and $HOME/.config/init.d/* stop on shutdown.

. /etc/rc.d/init.d/functions

ALLOWED=""
BANNED=""
STOP_WAIT_TIME=2
NICE=15
MAX_USER_SCRIPTS=20
RUN_ARGS=""

# subdirectory with user scripts
scripts_dir=".config/init.d"

if [ -f /etc/sysconfig/userscripts ]; then
	. /etc/sysconfig/userscripts
fi

service_name="User init.d scripts"

VALID_SHELLS=""
while read shell; do
	case $shell in
		/*)
			[ -x "$shell" ] && VALID_SHELLS="$VALID_SHELLS $shell"
			;;
	esac
done < /etc/shells

is_on_list()
{
	local word=$1
	local list=$2

	local IFS
	unset IFS
	for tword in $list; do
		[ "$tword" = "$word" ] && return 0
	done
	return 1
}

is_allowed()
{
	local user=$1
	local shell=$2

	is_on_list "$shell" $VALID_SHELLS || return 1
	if [ -n "$ALLOWED" ]; then
		is_on_list "$user" $ALLOWED || return 1
	fi
	if [ -n "$BANNED" ]; then
		is_on_list "$user" $BANNED && return 1
	fi

	return 0
}

run_scripts()
{
	local action="$1"

	SCRIPTS_RUN=0
	local IFS=":"
	getent passwd | while read user pass uid gid name home shell; do
		[ -d "$home/$scripts_dir" ] || continue

		if ! is_allowed "$user" "$shell"; then
			nls "User %s is not allowed to run scripts" "$user"
			continue
		fi

		local USER_SCRIPTS=0
		for script in "$home/$scripts_dir"/*; do

			# skip unrecognized files
			case $script in
				*.init|*.sh)
					;;
				*)
					continue
					;;
			esac

			if [ $((USER_SCRIPTS++)) -ge $MAX_USER_SCRIPTS ]; then
				nls "Maximum number of scripts run for %s was reached" "$user"
				break
			fi

			show "Running %s %s as %s" "$script" "$action" "$user"
			busy

			if [ ! -x "$script" ]; then
				fail
				continue
			fi

			su - "$user" -s /bin/sh -c "exec /sbin/run-fast-or-hide -n '$NICE' $RUN_ARGS -- '$script' '$action'"
			local RET=$?
			deltext
			if [ $RET -eq 250 ]; then
				started
				: $((SCRIPTS_RUN++))
			else
				[ $RET -eq 0 ] && ok || fail
			fi
		done
	done
}

start()
{
	if [ -f /var/lock/subsys/userscripts ]; then
		msg_already_running "$service_name"
		return 1
	fi

	msg_starting "$service_name"; ok

	run_scripts start

	touch /var/lock/subsys/userscripts
}

stop()
{
	if [ ! -f /var/lock/subsys/userscripts ]; then
		msg_not_running "$service_name"
		return 2
	fi

	run_scripts stop

	msg_stopping "$service_name"; busy

	# give them some time to stop, but don't wait for finish
	[ "$SCRIPTS_RUN" -gt 0 ] && sleep $STOP_WAIT_TIME
	ok

	rm -f /var/lock/subsys/userscripts
}

restart()
{
	if [ ! -f /var/lock/subsys/userscripts ]; then
		msg_not_running "$service_name"
		start
		return $?
	fi

	show "Restarting %s service" "$service_name"; ok
	run_scripts restart
}

reload()
{
	if [ ! -f /var/lock/subsys/userscripts ]; then
		msg_not_running "$service_name"
		return 2
	fi

	msg_reloading "$service_name"; ok
	run_scripts reload
}

status()
{
	if [ -f /var/lock/subsys/userscripts ]; then
		nls "$service_name should be running";
	else
		nls "$service_name should be stopped";
	fi
}

RETVAL=0
# See how we were called.
case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
  	status)
		status
		;;
	restart)
		restart
		;;
	reload|force-reload)
		reload
		;;
	*)
		msg_usage "$0 {start|stop|restart|reload|force-reload|status}"
		exit 3
esac

exit $RETVAL
