]>
Commit | Line | Data |
---|---|---|
356d834b | 1 | #!/bin/sh - keep it for file(1) to get bourne shell script result |
7742e157 AF |
2 | # functions This file contains functions to be used by most or all |
3 | # shell scripts in the /etc/init.d directory. | |
4 | # | |
ec8b15cb | 5 | # $Id$ |
7742e157 AF |
6 | # |
7 | # Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org> | |
8a835e11 | 8 | # Hacked by: Greg Galloway and Marc Ewing |
ffe19b59 | 9 | # Modified for PLD Linux by: |
ec8b15cb | 10 | # Marek Obuchowicz <elephant@pld-linux.org> |
fdc764ae ER |
11 | # Arkadiusz Miśkiewicz <misiek@pld-linux.org> |
12 | # Michał Kochanowicz <mkochano@pld-linux.org> | |
13 | # Łukasz Pawelczyk <havner@pld-linux.org> | |
7742e157 AF |
14 | |
15 | # First set up a default search path. | |
cee18a41 | 16 | export PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin" |
7742e157 | 17 | |
d7e5835b SZ |
18 | # Set defaults |
19 | INIT_COL=67 | |
9e9fac7d | 20 | |
503bfc80 AM |
21 | # Set colors |
22 | RED=1 | |
23 | GREEN=2 | |
24 | YELLOW=3 | |
25 | BLUE=4 | |
26 | MAGENTA=5 | |
27 | CYAN=6 | |
28 | WHITE=7 | |
29 | NORMAL=9 | |
30 | # Bold definition (second parameter to termput setaf) | |
31 | BOLD=1 | |
32 | NOBOLD=0 | |
33 | # Default colors | |
34 | CBRACKETS="$CYAN" # brackets [ ] color | |
35 | CDONE="$GREEN" # DONE and WORK color | |
36 | CBUSY="$MAGENTA" # BUSY color | |
37 | CFAIL="$RED" # FAIL and DIED color | |
38 | CPOWEREDBY="$CYAN" # "Powered by" color | |
39 | CPLD="$GREEN" # "PLD Linux Distribution" color | |
40 | CI="$RED" # Capital I color (press I to enter interactive startup) | |
41 | CRESMAN="$GREEN" # "Resource Manager" color | |
bca43764 | 42 | CHARS="" # Characters displayed on the beginning of show line |
503bfc80 AM |
43 | CCHARS="$NORMAL" # Color of these characters (look at /etc/sysconfig/init-colors.gentoo example) |
44 | ||
d7e5835b | 45 | # Source configuration if available - may override default values |
503bfc80 | 46 | [ -r /etc/sysconfig/init-colors ] && . /etc/sysconfig/init-colors |
de1fc6ce | 47 | [ -r /etc/sysconfig/system ] && . /etc/sysconfig/system |
7f229d88 | 48 | [ -r /etc/sysconfig/bootsplash ] && . /etc/sysconfig/bootsplash |
d7e5835b | 49 | [ -z "$COLUMNS" ] && COLUMNS=80 |
7e04fe0e | 50 | |
9e22837c | 51 | if [ -z "$VSERVER" -o "$VSERVER" = "detect" ]; then |
ce397bd8 JR |
52 | { |
53 | while read _f _ctx; do | |
54 | [ "$_f" = "VxID:" -o "$_f" = "s_context:" ] && break | |
55 | done </proc/self/status | |
56 | } 2>/dev/null | |
9e22837c JR |
57 | if [ -z "$_ctx" -o "$_ctx" = "0" ]; then |
58 | VSERVER=no | |
59 | else | |
60 | VSERVER=yes | |
61 | fi | |
55a4bc1b | 62 | unset _f _ctx |
9e22837c JR |
63 | fi |
64 | ||
4132441e ER |
65 | # we need to know in functions if we were called from a terminal |
66 | if [ -z "$ISATTY" ]; then | |
67 | [ -t ] && ISATTY=yes || ISATTY=no | |
68 | fi | |
69 | ||
13a745bb AM |
70 | is_yes() |
71 | { | |
72 | # Test syntax | |
73 | if [ $# = 0 ] ; then | |
74 | msg_usage " is_yes {value}" | |
75 | return 2 | |
76 | fi | |
77 | ||
78 | # Check value | |
79 | case "$1" in | |
80 | yes|Yes|YES|true|True|TRUE|on|On|ON|Y|y|1) | |
81 | # true returns zero | |
82 | return 0 | |
83 | ;; | |
84 | *) | |
85 | # false returns one | |
86 | return 1 | |
87 | ;; | |
88 | esac | |
89 | } | |
90 | ||
91 | is_no() | |
92 | { | |
93 | # Test syntax | |
94 | if [ $# = 0 ] ; then | |
95 | msg_usage " is_no {value}" | |
96 | return 2 | |
97 | fi | |
98 | ||
99 | case "$1" in | |
100 | no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0) | |
101 | # true returns zero | |
102 | return 0 | |
103 | ;; | |
104 | *) | |
105 | # false returns one | |
106 | return 1 | |
107 | ;; | |
108 | esac | |
109 | } | |
110 | ||
45e0ac73 ER |
111 | # checks if file is empty |
112 | # empty lines and lines beginning with hash are ignored | |
113 | is_empty_file() { | |
114 | [ -s "$1" ] || return 0 | |
0011afb6 | 115 | egrep -vq "^(#|[[:blank:]]*$)" "$1" && return 1 || return 0 |
45e0ac73 ER |
116 | } |
117 | ||
1626fc86 ER |
118 | # returns OK if $1 contains $2 |
119 | strstr() { | |
4ec13019 ER |
120 | local a=$2 |
121 | [ "${1#*$a*}" = "$1" ] && return 1 | |
1626fc86 ER |
122 | return 0 |
123 | } | |
124 | ||
bc94aa53 | 125 | if is_yes "$FASTRC" || is_yes "$IN_SHUTDOWN"; then |
d84e0c78 JR |
126 | RC_LOGGING=no |
127 | fi | |
128 | ||
bc94aa53 | 129 | if is_no "$RC_LOGGING"; then |
0a35929a AM |
130 | initlog() |
131 | { | |
6d0838f4 | 132 | RESULT=0 |
bb49a1c7 | 133 | while [ "$1" != "${1##-}" ]; do |
0a35929a | 134 | case $1 in |
5e6dfc29 JR |
135 | -c) |
136 | shift | |
137 | $1 | |
138 | RESULT=$? | |
139 | break | |
140 | ;; | |
141 | *) | |
142 | shift | |
143 | ;; | |
0a35929a AM |
144 | esac |
145 | done | |
6d0838f4 | 146 | return $RESULT |
0a35929a AM |
147 | } |
148 | fi | |
149 | ||
6f2d09b1 AM |
150 | kernelver() |
151 | { | |
55a4bc1b JR |
152 | typeset _x _y _z v old_IFS ver |
153 | { | |
154 | read _x _y v _z | |
155 | old_IFS=$IFS | |
156 | IFS='.' | |
157 | set -- $v | |
158 | IFS=$old_IFS | |
28d62f54 ER |
159 | |
160 | # strip _* or -* from versions like: "2.6.25_vanilla-1", "2.6.25-1" | |
89ec4154 | 161 | ver=${3%%[-_]*} |
28d62f54 ER |
162 | |
163 | while [ ${#ver} -lt 3 ]; do ver="0$ver"; done | |
55a4bc1b | 164 | ver="$2$ver" |
28d62f54 | 165 | while [ ${#ver} -lt 6 ]; do ver="0$ver"; done |
55a4bc1b | 166 | ver="$1$ver" |
28d62f54 | 167 | while [ ${#ver} -lt 9 ]; do ver="0$ver"; done |
55a4bc1b | 168 | echo $ver |
28d62f54 | 169 | } < /proc/version |
6f2d09b1 AM |
170 | } |
171 | ||
172 | kernelverser() | |
173 | { | |
55a4bc1b JR |
174 | typeset _x _y _z v old_IFS ver |
175 | { | |
176 | read _x _y v _z | |
177 | old_IFS=$IFS | |
178 | IFS='.' | |
179 | set -- $v | |
180 | IFS=$old_IFS | |
181 | ver=$2 | |
182 | while [ ${#ver} -lt 3 ] ; do ver="0$ver" ; done | |
183 | ver="$1$ver" | |
184 | while [ ${#ver} -lt 6 ] ; do ver="0$ver" ; done | |
185 | echo $ver | |
186 | } </proc/version | |
6f2d09b1 AM |
187 | } |
188 | ||
189 | kernelvermser() | |
190 | { | |
55a4bc1b JR |
191 | typeset _x _y _z v old_IFS ver |
192 | { | |
193 | read _x _y v _z | |
194 | old_IFS=$IFS | |
195 | IFS='.' | |
196 | set -- $v | |
197 | IFS=$old_IFS | |
198 | ver="$1$ver" | |
199 | while [ ${#ver} -lt 3 ] ; do ver="0$ver" ; done | |
200 | echo $ver | |
201 | } </proc/version | |
6f2d09b1 AM |
202 | } |
203 | ||
cee18a41 | 204 | # Colors workaround |
8a835e11 | 205 | termput() |
c6c1bd0c | 206 | { |
4132441e | 207 | is_yes "$ISATTY" || return |
e3aafb2f | 208 | |
294b03eb | 209 | if is_yes "$FASTRC" || is_no "$TPUT"; then |
972964bb AM |
210 | case "$1" in |
211 | hpa) | |
8a835e11 | 212 | echo -ne "\033[$(($2+1))G" |
972964bb AM |
213 | ;; |
214 | cuu*) | |
8a835e11 | 215 | echo -ne "\033[${2}A" |
972964bb AM |
216 | ;; |
217 | el) | |
8a835e11 | 218 | echo -ne "\033[0K" |
972964bb AM |
219 | ;; |
220 | setaf) | |
503bfc80 AM |
221 | typeset ISBOLD |
222 | if [ -n "$3" ]; then | |
223 | ISBOLD="$3" | |
224 | else | |
225 | ISBOLD="$NOBOLD"; | |
226 | fi | |
227 | is_yes "$COLOR_INIT" && echo -ne "\033[${ISBOLD};3${2}m" | |
8a835e11 | 228 | ;; |
dcb00bd9 | 229 | op) |
503bfc80 | 230 | termput setaf $NORMAL |
dcb00bd9 | 231 | ;; |
8a835e11 | 232 | esac |
c6c1bd0c | 233 | else |
8a835e11 | 234 | case "$1" in |
f054a85e | 235 | hpa | cuu* | el) |
8a835e11 | 236 | tput "$@" |
945790a2 JR |
237 | ;; |
238 | setaf) | |
503bfc80 AM |
239 | if [ "$3" == "1" ]; then tput bold; else tput sgr0; fi |
240 | is_yes "$COLOR_INIT" && tput setaf "$2" | |
945790a2 JR |
241 | ;; |
242 | op) | |
503bfc80 | 243 | termput setaf $NORMAL |
945790a2 | 244 | ;; |
8a835e11 | 245 | esac |
c6c1bd0c AF |
246 | fi |
247 | } | |
cee18a41 | 248 | |
0c4f3cf5 ER |
249 | if [ ! -x /bin/printf ]; then |
250 | # printf equivalent | |
251 | # FIXME: buggy when single or double quotes in message! | |
252 | printf() | |
253 | { | |
254 | typeset text m | |
255 | text="$1" | |
256 | shift | |
257 | if [ $# -gt 0 ]; then | |
258 | m="$1" | |
259 | shift | |
260 | while [ $# -gt 0 ]; do | |
261 | m="$m\",\"$1" | |
262 | shift | |
263 | done | |
264 | fi | |
265 | awk "BEGIN {printf \"$text\", \"$m\"; }" | |
266 | } | |
267 | fi | |
8a835e11 | 268 | |
38198f50 AM |
269 | # National language support function |
270 | nls() | |
271 | { | |
50ed8c3f | 272 | typeset msg_echo nls_domain text message |
d553f606 | 273 | msg_echo='\n' |
50ed8c3f | 274 | nls_domain="$NLS_DOMAIN" |
e2c2c3a6 | 275 | while [ "$1" != "${1##-}" ]; do |
d553f606 | 276 | case "$1" in |
8a835e11 | 277 | --nls-domain) |
278 | shift | |
50ed8c3f | 279 | nls_domain="$1" |
8a835e11 | 280 | shift |
281 | ;; | |
282 | -n) | |
283 | msg_echo='' | |
284 | shift | |
285 | ;; | |
d553f606 JR |
286 | esac |
287 | done | |
288 | message="$1" | |
289 | shift | |
50ed8c3f | 290 | |
d553f606 JR |
291 | # empty message, so we return --misiek |
292 | if [ -z "$message" ]; then | |
d553f606 JR |
293 | echo -en "$msg_echo" |
294 | return | |
38198f50 | 295 | fi |
8a835e11 | 296 | |
e2c2c3a6 ER |
297 | if is_yes "$GETTEXT"; then |
298 | message=$(TEXTDOMAINDIR="/etc/sysconfig/locale" gettext -e --domain="${nls_domain:-rc-scripts}" "$message") | |
972964bb | 299 | fi |
8a835e11 | 300 | |
e2c2c3a6 | 301 | printf "$message" "$@" |
d553f606 | 302 | echo -en "$msg_echo" |
38198f50 AM |
303 | } |
304 | ||
fae22957 AM |
305 | rc_splash() |
306 | { | |
307 | typeset action | |
308 | ||
862c980c AM |
309 | action="$1" |
310 | ||
9e22837c | 311 | if ! is_no "$BOOT_SPLASH" && ! is_yes "$VSERVER"; then |
fae22957 AM |
312 | [ -x /bin/splash ] && /bin/splash "$action" |
313 | fi | |
b6509675 AM |
314 | |
315 | : $((progress++)) | |
fae22957 AM |
316 | } |
317 | ||
d553f606 | 318 | msg_network_down() |
a916d1c6 | 319 | { |
228edf1d | 320 | nls "ERROR: Networking is down. %s can't be run." "$1" >&2 |
a916d1c6 | 321 | } |
322 | ||
323 | msg_starting() | |
324 | { | |
325 | show "Starting %s service" "$1" | |
326 | } | |
327 | ||
d553f606 | 328 | msg_already_running() |
a916d1c6 | 329 | { |
599d198a | 330 | nls "%s service is already running." "$1" |
a916d1c6 | 331 | } |
332 | ||
333 | msg_stopping() | |
334 | { | |
335 | show "Stopping %s service" "$1" | |
336 | } | |
337 | ||
d553f606 | 338 | msg_not_running() |
a916d1c6 | 339 | { |
599d198a | 340 | nls "%s service is not running." "$1" |
a916d1c6 | 341 | } |
342 | ||
343 | msg_reloading() | |
344 | { | |
345 | show "Reloading %s service" "$1" | |
346 | } | |
347 | ||
d553f606 | 348 | msg_usage() |
a916d1c6 | 349 | { |
599d198a | 350 | nls "Usage: %s" "$*" |
a916d1c6 | 351 | } |
352 | ||
ffe19b59 | 353 | # Some functions to handle PLD Linux-style messages |
8a835e11 | 354 | show() |
355 | { | |
ce410bbc JR |
356 | typeset text |
357 | typeset -i len | |
0a35929a | 358 | |
ce410bbc JR |
359 | if is_no "$FASTRC" && is_yes "$GETTEXT"; then |
360 | text=$(nls -n "$@") | |
361 | else | |
362 | text=$(printf "$@") | |
363 | fi | |
364 | len=${#text} | |
365 | while [ $((len++)) -lt $INIT_COL ]; do | |
366 | text="$text." | |
367 | done | |
368 | if [ -n "$CHARS" ]; then | |
369 | termput setaf $CCHARS | |
370 | echo -n "$CHARS" | |
371 | termput op | |
372 | fi | |
373 | echo -n "$text" | |
7742e157 AF |
374 | } |
375 | ||
a292b175 ER |
376 | deltext() |
377 | { | |
378 | termput hpa $INIT_COL | |
379 | } | |
380 | ||
b9cad282 | 381 | # Displays message in square brackests ("[ DONE ]"). Takes two arguments. |
382 | # First is the text to display, second is color number to use (argument to | |
383 | # tput setaf). If second argument is not given, default (2, green) will be | |
384 | # used). | |
385 | progress() | |
7e04fe0e | 386 | { |
da1fc19d | 387 | typeset COLOR |
503bfc80 | 388 | if [ -n "$2" ]; then COLOR="$2"; else COLOR="$CDONE"; fi |
cd8dfdf0 | 389 | deltext |
503bfc80 | 390 | echo -n "$(termput setaf $CBRACKETS)[$(termput setaf $COLOR) $(nls --nls-domain rc-scripts "$1") $(termput setaf $CBRACKETS)]$(termput op)" |
b9cad282 | 391 | } |
392 | ||
8a835e11 | 393 | busy() |
b9cad282 | 394 | { |
a292b175 | 395 | echo -n "$_busy" |
7742e157 AF |
396 | } |
397 | ||
8a835e11 | 398 | ok() |
7e04fe0e | 399 | { |
a292b175 | 400 | echo "$_ok" |
7742e157 AF |
401 | } |
402 | ||
7e04fe0e | 403 | started() |
404 | { | |
a292b175 | 405 | echo "$_started" |
7e04fe0e | 406 | } |
407 | ||
8a835e11 | 408 | fail() |
7e04fe0e | 409 | { |
a292b175 | 410 | echo "$_fail" |
d553f606 | 411 | return 1 |
7742e157 AF |
412 | } |
413 | ||
8a835e11 | 414 | died() |
7e04fe0e | 415 | { |
a292b175 | 416 | echo "$_died" |
d553f606 | 417 | return 1 |
6cac3cb2 | 418 | } |
419 | ||
bbb612de AM |
420 | # Check if $pid (could be plural) are running |
421 | checkpid() | |
422 | { | |
8a835e11 | 423 | while [ "$1" ]; do |
424 | [ -d "/proc/$1" ] && return 0 | |
425 | shift | |
426 | done | |
427 | return 1 | |
bbb612de AM |
428 | } |
429 | ||
290eb891 AM |
430 | # - outside chroot get only those processes, which are outside chroot. |
431 | # - inside chroot get only those processes, which are inside chroot. | |
432 | # - don't filter out pids which do not have corresponding running processes (process died etc) | |
1e5e8177 | 433 | # (note: some processes like named are chrooted but run outside chroot) |
c3403882 | 434 | # - do nothing inside vserver |
1e5e8177 AM |
435 | filter_chroot() |
436 | { | |
c3403882 JR |
437 | if is_yes "$VSERVER"; then |
438 | echo $@ | |
439 | return | |
440 | fi | |
8e3b6875 AM |
441 | if [ $# -lt 1 -o ! -d /proc/1 ] ; then |
442 | echo $@ | |
443 | return | |
444 | fi | |
33ca787f | 445 | local root_dir good_pids="" good_add_pid |
1e5e8177 AM |
446 | for root_pid in $@; do |
447 | root_dir=$(resolvesymlink /proc/${root_pid}/root) | |
448 | if [ -n "$root_dir" ]; then | |
5a8ff397 AM |
449 | good_add_pid=1 |
450 | if [ -n "${SYSTEM_CHROOTS}" ]; then | |
451 | for r_dir in ${SYSTEM_CHROOTS}; do | |
452 | echo "$root_dir" | grep -q "^${r_dir}" && good_add_pid=0 | |
453 | done | |
454 | fi | |
455 | [ "$good_add_pid" -eq 1 ] && good_pids="$good_pids $root_pid" | |
290eb891 AM |
456 | elif [ ! -d "/proc/$root_pid" ]; then |
457 | good_pids="$good_pids $root_pid" | |
1e5e8177 | 458 | fi |
5a8ff397 AM |
459 | done |
460 | echo $good_pids | |
1e5e8177 AM |
461 | } |
462 | ||
cee18a41 AM |
463 | # Usage run_cmd Message command_to_run |
464 | run_cmd() | |
465 | { | |
da1fc19d | 466 | typeset exit_code errors message force_err |
d553f606 JR |
467 | typeset -i force_err=0 |
468 | typeset -i exit_code=0 | |
469 | case "$1" in | |
8a835e11 | 470 | -a) |
471 | force_err=1 | |
472 | shift | |
473 | ;; | |
d553f606 JR |
474 | esac |
475 | message=$1 | |
476 | show "$message"; busy | |
1b228409 | 477 | shift |
90c59319 | 478 | cd / |
f10f2102 ER |
479 | if errors=$( |
480 | export HOME=/tmp TMPDIR=/tmp | |
481 | if is_no "$RC_LOGGING"; then | |
482 | "$@" 2>&1 | |
483 | else | |
484 | initlog -c "$*" 2>&1 | |
485 | fi | |
486 | ); then | |
cd8dfdf0 | 487 | ok |
d553f606 | 488 | log_success "$1 $message" |
1b228409 | 489 | else |
d553f606 JR |
490 | fail |
491 | log_failed "$1 $message" | |
b7299ffc | 492 | exit_code=1 |
1b228409 | 493 | fi |
d553f606 | 494 | [ -n "$errors" ] && [ $exit_code -eq 1 -o $force_err -eq 1 ] && echo "$errors" |
1b228409 | 495 | return $exit_code |
cee18a41 AM |
496 | } |
497 | ||
e81194ca | 498 | _daemon_set_ulimits() { |
0fba6fe4 ER |
499 | local opt val ksh=${KSH_VERSION:+1} |
500 | set -- ${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS} | |
501 | while [ $# -gt 0 ]; do | |
502 | opt=$1 | |
503 | val=$2 | |
504 | if [ "$ksh" ]; then | |
505 | case "$opt" in | |
506 | -Hu) | |
507 | opt=-Hp | |
508 | ;; | |
509 | -Su) | |
510 | opt=-Sp | |
511 | ;; | |
512 | -u) | |
513 | opt=-p | |
514 | ;; | |
515 | esac | |
516 | fi | |
517 | ulimit $opt $val | |
518 | shift 2 | |
519 | done | |
e81194ca ER |
520 | } |
521 | ||
e2e24f5a | 522 | # A function to start a program (now it's useful on read-only filesystem too) |
8a835e11 | 523 | daemon() |
7e04fe0e | 524 | { |
0a177614 | 525 | typeset errors="" prog="" end="" waitname="" waittime="" |
d553f606 | 526 | typeset -i exit_code=0 |
42595a81 | 527 | local nice=$SERVICE_RUN_NICE_LEVEL |
f10f2102 | 528 | local fork user closefds pidfile |
42595a81 ER |
529 | |
530 | while [ $# -gt 0 ]; do | |
d553f606 | 531 | case $1 in |
8a835e11 | 532 | '') |
42595a81 | 533 | msg_usage " daemon [--user user] [--fork] [--waitforname procname] [--waitfortime seconds] [+/-nicelevel] {program} <program args>" |
8a835e11 | 534 | return 2 |
d553f606 | 535 | ;; |
8a835e11 | 536 | --check) |
d553f606 JR |
537 | # for compatibility with redhat/mandrake |
538 | nls "warning: --check option is ignored!" | |
539 | shift | |
d553f606 | 540 | ;; |
8a835e11 | 541 | --user) |
d553f606 | 542 | shift |
7b1a2a70 | 543 | [ "$1" != "root" ] && prog="/bin/su $1 -s /bin/sh -c \"" |
f10f2102 | 544 | user=$1 |
d553f606 | 545 | ;; |
b486c392 | 546 | --fork) |
f10f2102 | 547 | fork=1 |
b486c392 ER |
548 | prog="/usr/bin/setsid sh -c \"" |
549 | end='&' | |
b486c392 | 550 | ;; |
f10f2102 ER |
551 | --closefds) |
552 | closefds=1 | |
553 | ;; | |
683d384e | 554 | --waitforname) |
b486c392 | 555 | shift |
683d384e | 556 | waitname="$1" |
683d384e AM |
557 | ;; |
558 | --waitfortime) | |
b486c392 | 559 | shift |
683d384e | 560 | waittime="$1" |
683d384e | 561 | ;; |
0a177614 ER |
562 | --pidfile) |
563 | shift | |
564 | pidfile="$1" | |
565 | ;; | |
42595a81 ER |
566 | -*|+*) |
567 | nice=$1 | |
a6e727aa | 568 | shift |
42595a81 ER |
569 | break |
570 | ;; | |
571 | *) | |
572 | break | |
683d384e | 573 | ;; |
d553f606 | 574 | esac |
42595a81 | 575 | shift |
d553f606 | 576 | done |
2eea8492 | 577 | # If command to execute ends with quotation mark, add remaining |
578 | # arguments and close quotation. | |
579 | if [ "$prog" != "${prog%\"}" ]; then | |
565736ed | 580 | prog="$prog $*$end\"" |
2eea8492 | 581 | else |
565736ed | 582 | prog="$prog $*$end" |
2eea8492 | 583 | fi |
7742e157 | 584 | |
e81194ca | 585 | _daemon_set_ulimits |
f054a85e | 586 | |
3edf5e48 | 587 | [ -z "$DEFAULT_SERVICE_UMASK" ] && DEFAULT_SERVICE_UMASK=022 |
42595a81 | 588 | [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0 |
3edf5e48 | 589 | |
7742e157 AF |
590 | # And start it up. |
591 | busy | |
90c59319 | 592 | cd / |
42595a81 | 593 | [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" && echo $$ > "/dev/cpuset/${SERVICE_CPUSET}/tasks" |
f10f2102 ER |
594 | if errors=` |
595 | umask ${SERVICE_UMASK:-$DEFAULT_SERVICE_UMASK}; | |
596 | export USER=root HOME=/tmp TMPDIR=/tmp | |
597 | nice=${nice:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} | |
598 | nice=${nice:-0} | |
599 | ||
600 | if [ "$closefds" = 1 ]; then | |
601 | exec 1>&- | |
602 | exec 2>&- | |
603 | exec 0>&- | |
604 | else | |
605 | exec 2>&1 | |
606 | fi | |
607 | ||
608 | if is_no "$RC_LOGGING" ; then | |
609 | prog=$1; shift | |
610 | if [ ! -x $prog ]; then | |
611 | logger -t rc-scripts -p daemon.debug "daemon: Searching PATH for $prog, consider using full path in initscript" | |
612 | local a o=$IFS | |
613 | IFS=: | |
614 | for a in $PATH; do | |
615 | if [ -x $a/$prog ]; then | |
616 | prog=$a/$prog | |
617 | break | |
618 | fi | |
619 | done | |
620 | IFS=$o | |
621 | fi | |
622 | /sbin/start-stop-daemon -q --start \ | |
623 | --nicelevel $nice \ | |
624 | ${pidfile:+--pidfile $pidfile} \ | |
625 | ${user:+-u $user} \ | |
626 | ${fork:+-b} \ | |
627 | --exec "$prog" \ | |
628 | -- ${1:+"$@"} | |
629 | else | |
630 | nice -n $nice initlog -c "$prog" 2>&1 | |
631 | fi | |
632 | `; then | |
633 | ||
683d384e AM |
634 | if [ -n "$waitname" -a -n "$waittime" ]; then |
635 | # Save basename. | |
03e01a49 | 636 | base=${waitname##*/} |
683d384e AM |
637 | # Find pid. |
638 | pid=$(pidofproc "$waitname" "$pidfile") | |
639 | [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile") | |
640 | i=0 | |
641 | while [ "$i" -lt "$waittime" ]; do | |
42595a81 | 642 | i=$((i + 1)) |
683d384e AM |
643 | checkpid $pid && sleep 1 || break |
644 | done | |
645 | fi | |
d553f606 | 646 | log_success "$1 startup" |
1b228409 | 647 | ok |
7742e157 | 648 | else |
b7299ffc | 649 | exit_code=1 |
1b228409 | 650 | fail |
d553f606 JR |
651 | log_failed "$1 startup" |
652 | [ -n "$errors" ] && echo "$errors" | |
7742e157 | 653 | fi |
b7299ffc | 654 | return $exit_code |
7742e157 AF |
655 | } |
656 | ||
657 | # A function to stop a program. | |
8a835e11 | 658 | killproc() |
7e04fe0e | 659 | { |
8de7f381 | 660 | typeset notset killlevel base pid pidfile result |
7742e157 AF |
661 | # Test syntax. |
662 | if [ $# = 0 ]; then | |
d553f606 | 663 | msg_usage " killproc {program} [signal]" |
228edf1d | 664 | return 2 |
7742e157 AF |
665 | fi |
666 | ||
bb49a1c7 | 667 | while [ "$1" != "${1##-}" ]; do |
8de7f381 | 668 | case $1 in |
5e6dfc29 JR |
669 | --pidfile) |
670 | shift | |
671 | pidfile="$1" | |
672 | shift | |
8de7f381 | 673 | ;; |
5e6dfc29 JR |
674 | --waitforname) |
675 | shift | |
676 | waitname="$1" | |
677 | shift | |
683d384e | 678 | ;; |
5e6dfc29 JR |
679 | --waitfortime) |
680 | shift | |
681 | waittime="$1" | |
682 | shift | |
683d384e | 683 | ;; |
8de7f381 AM |
684 | esac |
685 | done | |
686 | ||
7742e157 | 687 | busy |
8a835e11 | 688 | |
d553f606 | 689 | typeset -i notset=0 |
7742e157 | 690 | # check for second arg to be kill level |
d553f606 | 691 | if [ -n "$2" ] ; then |
7742e157 AF |
692 | killlevel=$2 |
693 | else | |
694 | notset=1 | |
695 | killlevel="-9" | |
696 | fi | |
697 | ||
228edf1d | 698 | # Save basename. |
03e01a49 | 699 | base=${1##*/} |
7742e157 | 700 | |
228edf1d | 701 | # Find pid. |
8de7f381 AM |
702 | pid=$(pidofproc "$1" "$pidfile") |
703 | [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile") | |
7742e157 | 704 | |
228edf1d | 705 | # Kill it. |
34b6b730 | 706 | if [ -n "$pid" -a "$pid" != "$$" ] && checkpid $pid 2>&1 ; then |
830949ca | 707 | if [ "$notset" = "1" ] ; then |
228edf1d | 708 | if checkpid $pid 2>&1; then |
709 | # TERM first, then KILL if not dead | |
710 | kill -TERM $pid | |
711 | usleep 100000 | |
712 | if checkpid $pid && sleep 1 && | |
713 | checkpid $pid && sleep 3 && | |
714 | checkpid $pid; then | |
715 | kill -KILL $pid | |
716 | usleep 100000 | |
717 | fi | |
7742e157 | 718 | fi |
228edf1d | 719 | checkpid $pid |
bbb612de AM |
720 | result=$? |
721 | if [ "$result" -eq 0 ]; then | |
228edf1d | 722 | fail |
723 | log_failed "$1 shutdown" | |
724 | else | |
725 | ok | |
726 | log_success "$1 shutdown" | |
727 | fi | |
728 | result=$(( ! $result )) | |
729 | else | |
730 | # use specified level only | |
731 | if checkpid $pid > /dev/null 2>&1; then | |
732 | kill $killlevel $pid | |
733 | result=$? | |
734 | if [ "$result" -eq 0 ]; then | |
735 | ok | |
736 | log_success "$1 got $killlevel" | |
737 | else | |
738 | result=7 | |
739 | fail | |
740 | log_failed "$1 didn't get $killlevel" | |
741 | fi | |
e016cdae | 742 | else |
228edf1d | 743 | result=7 |
744 | died | |
745 | log_failed "$1 shutdown" | |
e016cdae | 746 | fi |
7742e157 AF |
747 | fi |
748 | else | |
228edf1d | 749 | died |
750 | log_failed "$1 shutdown" | |
751 | result=7 | |
7742e157 | 752 | fi |
5e6dfc29 | 753 | |
683d384e | 754 | if [ -n "$waitname" -a -n "$waittime" ]; then |
e6f93a80 | 755 | # Save basename. |
03e01a49 | 756 | base=${waitname##*/} |
e6f93a80 AM |
757 | # Find pid. |
758 | pid=$(pidofproc "$waitname" "$pidfile") | |
759 | [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile") | |
683d384e AM |
760 | i=0 |
761 | while [ "$i" -lt "$waittime" ]; do | |
1101d321 | 762 | i=$(( i + 1 )) |
683d384e AM |
763 | checkpid $pid && sleep 1 || break |
764 | done | |
765 | fi | |
7742e157 | 766 | |
228edf1d | 767 | # Remove pid file if any. |
e016cdae | 768 | if [ "$notset" = "1" ]; then |
228edf1d | 769 | rm -f /var/run/${base}.pid |
7742e157 | 770 | fi |
bbb612de AM |
771 | |
772 | return $result | |
7742e157 AF |
773 | } |
774 | ||
775 | # A function to find the pid of a program. | |
8a835e11 | 776 | pidofproc() |
7e04fe0e | 777 | { |
03e01a49 | 778 | typeset pid pidfile base=${1##*/} |
8de7f381 AM |
779 | pidfile="$base.pid" |
780 | [ -n "$2" ] && pidfile="$2" | |
7742e157 | 781 | |
8a835e11 | 782 | # Test syntax. |
783 | if [ $# = 0 ] ; then | |
784 | msg_usage " pidofproc {program}" | |
785 | return 2 | |
786 | fi | |
787 | ||
8de7f381 | 788 | # First try pidfile or "/var/run/*.pid" |
f955cf0f | 789 | if [[ "$pidfile" = /* ]]; then |
1c26fe27 AM |
790 | pidfile="${pidfile}" |
791 | else | |
792 | pidfile="/var/run/${pidfile}"; | |
793 | fi | |
794 | if [ -f "${pidfile}" ] ; then | |
7eb94de6 | 795 | typeset p pid |
8a835e11 | 796 | pid= |
7eb94de6 | 797 | for p in $(< "${pidfile}"); do |
3030e60e | 798 | [ -z "$(echo "$p" | awk '{gsub(/[0-9]/,"");print;}')" ] && pid="$pid $p" |
8a835e11 | 799 | done |
7742e157 | 800 | fi |
8a835e11 | 801 | |
7742e157 | 802 | # Next try "pidof" |
1e5e8177 AM |
803 | [ -z "$pid" ] && pidof -o $$ -o $PPID -o %PPID -x "$1" |
804 | pid=$(filter_chroot "$pid") | |
805 | echo $pid | |
7742e157 | 806 | } |
12de71be | 807 | |
8a835e11 | 808 | status() |
7e04fe0e | 809 | { |
03e01a49 | 810 | typeset pid subsys daemon cpuset_msg |
8a835e11 | 811 | subsys=$1 |
812 | daemon=${2:-$subsys} | |
03e01a49 | 813 | local base=${daemon##*/} |
bbb612de | 814 | |
8a835e11 | 815 | # Test syntax. |
816 | if [ $# = 0 ] ; then | |
817 | msg_usage " status {subsys} [{daemon}]" | |
818 | return 2 | |
819 | fi | |
bbb612de | 820 | |
8a835e11 | 821 | # First try "pidof" |
822 | pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon) | |
1e5e8177 | 823 | pid=$(filter_chroot "$pid") |
bbb612de | 824 | |
b90fbc1e | 825 | if [ "$pid" ]; then |
814e38ce | 826 | cpuset_msg="..." |
b90fbc1e | 827 | if [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" ]; then |
6c99c680 | 828 | if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then |
814e38ce JR |
829 | cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET") |
830 | else | |
831 | cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET") | |
832 | fi | |
833 | fi | |
834 | nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg" | |
8a835e11 | 835 | return 0 |
836 | # else | |
f74fbf2c | 837 | # pid=$(ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } |
8a835e11 | 838 | # { if ((prog == $5) || (("(" prog ")") == $5) || |
5e6dfc29 | 839 | # (("[" prog "]") == $5) || |
f74fbf2c | 840 | # ((prog ":") == $5)) { print $1 ; exit 0 } }' $1) |
8a835e11 | 841 | # if [ "$pid" != "" ]; then |
54e6320e | 842 | # cpuset_msg="..." |
b90fbc1e | 843 | # if [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" ]; then |
6c99c680 | 844 | # if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then |
54e6320e JR |
845 | # cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET") |
846 | # else | |
847 | # cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET") | |
848 | # fi | |
849 | # fi | |
850 | # nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg" | |
8a835e11 | 851 | # return 0 |
852 | # fi | |
853 | fi | |
854 | ||
855 | # Next try "/var/run/*.pid" files | |
856 | if [ -f /var/run/${base}.pid ]; then | |
857 | read pid < /var/run/${base}.pid | |
1e5e8177 | 858 | pid=$(filter_chroot "$pid") |
8a835e11 | 859 | if [ "$pid" != "" ]; then |
860 | nls "%s dead but pid file exists" "$subsys" | |
861 | return 1 | |
862 | fi | |
863 | fi | |
864 | ||
865 | # See if /var/lock/subsys/$subsys exists | |
866 | if [ -f /var/lock/subsys/$subsys ]; then | |
867 | nls "%s dead but subsys locked" "$subsys" | |
868 | return 2 | |
7742e157 | 869 | fi |
8a835e11 | 870 | nls "%s is stopped" "$subsys" |
871 | return 3 | |
7742e157 | 872 | } |
0524c81f | 873 | |
6b4a354c AM |
874 | # Confirm whether we really want to run this service |
875 | confirm() { | |
da1fc19d | 876 | typeset answer |
d553f606 | 877 | nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1" |
6b4a354c AM |
878 | read answer |
879 | case $answer in | |
8a835e11 | 880 | y|Y|t|T|j|J|"") |
881 | return 0 | |
6b4a354c | 882 | ;; |
8a835e11 | 883 | c|C|k|K|w|W) |
884 | return 2 | |
6b4a354c | 885 | ;; |
8a835e11 | 886 | n|N) |
887 | return 1 | |
6b4a354c | 888 | ;; |
8a835e11 | 889 | *) |
890 | confirm $1 | |
891 | return $? | |
6b4a354c AM |
892 | ;; |
893 | esac | |
894 | } | |
895 | ||
d553f606 JR |
896 | # module is needed (ie. is requested, is available and isn't loaded already) |
897 | is_module() | |
898 | { | |
899 | # module name without .o at end | |
5778a670 ER |
900 | if ! lsmod | grep -q "$1"; then |
901 | if ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.\(\|k\)o\(\|.gz\)"; then | |
d553f606 JR |
902 | # true |
903 | return 0 | |
904 | fi | |
905 | fi | |
906 | # false | |
907 | return 1 | |
0524c81f | 908 | } |
f7b2d235 JR |
909 | |
910 | _modprobe() | |
911 | { | |
da1fc19d | 912 | typeset parsed single die args foo result |
f7b2d235 | 913 | parsed=no |
d553f606 | 914 | while is_no "$parsed" ; do |
f7b2d235 | 915 | case "$1" in |
8a835e11 | 916 | "single") |
917 | single=yes | |
918 | shift | |
919 | ;; | |
920 | "die") | |
921 | die=yes | |
922 | shift | |
923 | ;; | |
924 | -*) | |
925 | args="$args $1" | |
926 | shift | |
927 | ;; | |
928 | *) | |
929 | parsed=yes | |
930 | ;; | |
f7b2d235 JR |
931 | esac |
932 | done | |
933 | if is_yes "${single}" ; then | |
934 | foo="$@" | |
935 | show "Loading %s kernel module(s)" "$foo" | |
f7b2d235 JR |
936 | busy |
937 | fi | |
938 | if [ -x /sbin/modprobe ] ; then | |
939 | /sbin/modprobe -s $args "$@" | |
940 | result=$? | |
941 | else | |
942 | deltext ; fail | |
943 | result=1 | |
944 | fi | |
945 | if is_yes "${single}" ; then | |
946 | deltext | |
947 | if [ $result == "0" ] ; then | |
d553f606 | 948 | is_yes "$single" && ok |
f7b2d235 JR |
949 | else |
950 | fail | |
951 | if is_yes "$die" ; then | |
952 | nls "Could not load %s kernel module(s)" "$@" | |
953 | exit 1 | |
954 | fi | |
955 | fi | |
956 | fi | |
f7b2d235 | 957 | } |
d553f606 | 958 | |
bc94aa53 ER |
959 | if is_no "$RC_LOGGING"; then |
960 | log_success() { | |
961 | : | |
962 | } | |
d553f606 | 963 | |
bc94aa53 ER |
964 | log_failed () { |
965 | : | |
966 | } | |
967 | else | |
968 | log_success () { | |
969 | initlog -n $0 -s "$1 $2" -e 1 | |
970 | } | |
971 | ||
972 | log_failed () { | |
973 | initlog -n $0 -s "$1 $2" -e 2 | |
974 | } | |
975 | fi | |
d553f606 | 976 | |
f0c296a0 JR |
977 | # Check if any flavor of portmapper is running |
978 | check_portmapper() { | |
1cb7535e JR |
979 | typeset RPCINFO |
980 | ||
cbb91a00 ER |
981 | if [ -x /usr/sbin/rpcinfo ]; then |
982 | if /usr/sbin/rpcinfo -p localhost >/dev/null 2>/dev/null; then | |
fd8737b5 | 983 | return 0 |
f0c296a0 JR |
984 | else |
985 | return 1 | |
986 | fi | |
987 | elif [ -x /sbin/pidof ]; then | |
f74fbf2c JR |
988 | [ -z "$(/sbin/pidof portmap)" -a \ |
989 | -z "$(/sbin/pidof rpcbind)" ] && return 1 | |
f0c296a0 JR |
990 | fi |
991 | return 0 | |
992 | } | |
993 | ||
0084dcf3 | 994 | rc_cache_init() { |
6e311c54 ER |
995 | # If we have cachefile, use it. |
996 | # If we don't, create memory variables and try to save silently, | |
acf05b4f | 997 | local cachefile='/var/cache/rc-scripts/msg.cache' |
0084dcf3 | 998 | |
4132441e ER |
999 | local term |
1000 | if is_yes "$ISATTY"; then | |
1001 | term=$TERM | |
1002 | else | |
1003 | term=dumb | |
1004 | fi | |
1005 | ||
0084dcf3 ER |
1006 | # We create $check variable which is used to invalidate the cache. |
1007 | # The $check contains user locale and terminal. | |
4132441e | 1008 | local check="$term.$LC_MESSAGES" |
0084dcf3 | 1009 | |
f9df72e7 | 1010 | if [ -f "$cachefile" -a "$cachefile" -nt /etc/sysconfig/system -a "$cachefile" -nt /etc/sysconfig/init-colors ]; then |
0084dcf3 ER |
1011 | if . "$cachefile" 2>/dev/null; then |
1012 | if [ "$check" = "$_check" ]; then | |
1013 | return | |
1014 | fi | |
1015 | fi | |
f9df72e7 ER |
1016 | fi |
1017 | ||
1018 | # primitive caching | |
1019 | _busy=$(progress "BUSY" "$CBUSY") | |
1020 | _ok=$(progress "DONE") | |
1021 | _started=$(progress "WORK") | |
1022 | _fail=$(progress "FAIL" "$CFAIL") | |
1023 | _died=$(progress "DIED" "$CFAIL") | |
cc54351b ER |
1024 | |
1025 | # we don't use heredoc, as ksh attempts to create tempfile then | |
3ba0bc12 | 1026 | (> "$cachefile" ) 2>/dev/null || return |
cc54351b ER |
1027 | echo "_busy='$_busy';" >> "$cachefile" |
1028 | echo "_ok='$_ok';" >> "$cachefile" | |
1029 | echo "_started='$_started';" >> "$cachefile" | |
1030 | echo "_fail='$_fail';" >> "$cachefile" | |
1031 | echo "_died='$_died';" >> "$cachefile" | |
1032 | echo "_check='$check';" >> "$cachefile" | |
f9df72e7 ER |
1033 | } |
1034 | ||
0084dcf3 | 1035 | rc_gettext_init() { |
9a0a016d ER |
1036 | if [ -z "$GETTEXT" ]; then |
1037 | if [ -x /bin/gettext -o -x /usr/bin/gettext ]; then | |
1038 | GETTEXT=yes | |
1039 | else | |
1040 | GETTEXT=no | |
1041 | fi | |
1042 | fi | |
1043 | ||
1044 | if [ -z "$TPUT" ]; then | |
1045 | if [ -d /usr/share/terminfo ] && [ -x /usr/bin/tput -o -x /bin/tput ] ; then | |
1046 | TPUT=yes | |
1047 | # check if we are on proper terminal | |
1048 | tput longname >/dev/null 2>&1 || TPUT=no | |
1049 | else | |
1050 | TPUT=no | |
1051 | fi | |
1052 | fi | |
1053 | } | |
1054 | ||
0084dcf3 ER |
1055 | rc_gettext_init |
1056 | rc_cache_init | |
f9df72e7 | 1057 | |
bbb612de AM |
1058 | #/* |
1059 | # * Local variables: | |
1060 | # * mode: sh | |
1061 | # * indent-tabs-mode: notnil | |
1062 | # * End: | |
1063 | # * | |
bbb612de | 1064 | # */ |