L'impression sous Linux

Denis Bodor

Historique des versions
Version 1.0Mars 2002
Article sous licence GNU FDL

Parmi les différentes fonctionnalités qui doivent être présentes dans un système, il y en a une qui nécessite la plus grande attention. Il s'agit de l'impression, ou plus exactement du système d'impression mis à la disposition de l'utilisateur. Un tel système n'est pas une simple application envoyant sans réfléchir les données à un périphérique d'impression, en particulier sur un système réellement multi-utilisateur comme GNU/Linux.

Un système d'impression a pour charge d'être à l'écoute des demandes d'impression. Il doit également gérer les demandes des clients (utilisateurs) locaux ou distants concernant le suivi des impressions. Le système doit également gérer les permissions et les droits des utilisateurs sur la ou les file(s) d'impression. Enfin, tout ce système repose sur une base de filtre permettant de transformer les données fournies par l'utilisateur en données interprétables par l'imprimante. En d'autre terme, les filtres d'impression sont les véritables pilotes des imprimantes reliées au système.

Vue d'ensemble

Le système d'impression généralement utilisé sous GNU/Linux est le système BSD. La gestion et le contrôle sont assurés par un démon nommé lpd. Ce démon est normalement lancé automatiquement au démarrage du système via la procédure d'Init. Vous devez donc trouver dans votre /etc/init.d/ ou /etc/rc.d/ un script d'Init nommé lpd. Vous pourrez ainsi très facilement arrêter, démarrer ou relancer le démon :


/etc/init.d/lpd restart
Stopping printer spooler: lpd.
Starting printer spooler: lpd.

lpd est la partie démon du spooler Berkeley. Il a pour charge de gérer les files d'attente pour les impressions ordonnées par les utilisateurs.

Historiquement, les imprimantes Unix supportent en principe un langage commun : PostScript. Il s'agit presque d'un véritable langage de programmation. En réalité, les imprimantes supportant le PostScript sont maintenant principalement des imprimantes laser haut de gamme. Avec l'arrivée du marché de la bureautique pour les particuliers, les constructeurs ont développé leur propre langage. Ainsi, HP a abandonné PostScript au profit de PCL, leur propre langage de description de page (PDL ou Page Description Language). Pendant un moment, PostScript et PCL étaient les deux seules possibilités se présentant à l'utilisateur. Aujourd'hui, chaque fabricant possède son langage et sa manière de dialoguer avec ses imprimantes. Pire encore, il est très courant que toutes les imprimantes d'un seul et même constructeur utilisent un langage différent.

A ce niveau de spécificité, on ne parle plus de langage, mais de pilote. Si vous avez déjà utilisé un système comme Windows, vous devez savoir que chaque périphérique d'impression nécessite un pilote qui lui est propre. Le problème qui se pose alors avec un système Unix comme GNU/Linux se résume par la capacité de transformer le traditionnel langage PostScript en un patois intelligible par l'imprimante que vous possédez. Bien sûr, si vous choisissez d'investir dans une imprimante laser digne de ce nom, il est fort probable qu'elle comprenne le PostScript ou le PCL (ou les deux). Malheureusement, les imprimantes courantes destinées aux particuliers n'entrent pas dans cette catégorie.

La solution pour GNU/Linux est donc de travailler sur une base PostScript et de traduire ce langage en fonction de l'imprimante. Le pilote devient donc un filtre. Il existe plusieurs packages de filtres pour les distributions GNU/Linux. Les plus connus sont APS Filters et Magic Filters.

Les files d'impression associées aux imprimantes sont configurées dans un fichier spécifique : printcap. Ce fichier définit plusieurs caractéristiques de la file d'attente, des paramètres de l'imprimante, et des filtres à utiliser.

printcap

