Créer le script functions

Un nouveau fichier /etc/init.d/functions est créé, contenant ce qui suit:



cat > functions << "EOF"
#!/bin/sh
# Debut de /etc/init.d/functions

#
# Definition de quelques variables qui influencent la facon dont
# le texte sera affiche a l'ecran. La variable SET_COL fait demarrer
# le texte en colonne 70 (comme specifie par la variable COL).
# NORMAL affiche le texte en mode normal. SUCCESS affichera le texte en
# vert et FAILURE en rouge.
#

COL=70
SET_COL="echo -en \\033[${COL}G"
NORMAL="echo -en \\033[0;39m"
SUCCESS="echo -en \\033[1;32m"
FAILURE="echo -en \\033[1;31m"

#
# La fonction evaluate_retval evalue la valeur de retour du processus
# qui etait execute juste avant que la fonction ne soit appelee. Si cette
# valeur de retour etait 0, indiquant le succes, la fonction print_status
# est appelee avec le parametre "success". Dans les autres cas, la fonction
# print_status est appelee avec le parametre d'erreur.
#

evaluate_retval()
{
        if [ $? = 0 ]
        then
                print_status success
        else
                print_status failure
        fi
}

#
# La fonction print_status affiche [ OK  ] ou [ECHEC] a l'ecran. OK
# apparaitra avec la couleur definie par la variable SUCCESS et FAILED 
# avec celle definie par la variable FAILURE. Les deux sont affichees
# a partir de la colonne definie par la variable COL.
#

print_status()
{

#
# Si aucun parametre n'est passe a la fonction print_status, afficher
# le mode d'emploi.
#

        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 "  ]"
                        ;;
                failure)
                        $SET_COL
                        echo -n "["
                        $FAILURE
                        echo -n "ECHEC"
                        $NORMAL
                        echo "]"
                        ;;
        esac

}

#
# La fonction loadproc lance un processus (souvent un demon)
# avec les controles d'erreur appropries.
#

