#!/sbin/sh
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# This file is part of FRRouting.
#
# FRRouting is free software; you can redistribute it and/or modify 
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# FRRouting is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with FRRouting; see the file COPYING.  If not, write to 
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
# Boston, MA 02111-1307, USA.
#
# Starts/stops the given daemon

SMFINCLUDE=/lib/svc/share/smf_include.sh
ROUTEADMINCLUDE=/lib/svc/share/routing_include.sh
GLOBAL_OPTIONS="PAfiug"
DAEMON_PATH=@sbindir@
USER=@enable_user@
GROUP=@enable_group@

# handle upgrade of daemon-args SMF property to new routeadm properties
# used during upgrade too by routeadm.
# relevant to S10U4+ only.
handle_routeadm_upgrade () {
	GLOBAL_OPTIONS="PAfiug"
	
	daemon_args=`get_daemon_args $SMF_FMRI`
	
	if [ -n "$daemon_args" ]; then
		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
			"$GLOBAL_OPTIONS" "P" vty_port 0
		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
			"$GLOBAL_OPTIONS" "A" vty_address
		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
			"$GLOBAL_OPTIONS" "f" config_file
		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
			"$GLOBAL_OPTIONS" "i" pid_file
		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
			"$GLOBAL_OPTIONS" "u" user
		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
			"$GLOBAL_OPTIONS" "g" group
		
		case "$1" in
		zebra)
			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
				"${GLOBAL_OPTIONS}b" "b" batch true false
			;;
		ripd|ripngd)
			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
				"${GLOBAL_OPTIONS}r" "r" retain true false
			;;
		bgpd)
			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
				"${GLOBAL_OPTIONS}rnp" "r" retain true false
			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
				"${GLOBAL_OPTIONS}rnp" "n" no_kernel true false
			set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
				"${GLOBAL_OPTIONS}rnp" "p" bgp_port
		esac
		clear_daemon_args $SMF_FMRI
	fi
}

upgrade_config () {
	DAEMON=$1
	# handle upgrade of SUNWzebra to FRRouting
	if [ -d "/etc/frr" -a ! -f "/etc/frr/${DAEMON}.conf" ] ; then
		if [ -f "/etc/sfw/zebra/${DAEMON}.conf" ] ; then
			cp "/etc/sfw/zebra/${DAEMON}.conf" \
				"/etc/frr/${DAEMON}.conf.upgrade" \
				|| exit $SMF_EXIT_ERR_FATAL
			chown "${USER}:${GROUP}" "/etc/frr/${DAEMON}.conf.upgrade" \
				|| exit $SMF_EXIT_ERR_FATAL
			chmod 0600 "/etc/frr/${DAEMON}.conf.upgrade" \
				|| exit $SMF_EXIT_ERR_FATAL
			mv "/etc/frr/${DAEMON}.conf.upgrade" "/etc/frr/${DAEMON}.conf" \
				|| exit $SMF_EXIT_ERR_FATAL
		fi
	fi

	if [ ! -f "/etc/frr/${DAEMON}.conf" ] ; then
		touch "/etc/frr/${DAEMON}.conf.new" \
			|| exit $SMF_EXIT_ERR_FATAL
		chown "${USER}:${GROUP}" "/etc/frr/${DAEMON}.conf.new" \
			|| exit $SMF_EXIT_ERR_FATAL
		chmod 0600 "/etc/frr/${DAEMON}.conf.new" \
			|| exit $SMF_EXIT_ERR_FATAL
		mv "/etc/frr/${DAEMON}.conf.new" "/etc/frr/${DAEMON}.conf" \
			|| exit $SMF_EXIT_ERR_FATAL
	fi
}

# Relevant to S10+
frr_is_globalzone () {
	if [ "${FRR_INIT_ZONENAME:=`/sbin/zonename`}" = "global" \
		-o `/sbin/zonename -t` = "exclusive" ]; then
		return 0
	else
		return 1
	fi
}

