#!/bin/sh # # functions This file contains functions to be used by most or all # shell scripts in the /etc/init.d directory. # # Based on functions scripts from LFS-3.1 and RedHat/Fedora # Splash functions added by Silvan Calarco # Modified for LSB and dash compliance by Davide Madrisan TEXTDOMAIN=initscripts umask 022 # Set up a default search path. PATH="/sbin:/usr/sbin:/bin:/usr/bin" export PATH # Get a sane screen width. [ -z "${COLUMNS:-}" ] && COLUMNS=80 [ -z "${CONSOLETYPE:-}" ] && CONSOLETYPE="`/sbin/consoletype`" COL=$(( $COLUMNS - 10 )) WCOL=$(( $COLUMNS - 30 )) if [ -z "${BOOTUP:-}" ]; then if [ "$CONSOLETYPE" = "serial" ]; then BOOTUP=serial MOVE_TO_COL= MOVE_TO_WCOL= MOVE_TO_LCOL= MOVE_CURS_UP= SETCOLOR_NORMAL= SETCOLOR_SUCCESS= SETCOLOR_WARNING= SETCOLOR_FAILURE= else BOOTUP=color MOVE_TO_COL="/bin/echo -en \\033[${COL}G" MOVE_TO_WCOL="/bin/echo -en \\033[${WCOL}G" MOVE_TO_LCOL="/bin/echo -en \\033[0G" MOVE_CURS_UP="/bin/echo -en \\033[A" SETCOLOR_NORMAL="/bin/echo -en \\033[0;39m" SETCOLOR_SUCCESS="/bin/echo -en \\033[1;32m" SETCOLOR_WARNING="/bin/echo -en \\033[1;33m" SETCOLOR_FAILURE="/bin/echo -en \\033[1;31m" fi fi if [ "${BOOTUP:-}" != "verbose" ]; then INITLOG_ARGS="-q" else INITLOG_ARGS= fi if [ -e /bin/plymouth -a -e /sbin/plymouthd ]; then PLYMOUTH=/bin/plymouth PLYMOUTHD=/sbin/plymouthd else PLYMOUTH=/bin/true PLYMOUTHD=/bin/true fi # Check if $pid (could be plural) are running checkpid () { local i for i in $*; do [ -d "/proc/$i" ] && return 0 done return 1 } #function getpids #{ # # save basename # base=${1##*/} # # pidlist=$(pidof -o $$ -o $PPID -x $base) # pidlist=$(for p in $pidlist; do echo $p; done | sort) #} # function: # __pids_var_run {program} [pidfile] # description: # Set $pid to pids from /var/run* for {program}. # $pid should be declared local in the caller. # Returns LSB exit code for the 'status' action. __pids_var_run () { local base=${1##*/} local pid_file=${2:-/var/run/$base.pid} pid= if [ -f "$pid_file" ] ; then local line p read line < "$pid_file" for p in $line ; do [ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p" done if [ -n "$pid" ]; then return 0 fi return 1 # "Program is dead and /var/run pid file exists" fi return 3 # "Program is not running" } # function: # __pids_pidof {program} # description: # Output PIDs of matching processes, found using pidof. __pids_pidof () { /bin/pidof -o $$ -o $PPID -o %PPID -x "$1" || \ /bin/pidof -o $$ -o $PPID -o %PPID -x "${1##*/}" } # function: # daemon {args} [+/-nicelevel] {program} # description: # A function to start a program daemon () { # test syntax local gotbase= force= local base= user= nice= bg= pid= pidfile= nicelevel=0 while [ "$1" != "${1##[-+]}" ]; do case $1 in '') echo $"daemon: Usage: daemon {args} [+/-nicelevel] {program}" 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 ;; --pidfile=?*) pidfile=${1#--pidfile=} shift ;; [-+][0-9]*) nice="nice -n $1" shift ;; *) echo $"daemon: Usage: daemon {args} [+/-nicelevel] {program}" return 1 ;; esac done # save basename [ -z "$gotbase" ] && base=${1##*/} [ -z "$pidfile" ] && pidfile="/var/run/${base}.pid" # see if it's already running. Look *only* at the pid file if [ -f $pidfile ]; then local line p read line < $pidfile for p in $line ; do [ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p" done fi [ -n "${pid:-}" -a -z "${force:-}" ] && return 0 # make sure it doesn't core dump anywhere unless requested ulimit -S -c ${DAEMON_COREFILE_LIMIT:-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" # 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 [ "$?" -eq 0 ] && success $"$base startup" || failure $"$base startup" } # function: # killproc [-p pidfile] {program} [signal] # description: # A function to stop a program (LSB 2.x compliant). killproc () { TEMP=`LANG=C POSIXLY_CORRECT=1 getopt "p:" $*` if [ $? -ne 0 -o $# -eq 0 ]; then echo $"Usage: killproc [-p ] pathname [signal]" return 1 fi eval set -- "$TEMP" local pid_file while :; do case $1 in -p) pid_file=$2; shift ;; --) shift; break ;; *) echo $"Usage: killproc [-p ] pathname [signal]" return 1 ;; esac shift done local base=${1##*/} # Check for second arg to be kill level. local signal=${2:-} [ -z "$pid_file" ] && pid_file=/var/run/$base.pid # Find pid. local retcode=0 pid __pids_var_run "$1" "$pid_file" if [ ! -e "$pid_file" -a -z "$pid" ]; then pid="$(__pids_pidof "$1")" fi # Kill it. if [ "${pid:-}" ] ; then # Use specified level only. if [ "$signal" ]; then if checkpid $pid 2>&1; then kill $signal $pid >/dev/null 2>&1 retcode=$? else retcode=1 fi else if checkpid $pid 2>&1; then # TERM first, then KILL if not dead kill -s TERM $pid >/dev/null 2>&1 usleep 100000 if checkpid $pid && sleep 1 && checkpid $pid && sleep 3 && checkpid $pid ; then kill -s KILL $pid >/dev/null 2>&1 usleep 100000 fi checkpid $pid retcode=$((! $? )) fi fi else [ "$signal" ] && retcode=1 fi [ "$retcode" -eq 0 ] && success $"$base shutdown" || failure $"$base shutdown" # Remove pid file if any. rm -f $pidfile >/dev/null 2>&1 return $retcode } # function: # pidfileofproc {program} # description: # A function to find the pid of a program. Looks *only* at the pidfile. pidfileofproc () { local base=${1##*/} # Test syntax. if [ "$#" = 0 ] ; then echo $"Usage: pidfileofproc {program}" return 1 fi __pids_var_run "$1" [ -n "$pid" ] && echo $pid return 0 } # function: # pidofproc [-p pidfile] {program} # description: # A function to find the pid of a program (LSB 2.x compliant). pidofproc () { TEMP=`LANG=C POSIXLY_CORRECT=1 getopt "p:" $*` if [ $? -ne 0 -o $# -eq 0 ]; then echo $"Usage: pidofproc [-p ] {program}" return 1 fi eval set -- "$TEMP" local pid_file while :; do case $1 in -p) pid_file=$2; shift ;; --) shift; break ;; *) echo $"Usage: pidofproc [-p ] {program}" return 1 ;; esac shift done local base=${1##*/} rc if [ -z "$pid_file" ]; then pid_file=/var/run/$base.pid else # Assume program is stopped [ -f "$pid_file" ] || return 3 fi if [ -f "$pidfile" ]; then __pids_var_run "$1" "$pid_file" rc=$? if [ -n "$pid" ]; then echo $pid return 0 else return 1 # Dead and /var/run pid file exists fi elif [ -x /bin/pidof ]; then __pids_pidof "$1" [ "$?" = 1 ] && return 3 # Daemon stopped return 0 fi return 4 # Service status is unknown } # function: # statusproc [-p pidfile] {program} # description: # A function to check the status of a program statusproc () { local base pid pid_file= # Test syntax. if [ "$#" = 0 ] ; then echo $"Usage: statusproc [-p pidfile] {program}" return 1 fi if [ "$1" = "-p" ]; then pid_file=$2 shift 2 fi base=${1##*/} # First try "pidof" pid="$(__pids_pidof "$1")" if [ -n "$pid" ]; then echo $"${base} (pid $pid) is running..." return 0 fi # Next try "/var/run/*.pid" files __pids_var_run "$1" "$pid_file" case "$?" in 0) echo $"${base} (pid $pid) is running..." return 0 ;; 1) echo $"${base} dead but pid file exists" return 1 ;; esac # See if /var/lock/subsys/${base} exists. if [ -f /var/lock/subsys/${base} ]; then echo $"${base} dead but subsys locked" return 2 fi echo $"${base} is stopped" return 3 } loadproc () { if [ $# = 0 ]; then echo "Usage: loadproc {program}" exit 1 fi local pid pid="$(__pids_pidof "$1")" if [ -z "$pid" ]; then "$@" [ $? -eq 0 ] && echo_success || echo_failure else $MOVE_TO_WCOL echo_passed fi } reloadproc () { if [ $# = 0 ]; then echo "Usage: reloadproc {program} [signal]" exit 1 fi local signal if [ -z "$2" ]; then signal=HUP else signal=${2##-} signal=${signal##SIG} fi local pid apid failure pid="$(__pids_pidof "$1")" if [ -n "$pid" ]; then failure=0 for apid in $pid; do kill -s $signal $apid || failure=1 done [ $failure -eq 0 ] && echo_success || echo_failure else $MOVE_TO_WCOL echo_warning not_running fi } echo_ok () { echo_success return $? } echo_success () { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS echo -n $" OK " [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" /bin/echo -ne "\r" return 0 } echo_failure () { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE echo -n $"FAILED" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" /bin/echo -ne "\r" return 1 } echo_warning () { case "$1" in running) [ "$BOOTUP" = "color" ] && $MOVE_TO_WCOL echo $"Already running" [ "$BOOTUP" = "color" ] && $MOVE_CURS_UP ;; not_running) [ "$BOOTUP" = "color" ] && $MOVE_TO_WCOL echo $"Stopped" [ "$BOOTUP" = "color" ] && $MOVE_CURS_UP ;; esac [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING echo -n $"WARNING" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" /bin/echo -ne "\r" return 1 } echo_passed () { # [ "$BOOTUP" = "color" ] && $MOVE_TO_COL # echo -n "[" # [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING # echo -n $"PASSED" # [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL # echo -n "]" # /bin/echo -ne "\r" echo_warning running return 1 } # Log that something succeeded. success () { if [ -z "${IN_INITLOG:-}" ]; then initlog $INITLOG_ARGS -n $0 -s "$1" -e 1 fi [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_success return 0 } # Log that something failed. failure () { local rc=$? if [ -z "${IN_INITLOG:-}" ]; then initlog $INITLOG_ARGS -n $0 -s "$1" -e 2 fi [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_failure return $rc } # Log that something passed, but may have had errors. Useful for fsck passed () { local rc=$? if [ -z "${IN_INITLOG:-}" ]; then initlog $INITLOG_ARGS -n $0 -s "$1" -e 1 fi [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_passed return $rc } # Log a warning. warning () { local rc=$? if [ -z "${IN_INITLOG:-}" ]; then initlog $INITLOG_ARGS -n $0 -s "$1" -e 1 fi [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_warning return $rc } evaluate_retval () { [ $? -eq 0 ] && echo_success || echo_failure } # WARNING: this function is obsolete: do not use it print_status () { if [ $# = 0 ]; then echo "Usage: $0 {success|failure|warning}" return 1 fi case "$1" in success) echo_success ;; failure) echo_failure ;; warning) echo_warning $2 ;; esac } # Run some action. Log its output. action () { local msg rc msg=$1 echo -n "$msg " shift "$@" && success $"$msg" || failure $"$msg" rc=$? echo return $rc } spl_cachedir="/lib/splash/cache" spl_fifo="/dev/.splashfifo" spl_pidfile="/dev/.splashpid" splash_comm_send () { [ -w "$spl_fifo" -a -r "$spl_pidfile" ] || return 1 [ "`pidof fbsplashd`" ] || return echo $* > $spl_fifo || return 1 return 0 } splash_comm_progress () { [ "$1" ] || return 1 progress=`expr 65535 \* $1 / 100` splash_comm_send progress ${progress} splash_comm_send repaint } check_link () { if [ $# = 0 ]; then echo "Usage: check_link " return 1 fi if [ ! -f "$1" ]; then echo "$1 is a broken symlink, skipping" return 2 fi if [ ! -x "$1" ]; then echo "$1 is not executable, skipping" return 3 fi return 0 } # define aliases for compatibility alias status=statusproc alias gprintf=printf