#!/bin/sh
#
# Copyright (C) 2005-2008 Red Hat, Inc.
#
# This program is Free Software. You may modify and/or redistribute it under
# the terms of the GNU General Public License version 2.
#
# description:  Starts and stops Red Hat Cluster and Storage Remote \
#               Configuration Web Interface (luci)
# chkconfig: - 99 01
#

# Source function library
. /etc/init.d/functions

# Grab the network config file
. /etc/sysconfig/network

# grab luci defaults
. /etc/sysconfig/luci

PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH

ID='luci'
LUCID='/var/lib/luci/bin/runzope'
PIDFILE='/var/lib/luci/var/Z2.pid'
GLOB_PIDFILE='/var/run/luci.pid'
GLOB_LOCKFILE='/var/lock/subsys/luci'

LUCI_USER='luci'
LUCI_GROUP='luci'

LUCI_URL="https://`/bin/hostname`:$LUCI_HTTPS_PORT"

HTTPS_PUBKEY='/var/lib/luci/var/certs/https.pem'
HTTPS_PRIVKEY='/var/lib/luci/var/certs/https.key.pem'

KEY_LIFE_DAYS='1825'
KEY_BITS='2048'

STUNNEL_D='/usr/sbin/stunnel'
STUNNEL_PID='/var/lib/luci/var/stunnel/pid'
STUNNEL_CONF='/var/lib/luci/etc/stunnel.conf'

#
# Only root wants to run this...
#
[ `id -u` = 0 ] || exit 4

#
# If we're not configured, then don't start anything.
#
[ "${NETWORKING}" = "yes" ] || exit 1


https_certs_ok()
{
	if [ ! -f "$HTTPS_PRIVKEY" ]; then
		return 1
	fi

	if [ ! -f "$HTTPS_PUBKEY" ]; then
		return 2
	fi

	return 0
}

generate_https_certs()
{
	echo -n "Generating https SSL certificates...  "
	old_umask=`umask`
	umask 077

	rm -f -- "$HTTPS_PRIVKEY" "$HTTPS_PUBKEY"
	/usr/bin/openssl genrsa -out "$HTTPS_PRIVKEY" "$KEY_BITS" >&/dev/null
	/usr/bin/openssl req -new -x509 -key "$HTTPS_PRIVKEY" -out "$HTTPS_PUBKEY" -days "$KEY_LIFE_DAYS" -set_serial "$(/bin/date +%s)" -config /var/lib/luci/var/certs/cacert.config
	/bin/chmod -- 600 "$HTTPS_PRIVKEY"
	/bin/chmod -- 644 "$HTTPS_PUBKEY"
	/bin/chown -- $LUCI_USER:$LUCI_GROUP "$HTTPS_PRIVKEY" "$HTTPS_PUBKEY"
	ret=$?

	umask $old_umask
	echo "done"
	return $ret
}

stop_luci()
{
	pid_num=`cat -- $PIDFILE 2>/dev/null`
	ret=$?
	if [ $ret -eq 0 ]; then
		kill $pid_num >& /dev/null
		ret=$?
	fi

	if [ $ret -ne 0 ]; then
		pkill -u "$LUCI_USER" -- python >&/dev/null
		ret=$?
	fi
	return $ret
}

stop_stunnel()
{
	pid_num=`cat -- $STUNNEL_PID 2>/dev/null`
	ret=$?
	if [ $ret -eq 0 ]; then
		kill $pid_num >& /dev/null
		ret=$?
	fi

	if [ $ret -ne 0 ]; then
		pkill -u "$LUCI_USER" -- stunnel >&/dev/null
		ret=$?
	fi
	return $ret
}

stop()
{
	stop_stunnel
	max_wait=5
	cur_wait=0
	while [ $cur_wait -lt $max_wait ]; do
		sleep 1
		cur_wait=`expr $cur_wait + 1`
		stunnel_running
		if [ $? -eq 0 ]; then
			break
		fi
	done

	if [ $? -ne 0 ]; then
		errmsg='Failed to stop stunnel'
		return 1
	fi

	stop_luci
	max_wait=10
	cur_wait=0
	while [ $cur_wait -lt $max_wait ]; do
		sleep 1
		cur_wait=`expr $cur_wait + 1`
		luci_running
		if [ $? -eq 0 ]; then
			break
		fi
	done

	if [ $? -ne 0 ]; then
		errmsg='Failed to stop luci'
		return 1
	fi
	return 0
}

start()
{
	https_certs_ok
	if [ $? -ne 0 ]; then
		generate_https_certs
		if [ $? -ne 0 ]; then
			errmsg='An error occurred while generating certificates'
			return 1
		fi
	fi

	sh $LUCID >&/dev/null &

	cur_wait=0
	max_wait=10
	luci_running
	ret=$?
	while [ $ret -ne 1 ] && [ $cur_wait -lt $max_wait ]; do
		sleep 1
		cur_wait=`expr $cur_wait + 1`
		luci_running
		ret=$?
	done

	if [ $ret -ne 1 ]; then
		errmsg='An error occurred while starting luci'
		stop_luci
		return 1
	fi

	sed -e s,\\\(^accept.*=\ \\\)\\\(.*\\\),\\\1$LUCI_HTTPS_PORT, $STUNNEL_CONF | $STUNNEL_D -fd 0
	if [ $? -ne 0 ]; then
		errmsg='An error occurred while starting stunnel'
		stop_luci >& /dev/null
		return 1
	fi

	max_wait=5
	cur_wait=0
	stunnel_running
	ret=$?
	while [ $ret -ne 2 ] && [ $cur_wait -lt $max_wait ]; do
		sleep 1
		cur_wait=`expr $cur_wait + 1`
		stunnel_running
		ret=$?
	done

	if [ $ret -ne 2 ]; then
		errmsg='An error occurred while starting stunnel'
		stop_luci >& /dev/null
		stop_stunnel >& /dev/null 
		return 1
	fi

	return 0
}

