1#!/sbin/sh
2#
3# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
4# Use is subject to license terms.
5#
6# This file is part of Quagga.
7#
8# Quagga is free software; you can redistribute it and/or modify it
9# under the terms of the GNU General Public License as published by the
10# Free Software Foundation; either version 2, or (at your option) any
11# later version.
12#
13# Quagga is distributed in the hope that it will be useful, but
14# WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16# General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with Quagga; see the file COPYING.  If not, write to the Free
20# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21# 02111-1307, USA.
22#
23# Starts/stops the given daemon
24
25SMFINCLUDE=/lib/svc/share/smf_include.sh
26ROUTEADMINCLUDE=/lib/svc/share/routing_include.sh
27GLOBAL_OPTIONS="PAfiug"
28DAEMON_PATH=@sbindir@
29USER=@enable_user@
30GROUP=@enable_group@
31
32# handle upgrade of daemon-args SMF property to new routeadm properties
33# used during upgrade too by routeadm.
34# relevant to S10U4+ only.
35handle_routeadm_upgrade () {
36	GLOBAL_OPTIONS="PAfiug"
37	
38	daemon_args=`get_daemon_args $SMF_FMRI`
39	
40	if [ -n "$daemon_args" ]; then
41		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
42			"$GLOBAL_OPTIONS" "P" vty_port 0
43		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
44			"$GLOBAL_OPTIONS" "A" vty_address
45		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
46			"$GLOBAL_OPTIONS" "f" config_file
47		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
48			"$GLOBAL_OPTIONS" "i" pid_file
49		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
50			"$GLOBAL_OPTIONS" "u" user
51		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
52			"$GLOBAL_OPTIONS" "g" group
53		
54		case "$1" in
55		zebra)
56			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
57				"${GLOBAL_OPTIONS}b" "b" batch true false
58			;;
59		ripd|ripngd)
60			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
61				"${GLOBAL_OPTIONS}r" "r" retain true false
62			;;
63		bgpd)
64			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
65				"${GLOBAL_OPTIONS}rnp" "r" retain true false
66			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
67				"${GLOBAL_OPTIONS}rnp" "n" no_kernel true false
68			set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
69				"${GLOBAL_OPTIONS}rnp" "p" bgp_port
70		esac
71		clear_daemon_args $SMF_FMRI
72	fi
73}
74
75upgrade_config () {
76	DAEMON=$1
77	# handle upgrade of SUNWzebra to Quagga
78	if [ -d "/etc/quagga" -a ! -f "/etc/quagga/${DAEMON}.conf" ] ; then
79		if [ -f "/etc/sfw/zebra/${DAEMON}.conf" ] ; then
80			cp "/etc/sfw/zebra/${DAEMON}.conf" \
81				"/etc/quagga/${DAEMON}.conf.upgrade" \
82				|| exit $SMF_EXIT_ERR_FATAL
83			chown "${USER}:${GROUP}" "/etc/quagga/${DAEMON}.conf.upgrade" \
84				|| exit $SMF_EXIT_ERR_FATAL
85			chmod 0600 "/etc/quagga/${DAEMON}.conf.upgrade" \
86				|| exit $SMF_EXIT_ERR_FATAL
87			mv "/etc/quagga/${DAEMON}.conf.upgrade" "/etc/quagga/${DAEMON}.conf" \
88				|| exit $SMF_EXIT_ERR_FATAL
89		fi
90	fi
91
92	if [ ! -f "/etc/quagga/${DAEMON}.conf" ] ; then
93		touch "/etc/quagga/${DAEMON}.conf.new" \
94			|| exit $SMF_EXIT_ERR_FATAL
95		chown "${USER}:${GROUP}" "/etc/quagga/${DAEMON}.conf.new" \
96			|| exit $SMF_EXIT_ERR_FATAL
97		chmod 0600 "/etc/quagga/${DAEMON}.conf.new" \
98			|| exit $SMF_EXIT_ERR_FATAL
99		mv "/etc/quagga/${DAEMON}.conf.new" "/etc/quagga/${DAEMON}.conf" \
100			|| exit $SMF_EXIT_ERR_FATAL
101	fi
102}
103
104# Relevant to S10+
105quagga_is_globalzone () {
106	if [ "${QUAGGA_INIT_ZONENAME:=`/sbin/zonename`}" = "global" \
107		-o `/sbin/zonename -t` = "exclusive" ]; then
108		return 0
109	else
110		return 1
111	fi
112}
113
114routeadm_daemon_args () {
115	# globals
116	args="`get_daemon_option_from_property $SMF_FMRI config_file f`"
117	args="${args} `get_daemon_option_from_property $SMF_FMRI vty_port P`"
118	args="${args} `get_daemon_option_from_property $SMF_FMRI vty_address A`"
119	args="${args} `get_daemon_option_from_property $SMF_FMRI pid_file i`"
120	
121	# user and group we need for config file upgrade..
122	SMF_USER=`get_routeadm_property $SMF_FMRI user`
123	SMF_GROUP=`get_routeadm_property()$SMF_FMRI group`
124	if [ "${SMF_USER}" ] ; then
125		USER="${SMF_USER}"
126		args="${args} -u ${SMF_USER}"
127	fi
128	if [ "${SMF_GROUP}" ] ; then 
129		GROUP="${SMF_GROUP}"
130		args="${args} -g ${SMF_GROUP}"
131	fi
132
133	case $1 in
134	zebra)
135		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI batch -b true`"
136		;;
137	ripd|ripngd)
138		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
139		;;
140	bgpd)
141		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
142		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI no_kernel -n true`"
143		args="${args} `get_daemon_option_from_property $SMF_FMRI bgp_port p 179`"
144		;;
145	esac
146	echo ${args}
147}
148
149# Include smf functions, if available. If not, define smf_present to indicate
150# there is no SMF. Should allow this script to work pre-S10.
151if [ -f "$SMFINCLUDE" ] ; then
152	. "$SMFINCLUDE";
153	
154	# source the SMF-routeadm include if present..
155	if [ -f "$ROUTEADMINCLUDE" ] ; then
156		. "$ROUTEADMINCLUDE"
157	fi
158else
159	# pre-SMF system, fake up any functions and exit codes
160	# which SMFINCLUDE usually provides.
161	smf_present () {
162		return 1
163	}
164	SMF_EXIT_OK=0;
165	SMF_EXIT_ERR_CONFIG=96;
166	SMF_EXIT_ERR_FATAL=95;
167fi
168	
169# if there's no SMF, set some default DAEMON_ARGS
170smf_present || DAEMON_ARGS=""
171
172usage () {
173	if smf_present ; then
174		echo "Usage: $0 <daemon>";
175	else
176		echo "Usage: $0 <stop|start> <daemon> <daemon arguments>";
177	fi
178	echo "The --pid_file argument is implied";
179	echo "This help message: $0 <help|usage>";
180}
181
182# parse arguments, different according to SMF or not.
183case $1 in
184	'help' | 'usage')
185		usage
186		exit $SMF_EXIT_OK
187		;;
188esac
189
190if smf_present ; then
191	QUAGGA_METHOD="start"
192else
193	QUAGGA_METHOD="$1"
194	shift;
195fi
196
197DAEMON="$1"
198
199# daemon path must be given
200if [ -z "$DAEMON_PATH/$DAEMON" ]; then
201	usage
202	exit $SMF_EXIT_ERR_FATAL
203fi
204
205# only bgpd is suitable for running in a non-global zone, at this
206# time.
207case "${DAEMON}" in
208	bgpd)
209	;;
210	zebra | ospfd | ospf6d | ripd | ripngd )
211		quagga_is_globalzone || exit $SMF_EXIT_OK
212	;;
213	*)
214		usage
215		exit $SMF_EXIT_ERR_CONFIG;
216	;;
217esac
218
219# Older Quagga SMF packages pass daemon args on the commandline
220# Newer SMF routeadm model uses properties for each argument
221# so we must handle that.
222if [ smf_present -a -f "$ROUTEADMINCLUDE" ]; then
223	handle_routeadm_upgrade $DAEMON;
224	DAEMON_ARGS=`routeadm_daemon_args`;
225else
226	if [ $# -gt 0 ] ; then
227		shift
228		DAEMON_ARGS="$@"
229	fi
230fi
231
232upgrade_config "$DAEMON"
233
234if [ ! -f "@sysconfdir@/${DAEMON}.conf" ] ; then
235	echo "Could not find config file, @sysconfdir@/${DAEMON}.conf"
236	exit $SMF_EXIT_ERR_CONFIG
237fi
238
239# we need @quagga_statedir@ to exist, it probably is on tmpfs.
240if [ ! -d @quagga_statedir@ ] ; then
241	mkdir -p @quagga_statedir@
242	chown @enable_user@:@enable_group@ @quagga_statedir@
243	chmod 751 @quagga_statedir@
244fi
245
246PIDFILE="@quagga_statedir@/${DAEMON}.pid"
247
248start () {
249	if [ ! -x "$DAEMON_PATH/$DAEMON" ] ; then
250		echo "Error, could not find daemon, $DAEMON_PATH/$DAEMON"
251		exit $SMF_EXIT_ERR_FATAL
252	fi
253	eval exec $DAEMON_PATH/$DAEMON $DAEMON_ARGS --pid_file ${PIDFILE} &
254}
255
256stop_by_pidfile () {
257	if [ -f "${PIDFILE}" ]; then
258		/usr/bin/kill -TERM `/usr/bin/cat "${PIDFILE}"`
259	fi
260}
261
262case "$QUAGGA_METHOD" in
263'start')
264	start
265	;;
266'stop')
267	stop_by_pidfile
268	;;
269
270*)
271	usage
272	exit $SMF_EXIT_ERR_FATAL
273	;;
274esac	
275
276exit $SMF_EXIT_OK;
277