629 lines
13 KiB
Bash
629 lines
13 KiB
Bash
#!/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
|
|
[ -r "$pid_file" ] || return 4 # "user had insufficient privilege"
|
|
read line < "$pid_file"
|
|
for p in $line ; do
|
|
case $p in *[!0-9]*) : ;;
|
|
*) [ -d "/proc/$p" ] && pid="$pid $p" ;;
|
|
esac
|
|
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_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 <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
|