Verder Terug Inhoud

7. Hoe zaken in te stellen, basis

7.1 Traditionele lpd configuratie

De minimale setup voor lpd resulteert in een systeem die de bestanden in een wachtrij kan plaatsen en ze kan afdrukken. Het zal er geen enkele aandacht aan schenken, of je printer ze zal begrijpen of niet, en zal je waarschijnlijk geen aantrekkelijke uitvoer laten produceren. Toch is het de eerste stap naar begrip, dus lees verder!

Om een afdrukwachtrij aan lpd toe te voegen, moet je een record in /etc/printcap, en de nieuwe spooldirectory onder /var/spool/lpd aanmaken.

Een record in /etc/printcap ziet er ongeveer zo uit:

# LOCAL djet500
lp|dj|deskjet:\
        :sd=/var/spool/lpd/dj:\
        :mx#0:\
        :lp=/dev/lp0:\
        :sh:
Hiermee wordt een spool met de naam lp, dj, of deskjet gedefinieerd, tijdelijke opslag in de directory /var/spool/lpd/dj, zonder een maximumlimiet per taak, die afdrukt naar het device /dev/lp0, en zonder bannerpage (met de naam van de persoon die het afdrukte, enz) aan het begin van de afdruktaak toegevoegd.

Lees nu de manpage voor printcap.

Het bovenstaande lijkt zeer eenvoudig, maar er is een valstrik - tenzij ik bestanden verstuur die een DeskJet 500 kan begrijpen, zal deze DeskJet vreemde dingen afdrukken. Het versturen van bijvoorbeeld een gewoon Unix-tekstbestand naar een Deskjet resulteert in letterlijk geïnterpreteerde newlines, en geeft me:

Dit is regel één.
                 Dit is regel twee.
                                  Dit is regel drie.
Het afdrukken van een PostScript bestand naar deze spool zou resulteren in een prachtige lijst met PostScript-commando's, afgedrukt met dit "staircase effect", maar geeft geen bruikbare uitvoer.

Er is duidelijk meer voor nodig, en dit is het doel van filteren. De oplettenden onder jullie, die de printcap manpage hebben gelezen, is misschien de kenmerken if en of opgevallen. if, of de invoerfilter, is nu net wat we hier nodig hebben.

Als we een klein shell-script met de naam filter schrijven waarmee carriage returns voor de newlines worden ingevoegd, kan het trapsgewijze afdrukken worden uitgeschakeld. Dus we moeten een if regel aan ons printcap-record van hierboven toevoegen:

lp|dj|deskjet:\
        :sd=/var/spool/lpd/dj:\
        :mx#0:\
        :lp=/dev/lp0:\
        :if=/var/spool/lpd/dj/filter:\
        :sh:
Een eenvoudig filterscript zou kunnen zijn:
#!perl
# In de regel hierboven zou het hele pad naar perl moeten worden opgenomen
# Dit script moet uitvoerbaar zijn: chmod 755 filter
while(<STDIN>){chop $_; print "$_\r\n";};
# Je wilt misschien ook nog met een form feed eindigen: print "\f";
Als we het bovenstaande zouden doen, zouden we een spool hebben waarnaar we reguliere Unix tekstbestanden zouden kunnen printen om zinvolle resultaten te verkrijgen. (Ja, er zijn vier miljoen betere manieren om dit filter te schrijven, maar weinig zo illustratief. Je wordt aangemoedigd dit efficiënter te doen.)

Het enige resterende probleem is het afdrukken van plain tekst - zeker het zou beter zijn om PostScript en andere geformatteerde grafische uitvoer te kunnen afdrukken. Ja, dat is zo, en het is makkelijk te doen. De methode is eenvoudig een uitbreiding van het hierbovenstaande linefeed-herstel filter. Als je een filter schrijft dat willekeurige bestandstypes als invoer accepteert en DeskJet-uitvoer voor iedere situatie produceert, dan heb je inderdaad een slimme print spooler!

Een dergelijk filter wordt een magic filter genoemd. Doe geen moeite om er zelf één te schrijven, tenzij je nogal bizarre zaken afdrukt - er zijn er al vele goede voor je geschreven en op het net verkrijgbaar. APS Filter behoort tot de beste, of er moet zich in je Linux-distributie een printersetup-tool bevinden die het je allemaal nogal makkelijk maakt.

7.2 Bestandspermissies

Op veler verzoek, voeg ik hieronder een lijst in van de permissies van de interessante bestanden op mijn systeem. Er zijn wat betere manieren om dit te doen, ideaal gezien door alleen gebruik te maken van SGID binaries en niet alles als SUID root in te stellen, maar zo kwam mijn systeem uit de verpakking, en voor mij werkt het. (Eerlijk gezegd, als je verkoper zelfs geen werkende lpd kan leveren, heb je nog wat te doorstaan).

-r-sr-sr-x   1 root     lp    /usr/bin/lpr*
-r-sr-sr-x   1 root     lp    /usr/bin/lprm*
-rwxr--r--   1 root     root  /usr/sbin/lpd*
-r-xr-sr-x   1 root     lp    /usr/sbin/lpc*
drwxrwxr-x   4 root     lp    /var/spool/lpd/
drwxr-xr-x   2 root     lp    /var/spool/lpd/lp/

Lpd moet thans als root worden gedraaid zodat het verbonden kan worden met de laag-genummerde lp service poort. Het zou waarschijnlijk ingesteld moeten staan met UID lp.lp of iets dergelijks na binding, maar ik denk niet dat dit zo is.


Verder Terug Inhoud