let ipkg fail when a package file to be installed is not found
[openwrt.git] / openwrt / package / quagga / files / quagga.init
1 #!/bin/sh
2 #
3 # quagga        Starts/stops quagga daemons and watchquagga.
4 #               Create a daemon.conf file to have that routing daemon
5 #               started/stopped automagically when using this script
6 #               without any daemon names as args.
7 #               If watchquagga is available, it will also be
8 #               started/stopped if the script is called without
9 #               any daemon names.
10 #
11
12 ME=$(basename $0)
13
14 usage() {
15         echo "Usage: ${ME} {start|stop|restart} [daemon ...]"
16         exit 2
17 }
18
19 if [ -z "$1" ]
20 then
21         usage
22 else
23         COMMAND=$1
24 fi
25 shift
26 ARG_DAEMONS=$*
27 BINDIR=/usr/sbin
28 CONFDIR=/etc/quagga
29 STATEDIR=/var/run/quagga
30 DAEMONS="zebra ripd ripngd ospfd ospf6d bgpd"
31 DAEMON_FLAGS=-d
32 WATCHQUAGGA_FLAGS="-d -z -T 60 -R"
33 WATCHQUAGGA_CMD="$0 watchrestart"
34 if [ ${COMMAND} != "watchrestart" ]
35 then
36         DAEMONS="${DAEMONS} watchquagga"
37 fi
38 DAEMONS_STARTSEQ=${DAEMONS}
39
40 reverse()
41 {
42         local revlist r
43         revlist=
44         for r
45         do
46                 revlist="$r $revlist"
47         done
48         echo $revlist
49 }
50
51 DAEMONS_STOPSEQ=$(reverse ${DAEMONS_STARTSEQ})
52
53 #pidof() {
54 #       ps ax | awk 'match($5, "(^|/)'"$1"'$") > 0 { printf " %s", $1 }'
55 #}
56
57 quit() {
58         echo "${ME}: $1"
59         exit 0
60 }
61
62 die() {
63         echo "${ME}: $1"
64         exit 1
65 }
66
67 is_in() {
68         local i
69         for i in $2
70         do
71                 [ "$1" = "$i" ] && return 0
72         done
73         return 1
74 }
75
76 select_subset() {
77         local unknown i j
78         unknown=
79         RESULT=
80         for i in $1
81         do
82                 is_in $i "$2" || unknown="$unknown $i"
83         done
84         if [ -n "$unknown" ]
85         then
86                 RESULT=$unknown
87                 return 1
88         else
89                 for j in $2
90                 do
91                         is_in $j "$1" && RESULT="$RESULT $j"
92                 done
93                 return 0
94         fi
95 }
96
97 # check command
98
99 case ${COMMAND}
100 in
101         start|stop|restart)
102                 ;;
103         watchrestart)
104                 if [ -n "$ARG_DAEMONS" ]
105                 then
106                         echo "${ME}: watchrestart mode is only for use by watchquagga"
107                         exit 2
108                 fi
109                 ;;
110         *)
111                 usage
112                 ;;
113 esac
114
115 # select daemons to start
116
117 case ${COMMAND}
118 in
119         start|restart|watchrestart)
120                 START_DAEMONS=
121                 for d in ${DAEMONS_STARTSEQ}
122                 do
123                         [ -x "${BINDIR}/${d}" -a -f "${CONFDIR}/${d}.conf" ] \
124                         && START_DAEMONS="${START_DAEMONS}${d} "
125                 done
126                 WATCHQUAGGA_DAEMONS=${START_DAEMONS}
127                 if is_in watchquagga "${DAEMONS_STARTSEQ}"
128                 then
129                         START_DAEMONS="${START_DAEMONS} watchquagga"
130                 fi
131                 if [ -n "${ARG_DAEMONS}" ]
132                 then
133                         if select_subset "${ARG_DAEMONS}" "${DAEMONS}"
134                         then
135                                 if select_subset "${ARG_DAEMONS}" "${START_DAEMONS}"
136                                 then
137                                         START_DAEMONS=${RESULT}
138                                 else
139                                         die "these daemons are not startable:${RESULT}."
140                                 fi
141                         else
142                                 die "unknown daemons:${RESULT}; choose from: ${DAEMONS}."
143                         fi
144                 fi
145                 ;;
146 esac
147
148 # select daemons to stop
149
150 case ${COMMAND}
151 in
152         stop|restart|watchrestart)
153                 STOP_DAEMONS=${DAEMONS_STOPSEQ}
154                 if [ -n "${ARG_DAEMONS}" ]
155                 then
156                         if select_subset "${ARG_DAEMONS}" "${STOP_DAEMONS}"
157                         then
158                                 STOP_DAEMONS=${RESULT}
159                         else
160                                 die "unknown daemons:${RESULT}; choose from: ${DAEMONS}."
161                         fi
162                 fi
163                 stop_daemons=
164                 for d in ${STOP_DAEMONS}
165                 do
166                         pidfile=${STATEDIR}/${d}.pid
167                         if [ -f "${pidfile}" -o -n "$(pidof ${d})" ]
168                         then
169                                 stop_daemons="${stop_daemons}${d} "
170                         elif [ -n "${ARG_DAEMONS}" ]
171                         then
172                                 echo "${ME}: found no ${d} process running."
173                         fi
174                 done
175                 STOP_DAEMONS=${stop_daemons}
176                 ;;
177 esac
178
179 # stop daemons
180
181 for d in $STOP_DAEMONS
182 do
183         echo -n "${ME}: Stopping ${d} ... "
184         pidfile=${STATEDIR}/${d}.pid
185         if [ -f "${pidfile}" ]
186         then
187                 file_pid=$(cat ${pidfile})
188                 if [ -z "${file_pid}" ]
189                 then
190                         echo -n "no pid file entry found ... "
191                 fi
192         else
193                 file_pid=
194                 echo -n "no pid file found ... "
195         fi
196         proc_pid=$(pidof ${d})
197         if [ -z "${proc_pid}" ]
198         then
199                 echo -n "found no ${d} process running ... "
200         else
201                 count=0
202                 notinpidfile=
203                 for p in ${proc_pid}
204                 do
205                         count=$((${count}+1))
206                         if kill ${p}
207                         then
208                                 echo -n "killed ${p} ... "
209                         else
210                                 echo -n "failed to kill ${p} ... "
211                         fi
212                         [ "${p}" = "${file_pid}" ] \
213                         || notinpidfile="${notinpidfile} ${p}"
214                 done
215                 [ ${count} -le 1 ] \
216                 || echo -n "WARNING: ${count} ${d} processes were found running ... "
217                 for n in ${notinpidfile}
218                 do
219                         echo -n "WARNING: process ${n} was not in pid file ... "
220                 done
221         fi
222         count=0
223         survivors=$(pidof ${d})
224         while [ -n "${survivors}" ]
225         do
226                 sleep 1
227                 count=$((${count}+1))
228                 survivors=$(pidof ${d})
229                 [ -z "${survivors}" -o ${count} -gt 5 ] && break
230                 for p in ${survivors}
231                 do
232                         sleep 1
233                         echo -n "${p} "
234                         kill ${p}
235                 done
236         done
237         survivors=$(pidof ${d})
238         [ -n "${survivors}" ] && \
239         if kill -KILL ${survivors}
240         then
241                 echo -n "KILLed ${survivors} ... "
242         else
243                 echo -n "failed to KILL ${survivors} ... "
244         fi
245         sleep 1
246         survivors=$(pidof ${d})
247         if [ -z "${survivors}" ]
248         then
249                 echo -n "done."
250                 if [ -f "${pidfile}" ]
251                 then
252                         rm -f ${pidfile} \
253                         || echo -n " Failed to remove pidfile."
254                 fi
255         else
256                 echo -n "failed to stop ${survivors} - giving up."
257                 if [ "${survivors}" != "${file_pid}" ]
258                 then
259                         if echo "${survivors}" > ${pidfile}
260                         then
261                                 chown quagga:quagga ${pidfile}
262                                 echo -n " Wrote ${survivors} to pidfile."
263                         else
264                                 echo -n " Failed to write ${survivors} to pidfile."
265                         fi
266                 fi
267         fi
268         echo
269 done
270
271 # start daemons
272
273 if [ -n "$START_DAEMONS" ]
274 then
275         [ -d ${CONFDIR} ] \
276         || quit "${ME}: no config directory ${CONFDIR} - exiting."
277         chown -R quagga:quagga ${CONFDIR}
278         [ -d ${STATEDIR} ] || mkdir -p ${STATEDIR} \
279         || die "${ME}: could not create state directory ${STATEDIR} - exiting."
280         chown -R quagga:quagga ${STATEDIR}
281
282         for d in $START_DAEMONS
283         do
284                 echo -n "${ME}: Starting ${d} ... "
285                 proc_pid=$(pidof ${d})
286                 pidfile=${STATEDIR}/${d}.pid
287                 file_pid=
288                 if [ -f "${pidfile}" ]
289                 then
290                         file_pid=$(cat ${pidfile})
291                         if [ -n "${file_pid}" ]
292                         then
293                                 echo -n "found old pid file entry ${file_pid} ... "
294                         fi
295                 fi
296                 if [ -n "${proc_pid}" ]
297                 then
298                         echo -n "found ${d} running (${proc_pid}) - skipping ${d}."
299                         if [ "${proc_pid}" != "${file_pid}" ]
300                         then
301                                 if echo "${proc_pid}" > ${pidfile}
302                                 then
303                                         chown quagga:quagga ${pidfile}
304                                         echo -n " Wrote ${proc_pid} to pidfile."
305                                 else
306                                         echo -n " Failed to write ${proc_pid} to pidfile."
307                                 fi
308                         fi
309                 elif rm -f "${pidfile}"
310                 then
311                         if [ "${d}" = "watchquagga" ]
312                         then
313                                 $("${BINDIR}/${d}" \
314                                         ${WATCHQUAGGA_FLAGS} \
315                                         "${WATCHQUAGGA_CMD}" \
316                                         ${WATCHQUAGGA_DAEMONS})
317                                 status=$?
318                         else
319                                 $("${BINDIR}/${d}" ${DAEMON_FLAGS})
320                                 status=$?
321                         fi
322                         if [ $status -eq 0 ]
323                         then
324                                 echo -n "done."
325                         else
326                                 echo -n "failed."
327                         fi
328                 else
329                         echo -n " failed to remove pidfile."
330                 fi
331                 echo
332         done
333 fi