#!/bin/sh

# PROVIDE: sipxpbx
# REQUIRE: NETWORKING SERVERS postgresql
# BEFORE: apache22

#
# Add the following line to /etc/rc.conf to enable sipXpbx
# sipxpbx_enable (bool):     Set to "NO" by default.
#                            Set it to "YES" to enable sipxpbx

. %%RC_SUBR%%

name="sipxpbx"
rcvar=`set_rcvar`

extra_commands="status"
stop_cmd="sipxpbx_stop"
start_cmd="sipxpbx_start"
status_cmd="sipxpbx_status"

[ -z "$sipxpbx_enable" ] && sipxpbx_enable="NO"

# Source configuration
. %%PREFIX%%/etc/sipxpbx/config.defs

iam=`whoami`

# Set the limit for core file size based on the SIPX_CORELIMIT
# variable in config.defs.
# This either allows core files to be generated when sipX
# processes crash (if SIPX_CORELIMIT is "unlimited"), or
# disallows it (if SIPX_CORELIMIT is "0").
ulimit -c ${SIPX_CORELIMIT:-0}

# XXX
# The linux version of this start up file checks to see
# if coredumps can be made of suid processes and if possible
# modifies the system to do so.  This makes it possible to
# debug sipXvxml.  I don't think this is the appropriate place
# to do this.  If you want to enable this feature,
#    sysctl kern.sugid_coredump=1

# This should somehow be syncronized with what's in
# the ProcessDefinitions.xml and Watchdog.xml
sipx_processes="watchdog "`find %%PREFIX%%/etc/sipxpbx/process.d -name '*.process.xml' -print | sed -e 's/.process.xml//g' -e 's,%%PREFIX%%/etc/sipxpbx/process.d/,,g'`

subproc_start ()
{
	proc_name=$1; shift
	proc_cmd=%%PREFIX%%/bin/$proc_name.sh

	if [ $iam = sipx ]
	then
		( exec $proc_cmd ) < /dev/null &
	elif [ $iam = root ]
	then
		su sipx -c "$proc_cmd" < /dev/null &
	else
		echo "You must be able to start as sipx" 1>&2
		exit 1
	fi

	for ticks in 3 2 1 0
	do
		sleep 1
		test -e %%LOCALSTATEDIR%%/run/sipxpbx/$proc_name.pid && break
	done
	if [ ! -e %%LOCALSTATEDIR%%/run/sipxpbx/$proc_name.pid ]
	then
		STATUS=1
		echo "$proc_name did not start"
	fi

	return $STATUS
}

subproc_stop ()
{

	proc_name=$1; shift

	STATUS=0

	pidFile=%%LOCALSTATEDIR%%/run/sipxpbx/$proc_name.pid
	if [ -r $pidFile ]
	then
		PID=`cat $pidFile` 2> /dev/null
		kill $PID 2> /dev/null
	fi
}

subproc_stop_check ()
{

	proc_name=$1; shift

	STATUS=0

	pidFile=%%LOCALSTATEDIR%%/run/sipxpbx/$proc_name.pid
	PID=`cat $pidFile`
	found_pid=`ps -ax | awk "{if (\\\$1 == $PID) print \\\$1}"`
	if [ -n "$found_pid" ]
	then
		for ticks in 5 4 3 2 1 0
		do
			sleep 1
			found_pid=`ps -ax | \
			    awk "{if (\\\$1 == $PID) print \\\$1}"`
			test -n "$found_pid" || break
		done
		found_pid=`ps -ax | awk "{if (\\\$1 == $PID) print \\\$1}"`
		if [ -n "$found_pid" ]
		then
			kill -9 $PID 2> /dev/null
			for ticks in 3 2 1 0
			do
				sleep 1
				found_pid=`ps -ax | \
				    awk "{if (\\\$1 == $PID) print \\\$1}"`
				test -n "$found_pid" || break
			done
		fi

		found_pid=`ps -ax | awk "{if (\\\$1 == $PID) print \\\$1}"`
		if [ -n "$found_pid" ]
		then
			echo "$proc_name did not stop"
		fi

		rm -f $pidFile
	fi
}

