1 #!/bin/sh - keep it for file(1) to get bourne shell script result
2 # functions This file contains functions to be used by most or all
3 # shell scripts in the /etc/init.d directory.
7 # Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
8 # Hacked by: Greg Galloway and Marc Ewing
9 # Modified for PLD Linux by:
10 # Marek Obuchowicz <elephant@pld-linux.org>
11 # Arkadiusz Miśkiewicz <misiek@pld-linux.org>
12 # Michał Kochanowicz <mkochano@pld-linux.org>
13 # Łukasz Pawelczyk <havner@pld-linux.org>
15 # First set up a default search path.
16 export PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin"
30 # Bold definition (second parameter to termput setaf)
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
42 CHARS="" # Characters displayed on the beginning of show line
43 CCHARS="$NORMAL" # Color of these characters (look at /etc/sysconfig/init-colors.gentoo example)
45 # Source configuration if available - may override default values
46 [ -r /etc/sysconfig/init-colors ] && . /etc/sysconfig/init-colors
47 [ -r /etc/sysconfig/system ] && . /etc/sysconfig/system
48 [ -r /etc/sysconfig/bootsplash ] && . /etc/sysconfig/bootsplash
49 [ -z "$COLUMNS" ] && COLUMNS=80
51 if [ -z "$VSERVER" -o "$VSERVER" = "detect" ]; then
53 while read _f _ctx; do
54 [ "$_f" = "VxID:" -o "$_f" = "s_context:" ] && break
55 done </proc/self/status
57 if [ -z "$_ctx" -o "$_ctx" = "0" ]; then
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
74 msg_usage " is_yes {value}"
80 yes|Yes|YES|true|True|TRUE|on|On|ON|Y|y|1)
94 msg_usage " is_no {value}"
99 no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0)
110 # checks if file is empty
111 # empty lines and lines beginning with hash are ignored
113 [ -s "$1" ] || return 0
114 egrep -vq "^(#|[[:blank:]]*$)" "$1" && return 1 || return 0
117 # returns OK if $1 contains $2
120 [ "${1#*$a*}" = "$1" ] && return 1
124 if is_yes "$FASTRC" || is_yes "$IN_SHUTDOWN"; then
128 if is_no "$RC_LOGGING"; then
131 while [ "$1" != "${1##-}" ]; do
149 typeset _x _y _z v old_IFS ver
157 # strip _* or -* from versions like: "2.6.25_vanilla-1", "2.6.25-1"
160 while [ ${#ver} -lt 3 ]; do ver="0$ver"; done
162 while [ ${#ver} -lt 6 ]; do ver="0$ver"; done
164 while [ ${#ver} -lt 9 ]; do ver="0$ver"; done
170 typeset _x _y _z v old_IFS ver
178 while [ ${#ver} -lt 3 ] ; do ver="0$ver" ; done
180 while [ ${#ver} -lt 6 ] ; do ver="0$ver" ; done
186 typeset _x _y _z v old_IFS ver
194 while [ ${#ver} -lt 3 ] ; do ver="0$ver" ; done
201 is_yes "$ISATTY" || return
203 if is_yes "$FASTRC" || is_no "$TPUT"; then
206 echo -ne "\033[$(($2+1))G"
209 echo -ne "\033[${2}A"
221 is_yes "$COLOR_INIT" && echo -ne "\033[${ISBOLD};3${2}m"
224 termput setaf $NORMAL
233 if [ "$3" == "1" ]; then tput bold; else tput sgr0; fi
234 is_yes "$COLOR_INIT" && tput setaf "$2"
237 termput setaf $NORMAL
243 if [ ! -x /bin/printf ]; then
245 # FIXME: buggy when single or double quotes in message!
250 if [ $# -gt 0 ]; then
253 while [ $# -gt 0 ]; do
258 awk "BEGIN {printf \"$text\", \"$m\"; }"
262 # National language support function
264 typeset msg_echo nls_domain text message
266 nls_domain="$NLS_DOMAIN"
267 while [ "$1" != "${1##-}" ]; do
283 # empty message, so we return --misiek
284 if [ -z "$message" ]; then
289 if is_yes "$GETTEXT"; then
290 message=$(TEXTDOMAINDIR="/etc/sysconfig/locale" gettext -e --domain="${nls_domain:-rc-scripts}" "$message")
293 printf "$message" "$@"
302 if ! is_no "$BOOT_SPLASH" && ! is_yes "$VSERVER"; then
303 [ -x /bin/splash ] && /bin/splash "$action"
310 nls "ERROR: Networking is down. %s can't be run." "$1" >&2
314 show "Starting %s service" "$1"
317 msg_already_running() {
318 nls "%s service is already running." "$1"
322 show "Stopping %s service" "$1"
326 nls "%s service is not running." "$1"
330 show "Reloading %s service" "$1"
337 # Some functions to handle PLD Linux-style messages
342 if is_no "$FASTRC" && is_yes "$GETTEXT"; then
348 while [ $((len++)) -lt $INIT_COL ]; do
351 if [ -n "$CHARS" ]; then
352 termput setaf $CCHARS
360 termput hpa $INIT_COL
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
369 if [ -n "$2" ]; then COLOR="$2"; else COLOR="$CDONE"; fi
371 echo -n "$(termput setaf $CBRACKETS)[$(termput setaf $COLOR) $(nls --nls-domain rc-scripts "$1") $(termput setaf $CBRACKETS)]$(termput op)"
396 # Check if $pid (could be plural) are running
399 [ -d "/proc/$1" ] && return 0
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)
408 # (note: some processes like named are chrooted but run outside chroot)
409 # - do nothing inside vserver
411 if is_yes "$VSERVER"; then
415 if [ $# -lt 1 -o ! -d /proc/1 ] ; then
419 local root_dir good_pids="" good_add_pid
420 for root_pid in $@; do
421 root_dir=$(resolvesymlink /proc/${root_pid}/root)
422 if [ -n "$root_dir" ]; then
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
429 [ "$good_add_pid" -eq 1 ] && good_pids="$good_pids $root_pid"
430 elif [ ! -d "/proc/$root_pid" ]; then
431 good_pids="$good_pids $root_pid"
437 # Usage run_cmd Message command_to_run
439 typeset exit_code errors message force_err
440 typeset -i force_err=0
441 typeset -i exit_code=0
449 show "$message"; busy
453 export HOME=/tmp TMPDIR=/tmp
454 if is_no "$RC_LOGGING"; then
461 log_success "$1 $message"
464 log_failed "$1 $message"
467 [ -n "$errors" ] && [ $exit_code -eq 1 -o $force_err -eq 1 ] && echo "$errors"
471 _daemon_set_ulimits() {
472 local opt val ksh=${KSH_VERSION:+1}
473 set -- ${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS}
474 while [ $# -gt 0 ]; do
495 # A function to start a program (now it's useful on read-only filesystem too)
497 typeset errors="" prog="" end="" waitname="" waittime=""
498 typeset -i exit_code=0
499 local nice=$SERVICE_RUN_NICE_LEVEL
500 local fork user closefds pidfile chdir=/
502 while [ $# -gt 0 ]; do
505 msg_usage " daemon [--user user] [--fork] [--waitforname procname] [--waitfortime seconds] [+/-nicelevel] {program} <program args>"
509 # for compatibility with redhat/mandrake
510 nls "warning: --check option is ignored!"
515 [ "$1" != "root" ] && prog="/bin/su $1 -s /bin/sh -c \""
520 prog="/usr/bin/setsid sh -c \""
553 # If command to execute ends with quotation mark, add remaining
554 # arguments and close quotation.
555 if [ "$prog" != "${prog%\"}" ]; then
556 prog="$prog $*$end\""
563 [ -z "$DEFAULT_SERVICE_UMASK" ] && DEFAULT_SERVICE_UMASK=022
564 [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
569 [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" && echo $$ > "/dev/cpuset/${SERVICE_CPUSET}/tasks"
571 umask ${SERVICE_UMASK:-$DEFAULT_SERVICE_UMASK};
572 export USER=root HOME=/tmp TMPDIR=/tmp
573 nice=${nice:-$DEFAULT_SERVICE_RUN_NICE_LEVEL}
576 if [ "$closefds" = 1 ]; then
584 if is_no "$RC_LOGGING" ; then
586 if [ ! -x $prog ]; then
587 logger -t rc-scripts -p daemon.debug "daemon: Searching PATH for $prog, consider using full path in initscript"
591 if [ -x $a/$prog ]; then
598 /sbin/start-stop-daemon -q --start \
600 ${pidfile:+--pidfile $pidfile} \
602 ${chdir:+--chdir "$chdir"} \
607 nice -n $nice initlog -c "$prog" 2>&1
611 if [ -n "$waitname" -a -n "$waittime" ]; then
615 pid=$(pidofproc "$waitname" "$pidfile")
616 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
618 while [ "$i" -lt "$waittime" ]; do
620 checkpid $pid && sleep 1 || break
623 log_success "$1 startup"
628 log_failed "$1 startup"
629 [ -n "$errors" ] && echo "$errors"
634 # A function to stop a program.
636 typeset notset killlevel base pid pidfile result
639 msg_usage " killproc {program} [signal]"
643 while [ "$1" != "${1##-}" ]; do
666 # check for second arg to be kill level
667 if [ -n "$2" ] ; then
678 pid=$(pidofproc "$1" "$pidfile")
679 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
682 if [ -n "$pid" -a "$pid" != "$$" ] && checkpid $pid 2>&1 ; then
683 if [ "$notset" = "1" ] ; then
684 if checkpid $pid 2>&1; then
685 # TERM first, then KILL if not dead
688 if checkpid $pid && sleep 1 &&
689 checkpid $pid && sleep 3 &&
697 if [ "$result" -eq 0 ]; then
699 log_failed "$1 shutdown"
702 log_success "$1 shutdown"
704 result=$(( ! $result ))
706 # use specified level only
707 if checkpid $pid > /dev/null 2>&1; then
710 if [ "$result" -eq 0 ]; then
712 log_success "$1 got $killlevel"
716 log_failed "$1 didn't get $killlevel"
721 log_failed "$1 shutdown"
726 log_failed "$1 shutdown"
730 if [ -n "$waitname" -a -n "$waittime" ]; then
734 pid=$(pidofproc "$waitname" "$pidfile")
735 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
737 while [ "$i" -lt "$waittime" ]; do
739 checkpid $pid && sleep 1 || break
743 # Remove pid file if any.
744 if [ "$notset" = "1" ]; then
745 rm -f /var/run/${base}.pid
751 # A function to find the pid of a program.
753 typeset pid pidfile base=${1##*/}
755 [ -n "$2" ] && pidfile="$2"
759 msg_usage " pidofproc {program}"
763 # First try pidfile or "/var/run/*.pid"
764 if [[ "$pidfile" = /* ]]; then
767 pidfile="/var/run/${pidfile}";
769 if [ -f "${pidfile}" ] ; then
772 for p in $(< "${pidfile}"); do
773 [ -z "$(echo "$p" | awk '{gsub(/[0-9]/,"");print;}')" ] && pid="$pid $p"
778 [ -z "$pid" ] && pidof -o $$ -o $PPID -o %PPID -x "$1"
779 pid=$(filter_chroot "$pid")
784 typeset pid subsys daemon cpuset_msg
787 local base=${daemon##*/}
791 msg_usage " status {subsys} [{daemon}]"
796 pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon)
797 pid=$(filter_chroot "$pid")
801 if [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" ]; then
802 if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then
803 cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET")
805 cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET")
808 nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg"
811 # pid=$(ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
812 # { if ((prog == $5) || (("(" prog ")") == $5) ||
813 # (("[" prog "]") == $5) ||
814 # ((prog ":") == $5)) { print $1 ; exit 0 } }' $1)
815 # if [ "$pid" != "" ]; then
817 # if [ -n "$SERVICE_CPUSET" ] && is_yes "$CPUSETS" ]; then
818 # if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then
819 # cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET")
821 # cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET")
824 # nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg"
829 # Next try "/var/run/*.pid" files
830 if [ -f /var/run/${base}.pid ]; then
831 read pid < /var/run/${base}.pid
832 pid=$(filter_chroot "$pid")
833 if [ "$pid" != "" ]; then
834 nls "%s dead but pid file exists" "$subsys"
839 # See if /var/lock/subsys/$subsys exists
840 if [ -f /var/lock/subsys/$subsys ]; then
841 nls "%s dead but subsys locked" "$subsys"
844 nls "%s is stopped" "$subsys"
848 # Confirm whether we really want to run this service
851 nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1"
870 # module is needed (ie. is requested, is available and isn't loaded already)
872 # module name without .o at end
873 if ! lsmod | grep -q "$1"; then
874 if ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.\(\|k\)o\(\|.gz\)"; then
884 typeset parsed single die args foo result
886 while is_no "$parsed" ; do
905 if is_yes "${single}" ; then
907 show "Loading %s kernel module(s)" "$foo"
910 if [ -x /sbin/modprobe ] ; then
911 /sbin/modprobe -s $args "$@"
917 if is_yes "${single}" ; then
919 if [ $result == "0" ] ; then
920 is_yes "$single" && ok
923 if is_yes "$die" ; then
924 nls "Could not load %s kernel module(s)" "$@"
931 if is_no "$RC_LOGGING"; then
941 initlog -n $0 -s "$1 $2" -e 1
945 initlog -n $0 -s "$1 $2" -e 2
949 # Check if any flavor of portmapper is running
953 if [ -x /usr/sbin/rpcinfo ]; then
954 if /usr/sbin/rpcinfo -p localhost >/dev/null 2>/dev/null; then
959 elif [ -x /sbin/pidof ]; then
960 [ -z "$(/sbin/pidof portmap)" -a \
961 -z "$(/sbin/pidof rpcbind)" ] && return 1
967 # If we have cachefile, use it.
968 # If we don't, create memory variables and try to save silently,
969 local cachefile='/var/cache/rc-scripts/msg.cache'
972 if is_yes "$ISATTY"; then
978 # We create $check variable which is used to invalidate the cache.
979 # The $check contains user locale and terminal.
980 local check="$term.$LC_MESSAGES"
982 if [ -f "$cachefile" -a "$cachefile" -nt /etc/sysconfig/system -a "$cachefile" -nt /etc/sysconfig/init-colors ]; then
983 if . "$cachefile" 2>/dev/null; then
984 if [ "$check" = "$_check" ]; then
991 _busy=$(progress "BUSY" "$CBUSY")
992 _ok=$(progress "DONE")
993 _started=$(progress "WORK")
994 _fail=$(progress "FAIL" "$CFAIL")
995 _died=$(progress "DIED" "$CFAIL")
997 # we don't use heredoc, as ksh attempts to create tempfile then
998 (> "$cachefile" ) 2>/dev/null || return
999 echo "_busy='$_busy';" >> "$cachefile"
1000 echo "_ok='$_ok';" >> "$cachefile"
1001 echo "_started='$_started';" >> "$cachefile"
1002 echo "_fail='$_fail';" >> "$cachefile"
1003 echo "_died='$_died';" >> "$cachefile"
1004 echo "_check='$check';" >> "$cachefile"
1008 if [ -z "$GETTEXT" ]; then
1009 if [ -x /bin/gettext -o -x /usr/bin/gettext ]; then
1016 if [ -z "$TPUT" ]; then
1017 if [ -d /usr/share/terminfo ] && [ -x /usr/bin/tput -o -x /bin/tput ] ; then
1019 # check if we are on proper terminal
1020 tput longname >/dev/null 2>&1 || TPUT=no
1031 # * Local variables:
1033 # * indent-tabs-mode: notnil