#!/bin/sh
#
# $Id: musicipserver.in 2458 2010-07-21 11:52:43Z chris $
#

# PROVIDE: musicipserver
# BEFORE:  squeezeboxserver
# REQUIRE: LOGIN
# KEYWORD: shutdown

#
# Add the following lines to /etc/rc.conf to enable musicipserver:
#
#musicipserver_enable="YES"
#

. /etc/rc.subr

name="musicipserver"
procname="/usr/local/bin/MusicMagicServer"
status_cmd="${name}_status_cmd"
start_cmd="${name}_start_cmd"
stop_cmd="${name}_stop_cmd"

examplesdir="/usr/local/share/examples/musicipserver"
datadir="/usr/local/share/musicipserver"
logdir="/var/log/musicipserver"
rundir="/var/run/musicipserver"
statedir="/var/db/musicipserver"

serverlogfile=${logdir}/server.log
mipcorelogfile=${logdir}/mipcore.log
pidfile=${rundir}/${name}.pid
serverflogpidfile=${rundir}/${name}-server-flog.pid
mipcoreflogpidfile=${rundir}/${name}-mipcore-flog.pid
mipcoretailpidfile=${rundir}/${name}-mipcore-tail.pid
serverinfifo=${rundir}/${name}-fifo-in
serveroutfifo=${rundir}/${name}-fifo-out
mipcorelogfifo=${rundir}/${name}-mipcore-fifo

empty="/usr/local/bin/empty"
flog="/usr/local/bin/flog"
tail="/usr/bin/tail"

load_rc_config $name
musicip_enable=${musicip_enable:-"NO"}
musicip_user="mipserv"
musicip_group="mipserv"
musicip_port="10002" # Should probably pull this in from mmm.ini

musicipserver_check_pidfile()
{
	check_pidfile ${pidfile} ${empty}
}

musicipserver_status_cmd()
{

	pid=$(musicipserver_check_pidfile)

	if [ -n "${pid}" ]; then
		echo "${name} is running as pid ${pid}."
	else
		echo "${name} is not running."
		return 1
	fi
}

musicipserver_start_cmd()
{
	# Check whether we're already running
	pid=$(musicipserver_check_pidfile)

	if [ -n "${pid}" ]; then
		echo "${name} already running? (pid=${pid})."
		return 1
	fi

	echo "Starting ${name}."

	# MusicIP server will fail to start if there are any sockets still active on port 10002.
	waited=0
	while netstat -n \
	    | egrep "^tcp4 +[[:digit:]]+ +[[:digit:]]+ +([[:digit:]]+\.){4}$musicip_port +([[:digit:]]+\.){4}[[:digit:]]+ +TIME_WAIT\$" \
	    > /dev/null; do

		if [ $waited = 0 ]; then
			echo -n "Waiting on sockets"
			waited=1
		else
			echo -n "."
		fi

		sleep 1
	done

	if [ $waited = 1 ]; then
		echo "."
	fi


	mkfifo ${mipcorelogfifo} \
	    && chown ${musicip_user}:${musicip_group} ${mipcorelogfifo} \
	    && chmod 600 ${mipcorelogfifo}

	daemon -c -f -p ${mipcoretailpidfile} -u ${musicip_user} \
	    "sh" "-c" "exec ${tail} -f ${statedir}/log.txt > ${mipcorelogfifo}"

	daemon -c -f -p ${mipcoreflogpidfile} -u ${musicip_user} \
	    "sh" "-c" "exec ${flog} -t -T '%b %d %T ' ${mipcorelogfile} < ${mipcorelogfifo}"

	su -m ${musicip_user} -c \
	    "cd / && < /dev/null >& /dev/null ${empty} -f -i ${serverinfifo} -o ${serveroutfifo} -p ${pidfile} ${procname} -exec ${datadir} -data ${statedir} -verbose -logex start" \
	    && chmod -x ${serverinfifo} ${serveroutfifo} ${pidfile}

	daemon -c -f -p ${serverflogpidfile} -u ${musicip_user} \
	    "sh" "-c" "exec ${flog} -t -T '%b %d %T ' ${serverlogfile} < ${serveroutfifo}"


	# "MusicMagicServer start" either exits is there is an error, or forks is there isn't.
	# To check whether musicipserver starter successfully, we watch the 'empty' process we
	# created, using its pidfile.  If it disappears, we know that musicipserver failed, else
	# if it two or more child processes, we know it started successfully.

	while true; do

		pid=$(musicipserver_check_pidfile)

		if [ -z "${pid}" ]; then
			echo "${name} failed to start."
			_musicipserver_stop_cmd
			return 1
			break;
		elif [ $(pgrep -P ${pid} | wc -l) -gt 1 ]; then
			break
		fi

		sleep 1

	done

}

musicipserver_stop_cmd()
{

	echo "Stopping ${name}."

	_musicipserver_stop_cmd

}

_musicipserver_stop_cmd()
{

	pid=$(musicipserver_check_pidfile)
	if [ -n "${pid}" ]; then
		su -m ${musicip_user} -c "${procname} stop" > /dev/null 2>&1 \
		    && wait_for_pids ${pid}
	fi


	pid=$(check_pidfile ${serverflogpidfile} ${flog})
	if [ -n "{$pid}" ]; then
		kill ${pid} > /dev/null 2>&1 \
		    && wait_for_pids ${pid} \
		    && rm ${serverflogpidfile}
	fi

	pid=$(check_pidfile ${mipcoretailpidfile} ${tail})
	if [ -n "{$pid}" ]; then
		kill ${pid} > /dev/null 2>&1 \
		    && wait_for_pids ${pid} \
		    && rm ${mipcoretailpidfile}

	fi

	pid=$(check_pidfile ${mipcoreflogpidfile} ${flog})
	if [ -n "{$pid}" ]; then
		kill ${pid} > /dev/null 2>&1 \
		    && wait_for_pids ${pid} \
		    && rm ${mipcoreflogpidfile}
	fi

	if [ -p ${mipcorelogfifo} ]; then
		rm ${mipcorelogfifo}
	fi

}

run_rc_command "$1"
