9.4. Magasszintű nyomtatóbeállítás

Ebben a szakaszban olyan szűrőket mutatunk be, amelyek speciálisan formázott állományok, fejléclapok, hálózati nyomtatás, nyomtatási nyilvántartás vagy szabályozás esetén használhatóak.

9.4.1. Szűrők

Noha az LPD képes hálózati protokollokat, nyomtatási sorokat, hozzáférést és sok minden más nyomtatási feladatot kezelni, a tényleges munka legnagyobb része a szűrőkben (filter) történik. A szűrők olyan programok, amelyek tartják a kapcsolatot a nyomtatóval és megbirkóznak annak eszközfüggőségeivel és különleges igényeivel. Az egyszerű beállítás során egy primitív szövegszűrőt állítottunk be (lásd A szövegszűrő telepítése) - ami annyira egyszerű, hogy szinte minden nyomtatón működnie kell.

Azonban mindahhoz, hogy ki tudjuk használni a különböző átalakítási, nyilvántartási lehetőségeket, valamint a nyomtatók különlegességeit és egyebeit, meg kell értenünk a szűrők pontos működését. Az előbb említett feladatok ugyanis teljesen a szűrő kezében vannak. Ezzel kapcsolatban azonban rossz hír, hogy ezeket a szűrőket nekünk kell megírnunk. A jó hír ellenben az, hogy könnyen találunk ilyen szűrőket, vagy ha éppen nem lelnénk valamelyiket, akkor is gyorsan meg tudjuk ezeket írni.

Sőt, a FreeBSD alapból tartalmaz is egyet, amit a /usr/libexec/lpr/lpf helyen találunk meg, és sok olyan nyomtatóval képes együttműködni, amelyek nyers szöveget tudnak nyomtatni. (Kezeli az állományokban felbukkanó törléseket és tabulálásokat, valamint képes nyilvántartást vezetni, de semmi többet.) Rajta kívül még számos szűrőt és szűrőelemet is találhatunk a FreeBSD Portgyűjteményében.

Lássuk, mit tartogat számunkra ez a rész:

  • A Hogyan működnek a szűrők? című szakaszban megpróbálunk egyfajta áttekintést adni a szűrők nyomtatási folyamatban betöltött szerepéről. Mindenképpen érdemes elolvasnunk ezt a szakaszt, mivel ebben derül ki, hogy valójában mi is történik a "függöny mögött", vagyis amikor az LPD használja ezeket a szűrőket. Ezzel a tudással el tudjuk kerülni vagy éppen nyakon tudjuk csípni azokat a problémákat, amelyek a nyomtatóinkhoz telepített szűrők hozzáadása során adódhatnak.

  • Az LPD alapból arra számít, hogy minden nyomtató képes nyers szöveget nyomtatni. Ez gondot okoz a PostScript(R) (és minden más nyelv alapú) nyomtatók esetén, mivel azok nem képesek nyers szöveget nyomtatni. Szöveges nyomtatási feladatok PostScript(R) nyomtatókon című szakaszban viszont fény derül rá, hogyan kerekedjünk felül ezen. Feltétlenül olvassuk el, ha PostScript(R) nyomtatónk van.

  • A PostScript(R) számos program közkedvelt kimeneti formátuma, sőt gyakran maguk a felhasználók is szeretnek ilyen programokat írni. Sajnos azonban a PostScript(R) nyomtatók egyáltalán nem olcsók. A PostScript(R) szimulációja nem PostScript(R) nyomtatókon című szakaszban megtudhatjuk, miképp tudjuk úgy módosítani a szűrőt, hogy nem PostScript(R) nyomtatókon is tudjunk PostScript(R) programokkal nyomtatni. Ezt a szakaszt akkor érdemes elolvasni, ha nincs PostScript(R) nyomtatónk.

  • A Konverziós szűrők című szakaszban eláruljuk, miként lehetséges automatizálni a különböző állományformátumok és a nyomtatók által érthető formátumok közti konverziókat, legyen az grafikus vagy betűszedésre vonatkozó adat. A szakasz elolvasása során megismerjük, hogyan tudjuk a nyomtatónkat képessé tenni az lpr -t paranccsal troff adatok, vagy a lpr -d paranccsal a TeX DVI állományainak, esetleg az lpr -v paranccsal raszteres képek nyomtatására és így tovább. Csak ajánlani tudjuk ennek elolvasását.

  • A Kimeneti szűrők című szakaszban kivesézzük az LPD egyik kevésbé használt lehetőségét is, a kimeneti szűrőket. Hacsak nem fejléclapokat akarunk készíteni (lásd Fejléclapok), akkor ezt a szakaszt nyugodtan kihagyhatjuk.

  • Az lpf szövegszűrő szakaszban bemutatásra kerül a FreeBSD-ben alapból megtalálható lpf szűrő, amely egy sornyomtatóknál (vagy az így viselkedő lézernyomtatóknál) használható egyszerű szövegszűrő. Ha nyers szövegek nyomtatásánál meg akarjuk oldani a nyomtatási feladatok nyilvántartását, vagy a törlés karakter láttán a nyomtatónk füstölni kezdene, akkor mindenképpen érdemes belemerülnünk az lpf titkaiba.

Megjegyzés:

A most következő szkriptek mindegyike megtalálható a /usr/share/examples/printing könyvtárban.

9.4.1.1. Hogyan működnek a szűrők?

Ahogy már korábban is jeleztük, a szűrő egy olyan végrehajtható program, amelyet az LPD indít el, amikor a nyomtatóval eszközfüggetlen módon kommunikál.

Amikor az LPD egy feladat elvégzése során ki akar nyomtatni egy állományt, akkor elindít egy ilyen szűrőprogramot. A szűrő szabványos bemenetére elküldi a kinyomtatandó állományt, a szabványos kimenetét a nyomtatóra, a szabványos hibajelzéseit pedig egy naplóállományba irányítja (ez utóbbit az /etc/printcap állományban az lf tulajdonsággal adhatjuk meg, vagy alapértelmezés szerinti a /dev/console állományba kerül).

Az LPD a használni kívánt szűrőt és annak paramétereit az /etc/printcap állományban felsoroltak vagy az lpr(1) parancssorában megadottak szerint választja ki. Például, ha a felhasználó a lpr -t parancsot adja ki, akkor az LPD a célként megadott nyomtatónál szereplő tf tulajdonság által megadott troff szűrőt kezdi el használni. Amennyiben a felhasználó egyszerűen csak nyers szöveget akar nyomtatni, akkor az if szűrőnek kellene elindulnia (ez viszont csak részben igaz: lásd Kimeneti szűrők).

Háromfajta szűrő jelenhet meg az /etc/printcap állományban:

  • A szövegszűrő (text filter), ami a hagyományos szöveges nyomtatásért felelős, és amit az LPD dokumentációjában érdekes módon bemeneti szűrőnek (input filter) hívnak. Mivel az LPD arra számít, hogy minden nyomtató alapból képes kinyomtatni bármilyen nyers szöveget, ezért a szövegszűrő feladata, hogy a nyomtató számára gondoskodjon a tabulátorok, törlések és más egyéb speciális karakterek megfelelő kezeléséről. Emellett ha olyan helyen vagyunk, ahol szükség van a nyomtatási feladatok nyilvántartására is, a szövegszűrő ennek megoldására is képes, méghozzá úgy, hogy összeszámolja a kinyomtatott sorokat, és elosztja ezeket a nyomtató által oldalanként nyomtatott sorok számával. Egy szövegszűrő a következő paraméterekkel indulhat:

    szűrőnév [-c] -w szélesség -l hossz -i behúzás -n hozzáférés -h gépnév nyilvántartás

    ahol a

    -c

    akkor jelenik meg, ha egy nyomtatási feladatot az lpr -l paranccsal adunk át

    szélesség

    az /etc/printcap állományban definiált pw (page width, avagy oldalszélesség) tulajdonság értéke, ami alapbeállítás szerint 132

    hossz

    a pl (page length, avagy oldalhossz) tulajdonság értéke, amely az alapbeállítás szerint 66

    behúzás

    az lpr -i parancs megadása során használt behúzás mértéke, ami alapból 0

    hozzáférés

    a nyomtatást végző felhasználó hozzáférésének megnevezése

    gépnév

    a gép neve, amiről a nyomtatási feladat érkezett

    nyilvántartás

    ez a nyilvántartást tároló állomány af tulajdonsággal definiált neve

  • A konverziós szűrők (conversion filter) egy adott állományformátumot hoznak a nyomtató számára értelmes formára. Például ditroff adatok közvetlenül ugyan nem nyomtathatóak, azonban a ditroff állományokhoz tudunk telepíteni egy olyan szűrőt, amely a ditroff adatokat a nyomtató számára is emészthető és nyomtatható formájúvá teszi. A Konverziós szűrők című szakasz tud ezekről többet mondani. Ilyen esetekben kérhetünk nyilvántartást. A konverziós szűrők az alábbi paraméterekkel indulhatnak:

    szűrőnév -x pixelszélesség -y pixelmagasság -n hozzáférés -h gépnév nyilvántartás

    ahol a pixelszélesség a px tulajdonság értékéből (ami alapból 0), a pixelmagasság a py tulajdonság értékéből (ami alapból szintén 0) származik.

  • A kimeneti szűrő (output filter), ami csak akkor aktív, ha a szövegszűrő nem, vagy ha engedélyeztük fejléclapok nyomtatását. Tapasztalatom szerint az ilyen szűrőket ritkán használják. A Kimeneti szűrők című szakasz mutatja be a működésüket. Ekkor csupán két paraméterünk van:

    szűrőnév -w szélesség -l hosszúság

    amik rendre megegyeznek a szövegszűrők -w és -l paramétereivel.

A szűrők ki is tudnak lépni a következő kódokkal (exit status):

0

A szűrő sikeresen kinyomtatta az állományt.

1

A szűrőnek nem sikerült kinyomtatnia az állományt, azonban szeretné, ha az LPD újból megpróbálkozna vele. Az LPD tehát ebben az esetben újraindítja a szűrőt.

2

A szűrőnek nem sikerült kinyomtatnia az állományt, és nem is kívánja újra megpróbálni. Ekkor az LPD eldobja az állományt.

A FreeBSD kiadásokban megtalálható /usr/libexec/lpr/lpf szövegszűrő képes a kapott szélesség és hossz paraméterekkel megállapítani az oldaltöréseket és a nyomtató használatát nyilvántartani, amihez a hozzáférés, gépnév és nyilvántartás adatait használja fel.