subproc_configtest ()
{

	proc_name=$1; shift
	proc_cmd=%%PREFIX%%/bin/$proc_name.sh

	status=0
	if [ -x $proc_cmd ]
	then
		if [ $iam = sipx ]
		then
			$proc_cmd --configtest
			status=$?
		elif [ $iam = root ]
		then
			su sipx -c \
			    "test -x $proc_cmd && $proc_cmd --configtest; echo \$? > %%LOCALSTATEDIR%%/run/sipxpbx/$proc_name.result"
			status=`cat %%LOCALSTATEDIR%%/run/sipxpbx/$proc_name.result`
			rm -f %%LOCALSTATEDIR%%/run/sipxpbx/$proc_name.result
		else
			echo "You must be able to run as sipx" 1>&2
		fi
	else
		echo "Installation error?  '$proc_cmd' not found" 1>&2
	fi

	test "$status" = 0 && echo "   OK"
	# This assures that our return is either 0 or 1, regardless of what
	# $status was.
	return $?
}

subproc_status ()
{

	proc_name=$1

	pidFile=%%LOCALSTATEDIR%%/run/sipxpbx/$proc_name.pid
	PID=`cat $pidFile`

	echo -n "Checking $proc_name: "
	found_pid=`ps -ax | awk "{if (\\\$1 == $PID) print \\\$1}"`
	if [ -n "$found_pid" ]
	then
		echo "Running"
	else
		echo "Not Running"
	fi
}


start_check ()
{

	echo -n "Checking $1:"
	echo "Check $1" > $steperrfile
	echo -n "   " >> $steperrfile
}

finish_check ()
{

	check_status=$1
	STATUS=$(($STATUS+$check_status))

	if [ $check_status -eq 0 ]
	then
		echo "Success"
		cat /dev/null > $steperrfile
	else
		echo "Failure"
		cat $steperrfile >> $errfile
		echo "" >> $errfile
	fi
	echo ""
}

initialize_databases ()
{

	##
	## XXX
	## Verbatim from the linux init script.
	##
	## The installation process cannot create the postgres databases
	##  because (apparently) the network must be initialized first.
	## Since we have to have root privs for some of the setup operations,
	##  they must be done explicitly here rather than in the wrapper
	##  scripts (which are run as user sipx)

	# check to see if we need to do the initial database setup for
	# sipxconfig
	if test "CONFIG_SERVER_DISABLED" != "TRUE"
	then
		%%PREFIX%%/bin/sipxconfig.sh --setup
	fi
	# and the cdr database setup for the proxies and call resolver
	if test -x %%PREFIX%%/sipxcallresolver.sh
	then
		%%PREFIX%%/bin/sipxcallresolver.sh --setup
	fi
}

## High-level configtest function
## Verify that the prerequisites for running sipX are OK.
do_check ()
{

	## Do the 'global' check first, then call each shell script
	## to let it do its own checks (using the configtest wrapper
	## function).

	## Start with a good status, accumulate each check result into this
	STATUS=0

	## All output is captured in a temporary file,
	##   which is displayed at the end iff $STATUS != 0
	errfile=/tmp/sipxpbx_check.$$.log
	steperrfile=/tmp/sipxpbx_check_step.$$.log
	cat /dev/null > $errfile
	cat /dev/null > $steperrfile

	## Check to see that SSL is configured.  THIS SHOULD BE FIRST.
	start_check "TLS/SSL configuration"
	if ! [ -e %%PREFIX%%/etc/sipxpbx/ssl/ssl.key -a -e %%PREFIX%%/etc/sipxpbx/ssl/ssl.crt ]
	then
		cat <<EOF >> $steperrfile
	SSL key and/or certificate not found (%%PREFIX%%/etc/sipxpbx/ssl/ssl.{key,crt})

	Run setup wizard or see the instructions in
	    %%PREFIX%%/share/doc/sipX/INSTALL.ssl
EOF

		# If this has not been done, then lots of other stuff is
		# going to fail in non-obvious ways.  Usually, this
		# failure means that this is the first reboot after sipxpbx
		# was activated, and the setup wizard has not been run yet.
		# Rather than let things go and appear to be partly working,
		# just bail out now.
		finish_check 1	# force error
		cat $steperrfile 1>&2
		exit 1
	else
		## Rehash certificate authorities certificates.  If this
		## fails, it will be caught below.
		%%PREFIX%%/bin/ssl-cert/ca_rehash > /dev/null 2>&1

		## check certificate
		%%PREFIX%%/bin/ssl-cert/check-cert.sh \
		    --name $SIPXCHANGE_DOMAIN_NAME --name $MY_FULL_HOSTNAME \
		    --fail 5 %%PREFIX%%/etc/sipxpbx/ssl/ssl.crt \
		    >> $steperrfile 2>&1
		ssl_status=$?
	fi
	finish_check $ssl_status

	initialize_databases

	## Regenerate httpd configuration files from their .in's
	%%PREFIX%%/bin/httpd-sipxchange-config.sh

	# XXX skip this - a check is run when apache is started
	## check apache configuration files
#	start_check "apache"
	# XXX use our common httpd.conf, not the sipX special one
#	%%PREFIX%%/sbin/httpd -t -f %%PREFIX%%/etc/apache22/httpd.conf >> $steperrfile 2>&1
#	finish_check $?

	## Check to see that hosts file does not have extra names on
	## localhost addresses
	start_check "/etc/hosts file"
	localhostStatus=0
	badNames=/tmp/badnames.$$
	cat /dev/null > $badNames
	sed 's/#.*//' /etc/hosts \
	    | awk '$1 == "127.0.0.1" {for (n = 2; n <= NF; n++) print $n;}' \
	    | while read name ; \
	    do
		case $name in
			localhost)
				;;
			localhost.localdomain)
				;;
			*)
				echo "	$name" >> $badNames
				;;
		esac
	    done
	if [ -s $badNames ]
	then
		cat <<EOF >> $steperrfile
