Ce chapitre fut au départ la Foire Aux Questions lpd, puis a fait partie de la Foire Aux Questions Linux. Il est maintenant inclus dans ce document. Qui sait ce qu'il deviendra après...
Cette partie a été originellement écrite par Karl Auer <Karl.Auer@anu.oedu.au> (11/1/93) et est maintenant incluse ici, car ce manuel, écrit dans le style d'un manuel de référence, ne remplissait pas complètement son objectif, puisqu'il ne décrivait pas franchement la façon de configurer les services d'impression sur votre machine Linux.
C'est maintenant chose faite. Quelques modifications ont été apportées au document d'origine. A noter que certaines informations peuvent donc être redondantes par rapport au reste du document. Elles devraient néanmoins être utiles aux nouveaux venus dans le monde des techniques de l'impression BSD.
L'impression locale permet aux utilisateurs d'envoyer des travaux d'impression à l'imprimante directement rattachée à leur machine.
L'impression distante, par contre, permet de soumettre des travaux d'impression depuis une machine, à une autre machine sur le réseau, sur laquelle est connectée une imprimante.
Nous supposons que vous savez éditer un fichier texte sous Linux et que vous avez une bonne compréhension des notions de droits d'accès et de propriété (chmod, chown).
Nous supposons également que votre système Linux fonctionne correctement. En particulier, si vous souhaitez faire de l'impression distante, que votre réseau fonctionne déjà.
Consultez à ce propos les nombreuses documentations disponibles sur le sujet.
La façon la plus simple d'imprimer sous Unix (et donc Linux) est d'envoyer les données directement à l'imprimante.
ls >/dev/lp0
en est un exemple simple. Cette méthode, si elle a l'avantage d'être simple, ne tire pas avantage des caractéristiques multi-tâches de Linux, puisqu'elle attendra que l'imprimante ait absorbé toutes les données avant de se terminer. Plus l'imprimante est lente, et a un petit buffer, plus ce sera long.
Une meilleure méthode consiste à utiliser un spool d'impression, dont le rôle est de collecter les données temporairement dans des fichiers afin de les envoyer, en tâche de fond, à l'imprimante.
C'est la façon de travailler de Linux. Pour chaque imprimante est définie une zone de spool. Les données à envoyer à l'imprimante sont collectées dans le spool, un fichier par travail soumis. Le processus démon (donc en tâche de fond) est averti des nouveaux travaux soumis, et se charge d'envoyer les données à l'imprimante (locale), ou à la machine (distante) qui se chargera de l'impression. Lorsque plusieurs fichiers sont soumis, ils seront imprimés dans l'ordre de soumission. (premier entré, premier sorti). La zone de spool est donc bien une file. On dit que les travaux sont dans la file d'impression.
Lors de la soumission de travaux pour une imprimante distante, les fichiers sont d'abord mis en file localement avant d'être envoyés au démon distant qui se chargera alors de les mettre dans le spool de l'imprimante.
Toutes les informations nécessaires au démon (numéro du périphérique à utiliser, zone de spool, nom de la machine distante ou de l'imprimante, ...) sont décrites dans le fichier /etc/printcap. Les détails et la syntaxe de ce fichier son explicités plus loin.
Dans la description qui suit, le terme "imprimante" correspondra toujours à une imprimante déclarée dans /etc/printcap. Le terme "imprimante physique", correspondra toujours à l'objet qui imprime~! Il est possible d'avoir plusieurs entrées dans /etc/printcap, chacune définissant une imprimante physique différente, ou alors toutes décrivant la même imprimante, mais avec des options différentes. Vous comprendrez mieux les détails plus loin.
Le système d'impression Unix comprend (au moins) 5 programmes. Ils doivent se trouver à l'endroit décrit (c'est le mieux) ou dans un répertoire accessible (avec la variable PATH), appartenir à root (groupe lp), et avoir les permissions suivantes~:
-r-sr-sr-x root lp /usr/bin/lpr
-r-sr-sr-x root lp /usr/bin/lpq
-r-sr-sr-x root lp /usr/bin/lprm
-r-xr-sr-x root lp /usr/sbin/lpc
-rwxr--r-- root lp /usr/sbin/lpd
Les quatre premiers sont utilisés pour soumettre, visualiser, annuler, contrôler les travaux d'impression. Le dernier est le démon.
Il existe bien entendu des pages de manuel en ligne pour ces commandes que vous pourrez consulter pour plus d'information. Le point important à noter est que les commandes lpr, lpq, lpc et lprm opèrent sur une imprimante par défaut nommée lp. La variable d'environnement PRINTER peut contenir le nom de l'imprimante que vous avez définie. La spécification du nom d'une imprimante sur la ligne de commande surchargera ces définitions (les imprimantes de l'exemple sont hors-ligne)~:
# echo $PRINTER
(vide)
#
# lpq
waiting for lpr0 to become ready (offline ?)
...
# export PRINTER=mon_imprimante
# lpq
waiting for mon_imprimante to become ready (offline ?)
...
# lpq -Plpr0
waiting for lpr0 to become ready (offline ?)
...
La commande lpr soumet un travail d'impression. Elle se charge de mettre les données à imprimer dans un fichier dans le spool d'impression. Ces données peuvent provenir soit d'un fichier (les données sont dupliquées et toute modification ultérieure du fichier d'origine n'affectera pas l'impression), soit de l'entrée standard (stdin). Le démon est averti de l'existence d'un nouveau fichier et envoie, dès que possible, les données vers l'imprimante physique (ou la machine distante).
La commande lpq affiche le contenu du spool, pour une imprimante donnée. Une des informations importantes fournies est le numéro du travail (job). C'est lui qui pourra servir à annuler un des travaux soumis, y compris celui en cours d'impression. Parmi tous les travaux soumis, l'indication "active" indique le travail en cours d'impression (ou que lpd essaie d'envoyer à l'impression).
La commande lprm enlève un travail de la file (et donc le fichier du spool). Vous pouvez soit spécifier un numéro de job, soit un tiret permettant de supprimer tous les travaux vous appartenant. Si vous êtes root, tous les travaux sont supprimés. Pour supprimer les travaux d'un utilisateur, spécifiez son nom.
# lprm 1
dfA001Aa00484 dequeued
cfA001Aa00484 dequeued
#
Le premier fichier contient les données à imprimer. Il a été créé par lpr. Le deuxième contient des informations que le démon utilisera pour savoir que faire des donnés (impression locale, distante, ...) Consultez le manuel en ligne~: lpd(8)
La commande lpc permet de contrôler les travaux en cours ainsi que l'imprimante, et certains aspects de son utilisation. En particulier, vous pouvez démarrer ou stopper la sortie des travaux du spool pour l'impression, valider ou invalider une imprimante, et même modifier l'ordre d'impression des fichiers. Les commandes suivantes permettent d'invalider l'impression sur mon_imprimante, de valider le spool sur ton_imprimante, et de faire passer le job 37 en début de file~:
lpc down mon_imprimante
lpc enable ton_imprimante
lpc topq 37
lpc peut fonctionner en interactif si aucun paramètre ne lui est passé. Vous pouvez lire les pages du manuel en ligne pour obtenir des instructions complètes. A noter que certaines actions de lpc sont réservées à root.
Le répertoire le plus important est le répertoire de spool, dans lequel les données vont être stockées avant d'être imprimées. Typiquement, un système sera configuré pour avoir un répertoire de spool par imprimante. Cela rend la gestion plus facile. Sur mon système, par exemple, le répertoire /usr/spool/lp est le répertoire principal. Sous ce répertoire, on y trouve le sous-répertoire lpr0, correspondant à la déclaration que j'ai faite dans /etc/printcap pour le répertoire de spool de mon imprimante.
NDT: Ce qui va suivre décrit une façon de faire pour donner les bons droits d'accès aux répertoires de spool. Différentes méthodes sont possibles, sachant que, comme sous Un*x, beaucoup de choses sont possibles dans ce domaine, il convient de faire attention de ne pas offrir de failles à la sécurité de l'ensemble.
Le répertoire de spool doit appartenir à root, et au groupe lp, avec les droits de lecture/d'écriture pour utilisateur et groupe, et lecture seule pour le reste du monde.
chmod ug=rwx,o=rx lpr0
chgrp lp lpr0
drwxrwxr-x 2 root lp 1024 Feb 11 10:51 lpr0/
Un autre répertoire doit également être présent~: /usr/spool/lpd avec les mêmes droits. Vous aurez plus d'informations plus avant dans ce document.
En dehors des programmes que nous avons déjà
évoqués précédemment, quatre fichiers doivent
se trouver dans chaque répertoire de spool
-rw-rw-r--
. Le fichier .seq contient un compteur pour
l'affectation des numéros de jobs. Le fichier status contient
le message devant être émis par la commande
lpc~stat
. Le fichier lock est utilisé par le
démon pour qu'il n'imprime qu'un fichier à la fois. Le
fichier errs contient les erreurs survenues sur l'imprimante.
Le fichier errs n'est pas obligatoire. De plus, il peut s'appeler comme vous le souhaitez, pourvu que son nom soit déclaré dans le fichier /etc/printcap que nous décrirons dans la suite.
Le fichier /etc/printcap, qui peut être modifié avec votre éditeur préféré, doit appartenir à root et avoir les droits suivants:
-rw-r--r-- 1 root system 164 Oct 25 21:23 /etc/printcap
Le contenu du fichier semble assez imcompréhensible à première vue. Il respecte effectivement une syntaxe particulière et malgré les apparences, assez simple lorsque l'on connaît~! Il n'y a pas toujours de manuels concernant ce fichier, et cela complique un peu les choses. Un petit conseil en passant~: essayez, dans la mesure du possible de rendre votre fichier le plus lisible possible, avec des commentaires. Vous pouvez consulter les pages du manuel en ligne concernant printcap(5) (ou empressez-vous de les récupérer si vous ne les avez pas). Plus loin sont décrits les paramètres importants.
Une entrée de printcap décrit une imprimante, c'est-à-dire une correspondance nom logique - imprimante physique, puis décrit la façon de transmettre les données. Par exemple, une entrée va décrire le périphérique physique à utiliser, le répertoire de spool, les traitements à effectuer sur les données avant impression, ou encore le répertoire dans lequel seront notifiées les erreurs. Vous pouvez aussi limiter la quantité de données pour un job, ou même limiter l'accès d'une imprimante à une classe d'utilisateurs. Vous trouverez dans la partie suivante la description des champs.
Il est tout à fait possible d'avoir plusieurs entrées décrivant différentes façons d'envoyer des données à une même imprimante physique. Par exemple, une imprimante physique peut supporter les formats HP LaserJet et PostScript, en fonction de la séquence de caractères envoyée au début d'un travail. Vous définirez donc deux entrées, l'une permettant de traiter le format HP, l'autre le format PostScript. Les programmes générant des données "HP" les enverront à l'imprimante HP, ceux générant des données PostScript les enverront à l'imprimante PostScript.
Les programmes qui modifient les données avant de les envoyer à l'imprimante physique sont des filtres.
Exemple d'entrée d'un fichier /etc/printcap~:
# exemple d'entree de printcap avec deux alias
lpr0|laserwriter\
# lp est le peripherique d'impression - ici une imprimante parallele
:lp=/dev/lp0:\
# sd signifie spool directory - ou les donnees sont collectees
:sd=/usr/spool/lp/lpr0:
Il y a tellement de champs que nous ne pourrons tous les décrire ici. Nous verrons seulement les principaux. Tous les champs exceptés les noms d'imprimantes sont entourés de deux-points et repérés par un symbole de deux lettres suivi du signe égal. Ensuite est indiquée la valeur qui peut être numérique, booléenne ou chaîne de caractères~:
champ type signification
lp string designe le peripherique d'impression
sd string designe le repertoire de spool
lf string designe le fichier de rapport d'erreurs
if string specifie le nom du filtre d'entree
rm string designe le nom d'un site d'impression distant
rp string designe le nom d'une imprimante distante
sh booleen indique s'il faut supprimer les en-tetes
sf booleen indique s'il faut supprimer les sauts de pages de fin de travaux
mx numerique indique la taille maximum d'un job (en blocs = 1Ko sous linux)
Si vous spécifiez /dev/null comme périphérique, tous les traitements se feront, mais tout partira à la poubelle. Ca semble ridicule, mais cela vous permet par exemple de tester une configuration. Lisez le chapitre Imprimantes qui ne sont pas de simples périphériques. Si vous désignez une imprimante distante avec rp et rm, lp doit contenir ":lp=:".
Ne laissez pas ce champ vide en cas d'impression locale, le démon signalerait une erreur.
Tout fichier spécifié ici doit exister, sinon le rapport d'erreurs ne se ferait pas.
Les filtres d'entrée sont des utilitaires transformant les données qu'il reçoivent sur leur entrée standard en un format particulier qu'il sortent sur leur sortie standard. Typiquement, la conversion texte - PostScript déjà mentionnée. Voir Ecrire des filtres.
Si vous spécifiez un filtre d'entrée, le démon n'envoie pas directement les données au périphérique. Il exécute le filtre en dirigeant les donnés sur son entrée standard et en désignant le périphérique de sortie comme sortie standard. Voir Une entrée Printcap de test pour d'autres utilisations des filtres.
Envoyer des données à une imprimante rattachée à une machine distante est très simple~: il suffit de spécifier le nom de la machine avec rm et le nom de l'imprimante avec rp. S'assurer que l'entrée lp est vide. A noter que les données seront d'abord mises dans le spool local avant d'être transférées. Même si votre imprimante est distante, il faudra également un spool local. Tout filtre d'entrée sera bien entendu exécuté avant.
Les bannières concernent éventuellement les utilisations à plusieurs personnes. Elles identifient les jobs.
La suppression de ces bannières vous permet d'économiser du papier. Par contre la gestion des sauts de page sera plus intéressante, surtout si vous utilisez des traitements de textes qui formatent toujours des pages pleines. Dans ce cas, pas besoin de saut de page supplémentaire. Vous auriez sinon une page blanche en fin de chaque travail. Si vous utilisez des listings ou autres documents, ajouter un saut de page garantit que chaque travail commancera bien en début de page.
Ce champ permet de limiter la taille des données pour chaque job.
Le nombre à spécifier est en blocs de BUFSIZE (pardon, de 1
Ko sous Linux). La valeur 0 rend la taille illimitée, permettant la
soumission de travaux limitée à la taille du disque. Notez
que la limite concerne la taille des données mises en spool, et non
pas les données envoyées à l'imprimante physique. Si
la limite est dépassée, le fichier est tronqué avec
l'émission d'un message disant: lpr: <fichier>: copy file
is too large
.
Cela peut être intéressant pour des imprimantes physiques en mode texte, notamment si des utilisateurs ou des programmes créent accidentellement des données trop volumineuses.
Si vous manquez de mémoire de masse, pourquoi n'inventeriez-vous pas un filtre qui décompresse ce qu'il a à envoyer à l'imprimante. Vous soumettriez alors des données compressées.
Le shell-script suivant est un exemple de filtre très simple. Il ajoute ce qu'il reçoit à un fichier temporaire /tmp/testlp.out après avoir inséré une bannière. Dans le fichier printcap, nous spécifions ce filtre dans le champ if, puis utilisons le périphérique /dev/null. Il ne sera pas réellement utilisé, mais il faut spécifier quelque chose, sinon le démon émettrait une erreur.
# Ce fichier pourra etre place dans le repertoire de spool
# et nomme filtre_entree. Il devra appartenir a root
# et au groupe daemon, et etre executable par tout le monde.
echo ------------------------------------- >> /tmp/testlp.out
date >> /tmp/testlp.out
echo ------------------------------------- >> /tmp/testlp.out
cat >> /tmp/testlp.out
Voici l'entrée du fichier printcap. Notez la lisibilité (toute relative) et l'utilisation de caractères de continuation~:
lpr0|lpr0: \
:lp=/dev/null: \
:sd=/usr/spool/lp/lpr0: \
:lf=/usr/spool/lp/lpr0/errs: \
:if=/usr/spool/lp/lpr0/filtre_entree: \
:mx#0: \
:sh: \
:sf:
Mettre tout ce qui est ci-dessus ensemble~! Voici un guide de configuration étape par étape pour une imprimante nommée /dev/lp0. Vous pouvez l'étendre à votre guise. Pour faire ce qui suit, vous devez être root. (NDT~: L'auteur a tout installé dans /usr/spool/lpd. J'ai préféré modifier légèrement cette configuration en définissant /usr/spool/lp/lpr0 et /usr/spool/lpd, comme dans la plupart des distributions)
mkdir /usr/spool/lp /usr/spool/lp/lpr0
chowm root.lp /usr/spool/lp /usr/spool/lp/lpr0
chmod ug=rwx,o=rx /usr/spool/lp /usr/spool/lp/lpr0
mkdir /usr/spool/lpd
chowm root.lp /usr/spool/lpd
chmod ug=rwx,o=rx /usr/spool/lpd
cd /usr/spool/lp/lpr0
touch .seq errs status lock
chown root.lp .seq errs status lock
chmod ug=rw,o=r errs status
chmod u=rw,go=r lock
chmod u=rw,g=r,o=x .seq
cd /usr/spool/lpd
touch .seq errs status lock
chown root.lp .seq errs status lock
chmod ug=rw,o=r errs status
chmod u=rw,go=r lock
chmod u=rw,g=r,o=x .seq
cd /usr/spool/lp/lpr0
chmod ug=rwx,o=rx filtre_entree
-rw-r--r--
.
ls -l | lpr -Plpr0
ls -l | lpr -Plpr0
Pour que des machines distantes puissent utiliser l'imprimante attachée à votre machine, le nom de ces machines doit être référencé soit dans le fichier /etc/hosts.lpd, soit dans le fichier /etc/hosts.equiv. Ce sont des fichiers textes normaux, dans lesquels on indique un nom de machine par ligne.
Il est préférable de déclarer les machines dans /etc/hosts.lpd spécialement réservé à l'impression, le fichier /etc/hosts.equiv donnant des droits plus étendus.
Vous pouvez restreindre les droits d'accès distants par groupe ou par utilisateur. Les groupes autorisés sont indiqués grâce au paramètre :rg=: du fichier printcap~; :rg=admin: restreint l'utilisation aux utilisateurs du groupe admin. Le paramètre booléen :rs=: du même fichier restreint l'accès aux utilisateurs ayant un compte sur votre machine.
Si tout ce que vous avez fait ci-dessus fonctionne, vous devez avoir deux imprimantes déclarées, l'une, testlp, ajoutant les données reçues au fichier /tmp/testlp.out, l'autre lpr0, imprimant sans modification sur le périphérique physique attaché à /dev/lp0. Les deux partagent le même spool. A titre d'exercice, amusez-vous à définir un spool différent pour testlp.
Si votre imprimante est PostScript, elle peut ne pas être
capable de traiter du texte pur. Si tel est le cas, vous devrez mettre en
place un filtre pour transformer le texte en PostScript. Un excellent
freeware
Vous pouvez également définir dans vos fichiers de login (.profile, par exemple) ou celui par défaut, une variable d'environnement PRINTER définissant l'imprimante à utiliser. Exemple~:
export PRINTER=lpr0
Ceci évite d'avoir à spécifier -Plpr0 à chaque fois.
Il est possible de "réutiliser" une entrée printcap. Si vous déclarez votre propre machine comme machine hôte distante, et une autre imprimante comme imprimante distante, vous pouvez rediriger les données à imprimer de l'une vers l'autre. Souvenez-vous que si vous utilisez cette technique, les données passeront par chaque filtre de la chaîne et seront mises successivement dans chaque spool.
Bien que vous puissiez spécifier pour une imprimante autant d'alias que vous le souhaitez, il semble que pour la meilleure utilisation, les deux premiers doivent être identiques et doivent correspondre au nom réel. Certains programmes n'utiliseront que ces deux entrées. La commande lpc indiquera seulement le premier alias, alors que les commandes lpr, lprm et lpq comprennent tous les alias.
Plutôt que de spécifier une taille maximum de fichier pour l'impression, vous préfereriez sans doute que les fichiers du spool ne puissent remplir votre disque, même temporairement. Pour ce faire, créez un fichier appelé minfree dans chaque répertoire de spool, contenant, sous forme d'un nombre de blocs (1 Ko pour Linux), la quantité minimum d'espace disque devant rester pour que les données puissent être acceptées dans le spool. Vous créerez un fichier réel dans le répertoire principal de spool et, dans chaque sous-répertoire, un lien symbolique vers ce fichier.
Vous avez un message indiquant: lpd: connect: No
such file or directory
Le démon lpd ne tourne pas. Vous avez peut-être oublié de l'inclure dans rc.local ou rc.multi. Ou n'avez vous tout simplement pas rebooté. Eventuellement lancez le à la main en étant root.
Vous obtenez un message~: Job queued, but cannot
start daemon
Ceci apparaît en général après le message précédent~!
Vous avez un message indiquant~: lpd: cannot create
<spooldir>/.seq.
Vous n'avez pas créé (ou pas correctement) le répertoire de spool défini dans /etc/printcap. Peut-être n'avez vous plus d'espace disque disponible~?
Vous avez un message indiquant~: lpr: Printer queue
is disabled
Sous root utilisez lpc enable
<NOM_IMPRIMANTE>
pour valider l'imprimante. Notez que en tant que
root, vous pouvez soumettre des travaux, l'imprimante étant
invalidée.
Vous soumettez un travail, aucun message d'erreur n'est enregistré, mais rien ne sort.
Plusieurs raisons. L'imprimante est éteinte,
mal connectée ou mal sélectionnée~! Utilisez
lpq
pour vérifier que l'entrée est dans la file. Si
c'est le cas, le périphérique peut être occupé,
l'imprimante pas prête ou en erreur. Regardez dans le fichier
d'erreurs référencé dans /etc/printcap pour
avoir des indices. Utilisez lpc status
pour voir si l'imprimante est
prête, et lancez lpc up <NOM_IMPRIMANTE>
si ce n'est pas
le cas.
Si après tout cela, rien ne sort, vérifiez que les filtres
existent bien, dans les bons répertoires, avec les bons droits. Si
vous utilisez syslogd, vous pouvez regarder les messages
enregistrés concernant lpd. Si une entrée indique cannot
execv <name of input filter>
, c'est certainement ce problème.
Une autre possibilité est que votre imprimante est PostScript et que vous lui envoyez autre chose que du PostScript. Certaines imprimantes ignorent les données qui ne sont pas PostScript. Installez un filtre approprié.
Enfin, (et si c'est cela, je sens un certain état fébrile~!) vérifiez que votre filtre sort bien quelque chose sur la sortie standard, et qu'il n'est pas relié à /dev/null.
Lorsque vous imprimez à distance, vos travaux vont bien dans la file distante, mais ils ne sortent pas.
Si vous pouvez, regardez l'entrée de l'imprimante distante dans /etc/printcap de la machine distante. Il se peut que vous n'ayez pas l'autorisation. Regardez le champ :rg=:, qui restreint aux membres d'un groupe et :rs=: qui limite l'accès aux utilisateurs connus de la machine distante. Eventuellement l'imprimante a été invalidée par l'administrateur de la machine distante. Voir aussi: Utiliser lpr en réseau.
La plupart des systèmes Unix possèdent le démon d'impression lpd (et la variante System V: lp) accompagné des commandes déjà décrites et utilisant éventuellement des filtres. Il est à noter que la méthode de spool et de traitement par filtre est une chose bien adaptée aux imprimantes modernes, les imprimantes "ligne" tendant à disparaitre. (Note subliminale~:-) trouvez et lisez les pages de manuel concernant lpr, lpc, lpq, lpd et lprm).
Le gestionnaire d'impression est disponible à différents endroits. En général un ensemble est livré avec chaque distribution~: slackware livre lpr.tgz dans le disque a3. TAMU également, soit binaires, soit sources (lpd-5.12.tar.gz). On peut trouver des sources sur tsx-11 dans sources/usr.bin.
NDT: L'auteur semble dire que les distributions contiennent des versions assez "légères", et qu'il serait bien de les mettres à jour. Laissons-lui ses mots qui datent peut être un peu. Je pense personnellement que les versions livrées, soit avec la slackware, soit avec des distributions comme yggdrasil sont très correctes.
Les fans de System V pourrons opter pour l'ensemble plp dont ce document ne parlera pas).
Si vous possédez une version assez ancienne du noyau et éventuellement des outils réseau, pensez à mettre à jour votre système pour éviter des instabilités.
Pensez également à mettre à jour le fichier /etc/printcap pour configurer lpd et utiliser votre imprimante. Configurer lpd pour une impression PostScript n'est pas très difficile~; écrivez un filtre comme indiqué au paragraphe Ecrire des filtres.
Configurer lpd correctement en vaut vraiment l'effort que cela nécessite, sauf si vous n'imprimez quasiment rien~!
Ghostscript 2.6.x est livré avec un shell-script assez compliqué permettant de générer les entrées du fichier /etc/printcap adapté à la gestion de plusieurs files pour une imprimante. Je n'ai pas pu le tester, mais je pense que cela fonctionne. Si vous travaillez dans un environnement assez vaste avec de multiple machines, je pense que cela vaut le coup d'y prêter attention.
Les différences qui existent entrent les nombreuses distributions font que l'on ne peut ici être exhaustif. Je pense que beaucoup de gens utilisent maintenant les distributions type slackware et on peut raisonnablement s'appuyer sur cet exemple.
Pensez à inclure lpd dans le fichier rc.local après le démarrage éventuel de syslogd. Voici les fichiers tels que l'on peut les trouver:
-r-sr-xr-x 1 root lp 9308 Aug 23 21:45 /usr/bin/lpq*
-r-sr-xr-x 1 root lp 10056 Aug 23 21:45 /usr/bin/lpr*
-r-sr-xr-x 1 root lp 8900 Aug 23 21:45 /usr/bin/lprm*
-r-x------ 1 root lp 1596 Aug 23 21:45 /usr/bin/lptest*
-r-xr-sr-x 1 root lp 17160 Aug 23 21:45 /usr/sbin/lpc*
-rwxr--r-- 1 root lp 34072 Aug 23 21:45 /usr/sbin/lpd*
et pour chaque répertoire de spool~:
/usr/spool/lp/lpr0/
total 5
drwxr-xr-x 2 root lp 1024 Feb 12 15:15 ./
drwxr-xr-x 3 root lp 1024 Sep 2 1993 ../
-rw-r----x 1 root lp 4 Feb 12 15:15 .seq
-rw-r--r-- 1 root lp 3 Feb 13 20:46 lock
-rw-rw-r-- 1 root root 27 Feb 12 15:15 status
Ces trois fichiers sont créés par lpr et lpd. Ils peuvent être absents si vous ne les avez encore jamais lancés. Avec d'anciennes versions il fallait exécuter touch sur ces fichiers ou bien modifier leurs droits. Les bugs concernant ces fichiers ont maintenant été corrigés dans les versions récentes.
Il est à noter également que le groupe d'appartenance était daemon avec d'anciennes versions, et est maintenant lp.
Ne soyez pas surpris de trouver des choses légèrement différentes sur votre système. D'un autre côté, si quelque chose ne fonctionne pas, pensez à soupçonner ces droits avant d'affoler nos boîtes aux lettres (Si vous saviez le nombre de courriers électroniques reçus et basés sur ces problèmes~!).
On peut trouver le programme lpr avec ou sans le bit setuid(root). En fait ce n'est pas si évident que cela. Tout dépend des droits et permissions des répertoires de spool. Autant que je sache, il y a une totale sécurité avec lpr, même si il est setuid(root). Donc, à la limite, positionnez le bit pour ne pas vous soucier des droits d'accès au répertoire de spool.
Vous êtes libre de mettre les binaires dans les répertoires que vous voulez, bien qu'ils se trouvent couramment dans /usr/bin ou /usr/sbin. (lpc et lpd peuvent se trouver par exemple dans /etc). Certaines commandes étant intéressantes pour tout utilisateur, il est bon de les laisser aux endroits habituels.
Attention toutefois, car les gens qui conçoivent les distributions, sont également libres de choisir. Pensez à supprimer les anciennes versions, si vous changez de distribution.
L'emplacement du fichier de verrouillage principal du démon lpd (lpd.lock), est fixé en dur dans le code. Il se trouve dans /var/spool/lpd/lpd.lock. Donc, vous devrez prévoir un répertoire /var/spool/lpd même si votre répertoire de spool est différent. Les binaires anciens mettaient ce fichier dans /var/spool/lpd.lock
Typiquement, chez moi, on trouve
/var/spool/lpd/
drwxr-xr-x 4 root lp 1024 Aug 18 1994 ./
drwxr-xr-x 18 root root 1024 Aug 17 1994 ../
-rw-r--r-- 1 root root 3 Feb 14 20:12 lpd.lock
/var/spool/lp/lpr0
drwxr-xr-x 2 root lp 1024 Feb 12 15:15 ./
drwxr-xr-x 3 root lp 1024 Sep 2 1993 ../
-rw-r----x 1 root lp 4 Feb 12 15:15 .seq*
-rw-r--r-- 1 root root 3 Feb 14 20:12 lock
-rw-rw-r-- 1 root root 27 Feb 12 15:15 status
Etant donné que l'on jongle en permanence entre /usr et /var, il est clair qu'un lien doit exister entre les deux. Soit vous définissez vos répertoires dans /usr/spool/... et définissez le lien /var vers /usr, soit vous mettez tout sous /var/spool/lpd... et définissez le lien /usr/spool vers /var/spool.
Si vous avez, comme moi une partition root (/) et une partition /usr, les deux cas ne sont pas identiques. Dans le premier, vos fichiers seront stockés dans la partition de root, /var etant créé sous /, dans l'autre, ce sera dans la partition /usr, puisque /usr est monté. Vous pouvez aussi avoir un système de fichiers /var réservé.
Le fichier de configuration principal est /etc/printcap. Il existe aussi, pour l'impression distante, les fichiers /etc/hosts.allow et /etc/hosts.lpd.
Désormais, le répertoire /etc est le répertoire où sont situés les fichiers de configuration. Vous pouvez choisir de les mettre ailleurs, mais définissez toujours un lien symbolique de /etc vers vos fichiers. Si votre système comporte des binaires qui vont toujours chercher leur configuration dans /usr/etc ou /etc/inet, ils sont sûrement très anciens et vous gagneriez à mettre votre système à jour.
Si votre commande ps favorite~: ps -a
, ne vous
révèle pas de démon, soit vous ne l'avez pas
lancé, soit il est mort. Il se peut qu'il n'ait pas pu créer
le fichier de verrouillage. Il se peut également qu'il n'ait pas eu
accès au fichier /etc/services, qui décrit les ports
réservés (ce qui peut arriver si tous vos systèmes de
fichiers ne sont pas montés).
Si la commande lpr ne fonctionne que pour root, il y a sûrement un problème de droits.
Si la seule chose que vous pouvez faire pour imprimer est d'utiliser la redirection vers le périphérique (/dev/...), c'est que celui déclaré dans votre fichier /etc/printcap n'est pas le bon. Voir~: Noms de périphériques d'imprimantes. Vous pouvez effectuer des paramétrages avec tunelp. Voir~: Matériels et pilotes.
Si l'un des messages "Job queued, but cannot start daemon
" ou
"lpc: connect: No such file or directory
" apparaît alors que le
démon tourne, c'est peut-être qu'il y a un problème de
connexion socket. ("start", dans ce contexte, signifie
réveiller.) Vérifiez que vous avez compilé un noyau
avec les sockets.
NDT: L'auteur semble dire qu'il y a ici des interactions entre des problèmes réseaux et les sockets (non réseaux) du monde Unix. Non seulement je doute de ce genre d'interaction (mais là le débat est ouvert~...) mais en plus certains gestionnaires d'impression (tels que PLP de l'Université du Minnesota) n'utilisent quasiment plus que les sockets INET).
De toute façon, même sur une configuration isolée, vous devrez inclure les commandes suivantes à votre configuration~:
ifconfig lo localhost
route add localhost
Cette question est malheureusement sans objet. Veuillez ne pas encombrer les boîtes aux lettres et Usenet avec ces questions. Jetez un oeil à la syntaxe du fichier. Il est très facile d'en écrire un. Voir le paragraphe suivant.
Bien qu'apparemment similaires, les fichiers /etc/termcap et /etc/printcap sont très différents. Alors que /etc/termcap contient les caractéristiques de terminaux (séquences d'échappement), printcap contient, lui, des informations liées à l'environnement de votre imprimante pour qu'elle fonctionne (répertoire de spool, taille réservée, nom du périphérique, fichier d'erreurs, ...). En aucun cas il ne contiendra les séquences d'échappement nécessaires à son fonctionnement. Ce rôle est affecté aux filtres. On indiquera seulement, dans le fichier printcap, l'endroit où se trouvent ces filtres.
Vous pouvez lire la documentation sur termcap(5) si vous la possédez.
Comme vous auriez pu le deviner, les lignes commençant par \# sont des commentaires.
Chaque imprimante utilisable avec la commande lpr doit correspondre à une entrée (ligne logique) dans /etc/printcap. Pour des raisons de lisibilité, une ligne logique peut être découpée en plusieurs lignes physiques pourvu qu'elles se terminent par le caractère `\' (anti-slash).
Chaque ligne logique à la syntaxe suivante~:
NOM1|NOM2|NOM3:CAPACITE_CHAINE=VALEUR_CHAINE:\
:CAPACITE_NUMERIQUE#VALEUR_NUMERIQUE:CAPACITE_BOOLEENNE:
Les espaces en début de deuxième ligne ne sont utilisées que pour la lisibilité.
Une imprimante peut avoir autant de noms (alias) que vous le souhaitez et traditionnellement le dernier nom correspond à une description plus étendue mais rarement utilisée. Vous pouvez très bien ensuite entrer la commande suivante~:
lpr -P"imprimante laser situee en salle 213"
Un des noms de votre imprimante par défaut doit être lp.
Le terme capacité provient de l'héritage de termcap~: il est plus juste de parler ici de paramètre ou attribut.
Note de Ross Biro~:
Les capacités de 3 caractères ne fonctionnent pas correctement, ce qui explique pourquoi le port série n'était pas bien géré avec les anciens binaires.
Les paramètres de type chaîne sont délimités par le signe = entre leur nom et la chaîne. Les paramètres numériques sont délimités par le symbole \# (le symbole = est accepté). Les paramètres booléens sont vrais s'ils apparaissent et faux sinon.
Les caractères spéciaux dans une chaîne peuvent être exprimés à l'aide de séquences d'échappement précédées d'un anti-slash comme en langage C~; De plus \E correspond à Escape (ESC). `ˆ' sert aussi pour les caractères d'échappement. `ˆ' suivi d'un caractère (CHAR) permet de coder Control-CHAR. Donc `ˆa' définit control-a, de la même manière que \001. `\' et `ˆ' eux-même doivent être définis respectivement par `\\' et `\ˆ'. `\:' définit `:' mais il semble préférable d'utiliser `\072'. Le code source met en garde sur l'utilisation de ce codage.
Exemple:
lp|bam|Epson FX-80:lp=/dev/lp1:sd=/usr/spool/lp1:sh=mx#0: \
:df=/usr/local/lib/magic-filter/lp.df: \
:if=/usr/local/lib/magic-filter/lp.if:
Le nom de l'imprimante par défaut est lp. Elle est aussi conue sous les noms bam et Epson FX-80.
L'imprimante est sur /dev/lp1 (AT-bus LPT1:). Pas de rupture de
page, pas de taille limite de fichier. Les fichiers imprimés par la
commande lpr -d
sont passés par le filtre
/usr/local/lib/magic-filter/lp.df et ceux imprimés par la
commande lpr
passent par le filtre
/usr/local/lib/magic-filter/lp.if.
Voir aussi le chapitre suivant.
Deux fichiers /etc/printcap peuvent sembler identiques et pourtant l'un va
fonctionner et pas l'autre. La commande lpc stat
permet d'avoir des
informations sur vos imprimantes. Si lpc stat indique qu'une imprimante
s'appelle `:', vous avez peut-être oublié une anti-slash en fin
de ligne. Des blancs après l'anti-slash annule son effet et la
ligne suivante ne sera pas prise en compte en tant que suite de la
même ligne logique.
Cette question ne devrait pas se poser, et pourtant~! On peut répondre ceci: "lp:sh", ce qui fait 6 caractères avec la fin de ligne. Vous devez créer un lien de /dev/lp vers votre périphérique et créer un répertoire de spool /usr/spool/lpd. Vous pensez peut-être, si vous ne voulez pas de bannière, pouvoir enlever ":sh". Malheureusement la syntaxe nécessite au moins une capacité par entrée.
Le système Unix, contrairement à DOS termine chaque ligne
d'un fichier avec un caractère avance de ligne
(linefeed
#!/bin/sh
if [ "$1" = -c ]; then
cat
else
sed -e s/$/^M/
fi
# echo -ne suppose que /bin/sh correspond a bash
echo -ne \\f
Notez que `ˆM' symbolise le caractère retour-chariot et non pas un
`ˆ' suivi d'un M. Dans emacs, pour saisir ce caractère, entrez la
séquence C-q~C-m
, alors que sous vi, entrez
C-v~C-m
. Le test de $1 permet d'invalider l'insertion du
retour-chariot par la commande lpr~-l
Déclarez ce filtre dans /etc/printcap, avec le paramètre
if~: :if=/usr/lib/lpf:
.
Il se peut aussi que votre imprimante puisse passer dans un mode permettant
l'ajout de retour-chariots grâce à une séquence
d'échappement. Voici un exemple de filtre utilisant la commande
echo -ne
pour envoyer cette séquence~:
#!/bin/sh
# Filtre pour imprimantes HP, permettant de traiter LF comme CRLF
# La commande echo -ne suppose que /bin/sh correspond a bash
echo -ne \\033&k2G
cat
echo -ne \\f
Vous pouvez confier cette tâche soit à votre filtre, soit au paramètre tr du fichier printcap. Pour avoir les détails sur le format de ce paramètre, consultez le chapitre sur La syntaxe du fichier /etc/printcap. Vous pouvez rencontrer des problèmes si l'impression se plante en plein milieu d'un séquence d'échappement. Essayer de mettre plusiers caractères `ˆ@' au début de la chaîne (ceci risque fort de ne pas suffire lors d'impression de graphiques).
Si le paramètre `if' n'est pas présent dans le fichier
printcap, lpd ajoutera systématiquement un saut de page
à la fin de chaque fichier. Si vous utilisez un filtre, c'est
à lui de mettre ou non un saut de page. Pour complètement
supprimer les sauts de page si vous n'avez pas de paramètre if,
mettez le paramètre :ff=:
dans /etc/printcap. Mais
notez que ceci supprimera également les sauts qui seront faits
lorsque un filtre meurt (arrêt d'impression). Si vous
désirez des sauts de pages après impression sauf celles
soumises avec la commande lpr -l
, vous pouvez créer le filtre
suivant~:
#!/bin/sh
# La commande echo -ne suppose que /bin/sh correspond a bash
cat
if [ "$1" != -c ]; then
echo -ne \\f
fi
Si vous souhaitez un saut de page optionnel après lpr~-l
,
vous pouvez par exemple redéfinir l'utilisation du paramètre
-i de la commande lpr~:
#!/bin/sh
cat
# La commande lpr -i -l imprime tel quel et supprime les sauts de lignes
if [ "$1" != -c -o "$4" = -i0 ]; then
# echo -ne suppose que /bin/sh correspond a bash
echo -ne \\f
fi
En premier lieu, si votre version de lpd signale "ioctl(TIOCEXCL)", prenez un version plus récente n'émettant pas ce message (lpd-590p2).
Deux ensembles de paramètres sont à positionner dans le
fichier printcap, ainsi que la vitesse du port en bauds. Pour la vitesse
du port, la syntaxe est évidente. Exemple: br\#9600
.
Les autres paramètres à positionner correspondent à un ensemble de bits, que l'on pourra soit positionner (1), soit mettre à 0. Pour effacer des bits, on utilisera les paramètres fc\# et xc\#, pour les positionner, fs\# et xs\#.
Faites bien attention aux bits que vous sélectionnez. Mais au fait
que sont-ils~? Souvenez-vous..., la commande stty. Elle indique
de nombreux paramètres caractérisant un tty. La
commande stty~-a
affiche en clair les paramètres du tty,
certains d'entre-eux étant précédés d'un tiret
s'ils sont invalidés et sans tiret s'ils sont validés. Ce
sont ces paramètres (des drapeaux, des flags, donc des bits)
que l'on va manipuler.
# stty -a < /dev/ttyS2
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr
-igncr -icrnl ixon -ixoff -iuclc -ixany -imaxbel
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0
bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop
-echoprt -echoctl -echoke
Vous pouvez utiliser cette commande pour configurer le port de façon à obtenir une impression correcte. Par exemple, les différences que l'on peut noter entre le stty ci-dessus et l'initialisation du port au démarrage de ma machine réside dans les informations -clocal, -crtscts et ixon. (La configuration de votre port pourra très bien être différente selon la manière dont votre imprimante gère le contrôle de flux).
Lorsque vous avez configuré votre port correctement à l'aide
de cette commande, faites~: cat fichier > /dev/ttyS?
(?
est le numéro de votre port) pour imprimer un fichier.
Imprimez par exemple le fichier /usr/src/linux/include/linux/termios.h. Vous y découvrirez un tas de définitions de constantes et de structures. Nous allons voir quelles valeurs définies dans ce fichier vont nous servir pour configurer le port, non plus avec stty, mais avec les paramètres fc, xc, fs et xs du fichier printcap. Regardez la section commençant par~:
/* c_cflag bit meaning */
#define CBAUD 0010017
Elle décrit justement les bits manipulables à l'aide de fc\# et fs\# dont on parlait. On y voit les constantes des vitesses de modulation en baud, puis des lignes qui nous intéressent particulièrement~: ce sont les mêmes paramètres que dans la commande stty. Je sens que vous voyez où on veut en venir. Modifier un paramètres de stty, cela va consister à positionner ou effacer un bit dont la position est indiquée dans la constante.
Vous savez maintenant que les paramètres de stty sont des bits, et qui ont la valeur 0 lorsqu'il y a un tiret devant. Notez alors les bits à effacer (ce sera fait avec la paramètre fc\#) et ceux à positionner (paramètre fs\#). Exemple: `fc\#0177777' (Attention le paramètre fc semble surcharger le paramètre br\#, donc prenez garde à les positionner correctement).
Ensuite occupez-vous des bits à positionner. Par exemple s'il faut positionner les bits cs8, hupcl et cread, regardez les constantes CS8 (0000060), HUPCL (0002000) et CREAD (0000200). Pensez à la vitesse de modulation qu'il faut aussi définir, dans mon cas, ce sera B9600 (0000015). Tous ces bits ensemble font `0002275'. Indiquez cette valeur au paramètre fs\#.
Effectuez les même réglages avec la section suivante intitulée
/* c_lflag bits */
Dans mon cas je n'ai rien à positionner, j'ai donc simplement à fournir la valeur xc\#0157777, puis xs\#0. Une fois votre fichier correctement défini, essayez d'imprimer. Si quelque chose ne va pas, continuez à lire les paragraphes suivants.
Souvenez-vous de toujours commencer par les bits que vous souhaitez voir à 0 (fc\# et xc\#), puis de définir seulement après des bits à positionner (fs\# et xs\#).
La mise en place de lpd n'est pas traitée ici, mais sachez que si vous avez des problèmes avec la configuration du port série, vous pouvez empêcher lpd de le configurer en considérant votre imprimante comme ne présentant pas une interface normale. Lisez également à ce propos le chapitre suivant.
mknod~/dev/null1~c~1~3
).
N'utilisez pas /dev/null, pour ne pas qu'il soit ouvert de manière
exclusive.
Enlevez les paramètres de vitesse et de positionnement des bits du
fichier printcap.
#!/bin/sh
echo if: $* >> /var/spool/lpd/results
# /dev/lp est un lien vers /dev/ttyS2 auquel est reliee l'imprimante
exec votre_vieux_filtre $* > /dev/lp
...ou si vous n'avez pas de paramètre `if' configuré...
#!/bin/sh
echo if: $* >> /var/spool/lpd/results
cat > /dev/lp
# la commande ``echo -ne'' suppose que /bin/sh correspond a bash
echo -en \\f > /dev/lp
Donnez-lui les droits de lecture/écriture pour tout le
monde. Essayez-le~: /usr/lib/lpd/if~<FICHIER
.
:if=/usr/lib/lpd/if:
'.
Supposons donc que la méthode précédente a
fonctionné, et que vous pensez avoir correctement configuré
votre fichier printcap. Exécutez la commande
stty~-a~</dev/ttyS?
. Si certains paramètres
ne sont pas corrects, vérifiez les constantes du fichier
termios.h. Si la configuration est incorrecte, malgré tous vos
efforts de vérification, n'hésitez pas à installer un
démon récent.
Le patch qui suit (et vous verrez rapidement pourquoi il est nécessaire) est réservé aux anciennes versions de lpd. La version lpd-590p2 et ultérieures l'intègrent déjà.
Lorsque j'ai inséré le mien, j'ai effectué les essais suivants:
lprm TOUT # assurez-vous que la file est vide, que le demon tourne
stty PARAMETRE < /dev/ttyS2
lpr JUSTE_UN_PETIT_TRUC
stty -a < /dev/ttyS2
réglage des bits
lprm TOUT # la file doit être à nouveau vide.
Voici le patch (il est inversé et il faut l'appliquer avec `-R' ou plutôt à la main~!)
-------------------------------Cut Here-------------------------------------
*** lpd-590/lpd/printjob.c Thu Jul 8 20:56:59 1993
--- lpd-590/lpd/printjob.c~ Sat Feb 27 09:07:01 1993
***************
*** 1271,1277 ****
}
#ifdef LINUX
ttybuf.c_cflag &= ~FC; /* not quite right! */
! ttybuf.c_cflag |= FS; /* not quite right! */
#else
ttybuf.sg_flags &= ~FC;
ttybuf.sg_flags |= FS;
--- 1271,1277 ----
}
#ifdef LINUX
ttybuf.c_cflag &= ~FC; /* not quite right! */
! ttybuf.c_cflag |= ~FS; /* not quite right! */
#else
ttybuf.sg_flags &= ~FC;
ttybuf.sg_flags |= FS;
-------------------------------Cut Here-------------------------------------
Cut Here~: Coupez ici.\\ not quite right!~: Pas tout à fait ça~!
Qu'est-ce qu'une telle imprimante~? Imaginez une imprimante distante à laquelle vous ne pouvez accéder que par courrier électronique~!
Pour utiliser ce genre d'imprimante avec lpr, le paramètre `lp'
du fichier printcap doit définir un périphérique de
type /dev/null (disons /dev/null1: mknod /dev/null1 c
1 3
), mais pas /dev/null puisque lpd ouvre le
périphérique en accès exclusif. Un filtre devra donc
encoder les données (uuencode) et envoyer un courrier (mail)
dont le contenu correspond à ce qu'il émet sur la sortie
standard.
Plus difficile est le cas ou vous avez déjà défini un filtre avec le paramètre `if' ou `of' pour une imprimante spéciale. Dans ce cas ce filtre existant doit diriger sa sortie vers le nouveau filtre. Le filtre `if' doit être appelé avec le paramètre -c pour minimiser les modifications de données.
Quelqu'un m'a dit avoir déjà essayé une telle manipulation avec un réseau Novell NetWare et l'outil d'envoi de mails "Charon".
Pour une imprimante classique (texte, non PostScript), et pour une bannière simple, enlevez simplement le paramètre `sh' du fichier printcap.
Si vous optez pour une bannière, positionnez aussi le paramètre `tr' pour figer la fonte utilisée pour la bannière et éviter des bannières fantaisistes dépendantes de la dernière fonte utilisée.
Si vous souhaitez définir votre banière (avec une imprimante PostScript par exemple), laissez le paramètre `sh' et faites imprimer la bannière à votre filtre. Consultez la documentation sur printcap (man printcap). Si vous utilisez les filtres magiques de <B.A.McCauley@bham.ac.uk> (magic-filters-0.4), appelez le code permettant d'imprimer les bannières.
Vous aurez besoin d'un filtre basé sur un programme qui convertit l'Ascii en PostScript. Le plus connu d'entre-eux est enscript, mais il est aussi le plus dur à trouver (et pas gratuit). D'autres tels que a2ps, nenscript, mpage pourront faire l'affaire. Voir Imprimer du texte via PostScript.
C'est sûrement parce que vous avez limité la taille des fichiers imprimables à une valeur trop petite. Mettez `mx\#0' dans votre fichier printcap.
Pour que lpr -i
fonctionne, vous devez avoir un filtre `if' qui
implémente son fonctionnement. Le paramètre `-i' est
simplement passé au filtre par lpd. Le filtre appelé
lpf livré avec lpd supporte cette caractéristique, mais
ne peut être utilisé qu'avec du texte. Si vous souhaitez
utiliser cet outil et effectuer en plus certaines initialisations,
écrivez un script comme le suivant~:
#!/bin/sh
# Ici, mes diverses initialisations
exec /usr/lib/lpf $*
Mieux, votre filtre peut envoyer à l'imprimante la séquence de définition de marge gauche~:
#!/usr/bin/perl
# Cet exemple est ecrit en perl pour changer, car convertir
# les nombres en chaine est plus dur en langage 'shell'
for ($i=0; !($_ = $ARGV[$i]) || !/^-i([0-9])+/; $i++) {}
print pack("cAc",27,"l",$1);
while (<STDIN>) { print; }
Essentiellement parce que vous avez une version trop ancienne du
gestionnaire d'impression
Il est également possible que le programme pr ne soit pas à l'endroit ou lpd va le chercher (et ce n'est pas paramétrable). Déplacez-le ou définissez un lien (normalement~: /usr/bin/pr).
Le démon lpd tourne tout le temps. Il crée un fils pour
chaque imprimante à gérer, selon la configuration
décrite dans printcap. La santé du démon n'est pas
explicitement rapportée par lpc néanmoins, l'absence d'erreur
indique un fonctionnement correct. Voir le chapitre~: Le
démon ne fonctionne pas. La commande lpc~stat
signalera
"no daemon present
" (pas de démon) pour chaque file
d'impression pour laquelle il n'y a pas d'impression en cours~: c'est
normal. Si la file a été invalidée ou si elle est
vide, il n'y a pas d'erreur. lpq, quant à lui est un peu plus
alarmiste, puisqu'il indique "Warning: no daemon present
". Si la
file n'est pas vide, n'a pas été stoppée et que le
démon est absent, il y a probablement une erreur dans un filtre.
Corrigez-le et relancez le démon à l'aide de la
commande~: lpd~up~NOM_DE_FILE
.
Il se peut également que lpc essaie de tuer un démon absent lorsque vous voulez arrêter une imprimante. Ceci conduit à des messages d'erreurs gênant mais sans gravité. Ils sont rares à partir de la version lpd-590p2.
Pour imprimer sur l'imprimante nommée lpdist sur la machine dist.net.fr à partir de la machine moi.net.fr, mettez une entrée dans /etc/printcap ressemblant à la suivante~:
lpdist:lp=:rm=dist.net.fr:rp=lpdist:sd=/usr/lpd/spool/dist:
et, bien sûr, créez le répertoire /usr/spool/lpd/dist
Aucun filtre n'est spécifié puisque ce seront ceux de la machine distante qui seront utilisés.
Sur la machine distante dist.net.fr, vous devrez notifier la machine locale moi.net.fr soit dans /etc/hosts.equiv, soit dans /etc/hosts.lpd, plus spécifiquement réservé à l'impression.
Les machines décrites dans /etc/hosts.* doivent avoir des
noms ou des numéros sous forme canonique, puisque lpd va chercher
les noms à partir des adresses IP (DNS inverse). Si vous
n'êtes pas sûr des noms, listez les noms déjà
connus pour une machine. L'utilitaire dig réalise très
bien cela. dig~-x~A.B.C.D
donne les noms canoniques de la
machine dont l'adresse IP est A.B.C.D.
Si le serveur d'impression n'est pas de type BSD, il sera possible de le faire fonctionner mais les fichiers d'autorisation pourront avoir un format différent. Chris Nystrom <chrisn@medianet.com> a trouvé qu'il fallait qu'il crée le fichier /usr/spool/lp/admins/lp/Systems sur la machine distante, indiquant son nom de machine linux. Nous ne savons pas si cela est spécifique à System V ou à dynix/ptx 2.0.3 qu'il utilise.
Si vous ne pouvez pas imprimer à distance, utilisez les commandes d'exécution à distance~:
rsh dist.net.fr "lp -dlp" < FICHIER
Cet exemple correspond à un système d'impression à distance System V sur la machine dist.net.fr.
Dans la terminologie Unix standard un filtre est un simple programme (donc avec les droits d'exécution) qui lit les données sur son entrée standard et sort le résultat sur sa sortie standard.
Les filtres lpd correspondent tout à fait à cette définition puisqu'ils lisent sur stdin et écrivent sur stdout. Leurs particularités résident dans le fait qu'ils supposent que leur entrée standard est un fichier à accès aléatoire, et donc qu'il peuvent faire des positionnements à l'aide d'opérations lseek().
Tous les filtres lpd ont une syntaxe d'appel commune (et souvent ne nécessitent pas de paramètres). La documentation de printcap détaille un peu comment passer des paramètres.
Si vous souhaitez écrire un filtre sous forme de shell-script,
celui-ci doit commencer par \#!/bin/sh
. Un filtre très
classique pour l'interprétation PostScript est le suivant~:
#!/bin/sh
/PATH/.../gs -q -dSAFER -dNOPAUSE -r??? -sDEVICE=????? -sOutputFile=- -
Le paramètre -dSAFER tente d'éviter des problèmes d'interprétation PostScript. Les paramètres -q et -dNOPAUSE permet de supprimer la pause qui est normalement insérée entre chaque page (notamment lors d'une visualisation à l'écran). Indiquez dans printcap le chemin d'accès complet à votre filtre pour l'un des paramètres de type filtre (sauf pour of~!). Je vous conseille d'ailleurs de placer vos filtres dans /usr/lib/lpd. Vous pouvez également les placer dans le répertoire de spool, mais ceci va un peu à l'encontre de la règle qui veut que l'on sépare données et programmes.
Voici par exemple mon filtre pour une Epson Stylus 800~:
#!/bin/sh
/usr/bin/gs -q -dSAFER -dNOPAUSE -sPAPERSIZE=a4 -sDEVICE=escp2 -sOutputFile=- -
D'autres outils sont décrits à divers endroits de ce document.
Il est beaucoup plus facile de tester et corriger un filtre si vous
l'exécutez à la main, plutôt que de l'insérer
tout de suite dans printcap. Vous devez alors rediriger les entrées
et sorties standard~:
mon_filtre~<FICHIER~>/dev/lp1
.
Une astuce que beaucoup de gens utilisent lors des tests, lorsque leur filtre nécessite des arguments, consiste à ajouter au début du filtre un ligne comme celle-ci~:
echo $* >> /tmp/filter-log
Si le filtre fonctionne pendant les tests et qu'il ne fonctionne plus une
fois appelé par lpd, c'est peut-être qu'il manque
#!/bin/sh
au début. Il se peut aussi que le démon ne
sache pas accéder à un répertoire, auquel cas vous
devrez inclure ce chemin dans le script. Enfin sachez que le filtre est
lancé par root ou daemon, et que tout programme qu'il
appelle doit être exécutable par tout le monde.
A ne jamais utiliser. Je veux dire par là que je souhaite que vous ne soyez pas dans une situation ou vous en aurez besoin. Au début de 1994, il y a eu un grand débat sur comp.os.linux.help à propos de ces filtres. Le paramètre `of' est utilisé par exemple lorsque la soumission d'un nouveau travail est pris en compte immédiatement pour l'impression, ce qui se traduit par la sortie du fichier avec un simple saut de page pour interrompre la sortie en cours. Ceci peut conduire à un résultat mauvais puisqu'il n'y a pas eu de réinitialisation de l'imprimante.
Une fois que vous avez choisi le programme qui vous convient pour la conversion de format, il faut très peu de temps pour écrire un filtre. De plus des filtres existent déjà dans certaines distributions. Il y a donc peu de demandes et pas de site ftp pour cela.
Si vous disposez déjà d'un programme pour imprimer ce que vous souhaitez, ce n'est vraiment pas un problème pour en faire un filtre. En général, un petit script suffit. Voir~: Ecrire des filtres. Si malheureusement votre programme ne sait lire que des fichiers passés en paramètres (donc pas sur l'entrée standard), lisez le chapitre suivant.
Les filtres en mode texte sont également très simples, sauf
si vous souhaitez pouvoir sélectionner des fontes, ce qui complique
un peu. Vous pourrez par exemple insérer une commande
echo~-ne
au début et à la fin du filtre pour
choisir une fonte.
Il est tout à fait possible d'écrire des filtres avec de tels programmes. Par exemple dvilj2p demande un nom de fichier (de plus avec l'extension .dvi). L'exemple ci-après vous montre comment vous en sortir~:
#!/bin/sh
ln -s /proc/self/fd/0 /tmp/$$.dvi
dvilj2p /tmp/$$
rm /tmp/$$.dvi
Note: Un lien symbolique est nécessaire ici parce que dvilj2p
ajoute lui même l'extension .dvi. Sinon vous pouvez donner au
programme directement /proc/self/fd/0. Il peut être
astucieux de créer un lien permanent~:
ln~-s~/proc/self/fd/0~/dev/stdin
. Si vous
êtes très attentifs aux problèmes de
sécurité, et ne permettez pas l'accès à
/proc, utilisez plutôt la méthode du fichier
temporaire.
Les gestionnaires d'impression ne reconnaissent basiquement qu'un nombre limité de types de fichiers. En fait, toutes les raisons sont bonnes pour utiliser un filtre. Ils peuvent être activables lorsque certains paramètres de lpr sont donnés. Par exemple lpr -v peut permettre d'imprimer un fichier GIF. L'option supplémentaire -d pouvant sélectionner une résolution inférieure. Sachez que les temps de traitement dûs aux filtres peuvent être assez long (attente entre deux jobs).
Si vous êtes en réseau, des filtres s'exécuteront aussi
sur le serveur d'impression. Une façon d'activer ou non certains
filtres, consiste à créer plusieurs entrées dans
printcap ciblant toutes la même imprimante physique, mais
définissant des paramètres `if' différents. Ceci
a l'avantage d'un paramétrage facile grâce à la
variable d'environnement PRINTER
pour choisir l'imprimante (je veux
dire l'entrée du fichier printcap), évitant de donner le
paramètre à chaque fois.
Une autre possibilité (et cela se fait de plus en plus) est d'utiliser des filtres magiques.
Les filtres magiques déduisent le type de données qu'ils ont en entrée d'un nombre magique caractérisant ce type. Ceci existe déjà pour certains fichiers Unix.
Les filtres magiques sont généralement des scripts écrits en perl, en shell ou en langage C qui identifient le fichier et appellent le bon programme (qui, lui, n'est pas magique). Brian (un des auteurs) possède un filtre magique assez générique écrit en bash, permettant de sélectionner le filtre selon le résultat de la commande file. Avec un filtre magique et 3 filtres normaux, vous pouvez lancer une impression comme celle-ci~:
lpr -d fichier1.dvi fichier2.div.Z fichier3.ps fichier4.texinfo.gz
(Pas besoin de configurer lpr pour des fichier texinfo)
De tels filtres magiques sont disponibles sur~:
tsx-11.mit.edu:/pub/linux/sources/usr.bin/magic-filter-0.4.tar.gz
apsfilter est un exemple de shell-script assez simple ne nécessitant aucun filtre supplémentaire et utile pour les imprimantes laser compatibles HP.
Les filtres magiques ne doivent pas être utilisés en sortie (paramètre `of') puisqu'ils ne sont appelés qu'une fois lorsque plusieurs fichiers sont envoyés à la suite (en une fois).
Remarque~: Mon opinion (Brian) est que les filtres d'entrée sont assez inélégants. Essayez par exemple d'imprimer un source PostScript ou nroff~! Mais je reconnais que les opinions sont partagées.
L'exemple suivant est un shell-script magique capable de traiter les données au format PostScript ou texte~:
#!/bin/sh
# Base sur un script envoye par Scott Doty et ecrit par Keith Walker
# Utilise le fait que lpd passe des parametres a `if'.
#
# <if> -w<width> -l<length> -i<ident> -n<user> -h<host> <fichier>
#
# pour imprimer un fichier a n'importe quelle taille. Ces options sont
# interessantes si vous vous faites votre propre banniere.
#
# `gs' reinitialisera l'imprimante. L'initialisation doit inclure la
# conversion des retour-chariot si besoin
printf "<initialisation imprimante pour impression texte (code echappement,
etc)>"
read premiere_ligne
deux_prem_caract=`expr $premiere_ligne : '\(..\)'`
if [ "$deux_prem_caract" = "%!" ]; then # c'est du PostScript
/usr/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=??????? -sOutputFile=- -
else # c'est du texte
echo -n $premiere_ligne
cat
printf "\014"
fi
A noter (pour les paranos de l'effraction logicielle) que certains scripts lancés par d'autres peuvent poser des problèmes de sécurité, mais ici ce n'est pas le cas avec les filtres pour lpd, car l'environnement de travail n'est pas sous le contrôle d'un pirate potentiel.
Chapitre suivant, Chapitre Précédent
Table des matières de ce chapitre, Table des matières générale
Début du document, Début de ce chapitre