Amikor majd igyekszünk mellé újabb szűrőket beszerezni, ne felejtsük el ellenőrizni, hogy együtt tudnak-e működni az LPD-vel. Ha a válasz igen, akkor a fentebb említett paraméterek mindegyikét ismerniük kell. Az általános használatra készült szűrők készítése során mi magunknak is be kell tartanunk ezeket az elvárásokat.

9.4.1.2. Szöveges nyomtatási feladatok PostScript(R) nyomtatókon

Ha csak egyedül dolgozunk a számítógépen és PostScript(R) (vagy bármilyen más nyelvet ismerő) nyomtatónk van, valamint megígérjük, hogy soha nem küldünk sem mi, sem pedig nem küldetünk semmilyen más programmal nyers szöveget a nyomtatóra, akkor átléphetjük ezt a szakaszt.

Ha viszont egyaránt akarunk küldeni PostScript(R) programot és nyers szöveget tartalmazó nyomtatási feladatot a nyomtatónak, akkor ehhez kénytelenek vagyunk a rendszerünket beállítani. Először is szükségünk van szövegszűrőre, ami megállapítja, hogy a frissen érkezett nyomtatási feladat nyers szöveget vagy PostScript(R) programot tartalmaz-e. Minden PostScript(R)-alapú feladat a %! karaktersorozattal kezdődik (a többi esetben olvassuk a nyomtató leírását). Szóval, ha a nyomtatandó állomány első két karaktere ilyen, akkor egy PostScript(R) programmal van dolgunk és közvetlenül továbbküldhetjük a nyomtatási feladatot a nyomtatónak. Minden más esetben a szűrőnek előbb át kell alakítania a szöveget PostScript(R) nyelvre.

Hogyan érhetjük el mindezt?

Ha soros nyomtatónk van, akkor erre a feladatra az lprps parancs tökéletes. Az lprps egy olyan PostScript(R) szűrő, amely mind a két irányban képes közvetíteni. Folyamatosan rögzíti egy állományba a nyomtató állapotát, így a felhasználók és rendszergazdák pontosan látják a nyomtató jelenlegi állapotát (például toner low (a toner hamarosan kifogy) vagy paper jam (a papír beragadt)). Ami viszont sokkal lényegesebb, hogy a psif nevű program képes megmondani az érkező nyomtatási feladat valódi típusát, és ennek megfelelően meg tudja hívni nyers szöveg átalakítására a textps (egy másik program, amit a lprps mellé kapunk) parancsot. Ezután az lprps elküldi a feladatot a nyomtatónak.

Az lprps a FreeBSD Portgyűjteményének része (lásd A Portgyűjtemény), ezért a használni kívánt papír méretétől függően pillanatok alatt magunk is letölhetjük, fordíthatjuk és telepíthetjük a print/lprps-a4 és print/lprps-letter csomagok valamelyikét. Az lprps telepítése után egyszerűen csak adjuk meg a psif elérési útvonalát. Ha tehát telepítettük a Portgyűjteményből az lprps csomagot, akkor egy soros portra csatlakozó PostScript(R) nyomtató esetén ezt kell beírnunk az /etc/printcap állományba:

:if=/usr/local/libexec/psif:

Ezenkívül még az rw tulajdonsággal meg kell mondanunk az LPD-nek, hogy a nyomtatót írásra és olvasásra nyissa meg.

Amennyiben a PostScript(R) nyomtatónk a párhuzamos porton csatlakozik (és amiért a nyomtatónk nem képes az lprps által igényelt kétirányú kommunikációra), szövegszűrőként a következő szkriptet fogjuk használni:

#!/bin/sh
#
#  psif - PostScript vagy nyers szöveg nyomtatása PostScript nyomtatón
#  Ez a szkriptes változat, NEM pedig az lprps-hez mellékelt szűrő
#  (a /usr/local/libexec/psif állomány)!
#

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

if [ "$first_two_chars" = "%!" ]; then
    #
    #  PostScript: nyomtassuk ki.
    #
    echo "$first_line" && cat && printf "\004" && exit 0
    exit 2
else
    #
    #  Nyers szöveg: alakítsuk át, majd nyomtassuk ki.
    #
    ( echo "$first_line"; cat ) | /usr/local/bin/textps && printf "\004" && exit 0
    exit 2
fi

A fentebb szereplő szkriptben a textps programot használjuk a nyers szövegek PostScript(R) programokra alakításához, de helyette bármilyen más konvertáló programot is igénybe vehetünk. A FreeBSD Portgyűjteményében (lásd A Portgyűjtemény) találhatunk erre a célra egy a2ps nevű programot is, amit esetleg érdemes lehet közelebbről megnéznünk.

9.4.1.3. PostScript(R) szimulációja nem PostScript(R) nyomtatókon

A PostScript(R) a magas színvonalú betűszedés és nyomtatás de facto szabványa. Emellett azonban a PostScript(R) egy költséges szabvány is. Az Aladdin Enterprises-nak hála azonban létezik egy hozzá hasonló szabad szoftver, a Ghostscript, amely képes FreeBSD-n is futni. A Ghostscript képes a legtöbb PostScript(R) állomány olvasására, megjelenítésére mindenféle eszközökön, beleértve a PostScript(R)et nem ismerő nyomtatókat is. A Ghostscript és egy speciális szövegszűrő telepítésével el tudjuk érni, hogy egy nem PostScript(R) nyomtató valódi PostScript(R) nyomtatóként viselkedjen.

Ha telepíteni szeretnénk, a Ghostscript megtalálható a FreeBSD Portgyűjteményében. Innen tehát magunk is könnyedén le tudjuk tölteni, fordítani és telepíteni.

A PostScript(R) nyomtatás szimulációjához először egy szűrő segítségével észre kell vennünk, hogy egy PostScript(R) formátumú állományt készülünk kinyomtatni. Ha nem ilyen a nyomtatási feladat, akkor egyenesen a nyomtatóra küldjük, azonban minden más esetben először a Ghostscript segítségével átalakítjuk egy olyan formátumba, amit a nyomtató is képes feldolgozni.

Nézzünk erre egy példát: a most következő szövegszűrő a Hewlett Packard DeskJet 500-as nyomtatóihoz használható. Más nyomtató esetén cseréljük ki a gs (Ghostscript) parancs -sDEVICE paraméterét a neki megfelelőre. (A telepített Ghostscript által ismert nyomtatók listáját a gs -h paranccsal kérdezhetjük le.)

#!/bin/sh
#
#  ifhp - Ghostscripttel szimulált Postscript nyomtatás DeskJet 500-on
#  Helye: /usr/local/libexec/ifhp

#
#  LF karaktereket CR+LF-ként kezeljük (elkerülve ezzel a HP/PCL
#  nyomtatókon a "lépcsőzést"):
#
printf "\033&k2G" || exit 2

#
#  Az állomány első két karakterének beolvasása
#
IFS="" read -r first_line
first_two_chars=`expr "$first_line" : '\(..\)'`

if [ "$first_two_chars" = "%!" ]; then
    #
    #  Ez PostScript: küldjük át a Ghostscripten és nyomtassuk ki.
    #
    /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
      -sOutputFile=- - && exit 0
else
    #
    #  Nyers szöveg vagy HP/PCL, ezért küldjük át közvetlenül. Az utolsó
    #  lap kidobásához küldünk még egy lapdobást is.
    #
    echo "$first_line" && cat && printf "\033&l0H" &&
exit 0
fi

exit 2

Befejezésül az if tulajdonságon keresztül értesítenünk kell erről a szűrőről az LPD-t is:

:if=/usr/local/libexec/ifhp:

Készen is vagyunk! Most már nyugodtan beírhatjuk, hogy lpr sima.szöveg vagy lpr akármi.ps, mind a kettőnek ki kell tudnia nyomtatódnia.

9.4.1.4. Konverziós szűrők

Miután elvégeztük az Alacsonyszintű nyomtatóbeállítás című szakaszban leírt beállításokat, a (nyers ASCII szöveg mellett) kedvenc állományformátumainkhoz is minden bizonnyal szeretnénk telepíteni néhány konverziós szűrőt.

9.4.1.4.1. Miért használjunk konverziós szűrőket?

A konverziós szűrők segítségével állományok mindenféle formátumait könnyen ki tudjuk nyomtatni. Például tegyük fel, hogy sokat dolgozunk a TeX betűszedő rendszerrel és egy PostScript(R) nyomtatónk van. Minden alkalommal, amikor egy DVI állományt hozunk létre a TeX forrásból, azt közvetlenül még nem tudjuk a nyomtatóra küldeni. Ehhez a következő parancsokat kell kiadnunk:

% dvips hínár-elemzés.dvi
% lpr hínár-elemzés.ps

Ha telepítünk egy konverziós szűrőt a DVI állományokhoz, meg tudjuk spórolni ezt a manuális átalakítási lépést azzal, hogy átadjuk ezt a feladatot az LPD-nek. Így ezután mindig, amikor egy DVI állományt akarunk kinyomtatni, csupán egyetlen lépésre lesz szükségünk:

% lpr -d hínár-elemzés.dvi

Az LPD-nek a -d paraméterrel adjuk meg, hogy a nyomtatás előtt hajtsa végre a DVI átalakítását. A Formázási és konverziós beállítások című szakaszban találjuk meg a többi konverziós opciót.

Minden olyan konverziós beállításhoz, amit használni szeretnénk a nyomtatóval, telepítenünk kell egy konverziós szűrőt (conversion filter) és meg kell adnunk a nevét az /etc/printcap állományban. A konverziós szűrők az egyszerű nyomtatóbeállításnál szereplő szövegszűrőkhöz hasonlítanak (lásd A szövegszűrő telepítése szakasz) azzal a kivétellel, hogy a nyers szövegek kinyomtatása helyett ezek a szűrők a nyomtató számára értelmes formátumra alakítják az állományokat.

9.4.1.4.2. Milyen konverziós szűrőket érdemes telepíteni?

Olyan konverziós szűrőket telepítsünk, amelyekre gyakran szükségünk lehet. Ha például sok DVI adatot szeretnénk nyomtatni a jövőben, akkor használjunk DVI konverziós szűrőt, vagy ha sok troff formátumú adatot nyomtatunk, akkor minden bizonnyal jól fog jönni egy troff szűrő.

