initscripts/etc/rc.d/init.d/functions

621 lines
13 KiB
Plaintext
Raw Normal View History

2011-04-26 12:26:24 +02:00
#!/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 <silvan.calarco@mambasoft.it>
# Modified for LSB and dash compliance by Davide Madrisan <davide.madrisan@gmail.com>
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 <pidfile>] 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 <pidfile>] 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 <pidfile>] {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 <pidfile>] {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_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 <symlink>"
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