Créez le script /etc/init.d/functions par la commande suivante:
cat > /etc/init.d/functions << "EOF"
#!/bin/sh
# Début de /etc/init.d/functions
#
# Positionne certaines variables qui influencent l'affichage du texte à l'écran.
# La variable SET_COL positionne le texte au numéro de colonne
# initialisé dans les sections COL et WCOL (comme défini par la variable COL).
# NORMAL affiche le texte en mode normal.
# SUCCESS affiche le texte en vert et FAILURE l'affiche en rouge.
#
# Si COLUMNS n'a pas encore été initialisé (bash le fait mais pas lorsqu'il est
# appelé comme sh), faisons-le
if [ -z "$COLUMNS" ]
then
# Récupère le périphérique de la console si nous ne l'avions pas
# déjà. Cela est conforme au FHS comme il y a une sécurité si
# /usr/bin/tty n'est pas présent, par exemple au démarrage.
test -x /usr/bin/tty && CONSOLE=`/usr/bin/tty`
test -z "$CONSOLE" && CONSOLE=/dev/console
# Récupère la taille de la console (lignes colonnes)
SIZE=$(stty size < $CONSOLE)
# Ne garde que les colonnes
COLUMNS=${SIZE#*\ }
fi
COL=$[$COLUMNS - 10]
WCOL=$[$COLUMNS - 30]
SET_COL="echo -en \\033[${COL}G"
SET_WCOL="echo -en \\033[${WCOL}G"
NORMAL="echo -en \\033[0;39m"
SUCCESS="echo -en \\033[1;32m"
WARNING="echo -en \\033[1;33m"
FAILURE="echo -en \\033[1;31m"
#
# La fonction evaluate_retval évalue la valeur de retour du processus
# précédemment exécuté juste avant que cette fonction ne soit appelée. Si la
# valeur de retour est égale à 0, indiquant une sortie sans erreur, la
# fonction print_status est appelée avec le paramètre 'success'.
# Sinon, la fonction print_status est appelée avec le paramètre 'failure'.
#
evaluate_retval()
{
if [ $? = 0 ]
then
print_status success
else
print_status failure
fi
}
#
# Print_status affiche [ OK ] ou [FAILED] à l'écran. OK apparaît
# dans la couleur définit par la variable SUCCESS et FAILED apparaît dans
# la couleur définit par la variable FAILURE. Ils sont tous les deux affichés
# à partir de la colonne définit par la variable COL.
#
print_status()
{
#
# Si aucun paramètre n'est donné à la fonction print_status, l'usage de la
# fonction est affiché.
#
if [ $# = 0 ]
then
echo "Usage: print_status {success|failure}"
return 1
fi
case "$1" in
success)
$SET_COL
echo -n "[ "
$SUCCESS
echo -n "OK"
$NORMAL
echo " ]"
;;
warning)
$SET_COL
echo -n "[ "
$WARNING
echo -n "ATTN"
$NORMAL
echo " ]"
;;
failure)
$SET_COL
echo -n "["
$FAILURE
echo -n "FAILED"
$NORMAL
echo "]"
;;
esac
}
#
# La fonction loadproc démarre un processus (appelé daemon)
# avec son propre système de vérification d'exécution
#
loadproc()
{
#
# Si aucun paramètre n'est donné, affiche les informations
# d'usage.
#
if [ $# = 0 ]
then
echo "Usage: loadproc {program}"
exit 1
fi
#
# Récupère le nom seul du premier paramètre (le nom du daemon sans
# le chemin, c'est le cas de /usr/sbin/syslogd qui devient 'syslogd' après
# l'exécution de la commande)
#
base=$(/usr/bin/basename $1)
#
# la variable pidlist contiendra la sortie de la commande pidof.
# pidof tentera de trouver les PID associés à une certaine chaîne de
# caractères ; $base dans notre cas
#
pidlist=$(/bin/pidof -o $$ -o $PPID -o %PPID -x $base)
pid=""
for apid in $pidlist
do
if [ -d /proc/$apid ]
then
pid="$pid $apid"
fi
done
#
# Si la variable $pid n'est pas vide (résultat de la précédente boucle) cela
# veut dire que le daemon est déjà présent
#
if [ ! -n "$pid" ]
then
#
# Une variable $pid vide signifie que le daemon ne tourne pas, donc nous
# lançons "$@" (l'ensemble des paramètres donnés à cette fonction par le
# script) puis nous vérifions la valeur de retour
#
"$@"
evaluate_retval
else
#
# Une variable $pid non vide, signifie qu'il tournait déjà. Nous afficherons
# [ ATTN ] alors
#
$SET_WCOL
echo -n "Already running"
print_status warning
fi
}
#
# La fonction killproc tue un processus avec son propre système de vérification
# d'erreur
#
killproc()
{
#
# Si aucun paramètre n'est passé, affichage des informations d'usage.
#
if [ $# = 0 ]
then
echo "Usage: killproc {program} [signal]"
exit 1
fi
#
# Récupère le nom seul du premier paramètre (le nom du daemon sans
# le chemin, c'est le cas de /usr/sbin/syslogd qui devient 'syslogd' après
# l'exécution de la commande)
#
base=$(/usr/bin/basename $1)
#
# Vérifie si nous avons un signal avec lequel tuer le processus (comme -HUP, -TERM,
# -KILL, etc) de cette fonction (le deuxième paramètre). Si aucun deuxième paramètre
# n'est fourni, positionne la variable nolevel. Sinon met la variable
# killlevel à la valeur de $2 (le second paramètre).
#
if [ "$2" != "" ]
then
killlevel=-$2
else
nolevel=1
fi
#
# la variable pidlist contiendra la sortie de la commande pidof.
# pidof tentera de trouver les PID associés à une certaine chaîne de
# caractères ; $base dans notre cas
#
pidlist=$(/bin/pidof -o $$ -o $PPID -o %PPID -x $base)
pid=""
for apid in $pidlist
do
if [ -d /proc/$apid ]
then
pid="$pid $apid"
fi
done
#
# Si $pid contient quelque chose, résultat de la précédente boucle
# cela signifie qu'un ou plusieurs PID ont été trouvés
# et correspondent aux processus à tuer
#
if [ -n "$pid" ]
then
#
# Si aucun signal n'est spécifié nous essayerons -TERM d'abord puis attendrons
# 2 secondes pour attendre la fin du processus de terminaison
#
if [ "$nolevel" = 1 ]
then
/bin/kill -TERM $pid
#
# Si après -TERM le PID continue d'exister nous attendrons 2 secondes avant
# d'essayer de le tuer avec le signal -KILL. Si le PID existe toujours après ça,
# nous attendons encore 2 secondes. Si le PID existe toujours on peut
# raisonnablement estimer que l'on ne peut le tuer.
#
if /bin/ps h $pid >/dev/null 2>&1
then
/usr/bin/sleep 2
if /bin/ps h $pid > /dev/null 2>&1
then
/bin/kill -KILL $pid
if /bin/ps h $pid > /dev/null 2>&1
then
/usr/bin/sleep 2
fi
fi
fi
/bin/ps h $pid >/dev/null 2>&1
if [ $? = 0 ]
then
#
# Si après l'utilisation du signal KILL il continue d'exister, c'est qu'il ne
# peut être tué et nous affichons alors [FAILED]
#
print_status failure
else
#
# S'il a été tué, on peut alors effacer le fichier associé au PID dans /var/run et
# afficher [ OK ]
#
/bin/rm -f /var/run/$base.pid
print_status success
fi
else
#
# Un signal d'arret a été fourni. On tue le processus avec ce signal et on attend
# 2 secondes pour permettre au processus de s'arrêter
#
/bin/kill $killlevel $pid
if /bin/ps h $pid > /dev/null 2>&1
then
/usr/bin/sleep 2
fi
/bin/ps h $pid >/dev/null 2>&1
if [ $? = 0 ]
then
#
# Si la valeur de retour de la commande ps est égale à 0, cela signifie que le PID
# continue de vivre et donc que le processus n'a pas été tué proprement avec le
# signal fourni. On affiche [FAILED].
#
print_status failure
else
#
# Si la valeur de retour est supérieure ou égale à 1 alors le PID n'existe plus.
# On peut alors effacer le fichier associé à ce PID dans /var/run et afficher [ OK ]
#
/bin/rm -f /var/run/$base.pid
print_status success
fi
fi
else
#
# Le PID n'existe pas donc pas besoin de le tuer. On affiche [ ATTN ]
#
$SET_WCOL
echo -n "Not running"
print_status warning
fi
}
#
# La fonction reloadproc envoie un signal au daemon pour lui dire de
# recharger son fichier de configuration. C'est à peu près le même
# fonctionnement que la fonction killproc sans l'envoi du signal
# -KILL (aka -9)
#
reloadproc()
{
#
# Si aucun paramètre n'est donné à la fonction print_status, on affiche les
# informations d'usage.
#
if [ $# = 0 ]
then
echo "Usage: reloadproc {program} [signal]"
exit 1
fi
#
# Récupère le nom seul du premier paramètre (le nom du daemon sans
# le chemin, c'est le cas de /usr/sbin/syslogd qui devient 'syslogd' après
# l'exécution de la commande)
#
base=$(/usr/bin/basename $1)
#
# Vérifie si nous avons un signal avec lequel tuer le processus (comme -HUP, -TERM,
# -KILL, etc) de cette fonction (le deuxième paramètre). Si aucun deuxième paramètre
# n'est fourni, positionne la variable nolevel. Sinon met la variable
# killlevel à la valeur de $2 (le second paramètre).
#
if [ -n "$2" ]
then
killlevel=-$2
else
nolevel=1
fi
#
# la variable pidlist contiendra la sortie de la commande pidof.
# pidof tentera de trouver les PID associés à une certaine chaîne de
# caractères ; $base dans notre cas
#
pidlist=$(/bin/pidof -o $$ -o $PPID -o %PPID -x $base)
pid=""
for apid in $pidlist
do
if [ -d /proc/$apid ]
then
pid="$pid $apid"
fi
done
#
# Si $pid contient quelque chose, résultat de la précédente boucle
# cela signifie qu'un ou plusieurs PID ont été trouvés
# et correspondent aux processus à recharger
#
if [ -n "$pid" ]
then
#
# Si nolevel est positionnée nous utilserons le signal par défaut SIGHUP.
#
if [ "$nolevel" = 1 ]
then
/bin/kill -SIGHUP $pid
evaluate_retval
else
#
# Sinon nous utiliserons le signal fourni
#
/bin/kill $killlevel $pid
evaluate_retval
fi
else
#
# Si $pid est vide alors aucun PID ne correspond.
# On affiche [ ATTN ]
#
$SET_WCOL
echo -n "Not running"
print_status warning
fi
}
#
# La fonction statusproc essaiera de déterminer si un processus tourne
# ou pas
#
statusproc()
{
#
# Si aucun paramètre n'est donné à la fonction print_status, on affiche
# les informations d'usage.
#
if [ $# = 0 ]
then
echo "Usage: status {program}"
return 1
fi
#
# $pid contiendra une liste des PID qui correspondent au processus.
#
pid=$(/bin/pidof -o $$ -o $PPID -o %PPID -x $1)
if [ -n "$pid" ]
then
#
# Si $pid contient quelque chose, le processus tourne, on affiche alors
# le contenu de la variable $pid.
#
echo "$1 running with Process ID $pid"
return 0
fi
#
# Si $pid ne contient rien, on vérifie si un fichier associé au PID existe
# dans /var/run et on informe l'utilisateur de sa présence.
#
if [ -f /var/run/$1.pid ]
then
pid=$(/usr/bin/head -1 /var/run/$1.pid)
if [ -n "$pid" ]
then
echo "$1 not running but /var/run/$1.pid exists"
return 1
fi
else
echo "$1 is not running"
fi
}
# Fin de /etc/init.d/functions
EOF |