luci_running()
{
	LUCI_UP=1

	test -f "$PIDFILE"
	LUCI_PID_EXISTS=$?
	if [ "$LUCI_PID_EXISTS" -eq 0 ]; then
		pgrep -u "$LUCI_USER" -- python >&/dev/null
		if [ $? -ne 0 ]; then
			LUCI_UP=0
			# remove stale pidfile
			rm -f -- "$PIDFILE" >& /dev/null
		fi
	else
		LUCI_UP=0
	fi

	return $LUCI_UP
}

stunnel_running()
{
	ST_UP=2
	pgrep -u "$LUCI_USER" -- stunnel >&/dev/null
	if [ $? -ne 0 ]; then
		ST_UP=0
	fi

	if [ -f "$STUNNEL_PID" ] && [ $ST_UP -eq 0 ]; then
		# stale pidfile
		rm -f -- "$STUNNEL_PID"
	fi
	return $ST_UP
}

system_running()
{
	luci_running
	LUCI_UP=$?

	stunnel_running
	STUNNEL_UP=$?

	res=`echo $LUCI_UP $STUNNEL_UP + p | /usr/bin/dc`
	if [ $res -eq 0 ]; then
		# none up
		return 0
	elif [ $res -eq 3 ]; then
		# both up
		return 1
	elif [ $res -eq 1 ]; then
		# only luci up
		stop_luci
		if [ $? -ne 0 ]; then
			errmsg='Only luci was running and it could not be stopped'
			return 3
		fi
	elif [ $res -eq 2 ]; then
		# only stunnel up
		stop_stunnel
		if [ $? -ne 0 ]; then
			errmsg='Only stunnel was running and it could not be stopped'
			return 4
		fi
	fi
	return 0
}

case $1 in
	start)
		grep True /var/lib/luci/.default_password_has_been_reset >&/dev/null
		if [ $? -ne 0 ]; then
			echo ""
			echo "The admin user password must be set before the luci can start"
			echo "To set it, execute (as root): "
			echo -e "\tluci_admin password\n"
			/usr/bin/logger -t "$ID" -- "Luci startup failed: admin password not set (execute 'luci_admin password')"
			exit 6
		fi

		echo -n "Starting $ID: "
		system_running
		ret=$?
		if [ $ret -eq 0 ]; then
			start
		elif [ $ret -eq 1 ]; then
			# already running
			echo_success
			echo
			exit 0
		elif [ $ret -gt 2 ]; then
			# one of the two processes was running and couldn't be stopped.
			/usr/bin/logger -t "$ID" -- "Luci startup failed: $errmsg"
			exit 1
		fi

		system_running
		if [ $? -eq 1 ]; then
			echo_success
			cat -- "$PIDFILE" > "$GLOB_PIDFILE"
			touch -- "$GLOB_LOCKFILE"
			/usr/bin/logger -t "$ID" -- "Luci startup succeeded"
			/usr/bin/logger -t "$ID" -- "Listening on port $LUCI_HTTPS_PORT; accessible via URL $LUCI_URL"
			echo; echo
			echo "Point your web browser to $LUCI_URL to access luci"
			echo
			exit 0
		else
			echo_failure
			/usr/bin/logger -t "$ID" -- "Luci startup failed $errmsg"
			echo
			exit 1
		fi
	;;

	restart)
		$0 stop
		rtrn=$?
		if [ $rtrn -eq 0 ];  then
			$0 start
			rtrn=$?
		fi
	;;

	condrestart)
		system_running
		rtrn=$?
		if [ $rtrn -eq 1 ]; then
			$0 restart
			rtrn=$?
		fi
	;;

	status)
		system_running
		if [ $? -eq 1 ]; then
			echo "$ID is running..."
			rtrn=0
		else
			echo "$ID is stopped"
			rtrn=7
		fi
	;;

	stop)
		echo -n "Shutting down $ID: "
		system_running
		rtrn=$?
		if [ $rtrn -eq 1 ]; then
			stop
			if [ $? -eq 0 ]; then
				rm -f -- "$GLOB_PIDFILE"
				rm -f -- "$GLOB_LOCKFILE"
				/usr/bin/logger -t "$ID" -- "Luci shutdown succeeded"
				rtrn=0
			else
				/usr/bin/logger -t "$ID" -- "Luci shutdown failed"
				rtrn=1
			fi
		elif [ $rtrn -eq 0 ]; then
			rtrn=0
		else
			rtrn=1
		fi

		if [ $rtrn -eq 0 ]; then
			echo_success
		else
			echo_failure
		fi
		echo
	;;

	try-restart)
		rtrn=3
	;;

	reload)
		rtrn=3
	;;

	*)
		echo "Usage: $0 {start|stop|status|restart|condrestart|reload}"
		rtrn=3
	;;
esac

exit $rtrn