loadproc()
{

#
# Si aucun parametre n'est passe a la fonction loadproc, afficher
# le mode d'emploi.
#

        if [ $# = 0 ]
        then
                echo "Usage: loadproc {program}"
                exit 1
        fi
#
# Trouver le nom de base ("basename") du premier parametre (le nom du demon
# sans le chemin d'acces qui a ete fourni: ainsi /usr/sbin/syslogd devient
# "syslogd" une fois que basename a ete lance).
#

        base=$(/usr/bin/basename $1)
#
# La variable pidlist contiendra le resultat de la commande pidof.
# pidof essaiera de trouver le PID correspondant a une chaine de
# caracteres donnee ($base dans le cas present).
#

        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 contient quelque chose (provenant de la boucle for
# precedente), cela signifie que le demon tourne deja.
#

        if [ ! -n "$pid" ]
        then
#
# Une variable $pid vide signifie que le demon ne tourne pas; nous executons
# donc $* (tous les parametres du script sont passes a cette fonction par
# le script) puis nous controlons la valeur de retour.
#
                $*
                evaluate_retval
        else
#
# La variable $pid n'etait pas vide, signifiant que le demon tournait
# deja. Nous affichons maintenant [ECHEC].
#
                print_status failure
        fi

}

#
# La fonction killproc tue un processus en effectuant le controle
# d'erreur proprement.
#

killproc()
{

#
# Si aucun parametre n'est passe a la fonction killproc, afficher
# le mode d'emploi.
#

        if [ $# = 0 ]
        then
                echo "Usage: killproc {program} [signal]"
                exit 1
        fi

#
# Trouver le nom de base ("basename") du premier parametre (le nom du demon
# sans le chemin d'acces fourni: ainsi /usr/sbin/syslogd devient
# "syslogd" une fois que basename a ete lance).
#

        base=$(/usr/bin/basename $1)

#
# Verifie si nous avons passe un signal pour tuer le processus (tel que
# -HUP, -TERM, -KILL, etc.) a cette fonction (le second parametre). Si
# aucun second parametre n'a ete fourni, la variable nolevel est positionnee.
# Dans le cas contraire, la variable killlevel recoit la valeur de $2
# (le second parametre).
#

        if [ "$2" != "" ]
        then
                killlevel=-$2
        else
                nolevel=1
        fi

#
# La variable pidlist contiendra le resultat de la commande pidof.
# pidof essaiera de trouver le PID correspondant a une chaine de
# caracteres donnee ($base dans le cas present).
#

        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 provenant de la boucle for, cela
# signifie qu'on a trouve un ou plusieurs PID appartenant aux processus
# qu'il faut tuer.
#
        if [ -n "$pid" ]
        then
#
# Si aucun signal pour kill n'a ete indique, on va d'abord essayer -TERM
# puis attendre 2 secondes pour laisser le temps à kill de finir
# son travail.
#
                if [ "$nolevel" = 1 ]
                then
                        /bin/kill -TERM $pid
#
# Si apres -TERM, le PID existe toujours, nous attendons 2 secondes avant
# d'essayer de le tuer avec un -KILL. Si le PID existe encore apres cela,
# attendre encore 2 secondes. Si les PID existent encore, alors il faut
# considerer que nous ne pouvons pas les 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, apres le -KILL, il existe encore, il ne peut etre tue pour une
# raison quelconque; on va donc afficher [ECHEC].
#
                                print_status failure
                        else
#
# Il a ete tue; on supprime un eventuel fichier PID qui subsisterait
# dans /var/run puis on affiche [ OK  ].
#
                                /bin/rm -f /var/run/$base.pid
                                print_status success
                        fi
                else
#
# Un signal de kill a ete fourni. On execute donc kill avec le signal
# en question puis on attend 2 secondes pour permettre a kill de finir
# son travail.
#
                        /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 ps vaut 0, cela signifie que cette commande
# s'est executee avec succes et par consequent que le PID existe toujours.
# Donc le processus n'a pas ete tue correctement avec le signal fourni.
# Afficher [ECHEC].
#
                                print_status failure
                        else
#
# Si la valeur de retour valait 1 ou plus, cela signifie que le PID
# n'existe plus desormais, donc qu'il a ete tue avec succes. Supprimer
# un eventuel fichier PID residuel et afficher [ OK  ].
#
                                /bin/rm -f /var/run/$base.pid
                                print_status success
                        fi
                fi
        else
#
# Le PID n'existe pas, il n'est donc pas necessaire d'essayer
# de le tuer. Afficher [ECHEC]
#
                print_status failure
        fi
}

#
# La fonction reloadproc envoie un signal au demon en lui disant de
# recharger son fichier de configuration. Elle est presque identique
# a la fonction killproc si ce n'est qu'elle n'essaie pas de tuer le
# processus avec un signal -KILL (c'est-a-dire -9).
#

reloadproc()
{

#
# Si aucun parametre n'est passe a la fonction reloadproc, afficher
# le mode d'emploi.
#

        if [ $# = 0 ]
        then
                echo "Usage: reloadproc {program} [signal]"
                exit 1
        fi

#
# Trouver le nom de base ("basename") du premier parametre (le nom du demon
# sans le chemin d'acces fourni: ainsi /usr/sbin/syslogd devient
# "syslogd" une fois que basename a ete lance).
#

        base=$(/usr/bin/basename $1)

#
# Verifie si nous avons passe un signal a envoyer au processus (comme
# -HUP) a la fonction (le second parametre). Si aucun second parametre
# n'a ete fourni, la variable nolevel est positionnee. Dans le cas contraire,
# la variable killlevel recoit la valeur de $2 (le second parametre).
#


        if [ -n "$2" ]
        then
                killlevel=-$2
        else
                nolevel=1
        fi

#
# La variable pidlist contiendra le resultat de la commande pidof.
# pidof essaiera de trouver le PID correspondant à une chaine de
# caracteres donnee ($base dans le cas present).
#

        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 provenant de la boucle for precedente,
# cela signifie qu'un ou plusieurs PID appartenant aux processus a
# recharger ont ete trouves.
#

        if [ -n "$pid" ]
        then

#
# Si aucun signal n'a ete indique, on va utiliser le signal de
# rechargement par defaut : SIGHUP.
#

                if [ "$nolevel" = 1 ]
                then
                        /bin/kill -SIGHUP $pid
                        evaluate_retval
                else
#
# Sinon, on utilisera le signal fourni.
#

                        /bin/kill $killlevel $pid
                        evaluate_retval
                fi
        else
#
# Si $pid est vide, aucun PID appartenant au processus n'a ete trouve
# et on affiche [ECHEC].
#

                print_status failure
        fi
}

#
# La fonction statusproc essaiera de savoir si un processus tourne
# ou non.
#

statusproc()
{

#
# Si aucun parametre n'a ete passe a la fonction statusproc, afficher
# le mode d'emploi.
#

        if [ $# = 0 ]
        then
                echo "Usage: status {program}"
                return 1
        fi

#
# $pid contiendra la liste des PIDs appartenant à un 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 le contenu de la variable $pid.
#
                echo "$1 en cours d'execution, avec le PID $pid"
                return 0
        fi

#
# Si $pid ne contient rien, on regarde s'il existe un fichier PID et
# on en informe eventuellement l'utilisateur.
#

        if [ -f /var/run/$1.pid ]
        then
                pid=$(/usr/bin/head -1 /var/run/$1.pid)
                if [ -n "$pid" ]
                then
                        echo "$1 ne tourne plus mais /var/run/$1.pid existe"
                        return 1
                fi
        else
                echo "$1 ne tourne plus"
        fi

}

# Fin de /etc/init.d/functions
EOF