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