A következő táblázat foglalja össze azokat a szűrőket, amelyekkel az LPD képes együttműködni. Megtudhatjuk, hogy az /etc/printcap állományban melyik tulajdonság tartozik hozzájuk és hogyan hívjuk meg ezeket az lpr paranccsal:

ÁllománytípusTulajdonság az /etc/printcap állománybanAz lpr kapcsolója
cifplotcf-c
DVIdf-d
plotgf-g
ditroffnf-n
FORTRAN forrásrf-f
trofftf-f
rastervf-v
nyers szövegifnincs, -p, vagy -l

A példánkban tehát a lpr -d parancs használata arra utal, hogy a nyomtatónak az /etc/printcap állományból a df tulajdonságára van szüksége.

Minden hadakozás ellenére állíthatjuk, hogy a FORTRAN források és a plot által használt szövegek formátuma napjainkra már elavultnak tekinthető. Ezért ezekhez az opciókhoz a saját szűrőinkkel tetszőleges formázási lehetőségeket rendelhetünk. Például, ha Printerleaf (az Interleaf asztali kiadványszerkesztő formátuma) állományokat szeretnénk közvetlenül nyomtatni, akkor valószínűleg nem lesz szükségünk plot állományokra. Ezért a gf tulajdonságnak megadhatunk egy Printerleaf konverziós szűrőt, amelyen keresztül aztán a felhasználók az lpr -g paranccsal Printerleaf állományokat tudnak nyomtatni.

9.4.1.4.3. Konverziós szűrők telepítése

Mivel a konverziós szűrők az alap FreeBSD rendszeren kívülre kerülnek, ezért ezeket minden valószínűség szerint valahol a /usr/local könyvtárban találjuk meg. Ezen belül is általában a /usr/local/libexec könyvtárban fordulnak elő, mivel ezeket csak az LPD futtatja, senki másnak nincs rájuk szüksége.

A konverziós szűrők aktiválásához az /etc/printcap állományban egyszerűen adjuk meg az alkalmas tulajdonságoknak megfelelő szűrők elérési útvonalait.

A példánkban most felveszünk egy DVI konverziós szűrőt a bamboo nevű nyomtatóhoz. Itt ismét láthatjuk a korábban használt /etc/printcap állományt, ahol most azonban a bamboo nevű nyomtatónál hozzáadtunk egy df tulajdonságot:

#
#  /etc/printcap (rose) -  egy df szűrő hozzáadása a bamboo
#  nevű nyomtatóhoz
#
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/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\
        :if=/usr/local/libexec/psif:\
        :df=/usr/local/libexec/psdf:

A DVI szűrő ebben az esetben a /usr/local/libexec/psdf néven elérhető aprócska szkript. Ezt találhatjuk benne:

#!/bin/sh
#
#  psdf - DVI szűrő PostScript nyomtatóhoz
#  Helye: /usr/local/libexec/psdf
#
# Az lpr -d parancs hatására hívódik meg
#
exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@"

A szkript a dvips parancsot szűrőként futtatja (az -f paraméterrel) a szabványos bemenetről, ahova a nyomtatási feladatot is kapja. Ezután elindítja az lprps PostScript(R) szűrőt (lásd a Szöveges nyomtatási feladatok PostScript(R) nyomtatókon című szakaszt) az LPD által átadott paraméterekkel. Az lprps parancs ezekkel a paraméterekkel tartja nyilván az így kinyomtatott lapokat.

9.4.1.4.4. További példák konverziós szűrőkre

A konverziós szűrők telepítésének nincs bevált receptje, ezért ebben a szakaszban bemutatunk rájuk néhány működő illusztrációt. Ezeket tudjuk felhasználni saját szűrők elkészítésére. Vagy ha megtehetjük, használjuk közvetlenül ezeket.

Ebben a példa szkriptben Hewlett Packard LaserJet III-Si nyomtatókhoz hozunk létre raszteres (pontosabban GIF formátumú) konverziós szűrőt:

#!/bin/sh
#
#  hpvf - GIF állományokat konvertál át HP/PCL-be, majd kinyomtatja
#  Helye: /usr/local/libexec/hpvf

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

Úgy működik, hogy a GIF állományt először PNM (portable anymap), utána PGM (portable graymap), majd PBM (portable bitmap) formátumúra alakítja, amiből végül LaserJet/PCL-kompatibilis adat lesz.

Ez lesz a hozzá tartozó /etc/printcap állomány:

#
#  /etc/printcap (orchid)
#
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
        :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\
        :if=/usr/local/libexec/hpif:\
        :vf=/usr/local/libexec/hpvf:

A most következő szkript a groff betűszedű rendszerből érkező troff adatokat alakítja át a bamboo nevű PostScript(R) nyomtató számára:

#!/bin/sh
#
#  pstf - a groff troff adait alakítja PS-re, majd kinyomtatja
#  Helye: /usr/local/libexec/pstf
#
exec grops | /usr/local/libexec/lprps "$@"

A szkript az lprps parancs segítségével kommunikál a nyomtatóval. Ha a nyomtatónk párhuzamos porton csatlakozik, akkor helyette ezt a szkriptet használjuk:

#!/bin/sh
#
#  pstf - a groff troff adatait alakítja PS-re, majd kinyomtatja
#  Helye: /usr/local/libexec/pstf
#
exec grops

Kész is! A szűrő életrekeltéséhez mindössze ennyit kell beillesztenünk az /etc/printcap állományba:

:tf=/usr/local/libexec/pstf:

Most pedig jöjjön a FORTRAN szerelmeseinek szívét megmelengető szkript. Ez egy olyan szövegszűrő, amely bármelyik nyers szöveget közvetlenül kezelni tudó nyomtató esetén működik. A teak nevű nyomtatóhoz helyezzük be:

#!/bin/sh
#
# hprf - FORTRAN szövegszűrő LaserJet 3si-hez
# Helye: /usr/local/libexec/hprf
#

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

Az /etc/printcap állományban a teak nyomtatóhoz a következő sor beírásával tudjuk engedélyezni ezt a szűrőt:

:rf=/usr/local/libexec/hprf:

Most pedig következzen egy utolsó, de az eddigieknél valamivel összetettebb példa. Ebben a korábban bemutatott teak nevű LaserJet nyomtatóhoz fogunk hozzáadni egy DVI szűrőt. Először is következzen a művelet egyszerűbb része: bővítsük ki az /etc/printcap állományt a DVI szűrő helyének megadásával:

:df=/usr/local/libexec/hpdf:

Ezután következzék a nehezebb rész: a szűrő elkészítése. Ehhez szükségünk lesz egy DVI-ről LaserJet/PCL-re alakító programra. A FreeBSD Portgyűjteményében (lásd A Portgyűjtemény) találunk is egyet: a csomag neve print/dvi2xx. A csomag telepítésével megkapjunk a nekünk kellő dvilj2p programot, ami képes DVI-t LaserJet IIp, LaserJet III és a LaserJet 2000 típusok által ismert kódokra fordítani.

A dvilj2p felhasználásától függetlenül a hpdf néven létrehozni kívánt szűrőnk még így is bonyolult lesz, hiszen a dvilj2p nem tud olvasni a szabványos bemenetről, hanem mindenáron egy állománnyal akar dolgozni. Sőt, olyan állománnyal, amelynek .dvi kiterjesztése van, ezért még a /dev/fd/0 (vagyis a szabványos bemenethez tartozó eszközleíró) használata is akadályokba ütközik.

Üröm még az örömünkben, hogy a /tmp könyvtárat sem tudjuk felhasználni ideiglenes link létrehozására: a szimbolikus linkeket a bin felhasználó és csoport birtokolja, a szűrőt pedig a daemon felhasználó futtatja. A /tmp könyvtárban rááadásul csak a tulajdonosaik képesek állományokat átnevezni vagy törölni (sticky bit). Ezért a szűrő ugyan létre tudna hozni egy linket, azonban ezt a feladata végeztével nem lesz majd képes törölni, mivel a link egy másik felhasználóhoz tartozik.

Ezért a szűrő az aktuális könyvtárban fogja létrehozni ezt a szimbolikus linket, ami jelen esetünkben a nyomtatási rendszer által használt könyvtár lesz (ezt az /etc/printcap állomány sd tulajdonságával adjuk meg). Itt remekül el tudják végezni a feladataikat a szűrők, különösen mivel (néha) több hely van itt, mint a /tmp könyvtárban.

Végül lássuk magát a szűrőt:

#!/bin/sh
#
#  hpdf - DVI adat nyomtatása HP/PCL nyomtatón
#  Helye: /usr/local/libexec/hpdf

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

#
#  Létrehozunk egy függvényt az átmeneti állományok törlésére. Ezek
#  az aktuális könyvtárban jönnek létre, ami pedig a nyomtatási
#  rendszer adott nyomtatóhoz tartozó könyvtára lesz.
#
cleanup() {
   rm -f hpdf$$.dvi
}

#
#  Létrehozunk egy függvényt a súlyos hibák kezelésére: írassunk ki
#  egy adott üzenetet és lépjünk ki a 2-es hibakóddal.  Ezzel üzenünk
#  az LPD-nek, hogy ne hajtsa végre újra a nyomtatási feladatot.
#
fatal() {
    echo "$@" 1>&2
    cleanup
    exit 2
}

#
#  Ha a felhasználó eltávolítja a nyomtatási feladatot a sorból, akkor az
#  LPD egy SIGINT jelzést fog küldeni, ezért próbáljuk meg azt elkapni
#  (néhány más egyéb jelzéssel együtt), így még tudjuk törölni az
#  ideiglenesen # létrehozott állományokat.
#
trap cleanup 1 2 15

#
#  Gondoskodjunk róla, hogy a feladat megkezdésekor még egyetlen
#  használt állomány sem létezik.
#
cleanup

#
#  Kössük össze a szabványos bemenetet egy DVI állománnyal (amit
#  majd nyomtatni akarunk).
#
ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0"

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

#
#  Alakítsuk át az adatot és nyomtassunk. A dvilj2p által visszaadott érték
#  nem túlságosan megbízható, ezért ne is foglalkozzunk vele.
#
dvilj2p -M1 -q -e- dfhp$$.dvi

#
#  Takarítsunk el magunk után és lépjünk ki szabályosan
#
cleanup
exit 0
9.4.1.4.5. Automatikus konverziók: a konverziós szűrők helyett