Ce fichier est la base de la configuration d'impression. Le démon lpd utilisera ce fichier pour soumettre un travail d'impression. printcap est composé de plusieurs entrées sous la forme d'une ligne. Un coup d'oeil à votre fichier printcap (si vous avez déjà une imprimante de configurée) pourrait vous laisser penser qu'il s'agit de paragraphes. Mais regardez attentivement, toutes les lignes, sauf la dernière, possèdent un \ à la fin. C'est le marqueur permettant de spécifier qu'une ligne ne s'arrête pas, mais continue juste en dessous.

Une entrée et donc une ligne printcap définissent une file d'impressions. Celle-ci est constituée de plusieurs variables de configuration qui sont renseignées via le symbole =. Chaque initialisation de variable est séparée des autres par un double-point (:). Ce sont les champs d'une entrée printcap. L'ordre des champs n'a pas grande importance si ce n'est le premier qui est toujours le nom de la file d'attente et les alias de ce nom. Voici un exemple :


lp|lptest|testst:\
	:lp=/dev/lp0:sd=/var/spool/lpd/lptest:\
	:sh:pw#80:pl#72:px#1440:mx#0:\
	:if=/etc/magicfilter/ps300-filter:\
	:af=/var/log/lp-acct:lf=/var/log/lp-errs:

Comme dit plus haut, la première ligne est la définition du nom de la file d'impressions : lp. Les alias suivent ensuite séparés par une barre verticale (|). Voici les paramètres / variables définis ensuite :

lp= indique le périphérique physique à utiliser pour l'impression. Ici /dev/lp0, le premier port parallèle.
sd= définit le répertoire de spool, c'est-à-dire l'emplacement sur le système de fichiers où seront stockés les travaux en attente pour la file d'impressions.
sh est un booléen. Sa seule présence suffit pour désactiver l'impression d'une entête.
pw#, ici = devient # car nous travaillons avec des valeurs numériques. pw permet de spécifier une largeur de page en caractères.
pl# définit la longueur d'une page en lignes.
px# définit la taille horizontale de la page en pixels (axe x).
py# définit la taille verticale de la page en pixels (axe y).
mx# définit la taille maximale des fichiers. Ici, 0 nous permet de définit une taille illimitée.
if= donne le chemin vers le filtre à utiliser pour l'impression.
af= spécifie le fichier où stocker les informations de comptabilisation (log).
lf= spécifie le fichier dans lequel il faut placer les messages d'erreur.

Vous l'aurez compris à la valeur du champ if, cette entrée printcap utilise un filtre Magic Filters. Voici un autre exemple pour une imprimante Canon BJ200 utilisant un filtre du package APS Filters.


lp|lp2|bj200-a4-auto-mono-360|bj200 a4 auto mono 360:\
	:lp=/dev/lp0:\
	:sd=/var/spool/lpd/bj200-a4-auto-mono-360:\
	:lf=/var/spool/lpd/bj200-a4-auto-mono-360/log:\
	:af=/var/spool/lpd/bj200-a4-auto-mono-360/acct:\
	:if=/var/lib/apsfilter/bin/bj200-a4-auto-mono-360:\
	:la@:mx#0:\
	:tr=:cl:sh:

Nous retrouvons des champs semblables à l'exemple précédent. Remarquez que le filtre est différent. Comme vous pouvez le constater, une fois la fonction de chaque champ correctement assimilée, la définition d'une entrée dans printcap est relativement simple. De plus, il existe un certain nombre d'applications permettant de configurer les files simplement via une interface graphique. C'est le cas de printtool livré dans bon nombre de distributions.

lpr, lprm, lpc et lpq

Une fois la ou les file(s) d'impression et les filtres configurés et installés, il faut encore soumettre les impressions au démon lpd. La plupart des applications GNU/Linux ne vous proposeront même pas de choisir l'imprimante à utiliser. Par défaut, la file d'impression lp sera utilisée et le logiciel générera une page en langage PostScript. A la charge du filtre, ensuite, de traduire le PostScript en langage d'impression du périphérique.

