---
title: Hoofdstuk 10. Afdrukken
part: Deel II. Algemene taken
prev: books/handbook/kernelconfig
next: books/handbook/linuxemu
showBookMenu: true
weight: 13
params:
  path: "/books/handbook/printing/"
---

[[printing]]
= Afdrukken
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 10
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/printing/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[printing-synopsis]]
== Overzicht

FreeBSD kan gebruikt worden om op een scala aan printers af te drukken, van de oudste matrixprinter tot de nieuwste laserprinters en alles er tussenin, waardoor op hoge kwaliteit afgedrukt kan worden vanuit de gebruikte programma's.

FreeBSD kan ook ingesteld worden als printserver in een netwerk. Dan kan FreeBSD afdrukopdrachten ontvangen van uiteenlopende computers, waaronder FreeBSD computers, Windows(R) en Mac OS(R) hosts. FreeBSD zorgt ervoor dat er één afdrukopdracht per keer wordt afgedrukt, houdt statistieken bij van gebruikers en computers die de meeste afdrukken maken, drukt "voorbladen" af, zodat duidelijk is van wie de afdruk is en nog veel meer.

Na het lezen van dit hoofdstuk weet de lezer:

* Hoe het FreeBSD afdrukwachtrijsysteem moet worden ingesteld;
* Hoe afdrukfilters kunnen worden geïnstalleerd, om bepaalde afdrukopdrachten op een andere manier af te handelen, zoals het omzetten van documenten naar formaten die een printer begrijpt;
* Hoe voorbladen kunnen worden afgedrukt;
* Hoe er op printers die op andere computers zijn aangesloten kan worden afgedrukt;
* Hoe er op printers die direct op het netwerk zijn aangesloten kan worden afgedrukt;
* Hoe afdrukbeperkingen kunnen worden opgelegd, zoals het beperken van de grootte van de afdrukopdracht, en bepaalde gebruikers verbieden af te drukken;
* Hoe afdrukstatistieken kunnen worden bijgehouden en het printergebruik in de gaten kan worden gehouden;
* Hoe problemen met afdrukken kunnen worden opgelost.

Aangeraden voorkennis:

* Hoe een nieuwe kernel wordt ingesteld, gebouwd en geïnstalleerd (crossref:kernelconfig[kernelconfig,De FreeBSD-kernel instellen]).

[[printing-intro-spooler]]
== Inleiding

Om printers onder FreeBSD te kunnen gebruiken moeten ze kunnen werken met het Berkeley lijnafdrukwachtrijsysteem, ook wel bekend als het wachtrijsysteem LPD of simpelweg LPD. Dit is het standaard afdruksysteem onder FreeBSD. Dit hoofdstuk introduceert LPD en begeleidt bij het instellen.

Als de gebruiker al bekend is met LPD of een ander afdrukwachtrijsysteem, dan kan verder worden lezen vanaf <<printing-intro-setup,Standaardinstallatie>>.

LPD regelt alles met betrekking tot de printer van een host. Het is verantwoordelijk voor een aantal zaken:

