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.
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® (é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 nyomtatókon című szakaszban viszont fény derül rá, hogyan kerekedjünk felül ezen. Feltétlenül olvassuk el, ha PostScript nyomtatónk van.
A PostScript 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 nyomtatók egyáltalán nem olcsók. A PostScript szimulációja nem PostScript nyomtatókon című szakaszban megtudhatjuk, miképp tudjuk úgy módosítani a szűrőt, hogy nem PostScript nyomtatókon is tudjunk PostScript programokkal nyomtatni. Ezt a szakaszt akkor érdemes elolvasni, ha nincs PostScript 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.
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
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
a pl (page length, avagy oldalhossz) tulajdonság értéke, amely az alapbeállítás szerint 66
az lpr -i
parancs megadása során használt
behúzás mértéke, ami
alapból 0
a nyomtatást végző felhasználó hozzáférésének megnevezése
a gép neve, amiről a nyomtatási feladat érkezett
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):
A szűrő sikeresen kinyomtatta az állományt.
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.
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.
Ha csak egyedül dolgozunk a számítógépen és PostScript (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 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 programot tartalmaz-e. Minden PostScript-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 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 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 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 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 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 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.
A PostScript a magas színvonalú betűszedés és nyomtatás de facto szabványa. Emellett azonban a PostScript 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 állomány olvasására, megjelenítésére mindenféle eszközökön, beleértve a PostScriptet 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 nyomtató valódi PostScript 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 nyomtatás szimulációjához először egy szűrő segítségével észre kell vennünk, hogy egy PostScript 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.
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.
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 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.
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ípus | Tulajdonság az /etc/printcap állományban | Az lpr kapcsolója |
---|---|---|
cifplot | cf | -c |
DVI | df | -d |
plot | gf | -g |
ditroff | nf | -n |
FORTRAN forrás | rf | -f |
troff | tf | -f |
raster | vf | -v |
nyers szöveg | if | nincs, -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.
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
szűrőt (lásd a Szöveges
nyomtatási feladatok PostScript
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.
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 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
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 programokat, DVI és szinte bármilyen formátumú állományokat, lefuttatni rájuk a megfelelő átalakításokat, majd kinyomtatni ezeket.
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.
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.
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 nyomtatónk van, akkor ennek legyártásához egy külső programra van szükségünk, lásd a Fejléclapok PostScript nyomtatókon szakaszt.
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.
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.
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.
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 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 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 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
kódot a nyomtatóra.
Ha soros PostScript 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.
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.
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:
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.
Szándékosan hagyjuk az lp tulajdonságot üresen (:lp=:).
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.
Adjuk meg a nyomtatószerver nevét az rm tulajdonság segítségével.
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 formátumra átalakítani (mivel a bamboo egy PostScript nyomtató).
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
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.
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!
A UNIX® 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.
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 á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.
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 /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.
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
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).
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.
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.
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.
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 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 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): <[email protected]>.
Ha ezzel a dokumentummal kapcsolatban van kérdése,
kérjük erre a címre írjon: <[email protected]>.