routeadm_daemon_args () {
	# globals
	args="`get_daemon_option_from_property $SMF_FMRI config_file f`"
	args="${args} `get_daemon_option_from_property $SMF_FMRI vty_port P`"
	args="${args} `get_daemon_option_from_property $SMF_FMRI vty_address A`"
	args="${args} `get_daemon_option_from_property $SMF_FMRI pid_file i`"
	
	# user and group we need for config file upgrade..
	SMF_USER=`get_routeadm_property $SMF_FMRI user`
	SMF_GROUP=`get_routeadm_property()$SMF_FMRI group`
	if [ "${SMF_USER}" ] ; then
		USER="${SMF_USER}"
		args="${args} -u ${SMF_USER}"
	fi
	if [ "${SMF_GROUP}" ] ; then 
		GROUP="${SMF_GROUP}"
		args="${args} -g ${SMF_GROUP}"
	fi

	case $1 in
	zebra)
		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI batch -b true`"
		;;
	ripd|ripngd)
		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
		;;
	bgpd)
		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI no_kernel -n true`"
		args="${args} `get_daemon_option_from_property $SMF_FMRI bgp_port p 179`"
		;;
	esac
	echo ${args}
}

# Include smf functions, if available. If not, define smf_present to indicate
# there is no SMF. Should allow this script to work pre-S10.
if [ -f "$SMFINCLUDE" ] ; then
	. "$SMFINCLUDE";
	
	# source the SMF-routeadm include if present..
	if [ -f "$ROUTEADMINCLUDE" ] ; then
		. "$ROUTEADMINCLUDE"
	fi
else
	# pre-SMF system, fake up any functions and exit codes
	# which SMFINCLUDE usually provides.
	smf_present () {
		return 1
	}
	SMF_EXIT_OK=0;
	SMF_EXIT_ERR_CONFIG=96;
	SMF_EXIT_ERR_FATAL=95;
fi
	
# if there's no SMF, set some default DAEMON_ARGS
smf_present || DAEMON_ARGS=""

usage () {
	if smf_present ; then
		echo "Usage: $0 <daemon>";
	else
		echo "Usage: $0 <stop|start> <daemon> <daemon arguments>";
	fi
	echo "The --pid_file argument is implied";
	echo "This help message: $0 <help|usage>";
}

# parse arguments, different according to SMF or not.
case $1 in
	'help' | 'usage')
		usage
		exit $SMF_EXIT_OK
		;;
esac

if smf_present ; then
	FRR_METHOD="start"
else
	FRR_METHOD="$1"
	shift;
fi

DAEMON="$1"

# daemon path must be given
if [ -z "$DAEMON_PATH/$DAEMON" ]; then
	usage
	exit $SMF_EXIT_ERR_FATAL
fi

# only bgpd is suitable for running in a non-global zone, at this
# time.
case "${DAEMON}" in
	bgpd)
	;;
	zebra | ospfd | ospf6d | ripd | ripngd )
		frr_is_globalzone || exit $SMF_EXIT_OK
	;;
	*)
		usage
		exit $SMF_EXIT_ERR_CONFIG;
	;;
esac

# Older FRRouting SMF packages pass daemon args on the commandline
# Newer SMF routeadm model uses properties for each argument
# so we must handle that.
if [ smf_present -a -f "$ROUTEADMINCLUDE" ]; then
	handle_routeadm_upgrade $DAEMON;
	DAEMON_ARGS=`routeadm_daemon_args`;
else
	if [ $# -gt 0 ] ; then
		shift
		DAEMON_ARGS="$@"
	fi
fi

upgrade_config "$DAEMON"

if [ ! -f "@sysconfdir@/${DAEMON}.conf" ] ; then
	echo "Could not find config file, @sysconfdir@/${DAEMON}.conf"
	exit $SMF_EXIT_ERR_CONFIG
fi

# we need @frr_statedir@ to exist, it probably is on tmpfs.
if [ ! -d @frr_statedir@ ] ; then
	mkdir -p @frr_statedir@
	chown @enable_user@:@enable_group@ @frr_statedir@
	chmod 751 @frr_statedir@
fi

PIDFILE="@frr_statedir@/${DAEMON}.pid"

start () {
	if [ ! -x "$DAEMON_PATH/$DAEMON" ] ; then
		echo "Error, could not find daemon, $DAEMON_PATH/$DAEMON"
		exit $SMF_EXIT_ERR_FATAL
	fi
	eval exec $DAEMON_PATH/$DAEMON $DAEMON_ARGS --pid_file ${PIDFILE} &
}

stop_by_pidfile () {
	if [ -f "${PIDFILE}" ]; then
		/usr/bin/kill -TERM `/usr/bin/cat "${PIDFILE}"`
	fi
}

case "$FRR_METHOD" in
'start')
	start
	;;
'stop')
	stop_by_pidfile
	;;

*)
	usage
	exit $SMF_EXIT_ERR_FATAL
	;;
esac	

exit $SMF_EXIT_OK;