* Het regelt de toegang tot aangesloten printers en printers die op andere hosts op het netwerk zijn aangesloten;
* Het geeft gebruikers de mogelijkheid bestanden aan te bieden die afgedrukt moeten worden; deze aangeboden bestanden worden _afdrukopdrachten_ genoemd;
* Het voorkomt dat gebruikers tegelijkertijd een printer benaderen door een _wachtrij_ bij te houden voor elke printer;
* Het kan _voorbladen_ afdrukken (in het Engels ook wel bekend als _banner_, of _burst_ pagina's) zodat gebruikers hun afdruk tussen andere afdrukken makkelijk terug kunnen vinden;
* Het handelt de communicatie af voor printers die op een seriële poort zijn aangesloten;
* Het kan afdrukopdrachten over een netwerk versturen naar een LPD wachtrij op een andere host;
* Het kan speciale filters aanroepen die afdrukopdrachten converteren voor verschillende printertalen of afdrukmogelijkheden;
* Het houdt statistieken bij van het printergebruik.

Middels een instellingenbestand ([.filename]#/etc/printcap#) en door speciale filters beschikbaar te stellen, kan het LPD systeem alle, of enkele van bovenstaande taken uitvoeren op een grote verscheidenheid aan afdrukhardware.

[[printing-intro-why]]
=== Waarom het wachtrijsysteem gebruikt zou moeten worden

Het wachtrijsysteem biedt nog steeds voordelen op een systeem met een enkele gebruiker en dient gebruikt te worden omdat:

* LPD afdrukopdrachten in de achtergrond afhandelt. Dan is het niet nodig te wachten tot de gegevens naar de printer zijn verzonden;
* LPD op eenvoudige wijze een afdrukopdracht door een filter kan afdrukken om kopteksten met datum/tijd toe te voegen of een speciaal bestandsformaat (zoals een TeX DVI-bestand) om te zetten naar een formaat dat de printer begrijpt. Deze handelingen hoeven dan niet handmatig uitgevoerd te worden;
* Veel gratis en commerciële software met een afdrukfunctie verwacht dat er een wachtrijsysteem aanwezig is op een systeem om afdrukopdrachten naar te sturen. Door een wachtrijsysteem op te zetten, wordt toekomstig te installeren of reeds geïstalleerde software op eenvoudige wijze ondersteund.

[[printing-intro-setup]]
== Standaardinstallatie

Om printers met het LPD wachtrijsysteem te kunnen gebruiken, dienen zowel de printerhardware als de LPD software geïnstalleerd te worden. Dit document beschrijft deze installatie in twee stappen:

* In het onderdeel <<printing-simple,Eenvoudige printerinstallatie>> staat hoe een printer moet worden aangesloten, hoe LPD er mee kan communiceren en hoe tekstbestanden afgedrukt kunnen worden.
* In <<printing-advanced,Geavanceerde printerinstallatie>> staat beschreven hoe een scala aan bestandsformaten afgedrukt kan worden, hoe voorbladen kunnen worden afgedrukt en hoe statistieken van de printer kunnen worden bijgehouden.

[[printing-simple]]
=== Eenvoudige printerinstallatie

Nu wordt toegelicht hoe de printerhardware en de LPD software ingesteld moeten worden om een printer te kunnen gebruiken. Het behandelt de basis:

* <<printing-hardware,Hardware-instellingen>> geeft een aantal aanwijzingen voor het aansluiten van een printer op een poort van een computer.
* <<printing-software,Software-instellingen>> toont hoe het instellingenbestand ([.filename]#/etc/printcap#) voor het LPD-systeem moet worden opgezet.

Hoe een printer geïnstalleerd moet worden die via een netwerkprotocol gegevens ontvangt, in plaats van een seriële of parallelle poort, staat in <<printing-advanced-network-net-if,Printers met netwerkinterfaces>>.

Hoewel dit onderdeel "Eenvoudige printerinstallatie" heet, is het redelijk complex. De printer met de computer en het LPD-systeem laten samenwerken is het moeilijkste. De geavanceerde opties, zoals voorbladen en statistieken, zijn relatief makkelijk als de printer eenmaal werkt.

[[printing-hardware]]
==== Hardware-instellingen

Hier worden de verschillende manieren waarop een printer op een computer kan worden aangesloten beschreven. Het bespreekt de soorten poorten en kabels en de kernelinstellingen die nodig kunnen zijn om FreeBSD met een printer te laten communiceren.

Als een printer al is aangesloten en succesvol is gebruikt onder een ander besturingssysteem, dan kan waarschijnlijk verder gelezen worden in <<printing-software,Software-instellingen>>.

[[printing-ports]]
===== Poorten en kabels

De printers die tegenwoordig voor PC's verkocht worden hebben eigenlijk altijd een van de volgende drie poorten:

* _Seriële_ poort, ook bekend als RS-232- of COM-poorten, gebruiken een seriële poort op een computer om gegevens naar een printer te sturen. Seriële poorten zijn heel gebruikelijk in de computerindustrie en kabels zijn eenvoudig verkrijgbaar en makkelijk te maken. Seriële poorten hebben soms speciale kabels nodig en vereisen soms het instellen van ingewikkelde communicatieparameters. De meeste seriële poorten hebben een maximale doorvoersnelheid van 115.200 bps waardoor het afdrukken van grote grafische afdrukopdrachten erg onpraktisch wordt.
* _Parallelle_ poorten gebruiken een parallelle poort op een computer om gegevens naar een printer te sturen. Parallelle poorten zijn gebruikelijk in de PC-markt en zijn sneller dan RS-232 serieel. Kabels zijn goed verkrijgbaar, maar moeilijker handmatig te vervaardigen. Meestal zijn er geen communicatieparameters bij parallelle poorten, wat het instellen erg eenvoudig maakt.
+ 
Parallelle poorten staan ook wel bekend als "Centronics" poorten, genoemd naar het soort aansluiting op de printer.
* USB poorten, genoemd naar de Universal Serial Bus, kunnen zelfs op nog hogere snelheid werken dan parallelle of RS-232 seriële poorten. De kabels zijn eenvoudig en goedkoop. USB is voor afdrukken superieur aan RS-232 Serieel en Parallel, maar wordt op UNIX(R)-systemen niet altijd goed ondersteund. Een van de manieren om dit te omzeilen is de aanschaf van een printer met zowel een USB als een parallelle poort, zoals veel printers die hebben.

Over het algemeen kunnen parallelle poorten meestal in één richting communiceren (van computer naar printer), terwijl seriële en USB poorten in twee richtingen kunnen communiceren. Nieuwere parallelle poorten (EPP en ECP) en printers kunnen onder FreeBSD in beide richtingen communiceren, mits een IEEE-1284 gekeurde kabel wordt gebruikt.

Tweewegcommunicatie met een printer over een parallelle poort verloopt meestal op een van de volgende twee manieren. De eerste manier is door gebruik te maken van een op maat gemaakt stuurprogramma voor FreeBSD dat de taal spreekt die door de printer wordt gebruikt. Dit geldt meestal voor inkjet printers en er kan dan gebruikt gemaakt worden van rapportagemogelijkheden over bijvoorbeeld inktniveaus en andere statusinformatie. De tweede methode wordt gebruikt als een printer PostScript(R) ondersteunt.

PostScript(R)-taken zijn eigenlijk programma's die naar de printer worden gestuurd. Het hoeft zelfs niet in een afdruk te resulteren; het resultaat van de opdracht kan direct weer naar de computer worden gestuurd. PostScript(R) gebruikt ook tweewegcommunicatie om een computer op de hoogte te stellen van opgetreden fouten, zoals fouten in het PostScript(R)-programma of vastgelopen papier. Gebruikers kunnen dit soort informatie handig vinden. De beste manier om bij een PostScript(R)-printer effectief bij te houden wat het printergebruik is, vraagt om tweewegcommunicatie: de printer wordt gevraagd om het totaal aantal afgedrukt pagina's, de afdrukopdracht wordt verzonden en vervolgens wordt nogmaals om het totaal aantal afgedrukte pagina's gevraagd. Het verschil van deze getallen geeft het aantal afgedrukte pagina's van de afdrukopdracht van de betreffende gebruiker.

[[printing-parallel]]
===== Parallelle poorten

Om een printer met een parallelle poort aan te sluiten, moet een Centronics kabel de printer met de computer verbinden. De instructies die geleverd zijn bij de printer, de computer of beide, moeten voldoende zijn om dit te verduidelijken.

Onthoud op welke parallelle poort de printer is aangesloten. De eerste parallelle poort heet onder FreeBSD [.filename]#ppc0#, de tweede [.filename]#ppc1#, enzovoort. De benaming voor de printer gaat analoog: [.filename]#/dev/lpt0# voor de printer op de eerste parallelle poort enzovoort.

[[printing-serial]]
===== Seriële poorten

Gebruik de juiste seriële kabel om een printer met een seriële poort op een computer aan te sluiten. De instructies die geleverd zijn bij de printer, de computer of beide, moeten voldoende zijn om dit te verduidelijken.

Als onduidelijk is wat de "juiste seriële kabel" is, kan een van onderstaande opties geprobeerd worden:

* Een __modem__kabel verbindt elke pin van de stekker aan het ene eind direct met de corresponderende pin van de stekker aan het andere eind. Dit type kabel heet ook wel een "DTE-naar-DCE"-kabel.
* Een _null-modem_ kabel verbindt enkele pinnetjes direct, verwisselt andere (bijvoorbeeld van verstuur gegevens naar ontvang gegevens) en sluit sommige draden kort in de stekker. Dit type kabel heet ook wel een "DTE-to-DTE"-kabel.
* Een __seriële printer__kabel, nodig bij sommige ongebruikelijke printers, is als een null-modem kabel, maar stuurt sommige signalen naar hun tegenhangers in plaats van ze intern kort te sluiten.

Het is ook nodig de communicatieparameters voor de printer in te stellen, meestal via het bedieningspaneel of middels DIP-schakelaars op de printer. Selecteer de hoogste `bps` (bits per seconde, soms _baud_) die zowel door de computer als de printer wordt ondersteund. Kies 7 of 8 data bits. Geen, even of oneven pariteit en 1 of 2 stop bits. Selecteer ook het flow-control protocol: ofwel geen, ofwel XON/XOFF (ook bekend als "in-band" of "software") flow-control. Onthoud deze instellingen voor de hier op volgende software-instellingen.

[[printing-software]]
==== Software-instellingen

Nu wordt beschreven welke software-instellingen nodig zijn om onder FreeBSD af te drukken met behulp van het wachtrijsysteem LPD.

Een overzicht van de te doorlopen stappen:

[.procedure]
====
. Maak, indien nodig, de kernel geschikt voor de poort die door de printer wordt gebruikt. In <<printing-kernel,Kernelinstellingen>> is te lezen hoe dit gedaan kan worden.
. Stel de communicatievorm voor de parallelle poort in, als gebruik wordt gemaakt van een parallelle printer. In <<printing-parallel-port-mode,Communicatietype instellen voor een parallelle poort>> staan de details.
. Test of het besturingssysteem gegevens naar de printer kan sturen. In <<printing-testing,Printercommunicatie controleren>> staat een aantal suggesties.
. Stel LPD in voor de printer door [.filename]#/etc/printcap# aan te passen. Dat wordt later in het hoofdstuk beschreven.
====

[[printing-kernel]]
===== Kernelinstellingen

Het besturingssysteem is gecompileerd om met een beperkte verzameling apparaten te kunnen werken. De seriële en parallelle poorten zijn onderdeel van deze verzameling. Daarom kan het nodig zijn om ondersteuning voor een extra seriële of parallelle poort toe te voegen als een kernel hier nog niet voor is ingesteld.

Om te achterhalen of de huidige kernel een seriële poort ondersteunt:

[source,shell]
....
# grep sioN /var/run/dmesg.boot
....

Hier is _N_ het aantal seriële poorten, beginnende bij nul. Als de uitvoer op het volgende lijkt, dan wordt de poort door de kernel ondersteund:

[source,shell]
....
sio2 at port 0x3e8-0x3ef irq 5 on isa
sio2: type 16550A
....

Om te achterhalen of de kernel een parallelle poort ondersteunt:

[source,shell]
....
# grep ppcN /var/run/dmesg.boot
....

Hier is _N_ het aantal parallelle poorten beginnende bij nul. Als de uitvoer er ongeveer als volgt uit ziet, dan wordt de poort door de kernel ondersteund:

[source,shell]
....
ppc0: <Parallel port> at port 0x378-0x37f irq 7 on isa0
ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
ppc0: FIFO with 16/16/8 bytes threshold
....

Het kan nodig zijn een kernel aan te passen om het besturingssysteem in staat te stellen een parallelle of seriële poort die voor een printer wordt gebruikt te herkennen en te gebruiken.

In het onderdeel over kernelinstellingen staat meer informatie om ondersteuning voor een seriële poort toe te voegen. Lees de betreffende _en_ de volgende sectie om ondersteuning voor een parallelle poort toe te voegen.

[[printing-parallel-port-mode]]
==== Communicatietype instellen voor een parallelle poort

Wanneer een parallelle poort wordt gebruikt, kan worden aangegeven of FreeBSD voor de printer interrupt-gestuurde of "polled" communicatie moet gebruiken. Het generieke printerapparaatstuurprogramma (man:lpt[4]) onder FreeBSD gebruikt het systeem man:ppbus[4]. Dit bestuurt de chipset van de poort met het stuurprogramma man:ppc[4].

* De _interrupt-gestuurde_ methode is standaard in de GENERIC kernel. In dit geval gebruikt het besturingssysteem een IRQ om te bepalen of de printer klaar is om gegevens te ontvangen.
* Bij de _polled_ methode vraagt het besturingssysteem met vaste intervallen aan de printer of deze klaar is om gegevens te ontvangen. Als de printer antwoordt met "klaar", stuurt de kernel meer gegevens.

De interrupt-gestuurde methode is meestal iets sneller, maar gebruikt een kostbaar IRQ-nummer. Van sommige HP printers wordt beweerd dat ze niet goed werken in interruptmodus, schijnbaar door een (nog niet begrepen) timing-probleem. Deze printers moeten gebruik maken van de polled methode. Gebruik de methode die werkt. Sommige printers werken met beide methodes, maar zijn tergend langzaam in de interrupt modus.

Het communicatietype kan op twee manieren worden ingesteld: door de kernel in te stellen of door gebruik te maken van man:lptcontrol[8].

_Het communicatietype instellen door de kernel aan te passen:_

[.procedure]
====

. Pas het kernelinstellingenbestand aan. Zoek naar een `ppc0` ingang. Gebruik `ppc1` voor het opzetten van een tweede parallelle poort. Gebruik `ppc2` voor de derde poort, enzovoort.

** Als u gebruik wilt maken van de interrupt gestuurde modus, bewerk dan de regel hieronder:
+
[.programlisting]
....
hint.ppc.0.irq="N"
....
+ 
Het kernelinstellingenbestand moet ook het stuurprogramma man:ppc[4] bevatten:
+
[source,shell]
....
device ppc
....
+
** Om gebruik te maken van polled modus verwijder dan het volgende regel uit [.filename]#/boot/device.hints#:
+
[.programlisting]
....
hint.ppc.0.irq="N"
....
+ 
In sommige gevallen is het onder FreeBSD niet voldoende om een poort in polled modus te zetten. In veel gevallen komt dat door het stuurprogramma man:acpi[4]. Dit is in staat om apparaten te testen en aan te sluiten en kan zodoende het communicatietype van de printer wijzigen. Raadpleeg de instellingen voor man:acpi[4] om dit probleem te verhelpen.
+
. Sla het bestand op. Maak en installeer de nieuwe kernel en herstart de computer. In crossref:kernelconfig[kernelconfig,De FreeBSD-kernel instellen] staan meer details.
====

_Communicatietype instellen met_ man:lptcontrol[8]:

[.procedure]
====
. Typ:
+
[source,shell]
....
# lptcontrol -i -d /dev/lptN
....
+ 
om `lptN` op interrupt-gestuurde modus in te stellen.
. Typ:
+
[source,shell]
....
# lptcontrol -p -d /dev/lptN
....
+ 
om `lptN` op polled modus in te stellen.
+
[source,shell]
....
# lptcontrol -p -d /dev/lptN
....
====

Zet deze commando's in het bestand [.filename]#/etc/rc.local# zodat het communicatietype juist wordt ingesteld bij het opstarten. In man:lptcontrol[8] staat meer informatie.

[[printing-testing]]
==== Printercommunicatie controleren

Voor het instellen van het wachtrijsysteem, is het verstandig te controleren of het besturingssysteem gegevens naar een printer kan versturen. Het is een stuk makkelijker om problemen met printercommunicatie en het wachtrijsysteem apart op te lossen.

De printer wordt getest door er tekst naar toe te sturen. Voor printers die direct tekens kunnen afdrukken is het programma man:lptest[1] handig: het genereert alle 96 afdrukbare ASCII-tekens op 96 regels.

Voor PostScript(R) (of andere op taal gebaseerde) printers, is een meer geavanceerde test nodig. Een eenvoudig PostScript(R)-programma zoals het volgende volstaat:

[.programlisting]
....
%!PS
100 100 moveto 300 300 lineto stroke
310 310 moveto /Helvetica findfont 12 scalefont setfont
(Werkt dit?) show
showpage
....

Bovenstaande PostScript(R)-code kan in een bestand worden opgeslagen en in de voorbeelden in de volgende paragrafen gebruikt worden.

[NOTE]
====
Als in dit document wordt gesproken over een printertaal, wordt uitgegaan van een taal als PostScript(R) en niet PCL van HP. Hoewel PCL zeer functioneel is, kan het direct platte tekst afdrukken door gebruik te maken van escape-tekens. PostScript(R) kan niet direct platte tekst afdrukken. Voor dat soort printertalen zijn speciale aanpassingen nodig.
====

[[printing-checking-parallel]]
===== Parallelle printer controleren

In deze sectie wordt beschreven hoe te controleren of FreeBSD kan communiceren met een printer die op een parallelle poort is aangesloten.

_Voer de volgende stappen uit om een printer op een parallelle poort te testen:_

[.procedure]
====

. man:su[1] naar `root`.
. Stuur gegevens naar de printer.

** Gebruik man:lptest[1] als de printer platte tekst af kan drukken:
+
[source,shell]
....
# lptest > /dev/lptN
....
+ 
Hier is _N_ het nummer van de parallelle poort, beginnende bij nul.
+
** Als de printer PostScript(R) of een andere printertaal begrijpt, stuur dan een klein programma naar de printer:
+
[source,shell]
....
# cat > /dev/lptN
....
+ 
Geef het programma regel voor regel _heel nauwkeurig_ in. Een regel kan niet worden gewijzigd als er op `RETURN` of `ENTER` is gedrukt. Geef na het afronden van de invoer voor het programma het einde-van-invoer-teken. Dit is meestal `CONTROL+D`.
+ 
Het programma kan ook in een bestand worden opgeslagen:
+
[source,shell]
....
# cat bestand > /dev/lptN
....
+ 
Hier is _bestand_ de naam van het bestand waarin het programma is opgeslagen dat naar een printer gestuurd kan worden.
====

Nu moet er iets worden afgedrukt. Tekst die er niet goed uitziet is geen probleem. Dit wordt later gerepareerd.

[[printing-checking-serial]]
===== Seriële printer controleren

In deze sectie wordt beschreven hoe te controleren of FreeBSD kan communiceren met een printer die op een seriële poort is aangesloten.

_Voer de volgende stappen uit om een printer op de seriële poort te testen:_

[.procedure]
====

. man:su[1] naar `root`.
. Voeg de volgende regel toe aan [.filename]#/etc/remote#:
+
[.programlisting]
....
printer:dv=/dev/poort:br#bps-snelheid:pa=pariteit
....
+ 
Hier is _poort_ de apparaatingave voor de seriële poort (`ttyu0`, `ttyu1`, enzovoort), _bps-snelheid_ is het aantal bits per seconde waarop de printer communiceert en _pariteit_ is de pariteit die door de printer wordt vereist (`even`, `odd`, `none` of `zero`).
+ 
Hier volgt een voorbeeldregel voor een printer verbonden met een seriële lijn op de derde seriële poort op 19200 bps, zonder pariteit:
+
[.programlisting]
....
printer:dv=/dev/ttyu2:br#19200:pa=none
....
+
. Maak verbinding met de printer met man:tip[1]:
+
[source,shell]
....
# tip printer
....
+ 
Als dit niet werkt, pas dan [.filename]#/etc/remote# opnieuw aan en probeer gebruik te maken van [.filename]#/dev/cuaaN# in plaats van [.filename]#/dev/ttyuN#.
+
. Stuur gegevens naar de printer.
+
** Gebruik man:lptest[1] als de printer platte tekst af kan drukken:
+
[source,shell]
....
% $lptest
....
+
** Als de printer PostScript(R) of een andere printertaal begrijpt, stuur dan een klein programma naar de printer. Geef het programma regel voor regel _heel nauwkeurig_ in. Backspace of andere speciale toetsen kunnen een speciale betekenis hebben voor de printer. Het kan ook nodig zijn een speciaal einde-van-invoer-teken te geven zodat de printer weet dat het gehele programma ontvangen is. Druk voor PostScript(R)-printers `CONTROL+D`.
+ 
Het programma kan ook in een bestand worden opgeslagen:
+
[source,shell]
....
% >bestand
....
+ 
Hier is _bestand_ de naam van het bestand waarin het programma is opgeslagen. Nadat man:tip[1] het bestand heeft verstuurd kan het juiste einde-van-invoer-teken ingegeven worden.
====

Nu moet er iets worden afgedrukt. Tekst die er niet goed uitziet is geen probleem. Dit wordt later gerepareerd.

[[printing-printcap]]
==== De wachtrij aanzetten: [.filename]#/etc/printcap#

Op dit punt moet de printer zijn aangesloten, de kernel ingesteld zijn om met de printer te communiceren (indien nodig) en is het mogelijk eenvoudige gegevens naar de printer te sturen. Nu kan LPD ingesteld worden zodat de toegang tot de printer wordt geregeld.

LPD wordt ingesteld door het bestand [.filename]#/etc/printcap# aan te passen. Het wachtrijsysteem LPD leest dit bestand iedere keer dat het systeem wordt aangeroepen zodat wijzigingen direct van toepassing zijn.

De opmaak van het bestand man:printcap[5] is voor de hand liggend. Met een willekeurige tekstverwerker kunnen wijzigen in [.filename]#/etc/printcap# aangebracht worden. De opmaak is identiek aan die van andere bestanden die voor dergelijke instellingen worden gebruik, zoals [.filename]#/usr/shared/misc/termcap# en [.filename]#/etc/remote#. In man:cgetent[3] staat een uitgebreid overzicht van dit formaat.

De vereenvoudigde instellingen bestaan uit de volgende stappen:

[.procedure]
====
. Kies een naam (en een paar handige aliassen) voor de printer en voeg ze toe aan [.filename]#/etc/printcap#. In <<printing-naming,Printernaamgeving>> staat meer informatie over het toekennen van een naam aan een printer.
. Het afdrukken van voorbladen (standaard) kan uitgezet worden met de optie `sh`. In <<printing-no-header-pages,Voorbladen onderdrukken>> staat meer informatie.
. Maak een wachtrijmap aan en specificeer de locatie door middel van de optie `sd`. In <<printing-spooldir,Wachtrijmap aanmaken>> staat meer informatie.
. Bepaal welke ingave in [.filename]#/dev# voor de printer wordt gebruikt en geef dit in [.filename]#/etc/printcap# aan door gebruik te maken van de optie `lp`. In <<printing-device,Printerapparaat identificeren>> staat meer informatie. Als de printer is aangesloten op een seriële poort moeten de communicatieparameters worden ingesteld met de optie `ms#`. Dit wordt beschreven in <<printing-commparam,Communicatieparameters voor het wachtrijsysteem instellen>>.
. Installeer een filter voor platte tekst. In <<printing-textfilter,Tekstfilter installeren>> staan details.
. Test de instellingen door iets met man:lpr[1] af te drukken. Details staan in <<printing-trying,Printer uitproberen>> en <<printing-troubleshooting,Problemen oplossen>>.
====

[NOTE]
====
Op taal gebaseerde printers, zoals PostScript(R)-printers, kunnen niet direct platte tekst afdrukken. De vereenvoudigde instellingen, zoals hierboven beschreven en hieronder verder beschreven, gaan er van uit dat alleen bestanden naar een printer worden gestuurd die de printer begrijpt.
====

Gebruikers verwachten vaak dat ze platte tekst naar printers op een systeem kunnen sturen. Programma's die LPD gebruiken om af te drukken gaan hier ook vaak van uit. Als een dergelijke printer wordt geïnstalleerd en het moet mogelijk zijn zowel afdrukopdrachten in de printertaal als in platte tekst naar een printer te sturen, dan is het zeer aan te raden een extra stap in deze vereenvoudigde opzet in te voegen: installeer een conversieprogramma dat automatisch platte tekst omzet in PostScript(R) (of een andere printertaal). In <<printing-advanced-if-conversion,Platte tekst op PostScript(R)-printers afdrukken>> staat hoe dit in zijn werk gaat.

[[printing-naming]]
===== Printernaamgeving

De eerste (makkelijke) stap is het kiezen van een naam voor een printer. Het maakt niet uit of een naam functioneel of grappig is, aangezien ook een aantal aliassen aan een printer toegekend kunnen worden.

Ten minste één van de printers die in [.filename]#/etc/printcap# worden genoemd moet het alias `lp` hebben. Dit is de standaardnaam voor de printer. Als gebruikers de omgevingsvariabele `PRINTER` niet ingesteld hebben en ook geen printernaam specificeren als ze LPD gebruiken, dan wordt standaard de printer `lp` gebruikt.

Het is verder gebruikelijk om het laatste alias zo te kiezen dat het een volledige beschrijving van de printer is, inclusief merk en model.

Als een naam en een aantal aliassen zijn gekozen, kunnen ze aan [.filename]#/etc/printcap# worden toegevoegd. De naam van een printer wordt in de meest linker kolom geplaatst. Scheid ieder alias met een verticale streep en plaats een dubbele punt achter het laatste alias.

In het volgende voorbeeld is de beginsituatie een uitgekleed [.filename]#/etc/printcap# waarin twee printers worden gedefinieerd (een Diablo 630 lijnprinter en een Panasonic KX-P4455 PostScript(R)-laserprinter):

[.programlisting]
....
#
#  /etc/printcap voor host rose
#
rattan|line|diablo|lp|Diablo 630 Line Printer:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:
....

In dit voorbeeld heet de eerste printer `rattan` en heeft de volgende aliassen: `line`, `diablo`, `lp` en `Diablo 630 Line Printer`. Omdat deze printer het alias `lp` heeft, is het de standaard printer. De tweede printer heet `bamboo` en heeft de aliassen `ps`, `PS`, `S`, `panasonic` en `Panasonic KX-P4455 PostScript v51.4`.

[[printing-no-header-pages]]
===== Voorbladen onderdrukken

Het wachtrijsysteem LPD drukt standaard een _voorblad_ af voor elke afdrukopdracht. Het voorblad bevat de gebruikersnaam van de gebruiker die de afdrukopdracht gaf, de computer waar de opdracht is gegeven en, in mooie grote letters, de naam van de afdrukopdracht. Het nadeel hiervan is dat al deze extra tekst het debuggen van de eenvoudige printerinstallatie bemoeilijkt. Daarom wordt het afdrukken van voorbladen onderdrukt.

Om voorbladen te onderdrukken, wordt de optie `sh` toegevoegd voor de relevante printer in [.filename]#/etc/printcap#. Hieronder staat een voorbeeld van [.filename]#/etc/printcap# met de optie `sh`:

[.programlisting]
....
#
#  /etc/printcap voor host rose - nergens worden voorbladen afgedrukt
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:
....

Het juiste formaat is gebruikt: de eerste regel begint in de meest linker kolom, volgende regels springen in. Elke regel eindigt met een backslash, behalve de laatste.

[[printing-spooldir]]
===== Wachtrijmap aanmaken

De volgende stap in deze eenvoudige opzet is het aanmaken van een _wachtrijmap_. Dit is een map waar afdrukopdrachten geplaatst worden totdat ze worden afgedrukt. Ook wordt er een aantal bestanden geplaatst die nodig zijn voor het functioneren van het wachtrijsysteem.

Vanwege het veranderlijke karakter van wachtrijmappen is het gebruikelijk om deze mappen onder [.filename]#/var/spool# te plaatsen. Het is niet nodig om een reservekopie van de inhoud van deze mappen te maken. Ze kunnen eenvoudigweg opnieuw worden aangemaakt met man:mkdir[1].

Het is ook gebruikelijk om de naam van de map overeen te laten komen met die van de printer, zoals onder is weergegeven:

[source,shell]
....
# mkdir /var/spool/printernaam
....

Als er veel printers zijn aangesloten op een netwerk, is het beter de wachtrijmappen aan te maken in een enkele map die speciaal wordt gebruikt voor afdrukken met LPD. In dit voorbeeld wordt dat gedaan voor de printers `rattan` en `bamboo`:

[source,shell]
....
# mkdir /var/spool/lpd
# mkdir /var/spool/lpd/rattan
# mkdir /var/spool/lpd/bamboo
....

[NOTE]
====
Als de afdrukopdrachten privé moeten blijven, dan is het belangrijk de wachtrijmap niet algemeen toegankelijk te maken. Wachtrijmappen moeten eigendom zijn van gebruiker `daemon` en groep `daemon`. Uitsluitend deze gebruiker en groep moeten de map kunnen lezen, schrijven en doorzoeken. We doen dit voor onze voorbeeldprinters:

[source,shell]
....
# chown daemon:daemon /var/spool/lpd/rattan
# chown daemon:daemon /var/spool/lpd/bamboo
# chmod 770 /var/spool/lpd/rattan
# chmod 770 /var/spool/lpd/bamboo
....

====

Tenslotte moet LPD verteld worden dat deze mappen bestaan. Dit kan met het bestand [.filename]#/etc/printcap#. De locatie van de wachtrijmap wordt opgegeven met de optie `sd`:

[.programlisting]
....
#
#  /etc/printcap voor host rose - wachtrijmappen toegevoegd
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:sd=/var/spool/lpd/rattan:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:
....

De naam van de printer staat in de eerste kolom, maar alle andere regels die de printer beschrijven worden ingesprongen en elke regel eindigt met een backslash.

Als geen wachtrijmap wordt opgegeven met `sd`, dan wordt standaard [.filename]#/var/spool/lpd# gebruikt.

[[printing-device]]
===== Printerapparaat identificeren

In de sectie <<printing-hardware,Hardware-instellingen>> is bepaald welke poort en ingang in de map [.filename]#/dev# door FreeBSD worden gebruikt om met een printer te communiceren. Nu moet LPD dit ook weten. Als het wachtrijsysteem een afdrukopdracht krijgt, opent het het relevante apparaat namens het filterprogramma (dat verantwoordelijk is voor het sturen van gegevens naar een printer).

Geef de locatie van de ingang in [.filename]#/dev# op in [.filename]#/etc/printcap# door gebruik te maken van de optie `lp`.

In het huidige voorbeeld wordt aangenomen dat `rattan` op de eerste parallelle poort is aangesloten en `bamboo` op de zesde seriële poort. Hier volgen de toevoegingen voor [.filename]#/etc/printcap#:

[.programlisting]
....
#
#  /etc/printcap voor host rose - bepaald welke apparaten te gebruiken
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:sd=/var/spool/lpd/rattan:\
        :lp=/dev/lpt0:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:\
        :lp=/dev/ttyu5:
....

Als voor een printer de optie `lp` niet wordt gebruikt in [.filename]#/etc/printcap#, dan gebruikt LPD standaard [.filename]#/dev/lp#. Momenteel bestaat [.filename]#/dev/lp# niet in FreeBSD.

Als de te installeren printer is aangesloten op een parallelle poort, dan staan verdere instructies in <<printing-textfilter,Tekstfilter installeren>>. In andere gevallen kunnen de instructies in de volgende paragraaf gevold worden.

[[printing-commparam]]
===== Communicatieparameters voor het wachtrijsysteem instellen

Voor printers die zijn aangesloten op een seriële poort kan LPD de bps-snelheid, pariteit en andere seriële communicatie parameters instellen voor het filterprogramma dat gegevens naar een printer stuurt. Dit is gunstig omdat:

* De verschillende communicatieparameters uitgeprobeerd kunnen worden door [.filename]#/etc/printcap# aan te passen. Het is niet nodig het filterprogramma opnieuw te compileren;
* Het wachtrijsysteem kan hetzelfde filter gebruiken voor verschillende printers die mogelijk verschillende seriële communicatie-instellingen hebben.

Met de volgende opties in [.filename]#/etc/printcap# kunnen seriële communicatieparameters worden ingesteld voor het apparaat waar `lp` naar verwijst:

`br#bps-snelheid`::
Stelt de communicatiesnelheid van het apparaat in op _bps-snelheid_, waarbij _bps-snelheid_ de waarde 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600 of 115200 bits-per-seconde kan aannemen.

`ms#stty-modus`::
Bepaalt de opties voor het geval het printerapparaat een terminal is. In man:stty[1] staat uitleg over de beschikbare opties.

Als LPD het apparaat opent dat met `lp` is opgegeven, worden de eigenschappen van het apparaat bepaald door de optie `ms#`. Met name van belang zijn de modi `parenb`, `parodd`, `cs5`, `cs6`, `cs7`, `cs8`, `cstopb`, `crtscts` en `ixon`. Deze worden uitgelegd in man:stty[1].

Nu wordt de voorbeeldprinter op de zesde seriële poort aangepast. De bps-snelheid wordt ingesteld op 38400. Als modus wordt gekozen: geen pariteit met `-parenb`, 8-bit tekens met `cs8`, geen modemcontrole met `clocal` en hardware flow-control met `crtscts`:

[.programlisting]
....
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:\
        :lp=/dev/ttyu5:ms#-parenb cs8 clocal crtscts:
....

[[printing-textfilter]]
===== Tekstfilter installeren

Nu kan LPD verteld worden welke tekstfilters gebruikt moeten worden bij het versturen van afdrukopdrachten. Een _tekstfilter_ is een programma dat LPD aanroept als het een afdrukopdracht krijgt. Wanneer LPD het tekstfilter aanroept, wordt de standaard invoer van het filter gekoppeld aan de afdrukopdracht en de standaard uitvoer aan het printerapparaat dat door de optie `lp` is opgegeven. Er wordt aangenomen dat het filter van standaard invoer leest, vervolgens de nodige handelingen uitvoert en het resultaat naar de standaard uitvoer schrijft, zodat het afgedrukt wordt. In <<printing-advanced-filters,Filters>> staat meer informatie over het tekstfilter.

Voor deze eenvoudige printerinstallatie kan het tekstfilter een klein shellscript zijn dat `/bin/cat` aanroept om de afdrukopdracht naar de printer te sturen. FreeBSD wordt geleverd met een ander filter, [.filename]#lpf#, dat backspaces en onderlijnde tekst afhandelt voor printers die hier niet mee overweg kunnen. Natuurlijk kan elk filter gebruikt worden dat gewenst is. Het filter `lpf` wordt uitgebreid beschreven in <<printing-advanced-lpf,lpf: een tekstfilter>>.

Nu wordt eerst het shellscript [.filename]#/usr/local/libexec/if-simple# gemaakt dat als simpel tekstfilter dient. Plaats de volgende tekst in het bestand met een tekstverwerker naar keuze:

[.programlisting]
....
#!/bin/sh
#
# if-simple - Eenvoudig tekstfilter voor lpd
# Geïnstalleerd in /usr/local/libexec/if-simple
#
# Kopieert eenvoudigweg stdin naar stdout.
# Filterargumenten worden genegeerd.

/bin/cat && exit 0
exit 2
....

Zorg dat het bestand uitvoerbaar is:

[source,shell]
....
# chmod 555 /usr/local/libexec/if-simple
....

Zorg dat LPD het filter gebruikt door dit aan te geven met de optie `if` in [.filename]#/etc/printcap#. Nu volgt hoe dit te doen voor de twee printers uit het voorbeeld:

[.programlisting]
....
#
#  /etc/printcap voor host rose - met tekstfilter
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\
        :if=/usr/local/libexec/if-simple:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:\
        :lp=/dev/ttyu5:ms#-parenb cs8 clocal crtscts:\
        :if=/usr/local/libexec/if-simple:
....

[NOTE]
====
Een kopie van het script [.filename]#if-simple# staat in de map [.filename]#/usr/shared/examples/printing#.
====

===== LPD aanzetten

man:lpd[8] wordt gestart vanuit [.filename]#/etc/rc# door de variabele `lpd_enable`. Standaard staat deze variabele op `NO`. Als dit nog niet is gedaan, voeg dan de volgende regel toe aan [.filename]#/etc/rc.conf# en herstart de computer:

[.programlisting]
....
lpd_enable="YES"
....

Of voer het commando man:lpd[8] uit:

[source,shell]
....
# lpd
....

[[printing-trying]]
===== Printer uitproberen

Nu volgt het laatste onderdeel van de eenvoudige LPD installatie. Helaas zijn felicitaties nog niet gepast. De printer moet worden getest en eventuele problemen moeten worden opgelost. Om de installatie te testen kan iets afgedrukt worden. Afdrukken gaat met het commando man:lpr[1]. Dit stuurt een opdracht naar een printer.

Het programma man:lpr[1] is te combineren met het programma man:lptest[1] uit <<printing-testing,Printercommunicatie controleren >> om tekst te genereren.

_Om de eenvoudige installatie van LPD te testen:_

[source,shell]
....
# lptest 20 5 | lpr -Pprinternaam
....

Hier is _printernaam_ de naam van een printer (of een alias) die in [.filename]#/etc/printcap# wordt genoemd. De standaard printer kan worden getest door bij het aanroepen van man:lpr[1] de optie `-P` weg te laten. Nogmaals: test een PostScript(R)-printer door een PostScript(R)-programma naar een printer te sturen en maak geen gebruik van man:lptest[1]. Dit kan door het programma in een bestand op te slaan en de volgende commandoregel uit te voeren: `lpr bestand`.

Voor een PostScript(R)-printer moet het resultaat van het programma verschijnen. Als gebruik wordt gemaakt van man:lptest[1] ziet het resultaat er ongeveer zo uit:

[source,shell]
....
!"#$%&'()*+,-./01234
"#$%&'()*+,-./012345
#$%&'()*+,-./0123456
$%&'()*+,-./01234567
%&'()*+,-./012345678
....

Om de printer uitvoeriger te testen kunnen grotere programma's geprobeerd worden (voor taalgebaseerde printers) of kan man:lptest[1] aangeroepen worden met andere argumenten. Bijvoorbeeld: `lptest 80 60`, drukt 60 regels af met elk 80 karakters.

Als de printer niet werkt, lees dan verder in <<printing-troubleshooting,Problemen oplossen>>.

[[printing-advanced]]
== Geavanceerde printerinstallatie

Deze sectie behandelt het gebruik van filters om speciaal opgemaakte tekst en voorbladen af te drukken, via het netwerk af te drukken en printergebruik te beperken en statistieken bij te houden.

[[printing-advanced-filter-intro]]
=== Filters

Hoewel LPD veel van het afdrukwerk afhandelt (netwerkverkeer, wachtrijafhandeling, toegangscontrole, enzovoort), wordt het _echte_ werk door de filters gedaan. Filters zijn programma's die met een printer communiceren en inspelen op printerspecifieke eigenschappen. In de eenvoudige printeropzet is een filter geïnstalleerd voor platte tekst, een zeer eenvoudig filter dat met de meeste printers zou moeten werken (<<printing-textfilter,Tekstfilter installeren>>).

Om echter gebruik te maken van formaatomzetting, printeradministratie, printerspecifieke aanpassingen, enzovoort, is het nodig te weten hoe filters werken. Uiteindelijk is het de verantwoordelijkheid van het filter om deze zaken af te handelen. Het slechte nieuws is dat _de beheerder_ in het merendeel van de gevallen het filter moet aanleveren. Het goede nieuws is dat veel filters algemeen beschikbaar zijn en als ze dat niet zijn, zijn ze vaak makkelijk te schrijven.

FreeBSD heeft een ingebouwd filter, [.filename]#/usr/libexec/lpr/lpf#, die met veel printers werkt die platte tekst kunnen afdrukken. Het filter regelt backspace en tabs in bestanden en administreert printergebruik, maar dat is zo'n beetje alles wat dit filter doet. Er zijn ook diverse filters en filtercomponenten in de FreeBSD Portscollectie.

Hieronder wordt het volgende beschreven:

* In <<printing-advanced-filters,Hoe filters werken>> staat een overzicht van de rol die een filter speelt in het afdrukproces. Lees dat onderdeel om een indruk te krijgen wat er "onder de motorkap" gebeurt als LPD filters gebruikt. Deze kennis helpt mogelijke problemen te voorkomen of op te lossen als meerdere filters worden geïnstalleerd voor printers.
* LPD gaat er van uit dat elke printer standaard platte tekst af kan drukken. Dit geeft problemen voor PostScript(R) (of andere op taal gebaseerde) printers die niet in staat zijn direct platte tekst af te drukken. In <<printing-advanced-if-conversion,Platte tekst op PostScript(R)-printers afdrukken>> staat wat er kan worden gedaan om dit probleem te verhelpen. Lees verder in dit onderdeel als het om PostScript(R)-printers gaat.
* Voor veel programma's is PostScript(R) een populair uitvoerformaat. Sommige mensen schrijven PostScript(R) code zelfs direct. PostScript(R)-printers zijn echter kostbaar. In <<printing-advanced-ps,PostScript(R) simuleren op niet-PostScript(R)-printers>> staat hoe de tekstfilter van een printer aangepast moet worden zodat die PostScript(R) accepteert en afdrukt op een _niet-PostScript(R)_-printer. Dit onderdeel is van toepassing voor niet-PostScript(R)-printers.
* In <<printing-advanced-convfilters,Conversiefilters>> wordt een methode beschreven om de conversie van bepaalde bestandsformaten te automatiseren, zoals van grafische of tekstopmaakprogramma's, naar formaten die een printer kan begrijpen. Na het lezen van dit onderdeel is een beheerder in staat om een printer zodanig in te stellen dat gebruikers `lpr -t` kunnen invoeren om troff-gegevens af te drukken, `lpr -d` om TeX DVI-gegevens af te drukken of `lpr -v` om rasterplaatjes af te drukken, enzovoorts. Het wordt aangeraden deze sectie te lezen.
* In <<printing-advanced-of,Uitvoerfilters>> wordt een niet vaak gebruikte functionaliteit van LPD behandeld: uitvoerfilters. Tenzij voorbladen worden afgedrukt (<<printing-advanced-header-pages,Voorbladen>>), kan deze sectie waarschijnlijk overgeslagen worden.
* <<printing-advanced-lpf,lpf: een tekstfilter>> beschrijft `lpf`, een redelijk complete, eenvoudige tekstfilter voor lijnprinters (en laserprinters die zich als lijnprinters voordoen) dat wordt geleverd bij FreeBSD. Voor een snelle manier om printeradministratie aan de praat te krijgen voor platte tekst of voor printers waar rook uit komt bij het zien van backspace karakters, is het serieus te overwegen gebruik te maken van `lpf`.

[NOTE]
====
Een kopie van de scripts die hieronder worden beschreven, staan in de map [.filename]#/usr/shared/examples/printing#.
====

[[printing-advanced-filters]]
==== Hoe filters werken

Zoals eerder genoemd, is een filter een programma dat wordt uitgevoerd door LPD voor het afhandelen van het apparaatafhankelijke deel van de communicatie met een printer.

Als LPD een bestand wil afdrukken uit een afdrukopdracht, start het een filterprogramma. Het koppelt de standaard invoer van de filter aan het af te drukken bestand, de standaard uitvoer aan de printer en de standaard foutmelding aan het logboekbestand voor foutmeldingen (zoals opgegeven via de optie `lf` in [.filename]#/etc/printcap# of standaard [.filename]#/dev/console#).

Welk filter LPD start en de argumenten van het filter hangen af van wat er in het bestand [.filename]#/etc/printcap# wordt opgegeven en de argumenten die de gebruiker geeft op de commandoregel van man:lpr[1]. Als een gebruiker bijvoorbeeld `lpr -t` ingeeft, start LPD het filter troff, zoals wordt opgegeven via de optie `tf` voor de betreffende printer. Als een gebruiker platte tekst wilt afdrukken, dan wordt het filter `if` gestart (dit klopt bijna: zie <<printing-advanced-of,Uitvoerfilters>> voor de details).

Er zijn drie soorten filters die in [.filename]#/etc/printcap# kunnen worden opgegeven:

* Het tekstfilter, dat in de LPD documentatie verwarrend genoeg _input filter_ wordt genoemd, verwerkt het afdrukken van gewone tekst. Beschouw het als het standaardfilter. LPD verwacht dat elke printer standaard platte tekst kan afdrukken en het is de taak van het tekstfilter om er voor te zorgen dat backspaces, tabs en andere speciale karakters de printer niet in de war sturen. In een omgeving waar moet worden bijgehouden hoeveel er wordt afgedrukt, moet het tekstfilter ook administreren hoeveel pagina's er zijn afgedrukt. Dit gaat meestal door het aantal afgedrukte regels te tellen en dit te vergelijken met het aantal regels per pagina dat door de printer wordt ondersteund. Het tekstfilter wordt aangeroepen met de volgende lijst argumenten:
+
`filter-name` [ -c ] -w _width_ -l _length_ -i _indent_ -n _login_ -h _host_ _acct-file_
+ 
met
+
`-c`:::
wordt gebruikt als de afdrukopdracht is gegeven met `lpr -l`

_width_:::
is de waarde van de optie `pw` (_page width_: paginabreedte), zoals opgegeven in [.filename]#/etc/printcap#, standaard 132

_length_:::
is de waarde van de optie `pl` (_page length_: paginalengte), standaard 66

_indent_:::
geeft aan hoeveel wordt ingesprongen door `lpr -i`, standaard 0

_login_:::
de gebruikersnaam van de gebruiker die de afdrukopdracht gaf

_host_:::
de hostnaam waar de afdrukopdracht gegeven is

_acct-file_:::
de naam van het administratiebestand zoals opgegeven via de optie `af`.

* Een _conversiefilter_ converteert een specifiek bestandsformaat naar een formaat dat een printer begrijpt. Bijvoorbeeld: ditroff typesettinggegevens kunnen niet direct worden afgedrukt, maar er bestaat wel een conversiefilter om ditroff-gegevens te converteren naar een formaat dat een printer kan verteren en afdrukken. Dit wordt in <<printing-advanced-convfilters,Conversiefilters>> beschreven. Conversiefilters zijn ook nodig om printergebruik te administreren, mocht dat nodig zijn. Conversiefilters worden met de volgende argumenten aangeroepen:
+
`filter-name` -x _pixel-width_ -y _pixel-height_ -n _login_ -h _host_ _acct-file_
+ 
Hier is _pixel-width_ de waarde van de optie `px` (standaard 0) en _pixel-height_ is de waarde van de optie `py` (standaard 0).
* Het _uitvoerfilter_ wordt alleen gebruikt als er geen tekstfilter is of als er voorbladen worden afgedrukt. De ervaring leert dat uitvoerfilters zelden worden gebruikt. In sectie <<printing-advanced-of,Uitvoerfilters>> worden ze beschreven. Er zijn slechts twee argumenten die aan een uitvoerfilter worden meegegeven:
+
`filter-name` -w _width_ -l _length_
+ 
Deze zijn identiek aan de argumenten `-w` en `-l` van het tekstfilter.

Filters moeten _afsluiten_ met de volgende waarde:

exit 0::
Als het filter een bestand succesvol heeft afgedrukt.

exit 1::
Als het filter niet geslaagd is om een bestand af te drukken, maar wil dat LPD het nogmaals probeert. LPD herstart het filter als die afsluit met deze status.

exit 2::
Als het filter niet geslaagd is om een bestand af te drukken, maar niet wil dat LPD het nogmaals probeert. LPD verwijdert het bestand uit de wachtrij.

Het tekstfilter dat bij FreeBSD wordt geleverd, [.filename]#/usr/libexec/lpr/lpf#, benut de argumenten voor paginabreedte en -lengte om te bepalen wanneer een nieuwe pagina moet worden begonnen en om het printergebruik bij te houden. Het gebruikt de argumenten voor login, host en administratiebestand om accountingregels aan te maken.

Controleer bij het zoeken naar filters of ze LPD-compatibel zijn. Zo ja, dan ondersteunen ze de argumenten zoals hierboven beschreven. Zorg bij het zelf schrijven van filters voor algemeen gebruik dat ze dezelfde argumenten en exitcodes ondersteunen.

[[printing-advanced-if-conversion]]
==== Platte tekst op PostScript(R)-printers afdrukken

Als een computer en PostScript(R) (of andere op taal gebaseerde) printer maar één gebruiker hebben die belooft nooit platte tekst naar de printer te sturen of programma's te gebruiken die dat doen, dan is dit onderdeel overbodig.

Als gebruikers zowel PostScript(R) als platte tekst naar een printer willen sturen, dan is het aan te raden de printerinstellingen hierop aan te passen. Hiervoor moet het tekstfilter bij elke nieuwe opdracht bepalen of het om platte tekst of PostScript(R) gaat. Alle PostScript(R)-opdrachten beginnen met `%!` (raadpleeg de printerhandleiding voor andere printertalen). Als dit de eerste twee karakters zijn van een opdracht is het PostScript(R) en kan de rest van een opdracht direct doorgestuurd worden. Is dit niet het geval, dan moet de filter de tekst omzetten in PostScript(R) en het resultaat afdrukken.

Hoe gaat dat werken?

Voor seriële printers kan het meest eenvoudig `lprps` geïnstalleerd worden. `lprps` is een PostScript(R)-afdrukfilter die tweewegcommunicatie met een printer heeft. Het werkt het statusbestand van een printer bij met uitgebreide informatie afkomstig van een printer, zodat gebruikers en beheerders precies kunnen zien wat de status van een printer is (zoals: `toner bijna op` of `papier vastgelopen`). Maar belangrijker, het omvat het programma `psif` dat bepaalt of een binnenkomende opdracht platte tekst is en `textps` (dat ook geleverd wordt met `lprps`) om opdrachten om te zetten naar PostScript(R). Vervolgens wordt een opdracht met `lprps` naar een printer gestuurd.

`lprps` is onderdeel van de FreeBSD Portscollectie (zie crossref:ports[ports,De Portscollectie]). U kunt één van de ports package:print/lprps-a4[] of package:print-lprps-letter[] installeren afhankelijk van de gebruikte papiermaat. Nadat `lprps` is geïnstalleerd moet de installatielocatie ervan aan `psif` worden doorgeven dat onderdeel is van `lprps`. Als `lprps` is geïnstalleerd via de Portscollectie, gebruik dan het volgende voor de seriële PostScript(R)-printer in [.filename]#/etc/printcap#:

[.programlisting]
....
:if=/usr/local/libexec/psif:
....

Ook moet de optie `rw` worden opgeven, die LPD vertelt om een printer in lezen/schrijvenmodus te openen.

Als een parallelle PostScript(R)-printer wordt ingesteld (en dus geen tweewegcommunicatie toegepast kan worden met de printer, zoals vereist door `lprps`), dan kan het volgende shellscript gebruikt worden als tekstfilter:

[.programlisting]
....
#!/bin/sh
#
#  psif - Druk PostScript(R) of platte tekst af op een PostScript(R)
#  printer. Script versie; NIET de versie die wordt geleverd bij lprps
#  Geïnstalleerd in /usr/local/libexec/psif
#

IFS="" read -r first_line
first_two_chars=`expr "$first_line" : '\(..\)'`

if [ "$first_two_chars" = "%!" ]; then
    #
    #  PostScript(R) opdracht, afdrukken.
    #
    echo "$first_line" && cat && printf "\004" && exit 0
    exit 2
else
    #
    #  Platte tekst, converteren en dan afdrukken.
    #
    ( echo "$first_line"; cat ) | /usr/local/bin/textps && printf "\004" && exit 0
    exit 2
fi
....

In bovenstaand script is `textps` een programma dat geïnstalleerd is om platte tekst om te zetten naar PostScript(R). Elk tekst-naar-PostScript(R) programma volstaat. De FreeBSD Portscollectie (zie crossref:ports[ports,De Portscollectie]) bevat een uitgebreid tekst-naar-PostScript(R)-programma, `a2ps`, dat wellicht handig is om te gebruiken.

[[printing-advanced-ps]]
==== PostScript(R) simuleren op niet-PostScript(R)-printers

PostScript(R) is _de facto_ de standaard voor op hoge kwaliteit typesetten en afdrukken. PostScript(R) is echter een _dure_ standaard. Gelukkig heeft Aladdin Enterprises een gratis PostScript(R)-kloon, Ghostscript, die werkt onder FreeBSD. Ghostscript kan de meeste PostScript(R)-bestanden lezen en de pagina's op verschillende soorten apparaten weergeven, waaronder veel niet-PostScript(R)-printers. Door Ghostscript te installeren en een printer gebruik te laten maken van een speciaal tekstfilter voor uw printer, kan uw niet-PostScript(R)-printer zich gedragen als een echte PostScript(R)-printer.

Ghostscript is beschikbaar via de FreeBSD Portscollectie, vele versies zijn beschikbaar, de meest gebruikte versie is package:print/ghostscript-gpl[].

Om PostScript(R) te simuleren moet een tekstfilter detecteren of het een PostScript(R)-bestand aan het afdrukken is. Zo niet, dan stuurt het filter het bestand direct naar een printer, anders gebruikt het filter Ghostscript om het bestand om te zetten naar een formaat dat door een printer wordt begrepen.

Een voorbeeld: het volgende script is een tekstfilter voor Hewlett Packard DeskJet 500 printers. Voor andere printers moet het argument `-sDEVICE` voor het commando `gs` (Ghostscript) vervangen worden. (Met `gs -h` wordt een lijst met apparaten getoond worden die de huidige installatie van Ghostscript ondersteunt.)

[.programlisting]
....
#!/bin/sh
#
#  ifhp - Druk Ghostscript-gesimuleerd PostScript(R) af op een DeskJet
#  500.  Geïnstalleerd in /usr/local/libexec/ifhp

#
#  Behandel LF als CR+LF (om een "trapeffect" op HP/PCL
#  printer te voorkomen):
#
printf "\033&k2G" || exit 2

#
#  Lees de eerste twee karakters van het bestand
#
IFS="" read -r first_line
first_two_chars=`expr "$first_line" : '\(..\)'`

if [ "$first_two_chars" = "%!" ]; then
    #
    #  Het is PostScript(R). Gebruik Ghostscript om te converteren
    #  en druk het af.
    #
    /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
        -sOutputFile=- - && exit 0
else
    #
    #  Platte tekst of HP/PCL, dus direct afdrukken;  druk een
    #  pagina-einde af om de laatste pagina te ejecteren.
    #
    echo "$first_line" && cat && printf "\033&l0H" &&
exit 0
fi

exit 2
....

Tot slot moet LPD op de hoogte gebracht worden van het filter via de optie `if`:

[.programlisting]
....
:if=/usr/local/libexec/ifhp:
....

Dat is alles. Nu kan `lpr platte.tekst` en `lpr watdanook.ps` ingevoerd worden en beiden worden juist afgedrukt.

[[printing-advanced-convfilters]]
==== Conversiefilters

Na de eenvoudige installatie, zoals beschreven in <<printing-simple,Eenvoudige printerinstallatie>>, te hebben voltooid, is het waarschijnlijk wenselijk om conversiefilters te installeren voor favoriete bestandsformaten (naast platte ASCII-tekst).

===== Waarom conversiefilters installeren?

Conversiefilters maken het afdrukken van verschillende bestanden eenvoudig. Stel dat veel gebruik gemaakt wordt van het tekstverwerkingsprogramma TeX en een PostScript(R) printer. Elke keer als door TeX een DVI-bestand wordt gegenereerd, kan dat niet direct afgedrukt worden. Het DVI-bestand moet omgezet worden naar PostScript(R). De te geven opdrachten zijn de volgende:

[source,shell]
....
% dvips zeewieranalyse.dvi
% lpr zeewieranalyse.ps
....

Na installatie van een conversiefilter voor DVI-bestanden kan deze handmatige conversie overgeslagen worden door LPD de conversie te laten uitvoeren. Elke keer als een DVI-bestand wordt afgedrukt, hoeft alleen de volgende opdracht gegeven te worden:

[source,shell]
....
% lpr -d zeewieranalyse.dvi
....

LPD voert de DVI-bestandsconversie uit door `-d` te geven. In <<printing-lpr-options-format,Opties voor opmaak en conversie>> staat een lijst van conversie-opties.

Voor elke conversie-optie moet een _conversiefilter_ geïnstalleerd worden en moet in [.filename]#/etc/printcap# de locatie worden opgegeven. Een conversiefilter is als het tekstfilter voor de eenvoudige printerinstallatie (<<printing-textfilter,Tekstfilter installeren>>), behalve dat in plaats van platte tekst af te drukken, het conversiefilter het bestand converteert naar een formaat dat een printer begrijpt.

===== Welke conversiefilters installeren?

Installeer de conversiefilters die nodig zijn. Als veel DVI-bestanden worden afgedrukt, dan is het handig een DVI-filter te installeren. Als veel troff wordt afgedrukt, dan is het waarschijnlijk handig een troff-filter te installeren.

De volgende tabel geeft een samenvatting van filters waarmee LPD kan werken, hoe ze in [.filename]#/etc/printcap# kunnen worden aangeroepen en hoe ze met `lpr` kunnen worden aangeroepen:

[.informaltable]
[cols="1,1,1", frame="none", options="header"]
|===
| Bestandsformaat
| /etc/printcap optie
| lpr optie

|cifplot
|`cf`
|`-c`

|DVI
|`df`
|`-d`

|plot
|`gf`
|`-g`

|ditroff
|`nf`
|`-n`

|FORTRAN-tekst
|`rf`
|`-f`

|troff
|`tf`
|`-f`

|raster
|`vf`
|`-v`

|platte tekst
|`if`
|geen, `-p`, of `-l`
|===

In het voorbeeld waarbij `lpr -d` wordt gebruikt, moet voor de printer een optie `df` gedefinieerd staan in [.filename]#/etc/printcap#.

Ondanks wat anderen mogelijk beweren, zijn formaten als FORTRAN-tekst en plot waarschijnlijk verouderd. Dit biedt de mogelijkheid een nieuwe betekenis te geven aan deze opties door zelf een filter te installeren. Stel dat direct Printerleaf-bestanden afgedrukt moeten worden (bestanden van het bureaubladpublicatieprogramma Interleaf), maar nooit plotbestanden worden afgedrukt. Dan kan een Printerleaf-conversiefilter geïnstalleerd worden onder de optie `gf` en gebruikers kunnen geïnstrueerd worden om `lpr -g` te gebruiken om Printerleaf-bestanden af te drukken.

===== Conversiefilters installeren

Aangezien conversiefilters programma's zijn die niet onder de FreeBSD-basisinstallatie vallen, kunnen ze het best onder [.filename]#/usr/local# geplaatst worden. De map [.filename]#/usr/local/libexec# is een veelgebruikte locatie, omdat hier programma's te vinden zijn die alleen door LPD gebruikt worden. Gewone gebruikers hoeven ze nooit te gebruiken.

Om een conversiefilter te activeren, moet de bestandslocatie onder de juiste optie voor de betreffende printer in [.filename]#/etc/printcap# opgegeven worden.

In het onderstaande voorbeeld wordt het DVI-conversiefilter toegevoegd onder de sectie van de printer `bamboo`. Hieronder staat opnieuw het voorbeeldbestand [.filename]#/etc/printcap#, nu met de nieuwe optie `df` voor de printer `bamboo`:

[.programlisting]
....
#
#  /etc/printcap voor host rose - df-filter voor bamboo toegevoegd
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:sd=/var/spool/lpd/rattan:\
        :lp=/dev/lpt0:\
        :if=/usr/local/libexec/if-simple:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:\
        :lp=/dev/ttyu5:ms#-parenb cs8 clocal crtscts:rw:\
        :if=/usr/local/libexec/psif:\
        :df=/usr/local/libexec/psdf:
....

Het DVI-filter is een shellscript met de naam [.filename]#/usr/local/libexec/psdf#. Het script ziet er als volgt uit:

[.programlisting]
....
#!/bin/sh
#
#  psdf - DVI naar PostScript afdrukfilter
#  Geïnstalleerd in /usr/local/libexec/psdf
#
# Aangeroepen door lpd wanneer een gebruiker lpr -d uitvoert
#
exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@"
....

Dit script roept `dvips` in filtermodus aan (het `-f` argument) op de standaard uitvoer, de af te drukken opdracht. Vervolgens start het PostScript(R) afdrukfilter `lprps` (zie <<printing-advanced-if-conversion,Platte tekst op PostScript(R)-printers afdrukken>>) met de argumenten die LPD aan het script doorgeeft. `lprps` gebruikt deze argumenten om de afgedrukte pagina's te administreren.

===== Meer voorbeelden van conversiefilters

Er is geen vaste procedure om conversiefilters te installeren, er worden in deze sectie wat werkende voorbeelden gegeven. Gebruik deze als hulp bij het zelf maken van filters. Gebruik ze zonder aanpassingen indien mogelijk.

Dit voorbeeldscript is een raster (eigenlijk een GIF-bestand) conversiefilter voor een HP LaserJet III-Si printer:

[.programlisting]
....
#!/bin/sh
#
#  hpvf - Converteer GIF-bestanden naar HP/PCL, druk vervolgens af
#  Geïnstalleerd in /usr/local/libexec/hpvf

PATH=/usr/X11R6/bin:$PATH; export PATH
giftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \
    && exit 0 \
    || exit 2
....

Het script converteert achtereenvolgens het GIF-bestand naar een PNM-bestand (portable anymap), een PGM-bestand (portable graymap), een PBM-bestand (portable bitmap) en tenslotte naar LaserJet/PCL formaat.

Een [.filename]#/etc/printcap# bestand dat bovenstaand filter gebruikt ziet er als volgt uit:

[.programlisting]
....
#
#  /etc/printcap voor host orchid
#
teak|hp|laserjet|HP LaserJet 3Si:\
        :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\
        :if=/usr/local/libexec/hpif:\
        :vf=/usr/local/libexec/hpvf:
....

Het volgende script is een conversiefilter voor troff-gegevens afkomstig van het groff-typesettingsysteem voor de PostScript(R)-printer `bamboo`:

[.programlisting]
....
#!/bin/sh
#
#  pstf - Converteert groff's troffgegevens naar PS, drukt vervolgens af.
#  Geïnstalleerd in /usr/local/libexec/pstf
#
exec grops | /usr/local/libexec/lprps "$@"
....

Bovenstaande script maakt eveneens gebruik van `lprps` om de communicatie met een printer af te handelen. Als een printer op een parallelle poort is aangesloten, ziet het er als volgt uit:

[.programlisting]
....
#!/bin/sh
#
#  pstf - Converteert groff's troff naar PS, drukt vervolgens af.
#  Geïnstalleerd in /usr/local/libexec/pstf
#
exec grops
....

Dat is alles. In [.filename]#/etc/printcap# moet het volgende toegevoegd worden om het filter beschikbaar te maken:

[.programlisting]
....
:tf=/usr/local/libexec/pstf:
....

Hieronder een voorbeeld waarvan FORTRAN-programmeurs waarschijnlijk tranen in hun ogen krijgen: een FORTRAN-tekstfilter voor een willekeurige printer die in staat is platte tekst af te drukken. Het filter wordt actief gemaakt voor `teak`:

[.programlisting]
....
#!/bin/sh
#
# hprf - FORTRAN tekstfilter voor LaserJet 3si:
# Geïnstalleerd in /usr/local/libexec/hprf
#

printf "\033&k2G" && fpr && printf "\033&l0H" &&
 exit 0
exit 2
....

De onderstaande regel wordt toegevoegd aan [.filename]#/etc/printcap# voor de printer `teak` om het filter beschikbaar te maken:

[.programlisting]
....
:rf=/usr/local/libexec/hprf:
....

Het laatste voorbeeld is wellicht complexer. Er wordt een DVI-filter toegevoegd voor de eerder genoemde LaserJet printer `teak`. Eerst het makkelijke gedeelte: in [.filename]#/etc/printcap# wordt de locatie van het DVI-filter opgegeven:

[.programlisting]
....
:df=/usr/local/libexec/hpdf:
....

Nu het moeilijke gedeelte: het schrijven van het filter. Daarvoor is een DVI-naar-LaserJet/PCL conversieprogramma nodig. De FreeBSD Portscollectie (zie crossref:ports[ports,Portscollectie]) heeft er een: package:print/dvi2xx[]. Door deze port te installeren komt het programma dat nodig is beschikbaar, `dvilj2p`, waarmee DVI geconverteerd kan worden naar LaserJet IIp-, LaserJet III- en LaserJet 2000-formaten.

Het hulpprogramma `dvilj2p` maakt het filter `hpdf` redelijk complex, omdat `dvilj2p` niet van de standaard invoer kan lezen. Het wil werken met een bestandsnaam. Nog lastiger is dat de bestandsnaam moet eindigen op [.filename]#.dvi#, zodat moeilijk gebruik gemaakt kan worden van [.filename]#/dev/fd/0# als standaard. Dit probleem kan omzeild worden door een (symbolische) koppeling aan te maken van een tijdelijk bestand (eindigend op [.filename]#.dvi#) naar [.filename]#/dev/fd/0#. Hiermee wordt `dvilj2p` gedwongen van de standaard invoer te lezen.

De enige andere hobbel die genomen moet worden, is dat [.filename]#/tmp# niet gebruikt kan worden als tijdelijke koppeling. Symbolische koppelingen zijn eigendom van de gebruiker en groep `bin`. Het filter wordt uitgevoerd door de gebruiker `daemon`. De map [.filename]#/tmp# heeft het sticky-bit aan staan. Het filter kan de koppeling wel aanmaken, maar het is niet mogelijk de koppeling te verwijderen als de opdracht is uitgevoerd, omdat de koppeling eigendom is van een andere gebruiker.

In plaats hiervan maakt het filter een symbolische koppeling aan in de huidige werkmap, de wachtrijmap (zoals opgegeven in de optie `sd` in [.filename]#/etc/printcap#). Dit is een perfecte plaats voor filters om hun werk te doen, zeker gezien er (soms) meer vrije schijfruimte is in de wachtrijmap dan onder [.filename]#/tmp#.

Dit is het uiteindelijke filter:

[.programlisting]
....
#!/bin/sh
#
#  hpdf - Druk DVI-gegevens af op een HP/PCL printer
#  Geïnstalleerd in /usr/local/libexec/hpdf

PATH=/usr/local/bin:$PATH; export PATH

#
#  Definieer een functie om tijdelijke bestanden op te ruimen. Deze
#  staan in de huidige map; de wachtrijmap voor de printer.
#
cleanup() {
   rm -f hpdf$$.dvi
}

#
#  Definieer een functie om fatale fouten te verwerken: geef de
#  opgegeven boodschap weer en sluit af met 2. Afsluiten met 2 vertelt
#  LPD niet nog eens te proberen de afdrukopdracht af te drukken.
#
fatal() {
    echo "$@" 1>&2
    cleanup
    exit 2
}

#
#  Als de gebruiker de opdracht annuleert, stuurt LPD een SIGINT, dus
#  ondervang SIGINT (en enkele andere signalen) om onze rommel op te
#  ruimen.
#
trap cleanup 1 2 15

#
#  Voor de zekerheid bestaande tijdelijke bestanden opruimen
#
cleanup

#
#  Koppel het DVI-invoerbestand aan de standaard invoer (het af te
#  drukken bestand).
#
ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0"

#
#  Maak LF = CR+LF
#
printf "\033&k2G" || fatal "Cannot initialize printer"

#
#  Converteer en druk af.  De retourneerwaarde van dvilj2p lijkt niet
#  betrouwbaar, dus negeren we het.
#
dvilj2p -M1 -q -e- dfhp$$.dvi

#
#  Opruimen en afsluiten
#
cleanup
exit 0
....

[[printing-advanced-autoconv]]
===== Automatische conversie: een alternatief voor conversiefilters

Al deze conversiefilters bieden vele mogelijkheden voor afdrukomgevingen, maar dwingen de gebruiker aan te geven (op de man:lpr[1] commandoregel) welk filter gebruikt moet worden. Als gebruikers niet zo vaardig zijn in het gebruik van computers, wordt het al snel vervelend steeds aan te moeten geven welk filter gebruikt moet worden. Vervelender is echter wanneer een gebruiker een verkeerd filter gebruikt voor een bepaald bestandsformaat. Het resultaat kan zijn dat een printer honderden pagina's papier uitspuugt.

In plaats van het installeren van conversiefilters, is het te proberen om het (standaard) tekstfilter het bestandstype van het af te drukken bestand te laten detecteren en dan automatisch het juiste conversiefilter aan te laten roepen. Programma's als `file` kunnen hierbij handig zijn. Voor _sommige_ bestandsformaten kan het moeilijk zijn de verschillen te ontdekken en voor deze bestanden kan alsnog een conversiefilter beschikbaar worden gesteld.

De FreeBSD Portscollectie heeft een tekstfilter dat automatisch converteert genaamd `apsfilter` (package:print/apsfilter[]). Het detecteert platte tekst, PostScript(R) en DVI-bestanden, voert de juiste conversie uit en druk de bestanden af.

[[printing-advanced-of]]
==== Uitvoerfilters

Het wachtrijsysteem LPD ondersteunt een ander type filter waar nog geen aandacht aan is besteed: een uitvoerfilter. Een uitvoerfilter is bedoeld om alleen platte tekst af te drukken, net als een tekstfilter, maar met veel vereenvoudigingen. Wanneer een uitvoerfilter wordt gebruikt, maar geen tekstfilter, dan:

* start LPD een uitvoerfilter voor de gehele opdracht, in plaats van voor elk bestand in de opdracht;
* biedt LPD het uitvoerfilter niet de voorziening van het identificeren van het begin of eind van de bestanden in de afdrukopdracht;
* stuurt LPD de gebruikersnaam en de hostnaam niet door aan het filter. Het is dus niet bedoeld om een afdrukadministratie bij te houden. In feite zijn er maar twee argumenten:
+
`filter-name` -w_width_ -l_length_
+ 
Hierbij is _width_ afkomstig van de optie `pw` en _length_ afkomstig van de optie `pl` voor de betreffende printer.

De eenvoud van een uitvoerfilter is verleidelijk. Als elk bestand in een afdrukopdracht op een nieuwe pagina moet beginnen, is een uitvoerfilter _niet geschikt_. In dat geval dient een tekstfilter (ook wel invoerfilter) gebruikt te worden (zie <<printing-textfilter,Tekstfilter installeren>>. Verder is een uitvoerfilter eigenlijk _veel ingewikkelder_, omdat de te verwerken bytestroom gecontroleerd moet worden op speciale tekens en steeds signalen naar zichzelf moet sturen in opdracht van LPD.

Een uitvoerfilter is _noodzakelijk_ als voorbladen gewenst zijn en het nodig is om escape-reeksen of andere initialisatietekens te sturen voor het afdrukken van het voorblad. Maar het is tevens _nutteloos_ als het voorblad voor rekening van de afkomstige gebruiker moet komen, aangezien LPD geen gebruiker of hostinformatie naar het uitvoerfilter stuurt.

Op een enkele printer staat LPD het gebruik van zowel een uitvoerfilter als van een tekst of andere filter toe. In deze gevallen start LPD het uitvoerfilter alleen voor het afdrukken van het voorblad (zie <<printing-advanced-header-pages,Voorbladen>>). LPD verwacht vervolgens van het uitvoerfilter dat deze _zichzelf stopt_ door twee bytes naar het filter te sturen: ASCII 031 gevolgd door ASCII 001. Als een uitvoerfilter deze twee bytes ziet (031, 001), moet die stoppen door een `SIGSTOP` naar zichzelf te sturen. Als LPD klaar is met het uitvoeren van alle andere filters, dan herstart deze het uitvoerfilter door er een `SIGCONT` naar toe te sturen.

Als er wel een uitvoerfilter, maar _geen_ tekstfilter is en LPD is niet bezig met het verwerken van een opdracht met platte tekst, dan gebruikt LPD het uitvoerfilter voor het afdrukken van de opdracht. Zoals eerder vermeld, drukt het uitvoerfilter elk bestand van de opdracht achter elkaar af zonder pagina-einden of andere signalen voor paginavoortgang. Dit is waarschijnlijk _niet_ gewenst. In bijna alle gevallen is een tekstfilter nodig.

Het programma `lpf`, dat eerder geïntoduceerd is als tekstfilter, kan ook worden uitgevoerd als uitvoerfilter. Als een ad-hoc uitvoerfilter nodig is, maar het schrijven van de bytedetectie en signaalverzending code niet wenselijk is, dan is `lpf` het proberen waard. `lpf` kan ook opgenomen worden in een shellscript om initialisatiecode af te handelen die eventueel nodig is voor een printer.

[[printing-advanced-lpf]]
==== `lpf`: een tekstfilter

Het programma [.filename]#/usr/libexec/lpr/lpf# uit de gecompileerde FreeBSD-distributie is een tekstfilter (invoerfilter) die uitvoer kan inspringen (een opdracht gegeven met `lpr -i`), karakters onveranderd kan doorlaten (een opdracht gegeven met `lpr -l`), de printpositie voor backspaces en tabs in de opdracht kan aanpassen en afgedrukte pagina's kan administreren. Het kan ook functioneren als uitvoerfilter.

Het filter `lpf` is geschikt voor vele afdrukomgevingen. Hoewel het zelf niet in staat is initialisatiesequenties naar een printer te sturen, is het vrij eenvoudig om een shellscript te schrijven dat de initialisatie doet en vervolgens `lpf` aanroept.

Als `lpf` afgedrukte pagina's moet administreren, is het nodig om de juiste waarden in te vullen voor de opties `pw` en `pl` in het bestand [.filename]#/etc/printcap#. Deze waarden worden gebruikt om te bepalen hoeveel tekst er op een pagina past en hoeveel pagina's er in een afdrukopdracht zijn afgedrukt. Zie <<printing-advanced-acct,Printergebruik administreren>> voor meer informatie.

[[printing-advanced-header-pages]]
=== Voorbladen

Als er _veel_ gebruikers zijn die allemaal verschillende printers gebruiken, dan is het te overwegen gebruik te maken van _voorbladen_ als noodzakelijk kwaad.

Voorbladen, in het Engels ook wel bekend als _banner_ of _burst_ pagina's, identificeren wie een bepaalde opdracht heeft afgedrukt. Ze worden meestal bedrukt met grote, dikgedrukte letters, eventueel met een decoratieve rand, zodat ze in een stapel afdrukken opvallen tussen de afgedrukte documenten. Ze maken het gebruikers mogelijk hun afdrukopdracht snel te vinden. Het nadeel van het gebruik van voorbladen is dat er een extra blad moet worden afgedrukt voor elke opdracht, waarmee hun nut niet langer duurt dan een paar minuten. Uiteindelijk belanden ze in een papierbak of afvalberg. Voorbladen gaan vooraf aan elke opdracht, niet aan elk bestand in een opdracht, waardoor de verspilling beperkt blijft.

Het LPD-systeem kan automatisch voorbladen afdrukken _als_ een printer direct platte tekst kan afdrukken. In geval van een PostScript(R)-printer, is het nodig een extern programma aan te roepen om een voorblad te genereren (zie <<printing-advanced-header-pages-ps,Voorbladen op PostScript(R)-printers>>.

[[printing-advanced-header-pages-enabling]]
==== Voorbladen afdrukken

In de sectie <<printing-simple,Eenvoudige printerinstallatie>> is het afdrukken van voorbladen uitgeschakeld door de optie `sh` ("suppress header") in het bestand [.filename]#/etc/printcap# op te geven. Om wel voorbladen af te drukken, hoeft alleen de optie `sh` verwijderd te worden.

Dit klinkt wat al te makkelijk, of niet?

Dat klopt. Het _kan_ nodig zijn een uitvoerfilter op te geven die initialisatiestrings naar een printer stuurt. Hier is een voorbeeld uitvoerfilter voor HP PCL-compatible printers:

[.programlisting]
....
#!/bin/sh
#
#  hpof - Uitvoerfilter voor HP PCL-compatible printers
#  Geïnstalleerd in /usr/local/libexec/hpof

printf "\033&k2G" || exit 2
exec /usr/libexec/lpr/lpf
....

Geef de locatie van het uitvoerfilter op met de optie `of`. Zie <<printing-advanced-of,Uitvoerfilters>> voor meer informatie.

Hier is een voorbeeldbestand [.filename]#/etc/printcap# voor de printer `teak` die eerder is geïntroduceerd;. Het afdrukken van voorbladen is geactiveerd en bovenstaande uitvoerfilter is toegevoegd:

[.programlisting]
....
#
#  /etc/printcap voor host orchid
#
teak|hp|laserjet|HP LaserJet 3Si:\
        :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\
        :if=/usr/local/libexec/hpif:\
        :vf=/usr/local/libexec/hpvf:\
        :of=/usr/local/libexec/hpof:
....

Als gebruikers nu een opdracht sturen naar `teak`, wordt er bij elke opdracht een voorblad afgedrukt. Als gebruikers liever willen zoeken naar hun afdrukken, dan kunnen ze de voorbladen onderdrukken door de opdracht te geven met het commando `lpr -h`. Zie <<printing-lpr-options-misc,Voorbladopties>> voor meer opties voor man:lpr[1].

[NOTE]
====
LPD drukt een karakter voor pagina-einde af na elk voorblad. Als een printer een ander teken of sequentie gebruikt voor het beëindigen van een pagina, dan kan dit opgeven worden met de optie `ff` in [.filename]#/etc/printcap#.
====

[[printing-advanced-header-pages-controlling]]
==== Voorbladen beheren

Door het afdrukken van voorbladen aan te zetten, produceert LPD een _lang voorblad_ waarop in grote letters de gebruiker, host en opdracht te lezen zijn. Hier volgt een voorbeeld (`kelly` heeft de opdracht "outline" afgedrukt vanaf host `rose`):

[source,shell]
....
      k                   ll       ll
      k                    l        l
      k                    l        l
      k   k     eeee       l        l     y    y
      k  k     e    e      l        l     y    y
      k k      eeeeee      l        l     y    y
      kk k     e           l        l     y    y
      k   k    e    e      l        l     y   yy
      k    k    eeee      lll      lll     yyy y
                                               y
                                          y    y
                                           yyyy

                                   ll
                          t         l        i
                          t         l
       oooo    u    u   ttttt       l       ii     n nnn     eeee
      o    o   u    u     t         l        i     nn   n   e    e
      o    o   u    u     t         l        i     n    n   eeeeee
      o    o   u    u     t         l        i     n    n   e
      o    o   u   uu     t  t      l        i     n    n   e    e
       oooo     uuu u      tt      lll      iii    n    n    eeee

      r rrr     oooo     ssss     eeee
      rr   r   o    o   s    s   e    e
      r        o    o    ss      eeeeee
      r        o    o      ss    e
      r        o    o   s    s   e    e
      r         oooo     ssss     eeee

                                              Job:  outline
                                              Date: Sun Sep 17 11:04:58 1995
....

LPD geeft een paginabegin na deze tekst, zodat de opdracht op een nieuwe pagina begint (tenzij de optie `sf` (_suppress form feeds_, "onderdruk paginabegin") is toegevoegd bij de desbetreffende printer in [.filename]#/etc/printcap#).

Als dit wenselijk is, kan LPD ook een _korte tekst_ op het voorblad afdrukken; geef hiervoor de optie `sb` (_short banner_, "kort voorblad") op in het bestand [.filename]#/etc/printcap#. Het voorblad ziet er dan als volgt uit:

[source,shell]
....
rose:kelly  Job: outline  Date: Sun Sep 17 11:07:51 1995
....

Standaard drukt LPD het voorblad als eerste af en vervolgens de opdracht. Om dat om te keren, moet de optie `hl` (_header last_, "voorblad laatst") in [.filename]#/etc/printcap# worden opgeven.

[[printing-advanced-header-pages-accounting]]
==== Voorbladen administreren

Het gebruik van LPD's ingebouwde voorbladen dwingt een bepaald paradigma af wat betreft het administreren van printergebruik: voorbladen moeten _gratis_ zijn.

Waarom?

Omdat het uitvoerfilter het enige externe programma is dat controle heeft als het voorblad afgedrukt wordt dat het gebruik zou kunnen administreren. Het heeft echter geen beschikking over informatie over _gebruiker of host_ of een administratiebestand. Het heeft dus geen idee wie voor het gebruik moet worden belast. Het volstaat ook niet om gewoon "het aantal pagina's met één op te hogen" door het tekstfilter of een van de conversiefilters (dat wel beschikt over gebruiker- en hostinformatie) te veranderen, omdat gebruikers het afdrukken van een voorblad kunnen onderdrukken met `lpr -h`. Ze worden dan aangeslagen voor voorbladen die niet zijn afgedrukt. Milieubewuste gebruikers gebruiken vast `lpr -h`, maar dit kan niet worden afgedwongen.

Het is _ook niet voldoende_ om elk filter zijn eigen voorblad te laten genereren (om zo het gebruik te kunnen administreren). Als gebruikers het afdrukken van voorbladen willen onderdrukken met `lpr -h`, krijgen ze toch een voorblad en worden er ook voor belast, aangezien LPD geen kennis over de optie `-h` doorgeeft aan de filters.

Wat zijn dan de mogelijkheden?

* Accepteer het paradigma van LPD en maak voorbladen gratis;
* Installeer een alternatief voor LPD, zoals LPRng. In <<printing-lpd-alternatives,Alternatieven voor het standaard wachtrijsysteem>> staat meer over andere afdruksoftware die in plaats van LPD geïnstalleerd kan worden;
* Schrijf een _slim_ uitvoerfilter. Gewoonlijk is een uitvoerfilter bedoeld om niet meer te doen dan het initialiseren van een printer of wat eenvoudige karakterconversie. Het is geschikt voor voorbladen en opdrachten met platte tekst (als er een tekstfilter is). Maar als er een tekstfilter is voor opdrachten met platte tekst, dan start LPD het uitvoerfilter alleen voor voorbladen. Het uitvoerfilter kan dan het voorblad dat LPD genereert analyseren om te bepalen welke gebruiker en host belast moeten worden voor het afdrukken van het voorblad. Het enige probleem is dat het uitvoerfilter nog steeds niet weet in welk bestand het gebruik moet worden bijgehouden (de naam van het bestand opgegeven in de `af` wordt niet meegegeven), maar als een bekend bestand gebruikt wordt, kan dit in het uitvoerfilter worden opgeven. Om het parsen af te handelen kan gebruik gemaakt worden van de optie `sh` (_short header_, "kort voorblad") in [.filename]#/etc/printcap#. Dit kan echter wat omslachtig zijn en gebruikers waarderen zeker de meer gulle systeembeheerder die voorbladen gratis maakt.

[[printing-advanced-header-pages-ps]]
==== Voorbladen op PostScript(R)-printers

Zoals hierboven beschreven, kan LPD een voorblad in platte tekst genereren, dat geschikt is voor de meeste printers. Natuurlijk kan PostScript(R) platte tekst niet direct afdrukken, zodat de voorbladfunctie van LPD nutteloos is.

Een voor de hand liggende manier om voorbladen te krijgen, is elk conversiefilter en tekstfilter zijn eigen voorblad te laten genereren. De filters moeten gebruik maken van de argumenten gebruiker en host om een geschikt voorblad te genereren. Het nadeel van deze methode is dat gebruikers altijd een voorblad krijgen, ook wanneer zij een opdracht geven met `lpr -h`.

Deze methode wordt nader beschreven. Het volgende script heeft drie argumenten (gebruikersnaam, hostnaam en de naam van de opdracht) en maakt een eenvoudig PostScript(R)-voorblad:

[.programlisting]
....
#!/bin/sh
#
#  make-ps-header - genereer een PostScript-voorblad op stdout
#  Geïnstalleerd in /usr/local/libexec/make-ps-header
#

#
#  Dit zijn PostScript-eenheden (72 in een inch). Pas dit aan voor A4
#  of het gebruikte formaat:
#
page_width=612
page_height=792
border=72

#
#  Controleer argumenten
#
if [ $# -ne 3 ]; then
    echo "Usage: `basename $0` <user> <host> <job>" 1>&2
    exit 1
fi

#
#  Bewaar deze, voornamelijk voor de leesbaarheid in de PostScript(R)-code.
#
user=$1
host=$2
job=$3
date=`date`

#
#  Stuur de PostScript(R)-code naar stdout.
#
exec cat <<EOF
%!PS

%
%  Vermijd conflicten met de opdracht van de gebruiker die volgt.
%
save

%
%  Maak een dikke, onaangename border in de marge van het papier.
%
$border $border moveto
$page_width $border 2 mul sub 0 rlineto
0 $page_height $border 2 mul sub rlineto
currentscreen 3 -1 roll pop 100 3 1 roll setscreen
$border 2 mul $page_width sub 0 rlineto closepath
0.8 setgray 10 setlinewidth stroke 0 setgray

%
%  Toon de gebruikersnaam duidelijk, groot en prominent
%
/Helvetica-Bold findfont 64 scalefont setfont
$page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto
($user) show

%
%  Nu volgen de saaie bijzonderheden
%
/Helvetica findfont 14 scalefont setfont
/y 200 def
[ (Job:) (Host:) (Date:) ] {
200 y moveto show /y y 18 sub def }
forall

/Helvetica-Bold findfont 14 scalefont setfont
/y 200 def
[ ($job) ($host) ($date) ] {
        270 y moveto show /y y 18 sub def
} forall

%
% Dat is alles
%
restore
showpage
EOF
....

Nu kan zowel het conversiefilter als het tekstfilter dit script aanroepen om eerst een voorblad te genereren en vervolgens de opdracht van de gebruiker af te drukken. Hier volgt het eerder gebruikte DVI-conversieprogramma, aangepast om een voorblad te maken:

[.programlisting]
....
#!/bin/sh
#
#  psdf - DVI naar PostScript printfilter
#  Geïnstalleerd in /usr/local/libexec/psdf
#
#  Aangeroepen door lpd, wanneer de gebruiker lpr -d uitvoert
#

orig_args="$@"

fail() {
    echo "$@" 1>&2
    exit 2
}

while getopts "x:y:n:h:" option; do
    case $option in
        x|y)  ;; # Ignore
        n)    login=$OPTARG ;;
        h)    host=$OPTARG ;;
        *)    echo "LPD started `basename $0` wrong." 1>&2
              exit 2
              ;;
    esac
done

[ "$login" ] || fail "No login name"
[ "$host" ] || fail "No host name"

( /usr/local/libexec/make-ps-header $login $host "DVI File"
  /usr/local/bin/dvips -f ) | eval /usr/local/libexec/lprps $orig_args
....

Merk op hoe het filter eerst de argumentenlijst moet nagaan om te bepalen wat de gebruikers- en hostnaam zijn. Dit is gelijk voor de andere conversiefilters. Het tekstfilter heeft echter een andere verzameling argumenten (zie <<printing-advanced-filters,Hoe filters werken>>).

Zoals eerder is beschreven, is het in bovenstaande opzet, hoewel deze simpel is, niet mogelijk "voorbladen te onderdrukken" (de optie `-h` in `lpr`). Als gebruikers een boom willen sparen (of een paar centen bij betaalde voorbladen) dan is dit dus niet mogelijk, aangezien elk filter een voorblad afdrukt voor iedere opdracht.

Om gebruikers in staat te stellen per opdracht voorbladen te onderdrukken, moet gebruik gemaakt worden van de truc uit <<printing-advanced-header-pages-accounting,Voorbladen administreren>>: schrijf een uitvoerfilter dat het door LPD gegenereerde voorblad inleest en een PostScript(R)-versie genereert. Als de gebruiker de opdracht geeft met `lpr -h`, dan genereert LPD geen voorblad en het uitvoerfilter ook niet. Anders leest het uitvoerfilter de tekst van LPD in en stuurt een geschikt voorblad in PostScript(R) naar de printer.

Voor een PostScript(R)-printer op een seriële lijn kan gebruik gemaakt worden van `lprps`, dat met een uitvoerfilter wordt geleverd en het bovenstaande kan doen. Voorbladen worden door `psof` niet geteld.

[[printing-advanced-network-printers]]
=== Afdrukken via het netwerk

FreeBSD ondersteunt afdrukken via het netwerk: het sturen van opdrachten naar printers op afstand. Afdrukken via een netwerk betekent over het algemeen twee verschillende dingen:

* Het benaderen van een printer aangesloten op een andere computer. Een printer met een conventionele seriële of parallelle verbinding wordt op een bepaalde computer geïnstalleerd. Vervolgens wordt LPD zodanig ingesteld dat afdrukken vanaf andere computers in het netwerk mogelijk is. In <<printing-advanced-network-rm,Printers geïnstalleerd op andere hosts>> staat hoe dit te doen.
* Het benaderen van een printer die direct is aangesloten op een netwerk. Een printer heeft een netwerkinterface naast (of in plaats van) een gewone seriële of parallelle poort. Zo een printer kan als volgt werken:

** Het begrijpt het LPD protocol en kan zelfs opdrachten van andere hosts in de wachtrij plaatsen. In dit geval werkt een printer als een gewone host die LPD heeft draaien. Volg de procedure in <<printing-advanced-network-rm,Printers geïnstalleerd op andere hosts>> om een dergelijke printer te installeren
** Het kan zijn dat een printer een netwerkverbinding ondersteunt. In dit geval kan een printer worden "aangesloten" op een bepaalde host op het netwerk door deze host verantwoordelijk te maken voor het plaatsen van opdrachten in een wachtrij en het versturen van opdrachten naar de printer. In <<printing-advanced-network-net-if,Printers met netwerkinterfaces>> staan enkele suggesties om zulke printers te installeren.

[[printing-advanced-network-rm]]
==== Printers geïnstalleerd op andere hosts

Het wachtrijsysteem LPD heeft een ingebouwde mogelijkheid om opdrachten naar andere hosts te sturen die ook LPD draaien (of een systeem dat compatibel is met LPD). Deze eigenschap maakt het mogelijk om een printer op een host te installeren en deze toegankelijk te maken voor andere hosts. Het werkt ook met printers die over een netwerkinterface beschikken en het LPD-protocol begrijpen.

Om dit soort afdrukken op afstand mogelijk te maken, moet een printer eerst op een host geïnstalleerd worden, de _printerhost_, door de printerinstallatie te volgen als beschreven in <<printing-simple,Eenvoudige printerinstallatie>>. Stel desgewenst de printer in voor geavanceerde taken volgens <<printing-advanced,Geavanceerde printerinstallatie>>. Test de printer en controleer of deze werkt met eventueel speciaal ingestelde opties voor LPD. De _lokale host_ moet geautoriseerd zijn om de LPD-dienst op de _verre host_ te gebruiken (zie <<printing-advanced-restricting-remote,Opdrachten van hosts op afstand beperken>>).

Als een printer een netwerkinterface heeft die compatibel is met LPD, dan is de _printerhost_ in onderstaande beschrijving de printer zelf en de _printernaam_ is de naam die voor de printer is ingesteld. Meer informatie staat in de documentatie bij de printer en/of de printernetwerkinterface.

[TIP]
====

Bij een HP LaserJet voert de printernaam `text` automatisch de CRLF-conversie uit. Het is dan niet nodig het script [.filename]#hpif# te gebruiken.
====

Op hosts die toegang moeten krijgen tot de printer, moet in [.filename]#/etc/printcap# een regel worden toegevoegd met het volgende:

. Geef de regel een willekeurige naam. Om het eenvoudig te houden kunnen wellicht het beste dezelfde namen en aliassen worden gebruikt als op de printerhost;
. Laat de optie `lp` expliciet leeg (`:lp=:`);
. Maak een wachtrijmap aan en geef de locatie op met de optie `sd`. LPD slaat hier afdrukopdrachten op alvorens ze naar de printerhost te sturen;
. Geef de naam van de printerhost op met de optie `rm`;
. Geef de naam van de printer op de _printerhost_ op met de optie `rp`.

Dit is het. Conversiefilters, paginadimensies, enzovoort, hoeven niet in [.filename]#/etc/printcap# opgegeven te worden.

Hier volgt een voorbeeld. De host `rose` heeft twee printers: `bamboo` en `rattan`. Gebruikers op de host `orchid` krijgen toegang tot deze printers. Hier volgt [.filename]#/etc/printcap# voor `orchid` (uit <<printing-advanced-header-pages-enabling,Voorbladen afdrukken>>). Er stond in het bestand al een regel voor de printer `teak`. Voor de twee printers op de host `rose` zijn twee regels toegevoegd:

[.programlisting]
....
#
#  /etc/printcap voor host orchid - printers (op afstand) op rose toegevoegd
#

#
#  teak is lokaal; het is direct aangesloten op orchid:
#
teak|hp|laserjet|HP LaserJet 3Si:\
        :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\
        :if=/usr/local/libexec/ifhp:\
        :vf=/usr/local/libexec/vfhp:\
        :of=/usr/local/libexec/ofhp:

#
#  rattan is aangesloten op rose; stuur opdrachten voor rattan naar rose:
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan:

#
#  bamboo is ook aangesloten op rose:
#
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:
....

Op `orchid` moeten wachtrijmappen worden aangemaakt:

[source,shell]
....
# mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo
# chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo
# chown daemon:daemon /var/spool/lpd/rattan /var/spool/lpd/bamboo
....

Nu kunnen gebruikers op `orchid` afdrukken op `rattan` en `bamboo`. Een gebruiker op `orchid` geeft bijvoorbeeld de volgende invoer:

[source,shell]
....
% lpr -P bamboo -d sushi-review.dvi
....

Dan kopieert LPD op `orchid` de opdracht naar de wachtrijmap [.filename]#/var/spool/lpd/bamboo# en ziet dat het een DVI-opdracht is. Zodra de host `rose` ruimte heeft in zijn wachtrijmap `bamboo`, sturen de twee LPD's het bestand naar `rose`. Het bestand wacht in de wachtrij van `rose` totdat het succesvol is afgedrukt. Het wordt geconverteerd naar PostScript(R) (aangezien `bamboo` een PostScript(R)-printer is) op `rose`.

[[printing-advanced-network-net-if]]
==== Printers met netwerkinterfaces

Netwerkkaarten voor printers zijn er in twee versies: een versie die een wachtrij nabootst (de duurdere versies), of versies die alleen de mogelijkheid geven om er informatie naar te sturen alsof het een seriële of parallelle poort is (de goedkopere versies). In <<printing-advanced-network-rm,Printers geïnstalleerd op andere hosts>> wordt het voor de duurdere beschreven.

Het formaat van [.filename]#/etc/printcap# maakt het mogelijk om op te geven welke seriële, of parallelle poort gebruikt moet worden en (in geval van een seriële poort) de baud-snelheid, of er communicatie moet worden toegepast, vertragingen voor tabs, conversies voor nieuwe regelkarakters en meer. Er is geen mogelijkheid om een verbinding met een printer op te geven die op een TCP/IP of andere netwerkpoort luistert.

Om informatie naar een netwerkprinter te sturen, is het nodig een programma te ontwikkelen dat door tekst- en conversiefilters kan worden aangeroepen. Hier volgt een voorbeeld: het script `netprint` stuurt alle informatie van de standaard invoer naar een netwerkprinter. Als eerste argument wordt de hostnaam van de printer opgegeven en als tweede argument het poortnummer waarmee de verbinding moet worden opgezet. Er wordt alleen eenrichtingcommunicatie ondersteund (FreeBSD naar printer). Veel netwerkprinters ondersteunen tweewegcommunicatie. Het kan wenselijk zijn hiervan gebruik te maken (om printerstatus op te vragen, statistieken bij te houden, enzovoort).

[.programlisting]
....
#!/usr/bin/perl
#
#  netprint - Tekstfilter voor printer aangesloten op het netwerk
#  Geïnstalleerd in /usr/local/libexec/netprint
#
$#ARGV eq 1 || die "Usage: $0 <printer-hostname> <port-number>";

$printer_host = $ARGV[0];
$printer_port = $ARGV[1];

require 'sys/socket.ph';

($ignore, $ignore, $protocol) = getprotobyname('tcp');
($ignore, $ignore, $ignore, $ignore, $address)
    = gethostbyname($printer_host);

$sockaddr = pack('S n a4 x8', &AF_INET, $printer_port, $address);

socket(PRINTER, &PF_INET, &SOCK_STREAM, $protocol)
    || die "Can't create TCP/IP stream socket: $!";
connect(PRINTER, $sockaddr) || die "Can't contact $printer_host: $!";
while (<STDIN>) { print PRINTER; }
exit 0;
....

Dit script kan vervolgens in verschillende filters gebruikt worden. Stel dat een Diablo 750-N matrixprinter op het netwerk is aangesloten. Op poort 5100 accepteert de printer informatie om af te drukken. De hostnaam van de printer is `scrivener`. Hier volgt het tekstfilter voor de printer:

[.programlisting]
....
#!/bin/sh
#
#  diablo-if-net - Tekstfilter voor Diablo printer 'scrivener' luistert
#  op poort 5100. Geïnstalleerd in /usr/local/libexec/diablo-if-net
#
exec /usr/libexec/lpr/lpf "$@" | /usr/local/libexec/netprint scrivener 5100
....

[[printing-advanced-restricting]]
=== Printergebruik beperken

Nu volgt informatie over het beperken van printergebruik. Het LPD-systeem maakt het mogelijk te bepalen wie er toegang heeft tot een printer, zowel lokaal als op afstand, of meerdere kopieën afgedrukt mogen worden, hoe lang opdrachten mogen zijn en hoe lang wachtrijen mogen worden.

[[printing-advanced-restricting-copies]]
==== Meerdere kopieën beperken

Het LPD systeem maakt het heel makkelijk voor gebruikers om meerdere afdrukken van een bestand te maken. Gebruikers kunnen opdrachten afdrukken met bijvoorbeeld `lpr -#5` en krijgen dan vijf kopieën van elk bestand in de opdracht. De systeembeheerder kan beslissen of dit wenselijk is.

Wanneer meerdere kopieën onwenselijk zijn, kan de optie `-#` van man:lpr[1] worden uitgeschakeld door de optie `sc` in [.filename]##/etc/printcap## op te nemen. Als gebruikers opdrachten versturen met de optie `-#`, zien ze het volgende:

[source,shell]
....
lpr: multiple copies are not allowed
....

Als het mogelijk is van andere hosts af te drukken (zie <<printing-advanced-network-rm,Printers geïnstalleerd op andere hosts>>), moet de optie `sc` ook in [.filename]#/etc/printcap# van de andere hosts aanwezig zijn. Anders kunnen gebruikers nog steeds multi-kopie opdrachten van andere hosts sturen.

Hier volgt een voorbeeld. Hieronder staat [.filename]#/etc/printcap# voor de host `rose`. De printer `rattan` is redelijk krachtig, dus meerdere kopieën zijn toegestaan. De laserprinter `bamboo` is wat gevoeliger, dus meerdere kopieë zijn uitgeschakeld door de optie `sc` toe te voegen:

[.programlisting]
....
#
#  /etc/printcap voor host rose - beperk meerdere kopieën op bamboo
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:sd=/var/spool/lpd/rattan:\
        :lp=/dev/lpt0:\
        :if=/usr/local/libexec/if-simple:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:sc:\
        :lp=/dev/ttyu5:ms#-parenb cs8 clocal crtscts:rw:\
        :if=/usr/local/libexec/psif:\
        :df=/usr/local/libexec/psdf:
....

Nu moet ook de optie `sc` worden toegevoegd in [.filename]#/etc/printcap# van host `orchid` (tegelijk worden meerdere kopieën voor de printer `teak` uitgeschakeld):

[.programlisting]
....
#
#  /etc/printcap voor host orchid - geen meerdere kopieën voor lokale
#  printer teak of printer op afstand bamboo
teak|hp|laserjet|HP LaserJet 3Si:\
        :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:sc:\
        :if=/usr/local/libexec/ifhp:\
        :vf=/usr/local/libexec/vfhp:\
        :of=/usr/local/libexec/ofhp:

rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:sc:
....

Door de optie `sc` te gebruiken, wordt het gebruik van `lpr -#i` voorkomen, maar dat weerhoudt gebruikers er nog steeds niet van om man:lpr[1] meerdere keren te aanroepen of meerdere keren hetzelfde bestand te versturen in een opdracht:

[source,shell]
....
% lpr voorverkoop.teken voorverkoop.teken voorverkoop.teken voorverkoop.teken voorverkoop.teken
....

Er zijn vele manieren om dit misbruik te voorkomen (onder andere door het te negeren), welke vrij zijn om te verkennen.

[[printing-advanced-restricting-access]]
==== Printertoegang beperken

Door gebruik te maken van het UNIX(R) groepmechanisme en de optie `rg` in [.filename]#/etc/printcap# kan geregeld worden wie er op welke printer kan afdrukken. De gebruikers die toegang hebben tot een printer moeten in een groep worden geplaatst en deze groep moet in de optie `rg` worden genoemd.

Als gebruikers buiten de groep (inclusief `root`) naar de beheerde printer proberen te printen, worden ze begroet met het volgende bericht:

[source,shell]
....
lpr: Not a member of the restricted group
....

Net als met de optie `sc` (_suppress multiple copies_: onderdruk meerdere kopieën) moet `rg`, indien wenselijk, ook op andere hosts worden opgegeven die ook toegang hebben tot printers (zie <<printing-advanced-network-rm,Printers geïnstalleerd op andere hosts>>).

In het volgende voorbeeld heeft iedereen toegang tot de printer `rattan`, maar alleen gebruikers in de groep `artists` kunnen gebruik maken van `bamboo`. Hier volgt het bekende [.filename]#/etc/printcap# voor de host `rose`:

[.programlisting]
....
#
#  /etc/printcap voor host rose - beperkte toegang voor groep bamboo
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:sd=/var/spool/lpd/rattan:\
        :lp=/dev/lpt0:\
        :if=/usr/local/libexec/if-simple:

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:\
        :lp=/dev/ttyu5:ms#-parenb cs8 clocal crtscts:rw:\
        :if=/usr/local/libexec/psif:\
        :df=/usr/local/libexec/psdf:
....

De andere voorbeeldbestanden [.filename]#/etc/printcap# (voor de host `orchid`) worden niet aangepast. Natuurlijk kan iedereen op `orchid` afdrukken op `bamboo`. Het kan zijn dat er sowieso alleen bepaalde gebruikers op `orchid` zijn toegestaan en dat deze gebruikers toegang mogen hebben tot de printer. Of wellicht niet.

[NOTE]
====
Er kan per printer slechts één groep worden opgegeven.
====

[[printing-advanced-restricting-sizes]]
==== Grootte van afdrukopdrachten bepalen

Als veel gebruikers toegang hebben tot printers kan het nodig zijn een limiet op te geven voor de grootte van de bestanden die gebruikers naar een printer kunnen sturen. Er is immers slechts beperkte ruimte op het bestandssysteem en er moet ook voldoende ruimte zijn voor opdrachten van andere gebruikers.

LPD heeft de mogelijkheid om met de optie `mx` een limiet op te geven voor het maximum aantal bytes van een bestand in een afdrukopdracht. De eenheden worden opgegeven in `BUFSIZ` blokken, die 1024 bytes groot zijn. Een nul voor deze optie betekent geen limiet aan de bestandsgrootte. Als de optie wordt weggelaten, wordt een standaardlimiet van 1000 blokken gebruikt.

[NOTE]
====
De limiet heeft betrekking op de _bestanden_ in een opdracht, _niet_ op de totale grootte van een opdracht.
====

LPD weigert een bestand dat groter is dan de opgegeven limiet niet. In plaats daarvan plaatst het zo veel mogelijk van het bestand op de wachtrij, om dit vervolgens af te drukken. De rest wordt genegeerd. Of dit gedrag wenselijk is, is onderwerp van debat.

Nu worden limieten voor de voorbeeldprinters `rattan` en `bamboo` opgegeven. Aangezien de PostScript(R)-bestanden van die `artists` nogal groot kunnen worden, krijgen ze een limiet van vijf megabyte opgelegd. Er wordt geen limiet opgelegd voor de platte tekst printer:

[.programlisting]
....
#
#  /etc/printcap voor host rose
#

#
#  Geen limiet op opdrachtgrootte:
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:mx#0:sd=/var/spool/lpd/rattan:\
        :lp=/dev/lpt0:\
        :if=/usr/local/libexec/if-simple:

#
#  Limiet van vijf megabyte:
#
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\
        :lp=/dev/ttyu5:ms#-parenb cs8 clocal crtscts:rw:\
        :if=/usr/local/libexec/psif:\
        :df=/usr/local/libexec/psdf:
....

Ook hier zijn de limieten alleen van toepassing op lokale gebruikers. Als toegang tot deze printers van andere hosts mogelijk is, worden deze gebruikers niet beperkt. Het is daarom nodig de optie `mx` ook in de [.filename]#/etc/printcap# van de betreffende hosts op te geven. In <<printing-advanced-network-rm,Printers geïnstalleerd op andere hosts>> staat meer informatie over afdrukken op andere hosts.

Er is een andere gespecialiseerde manier om opdrachtgrootte voor printers op afstand te beperken (zie <<printing-advanced-restricting-remote,Opdrachten van hosts op afstand beperken>>.

[[printing-advanced-restricting-remote]]
==== Opdrachten van hosts op afstand beperken

Het wachtrijsysteem LPD beschikt over verschillende methoden om afdrukopdrachten van hosts op afstand te beperken:

Hostbeperkingen::
Met de bestanden [.filename]#/etc/hosts.equiv# en [.filename]#/etc/hosts.lpd# kan worden ingesteld van welke hosts op afstand een lokale LPD-opdracht wordt geaccepteerd. LPD controleert of een inkomend verzoek afkomstig is van een host die wordt genoemd in een van deze bestanden. Zo niet, dan weigert LPD het verzoek.
+
Het formaat van deze bestanden is eenvoudig: één host per regel. [.filename]#/etc/hosts.equiv# wordt ook gebruikt door het protocol man:ruserok[3] en heeft invloed op programma's als man:rsh[1] en man:rcp[1]. Voorzichtigheid is dus geboden.
+
Als voorbeeld volgt hier [.filename]#/etc/hosts.lpd# voor de host `rose`:
+
[.programlisting]
....
orchid
violet
madrigal.fishbaum.de
....
+
Dit betekent dat `rose` verzoeken accepteert van de hosts `orchid`, `violet` en `madrigal.fishbaum.de`. Voor iedere andere host die verbinding probeert te maken met LPD op `rose`, wordt de opdracht geweigerd.

Omvangbeperkingen::
De hoeveelheid vrije ruimte die over moet blijven op een bestandssysteem waar een wachtrij zich bevindt kan ook worden ingesteld. Hiervoor moet een bestand met de naam [.filename]#minfree# in de wachtrijmap worden aangemaakt. In dit bestand kan een getal worden gezet dat het aantal schijfblokken (512 bytes) aan vrije ruimte aangeeft dat beschikbaar moet blijven wil een opdracht worden geaccepteerd.
+
Hiermee kan worden gegarandeerd dat gebruikers op afstand een bestandssysteem niet vol kunnen schrijven. Ook kan hierdoor een soort voorrang worden gegeven aan lokale gebruikers: zij kunnen nog opdrachten plaatsen als de vrije schijfruimte al lang beneden de opgegeven limiet uit [.filename]#minfree# is gekomen.
+
Als voorbeeld wordt een bestand [.filename]#minfree# voor de printer `bamboo` toegevoegd. In [.filename]#/etc/printcap# staat de juiste wachtrijmap:
+
[.programlisting]
....
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\
        :lp=/dev/ttyu5:ms#-parenb cs8 clocal crtscts:rw:mx#5000:\
        :if=/usr/local/libexec/psif:\
        :df=/usr/local/libexec/psdf:
....
+
De wachtrijmap wordt opgegeven met de optie `sd`. Er wordt een limiet van drie megabyte ingesteld (wat gelijk staat aan 6144 schijfblokken) voor de hoeveelheid vrije schijfruimte die op het bestandssysteem beschikbaar moet zijn voordat LPD een opdracht op afstand accepteert:
+
[source,shell]
....
# echo 6144 > /var/spool/lpd/bamboo/minfree
....

Gebruikersbeperkingen::
Met de optie `rs` in [.filename]#/etc/printcap# kan worden geregeld welke gebruikers op afstand kunnen afdrukken op lokale printers. Als `rs` voorkomt voor een lokale printer accepteert LPD opdrachten van hosts op afstand _als_ de gebruiker die de opdracht wil plaatsen ook een account heeft met dezelfde gebruikersnaam op de lokale host. Anders weigert LPD de opdracht.
+
Deze optie is met name nuttig in een omgeving waar (bijvoorbeeld) verschillende afdelingen een netwerk delen en gebruikers de grenzen van de afdeling overschrijden. Door ze een account te geven op een systeem kunnen ze de aangesloten printers gebruiken vanaf het systeem van hun eigen afdeling. Wanneer ze _alleen_ gebruik mogen maken van de printers en niet van overige diensten op de computer, kunnen "tokenaccounts" worden aangemaakt, zonder thuismap en met een nutteloze shell als [.filename]#/usr/bin/false#.

[[printing-advanced-acct]]
=== Printergebruik administreren

Het kan nodig zijn om afdrukken te doorbelasten. Inkt en papier kosten geld en er zijn onderhoudskosten. Printers zitten vol met bewegende delen en hebben de neiging kapot te gaan. Nu is er gekeken naar de printers, het gebruikerspatroon en de onderhoudskosten en op basis hiervan is een prijs vastgesteld per pagina (of per centimeter, per meter, of per wat dan ook). Hoe wordt nu een administratie bijgehouden van gemaakte afdrukken?

Het slechte nieuws is dat het wachtrijsysteem LPD hierbij niet echt helpt. Het administreren van afdrukken is erg afhankelijk van het type printer, het afdrukformaat en de wensen die een systeembeheerder heeft ten aanzien van het doorbelasten van printergebruik.

Om het administreren te implementeren, is het nodig om aanpassingen te maken in de tekstfilter (om platte tekst opdrachten te belasten) en de conversiefilters (om opdrachten in andere bestandsformaten te belasten), om pagina's te tellen, of de printer te vragen hoeveel pagina's er zijn afgedrukt. Het volstaat niet om het eenvoudige uitvoerfilter te gebruiken, aangezien dit niet in staat is het gebruik te administreren. Zie <<printing-advanced-filter-intro,Filters>>.

In het algemeen zijn er twee manieren om gebruik te administreren:

* _Periodiek administreren_ is de meer gebruikelijke manier, omdat het waarschijnlijk makkelijker is. Als iemand een opdracht afdrukt, schrijft het filter de gebruiker, host en het aantal pagina's in een administratiebestand. Elke maand, semester, jaar, of een andere gewenste periode kunnen de administratiebestanden verzameld worden om het aantal afgedrukte pagina's op te tellen en het gebruik in rekening te brengen. De logboekbestanden kunnen vervolgens geschoond worden, zodat met een schone lei de volgende periode begonnen kan worden.
* _Directe administratie_ is minder gebruikelijk, waarschijnlijk omdat het moeilijker is. Met deze methode zorgen de filters ervoor dat gebruikers voor hun printergebruik worden afgerekend op het moment dat ze er gebruik van maken. Net als schijfquota is de administratie onmiddellijk. Hiermee wordt voorkomen dat gebruikers kunnen afdrukken wanneer ze over hun limiet zijn gegaan. Ook biedt dit de mogelijkheid voor gebruikers om hun afdrukquotum te controleren, of aan te passen. Deze methode vereist databasecode om gebruikers en hun quota bij te houden.

Het wachtrijsysteem LPD ondersteunt beide methoden op eenvoudige wijze. Aangezien de filters (meestal) moeten worden aangeleverd, moet ook de code voor de administratie worden geleverd. Er is echter een voordeel: er is grote flexibiliteit in de administratiemethode. Zo kan bijvoorbeeld gekozen worden tussen periodieke of directe administratie. Er kan gekozen worden welke informatie opgeslagen wordt: gebruikersnamen, hostnamen, type opdracht, aantal afgedrukte pagina's, hoe lang het afdrukken duurde, enzovoort. Dit alles kan worden gedaan door de filters aan te passen.

==== Kort door de bocht printeradministratie

FreeBSD wordt met twee programma's geleverd waarmee periodieke administratie direct kan worden opgezet. Het zijn het tekstfilter `lpf`, beschreven in <<printing-advanced-lpf,lpf: een tekstfilter>> en man:pac[8], een programma dat posten uit administratiebestanden verzamelt en optelt.

Zoals beschreven in de sectie over filters (<<printing-advanced-filters,Filters>>), roept LPD de tekst- en conversiefilters aan met de naam van het administratiebestand als argument. De filters kunnen dit argument gebruiken om te bepalen in welk bestand de gegevens voor de administratie moeten worden weggeschreven. De naam van dit bestand is afkomstig van de optie `af` uit [.filename]#/etc/printcap#. Als er geen absoluut pad wordt opgegeven, dan is de locatie relatief aan de wachtrijmap.

LPD start `lpf` met paginabreedte en -lengte argumenten (afkomstig uit de opties `pw` en `pl`). Het filter `lpf` gebruikt deze argumenten om te bepalen hoeveel papier er gebruikt zal worden. Nadat het bestand naar de printer is gestuurd, schrijft het een post in het administratiebestand. De posten zien er als volgt uit:

[.programlisting]
....
2.00 rose:andy
3.00 rose:kelly
3.00 orchid:mary
5.00 orchid:mary
2.00 orchid:zhang
....

Aangezien `lpf` geen ingebouwde logica voor bestandslocking kent, moet voor elke printer een apart administratiebestand gebruikt worden. Twee ``lpf``s kunnen elkaars posten corrumperen als ze tegelijk in hetzelfde bestand schrijven. De optie `af=acct` in [.filename]#/etc/printcap# biedt een makkelijke manier om er zeker van te zijn dat aparte bestanden worden gebruikt. Dan bevindt elk administratiebestand zich in de wachtrijmap van de betreffende printer en krijgt de naam [.filename]#acct# krijgen

Wanneer het tijd is om met gebruikers af te rekenen voor hun afdrukken, kan het programma man:pac[8] gedraaid worden. Ga naar de wachtrijmap van de printer waarvoor betaald moet worden en typ `pac`. Er verschijnt een dollar-centrische samenvatting zoals het volgende:

[source,shell]
....
  Login               pages/feet   runs    price
orchid:kelly                5.00    1   $  0.10
orchid:mary                31.00    3   $  0.62
orchid:zhang                9.00    1   $  0.18
rose:andy                   2.00    1   $  0.04
rose:kelly                177.00  104   $  3.54
rose:mary                  87.00   32   $  1.74
rose:root                  26.00   12   $  0.52

total                     337.00  154   $  6.74
....

Dit zijn de argumenten die man:pac[8] verwacht:

`-P _printer_`::
De _printer_ waarvoor een samenvatting moet worden gegenereerd. Deze optie werkt alleen als er een absoluut pad is gegeven in de optie `af` in [.filename]#/etc/printcap#.

`-c`::
Sorteer de uitvoer op kosten, in plaats van alfabetisch op gebruikersnaam.

`-m`::
Negeer de hostnamen in het administratiebestand. Met deze optie is de gebruiker `smith` op host `alpha` dezelfde gebruiker als `smith` op host `gamma`. Zonder deze optie zijn het verschillende gebruikers.

`-p _prijs_`::
Bereken de prijs met _prijs_ dollar per pagina of per voet, in plaats van de prijs uit de optie `pc` in [.filename]#/etc/printcap# of twee cent (de standaard). De _prijs_ kan worden opgegeven als een decimaal getal.

`-r`::
Keer de sorteervolgorde om.

`-s`::
Maak een bestand met een samenvatting van de administratie en leeg het administratiebestand.

_namen..._::
Druk de administratiegegevens alleen af voor gebruikersnamen _namen_.

In de standaard samenvatting die man:pac[8] genereert, is het aantal pagina's te zien dat iedere gebruiker vanaf een bepaalde host heeft afgedrukt. Wanneer de hostnaam niet van belang is (bijvoorbeeld omdat gebruikers iedere host kunnen gebruiken), gebruik dan `pac -m` om de volgende samenvatting te genereren:

[source,shell]
....
  Login               pages/feet   runs    price
andy                        2.00    1   $  0.04
kelly                     182.00  105   $  3.64
mary                      118.00   35   $  2.36
root                       26.00   12   $  0.52
zhang                       9.00    1   $  0.18

total                     337.00  154   $  6.74
....

Om het verschuldigde bedrag te berekenen gebruikt man:pac[8] de optie `pc` uit [.filename]#/etc/printcap# (standaard aantal van 200 of 2 cent per pagina). Specificeer, in honderden centen, de prijs per pagina of per voet die berekent moet worden. Deze waarde kan worden aangepast door man:pac[8] aan te roepen met de optie `-p`. De eenheden van de optie `-p` zijn echter in dollars, niet in honderden centen. Bijvoorbeeld,

[source,shell]
....
# pac -p1.50
....

zorgt ervoor dat elke pagina 1,50 dollar kost. U kunt echt grote winsten maken met deze optie.

Tenslotte kan met `pac -s` de samenvatting worden opgeslagen in een bestand dat dezelfde naam krijgt als het administratiebestand van de printer, maar dan met `_sum` toegevoegd aan de naam. Vervolgens wordt het administratiebestand geleegd. Als man:pac[8] opnieuw wordt aangeroepen, herleest man:pac[8] het samenvattingsbestand om de startwaarden te bepalen en telt daar de informatie bij op van het standaard administratiebestand.

==== Hoe kan het aantal afgedrukte pagina's worden geteld?

Om ook maar de minste nauwkeurigheid bij het administreren te verkrijgen, is het nodig te weten hoeveel papier een afdrukopdracht gebruikt. Dit is het centrale probleem van het bijhouden van printerstatistieken.

Voor opdrachten met platte tekst is het probleem niet zo moeilijk op te lossen: het aantal regels in een opdracht wordt geteld en vergeleken met het aantal regels per pagina dat door een printer wordt ondersteund. Hierbij moet niet worden vergeten dat backspaces in het bestand regels overschrijven en dat lange logische regels worden afgedrukt als meerdere fysieke regels.

Het tekstfilter `lpf` (geïntroduceerd in <<printing-advanced-lpf,lpf: een tekstfilter>>) houdt met deze zaken rekening bij het administreren. Als het nodig is een tekstfilter te schrijven dat ook het printergebruik moet bijhouden, dan is het nuttig de broncode van `lpf` te bestuderen.

Hoe worden andere bestandsformaten dan verwerkt?

Voor een DVI-naar-LaserJet, of DVI-naar-PostScript(R) conversie kan het filter de diagnostische uitvoer van `dvilj` of `dvips` bekijken om te bepalen hoeveel pagina's er zijn geconverteerd. Voor andere formaten kan hetzelfde worden gedaan met behulp van de betreffende conversieprogramma's.

Deze methoden hebben echter als nadeel dat een printer eventueel niet alle pagina's ook daadwerkelijk afdrukt. Zo kan het papier vast komen te zitten, de toner opraken of de printer ontploffen, terwijl de gebruiker toch moet betalen.

Dus, wat kan hieraan worden gedaan?

Er is slechts één _betrouwbare_ manier om _nauwkeurig_ te administreren. Dat is met behulp van een printer die kan vertellen hoeveel papier er is gebruikt. Deze moet vervolgens worden aangesloten met een seriële lijn, of een netwerkverbinding. Bijna alle PostScript(R)-printers hebben deze mogelijkheid, andere modellen en merken mogelijk ook (bijvoorbeeld Imagen netwerklaserprinters). De filters dienen voor deze printers aangepast te worden om het papierverbruik na elke opdracht te achterhalen en de administratieve informatie _alleen_ op deze waarde te baseren. Er is geen noodzaak om foutgevoelig regels te tellen of bestanden te analyseren.

Natuurlijk kan een beheerder ook vrijgevig zijn en alle afdrukken gratis maken.

[[printing-using]]
== Printers gebruiken

Hieronder wordt beschreven hoe printers die onder FreeBSD geïnstalleerd zijn gebruikt moeten worden. Nu volgt een overzicht van de commando's op gebruikersniveau:

man:lpr[1]::
Druk opdrachten af

man:lpq[1]::
Controleer printerwachtrijen

man:lprm[1]::
Verwijder opdrachten uit de wachtrij van een printer

Er is ook een administratief commando, man:lpc[8], beschreven in <<printing-lpc,Printers beheren>>, dat gebruikt wordt om printers en hun wachtrijen in te stellen.

Alledrie de commando's man:lpr[1], man:lprm[1] en man:lpq[1] accepteren een optie `-P__printernaam__` om aan te geven op welke printer uit [.filename]#/etc/printcap# een opdracht van toepassing is. Dit biedt de mogelijkheid opdrachten te versturen, verwijderen en controleren voor verschillende printers. Als `-P` niet wordt gebruikt, werken deze commando's op de printer gedefinieerd in de omgevingsvariabele `PRINTER`. Tot slot, wanneer de omgevingsvariabele `PRINTER` niet is gedefinieerd, wordt standaard verwezen naar de printer met de naam `lp`.

[[printing-lpr]]
=== Opdrachten afdrukken

Om bestanden af te drukken:

[source,shell]
....
% lpr bestandsnaam ...
....

Dit drukt elk van de opgegeven bestanden af op de standaard printer. Als geen bestanden worden opgegeven, drukt man:lpr[1] de standaard invoer af. De volgende opdracht drukt bijvoorbeeld een paar belangrijke systeembestanden af:

[source,shell]
....
% lpr /etc/host.conf /etc/hosts.equiv
....

Om een specifieke printer te selecteren:

[source,shell]
....
% lpr -P printernaam bestandsnaam ...
....

Dit voorbeeld drukt een lange opgave van de huidige map af op de printer `rattan`:

[source,shell]
....
% ls -l | lpr -P rattan
....

Omdat er geen bestanden worden meegegeven aan het commando man:lpr[1], drukt `lpr` de gegevens af die het van de standaard invoer leest: de uitvoer van het commando `ls -l`.

man:lpr[1] accepteert ook een breed scala aan opties om de vorm aan te passen, bestandsconversies toe te passen, meerdere kopieën af te drukken, enzovoort. Meer informatie staat in <<printing-lpr-options,Afdrukopties>>.

[[printing-lpq]]
=== Opdrachten controleren

Als man:lpr[1] wordt gebruikt om af te drukken, dan worden de gegevens die afdrukt moet worden in een pakketje samengevoegd dat een "afdrukopdracht" wordt genoemd en naar het wachtrijsysteem LPD gestuurd. Elke printer heeft een wachtrij met opdrachten van alle gebruikers. Een printer drukt deze opdrachten op volgorde van binnenkomst af.

De wachtrij voor de standaardprinter kan worden weergegeven met man:lpq[1]. Voor een specifieke printer moet de optie `-P` meegegeven worden. Het volgende commando toont de wachtrij van printer `bamboo`:

[source,shell]
....
% lpq -P bamboo
....

Hieronder volgt een voorbeeld van de uitvoer van het commando `lpq`:

[source,shell]
....
bamboo is ready and printing
Rank   Owner    Job  Files                              Total Size
active kelly    9    /etc/host.conf, /etc/hosts.equiv   88 bytes
2nd    kelly    10   (standard input)                   1635 bytes
3rd    mary     11   ...                                78519 bytes
....

Dit laat drie opdrachten zien in de wachtrij voor `bamboo`. De eerste opdracht, gegeven door gebruiker `kelly`, heeft opdrachtnummer 9 gekregen. Elke opdracht voor een printer krijgt een uniek opdrachtnummer. Dit nummer kan in de meeste gevallen genegeerd worden, maar is nodig om een opdracht te annuleren. In <<printing-lprm,Opdrachten verwijderen>> staan meer details.

Opdrachtnummer negen bestaat uit twee bestanden; meerdere bestanden opgegeven naar man:lpr[1], worden als één enkele opdracht behandeld. Het is de actieve opdracht (`active` onder de kolom "Rank"), wat betekent dat de printer deze opdracht momenteel aan het afdrukken is. De tweede opdracht bestaat uit gegevens doorgegeven aan man:lpr[1] als standaard invoer. De derde opdracht is afkomstig van gebruiker `mary`. Het is een veel grotere opdracht. De bestandsnaam van het bestand dat ze probeert af te drukken is te lang voor het overzicht, daarom toont man:lpq[1] drie puntjes.

De allereerste regel uitvoer van man:lpq[1] is ook handig: die vertelt wat de printer momenteel aan het doen is; dat wil zeggen, wat LPD denkt dat de printer aan het doen is.

Het commando man:lpq[1] ondersteunt ook een optie `-l` om een gedetailleerd, lang overzicht te geven. Hieronder volgt voorbeelduitvoer van `lpq -l`:

[source,shell]
....
waiting for bamboo to become ready (offline ?)
kelly: 1st				 [job 009rose]
       /etc/host.conf                    73 bytes
       /etc/hosts.equiv                  15 bytes

kelly: 2nd				 [job 010rose]
       (standard input)                  1635 bytes

mary: 3rd                                [job 011rose]
      /home/orchid/mary/research/venus/alpha-regio/mapping 78519 bytes
....

[[printing-lprm]]
=== Opdrachten verwijderen

Een gebruiker die van gedachten verandert over een af te drukken opdracht, kan een opdracht uit een wachtrij halen met het commando man:lprm[1]. Vaak kan met man:lprm[1] zelfs een actieve opdracht worden verwijderd, maar een deel of alles van de opdracht kan desondanks toch worden afgedrukt.

Om een opdracht van de standaardprinter te verwijderen dient eerst met man:lpq[1] het opdrachtnummer gevonden te worden. Typ vervolgens:

[source,shell]
....
% lprm opdrachtnummer
....

Om een opdracht van een specifieke printer te verwijderen, moet de optie `-P` worden toegevoegd. Het volgende commando verwijdert opdrachtnummer 10 uit de wachtrij van printer `bamboo`:

[source,shell]
....
% lprm -P bamboo 10
....

Het commando man:lprm[1] heeft een aantal snelkoppelingen:

lprm -::
Verwijder alle opdrachten (voor de standaardprinter) van de huidige gebruiker.

lprm _gebruiker_::
Verwijder alle opdrachten (voor de standaardprinter) die van _gebruiker_ zijn. De supergebruiker kan opdrachten van andere gebruikers verwijderen. Andere gebruikers kunnen alleen hun eigen opdrachten verwijderen.

lprm::
Zonder een opdrachtnummer, gebruikersnaam of `-` op de opdrachtregel, verwijdert man:lprm[1] de huidige actieve opdracht van de huidige gebruiker op de standaard printer. Alleen de supergebruiker kan iedere actieve opdracht verwijderen.

Gebruik de optie `-P` met bovenstaande snelkoppelingen om een specifieke printer in plaats van de standaard printer te selecteren. Het volgende voorbeeld verwijdert alle opdrachten van de huidige gebruiker uit de wachtrij van printer `rattan`:

[source,shell]
....
% lprm -P rattan -
....

[NOTE]
====
Als in een netwerkomgeving wordt gewerkt, staat man:lprm[1] alleen toe opdrachten te verwijderen vanaf hosts waarvan de afdrukopdrachten zijn gegeven, ook als dezelfde printer vanaf andere hosts bereikbaar is. Het volgende voorbeeld demonstreert dit:

[source,shell]
....
% lpr -P rattan mijnbestand
% rlogin orchid
% lpq -P rattan
Rank   Owner	  Job  Files                          Total Size
active seeyan	  12	...                           49123 bytes
2nd    kelly      13   myfile                         12 bytes
% lprm -P rattan 13
rose: Permission denied
% logout
% lprm -P rattan 13
dfA013rose dequeued
cfA013rose dequeued
....

====

[[printing-lpr-options]]
=== Meer dan platte tekst: afdrukopties

Het commando man:lpr[1] ondersteunt een aantal opties voor de opmaak van platte tekst, het converteren van grafische en andere bestandsformaten, het afdrukken van meerdere kopieën, afwikkeling van een opdracht en meer. In deze sectie worden die opties beschreven.

[[printing-lpr-options-format]]
==== Opties voor opmaak en conversie

De volgende opties voor man:lpr[1] zorgen voor de opmaak van de bestanden in de opdracht. Gebruik deze opties als de opdracht geen platte tekst bevat of als platte tekst opgemaakt dient te worden met behulp van man:pr[1].

Het volgende commando drukt bijvoorbeeld een DVI-bestand af (van het TeX typesettingsysteem) met de naam [.filename]#visrapport.dvi# op de printer `bamboo`:

[source,shell]
....
% lpr -P bamboo -d visrapport.dvi
....

Deze opties zijn van toepassing op alle bestanden in de opdracht. Het is dus niet mogelijk om bijvoorbeeld DVI- en ditroff-bestanden in een opdracht samen te voegen. In plaats hiervan moeten deze bestanden als aparte opdrachten worden gegeven, elk met een andere conversie-optie.

[NOTE]
====
Al deze opties, behalve `-p` en `-T`, vereisen dat er conversiefilters zijn geïnstalleerd voor een printer. De optie `-d` vereist bijvoorbeeld het DVI-conversiefilter. In <<printing-advanced-convfilters,Conversiefilters>> staan de details beschreven.
====

`-c`::
Afdrukken van cifplot-bestanden.

`-d`::
Afdrukken van DVI-bestanden.

`-f`::
Afdrukken van FORTRAN tekstbestanden.

`-g`::
Afdrukken van plotgegevens.

`-i _aantal_`::
De uitvoer wordt _aantal_ kolommen ingesprongen. Als _nummer_ wordt weggelaten, wordt acht kolommen ingesprongen. Deze optie werkt alleen met bepaalde conversiefilters.
+
[NOTE]
====
Plaats geen spatie tussen de `-i` en het nummer.
====

`-l`::
Drukt letterlijke tekstgegevens af, inclusief controlekarakters.

`-n`::
Afdrukken van ditroff (apparaatonafhankelijke troff) gegevens.

-p::
Opmaak van platte tekst met man:pr[1] alvorens af te drukken. Zie man:pr[1] voor meer informatie.

`-T _titel_`::
Gebruik _titel_ op de man:pr[1] koptekst in plaats van de bestandsnaam. Deze optie heeft alleen effect in combinatie met de optie `-p`.

`-t`::
Afdrukken van troffgegevens.

`-v`::
Afdrukken van rastergegevens.

In het volgende voorbeeld wordt een mooi opgemaakte versie van de handleiding man:ls[1] afgedrukt op de standaardprinter:

[source,shell]
....
% zcat /usr/shared/man/man1/ls.1.gz | troff -t -man | lpr -t
....

Het commando man:zcat[1] pakt de broncode van de man:ls[1] handleiding uit en geeft het door aan het commando man:troff[1], dat de broncode opmaakt, er GNU troff van maakt en dit doorstuurt naar man:lpr[1], dat de opdracht naar de LPD wachtrij stuurt. Omdat de optie `-t` meegeven wordt aan man:lpr[1], converteert het wachtrijsysteem de GNU troff uitvoer naar een formaat dat de standaardprinter begrijpt als de opdracht wordt afgedrukt.

[[printing-lpr-options-job-handling]]
==== Opties voor opdrachtafhandeling

De volgende opties voor man:lpr[1] geven LPD aan de opdracht speciaal te behandelen:

-# _kopieën_::
Produceer een aantal van _kopieën_ kopieën van elk bestand in de opdracht, in plaats van één kopie. Een beheerder kan deze optie uitschakelen om slijtage van de printer te voorkomen en gebruik van een kopieerapparaat aan te moedigen. Zie <<printing-advanced-restricting-copies,Meerdere kopieën beperken>>.
+
Dit voorbeeld drukt drie kopieën af van [.filename]#parser.c# gevolgd door drie kopieën van [.filename]#parser.h# op de standaardprinter:
+
[source,shell]
....
% lpr -#3 parser.c parser.h
....

-m::
Stuur een email na voltooiing van de afdrukopdracht. Met deze optie stuurt het LPD-systeem een email als een opdracht is afgehandeld. In dit bericht vertelt het of de opdracht succesvol is uitgevoerd of dat er een fout was met (vaak) de aard van de fout.

-s::
Kopieer de bestanden niet naar de wachtrijmap, maar maak in plaats hiervan een symbolische link.
+
Bij het afdrukken van een grote opdracht is het handig van deze optie gebruik te maken. Het spaart ruimte in de wachtrijmap (het kan zijn dat de opdracht de vrije ruimte verbruikt in het bestandssysteem waarin de wachtrijmap zich bevindt). Het bespaart ook tijd, omdat LPD niet elke byte van de opdracht naar de wachtrijmap hoeft te kopieëren.
+
Er is echter een nadeel: aangezien LPD het originele bestand nodig heeft, is het niet mogelijk dit te wijzigen, of te verwijderen totdat het is afgedrukt.
+
[NOTE]
====
Bij het afdrukken op een printer in een netwerk, moet LPD een bestand uiteindelijk toch kopieëren van een lokale host naar een netwerkhost. De optie `-s` bespaart dus ruimte in een lokale wachtrijmap, niet in die van een host in een netwerk. Het blijft echter nuttig.
====

-r::
Verwijder bestanden in een opdracht na ze naar een wachtrij gekopieerd te hebben of na ze te hebben afgedrukt als de optie `-s` is gebruikt. Wees voorzichtig met deze optie!

[[printing-lpr-options-misc]]
==== Voorbladopties

Deze opties voor man:lpr[1] passen de tekst aan die gewoonlijk op het voorblad van een opdracht verschijnt. Deze opties hebben geen effect als het afdrukken van voorbladen wordt onderdrukt op een gebruikte printer. Zie <<printing-advanced-header-pages,Voorbladen>> voor meer informatie over het opzetten van voorbladen.

-C _tekst_::
Vervang de hostnaam op het voorblad door _tekst_. De hostnaam is gewoonlijk de naam van de host waarvan de opdracht is verstuurd.

-J _tekst_::
Vervang de naam van de opdracht op het voorblad door _tekst_. De naam van de opdracht is standaard de naam van het eerste bestand in de opdracht of [.filename]#stdin# als de standaard uitvoer wordt afgedrukt.

-h::
Druk geen voorblad af.
+

[NOTE]
====
Bij sommige installaties kan het zijn dat deze optie geen effect heeft door de manier waarop de voorbladen worden gegenereerd. Zie <<printing-advanced-header-pages,Voorbladen>> voor de details.
====

[[printing-lpc]]
=== Printers beheren

De beheerder van de printers in een netwerk heeft deze moeten installeren, opzetten en testen. Met het commando man:lpc[8] kan een beheerder op nog meer manieren communiceren met printers. Met man:lpc[8] is het mogelijk om:

* Printers te starten en te stoppen;
* Wachtrijen aan en uit te zetten;
* De volgorde van opdrachten in elke wachtrij aan te passen.

Ten eerste een opmerking over terminologie: als een printer is _gestopt_, drukt die niets uit een wachtrij af. Gebruikers kunnen nog steeds opdrachten geven, maar opdrachten wachten in een wachtrij totdat de bijbehorende printer is _gestart_ of als de wachtrij vrij is.

Als een wachtrij is _uitgeschakeld_, kan geen enkele gebruiker (behalve `root`) opdrachten naar een printer versturen. Een _ingeschakelde_ wachtrij accepteert opdrachten. Een printer met een uitgeschakelde wachtrij kan worden _gestart_ en drukt dan alle afdrukopdrachten in de wachtrij af tot deze leeg is.

In het algemeen is het nodig `root`-rechten te hebben om het commando man:lpc[8] te gebruiken. Gewone gebruikers kunnen het commando man:lpc[8] gebruiken om een printerstatus op te vragen en om een vastgelopen printer te herstarten.

Nu volgt een samenvatting van de man:lpc[8] commando's. De meeste commando's accepteren een argument _printernaam_, om aan te geven op welke printer te werken. Om op alle printers te werken die in [.filename]#/etc/printcap# genoemd worden, kan `all` worden gebruikt als _printernaam_.

`abort printernaam`::
Annuleer de huidige opdracht en stop de printer. Gebruikers kunnen nog steeds opdrachten versturen als de wachtrij is ingeschakeld.

`clean printernaam`::
Verwijder oude bestanden uit de wachtrijmap van de betreffende printer. Het kan wel eens gebeuren dat de bestanden waaruit een opdracht bestaat niet juist worden verwijderd door LPD. Dit gebeurt bijvoorbeeld wanneer er fouten zijn opgetreden tijdens het afdrukken of tijdens grote administratieve activiteit. Dit commando vindt en verwijdert bestanden die niet in de wachtrijmap thuishoren.

`disable printernaam`::
Nieuwe opdrachten kunnen niet meer in de wachtrij worden geplaatst. Als de printer nog draait, drukt die de opdrachten die zich nog in de wachtrij bevinden af. De supergebruiker (`root`) kan altijd opdrachten versturen, ook naar een uitgeschakelde wachtrij.
+
Dit commando is handig bij het testen van een nieuwe printer of een filterinstallatie: schakel de wachtrij uit en verstuur als `root` opdrachten. Andere gebruikers kunnen geen opdrachten versturen totdat het testen is voltooid en de wachtrij weer is ingeschakeld met het commando `enable`.

`down printernaam boodschap`::
Schakel een printer uit. Equivalent aan `disable` gevolgd door `stop`. De _boodschap_ verschijnt als de status van de printer als een gebruiker de wachtrij van de printer controleert met man:lpq[1] of de status met `lpc status`.

`enable printernaam`::
Schakel de wachtrij van een printer in. Gebruikers kunnen opdrachten versturen, maar de printer drukt ze pas af als deze is gestart.

`help commandonaam`::
Geef hulp over het commando _commandonaam_. Zonder _commandonaam_, wordt een samenvatting van de beschikbare commando's getoond.

`restart printernaam`::
Start de printer. Gewone gebruikers kunnen dit commando gebruiken als door een uitzonderlijke omstandigheid LPD hangt, maar ze kunnen een printer niet starten die gestopt is met een van de commando's `stop` of `down`. Het commando `restart` is equivalent aan `abort` gevolgd door `start`.

`start printernaam`::
Start de printer. De printer drukt opdrachten in zijn wachtrij af.

`stop printernaam`::
Stop de printer. De printer maakt de huidige opdracht af en drukt opdrachten in de wachtrij niet af. Gebruikers kunnen nog steeds opdrachten versturen naar een ingeschakelde wachtrij, ook al is de printer gestopt.

`topq printernaam opdracht-of-gebruikersnaam`::
Herschik de wachtrij voor _printernaam_ door de opdrachten met de opgegeven _opdracht_ nummers of opdrachten van _gebruikersnaam_ bovenaan de wachtrij te plaatsen. Voor dit commando is het niet mogelijk `all` te gebruiken als _printernaam_.

`up printernaam`::
Schakel een printer in. Het omgekeerde van het commando `down`. Equivalent aan `start` gevolgd door `enable`.

man:lpc[8] accepteert bovenstaande commando's op de opdrachtregel. Als er geen commando's worden gegeven, schakelt man:lpc[8] over op een interactieve modus, waar opdrachten gegeven kunnen worden totdat het commando `exit`, `quit` of einde-van-bestand wordt gegeven.

[[printing-lpd-alternatives]]
== Alternatieven voor het standaard wachtrijsysteem

Na het lezen van deze handleiding, heeft de lezer zo'n beetje alles gelezen wat er te leren valt over het wachtrijsysteem LPD zoals het te vinden is in FreeBSD. Er zijn veel tekortkomingen te onderkennen, wat vanzelf leidt tot de vraag: "Welke andere wachtrijsystemen zijn er beschikbaar (en werken onder FreeBSD)?"

LPRng::
LPRng, dat "LPR: the Next Generation" betekent, is een compleet herschreven PLP. Patrick Powell en Justin Mason (de voornaamste beheerder van PLP) hebben samengewerkt om LPRng te maken. De thuispagina voor LPRng is http://www.lprng.org/[http://www.lprng.org/].

CUPS::
CUPS, het Common UNIX Printing System, voorziet in een overzetbare printlaag voor UNIX(R)-achtige besturingssystemen. Het is ontwikkeld door Easy Software Product, om een standaard afdrukoplossing voor alle UNIX(R)-producenten en gebruikers te promoten.
+
CUPS gebruikt het Internet Printing Protocol (IPP) als basis voor het beheren van afdrukopdrachten en wachtrijen. De protocollen Line Printer Daemon (LPD), Server Message Block (SMB) en AppSocket (ook bekend als JetDirect) worden ook ondersteund met minder functionaliteit. CUPS biedt bladeren naar netwerkprinters en PostScript(R) Printer Description (PPD) gebaseerde afdrukopties om echt printen onder UNIX(R) te ondersteunen.
+
De thuispagina voor CUPS is http://www.cups.org/[http://www.cups.org/].

HPLIP::
HPLIP, het HP Linux(R) Imaging and Printing systeem, is een suite van programma's ontwikkeld door HP dat printen, scannen en faxen voor toepassingen van HP ondersteunt. Deze suite van programma's maakt gebruikt van het printsysteem CUPS als een backend voor sommige van de printmogelijkheden.
+
De thuispagina voor HPLIP is http://hplipopensource.com/hplip-web/index.html[http://hplipopensource.com/hplip-web/index.html].

[[printing-troubleshooting]]
== Problemen oplossen

Na het uitvoeren van een simpele test met man:lptest[1] is mogelijk een van onderstaande resultaten verkregen, in plaats van de juiste uitvoer:

Het werkte na enige tijd of er kwam geen volle pagina.::
De printer drukte bovenstaande af, maar wachtte enige tijd zonder iets te doen. Het was zelfs nodig om een PRINT REMAINING, of FORM FEED-knop op te printer in te drukken om enig resultaat te krijgen.
+
Als dit het geval is, dan stond de printer waarschijnlijk te wachten of er nog meer gegevens van de opdracht zouden komen, alvorens iets af te drukken. Om dit probleem op te lossen, kan het tekstfilter worden aangepast zodat deze een FORM FEED-karakter (of wat er ook nodig is) naar de printer stuurt. Dit is meestal voldoende om een printer zover te krijgen om tekst af te drukken die zich nog in de interne buffer bevindt. Het is ook nuttig om er zeker van te zijn dat elke afdrukopdracht eindigt op een hele pagina, zodat de volgende opdracht niet ergens midden op de laatste pagina van de vorige opdracht begint.
+
De volgende vervanging voor het shellscript [.filename]#/usr/local/libexec/if-simple# drukt een form feed af nadat de opdracht naar een printer is gestuurd:
+
[.programlisting]
....
#!/bin/sh
#
# if-simple - Eenvoudige tekst invoerfilter voor lpd
# Geïinstalleerd in /usr/local/libexec/if-simple
#
# Kopieert eenvoudig stdin naar stdout.  Negeer alle filterargumenten.
# Schrijft een form feed karakter (\f) na het afdrukken van de opdracht.

/bin/cat && printf "\f" && exit 0
exit 2
....

De opdracht produceerde een getrapt effect.::
Het resultaat ziet er als volgt uit:
+
[source,shell]
....
!"#$%&'()*+,-./01234
                "#$%&'()*+,-./012345
                                 #$%&'()*+,-./0123456
....
+
Dit krijgen slachtoffers van het _trapeffect_ te zien. Het wordt veroorzaakt door conflicterende interpretaties van de karakters die een regeleinde aangeven. UNIX(R)-achtige besturingssystemen gebruiken een enkel karakter: ASCII-code 10, de line feed (LF). MS-DOS(R), OS/2(R) en andere besturingssystemen gebruiken twee karakters: ASCII-code 10 _en_ ASCII-code 13 (de carriage return, CR). Veel printers gebruiken de MS-DOS(R)-conventie voor het representeren van regeleinden.
+
Als onder FreeBSD wordt afgedrukt, bevat de tekst alleen het line feed-karakter. Na het zien van een line feed-karakter vervolgt de printer zijn werk op de volgende regel, maar behoudt dezelfde horizontale positie op de pagina voor het afdrukken van het volgende teken. Hier is de carriage return voor bedoeld: om het volgende karakter af te drukken aan de linkerkant van de pagina.
+
Dit is wat FreeBSD wil dat de printer doet:
+
[.informaltable]
[cols="1,1", frame="none"]
|===

|Printer ontvangt CR
|Printer drukt CR af

|Printer ontvangt LF
|Printer drukt CR + LF af
|===
+
Hier volgen een aantal manieren om dit te bereiken:

** Gebruik de instellingentoetsen of het bedieningspaneel van de printer om de interpretatie van deze karakters aan te passen. Controleer de handleiding van de printer om uit te vinden hoe dit moet.
+
[NOTE]
====
Als een systeem in een ander besturingssysteem dan FreeBSD wordt opgestart, kan het nodig zijn een printer _opnieuw_ in te stellen, zodat die een interpretatie voor CR- en LF-karakters gebruikt die bij dat andere besturingssysteem horen. Het kan de voorkeur genieten een van onderstaande oplossingen te gebruiken.
====

** Zorg dat het seriële lijnstuurprogramma van FreeBSD automatisch LF naar CR+LF converteert. Dit werkt natuurlijk _alleen_ voor printers op een seriële poort. Gebruik de optie `ms#` en zet de modus `onlcr` in het bestand [.filename]#/etc/printcap# voor de printer om deze functionaliteit in te schakelen.
** Stuur een _escape-code_ naar een printer om tijdelijk LF-karakters anders te behandelen. Raadpleeg hiervoor de handleiding van de printer om escape-codes te achterhalen die de printer ondersteunt. Als de juiste escape-code is gevonden, moet de tekstfilter worden aangepast zodat deze eerst de code stuurt en vervolgens de afdrukopdracht.
+ 
Hier volgt een eenvoudig tekstfilter voor printers die HP PCL-escape-codes begrijpen. Dit filter zorgt dat een printer LF-karakters behandelt als LF en CR, vervolgens verstuurt het de opdracht en tot slot een form feed om de laatste pagina in de opdracht uit te voeren. Het zou met alle HP printers moeten werken.
+
[.programlisting]
....
#!/bin/sh
#
# hpif - Eenvoudig tekst invoerfilter voor lpd voor HP PCL-printers
# Geïnstalleerd in /usr/local/libexec/hpif
#
# Kopieert eenvoudig stdin naar stdout.  Negeert alle filterargumenten.
# Vertelt de printer om LF te zien als CR+LF.
# Werpt de pagina uit na voltooiing.

printf "\033&k2G" && cat && printf "\033&l0H" && exit 0
exit 2
....
+ 
Nu volgt een voorbeeldbestand [.filename]#/etc/printcap# voor host `orchid`. Er is een printer aangesloten op de eerste parallelle poort; een HP LaserJet 3Si, genaamd `teak`. Die gebruikt bovenstaand script als tekstfilter:
+
[.programlisting]
....
#
#  /etc/printcap voor host orchid
#
teak|hp|laserjet|HP LaserJet 3Si:\
        :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\
        :if=/usr/local/libexec/hpif:
....

De regels zijn over elkaar afgedrukt.::
De printer is nooit een regel opgeschoven. Alle regels tekst lopen over elkaar en zijn op dezelfde regel afgedrukt.
+
Dit probleem is het "omgekeerde" van het trapeffect, zoals boven beschreven, en is veel zeldzamer. Ergens worden de LF-karakters die FreeBSD gebruikt om een regel te eindigen gezien als CR-karakters om de afdruklocatie te verplaatsen naar de linkerkant van het papier, zonder óók een regel naar beneden te gaan.
+
Gebruik de instellingentoetsen, of het bedieningspaneel van de printer om de volgende interpretatie van LF en CR af te dwingen:
+
[.informaltable]
[cols="1,1", frame="none", options="header"]
|===
| Printer ontvangt
| Printer drukt af

|CR
|CR

|LF
|CR + LF
|===
De printer is karakters kwijt.::
Tijdens het afdrukken heeft de printer een paar karakters per regel niet afgedrukt. Het kan zijn dat het probleem erger werd naarmate de printer zijn werk deed, steeds meer karakters verliezend.
+
Het probleem is dat de printer de snelheid waarmee de computer gegevens over een seriële lijn stuurt niet bij kan houden (dit probleem zou zich niet voor moeten doen met printers op een parallelle poort). Er zijn twee manieren om dit probleem te verhelpen:

** Als de printer XON/XOFF flow-control ondersteunt, zorg dan dat FreeBSD dit gebruikt door de modus `ixon` in de optie `ms#` te specificeren.
** Als de printer de Request to Send / Clear to Send hardware-handshake ondersteunt, (ook bekend als `RTS/CTS`), specificeer dan de modus `crtscts` in de optie `ms#`. Zorg dat de bedrading van de kabel die printer met de computer verbindt juist is voor hardware flow-control.

Er werd onzin afgedrukt.::
Het lijkt alsof de printer willekeurige onzin afdrukte en niet de gewenste tekst.
+
Dit is meestal een ander symptoom van verkeerde communicatieparameters voor een seriële printer. Controleer de bps-snelheid in de optie `br` en de instelling voor pariteit in de optie `ms#`. Wees er zeker van dat de printer dezelfde instellingen gebruikt als in het bestand [.filename]#/etc/printcap# worden opgegeven.

Er gebeurde niets.::
Als er niets gebeurde, ligt het probleem waarschijnlijk bij FreeBSD en niet bij de hardware. Voeg de optie logboekbestand (`lf`) toe in [.filename]#/etc/printcap# voor de betreffende printer. Hier is bijvoorbeeld de definitie voor `rattan` met de optie `lf`:
+
[.programlisting]
....
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :sh:sd=/var/spool/lpd/rattan:\
        :lp=/dev/lpt0:\
        :if=/usr/local/libexec/if-simple:\
        :lf=/var/log/rattan.log
....
+
Probeer vervolgens nogmaals af te drukken. Controleer het logboekbestand (in dit voorbeeld [.filename]#/var/log/rattan.log#) op mogelijke foutmeldingen. Probeer op basis van deze melding het probleem te verhelpen.
+
Als er geen optie `lf` is opgegeven, gebruikt LPD [.filename]#/dev/console# als standaard.
