* Merged newxml into HEAD
[linux_from_scratch.git] / bootscripts / contrib / new-boot-0.2 / sbin / init.d / functions
blob8e2c0e5691d1759a969c58b64f80b5935b99cea0
1 #!/bin/sh
3 export PATH=/sbin:/bin:/usr/sbin:/usr/bin
5 #If $INIT_D is unset (e.g. if script is being run by sysvinit), determine
6 #$INIT_D by the location of the functions script. If everyone would agree
7 #on where scripts should go, this would be just INIT_D=${INIT_D:-path}
8 #but there are 3 popular directories: /sbin/init.d, /etc/init.d and /etc/rc.d
9 #In order to make this script compatible with all 3 choices we have to work
10 #some shell magic.
11 if [ ! -n "$INIT_D" ]; then
12 INIT_D=`PATH=/sbin/init.d:/etc/init.d:/etc/rc.d type -p functions`
13 INIT_D=${INIT_D%/functions} #remove "/functions to get directory"
15 if [ ! -n "$INIT_D" ]; then
16 echo 1>&2 Cannot determine INIT_D!
17 exit 1
19 export INIT_D
22 if [ "$USERSPACE_INIT" = "1" ] #if testing boot scripts in user space
23 then #simulating some binaries might be desired
24 if [ -f $INIT_D/sim-bins ]; then
25 source $INIT_D/sim-bins
27 if [ ! -n "$INIT_ROOT" ]; then
28 echo 1>&2 INIT_ROOT not set!
29 exit 1
32 #catch common error of forgetting to add need symlink in user space
33 #testing environment
34 if [ ! -x $INIT_ROOT/sbin/need ]; then
35 echo 1>&2 "Cannot find $INIT_ROOT/sbin/need"
36 exit 1
37 fi
39 #prefer binaries in the current directory, in case someone forgot to
40 #export PATH=$INIT_ROOT/sbin:$PATH
41 export PATH=.:$PATH
44 if [ -f $INIT_D/services ]; then
45 source $INIT_D/services
48 #how many seconds between SIGTERM and SIGKILL
49 KILLDELAY=3
51 COL=$(stty size)
52 COL=${COL##* }
53 COL=${COL:-80}
55 WCOL=$(($COL - 30))
56 COL=$(($COL - 7))
57 CURS_UP="echo -en \\033[A"
58 SET_COL="echo -en \\033[${COL}G"
59 SET_WCOL="echo -en \\033[${WCOL}G"
60 NORMAL="echo -en \\033[0;39m"
61 SUCCESS="echo -en \\033[1;32m"
62 FAILURE="echo -en \\033[1;31m"
63 WARNING="echo -en \\033[1;33m"
64 SKIPPED="echo -en \\033[1;34m"
66 evaluate_retval()
68 saved_status=$?
69 if [ $saved_status = 0 ]
70 then
71 print_status success
72 else
73 print_status failure
75 return $saved_status
78 up_evaluate_retval()
80 saved_status=$?
81 $CURS_UP
82 if [ $saved_status = 0 ]
83 then
84 print_status success
85 else
86 print_status failure
88 return $saved_status
91 print_status()
93 if [ $# = 0 ]
94 then
95 echo "Usage: print_status success|failure|skipped|warning"
96 return 1
99 case "$1" in
100 success)
101 $SET_COL
102 echo -n "[ "
103 $SUCCESS
104 echo -n "OK"
105 $NORMAL
106 echo " ]"
108 failure)
109 $SET_COL
110 echo -n "["
111 $FAILURE
112 echo -n "FAILED"
113 $NORMAL
114 echo "]"
116 warning)
117 $SET_COL
118 echo -n "[ "
119 $WARNING
120 echo -n "ATTN"
121 $NORMAL
122 echo " ]"
124 skipped)
125 $SET_COL
126 echo -n "[ "
127 $SKIPPED
128 echo -n "SKIP"
129 $NORMAL
130 echo " ]"
132 esac
135 #getpids progname|progpath
136 #prints the pids with which the program is running. Only pids of processes
137 #belonging to the caller will be returned. The pid of the caller or that of its
138 #parent is never returned
139 getpids()
141 basename=${1##*/}
143 #we also want to catch scripts of the specified name,
144 #this is default behaviour for psmisc's killall but has to be
145 #activated with -x for the pidof from sysvinit/simpleinit-msb
146 #We want to be compatible with both, so we first try with -x and
147 #fall back to doing it without if that fails
148 #The "exec sh -c 'echo $$PPID ; exec " is necessary because $$
149 #does not return the pid of the subshell running getpids.
150 pidlist=`exec sh -c 'echo $PPID ; exec pidof -x '$basename 2>/dev/null`
151 if [ $? != 0 ]; then
152 pidlist=`exec sh -c 'echo $PPID ; exec pidof '$basename`
155 gpPID=${pidlist%%[^0-9]*} #PID if subshell running getpids
157 for pid in $pidlist
159 #ignore ourselves and our parent (which might have the same name
160 #as our target program)
161 if [ $pid = $$ -o $pid = $PPID -o $pid = $gpPID ]; then continue; fi
163 #only print pids of processes owned by caller
164 if [ -O /proc/$pid ]; then echo $pid ; fi
165 done
168 #loads a program unless it is already loaded. For the test whether it is
169 #loaded only processes belonging to the caller are considered (i.e. if some
170 #other user runs a program of the same name it will not confuse this function).
171 #The calling script and its parent will also be ignored, even if they have the
172 #same name as the program to load, so a script called syslogd can use loadproc
173 #to start syslogd
174 loadproc()
176 if [ $# == 0 ]
177 then
178 echo 1>&2 "Usage: loadproc program [args]"
179 return 1
182 pidlist=`getpids $1`
184 if [ ! -n "$pidlist" ];
185 then
186 #if not found, then start program
187 "$@"
188 up_evaluate_retval
189 else
190 $CURS_UP
191 $SET_WCOL
192 echo -n "...already running!"
193 print_status skipped
194 return 0
198 #sends a signal to all processes of a given name that belong to the caller,
199 #with the exception of the caller and its parent (should they have the same
200 #name)
201 #If a signal is passed as second parameter, only that signal is sent
202 #If the 2nd parameter is omitted, the process is shot down using SIGTERM
203 #followed $KILLDELAY seconds later by SIGKILL
204 killproc()
206 if [ $# = 0 ]
207 then
208 echo 1>&2 "Usage: killproc program [signal]"
209 echo 1>&2 "If signal is not given, shoot down with TERM+KILL"
210 return 1
213 if [ ! -n "$2" ]; then
214 signal=TERM
215 fallback=KILL
216 else
217 signal=${2##-} #tolerate signal with leading "-"
218 signal=${signal##SIG} #tolerate signal with leading "SIG"
219 fallback=""
222 pidlist=`getpids $1`
224 if [ -n "$pidlist" ]
225 then
226 failure=0
228 for pid in $pidlist
230 kill -$signal $pid 2>/dev/null
232 #wait a little - if the process terminates in this time frame
233 #we don't have to wait several seconds
234 for((i=0; $i<1000; i=$i+1)) ; do : ; done
236 #test if process still exists and wait if it does
237 for((i=0; $i<$KILLDELAY; i=$i+1)) ; do
238 kill -0 $pid 2>/dev/null || break
239 sleep 1
240 done
242 if [ -n "$fallback" ]; then kill -$fallback $pid 2>/dev/null; fi
244 #make sure it's really gone, set failure if it isn't
245 kill -0 $pid 2>/dev/null && failure=1
246 done
248 #if killing was successful make sure pidfile is removed
249 basename=${1##*/}
250 if [ $failure = 0 ]; then rm -f /var/run/$basename.pid ; fi
252 (exit $failure)
253 up_evaluate_retval
255 else #if pidlist is empty, i.e. process did not exist in the 1st place
256 $CURS_UP
257 $SET_WCOL
258 echo -n "...not running!"
259 print_status skipped
260 return 0
265 #The reloadproc functions sends a signal to all programs of the specified
266 #name that belong to the caller (except for the caller itself and its parent
267 #should they have the same name), telling them to
268 #reload their configuration files.
269 #If no signal is specified, SIGHUP will be assumed
271 reloadproc()
273 if [ $# = 0 ]
274 then
275 echo 1>&2 "Usage: reloadproc program [signal]"
276 echo 1>&2 "If signal is not given, the function uses SIGHUP"
277 return 1
280 if [ ! -n "$2" ]; then
281 signal=HUP
282 else
283 signal=${2##-} #tolerate signal with leading "-"
284 signal=${signal##SIG} #tolerate signal with leading "SIG"
287 pidlist=`getpids $1`
289 if [ -n "$pidlist" ]
290 then
291 failure=0
293 for pid in $pidlist
295 kill -$signal $pid || failure=1
296 done
298 (exit $failure)
299 up_evaluate_retval
301 else #if pidlist is empty, i.e. process did not exist in the 1st place
302 $CURS_UP
303 $SET_WCOL
304 echo -n "...not running!"
305 print_status skipped
306 return 0
311 # The statusproc function will try to find out if a process is running
312 # or not
315 statusproc()
317 if [ $# = 0 ]
318 then
319 echo 1>&2 "Usage: statusproc program"
320 return 1
323 basename=${1##*/}
324 pidlist=`getpids $basename`
326 if [ -n "$pidlist" ]
327 then
328 echo "$basename running with PID(s) $pidlist"
329 else
330 if [ -s /var/run/$basename.pid ]
331 then
332 echo "$basename is not running but /var/run/$basename.pid exists"
333 return 1
334 else
335 echo "$basename is not running"
338 return 0
341 exit_if_any_error()
343 if [ $? -ne 0 ]; then exit 1; fi
344 return 0
347 exit_if_fatal_error()
349 status=$?
350 if [ $status -ne 2 -a $status -ne 0 ]; then exit 1; fi
351 return $status
354 need()
356 if [ $# == 0 ]; then
357 echo 1>&2 'need called without argument! Maybe you used "need $var" and $var is unset'
358 return 2;
361 if [ -x $INIT_ROOT/sbin/need ]; then #if the system supports dependency
362 $INIT_ROOT/sbin/need "$@" #management (modern inits), use it
363 return $?
364 else #if not (sysvinit), assume that the
365 return 0 #admin set up symlink numbers correctly