The 127.0.0.1 address should map only to the names
  'localhost.localdomain' and 'localhost'.

  Any other name for that address may cause routing or authentication errors.

  Remove the following names from the 127.0.0.1 line in /etc/hosts:
EOF
		cat $badNames >> $steperrfile
		localhostStatus=1
	fi
	rm -f $badNames
	finish_check $localhostStatus

	# Iterate throught he processes and let each shell script do its
	# own checks.
	for process in $sipx_processes
	do
		start_check "$process"
		subproc_configtest $process >> $steperrfile 2>&1
		finish_check $?
	done

	testdate=`date -u +%Y-%m-%dT%H:%M:%S`
	if [ $STATUS -ne 0 ]
	then
		(echo ""; echo "sipXpbx configuration problems found:" \
		echo ""; cat $errfile ) | logger -s -t sipXpbx -p daemon.err
		echo "$testdate sipXpbx configuration problems found:" \
		    >> %%LOCALSTATEDIR%%/log/sipxpbx/configtest.log
		cat $errfile >> %%LOCALSTATEDIR%%/log/sipxpbx/configtest.log
	else
		echo "$testdate configtest passed" >> %%LOCALSTATEDIR%%/log/sipxpbx/configtest.log
	fi
	rm -f $errfile

	return $STATUS
}

sipxpbx_stop ()
{

	# Iterate through the list of processes, killing each one
	for process in $sipx_processes
	do
		subproc_stop $process
	done
	for process in $sipx_processes
	do
		subproc_stop_check $process
	done
}

sipxpbx_start ()
{

	## Clean up various temporary files and locks.

	# Clean up IMDB and all its dependent files.
	%%PREFIX%%/bin/autodel sipx

	# Remove the named semaphores.
	rm -f %%LOCALSTATEDIR%%/sipxdata/tmp/imdb.*

	# Remove the watchdog's temporary files.
	rm -f %%LOCALSTATEDIR%%/sipxdata/tmp/processAlias.dat \
	    %%LOCALSTATEDIR%%/sipxdata/tmp/locked.lck

	## Check configuration
	do_check || echo "Attempting to start despite configuration problems"

	### Start the programs.

	# Ensure that sipXvsml is owned by root and that the
	# UID premission bit is set.
	chown root %%PREFIX%%/bin/sipXvxml
	chmod 4755 %%PREFIX%%/bin/sipXvxml

	# Start up the watchdog
	# Start the watchdog with SIPX_LOGDIR as the working directory,
	# so that any core files it produces will be put there.
	cd %%LOCALSTATEDIR%%/log/sipxpbx
	subproc_start watchdog

	# Wait for keepalive to prime the IMDB, as the CGIs need them
	for seconds in 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
	do
		test -e %%LOCALSTATEDIR%%/run/sipxpbx/keepalive.pid && break
		[ $seconds -eq 0 ] && break
		sleep 1
	done

	[ $seconds -ne 0 ] && echo "sipxpbx" || echo "keepalive pid never appeard"
}

sipxpbx_status ()
{

	for process in $sipx_processes
	do
		subproc_status $process
	done
}

load_rc_config $name
run_rc_command "$1"


syntax highlighted by Code2HTML, v. 0.9.1