Cependant, il est souvent indispensable à l'utilisateur de savoir où en est son impression, quelles sont les files existantes, ou encore, il peut être nécessaire d'annuler une impression faite par erreur. Pour cela, le démon lpd se voit agrémenté d'applications utilisateurs permettant ces manipulations.

La première commande est lpc (line printer control). Celle-ci permet d'obtenir des informations sur les files en présence et l'état des périphériques :


# lpc
lpc> stat
ascii:
	queuing is enabled
	printing is enabled
	no entries
	printer idle
lp:
	queuing is enabled
	printing is enabled
	no entries
	printer idle
raw:
	queuing is enabled
	printing is enabled
	no entries
	printer idle
remote:
	queuing is enabled
	printing is enabled
	no entries
	printer idle
lpc>

lpc fonctionne de manière interactive. Après son lancement, vous êtes invité à entrer des commandes internes à lpc. L'une des plus utiles est stat permettant d'avoir une vue d'ensemble des files et de leur état.

Pour soumettre un travail d'impression directement depuis la ligne de commande sous la forme d'un fichier ou d'un flux de donnée, vous utiliserez lpr. Vous pouvez par exemple envoyer un fichier PostScript directement dans la file d'impressions avec lpr fichier.ps. Une autre solution est de rediriger la sortie d'un programme vers lpr avec | (pipe) :


# ls /var/log | lpr

Le listing complet du répertoire /var/log sera envoyé à lpr et sera inséré dans la file d'impressions par défaut (lp). Si vous désirez utiliser une autre file d'impressions, vous devrez utiliser l'option -P. Ce qui nous donne ici :


# ls /var/log | lpr -Premote

Si vous soumettez beaucoup d'impressions à une file d'attente, il est possible que la vitesse du périphérique ralentisse les opérations. Les impressions en attente sont donc stockées dans la file. Vous pouvez lister le contenu d'une file d'attente en utilisant lpq. Là encore, sans option spécifique, lpq vous listera les travaux en attente sur la file lp. Vous pourrez, une fois de plus, utiliser l'option -P pour spécifier une autre file à examiner. Enfin, ultime commande forte utile dans certains cas, lprm permet de supprimer un travail dans une file d'impressions. Il suffit pour cela de spécifier en paramètre le numéro du travail dans la file tel qu'il est spécifié dans la sortie de lpq.

Impression en réseau

lpd n'est pas un simple démon local, il peut en effet accepter des entrées via le réseau. De ce fait, il est possible d'installer un système d'impression BSD sur une machine et de demander à l'ensemble des autres hôtes du LAN de l'utiliser pour imprimer. Les imprimantes haut de gamme (valant entre 1500 et 2000 Euros) intègrent directement un système de gestion des impressions BSD. En d'autre terme, non seulement l'imprimante peut être directement connectée à un LAN via une interface ethernet intégrée, mais elle inclut un démon lpd.

Configurer une entée printcap sur les clients est une vraie partie de plaisir, car ce type d'imprimante professionnelle est généralement compatible PostScript et PCL. Il n'est donc pas utile de faire appel à un filtre d'impression :


remote|lp4|192.168.0.31-BRN_337895_P1|192.168.0.31 BRN_337895_P1:\
	:lp=:\
	:rm=192.168.0.31:\
	:rp=BRN_337895_P1:\
	:sd=/var/spool/lpd/192.168.0.31-BRN_337895_P1:\
	:lf=/var/spool/lpd/192.168.0.31-BRN_337895_P1/log:\
	:af=/var/spool/lpd/192.168.0.31-BRN_337895_P1/acct:\
	:ar:bk:mx#0:\
	:tr=:cl:sh:

La ligne importante, rm= définit le nom d'hôte ou l'adresse IP de la machine où tourne le lpd. Ensuite, rp= donne le nom de l'imprimante à utiliser, c'est-à-dire le nom de la file d'impression sur le serveur. Ce nom est généralement défini par le constructeur de l'imprimante. Il est sensé être unique puisque plusieurs imprimantes du même modèle pourraient être mises en oeuvre sur le LAN.