A konverziós szűrők sokat segítenek egy kényelmes nyomtatási környezet kialakításában, azonban a használatukhoz a felhasználóknak (az lpr(1) parancson keresztül) egyenként hivatkozniuk kell rájuk. Ha a rendszerünk felhasználói nem eléggé műveltek számítástechnikai téren, akkor még egy szűrő megadása is zavaró lehet számukra. Ami még ennél is rosszabb, hogy egy rosszul megadott szűrő hatására a nyomtató sem fogja jól kezelni az adott állomány formátumát és erre válaszul akár többszáz lapot is pillanatok alatt kiköphet magából.

A konverziós szűrők telepítése helyett gyakran csak egy (alapértelmezett) szövegszűrőre van szükségünk, amely kideríti a nyomtatandó állomány pontos formátumát és magától elindítja a neki megfelelő konverziós szűrőt. Ilyen esetekben például a file parancs pont a hasznunkra válhat. Persze bizonyos állománytípusok közt nagyon nehéz különbséget tenni - de ezekre továbbra is adhatunk még külön konverziós szűrőket.

A FreeBSD Portgyűjteményében találhatunk egy apsfilter elnevezésű szövegszűrőt (print/apsfilter), ami képes ilyen automatikus konverzióra. Képes felismerni a nyers szöveget, PostScript(R) programokat, DVI és szinte bármilyen formátumú állományokat, lefuttatni rájuk a megfelelő átalakításokat, majd kinyomtatni ezeket.

9.4.1.5. Kimeneti szűrők

Az LPD nyomtatási rendszer kezel egy eddig még nem tárgyalt szűrőtípust is: ez a kimeneti szűrő. A kimeneti szűrő a szövegszűrőhöz hasonlóan csak nyers szöveg nyomtatására használatos, de tartalmaz néhány egyszerűsítést. Ha kizárólag csak kimeneti szűrőket alkalmazunk, akkor:

  • Az LPD az egész nyomtatási feladathoz egyetlen kimeneti szűrőt fog használni, nem pedig minden állományhoz külön.

  • Az LPD a kimeneti szűrő számára nem nyújt semmilyen segítséget a nyomtatási feladaton belül szereplő állományok kezdetének vagy végének megállapításában.

  • Az LPD a szűrőnek nem adja át sem a felhasználó hozzáférését, sem pedig gépnevét, ezért nyilvántartásra nem alkalmas. Mindent összegezve lényegében csak két paramétert kap meg:

    szűrőnév -wszélesség -lhossz

    ahol a szélesség a kérdéses nyomtató pw tulajdonságából, a hossz pedig a pl tulajdonságából származik.

Ne bűvöljön el minket a szűrő egyszerűsége! Ha például a nyomtatási feladatban minden állományt újabb lapon szeretnénk kezdeni, akkor azt kimeneti szűrővel nem tudjuk megoldani. Erre a célra használjunk szövegszűrőt (másik nevén bemeneti szűrőt), lásd A szövegszűrő telepítése szakaszt. Továbbá, a kimeneti szűrő valójában sokkal bonyolultabb abban a tekintetben, hogy a beérkező adatok közül neki kell kikeresnie a speciális jelentéssel bíró karaktereket ugyanúgy, ahogy az LPD helyett saját magának kell küldenie a jelzéseket.

Azonban a kimeneti szűrők használata elkerülhetetlen, ha például fejléclapokat akarunk nyomtatni, és esetleg még különböző inicializálásra használatos speciális kódokat vagy karakterláncokat akarunk ez előtt kiküldeni. (Ellenben badarság a fejléclapoktól követelni a felhasználó adatait, hiszen az LPD a kimeneti szűrőnek nem ad semmilyen erre vonatkozó információt.)

Egyetlen nyomtató esetén az LPD egyaránt lehetővé teszi kimeneti, szöveg- és más egyéb szűrők használatát. Ilyenkor az LPD a kimeneti szűrőn keresztül csak a fejlécet tartalmazó oldal (lásd a Fejléclapok szakaszt) nyomtatását indítja el. Ezt követően az LPD arra számít, hogy a kimeneti szűrő két karakter, az ASCII 031 és az ezt követő ASCII 001, hatására leállítja magát. Amikor tehát a kimeneti szűrő érzékeli ezt a két karaktert (031, 001), akkor a SIGSTOP jelzéssel le kell állnia. Miután az LPD lefuttatta a többi szűrőt, a SIGCONT jelzéssel újraindítja a kimeneti szűrőt.

Ha van kimeneti szűrőnk, de nincs szövegszűrőnk, akkor az LPD minden további feldolgozás nélkül továbbadja a nyomtatási feladatot a kimeneti szűrőnek. Ahogy már korábban is említettük, a kimeneti szűrő a nyomtatási feladatban levő összes állományt egymás után nyomtatja ki, lapdobások vagy bármilyen más papírmozgatás nélkül, ezért valószínűleg nem ez kell nekünk. Az esetek túlnyomó részében ehhez elég egy szövegszűrő.

A korábban szövegszűrőként beharangozott lpf program kimeneti szűrőként is képes funkcionálni. Ha szükségünk lenne egy gyorsan összecsapható kimeneti szűrőre, és nem akarunk a speciális karakterek, valamint a jelzések küldésével elidőzni, akkor próbálkozzunk az lpf használatával. Az lpf parancsot mellesleg becsomagolhatjuk egy olyan szkriptbe is, amely elvégzi a nyomtató számára szükséges inicializálást.

9.4.1.6. Az lpf szövegszűrő

A FreeBSD bináris terjesztéséhez mellékelt /usr/libexec/lpr/lpf program egy szövegszűrő (bemeneti szűrő), amely képes (az lpr -i paranccsal hozzáadott nyomtatási feladatokat) tabulálni, (az lpr -l paranccsal felvett nyomtatási feladatokban) a vezérlőkaraktereket figyelemen kívül hagyni, a nyomtatási feladatban előforduló törlések és behúzások nyomtatási pozícióját igazítani és nyilvántartani a kinyomtatott lapokat. Kimeneti szűrőként is tud viselkedni.

Az lpf szűrő rengeteg nyomtatási környezetben felhasználható. Habár nem képes a nyomtatónak inicializáló jelsorozatokat küldeni, mégis könnyű olyan szkriptet írni, amely elvégzi ezeket a hiányzó kezdeti beállításokat, majd lefuttatja az lpf szűrőt.

Az lpf akkor lesz képes helyesen számolni a kinyomtatott lapokat, ha ehhez az /etc/printcap állományban jól töltjük ki a pw és pl tulajdonságokat. Ezen értékek segítségével határozható meg ugyanis, hogy mennyi szöveg fért rá egy lapra és így mennyi lapot emésztett fel az adott felhasználó által küldött nyomtatási feladat. A nyomtatás nyilvántartásával kapcsolatban A nyomtató használatának nyilvántartása című szakaszt érdemes elolvasni.

9.4.2. Fejléclapok

Ha nagyon sok felhasználónk van, és sok különböző nyomtatót is használnak, akkor előbb vagy utóbb minden bizonnyal elkerülhetetlenné fog válni a fejléclapok használata.

A fejléc-, vagy más néven munka- vagy elválasztó lapok segítik elő az elvégzett nyomtatási feladatok azonosítását. A többi dokumentumtól eltérő módon, általában dekoratív keretben, nagy, vastag betűkkel nyomtatódnak ki, hogy a halomnyi papír között a felhasználók könnyedén megtalálhassák az elküldött nyomtatási feladataik eredményét. Természetesen a fejléclapok nyilvánvaló hátulütője, hogy így minden nyomtatási feladathoz még egy lappal többet kell elhasználni és mivel gyakorlatilag néhány percnél tovább nincs is rájuk szükség, meglehetősen hamar a kukába kerülnek. (A fejléclapok nyomtatási feladatonként jönnek létre, nem pedig a nyomtatási feladatokban levő állományokhoz egyenként, ezért nem is akkora pazarlás ez.)

Az LPD rendszer képes magától fejléclapokat készíteni a nyomtatásokhoz, amennyiben a nyomtatónk képes közvetlenül nyers szöveget nyomtatni. Ha PostScript(R) nyomtatónk van, akkor ennek legyártásához egy külső programra van szükségünk, lásd a Fejléclapok PostScript(R) nyomtatókon szakaszt.

9.4.2.1. A fejléclapok engedélyezése

Az Alacsonyszintű nyomtatóbeállítás című szakaszban az /etc/printcap állományban a sh (úgy mint "suppress header") tulajdonsággal kikapcsoltuk a fejléclapokat. A fejléclapok engedélyezéséhez mindössze el kell távolítanunk ezt az sh tulajdonságot.

Ez túl egyszerű, nemde?

Igen, ez így van. Előfordulhat, hogy szükségünk van még egy olyan kimeneti szűrőre is, amely inicializáló karaktereket küld a nyomtatónak. Íme egy példa ehhez a Hewlett Packard PCL-kompatibilis nyomtatói esetére:

#!/bin/sh
#
#  hpof - Kimeneti szűrő Hewlett Packard PCL-kompatibilis nyomtatókhoz
#  Helye: /usr/local/libexec/hpof

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

Az of tulajdonsággal adjuk meg a kimeneti szűrőt. A Kimeneti szűrők szakaszban erről részletesebben is olvashatunk.

A korábban ismertetett teak nevű nyomtatóhoz most az alábbi minta /etc/printcap állományt mellékeljük. Itt engedélyeztük a fejléclapokat és hozzátettük az iménti kimeneti szűrőt:

#
#  /etc/printcap (orchid)
#
teak|hp|laserjet|Hewlett Packard 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:

Mostantól kezdve, amikor a felhasználók a teak nyomtatón akarnak nyomtatni, minden nyomtatási feladathoz kapni fognak egy fejléclapot. Amennyiben a kedves felhasználók mégis keresgetni akarják a nyomtatásaikat, az lpr -h paranccsal tetszőleges módon letilthatják azokat. Az lpr(1) többi hasonló opcióját A fejléclapokhoz tartozó beállítások szakaszban találjuk.

Megjegyzés:

Az LPD minden fejléclap után egy lapdobást küld. Ha erre a célra a nyomtatónk egy eltérő karaktert vagy karaktersorozatot használ, akkor azt az /etc/printcap állomány ff tulajdonságával határozhatjuk meg.

9.4.2.2. A fejléclapok vezérlése

A fejléclapok engedélyezésével az LPD egy ún. hosszú fejlécet fog készíteni, vagyis a felhasználót, a gépet és a nyomtatási feladatot jól azonosító, egész lapot kitöltő óriási betűket. Erre egy példa (amiben a rose nevű gépről kelly küldte az "outline" elnevezésű nyomtatási feladatot):

      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

