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