xref: /dragonfly/sbin/rcrun/rcrun.sh (revision 6e5c5008)
1#!/bin/sh
2#
3# Copyright (c) 2003
4#	The DragonFly Project.  All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in
14#    the documentation and/or other materials provided with the
15#    distribution.
16# 3. Neither the name of The DragonFly Project nor the names of its
17#    contributors may be used to endorse or promote products derived
18#    from this software without specific, prior written permission.
19#
20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23# FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
24# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25# INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31# SUCH DAMAGE.
32#
33
34if [ -r /etc/defaults/rc.conf ]; then
35	. /etc/defaults/rc.conf
36fi
37
38if [ -r /etc/rc.conf ]; then
39	. /etc/rc.conf
40fi
41
42buildrclist()
43{
44    rcfiles=`find /etc/rc.d -type f`
45    for d in $local_startup; do
46	if [ -d $d ]; then
47	    rcfiles="$rcfiles `find $d -type f`"
48	fi
49    done
50    # The last element of this list is the script that provides the target
51    # we want to run.
52    #
53    rclist=`rcorder -o $1 $rcfiles`
54}
55
56dostart()
57{
58    arg=$1
59    shift
60
61    for tgt in $@; do
62	case X`varsym -s -q rcng_$tgt` in
63	Xrunning*)
64	    echo "$tgt has already been started"
65	    ;;
66	Xconfigured*)
67	    echo "$tgt has already been configured"
68	    ;;
69	*)
70	    _return=0
71	    buildrclist $tgt
72	    for dep in $rclist; do
73		need=1
74		dep_prvd_list=`rcorder -p $dep`
75		# Because the dependency could actually provide more than one
76		# keyword, iterate it twice, first looking for a match in any
77		# of its PROVIDEs.
78		#
79		for dep_prvd in $dep_prvd_list; do
80		    if [ $dep_prvd = $tgt ]; then
81			need=0
82		    fi
83		done
84		if [ $need = 1 ]; then
85		    for dep_prvd in $dep_prvd_list; do
86			state=`varsym -s -q rcng_$dep_prvd`
87			case X$state in
88			Xrunning*|Xconfigured*|Xirrelevant*|Xdisabled*)
89			    ;;
90			*)
91			    echo "$tgt depends on $dep_prvd, current state: $state"
92			    _return=1
93			    ;;
94			esac
95		    done
96		fi
97	    done
98	    # $dep contains the last dependency, which we run
99	    #
100	    if [ X$dep = X ]; then
101		echo "Unable to find keyword $tgt"
102	    elif [ $_return = 0 ]; then
103		echo "Running $dep $arg"
104		(sh $dep $arg)
105		case X`varsym -s -q rcng_$tgt` in
106		Xdisabled*)
107		    echo "$tgt is disabled, enable in rc.conf first or use rcforce/rcone"
108		    ;;
109		Xfailed*)
110		    echo "$tgt has failed to start"
111		    ;;
112
113		esac
114	    fi
115	    ;;
116	esac
117    done
118}
119
120arg=$0
121case ${0##*/} in
122rcstart)
123    arg=start
124    ;;
125rcstop)
126    arg=stop
127    ;;
128rcrestart)
129    arg=restart
130    ;;
131rcreload)
132    arg=reload
133    ;;
134rcstatus)
135    arg=status
136    ;;
137rcvar)
138    arg=rcvar
139    ;;
140rcvars)
141    arg=rcvar
142    ;;
143rclist)
144    arg=list
145    ;;
146rcforce)
147    arg=forcestart
148    ;;
149rcfast)
150    arg=faststart
151    ;;
152rcone)
153    arg=onestart
154    ;;
155rcenable)
156    arg=enable
157    ;;
158rcdisable)
159    arg=disable
160    ;;
161*)
162    arg=$1
163    shift
164    ;;
165esac
166
167case $arg in
168start)
169	dostart start $@
170	;;
171forcestart)
172	dostart forcestart $@
173	;;
174faststart)
175	dostart faststart $@
176	;;
177onestart)
178	dostart onestart $@
179	;;
180stop)
181	for tgt in $@; do
182	    buildrclist $tgt
183	    dep=`echo "$rclist" | tail -1`
184	    if [ X$dep = X ]; then
185		echo "Unable to find keyword $tgt"
186	    else
187		(sh $dep stop)
188	    fi
189	done
190	;;
191restart)
192	for tgt in $@; do
193	    buildrclist $tgt
194	    dep=`echo "$rclist" | tail -1`
195	    if [ X$dep = X ]; then
196		echo "Unable to find keyword $tgt"
197	    else
198		(sh $dep restart)
199	    fi
200	done
201	;;
202reload)
203	for tgt in $@; do
204	    buildrclist $tgt
205	    dep=`echo "$rclist" | tail -1`
206	    if [ X$dep = X ]; then
207		echo "Unable to find keyword $tgt"
208	    else
209		(sh $dep reload)
210	    fi
211	done
212	;;
213status)
214	for tgt in $@; do
215	    buildrclist $tgt
216	    dep=`echo "$rclist" | tail -1`
217	    if [ X$dep = X ]; then
218		echo "Unable to find keyword $tgt"
219	    else
220		(sh $dep status)
221	    fi
222	done
223	;;
224disable|enable)
225	if [ "$arg" = "enable" ]; then
226	    mode=YES
227	else
228	    mode=NO
229	fi
230	for tgt in $@; do
231	    buildrclist $tgt
232	    dep=`echo "$rclist" | tail -1`
233	    if [ X$dep = X ]; then
234		echo "Unable to find provider id $tgt"
235	    elif [ `varsym -s -q rcng_$tgt` = "$mode" ]; then
236		echo "$tgt is already $mode"
237	    else
238		vars=`(sh $dep rcvar) 2>/dev/null | grep = | sed -e 's/\\$//g' | sed -e 's/=.*//g'`
239		cp /etc/rc.conf /etc/rc.conf.bak
240		if [ $arg = disable ]; then
241		    rcstop $tgt
242		fi
243		for k in $vars; do
244		    rm -f /etc/rc.conf.$$
245		    ( egrep -v "# rcrun enable ${k}$" /etc/rc.conf; printf "${k}=${mode}\t# rcrun enable ${k}\n" ) > /etc/rc.conf.$$
246		    mv -f /etc/rc.conf.$$ /etc/rc.conf
247		    echo "added/modified: ${k}=${mode}"
248		done
249		if [ $arg = enable ]; then
250		    rcstart $tgt
251		fi
252	    fi
253	done
254	;;
255rcvar)
256	for tgt in $@; do
257	    buildrclist $tgt
258	    dep=`echo "$rclist" | tail -1`
259	    if [ X$dep = X ]; then
260		echo "Unable to find provider id $tgt"
261	    else
262		(sh $dep rcvar)
263	    fi
264	done
265	;;
266list)
267	if [ "X$*" = X ]; then
268	    for tgt in `varsym -a -s | egrep '^rcng_'`; do
269		echo $tgt
270	    done
271	else
272	    for tgt in $@; do
273		varsym -s rcng_$tgt 2>/dev/null || varsym -s rcng_$tgt
274	    done
275	fi
276	;;
277*)
278	echo "usage: rcrun action rcscript1 ..."
279	echo "  where 'action' is one of:"
280	echo "    start|stop|restart|reload|status|rcvar|list|forcestart|faststart"
281	echo "    onestart|disable|enable"
282	;;
283esac
284