# -*-Shell-script-*- # # functions This file contains functions to be used by most or all # shell scripts in the /etc/init.d directory. # TEXTDOMAIN=initscripts TEXTDOMAINDIR=/etc/locale LOCPATH=/etc/locale export TEXTDOMAINDIR LOCPATH # Make sure umask is sane umask 022 # Set up a default search path. PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin" export PATH [ -z "${CONSOLETYPE:-}" ] && CONSOLETYPE="`/sbin/consoletype`" # Get a sane screen width [ -z "${COLUMNS:-}" ] && COLUMNS=80 if [ -z "$GP_LANG" -a -z "$LANGUAGE" -a -f /etc/sysconfig/i18n -a -z "$NOLOCALE" ]; then . /etc/sysconfig/i18n [ -n "$LANGUAGE" ] && GP_LANG=$LANGUAGE || GP_LANG=$LANG else if [ "$CONSOLETYPE" != "pty" ]; then [ "$CONSOLE_NOT_LOCALIZED" = "yes" ] && GP_LANG=C case "${LANG:-}" in ja*|ko*|zh*) export LC_MESSAGES=en_US ;; *) export LANG ;; esac else export LANG fi fi # Read in our configuration if [ -z "${BOOTUP:-}" ]; then if [ -f /etc/sysconfig/init ]; then . /etc/sysconfig/init else # This all seem confusing? Look in /etc/sysconfig/init, # or in /usr/share/doc/initscripts-*/sysconfig.txt BOOTUP=color RES_COL=60 MOVE_TO_COL="echo -en \\033[${RES_COL}G" SETCOLOR_SUCCESS="echo -en \\033[1;32m" SETCOLOR_FAILURE="echo -en \\033[1;31m" SETCOLOR_WARNING="echo -en \\033[1;33m" SETCOLOR_NORMAL="echo -en \\033[0;39m" LOGLEVEL=1 fi if [ "$CONSOLETYPE" = "serial" ]; then BOOTUP=serial MOVE_TO_COL= SETCOLOR_SUCCESS= SETCOLOR_FAILURE= SETCOLOR_WARNING= SETCOLOR_NORMAL= fi fi if [ "${BOOTUP:-}" != "verbose" ]; then INITLOG_ARGS="-q" else INITLOG_ARGS= fi gprintf() { if [ -x /bin/gettext -a -n "$1" ]; then if [ -n "$GP_LANG" ]; then local TEXT=`LANGUAGE=$GP_LANG gettext -e --domain=$TEXTDOMAIN "$1"` else local TEXT=`gettext -e --domain=$TEXTDOMAIN "$1"` fi else local TEXT=$1 fi [ "${1#*\\n}" ] || TEXT="$TEXT\n" shift printf "$TEXT" "$@" } # Frontend to gprintf (support up to 4 %s in format string) # returns the message transleted in GPRINTF_MSG and # the resting parms in GPRINTF_REST # This simplifies a lot the call of functions like action, # now with i18n support gprintf_msg_rest() { case "$1" in *%s*%s*%s*%s*) GPRINTF_MSG=$(gprintf "$1" "$2" "$3" "$4" "$5") shift 5;; *%s*%s*%s*) GPRINTF_MSG=$(gprintf "$1" "$2" "$3" "$4") shift 4;; *%s*%s*) GPRINTF_MSG=$(gprintf "$1" "$2" "$3") shift 3;; *%s*) GPRINTF_MSG=$(gprintf "$1" "$2") shift 2;; *) GPRINTF_MSG=$(gprintf "$1") shift;; esac GPRINTF_REST="$@" } # Check if $pid (could be plural) are running checkpid() { local i for i in $* ; do [ -d "/proc/$i" ] && return 0 done return 1 } # A function to start a program. daemon() { # Test syntax. local gotbase= force= local base= user= nice= bg= pid= nicelevel=0 while [ "$1" != "${1##[-+]}" ]; do case $1 in '') gprintf "%s: Usage: daemon [+/-nicelevel] {program}\n" $0 return 1;; --check) base=$2 gotbase="yes" shift 2 ;; --check=?*) base=${1#--check=} gotbase="yes" shift ;; --user) user=$2 shift 2 ;; --user=?*) user=${1#--user=} shift ;; --force) force="force" shift ;; [-+][0-9]*) nice="nice -n $1" shift ;; *) gprintf "%s: Usage: daemon [+/-nicelevel] {program}\n" $0 return 1;; esac done # Save basename. [ -z "$gotbase" ] && base=${1##*/} # See if it's already running. Look *only* at the pid file. if [ -f /var/run/${base}.pid ]; then local line p read line < /var/run/${base}.pid for p in $line ; do [ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p" done fi [ -n "${pid:-}" -a -z "${force:-}" ] && return # make sure it doesn't core dump anywhere; while this could mask # problems with the daemon, it also closes some security problems ulimit -S -c 0 >/dev/null 2>&1 # if they set NICELEVEL in /etc/sysconfig/foo, honor it [ -n "$NICELEVEL" ] && nice="nice -n $NICELEVEL" # Echo daemon [ "${BOOTUP:-}" = "verbose" -a -z "$LSB" ] && echo -n " $base" # libsafe support if [ -r /etc/sysconfig/system ] && grep -q '^LIBSAFE=yes$' /etc/sysconfig/system && [ -r /lib/libsafe.so.2 ]; then LD_PRELOAD=/lib/libsafe.so.2 export LD_PRELOAD fi # And start it up. if [ -z "$user" ]; then $nice initlog $INITLOG_ARGS -c "$*" else $nice initlog $INITLOG_ARGS -c "su -s /bin/bash - $user -c \"$*\"" fi rc=$? [ $rc = 0 ] && success "%s startup" $base || failure "%s startup" $base unset LD_PRELOAD return $rc } # A function to stop a program. killproc() { RC=0 # Test syntax. if [ "$#" -eq 0 ]; then gprintf "Usage: killproc {program} [signal]\n" return 1 fi notset=0 # check for second arg to be kill level if [ -n "$2" ]; then killlevel=$2 else notset=1 killlevel="-9" fi # Save basename. base=${1##*/} # Find pid. pid= if [ -f /var/run/${base}.pid ]; then local line p read line < /var/run/${base}.pid for p in $line ; do [ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p" done fi if [ -z "$pid" ]; then pid=`pidof -o $$ -o $PPID -o %PPID -x $1 || \ pidof -o $$ -o $PPID -o %PPID -x $base` fi # Kill it. if [ -n "${pid:-}" ] ; then [ "$BOOTUP" = "verbose" -a -z "$LSB" ] && echo -n "$base " if [ "$notset" -eq "1" ] ; then if checkpid $pid 2>&1; then # TERM first, then KILL if not dead kill -TERM $pid usleep 100000 if checkpid $pid && sleep 1 && checkpid $pid && sleep 3 && checkpid $pid ; then kill -KILL $pid usleep 100000 fi fi checkpid $pid RC=$? [ "$RC" -eq 0 ] && failure "%s shutdown" $base || success "%s shutdown" $base RC=$((! $RC)) # use specified level only else if checkpid $pid; then kill $killlevel $pid RC=$? [ "$RC" -eq 0 ] && success "%s %s" $base $killlevel || failure "%s %s" $base $killlevel fi fi else failure "%s shutdown" $base RC=1 fi # Remove pid file if any. if [ "$notset" = "1" ]; then rm -f /var/run/$base.pid fi return $RC } # A function to find the pid of a program. Looks *only* at the pidfile pidfileofproc() { local base=${1##*/} # Test syntax. if [ "$#" -eq 0 ] ; then gprintf "Usage: pidfileofproc {program}\n" return 1 fi # First try "/var/run/*.pid" files if [ -f /var/run/$base.pid ] ; then local line p pid= read line < /var/run/$base.pid for p in $line ; do [ -z "${p//[0-9]/}" -a -d /proc/$p ] && pid="$pid $p" done if [ -n "$pid" ]; then echo $pid return 0 fi fi } # A function to find the pid of a program. pidofproc() { base=${1##*/} # Test syntax. if [ "$#" -eq 0 ] ; then gprintf "Usage: pidofproc {program}\n" return 1 fi # First try "/var/run/*.pid" files if [ -f /var/run/$base.pid ]; then local line p pid= read line < /var/run/$base.pid for p in $line ; do [ -z "${p//[0-9]/}" -a -d /proc/$p ] && pid="$pid $p" done if [ -n "$pid" ]; then echo $pid return 0 fi fi pidof -o $$ -o $PPID -o %PPID -x $1 || \ pidof -o $$ -o $PPID -o %PPID -x $base } status() { local base=${1##*/} local pid # Test syntax. if [ "$#" -eq 0 ] ; then gprintf "Usage: status {program}\n" return 1 fi # First try "pidof" pid=`pidof -o $$ -o $PPID -o %PPID -x $1 || \ pidof -o $$ -o $PPID -o %PPID -x ${base}` if [ -n "$pid" ] ; then gprintf "%s (pid %s) is running...\n" ${base} $pid return 0 fi # Next try "/var/run/*.pid" files if [ -f /var/run/${base}.pid ] ; then read pid < /var/run/${base}.pid if [ -n "$pid" ] ; then gprintf "%s dead but pid file exists\n" ${base} return 1 fi fi # See if /var/lock/subsys/${base} exists if [ -f /var/lock/subsys/${base} ]; then gprintf "%s dead but subsys locked\n" ${base} return 2 fi gprintf "%s is stopped\n" ${base} return 3 } echo_success() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS gprintf " OK " [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" echo -ne "\r" return 0 } echo_failure() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE gprintf "FAILED" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" echo -ne "\r" return 1 } echo_passed() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING gprintf "PASSED" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" echo -ne "\r" return 1 } echo_warning() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING gprintf "WARNING" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" echo -ne "\r" return 1 } # Log that something succeeded success() { gprintf_msg_rest "$@" if [ -z "$IN_INITLOG" ]; then initlog $INITLOG_ARGS -n $0 -s "$GPRINTF_MSG" -e 1 else # silly hack to avoid EPIPE killing rc.sysinit trap "" SIGPIPE echo "$INITLOG_ARGS -n $0 -s \"$GPRINTF_MSG\" -e 1" >&21 trap - SIGPIPE fi [ "$BOOTUP" != "verbose" -a -z "$LSB" ] && echo_success return 0 } # Log that something failed failure() { rc=$? gprintf_msg_rest "$@" if [ -z "$IN_INITLOG" ]; then initlog $INITLOG_ARGS -n $0 -s "$GPRINTF_MSG" -e 2 else trap "" SIGPIPE echo "$INITLOG_ARGS -n $0 -s \"$GPRINTF_MSG\" -e 2" >&21 trap - SIGPIPE fi [ "$BOOTUP" != "verbose" -a -z "$LSB" ] && echo_failure return $rc } # Log that something passed, but may have had errors. Useful for fsck passed() { rc=$? gprintf_msg_rest "$@" if [ -z "$IN_INITLOG" ]; then initlog $INITLOG_ARGS -n $0 -s "$GPRINTF_MSG" -e 1 else trap "" SIGPIPE echo "$INITLOG_ARGS -n $0 -s \"$GPRINTF_MSG\" -e 1" >&21 trap - SIGPIPE fi [ "$BOOTUP" != "verbose" ] && echo_passed return $rc } # Run some action. Log its output. action() { gprintf_msg_rest "$@" echo -n "$GPRINTF_MSG " # libsafe support if [ -r /etc/sysconfig/system ] && grep -q '^LIBSAFE=yes$' /etc/sysconfig/system && [ -r /lib/libsafe.so.2 ]; then LD_PRELOAD=/lib/libsafe.so.2 export LD_PRELOAD fi if [ "$quiet" = "yes" ]; then initlog $INITLOG_ARGS -c "$GPRINTF_REST" && success "$GPRINTF_MSG" || (quiet off && echo -n "$GPRINTF_MSG" && failure "$GPRINTF_MSG" && echo && quiet on) else initlog $INITLOG_ARGS -c "$GPRINTF_REST" && success "$GPRINTF_MSG" || failure "$GPRINTF_MSG" fi rc=$? echo unset LD_PRELOAD return $rc } # returns OK if $1 contains $2 strstr() { #case "$1" in # *${2}*) return 0 ;; #esac #return 1 [ "$1" = "$2" ] && return 0 slice=${1#*$2*} [ "$slice" = "$1" ] && return 1 return 0 } # Confirm whether we really want to run this service confirm() { gprintf "Start service %s (Y)es/(N)o/(C)ontinue? [Y] \n" $1 local YES=`gprintf "yY"` local NOT=`gprintf "nN"` local CNT=`gprintf "cC"` read answer if strstr "$YES" "$answer" || [ "$answer" = "" ] ; then return 0 elif strstr "$CNT" "$answer" ; then return 2 elif strstr "$NOT" "$answer" ; then return 1 fi confirm $* } initsplash() { [[ -f /etc/sysconfig/bootsplash ]] && source /etc/sysconfig/bootsplash [[ -n $SPLASH ]] && splash=$SPLASH [[ -n $THEME ]] && theme=$THEME splash_cfg=/etc/bootsplash/ [[ $splash != "no" && $splash != "No" && $splash != "NO" ]] && export splash=yes [[ -d $splash_cfg/themes ]] || splash= if [[ $splash = "yes" && -n $theme ]];then [[ ! -d $splash_cfg/themes/$theme ]] && theme=Mandrake if [[ -f $splash_cfg/themes/$theme/global.config ]];then if [[ $LOGO_CONSOLE == theme ]];then source $splash_cfg/themes/$theme/global.config else #leave from the global config tmpval=$LOGO_CONSOLE source $splash_cfg/themes/$theme/global.config LOGO_CONSOLE=$tmpval fi fi if [[ -x /bin/fbresolution ]];then res=`/bin/fbresolution 2>/dev/null` if [[ -f $splash_cfg/themes/$theme/cfg/bootsplash-$res.cfg ]];then . $splash_cfg/themes/$theme/cfg/bootsplash-$res.cfg fi fi fi if [[ -z "$1" ]]; then set `/sbin/runlevel` runlevel=$2 previous=$1 else runlevel=5 previous=N fi nbservices=0 # # for small dir, it is faster than echo /etc/rc$runlevel.d/* | wc -w # for i in /etc/rc$runlevel.d/* do a=$[nbservices++] done for i in /etc/rc$runlevel.d/*.rpm* do a=$[nbservices--] done a=$[nbservices++] service=0 # this are the number of step in rc.sysinit, could be ajusted [[ "$previous" = "N" ]] && nbservices=$(($nbservices+7)) && service=7 export nbservices res service px py pw ph pc splash LOGO_CONSOLE } progress() { if [[ -n "$progress" ]]; then x=$(($1*$pw/$nbservices)) /bin/progress -t 1 -n "$px" "$py" "$x" "$ph" "$pc" > /dev/null fi } initquiet(){ [ -e /dev/vc/11 ] && export out=/dev/vc/ || export out=/dev/tty } quiet() { return [[ $quiet != "yes" || -z $out ]] && return if [[ "$1" = "on" ]]; then exec 1>"$out"11 elif [[ "$1" = "off" ]]; then exec 1>"$out"1 fi } disable_splash() { if [[ "$splash" = "yes" ]];then if [[ $LOGO_CONSOLE != yes ]] && [[ $LOGO_CONSOLE != YES ]] && [[ $LOGO_CONSOLE != Yes ]]; then if [[ -e /proc/splash ]];then action "Disabling Boot logo" echo 0 > /proc/splash export pc=0x000000 progress $nbservices fi fi unset progress fi quiet off }