Je viens d'examiner le code source du modèle d'impression
/usr/lib/lp/model/netstandard_foomatic. Ce modèle comme les autres est
développé en Bourne Shell (on n'a pas le choix de faire autrement car la
commande lpsched forke un shell sur le fichier).

Résultat de mon investigation pas brillant ! Le développement de ce code
à  été confié à des personnes qui ne programment pas proprement en
Shell. Le style de
programmation est tout simplement lourd et truffé de choses inutiles.

En terme de lisibilité c'est très mauvais.
En terme d'efficacité et de performance ce n'est pas optimisé.
En terme de maintenabilité cela pose problème.

Au vu de cela il n'est pas étonnant que lp ne marche pas bien. Le
problème
de lp est dans les modèles.

Parmi les perles  de programmation la fonction exit_clean :

exit_clean()
{

        if [ -f "${LPTMPDIR}/pr_eexit_code.$$" ]
        then
                /bin/rm ${LPTMPDIR}/pr_eexit_code.$$
        fi

        if [ -f "${LPTMPDIR}/small_banner.$$" ]
        then
                /bin/rm ${LPTMPDIR}/small_banner.$$
        fi

        if [ -f "${tmpfile}" ]
        then
                /bin/rm "${tmpfile}"
        fi

        exit $1
}

que je simplifierais ainsi :

exit_clean()
{
        /bin/rm -f ${LPTMPDIR}/pr_eexit_code.$$  ${LPTMPDIR}/small_banner.$$ \
                   "${tmpfile}"
        exit $1
}

Le programmeur ne connait pas rm -f et on retrouve cette erreur tout au
long
du code. Il est vrai que sous System V R3 (1988) l'option -f n'existait
pas
mais ce n'est pas une excuse puisque Solaris 2 est System V R4 et que ce
script
a été écrit en 2004.

Ou je ne comprends pas ou voila une autre perle :

exit_code=`expr 0`
exit_code=`expr 129`
exit_code=`expr 1`

Il est beaucoup plus clair et normal de faire exit_code=0, etc. (le
Bourne shell ne
connait pas les entiers).

Encore des marques de portage baclé autour de la fonction small_banner
pour construire une bannière qui montre le non nettoyage du code qui a
servi de base
de départ.

PAD="#####${NL}"   <<< A quoi sert le ${NL} ici ?
CR="\r"
NL="${CR}\n"
FF=                <<< A quoi sert  d'initialiser FF à rien ?

Dans la fonction 

small_banner() {
        echo "${CR}\c"
        echo "${PAD}\c"
        echo "#####  User: ${user_name}${NL}\c"
        if [ -n "${title}" ]   <<<<< le titre par défaut est le nom du
fichier  
        then
                echo "##### Title: ${title}${NL}\c"
        fi
        echo "#####  Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
        echo "#####   Job: ${request_id}${NL}\c"
        echo "${PAD}\c"
        if [ -n "${FF}" ]         <<<<<  code inutile FF est nul
        then
                echo "${CR}${FF}\c"
        fi
}



Une perle encore plus rare : au cas où l'admin aurait effacé la commande
lp.tell
ou lui aurait enlevé par hasard le droit d'éxécution on découvre ce code
sublime :

#####
# ${LPTELL} is the name of a program that will send its
# standard input to the Spooler. It is used to forward
# the description of a printer fault to the Spooler,
# which uses it in an alert to the administrator.
#####
if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
then
        fake_lptell () {
                header="no"
                while read line
                do
                        if [ "no" = "${header}" ]
                        then
                                errmsg ERROR ${E_IP_UNKNOWN} \
                "unknown printer/interface failure" \
                "consult your system administrator;
                reasons for failure (if any) follow:"
                                header=yes
                        fi
                        echo "${line}" >&2
                done
                return 1
        }
        LPTELL=fake_lptell
fi

Sur ce genre de problème j'aurais fait appel à logger qui n'est 
pourtant
pas inconnu du programmeur (cf. ce qui suit).
 

Ce n'est pas un programme fini car il reste une quantité superfétatoire
de
commandes logger montrant que le code de mise au point est encore là. En
plus une
seule ligne suffirait là ou il y en a plus de 10

logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" " "
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "INPUT"
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "   
printer : ${printer}"
@

logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "INPUT"
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "   
printer : ${printer}"
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "   
request_id : ${request_id}"
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "   
user_name : ${user_name}"
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "    title
: ${title}"
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "    copies
: ${copies}"
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "   
option_list :
${option_list}"
logger -p lpr.debug -t "netstandard_foomatic: ${request_id}" "    files
: ${files}"

Autres points la doc sur les filtres foomatic  indique qu'il ne faut pas
utiliser
l'option -T de lpadmin avec ce type de filtre. Or on trouve du code qui
indique
le contraire :

banner_filter=
case "${TERM}" in
PS | PSR )
        banner_filter=" | /usr/lib/lp/postscript/postprint "
        LPTELL_OPTS="-l"
        ;;
esac

etc.

et celui-ci qui est pour le moins curieux :

if [ -z "${FILTER}" ]
then
        #####
        #
        # If no filter is being used, we use netpr to push the
        # file to the printer.
        # (QUOTES ARE IMPORTANT!)
        #####

        case "$TERM" in
                PS )
                        # make the "postscript" printers use netpr
                        FILTER=
                ;;
                PSR )
                        # make the "reverse postscript" printers reverse
the
                        # output and the use postio to talk to the
printer
                        #FILTER="/usr/lib/lp/postscript/postreverse "
                        #FILTER=
                        FILTER="/usr/lib/lp/postscript/postreverse "
                ;;
                * )
                        # We don't know the type, so just assume that
the
                        # input and output are the same. Use netpr.
                        #FILTER=/bin/cat
                        FILTER=
                ;;
        esac
fi


Bref l'impression que je retire de cet examen est que ce code est la
source de
la plupart des problèmes de lp et que Sun ferait bien de l'améliorer en
tenant compte de ces qq remarques.

Un espoir peut-être avec OpenSolaris .
Inutile de dire que les autres filtres standard standard_foomatic et
netstandard
présentent une partie de ces défauts.

-- 
Christian Pélissier
Office National d'Études et de Recherches Aérospatiales
BP 72 92322 Chatillon
Tel: 33 1 46 73 44 19, Fax: 33 1 46 73 41 50

_______________________________________________
Solaris_fr liste de diffusion en français pour Solaris, sur toutes architectures
Solaris_fr@x86.sun.com
http://x86.sun.com/mailman/listinfo/solaris_fr

Répondre à