#!/bin/sh
#
# License: Copyright 2012 SpinetiX S.A. This file is licensed
#          under the terms of the GNU General Public License version 2.
#          This program is licensed "as is" without any warranty of any
#          kind, whether express or implied.
#
# Copyright 1999-2003 MontaVista Software, Inc.
# Copyright 2002, 2003, 2004 Sony Corporation
# Copyright 2002, 2003, 2004 Matsushita Electric Industrial Co., Ltd.
#
### BEGIN INIT INFO
# Required-Start:
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 5
# Default-Stop:
# Short-Description: Starting/stopping SpinetiX's Bonsai content player
# Description: Starting/stopping SpinetiX's Bonsai content player
### END INIT INFO
# chkconfig: 235 90 10

# Init script information
INIT_NAME=raperca
DESC="Bonsai content player"

# PHP fastcgi content processing server
# We disable all functions that allow to spawn sub-processes via
# disable_functions (this directive can only be specified in php.ini or
# in command line but not in php.ini sections); we also disable all the
# pcntl functions that have a side effect
DAEMON2=/usr/bin/php-cgi
SOCK2=/var/run/raperca/fcgi-php/sock
PHP_PCNTL_FUNCTIONS="pcntl_alarm,pcntl_exec,pcntl_fork,pcntl_setpriority,pcntl_signal_dispatch,pcntl_signal,pcntl_sigprocmask,pcntl_sigtimedwait,pcntl_sigwaitinfo,pcntl_wait,pcntl_waitpid"
PHP_DISABLE_FUNCTIONS="passthru,exec,system,popen,shell_exec,proc_open,${PHP_PCNTL_FUNCTIONS}"
ARGS2="-b $SOCK2 -d disable_functions=${PHP_DISABLE_FUNCTIONS}"
BASENAME2=php-raperca
USER2=nobody
GROUP2=nogroup
PIDFILE2=/var/run/$BASENAME2.pid

