Création du script functions

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