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
50 [ -z "$COLUMNS" ] && COLUMNS=80
52 if [ -z "$VSERVER" -o "$VSERVER" = "detect" ]; then
54 while read _f _ctx; do
55 [ "$_f" = "VxID:" -o "$_f" = "s_context:" ] && break
56 done </proc/self/status
58 if [ -z "$_ctx" -o "$_ctx" = "0" ]; then
70 msg_usage " is_yes {value}"
76 yes|Yes|YES|true|True|TRUE|on|On|ON|Y|y|1)
91 msg_usage " is_no {value}"
96 no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0)
107 if is_yes "$FASTRC"; then
111 if is_yes "${IN_SHUTDOWN}" || is_no "${RC_LOGGING}" ; then
115 while [ "$1" != "${1##-}" ]; do
134 typeset _x _y _z v old_IFS ver
142 while [ ${#ver} -lt 3 ] ; do ver="0$ver" ; done
144 while [ ${#ver} -lt 6 ] ; do ver="0$ver" ; done
146 while [ ${#ver} -lt 9 ] ; do ver="0$ver" ; done
153 typeset _x _y _z v old_IFS ver
161 while [ ${#ver} -lt 3 ] ; do ver="0$ver" ; done
163 while [ ${#ver} -lt 6 ] ; do ver="0$ver" ; done
170 typeset _x _y _z v old_IFS ver
178 while [ ${#ver} -lt 3 ] ; do ver="0$ver" ; done
187 if is_yes "$FASTRC" || is_no "$TPUT"; then
190 echo -ne "\033[$(($2+1))G"
193 echo -ne "\033[${2}A"
205 is_yes "$COLOR_INIT" && echo -ne "\033[${ISBOLD};3${2}m"
208 termput setaf $NORMAL
217 if [ "$3" == "1" ]; then tput bold; else tput sgr0; fi
218 is_yes "$COLOR_INIT" && tput setaf "$2"
221 termput setaf $NORMAL
227 if [ ! -x /bin/printf ]; then
229 # FIXME: buggy when single or double quotes in message!
235 if [ $# -gt 0 ]; then
238 while [ $# -gt 0 ]; do
243 awk "BEGIN {printf \"$text\", \"$m\"; }"
247 # National language support function
250 typeset msg_echo nls_domain text message
252 nls_domain="$NLS_DOMAIN"
253 while [ "$1" != "${1##-}" ]; do
269 # empty message, so we return --misiek
270 if [ -z "$message" ]; then
275 if is_yes "$GETTEXT"; then
276 message=$(TEXTDOMAINDIR="/etc/sysconfig/locale" gettext -e --domain="${nls_domain:-rc-scripts}" "$message")
279 printf "$message" "$@"
289 if ! is_no "$BOOT_SPLASH" && ! is_yes "$VSERVER"; then
290 [ -x /bin/splash ] && /bin/splash "$action"
298 nls "ERROR: Networking is down. %s can't be run." "$1" >&2
303 show "Starting %s service" "$1"
306 msg_already_running()
308 nls "%s service is already running." "$1"
313 show "Stopping %s service" "$1"
318 nls "%s service is not running." "$1"
323 show "Reloading %s service" "$1"
331 # Some functions to handle PLD Linux-style messages
337 if is_no "$FASTRC" && is_yes "$GETTEXT"; then
343 while [ $((len++)) -lt $INIT_COL ]; do
346 if [ -n "$CHARS" ]; then
347 termput setaf $CCHARS
356 termput hpa $INIT_COL
359 # Displays message in square brackests ("[ DONE ]"). Takes two arguments.
360 # First is the text to display, second is color number to use (argument to
361 # tput setaf). If second argument is not given, default (2, green) will be
366 if [ -n "$2" ]; then COLOR="$2"; else COLOR="$CDONE"; fi
368 echo -n "$(termput setaf $CBRACKETS)[$(termput setaf $COLOR) $(nls --nls-domain rc-scripts "$1") $(termput setaf $CBRACKETS)]$(termput op)"
398 # Check if $pid (could be plural) are running
402 [ -d "/proc/$1" ] && return 0
408 # - outside chroot get only those processes, which are outside chroot.
409 # - inside chroot get only those processes, which are inside chroot.
410 # - don't filter out pids which do not have corresponding running processes (process died etc)
411 # (note: some processes like named are chrooted but run outside chroot)
412 # - do nothing inside vserver
415 if is_yes "$VSERVER"; then
419 if [ $# -lt 1 -o ! -d /proc/1 ] ; then
424 for root_pid in $@; do
425 root_dir=$(resolvesymlink /proc/${root_pid}/root)
426 if [ -n "$root_dir" ]; then
428 if [ -n "${SYSTEM_CHROOTS}" ]; then
429 for r_dir in ${SYSTEM_CHROOTS}; do
430 echo "$root_dir" | grep -q "^${r_dir}" && good_add_pid=0
433 [ "$good_add_pid" -eq 1 ] && good_pids="$good_pids $root_pid"
434 elif [ ! -d "/proc/$root_pid" ]; then
435 good_pids="$good_pids $root_pid"
441 # Usage run_cmd Message command_to_run
444 typeset exit_code errors message force_err
445 typeset -i force_err=0
446 typeset -i exit_code=0
454 show "$message"; busy
457 if errors=$(HOME=/tmp TMPDIR=/tmp initlog -c "$*" 2>&1); then
459 log_success "$1 $message"
462 log_failed "$1 $message"
465 [ -n "$errors" ] && [ $exit_code -eq 1 -o $force_err -eq 1 ] && echo "$errors"
469 _daemon_set_ulimits() {
470 local opt val ksh=${KSH_VERSION:+1}
471 set -- ${SERVICE_LIMITS:-$DEFAULT_SERVICE_LIMITS}
472 while [ $# -gt 0 ]; do
493 # A function to start a program (now it's useful on read-only filesystem too)
496 typeset errors="" prog="" waitname="" waittime=""
497 typeset -i exit_code=0
498 [ -z "$DEFAULT_SERVICE_RUN_NICE_LEVEL" ] && DEFAULT_SERVICE_RUN_NICE_LEVEL=0
499 # Test syntax. Don't use -o instead || here - this will break ksh --misiek
500 while [ "$1" != "${1##-}" ] || [ "$1" != "${1##+}" ]; do
503 msg_usage " daemon [--user user] [--fork] [+/-nicelevel] {program}"
507 # for compatibility with redhat/mandrake
508 nls "warning: --check option is ignored!"
514 [ "$1" != "root" ] && prog="/bin/su $1 -s /bin/sh -c \""
518 prog="/usr/bin/setsid sh -c \""
532 -*|+*) SERVICE_RUN_NICE_LEVEL=$1
537 # If command to execute ends with quotation mark, add remaining
538 # arguments and close quotation.
539 if [ "$prog" != "${prog%\"}" ]; then
540 prog="$prog $*$end\""
547 [ -z "$DEFAULT_SERVICE_UMASK" ] && DEFAULT_SERVICE_UMASK=022
552 is_yes "$CPUSETS" && [ -n "$SERVICE_CPUSET" ] && echo $$ > "/dev/cpuset/${SERVICE_CPUSET}/tasks"
553 if errors=$(umask ${SERVICE_UMASK:-$DEFAULT_SERVICE_UMASK}; USER=root HOME=/tmp TMPDIR=/tmp nice -n ${SERVICE_RUN_NICE_LEVEL:-$DEFAULT_SERVICE_RUN_NICE_LEVEL} initlog -c "$prog" 2>&1); then
554 if [ -n "$waitname" -a -n "$waittime" ]; then
556 base=$(basename "$waitname")
558 pid=$(pidofproc "$waitname" "$pidfile")
559 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
561 while [ "$i" -lt "$waittime" ]; do
563 checkpid $pid && sleep 1 || break
566 log_success "$1 startup"
571 log_failed "$1 startup"
572 [ -n "$errors" ] && echo "$errors"
577 # A function to stop a program.
580 typeset notset killlevel base pid pidfile result
583 msg_usage " killproc {program} [signal]"
587 while [ "$1" != "${1##-}" ]; do
610 # check for second arg to be kill level
611 if [ -n "$2" ] ; then
619 base=$(basename "$1")
622 pid=$(pidofproc "$1" "$pidfile")
623 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
626 if [ -n "$pid" -a "$pid" != "$$" ] && checkpid $pid 2>&1 ; then
627 if [ "$notset" = "1" ] ; then
628 if checkpid $pid 2>&1; then
629 # TERM first, then KILL if not dead
632 if checkpid $pid && sleep 1 &&
633 checkpid $pid && sleep 3 &&
641 if [ "$result" -eq 0 ]; then
643 log_failed "$1 shutdown"
646 log_success "$1 shutdown"
648 result=$(( ! $result ))
650 # use specified level only
651 if checkpid $pid > /dev/null 2>&1; then
654 if [ "$result" -eq 0 ]; then
656 log_success "$1 got $killlevel"
660 log_failed "$1 didn't get $killlevel"
665 log_failed "$1 shutdown"
670 log_failed "$1 shutdown"
674 if [ -n "$waitname" -a -n "$waittime" ]; then
676 base=$(basename "$waitname")
678 pid=$(pidofproc "$waitname" "$pidfile")
679 [ -z "$pid" ] && pid=$(pidofproc "$base" "$pidfile")
681 while [ "$i" -lt "$waittime" ]; do
683 checkpid $pid && sleep 1 || break
687 # Remove pid file if any.
688 if [ "$notset" = "1" ]; then
689 rm -f /var/run/${base}.pid
695 # A function to find the pid of a program.
698 typeset pid pidfile base
699 base=$(basename "$1")
701 [ -n "$2" ] && pidfile="$2"
705 msg_usage " pidofproc {program}"
709 # First try pidfile or "/var/run/*.pid"
710 if (echo "${pidfile}" | grep -Eq "^/"); then
713 pidfile="/var/run/${pidfile}";
715 if [ -f "${pidfile}" ] ; then
718 for p in $(< "${pidfile}"); do
719 [ -z "$(echo "$p" | awk '{gsub(/[0-9]/,"");print;}')" ] && pid="$pid $p"
724 [ -z "$pid" ] && pidof -o $$ -o $PPID -o %PPID -x "$1"
725 pid=$(filter_chroot "$pid")
731 typeset base pid subsys daemon cpuset_msg
734 base=$(basename $daemon)
738 msg_usage " status {subsys} [{daemon}]"
743 pid=$(pidof -o $$ -o $PPID -o %PPID -x $daemon)
744 pid=$(filter_chroot "$pid")
746 if [ "$pid" != "" ]; then
748 if is_yes "$CPUSETS" && [ -n "$SERVICE_CPUSET" ]; then
749 if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then
750 cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET")
752 cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET")
755 nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg"
758 # pid=$(ps ax | awk 'BEGIN { prog=ARGV[1]; ARGC=1 }
759 # { if ((prog == $5) || (("(" prog ")") == $5) ||
760 # (("[" prog "]") == $5) ||
761 # ((prog ":") == $5)) { print $1 ; exit 0 } }' $1)
762 # if [ "$pid" != "" ]; then
764 # if is_yes "$CPUSETS" && [ -n "$SERVICE_CPUSET" ]; then
765 # if $(grep -q "$pid" "/dev/cpuset/${SERVICE_CPUSET}/tasks"); then
766 # cpuset_msg=$(nls " in cpuset %s..." "$SERVICE_CPUSET")
768 # cpuset_msg=$(nls " outside of configured cpuset %s..." "$SERVICE_CPUSET")
771 # nls "%s (pid %s) is running%s" "$daemon" "$pid" "$cpuset_msg"
776 # Next try "/var/run/*.pid" files
777 if [ -f /var/run/${base}.pid ]; then
778 read pid < /var/run/${base}.pid
779 pid=$(filter_chroot "$pid")
780 if [ "$pid" != "" ]; then
781 nls "%s dead but pid file exists" "$subsys"
786 # See if /var/lock/subsys/$subsys exists
787 if [ -f /var/lock/subsys/$subsys ]; then
788 nls "%s dead but subsys locked" "$subsys"
791 nls "%s is stopped" "$subsys"
795 # Confirm whether we really want to run this service
798 nls -n "Start service %s (Y)es/(N)o/(C)ontinue? [Y] " "$1"
817 # module is needed (ie. is requested, is available and isn't loaded already)
820 # module name without .o at end
821 if ! (lsmod | grep -q "$1"); then
822 if (ls -R /lib/modules/$(uname -r)/ 2> /dev/null | grep -q "${1}.\(\|k\)o\(\|.gz\)"); then
833 typeset parsed single die args foo result
835 while is_no "$parsed" ; do
854 if is_yes "${single}" ; then
856 show "Loading %s kernel module(s)" "$foo"
859 if [ -x /sbin/modprobe ] ; then
860 /sbin/modprobe -s $args "$@"
866 if is_yes "${single}" ; then
868 if [ $result == "0" ] ; then
869 is_yes "$single" && ok
872 if is_yes "$die" ; then
873 nls "Could not load %s kernel module(s)" "$@"
882 initlog -n $0 -s "$1 $2" -e 1
887 initlog -n $0 -s "$1 $2" -e 2
890 # RedHat/Mandrake specific functions
891 action () { STRING=$1; shift; run_cmd "$STRING" "$*"; }
892 success () { return 0; }
893 failure () { return 1; }
896 typeset _d selinuxfs _t _r
898 while read _d selinuxfs _t _r; do
899 [ "$_t" = "selinuxfs" ] && break
901 echo "*** Warning -- SELinux is active"
902 echo "*** Disabling security enforcement for system recovery."
903 echo "*** Run 'setenforce 1' to reenable."
904 echo "0" > $selinuxfs/enforce
908 typeset _d selinuxfs _t _r
910 while read _d selinuxfs _t _r; do
911 [ "$_t" = "selinuxfs" ] && break
914 *** Warning -- SELinux relabel is required. ***
915 *** Disabling security enforcement. ***
916 *** Relabeling could take a very long time, ***
917 *** depending on file system size. ***
919 echo "0" > $selinuxfs/enforce
920 /sbin/fixfiles -F relabel > /dev/null 2>&1
922 echo "*** Enabling security enforcement. ***"
923 echo $SELINUX > $selinuxfs/enforce
926 # Remove duplicate entries from mtab (for vserver guest use only)
927 clean_vserver_mtab() {
929 while read device mountpoint line; do
930 grep -qs "$mountpoint" /etc/mtab.clean || \
931 echo "$device $mountpoint $line" >> /etc/mtab.clean
933 cat /etc/mtab.clean > /etc/mtab
934 rm -f /etc/mtab.clean
937 # Check if any flavor of portmapper is running
941 if [ -x /usr/sbin/rpcinfo ]; then
942 if /usr/sbin/rpcinfo -p localhost >/dev/null 2>/dev/null; then
947 elif [ -x /sbin/pidof ]; then
948 [ -z "$(/sbin/pidof portmap)" -a \
949 -z "$(/sbin/pidof rpcbind)" ] && return 1
955 # If we have cachefile, use it.
956 # If we don't, create memory variables and try to save silently,
957 local cachefile='/var/cache/rc-scripts/msg.cache'
959 # We create $check variable which is used to invalidate the cache.
960 # The $check contains user locale and terminal.
961 local check="$TERM.$LC_MESSAGES"
963 if [ -f "$cachefile" -a "$cachefile" -nt /etc/sysconfig/system -a "$cachefile" -nt /etc/sysconfig/init-colors ]; then
964 if . "$cachefile" 2>/dev/null; then
965 if [ "$check" = "$_check" ]; then
972 _busy=$(progress "BUSY" "$CBUSY")
973 _ok=$(progress "DONE")
974 _started=$(progress "WORK")
975 _fail=$(progress "FAIL" "$CFAIL")
976 _died=$(progress "DIED" "$CFAIL")
978 # we don't use heredoc, as ksh attempts to create tempfile then
979 (> "$cachefile" ) 2>/dev/null || return
980 echo "_busy='$_busy';" >> "$cachefile"
981 echo "_ok='$_ok';" >> "$cachefile"
982 echo "_started='$_started';" >> "$cachefile"
983 echo "_fail='$_fail';" >> "$cachefile"
984 echo "_died='$_died';" >> "$cachefile"
985 echo "_check='$check';" >> "$cachefile"
989 if [ -z "$GETTEXT" ]; then
990 if [ -x /bin/gettext -o -x /usr/bin/gettext ]; then
997 if [ -z "$TPUT" ]; then
998 if [ -d /usr/share/terminfo ] && [ -x /usr/bin/tput -o -x /bin/tput ] ; then
1000 # check if we are on proper terminal
1001 tput longname >/dev/null 2>&1 || TPUT=no
1012 # * Local variables:
1014 # * indent-tabs-mode: notnil