]>
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 |
f10f2102 | 500 | local fork user closefds pidfile |
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 | ;; |
739070c4 ER |
523 | --closefds) |
524 | closefds=1 | |
f10f2102 | 525 | ;; |
739070c4 | 526 | --waitforname) |
b486c392 | 527 | shift |
683d384e | 528 | waitname="$1" |
683d384e | 529 | ;; |
739070c4 | 530 | --waitfortime) |
b486c392 | 531 | shift |
683d384e | 532 | waittime="$1" |
683d384e | 533 | ;; |
739070c4 | 534 | --pidfile) |
0a177614 ER |
535 | shift |
536 | pidfile="$1" | |
537 | ;; | |
739070c4 | 538 | -*|+*) |
42595a81 | 539 | nice=$1 |
a6e727aa | 540 | shift |
42595a81 ER |
541 | break |
542 | ;; | |
739070c4 | 543 | *) |
42595a81 | 544 | break |
683d384e | 545 | ;; |
d553f606 | 546 | esac |
42595a81 | 547 | shift |
d553f606 | 548 | done |
2eea8492 | 549 | # If command to execute ends with quotation mark, add remaining |
550 | # arguments and close quotation. | |
551 | if [ "$prog" != "${prog%\"}" ]; then | |
565736ed | 552 | prog="$prog $*$end\"" |
2eea8492 | 553 | else |
565736ed | 554 | prog="$prog $*$end" |
2eea8492 | 555 | fi |
7742e157 | 556 | |
e81194ca | 557 | _daemon_set_ulimits |
f054a85e | 558 | |
3edf5e48 | 559 | [ -z "$DEFAULT_SERVICE_UMASK" ] && DEFAULT_SERVICE_UMASK=022 |
42595a81 | 560 | [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0 |
3edf5e48 | 561 | |
7742e157 AF |
562 | # And start it up. |
563 | busy | |
90c59319 | 564 | cd / |
42595a81 | 565 | [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" && echo $$ > "/dev/cpuset/${SERVICE_CPUSET}/tasks" |
18bd13ac | 566 | if errors=$( |
f10f2102 | 567 | umask ${SERVICE_UMASK:-$DEFAULT_SERVICE_UMASK}; |
739070c4 | 568 | export USER=root HOME=/tmp TMPDIR=/tmp |
f10f2102 ER |
569 | nice=${nice:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} |
570 | nice=${nice:-0} | |
571 | ||
572 | if [ "$closefds" = 1 ]; then | |
573 | exec 1>&- | |
574 | exec 2>&- | |
575 | exec 0>&- | |
576 | else | |
577 | exec 2>&1 | |
578 | fi | |
579 | ||
580 | if is_no "$RC_LOGGING" ; then | |
581 | prog=$1; shift | |
582 | if [ ! -x $prog ]; then | |
583 | logger -t rc-scripts -p daemon.debug "daemon: Searching PATH for $prog, consider using full path in initscript" | |
584 | local a o=$IFS | |
585 | IFS=: | |
586 | for a in $PATH; do | |
587 | if [ -x $a/$prog ]; then | |
588 | prog=$a/$prog | |
589 | break | |
590 | fi | |
591 | done | |
592 | IFS=$o | |
593 | fi | |
594 | /sbin/start-stop-daemon -q --start \ | |
595 | --nicelevel $nice \ | |
596 | ${pidfile:+--pidfile $pidfile} \ | |
a526f709 | 597 | ${user:+-c $user} \ |
f10f2102 ER |
598 | ${fork:+-b} \ |
599 | --exec "$prog" \ | |
600 | -- ${1:+"$@"} | |
601 | else | |
602 | nice -n $nice initlog -c "$prog" 2>&1 | |
603 | fi | |
18bd13ac | 604 | ); then |
f10f2102 | 605 | |
683d384e AM |
606 | if [ -n "$waitname" -a -n "$waittime" ]; then |
607 | # Save basename. | |
03e01a49 | 608 | base=${waitname##*/} |
683d384e AM |
609 | # Find pid. |
610 | pid=$(pidofproc "$waitname" "$pidfile") | |
611 | [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile") | |
612 | i=0 | |
613 | while [ "$i" -lt "$waittime" ]; do | |
42595a81 | 614 | i=$((i + 1)) |
683d384e AM |
615 | checkpid $pid && sleep 1 || break |
616 | done | |
617 | fi | |
d553f606 | 618 | log_success "$1 startup" |
1b228409 | 619 | ok |
7742e157 | 620 | else |
b7299ffc | 621 | exit_code=1 |
1b228409 | 622 | fail |
d553f606 JR |
623 | log_failed "$1 startup" |
624 | [ -n "$errors" ] && echo "$errors" | |
7742e157 | 625 | fi |
b7299ffc | 626 | return $exit_code |
7742e157 AF |
627 | } |
628 | ||
629 | # A function to stop a program. | |
18bd13ac | 630 | killproc() { |
8de7f381 | 631 | typeset notset killlevel base pid pidfile result |
7742e157 AF |
632 | # Test syntax. |
633 | if [ $# = 0 ]; then | |
d553f606 | 634 | msg_usage " killproc {program} [signal]" |
228edf1d | 635 | return 2 |
7742e157 AF |
636 | fi |
637 | ||
bb49a1c7 | 638 | while [ "$1" != "${1##-}" ]; do |
8de7f381 | 639 | case $1 in |
739070c4 | 640 | --pidfile) |
5e6dfc29 JR |
641 | shift |
642 | pidfile="$1" | |
643 | shift | |
8de7f381 | 644 | ;; |
739070c4 | 645 | --waitforname) |
5e6dfc29 JR |
646 | shift |
647 | waitname="$1" | |
648 | shift | |
683d384e | 649 | ;; |
739070c4 | 650 | --waitfortime) |
5e6dfc29 JR |
651 | shift |
652 | waittime="$1" | |
653 | shift | |
683d384e | 654 | ;; |
8de7f381 AM |
655 | esac |
656 | done | |
657 | ||
7742e157 | 658 | busy |
8a835e11 | 659 | |
d553f606 | 660 | typeset -i notset=0 |
7742e157 | 661 | # check for second arg to be kill level |
d553f606 | 662 | if [ -n "$2" ] ; then |
7742e157 AF |
663 | killlevel=$2 |
664 | else | |
665 | notset=1 | |
666 | killlevel="-9" | |
667 | fi | |
668 | ||
228edf1d | 669 | # Save basename. |
03e01a49 | 670 | base=${1##*/} |
7742e157 | 671 | |
228edf1d | 672 | # Find pid. |
8de7f381 AM |
673 | pid=$(pidofproc "$1" "$pidfile") |
674 | [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile") | |
7742e157 | 675 | |
228edf1d | 676 | # Kill it. |
34b6b730 | 677 | if [ -n "$pid" -a "$pid" != "$$" ] && checkpid $pid 2>&1 ; then |
830949ca | 678 | if [ "$notset" = "1" ] ; then |
228edf1d | 679 | if checkpid $pid 2>&1; then |
680 | # TERM first, then KILL if not dead | |
681 | kill -TERM $pid | |
682 | usleep 100000 | |
683 | if checkpid $pid && sleep 1 && | |
684 | checkpid $pid && sleep 3 && | |
685 | checkpid $pid; then | |
686 | kill -KILL $pid | |
687 | usleep 100000 | |
688 | fi | |
7742e157 | 689 | fi |
228edf1d | 690 | checkpid $pid |
bbb612de AM |
691 | result=$? |
692 | if [ "$result" -eq 0 ]; then | |
228edf1d | 693 | fail |
694 | log_failed "$1 shutdown" | |
695 | else | |
696 | ok | |
697 | log_success "$1 shutdown" | |
698 | fi | |
699 | result=$(( ! $result )) | |
700 | else | |
701 | # use specified level only | |
702 | if checkpid $pid > /dev/null 2>&1; then | |
703 | kill $killlevel $pid | |
704 | result=$? | |
705 | if [ "$result" -eq 0 ]; then | |
706 | ok | |
707 | log_success "$1 got $killlevel" | |
708 | else | |
709 | result=7 | |
710 | fail | |
711 | log_failed "$1 didn't get $killlevel" | |
712 | fi | |
e016cdae | 713 | else |
228edf1d | 714 | result=7 |
715 | died | |
716 | log_failed "$1 shutdown" | |
e016cdae | 717 | fi |
7742e157 AF |
718 | fi |
719 | else | |
228edf1d | 720 | died |
721 | log_failed "$1 shutdown" | |
722 | result=7 | |
7742e157 | 723 | fi |
5e6dfc29 | 724 | |
683d384e | 725 | if [ -n "$waitname" -a -n "$waittime" ]; then |
e6f93a80 | 726 | # Save basename. |
03e01a49 | 727 | base=${waitname##*/} |
e6f93a80 AM |
728 | # Find pid. |
729 | pid=$(pidofproc "$waitname" "$pidfile") | |
730 | [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile") | |
683d384e AM |
731 | i=0 |
732 | while [ "$i" -lt "$waittime" ]; do | |
1101d321 | 733 | i=$(( i + 1 )) |
683d384e AM |
734 | checkpid $pid && sleep 1 || break |
735 | done | |
736 | fi | |
7742e157 | 737 | |
228edf1d | 738 | # Remove pid file if any. |
e016cdae | 739 | if [ "$notset" = "1" ]; then |
228edf1d | 740 | rm -f /var/run/${base}.pid |
7742e157 | 741 | fi |
bbb612de AM |
742 | |
743 | return $result | |
7742e157 AF |
744 | } |
745 | ||
746 | # A function to find the pid of a program. | |
18bd13ac | 747 | pidofproc() { |
03e01a49 | 748 | typeset pid pidfile base=${1##*/} |
8de7f381 AM |
749 | pidfile="$base.pid" |
750 | [ -n "$2" ] && pidfile="$2" | |
7742e157 | 751 | |
8a835e11 | 752 | # Test syntax. |
753 | if [ $# = 0 ] ; then | |
754 | msg_usage " pidofproc {program}" | |
755 | return 2 | |
756 | fi | |
757 | ||
8de7f381 | 758 | # First try pidfile or "/var/run/*.pid" |
f955cf0f | 759 | if [[ "$pidfile" = /* ]]; then |
1c26fe27 AM |
760 | pidfile="${pidfile}" |
761 | else | |
762 | pidfile="/var/run/${pidfile}"; | |
763 | fi | |
764 | if [ -f "${pidfile}" ] ; then | |
7eb94de6 | 765 | typeset p pid |
8a835e11 | 766 | pid= |
7eb94de6 | 767 | for p in $(< "${pidfile}"); do |
3030e60e | 768 | [ -z "$(echo "$p" | awk '{gsub(/[0-9]/,"");print;}')" ] && pid="$pid $p" |
8a835e11 | 769 | done |
7742e157 | 770 | fi |
8a835e11 | 771 | |
7742e157 | 772 | # Next try "pidof" |
1e5e8177 AM |
773 | [ -z "$pid" ] && pidof -o $$ -o $PPID -o %PPID -x "$1" |
774 | pid=$(filter_chroot "$pid") | |
775 | echo $pid | |
7742e157 | 776 | } |
12de71be | 777 | |
18bd13ac | 778 | status() { |
03e01a49 | 779 | typeset pid subsys daemon cpuset_msg |
8a835e11 | 780 | subsys=$1 |
781 | daemon=${2:-$subsys} | |
03e01a49 | 782 | local base=${daemon##*/} |
bbb612de | 783 | |
8a835e11 | 784 | # Test syntax. |
785 | if [ $# = 0 ] ; then | |
786 | msg_usage " status {subsys} [{daemon}]" | |
787 | return 2 | |
788 | fi | |
bbb612de | 789 | |
8a835e11 | 790 | # First try "pidof" |
791 | pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon) | |
1e5e8177 | 792 | pid=$(filter_chroot "$pid") |
bbb612de | 793 | |
b90fbc1e | 794 | if [ "$pid" ]; then |
814e38ce | 795 | cpuset_msg="..." |
b90fbc1e | 796 | if [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" ]; then |
6c99c680 | 797 | if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then |
814e38ce JR |
798 | cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET") |
799 | else | |
800 | cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET") | |
801 | fi | |
802 | fi | |
803 | nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg" | |
8a835e11 | 804 | return 0 |
805 | # else | |
f74fbf2c | 806 | # pid=$(ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } |
8a835e11 | 807 | # { if ((prog == $5) || (("(" prog ")") == $5) || |
5e6dfc29 | 808 | # (("[" prog "]") == $5) || |
f74fbf2c | 809 | # ((prog ":") == $5)) { print $1 ; exit 0 } }' $1) |
8a835e11 | 810 | # if [ "$pid" != "" ]; then |
54e6320e | 811 | # cpuset_msg="..." |
b90fbc1e | 812 | # if [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" ]; then |
6c99c680 | 813 | # if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then |
54e6320e JR |
814 | # cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET") |
815 | # else | |
816 | # cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET") | |
817 | # fi | |
818 | # fi | |
819 | # nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg" | |
8a835e11 | 820 | # return 0 |
821 | # fi | |
822 | fi | |
823 | ||
824 | # Next try "/var/run/*.pid" files | |
825 | if [ -f /var/run/${base}.pid ]; then | |
826 | read pid < /var/run/${base}.pid | |
1e5e8177 | 827 | pid=$(filter_chroot "$pid") |
8a835e11 | 828 | if [ "$pid" != "" ]; then |
829 | nls "%s dead but pid file exists" "$subsys" | |
830 | return 1 | |
831 | fi | |
832 | fi | |
833 | ||
834 | # See if /var/lock/subsys/$subsys exists | |
835 | if [ -f /var/lock/subsys/$subsys ]; then | |
836 | nls "%s dead but subsys locked" "$subsys" | |
837 | return 2 | |
7742e157 | 838 | fi |
8a835e11 | 839 | nls "%s is stopped" "$subsys" |
840 | return 3 | |
7742e157 | 841 | } |
0524c81f | 842 | |
6b4a354c AM |
843 | # Confirm whether we really want to run this service |
844 | confirm() { | |
da1fc19d | 845 | typeset answer |
d553f606 | 846 | nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1" |
6b4a354c AM |
847 | read answer |
848 | case $answer in | |
739070c4 | 849 | y|Y|t|T|j|J|"") |
8a835e11 | 850 | return 0 |
6b4a354c | 851 | ;; |
739070c4 | 852 | c|C|k|K|w|W) |
8a835e11 | 853 | return 2 |
6b4a354c | 854 | ;; |
739070c4 | 855 | n|N) |
8a835e11 | 856 | return 1 |
6b4a354c | 857 | ;; |
739070c4 | 858 | *) |
8a835e11 | 859 | confirm $1 |
860 | return $? | |
6b4a354c AM |
861 | ;; |
862 | esac | |
863 | } | |
864 | ||
d553f606 | 865 | # module is needed (ie. is requested, is available and isn't loaded already) |
18bd13ac | 866 | is_module() { |
d553f606 | 867 | # module name without .o at end |
5778a670 ER |
868 | if ! lsmod | grep -q "$1"; then |
869 | if ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.\(\|k\)o\(\|.gz\)"; then | |
d553f606 JR |
870 | # true |
871 | return 0 | |
872 | fi | |
873 | fi | |
874 | # false | |
875 | return 1 | |
0524c81f | 876 | } |
f7b2d235 | 877 | |
18bd13ac | 878 | _modprobe() { |
da1fc19d | 879 | typeset parsed single die args foo result |
f7b2d235 | 880 | parsed=no |
d553f606 | 881 | while is_no "$parsed" ; do |
f7b2d235 | 882 | case "$1" in |
739070c4 | 883 | "single") |
8a835e11 | 884 | single=yes |
885 | shift | |
886 | ;; | |
739070c4 | 887 | "die") |
8a835e11 | 888 | die=yes |
889 | shift | |
890 | ;; | |
739070c4 | 891 | -*) |
8a835e11 | 892 | args="$args $1" |
893 | shift | |
894 | ;; | |
739070c4 | 895 | *) |
8a835e11 | 896 | parsed=yes |
897 | ;; | |
f7b2d235 JR |
898 | esac |
899 | done | |
900 | if is_yes "${single}" ; then | |
901 | foo="$@" | |
902 | show "Loading %s kernel module(s)" "$foo" | |
f7b2d235 JR |
903 | busy |
904 | fi | |
905 | if [ -x /sbin/modprobe ] ; then | |
906 | /sbin/modprobe -s $args "$@" | |
907 | result=$? | |
908 | else | |
909 | deltext ; fail | |
910 | result=1 | |
911 | fi | |
912 | if is_yes "${single}" ; then | |
913 | deltext | |
914 | if [ $result == "0" ] ; then | |
d553f606 | 915 | is_yes "$single" && ok |
f7b2d235 JR |
916 | else |
917 | fail | |
918 | if is_yes "$die" ; then | |
919 | nls "Could not load %s kernel module(s)" "$@" | |
920 | exit 1 | |
921 | fi | |
922 | fi | |
923 | fi | |
f7b2d235 | 924 | } |
d553f606 | 925 | |
bc94aa53 ER |
926 | if is_no "$RC_LOGGING"; then |
927 | log_success() { | |
928 | : | |
929 | } | |
d553f606 | 930 | |
18bd13ac | 931 | log_failed() { |
bc94aa53 ER |
932 | : |
933 | } | |
934 | else | |
18bd13ac | 935 | log_success() { |
bc94aa53 ER |
936 | initlog -n $0 -s "$1 $2" -e 1 |
937 | } | |
938 | ||
18bd13ac | 939 | log_failed() { |
bc94aa53 ER |
940 | initlog -n $0 -s "$1 $2" -e 2 |
941 | } | |
942 | fi | |
d553f606 | 943 | |
f0c296a0 JR |
944 | # Check if any flavor of portmapper is running |
945 | check_portmapper() { | |
1cb7535e JR |
946 | typeset RPCINFO |
947 | ||
cbb91a00 ER |
948 | if [ -x /usr/sbin/rpcinfo ]; then |
949 | if /usr/sbin/rpcinfo -p localhost >/dev/null 2>/dev/null; then | |
fd8737b5 | 950 | return 0 |
f0c296a0 JR |
951 | else |
952 | return 1 | |
953 | fi | |
954 | elif [ -x /sbin/pidof ]; then | |
f74fbf2c | 955 | [ -z "$(/sbin/pidof portmap)" -a \ |
739070c4 | 956 | -z "$(/sbin/pidof rpcbind)" ] && return 1 |
f0c296a0 JR |
957 | fi |
958 | return 0 | |
959 | } | |
960 | ||
0084dcf3 | 961 | rc_cache_init() { |
6e311c54 ER |
962 | # If we have cachefile, use it. |
963 | # If we don't, create memory variables and try to save silently, | |
acf05b4f | 964 | local cachefile='/var/cache/rc-scripts/msg.cache' |
0084dcf3 | 965 | |
4132441e ER |
966 | local term |
967 | if is_yes "$ISATTY"; then | |
968 | term=$TERM | |
969 | else | |
970 | term=dumb | |
971 | fi | |
972 | ||
0084dcf3 ER |
973 | # We create $check variable which is used to invalidate the cache. |
974 | # The $check contains user locale and terminal. | |
4132441e | 975 | local check="$term.$LC_MESSAGES" |
0084dcf3 | 976 | |
f9df72e7 | 977 | if [ -f "$cachefile" -a "$cachefile" -nt /etc/sysconfig/system -a "$cachefile" -nt /etc/sysconfig/init-colors ]; then |
0084dcf3 ER |
978 | if . "$cachefile" 2>/dev/null; then |
979 | if [ "$check" = "$_check" ]; then | |
980 | return | |
981 | fi | |
982 | fi | |
f9df72e7 ER |
983 | fi |
984 | ||
985 | # primitive caching | |
986 | _busy=$(progress "BUSY" "$CBUSY") | |
987 | _ok=$(progress "DONE") | |
988 | _started=$(progress "WORK") | |
989 | _fail=$(progress "FAIL" "$CFAIL") | |
990 | _died=$(progress "DIED" "$CFAIL") | |
cc54351b ER |
991 | |
992 | # we don't use heredoc, as ksh attempts to create tempfile then | |
3ba0bc12 | 993 | (> "$cachefile" ) 2>/dev/null || return |
cc54351b ER |
994 | echo "_busy='$_busy';" >> "$cachefile" |
995 | echo "_ok='$_ok';" >> "$cachefile" | |
996 | echo "_started='$_started';" >> "$cachefile" | |
997 | echo "_fail='$_fail';" >> "$cachefile" | |
998 | echo "_died='$_died';" >> "$cachefile" | |
999 | echo "_check='$check';" >> "$cachefile" | |
f9df72e7 ER |
1000 | } |
1001 | ||
0084dcf3 | 1002 | rc_gettext_init() { |
9a0a016d ER |
1003 | if [ -z "$GETTEXT" ]; then |
1004 | if [ -x /bin/gettext -o -x /usr/bin/gettext ]; then | |
1005 | GETTEXT=yes | |
1006 | else | |
1007 | GETTEXT=no | |
1008 | fi | |
1009 | fi | |
1010 | ||
1011 | if [ -z "$TPUT" ]; then | |
1012 | if [ -d /usr/share/terminfo ] && [ -x /usr/bin/tput -o -x /bin/tput ] ; then | |
1013 | TPUT=yes | |
1014 | # check if we are on proper terminal | |
1015 | tput longname >/dev/null 2>&1 || TPUT=no | |
1016 | else | |
1017 | TPUT=no | |
1018 | fi | |
1019 | fi | |
1020 | } | |
1021 | ||
0084dcf3 ER |
1022 | rc_gettext_init |
1023 | rc_cache_init | |
f9df72e7 | 1024 | |
bbb612de AM |
1025 | #/* |
1026 | # * Local variables: | |
1027 | # * mode: sh | |
1028 | # * indent-tabs-mode: notnil | |
1029 | # * End: | |
1030 | # * | |
bbb612de | 1031 | # */ |