Ezt követően az LPD elküld még egy lapdobást is, ezért maga a nyomtatási feladat eredménye egy új oldalon fog kezdődni (kivéve, ha az /etc/printcap állományban az adott nyomtatóhoz tartozó bejegyzésben megadtuk az sf (úgy mint "suppress form feeds", vagyis a lapdobások letiltása) tulajdonságot.

Ha úgy jobban tetszik, akkor az /etc/printcap állományban a sb tulajdonsággal az LPD utasítható rövid fejlécek készítésére is. Ilyenkor a fejléclap tartalma mindössze ennyi lesz:

rose:kelly  Job: outline  Date: Sun Sep 17 11:07:51 1995

Alapértelmezés szerint az LPD először a fejléclapot, majd a nyomtatási feladatot végzi el. Ezt a sorrendet az /etc/printcap állományban a hl (header last) tulajdonsággal meg tudjuk fordítani.

9.4.2.3. A nyomtató használatának nyilvántartása

Az LPD által felkínált fejléclapok használata során egyetlen irányelv érvényesül a nyilvántartásukban: a fejléclapok költségmentesek.

De miért?

Azért, mert kizárólag csak a kimeneti szűrő képes a fejléclapok viselkedését irányítani, ami viszont nem képes semmiféle nyilvántartásra, hiszen nem kapja meg az ehhez szükséges felhasználói- vagy gépnév információkat, illetve nyilvántartásokat. Emiatt fogalma sincs róla, hogy kit terhel az adott nyomtató használata. Úgy sem tudjuk megoldani a problémát, ha a szöveg- vagy konverziós szűrőkben (ahol már rendelkezésünkre állnak a felhasználó és a gépének adatai) "növeljük a lapok számát eggyel" a nyomtatási feladatban, mivel a felhasználók az lpr -h parancs használatával kedvük szerint letilthatják a fejléclapokat. Ezt ugyan alapvetően a természetet óvni kívánó felhasználók részesítik előnyben, de ettől függetlenül sem erőszakolhatjuk rá mindenkire.

Az sem elég, ha minden szűrő létrehozza a saját fejlécét (amiért aztán pénzt kérhetnénk). Mivel ha a felhasználók az lpr -h paranccsal le akarják tiltani a fejlécek használatát, attól a szűrőkhöz még mindig létrejönnek, hiszen az LPD a -h opcióról semmilyen értesítést nem küld át a szűrőknek.

Nos, ilyenkor mitévők legyünk?

A lehetőségeink:

  • Elfogadjuk az LPD elvét, és nem számítunk fel költséget a fejléclapokra.

  • Az LPD helyett egy másik nyomtatási rendszert használunk, például az LPRng rendszert. A Más nyomtatási rendszerek című szakaszban kiderül, milyen alternatívák érhetőek el az LPD kiváltására.

  • Írjunk mi magunk egy intelligens kimeneti szűrőt. Normális esetben a kimeneti szűrők nem valók másra, csupán a nyomtató alaphelyzetbe hozására vagy egyszerűbb karakterkonverziók elvégzésére. Fejléclapokhoz és nyers szöveget tartalmazó nyomtatási feladathoz remekül használható (ahol nincs szöveg- (avagy bemeneti) szűrő). Azonban ha a nyers szövegekhez van szövegszűrőnk, akkor az LPD a kimeneti szűrőt csak a fejléclapokhoz indítja el. Emellett a kimeneti szűrő az LPD által generált fejléc szövegéből képes megmondani, melyik felhasználóhoz és géphez tartozik a szóbanforgó fejléc. A módszer egyetlen bökkenője, hogy a nyilvántartásokat tároló állományról viszont még így se tudunk semmilyen információt szerezni (mivel nem kapjuk meg az af tulajdonsággal beállított állomány nevét). Ha azonban egy rendszerszinten elérhető állományba mentjük ezeket az adatokat, akkor akár bele is drótozhatjuk ezt a kimeneti szűrőbe. A kimeneti szűrőnek az adatok megtalálásában ilyenkor úgy tudunk segíteni, ha az /etc/printcap állományban az sh (rövid fejléc) tulajdonságot állítjuk be. De ez igazából sok hűhó semmiért, és a felhasználók is jobban megbecsülik az olyan nagylelkű rendszergazdát, aki nem számítja fel nekik a fejléclapokat.

9.4.2.4. Fejléclapok PostScript(R) nyomtatókon

Ahogy arról már korábban is szó esett, az LPD képes többféle nyomtató számára is megfelelő, nyers szövegű fejléclapokat készíteni. Persze a PostScript(R) közvetlenül nem képes nyers szövegek nyomtatására, ezért az LPD ezen lehetősége lényegében használhatatlan - többnyire.

Ilyen helyzetben a fejléclapok használatának nyilvánvaló módja, hogy minden szövegszűrőt fejlécek gyártására utasítunk. Ezek a szűrők a felhasználóról és a gépéről kapott információkból össze tudják állítani a megfelelő fejléclapot. A megoldás hátránya, hogy ez még olyankor is megtörténik, amikor a felhasználók az lpr -h paranccsal küldik a nyomtatási feladataikat.

Kísérletezzünk egy kicsit ezzel a módszerrel! A most következő szkript három paramétert fogad el (a felhasználó hozzáférést, a gép és a nyomtatási feladat nevét), majd ezekből létrehoz egy egyszerű PostScript(R) formátumú fejlécet:

#!/bin/sh
#
#  make-ps-header - PostScript fejléc létrehozása a szabvány kimenetre
#  Helye: /usr/local/libexec/make-ps-header
#

#
#  Ezek itt a PostScript által használt egységekben vannak megadva
#  (72/col vagy 28/cm).  Írjuk át az általunk használt papírméretre,
#  A4-re vagy amit éppen használunk:
#
page_width=612
page_height=792
border=72

#
#  A paraméterek ellenőrzése.
#
if [ $# -ne 3 ]; then
    echo "Usage: `basename $0` <user> <host> <job>" 1>&2
    exit 1
fi

#
#  Mentsük el ezeket, leginkább az olvashatóság miatt.
#
user=$1
host=$2
job=$3
date=`date`

#
#  Küldjük el a PostScript-kódot a szabványos kimenetre.
#
exec cat <<EOF
%!PS

%
%  Gondoskodjunk róla, hogy ne zavarjuk az utánunk következő
%  felhasználó nyomtatási feladatának végrehajtását.
%
save

%
%  Csináljunk egy csúf vastag szegélyt, körbe a papíron.
%
$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

%
%  Jelenítsük meg a felhasználó azonosítóját szép, feltűnő
%  betűkkel.
%
/Helvetica-Bold findfont 64 scalefont setfont
$page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto
($user) show

%
%  Most pedig mutassuk az unalmas részleteket.
%
/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

%
% Ennyi lett volna.
%
restore
showpage
EOF

Ezzel a szkripttel pedig mindegyik konverziós és szövegszűrő először létrehoz egy fejléclapot, majd elvégzi a felhasználó nyomtatási feladatát. Íme egy korábban már bemutatott DVI szűrő, amit most kiegészítünk a fejléclapok használatával:

#!/bin/sh
#
#  psdf - DVI szűrő PostScript nyomtatóhoz
#  Helye: /usr/local/libexec/psdf
#
#  Az lpr -d parancs hatására hívódik meg.
#

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

Láthatjuk, hogy a szűrőnek a felhasználói- és a gépnév megállapításához végig kell néznie a paraméterek listáját. Ez lényegében minden más konverziós szűrőnél ugyanígy néz ki. Ez a lista azonban a szövegszűrők esetén némileg eltér (lásd a Hogyan működnek a szűrők? szakaszt).

Már az előbbiekben is tárgyaltuk, hogy ez a megoldás, habár eléggé egyszerű, az lpr számára nem teszi lehetővé a fejléclapok letiltását (a -h opció). Ha a felhasználóink kímélni akarják a fákat (vagy meg akarják úszni a fejléclapok égbeszökő költségeit), akkor ezt nem tudják megtenni, hiszen a szűrők minden nyomtatási feladathoz készíteni fognak fejléceket.

Ezt a korlátozást csak úgy tudjuk elsöpörni, ha bevetjük a A nyomtató használatának nyilvántartása szakaszban leírt cselt, tehát készítünk egy olyan kimeneti szűrőt, amely megkeresi az LPD-vel generált fejléceket és létrehozza azok PostScript(R) változatát. Ha valaki az lpr -h paranccsal küld nyomtatnivalót, akkor LPD nem készít hozzá fejléclapot, ahogy a kimeneti szűrőnk sem. A kimeneti szűrő minden más esetben beolvassa az LPD által küldött szöveget és átküldi a neki megfelelő PostScript(R) kódot a nyomtatóra.

Ha soros PostScript(R) nyomtatónk van, akkor használhatjuk a psof kimeneti szűrőhöz tartozó lprps parancsot is, ami pontosan az előbbit végzi el. Hozzátennénk azonban, hogy a psof nem számolja a fejléclapokat.

9.4.3. Hálózati nyomtatás

A FreeBSD tud hálozaton is nyomtatni, vagyis tud távoli számítógépeknek is nyomtatási feladatot küldeni. A hálózati nyomtatás kifejezés általánosságban véve két különböző dologra utalhat:

  • Egy távoli számítógéphez kapcsolt nyomtató hozzáférését. A géphez a nyomtató a hagyományos soros vagy párhuzamos csatolófelületen keresztül kapcsolódik, amit aztán az LPD alkalmas beállításával a hálózaton mindenki számára elérhetővé teszünk. A Távoli számítógépekre csatlakoztatott nyomtatók című szakasz erről szól.

  • Egy közvetlenül a hálózatra kapcsolt nyomtató hozzáférését. A nyomtató tehát rendelkezik még egy hálózati csatlakozással is a hagyományos soros vagy párhuzamos felület mellett (vagy éppen helyett). Egy ilyen nyomtató a következőképpen működhet:

    • Elfogadja az LPD kéréseit, és még képes nyomtatási feladatokat is tárolni. Ebben az esetben teljesen egyenértékű egy LPD alkalmazást futtató számítógéppel. Ekkor nincs más teendőnk, csak követnünk kell a Távoli számítógépeken telepített nyomtatók című szakasz utasításait.

    • Hálózati adatfolyamokkal dolgozik. Ebben az esetben a nyomtatót "hozzá kell kapcsolnunk" a hálózaton található egyik számítógéphez, ami majd a nyomtatási feladatok tárolásáért és folyamatos küldéséért lesz felelős. A Nyomtatók hálózati adatcsatlakozással szakasz az ilyen fajtájú nyomtatók telepítésére tesz néhány javaslatot.

9.4.3.1. Távoli számítógépekre csatlakoztatott nyomtatók

Az LPD nyomtatási rendszer alapból képes más, szintén LPD-t (vagy vele kompatibilis rendszert) futtató számítógépekre nyomtatási feladatokat küldeni. Ezzel lényegében az egyik géphez hozzá tudunk kapcsolni egy nyomtatót, amit aztán a többiek számára elérhetővé teszünk. Ez olyan nyomtatók esetében is működik, amelyek ismerik az LPD által alkalmazott protokollt.

A távoli nyomtatáshoz először telepítsük a nyomtatót valamelyik számítógépre az Alacsonyszintű nyomtatóbeállítás szakaszban leírtak szerint, és ezzel az lesz a nyomtatószerverünk. Ezután, amennyiben szükségesnek találjuk, végezzünk magasabb szintű nyomtatóbeállításokat is. Ne felejtsük el kipróbálni a nyomtatón, hogy rendesen működik az LPD mindegyik olyan beállításával, amit engedélyeztünk. Emellett gondoskodjunk minden olyan jogosultságról is, amivel a helyi számítógépről el tudjuk érni a távoli számítógép által felkínált LPD szolgáltatást (lásd Távoli számítógépekről érkező kérések szabályozása).

Ha olyan nyomtatót használunk, aminek a hálózati felülete kompatibilis az LPD rendszerrel, akkor az előbb említett nyomtatószerver lényegében maga lesz a nyomtató, valamint a nyomtató neve a rajta beállított név. Ezzel kapcsolatban olvassuk el a nyomtatóhoz és/vagy a hálózati csatolójához mellékelt dokumentációt.

Tipp:

Amikor a Hewlett Packard Laserjet típusú nyomtatóit használjuk, a text nevű nyomtatónév magától elvégzi a LF és CRLF formátumú sortörések közti átalakítást, ezért ilyenkor nincs szükségünk a hpif szkriptre.

Ezután ha szeretnénk más gépek részére is elérhetővé tenni a frissen telepített nyomtatónkat, adjuk meg mindegyikük /etc/printcap állományában a következőket:

  1. Tetszőlegesen választott nevet, álneveket. Az egyszerűség kedvéért azonban itt érdemes ugyanazokat a neveket választani, mint amit a nyomtatószerveren is használunk.

  2. Szándékosan hagyjuk az lp tulajdonságot üresen (:lp=:).

  3. Hozzunk létre egy nyomtatási könyvtárat, és jelöljük meg a helyét az sd tulajdonsággal. Az LPD itt fogja összegyűjteni a nyomtatási feladatokat, mielőtt elküldené azokat a nyomtatószervernek.

  4. Adjuk meg a nyomtatószerver nevét az rm tulajdonság segítségével.

  5. Az rp tulajdonsággal adjuk meg a nyomtatószerverre csatlakoztatott nyomtató nevét.

Kész! Az /etc/printcap állományban már nem kell megadni konverziós szűrőket, oldalbeállításokat és semmi más egyebet.

Lássunk mindezekre egy példát. A rose nevű számítógéphez két nyomtató csatlakozik, a bamboo és a rattan. Most pedig beállítjuk, hogy az orchid nevű gép felhasználói képesek legyenek ezekkel a nyomtatókkal dolgozni. Ekkor a most következők szerint fog kinézni az orchid (a Fejléclapok engedélyezése szakaszban bemutatott) /etc/printcap állománya. Tartalmazza a teak nevű nyomtató beállításait is, és ehhez fogjuk hozzáadni a rose másik két nyomtatóját:

#
#  /etc/printcap (orchid) - a rose két (távoli) nyomtatójának
#  hozzáadása
#

#
#  A "teak" egy helyi nyomtató, közvetlenül az orchidhoz
#  csatlakozik:
#
teak|hp|laserjet|Hewlett Packard 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:

#
#  A "rattan" rose-hoz csatlakozik, így küldhetünk neki nyomtatási
#  feladatot:
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
        :lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan:

#
#  A "bamboo" is a rose-hoz tartozik:
#
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
        :lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:

Ezután már csak létre kell hoznunk a megfelelő nyomtatási könyvtárakat az orchid nevű gépen:

# 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

Mostantól kezdve az orchid felhasználói képesek lesznek nyomtatni a rattan és bamboo nevű nyomtatókon is. Ezért, ha az orchid egyik felhasználója beírja, hogy:

% lpr -P bamboo -d sushi-leírás.dvi

Az orchid gépen működő LPD rendszer ezt a nyomtatási feladatot a bemásolja a /var/spool/lpd/bamboo nevű nyomtatási könyvtárba és feljegyzi róla, hogy a nyomtatásához DVI szűrőre lesz szükség. Ahogy rose gépen található bamboo nyomtatási könyvtárában elegendő hely keletkezik, a két LPD átküldi egymás közt a rose nevű gépre az állományt. Ezután az állomány egészen addig várakozik a rose nyomtatási sorában, amíg végezetül kinyomtatásra nem kerül. A rose fogja átalakítani DVI-ről PostScript(R) formátumra átalakítani (mivel a bamboo egy PostScript(R) nyomtató).

9.4.3.2. Nyomtatók hálózati adatcsatlakozással

Amikor hálózati kártyát vásárolunk a nyomtatónkhoz, általában két változatukkal találkozhatunk: az egyikük nyomtatási rendszerként működik (ez a drágább), a másikuk pedig egyszerűen csak soros vagy párhuzamos csatlakozón továbbítandó adatként közvetíti az adatokat a nyomtató felé (az olcsóbb). A drágábbik változatot az előző, Távoli számítógépekre csatlakoztatott nyomtatók című szakaszban leírtak szerint tudjuk használni.

Az /etc/printcap állományban ugyan meg tudjuk adni, hogy a nyomtató soros vagy párhuzamos portra csatlakozik, és azon keresztül milyen adatátviteli sebességgel (amennyiben soros), forgalomirányítással, tabulálással, sortörési konvenció szerint stb. kommunikáljunk vele. Azonban TCP/IP vagy más hálózati porton ülő nyomtatók adatait itt nem tudjuk kifejteni.

A hálózatra kötött nyomtatók használatához lényegében egy olyan külön kifejlesztett kommunikációs programra van szükségünk, amely a szöveg- vagy konverziós szűrőkhöz hasonló módon hívható meg. Erre rögtön adunk is egy példát: a netprint szkript a szabványos bemenetről beolvassa az összes kinyomtatandó adatot és átküldi azokat a hálózatra csatlakoztatott nyomtatónak. A szkript első paramétereként a nyomtató hálózati nevét adjuk meg, másodiknak pedig portot. Azonban megjegyezzünk, hogy ez csak egyirányú kommunikációt tesz lehetővé (a FreeBSD-től a nyomtatóig). Sok hálózati nyomtató viszont két irányban is képes kommunikálni, ezért érdemes lehet ezt kihasználni (a nyomtató állapotának lekérdezésére, nyilvántartások készítésére stb).

#!/usr/bin/perl
#
#  netprint - A hálózatra csatlakoztatott nyomtató szövegszűrője
#  Helye: /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;

Rengeteg szűrőben fel tudjuk használni ezt a szkriptet. Például tegyük fel, hogy egy Diablo 750-N típusú sornyomtatót csatlakoztattunk a hálózatra, amely az 5100-as porton várja a nyomtatandó adatokat. A hálózati neve most scrivener lesz. Íme a hozzá tartozó szövegszűrő:

#!/bin/sh
#
#  diablo-if-net - Az 5100-as porton figyelő `scrivener' nevű Diablo
#  nyomtató szövegszűrője. Helye: /usr/local/libexec/diablo-if-net
#
exec /usr/libexec/lpr/lpf "$@" | /usr/local/libexec/netprint scrivener 5100

9.4.4. A nyomtató használatának szabályozása

Ebben a szakaszban a nyomtató használatának korlázásáról írunk. Az LPD rendszeren keresztül meghatározhatjuk, hogy ki képes helyben vagy távolról hozzáférni a nyomtatóhoz, mennyi másolatot nyomtathat, mennyi és egyenként mekkora nyomtatási feladatokat küldhet.

9.4.4.1. A másolatok számának szabályozása

Az LPD segítségével a felhasználók egy állományt könnyen ki tudnak nyomtatni akár többször is. Ha (például) a felhasználó egy nyomtatási feladat kiküldéséhez az lpr -#5 parancsot használja, akkor a nyomtatási feladatban levő összes állományból öt példányt kap. Ennek létjogosultságát azonban nekünk kell megítélni.

Amennyiben úgy érezzük, hogy a további példányok készítése csupán felesleges papír- és tintapazarlás, akkor az sc tulajdonság megadásával az /etc/printcap állományban kikapcsolhatjuk az lpr(1) -# lehetőség használatát. Így amikor a felhasználók a -# kapcsolóval küldenek el feladatokat a nyomtatóra, a következőt fogják tapasztalni:

lpr: multiple copies are not allowed

Fordítása:

lpr: másolatok nyomtatása nem engedélyezett

Vigyázzunk arra, hogy ha távoli számítógépen zajlik a nyomtatás (lásd Távoli számítógépekre csatlakoztatott nyomtatók), akkor az sc tulajdonságot a távoli számítógép /etc/printcap állományában is be kell állítani, máskülönben a felhasználók egy másik számítógépről mindig képesek lesznek több példány nyomtatására.

Nézzünk erre egy példát. Itt most a rose nevű számítógép /etc/printcap állományát vesszük szemügyre. Ebben a rattan egy nagyon szívélyes nyomtató lesz, ezért engedélyezi a másolatok nyomtatását, azonban a bamboo nevű lézernyomtató nála már sokkal válogatósabb lesz, ezért a beállításai közt az sc tulajdonsággal kikapcsoljuk a másodpéldányok nyomtatását:

#
#  /etc/printcap (rose) - A másolatok korlátozása a "bamboo"
#  nevű nyomtatón
#
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/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\
        :if=/usr/local/libexec/psif:\
        :df=/usr/local/libexec/psdf:

Az sc tulajdonságot az orchid /etc/printcap állományában is meg kell adni (és ha már itt vagyunk, akkor tegyük meg ugyanezt a teak esetében is):

#
#  /etc/printcap (orchid) - Nincsenek másodpéldányok sem a helyi
#  "teak" nyomtatón, sem pedig a távoli "bamboo" nyomtatón
teak|hp|laserjet|Hewlett Packard 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:

Az sc tulajdonság használatával ugyan megakadályozzuk az lpr -# parancs teljesítését, azonban ez még mindig nem óv meg minket attól, hogy a felhasználók képesek legyenek többször egymás után lefuttatni az lpr(1) parancsot, vagy éppen egyetlen nyomtatási feladatban több állományt is elküldeni:

% lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.sign

Számos módszer kínálkozik az effajta visszaélések kivédésére (beleértve a figyelmen kívül hagyást is), lehet velük kísérletezgetni!

9.4.4.2. A nyomtatók hozzáférésének szabályozása

A UNIX(R) csoportkezelésével és az /etc/printcap állományban található rg tulajdonság felhasználásával korlátozni tudjuk, ki milyen nyomtatón dolgozhat. Ehhez mindössze annyit kell tennünk, hogy besoroljuk egy csoportba azokat a felhasználókat, amelyek hozzáférhetnek a nyomtatóhoz, és az rg tulajdonsággal megnevezzük azt.

A csoporton kívüli felhasználókat (köztük magát a root felhasználót is) pedig ezután így üdvözli a rendszer, ha megpróbálnak valamit kinyomtatni egy korlátozott felhasználású nyomtatón:

lpr: Not a member of the restricted group

Az üzenet fordítása:

lpr: Nem jogosult felhasználó

Ha erre a távoli számítógépek esetén szükségünk lenne (lásd Távoli számítógépekre csatlakoztatott nyomtatók), akkor tegyük ugyanazt, mint amit az sc (a másodpéldányok letiltása, "suppress multiple copies") tulajdonság esetén is, vagyis az rg tulajdonságot adjuk meg azokon a távoli számítógépeken is, amelyek hozzá tudnak férni a megosztott nyomtatóhoz.

Például megengedjük, hogy a rattan nevű nyomtatót bárki használhassa, azonban a bamboo nyomtatót csak az artists nevű csoport használhatja. Következzen hát akkor a rose korábbról már ismert /etc/printcap állománya:

#
#  /etc/printcap (rose) - A bamboo hozzáférésének korlátozása
#
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/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\
        :if=/usr/local/libexec/psif:\
        :df=/usr/local/libexec/psdf:

Most ne bántsuk a másik (az orchid nevű gépen levő) /etc/printcap állományt. Így persze az orchid bármelyik felhasználója nyomtathat a bamboo nyomtatón. De ez most egy olyan eset, ahol egyébként lekorlátozzuk a orchid elérését is, ezért az ott beengedett felhasználók már akár használhatják is a nyomtatót. Vagy sem.

Megjegyzés:

Minden nyomtatóhoz csak egy ilyen csoportot adhatunk meg.

9.4.4.3. A beküldött nyomtatási feladatok méretének szabályozása

Ha sok felhasználó szeretne a nyomtatóinkhoz hozzáférni, akkor minden bizonnyal meg akarunk adni egy felső határt a felhasználók által beküldhető nyomtatások méretére vonatkozóan. Mivel a nyomtatási könyvtáraknak otthont adó állományrendszer is egyszer betelhet, ezért mindenképpen érdemes gondoskodni arról, hogy mindenki nyomtatási feladatát el tudjuk rendesen tárolni.

Az LPD az mx tulajdonsággal lehetőséget ad arra, hogy lekorlátozzuk a nyomtatási feladatokban található egyes állományok méretét. Ennek mértékegysége egy BUFSIZ blokk, ami pedig 1024 byte. Ha értékül nullát adunk meg, akkor nincs korlátozás, viszont ha semmit sem rögzítünk, akkor az mx tulajdonság alapértéke, vagyis 1000 blokk lesz a határ.

Megjegyzés:

Ez az érték a nyomtatási feladatokban levő egyes állományok méretére vonatkozik, nem pedig a nyomtatási feladatok teljes méretére.

Fontos tudni, hogy az LPD nem dobja vissza a méreten felüli állományokat. Ehelyett a méret alatti részt szépen berakja a sorba és kinyomtatja, a többi pedig elhagyja. Lehetne rajta vitázni, hogy ez mennyire helyes cselekedet.

Példaképpen definiáljunk a korábban használt rattan és bamboo nyomtatóinkhoz ilyen korlátokat. Mivel az artists csoport tagjai hajlamosak nagy PostScript(R) állományokat küldeni, ezért most lekorlátozzuk ezt öt megabyte-ra. A szöveges nyomtatónk esetén azonban nem lesz semmilyen határ:

#
#  /etc/printcap (rose)
#

#
#  Itt nincs korlát a nyomtatási feladatokra:
#
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:

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

Ismét hozzátesszük, hogy ezek a korlátok csak a helyi felhasználókra vonatkoznak. Amennyiben távolról is el lehet érni ezt a nyomtatót, a távoli felhasználókat nem fog semmilyen korlátozás érinteni. Azokon a számítógépeken is meg kell adnunk az /etc/printcap állományban az mx tulajdonságot. Ehhez a Távoli számítógépekre csatlakoztatott nyomtatók című szakaszban találunk segítséget.

Van még egy speciális módszer, amivel képesek vagyunk szabályozni a távolról érkező kérések méretét. Erről a Távoli számítógépekről érkező kérések szabályozása szakaszban olvashatunk.

9.4.4.4. Távoli számítógépekről érkező kérések szabályozása

Az LPD nyomtatási rendszer több módot is szolgáltat a távolról érkező nyomtatási feladatok szabályozására:

Az elérés szabályozása

Az /etc/hosts.equiv és /etc/hosts.lpd állományok segítségével beállíthatjuk, hogy mely távoli számítógépektől fogadjon el kéréseket az LPD. Az LPD minden kérés elfogadásakor ellenőrzi, hogy a küldő számítógép címe szerepel-e az említett állományok valamelyikében. Ha nem, akkor az LPD visszautasítja a kérést.

A két állomány felépítése egyszerű, mert bennük minden sorban egy-egy hálózati nevet adunk meg. Hozzátennénk azonban, hogy legyünk óvatosak, mivel az /etc/hosts.equiv állományt az ruserok(3) protokoll is használja, ezért ennek módosítása hatással van az rsh(1) és rcp(1) programok működésére.

Például most nézzük meg a rose /etc/hosts.lpd állományát:

orchid
violet
madrigal.fishbaum.de

Ennek megfelelően tehát a rose elfogadja az orchid, violet és madrigal.fishbaum.de nevű távoli számítógépek kéréseit. Ha bármilyen más gép próbál hozzáférni a rose által felkínált LPD szolgáltatáshoz, visszautasítja.

A méret szabályozása

Szabályozhatjuk többek közt azt is, hogy mennyi szabad területnek kell fennmaradnia a nyomtatási könyvtárnak otthont adó állományrendszeren. A helyi nyomtató könyvtárában ehhez hozzunk létre egy minfree nevű állományt. Ide írjuk be, mennyi szabad lemezblokk (512 byte-os egység a lemezen) szükségeltetik egy távolról beérkező nyomtatási feladat fogadásához.

Így gondoskodhatunk róla, hogy a távoli felhasználók nem fogják eltömíteni az állományrendszerünket, illetve ezzel egyúttal adhatunk némi előnyt a helyi felhasználóknak is: ők ugyanis még azután is képesek lesznek nyomtatási feladatokat küldeni a nyomtatónak, miután az állományrendszeren található szabad terület mennyisége már rég a minfree állományban szereplő érték alá csökkent.

Példaként most a bamboo nevű nyomtatónkhoz adjunk meg egy ilyen minfree állományt. Ehhez az /etc/printcap állományból tudjuk kideríteni a hozzá tartozó nyomtatási könyvtárat. Lássuk tehát belőle a bamboo bejegyzését:

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

A nyomtatási könyvtárat az sd tulajdonság határozza meg. Úgy állítjuk most be, hogy az LPD számára a távoli nyomtatási feladatok fogadásához ebben a könyvtárban legalább három megabyte (6144 blokk) szabad területnek mindig lennie kell:

# echo 6144 > /var/spool/lpd/bamboo/minfree
A felhasználók szabályozása

Az /etc/printcap állományban megadható rs tulajdonság segítségével korlátozhatjuk a helyi nyomtatókhoz hozzáférni képes távoli felhasználókat. Amikor az rs tulajdonság szerepel egy helyben csatlakozó nyomtató leírásánál, akkor az LPD csak abban az esetben fogad el távoli felhasználóktól nyomtatási feladatot, ha az adott feladatot küldő felhasználónak ugyanazon a néven van a helyi gépen is hozzáférése. Máskülönben az LPD vissza fogja utasítani a kérést.

Ez a tulajdonság különösen fontos olyan környezetben, ahol (például) több szervezeti egység használ egyetlen közös hálózatot és bizonyos felhasználók képesek átlépni szervezeti egységük határait, mivel ha a hozzáférést adunk nekik a rendszereinkhez, akkor képesek a saját helyükről használni ezeket. Ha ehelyett csupán a nyomtatóinkat és a számítógépünk összes erőforrását akarjuk megosztani, akkor létrehozhatunk a számukra olyan "token" hozzáféréseket is, amikhez nem tartozik sem felhasználói könyvtár, sem pedig parancsértelmező (pontosabban a /usr/bin/false).

9.4.5. A nyomtató használatának nyilvántartása

Tehát szükségünk lenne a nyomtatások költségének elszámolására. Miért is ne tennénk ilyet? A papír és a tinta bizony pénzbe kerül, amihez még hozzájárulnak más egyéb karbantartási költségek is - a nyomtatók dugig vannak mindenféle mozgó alkatrésszel, amelyek előbb-utóbbi el is romlanak. Tegyük fel, hogy a nyomtatóink kapacitása, kihasználtsága és karbantartási költsége alapján már megállapítottunk egy elszámolási egységet (oldalanként, méterenként, akárminként). De hogyan lássunk hozzá a nyomtatások költségének tényleges nyilvántartásához?

Van egy rossz hírünk: az LPD nyomtatási rendszer önmaga nem tud segíteni ebben a feladatban. A nyilvántartás nagyban függ a használt nyomtatóktól, a nyomtatott formátumoktól és nyomtató általunk kiszabott költségeitől.

A nyilvántartás létrehozásához át kell írnunk a nyomtatóhoz tartozó szűrőt (a nyers szövegek költségének felszámításához) és konverziós szűrőket (a különféle formátumok költségei miatt), amikkel aztán számolhatjuk vagy lekérdezhetjük a kinyomtatott lapokat. Egyetlen kimeneti szűrő használatával szinte semmire se megyünk, mivel az nem képes nyilvántartás vezetésére. Erről bővebb útmutatást a Szűrők szakaszban találhatunk.

Általánosságban véve két módon vezethetünk nyilvántartást:

  • Az időszakos elszámolás a gyakoribb, mivel ez az egyszerűbb. Amikor valaki végrehajt egy nyomtatási feladatot, a szűrő a nyilvántartást tároló állományba feljegyzi a felhasználó azonosítóját, a gépének nevét és a kinyomtatott oldalakat. Ezután minden hónapban, félévben, évben vagy akár tetszőleges időközönként összegyűjtjük a nyomtatók nyilvántartásait és külön feljegyezzük az egyes felhasználók nyomtatásait, majd benyújtjuk róla a számlát. Töröljük az összes naplóállományt, és tiszta lappal kezdjük a következő időszakot.

  • Az azonnali elszámolás már nem annyira népszerű, mivel nehezebb megvalósítani. Ekkor a felhasználók már közvetlenül a nyomtatás után megkapják a számlát, hasonlóan a lemezkvótákhoz. Meg tudjuk akadályozni ezzel azt is, hogy a felhasználók túlléphessék az előre kiszabott "nyomtatási kvótájukat", amit persze menet közben lehet ellenőrizni és állítgatni. A felhasználók és kvótájuk nyomonkövetéséhez viszont szükségünk lesz egy kis adatbáziskezelésre is.

Az LPD nyomtatási rendszer mind a két módszer kivitelezéséhez tud segítséget nyújtani, hiszen amikor szűrőket állítunk be (vagyis szinte mindig), lehetőségünk van a nyilvántartást végző programrészleteket is beilleszteni. És ami feltétlenül előnyös: óriási mértékű rugalmasságot ajánl fel a nyilvántartás megvalósításához. Például magunk választhatjuk ki, hogy időszakos vagy azonnali elszámolást alkalmazunk. Meg tudjuk adni, milyen információkat rögzítsünk: felhasználói neveket, számítógépek neveit, a nyomtatási feladatok típusát, vagy a kinyomtatott oldalakat, a felhasznált lapok területét, a nyomtatások időbeli igényeit és így tovább. Ehhez mindössze csak a szűrőket kell módosítani.

9.4.5.1. Nyilvántartás gyorsan és egyszerűen

A FreeBSD-ben egyből találunk is két programot, amivel pillanatok alatt ki tudunk alakítani egy egyszerű időszakos elszámolási rendszert. Ezek Az lpf szövegszűrő című szakaszban ismertetett lpf és a nyomtatók nyilvántartásait tartalmazó állományok adatainak összegyűjtését és kiértékelését végző pac(8).

Ahogy korábban már leírtuk a szűrőkről szóló szakaszban (Szűrők), az LPD a szöveg- és konverziós szűrőket parancssorból a nyilvántartást tároló állomány nevével indítja el. Ezt a paramétert a szűrők aztán fel tudják használni a nyilvántartások feljegyzéséhez. Az állomány nevét az /etc/printcap állományban szereplő af tulajdonsággal tudjuk megadni, vagy teljes elérési úttal, vagy pedig a nyomtatási könyvtárhoz viszonyítva.

Az LPD az lpf szűrőt a lap szélességének és hosszának megadásával indítja el (ezeket az értékeket a pw és pl tulajdonságokból származtatja). Az lpf ezek felhasználásával meg tudja mondani, mennyi papírt használtunk el. Miután kiküldte az állományt a nyomtatóra, nyilvántartásba is veszi. Ezek a típusú bejegyzések valahogy így néznek ki:

2.00 rose:andy
3.00 rose:kelly
3.00 orchid:mary
5.00 orchid:mary
2.00 orchid:zhang

Minden nyomtatóhoz érdemes külön nyilvántartást vezetni, mivel az lpf nem tartalmaz semmilyen beépített zárolási megoldást, ezért két lpf párhuzamos futtatása könnyen összezagyválhatja a közösen használt nyilvántartások tartalmát. Az /etc/printcap állományban az af=acct tulajdonság megadásával könnyen létre tudunk hozni minden nyomtatóhoz külön nyilvántartást. Ilyenkor minden nyomtató könyvtárában megjelenik egy acct nevű állomány.

Amikor elérkezünk a nyomtatások kiszámlázásához, futtassuk le a pac(8) programot. Ehhez mindössze annyit kell tennünk, hogy átlépünk az elszámolni kívánt nyomtató könyvtárába és begépeljük a pac parancsot. Ekkor kapunk egy ehhez hasonló, dollár alapú kimutatást:

  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

A pac(8) a következő paramétereket várja:

-Pnyomtató

Az kiértékelendő nyomtató neve. Ez a paraméter csak akkor használható, ha az /etc/printcap állományban az af tulajdonságnak teljes elérési utat adtunk meg.

-c

A felhasználók nevei helyett a fizetendő összeg szerint rendezze a listát.

-m

Hagyja figyelmen kívül a nyilvántartásban szereplő gépek hálózati neveit. Ennek hatására az alpha gépről nyomtató smith meg fog egyezni a gamma gépről nyomtatóval. A beállítás nélkül ez a két felhasználó el fog térni.

-pár

A paraméterként megadott ár dollár értékkel számol oldalanként vagy lábanként az /etc/printcap állományban megadott pc tulajdonság értéke helyett (ami alapból két cent). Az ár lebegőpontos (valós) számként is megadható.

-r

A rendezési sorrend megfordítása.

-s

Hozzon létre egy elszámolást, majd törölje a hozzá kapcsolódó nyilvántartási adatokat.

név ...

Csak az adott nevű felhasználók adatait értékelje ki.

A pac(8) által alapértelmezés szerint generált kimutatásban láthatjuk az egyes gépekről származó egyes felhasználók kinyomtatott oldalait. Ha nekünk viszont nem számít, hogy honnan küldték a kéréseket (mivel bárhonnan lehet küldeni), akkor a pac -m paranccsal az alábbi táblázatot készíttethetjük el:

  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

Itt megtaláljuk a ténylegesen kifizetendő összegeket is, amik kiszámításához a pac(8) az /etc/printcap állomány pc tulajdonságát használja (ez alapból 200, avagy 2 cent oldalanként). Ezzel a tulajdonsággal tehát egy cent századrészében mérve tudjuk megadni az oldalakénti vagy lábankénti árakat. Ezt a beállítást természetesen a pac(8) -p opciójával felül tudjuk bírálni. Arra azonban vigyázzunk, hogy a -p után dollárban kell megadnunk az árat. Emiatt tehát a

# pac -p1.50

parancs szerint minden egyes oldal másfél dollárba fog kerülni. Ezzel az opcióval aztán alaposan megdönthetjük az árakat.

Végezetül megemlítjük, hogy a pac -s parancs az általa létrehozott elszámolást egy külön állományba menti, amelynek a neve nagyjából megegyezik a nyilvántartást végzőével, de _sum-ra (mint "summary", azaz elszámolás) végződik. Ezután nullázza a nyilvántartást. Amikor a pac(8) programot újra lefuttatjuk, újból beolvassa a korábban elmentett elszámolásokat, majd hozzászámolja a többit a hagyományos nyilvántartási adatokból.

9.4.5.2. Hogyan tudjuk számolni a kinyomtatott lapokat?

A nyilvántartás pontos vezetéséhez még távolról is valamilyen módon meg kell tudnunk mondani, hogy mennyi lapot használt egy nyomtatási feladat végrehajtása. Ez a nyomtatás nyilvántartásának egyik alapvető problémája.

A nyers szövegek esetében ez nem is annyira bonyolult: egyszerűen számoljuk össze, hogy a nyomtatási feladatban mennyi sor kinyomtatására lesz szükség és vessük össze ezt a nyomtató által lapoként kinyomtatott sorok számálva. Ne felejtsük el számításba venni a szövegben felbukkanó törlések hatását, vagy az olyan hosszú sorokat, amelyek a valóságban több sorban fognak megjelenni.

Viszont (Az lpf szövegszűrő című szakaszban bemutatott) lpf program ezeket mind lekezeli a nyilvántartások készítése során. Ezért ha szintén egy nyilvántartást vezetni képes szövegszűrőt akarunk írni, akkor mindenképpen érdemes megnéznünk az lpf forráskódját.

De hogyan bánjunk el a többi formátummal?

Nos, a DVI-Laserjet és DVI-PostScript(R) közti átalakítások esetén a kinyomtatott lapok számának megállapításához meg kell tanítanunk a szűrőnket értelmezni a dvilj vagy dvips parancsok kimenetét. Ugyanezt meg tudjuk tenni más formátumok és más konverziós programok használata során is.

Azonban ezek a módszerek nem veszik számításba, hogy a nyomtató egyáltalán kinyomtatta-e az összes elküldött oldalt. Sok minden történhet még addig, például beragadhat a papír, kifogyhat a tinta vagy akár felrobbanhat a nyomtató - a felhasználónak ettől függetlenül még fizetnie kell.

Mit lehet ilyenkor tenni?

A precíz nyilvántartásnak csak egyetlen biztos módja létezik. Olyan nyomtatót szerezzünk be, amely képes megmondani, mennyi lapot használt el a nyomtatás során, majd egy ilyet csatlakoztassunk soros porton vagy hálózaton keresztül. Szinte majdnem az összes PostScript(R) nyomtató támogatja ezt a lehetőséget, ahogy sok más gyártmány és típus is (például a hálózati Imagen lézernyomtatók). A nyomtatóhoz tartozó szűrőt ehhez úgy kell módosítani, hogy lekérdezzük a kinyomtatott lapok számát a nyomtatás után és kizárólag erre az értékre alapozva készítünk nyilvántartást. Itt nincs szükség sem a sorok számolására, sem pedig az állományok (könnyen elhibázható) átvizsgálására.

Természetesen lehetünk nagylelkűek és ne számítsunk fel semmit a nyomtatásért.

Ha kérdése van a FreeBSD-vel kapcsolatban, a következő címre írhat (angolul): <questions@FreeBSD.org>.

Ha ezzel a dokumentummal kapcsolatban van kérdése, kérjük erre a címre írjon: <gabor@FreeBSD.org>.