# Individual Deamon information
DAEMON3=/usr/bin/raperca
CONFFILE3=/etc/raperca/spxconfig.xml
ALTCONFFILE3=/etc/raperca/spxconfig-nonconfigured.xml
ARGS3="-daemon"
BASENAME3=${DAEMON3##*/}
USER3="raperca"
GROUP3="raperca"
PROGRESSDIR="/dev/raperca"
LOADKMODS=/etc/raperca/loadmodules.sh
CLEANCACHE=/var/spool/raperca/clean-cache
CLEANWEBSTORAGE=/var/spool/raperca/clean-webstorage
SAFEINDICATOR=/var/run/raperca.safe
SAFEREBOOTDELAY=3600
FONTSENTINEL=/var/run/raperca/font-sentinel

BOOTCOUNTFILE=/proc/bootcount

# Set up the path variables
. /etc/raperca/init-functions
init_dirs "$2"

# We run at nice level -2, kernel threads run at nice -5 or lower
# and essential system daemons such as udev run at -4, so -2
# is a good compromise between boost and not adding system latency
# (which could also adversely affect raperca)
NICELEVEL3=-2

# Load init script configuration
[ -f /etc/default/$INIT_NAME ] && . /etc/default/$INIT_NAME

# Source the init script functions
. /etc/init.d/init-functions

# Verify daemons are installed
[ "$1" = "status" ] && NFOUND=4 || NFOUND=5
test -f $DAEMON2 || exit $NFOUND
test -f $DAEMON3 || exit $NFOUND
test -f $LOADKMODS || exit $NFOUND
test -d $STARTDIR || exit $NFOUND
test -f $CONFFILE3 || exit $NFOUND
test -f $ALTCONFFILE3 || exit $NFOUND

make_progress_dir() {
    [ -d "$PROGRESSDIR" ] || mkdir -p "$PROGRESSDIR" || return 1
    chown "$USER3" "$PROGRESSDIR" || return 1
}

make_bootcount_rw() {
    [ -f "$BOOTCOUNTFILE" ] || return 0
    chmod 0664 "$BOOTCOUNTFILE" && chgrp "$GROUP3" "$BOOTCOUNTFILE"
}

make_font_sentinel() {
    [ -f "$FONTSENTINEL" ] && return
    # The font sentinel file should be a valid XML fontconfig file
    # to avoid error messages from fontconfig
    cat > "$FONTSENTINEL" <<EOF
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Dummy sentinel config file to trigger font rescan on mtime change -->
</fontconfig>
EOF
}

# Each init script action is defined below...

start() {
	local RET ERROR=
	local BOOTCOUNT

	log_status_msg "Starting $DESC: " -n

	if [ -f $BOOTCOUNTFILE ]; then
	    BOOTCOUNT=$(cat $BOOTCOUNTFILE)
	else
	    BOOTCOUNT=0
	fi

	log_status_msg "kernel-mods" -n
	$LOADKMODS
	RET=$?
	ERROR=
	if [ $RET -eq 0 ]; then
		log_success_msg ", " -n
	else
		log_failure_msg " failed ($RET: $ERROR)."
		return 1
	fi

	log_status_msg "clean tmp" -n
	clean "$TMPDIR"
	log_success_msg ", " -n

	if [ $BOOTCOUNT -ge 2 ]; then
	    log_warning_msg "clean cache (bootcount >= 2)" -n
	    clean $CACHEDIR
	    log_success_msg ", " -n
	elif [ -f "$CLEANCACHE" ]; then
	    log_status_msg "clean cache (requested)" -n
	    clean $CACHEDIR
	    log_success_msg ", " -n
	fi
	if [ -f "$CLEANWEBSTORAGE" ]; then
	    log_status_msg "clean web storage (requested)" -n
	    clean $WEBSTORAGEDIR
	    log_success_msg ", " -n
	fi
	if [ -f "$CLEANCACHE" -o -f "$CLEANWEBSTORAGE" ]; then
	    rm -f "$CLEANCACHE" "$CLEANWEBSTORAGE"
            # be sure cleanup is on stable storage and we do not retrigger it.
	    sync 
	fi

	if [ $BOOTCOUNT -ge 3 ]; then
	    log_warning_msg "starting in safe mode (bootcount >= 3)" -n
	    ARGS3="$ARGS3 -safemode"
	    touch $SAFEINDICATOR
	    # NOTE: we use sleep instead of shutdown's own delay capabilities
	    # because the latter precludes any other shutdown calls to succeed
	    (sleep $SAFEREBOOTDELAY; \
		logger -p user.notice -t raperca-safe-mode -- \
		"safe mode rebooting automatically (${SAFEREBOOTDELAY}s)" ; \
		shutdown -r now rebooting due to safe mode) &
	    log_success_msg ", " -n
	fi

	log_status_msg "$BASENAME2" -n
	RET=$?
	ERROR="failed creating / setting up socket dir"
	if [ $RET -eq 0 ]; then
	    # NOTE: each child takes about 1.5 MB of private memory
	    PHP_FCGI_CHILDREN=1 PHP_FCGI_MAX_REQUESTS=500 \
		start-stop-daemon -S -q -x $DAEMON2 -u $USER2 -c $USER2:$GROUP2 \
		-b -m -p $PIDFILE2 -- $ARGS2
	    RET=$?
	    ERROR="failed starting php-fcgi"
	fi
	if [ $RET -eq 0 ]; then
	        sleep 2 # Give time for php to really start up
		log_success_msg ", " -n
	else
		log_failure_msg " failed ($RET: $ERROR)."
		return 1
	fi

	log_status_msg "splash stop" -n
	splashd -n -k
	RET=$?
	if [ $RET -eq 0 ]; then
		log_success_msg ", " -n
	else
		log_failure_msg " failed ($RET: $ERROR)."
		return 1
	fi

	if [ ! -e /etc/spinetix/configured ]; then
	    log_status_msg "setting max resolution (unconfigured system)" -n
	    /etc/init.d/vidmode setmax
	    log_success_msg ", " -n
	fi

	log_status_msg "$BASENAME3" -n
	[ -f /etc/spinetix/configured ] && conffile=$CONFFILE3 || conffile=$ALTCONFFILE3
	make_progress_dir && make_bootcount_rw && make_font_sentinel && \
	    cd "$STARTDIR" && \
	    nice -n $NICELEVEL3 $DAEMON3 $ARGS3 $conffile
	RET=$?
	if [ $RET -eq 0 ]; then
		log_success_msg "."
	else
		log_failure_msg " failed ($RET: $ERROR)."
		return 1
	fi
	
	log_status_msg ""
	return 0
}

stop () {
	local RET ERROR=
	local RETF

	log_status_msg "Stopping $DESC: " -n
	RETF=0

	log_status_msg "$BASENAME3" -n
	killproc $BASENAME3
	RET=$?
	if [ $RET -eq 0 ]; then
		log_success_msg ", " -n
	else
		log_failure_msg "failed ($RET: $ERROR), " -n
		RETF=1
	fi

	log_status_msg "$BASENAME2" -n
	start-stop-daemon -K -q -o -x $DAEMON2 -u $USER2
	RET=$?
	if [ $RET -eq 0 ]; then
		log_success_msg "."
	else
		log_failure_msg " failed ($RET: $ERROR)."
		RETF=1
	fi

	log_status_msg ""
	return $RETF
}

restart() {
	local RET

	log_status_msg "Restarting $DESC..."
	stop
	sleep 2
	start
	RET=$?

	return $RET
}

tryrestart() {
	local RET

	pidstatus $BASENAME1
	RET=$?
	if [ $RET -eq 0 ]; then
		restart
		RET=$?
	else
		RET=7
	fi

	return $RET
}

#
# if the service does not support reload return code 3 should
# be the result...
#
reload() {
	local RET

	log_status_msg "Reloading $DESC configuration..." -n
	# killproc $BASENAME1 -HUP
	#
	# repeat as necessary...
	#
	log_success_msg "done."

	# No support for reload
	return 3
}

forcereload() {
	local RET

	reload
	RET=$?
	if [ $RET -ne 0 ]; then
		restart
		RET=$?
	fi
	
	return $RET
}

status() {
	local RET
	
	printstatus $BASENAME1
	RET=$?

	return $RET
}

#
# Everything after this should be the same for all init scripts
#
# See the policy manual for information on actions and return codes.
#

parse() {
	case "$1" in
  start)
			start
			return $?
	;;
  stop)
			stop
			return $?
	;;
		restart)
			restart
			return $?
			;;
		try-restart)
			tryrestart
			return $?
			;;
		reload)
			reload
			return $?
			;;
		force-reload)
			forcereload
			return $?
			;;
		status)
			status
			return $?
	;;
  *)
			echo "Usage: $INIT_NAME " \
			"{start|stop|restart|try-restart|reload|" \
			"force-reload|status} [service-dir]" >&2
	;;
	esac
	
	return 1
}

parse $@