Si vous utilisez un LAN, il est fort probable qu'un autre cas se présente à vous : l'impression depuis une autre plate-forme. Cette autre plate-forme est généralement Windows, et permettre l'impression sur le serveur lpd depuis Windows est parfois indispensable. Dans ce genre de situation, il faut mettre en oeuvre Samba pour mettre en place le partage de vos ressources. Une simple entrée supplémentaire dans votre smb.conf fera l'affaire :


[printers]
	comment = All Printers
	browseable = no
	printable = yes
	public = yes
	read only = yes
	create mode = 0700
	directory = /tmp

Nous rendons ainsi notre ou nos imprimante(s) GNU/Linux accessible(s) par l'ensemble des utilisateurs du LAN utilisant Windows. Ces utilisateurs se serviront du pilote fourni par le constructeur de l'imprimante et utiliseront une entrée spécifique dans printcap. Cette entrée n'utilisera aucun filtre, c'est habituellement par le nom raw ou lp-raw que la file d'attente sera désignée. Les données en provenance de Windows seront déjà formatées pour le périphérique d'impression, il n'est pas nécessaire de filtrer. De plus, il est courant que des fonctionnalités supplémentaires soient mises à disposition par le pilote Windows (test de l'imprimante, nettoyage des têtes, etc.). Ceci ne devrait pas poser de problème puisque ce genre de directives prennent la forme de paquet de données qui ne seront pas filtrées par le système BSD.

CUPS

Le système d'impression BSD est vu par certaines personnes comme une chose vieillissante. Un autre projet totalement nouveau a donc été mis en marche : CUPS. CUPS est l'acronyme de Common Unix Printing System. Le but de l'opération est de définir un système d'impression commun et utilisable avec tous les systèmes Unix.

L'architecture modulaire de CUPS permet déjà de mettre en oeuvre bon nombre d'imprimantes non supportées par les filtres APS ou Magik. De plus, un certain nombre de fonctionnalités dynamiques font de ce système le remplaçant idéal pour le vieux système BSD. CUPS permet par exemple de changer bon nombre de paramètres d'impression sans toucher à la configuration en place. Ces changements, comme la taille du papier, peuvent être faits via un simple argument sur la ligne de commande. Ceci n'est peut être qu'un détail, mais comparé aux manipulations nécessaires avec le système BSD, on perçoit immédiatement l'intérêt.

Autre point important : la sécurité. En effet, la communication entre un client et un serveur lpd se fait en clair. Il est donc parfaitement possible qu'une personne sur votre réseau «écoute» la communication et arrive à recomposer le document que vous imprimez. S'il s'agit d'une page Web ou d'une documentation quelconque, ceci n'a pas une grande importance. S'il s'agit de pièces comptables, de contrats, etc., il en va tout autrement.

CUPS, à terme, inclura un système permettant de chiffrer les transmissions entre client et serveur de manière à éviter le problème. Cela ajoutera également une capacité d'authentification robuste pour la gestion des permissions d'impression.

Conclusion

Le monde de l'impression sur un système Unix est vaste et passionnant. La simple création d'un filtre pour une nouvelle imprimante est un travail d'investigation, de recherche et de patience. Mais vous pouvez également vous amuser en imaginant d'autres fonctionnalités en développant un filtre, comme l'impression sur un Fax ou la conversion automatique en PDF. Les liens qui suivent vous donneront les bases techniques suffisantes pour vous lancer dans le domaine et peut-être vous rendre célèbre :)

Liens

Un guide rapide pour l'impression sous Linux (en français)
http://www.ac-creteil.fr/reseaux/systemes/linux/impression-linux.html
Le Howto pour imprimer de Linux vers Windows
http://www.linuxdoc.org/HOWTO/mini/Print2Win.html
L'incontournable Printing Howto en français
http://www.freenix.org/unix/linux/HOWTO/Printing-HOWTO.html
CUPS
http://www.cups.org