LPD では, ネットワークプロトコル, キュー, アクセス制御, そ して, 印字のためのその他の側面について扱いますが, 実際の 作業のほとんどはフィルタによっておこなわれています. フィルタ は, プリンタと通信し, プリンタのデバイス依存性や特殊な要求を扱 うプログラムです. 簡単なプリンタ設定では, プレインテキストのた めのフィルタをインストールしました. このプレインテキストフィル タは, ほとんどのプリンタで機能する極めて単純なものでした. (「 テキストフィルタのインストール」を参照)
しかしながら, 形式変換やプリンタ課金, 特定のプリンタの癖, など をうまく利用するためには, フィルタがどのように機能するかという ことを理解しておくべきです. これらの側面を扱うためには, 最終的 には, フィルタの責任であるからです. そして, これは悪い情報です が, ほとんどの場合において, あなた自身がフィルタを供給す る必要があるということです. また都合のよいことには, たくさんのフィルタが 一般的に利用できるということです. もしフィルタがなかったとし ても, 普通は, フィルタを作るのは簡単です.
FreeBSD にも, プレインテキストを印字させることができる
/usr/libexec/lpr/lpf
というフィルタが1つ付いています.
(このフィルタはファイルに含まれるバックスペースやタブを扱いま
す. また, 課金をすることもできますが, できることはこれだけしか
ありません.) いくつかのフィルタとフィルタの構成要素が FreeBSD
の ポート集にもあります.
この節で述べることは次の通りです.
lpr -t
,
または, TeX DVI を印字するには lpr -d
, ラスタイ
メージデータを印字するには lpr -v
, などといったよ
うにユーザが入力することができるようにプリンタの設定を
おこなうことができます. この節もお読みになることをお薦めし
ます.
lpf
についての説明が,
ほぼ完全におこなわれています. これは FreeBSD に付属するラ
インプリンタ (または, ラインプリンタのように動作するレー
ザプリンタ) のための, 単純なテキストフィルタです. プレ
インテキストを印字したことに対して課金をおこなう方法が至急
必要な場合, もしくは, バックスペース文字を印字しようと
すると煙を発するプリンタを持っている場合は, 絶対に
lpf
を検討するべきです.
既に言及したように, フィルタとは, プリンタにデータを送る 際に, デバイスに依存した部分を取り扱うために LPD によって起動 される実行プログラムです.
LPD がジョブ中のファイルを印字しようとするとき, LPD はフィル
タプログラムを起動します. このとき, フィルタの標準入力を印字す
るファイルに, 標準出力をプリンタに, そして, 標準エラー出力をエ
ラーログファイル (/etc/printcap
内の lf
項目で指
定されたファイル, または, 指定されていない場合は, デフォルトと
して /dev/console
) にセットします.
LPD が起動するフィルタと, その引数が何であるかは,
/etc/printcap
ファイルの内容と, ジョブの起動時に
ユーザが指定した lpr
コマンドの引数に依存しています. 例え
ば, ユーザが lpr -t
と入力した場合は, LPD は出力先のプリ
ンタ用の tf
項目で指定されている troff 用のフィルタを起動
させるでしょう. ユーザがプレインテキストの印字を指示したときは,
if
で指定されたフィルタが起動されるでしょう (このことはほ
とんどの場合にあてはまります. 詳細については, 「
出力フィルタ」をご覧ください).
/etc/printcap
で指定可能なフィルタは次の3種類がありま
す.
[-c] -wwidth -llength -iindent -n login -h host acct-file
ここで,
-c
lpr -l
によってジョブが入力されたときに与
えられます.
width
/etc/printcap
で指定された pw
(page width) 項目の値が与えられます. デフォル
トは, 132です.
length
pl
(page length) 項目で指定された値が与え
られます. デフォルトは66です.
indent
lpr -i
によって与えられた字下げの量で, デ
フォルトは0です.
login
ファイルを印字したユーザのアカウント名が与えら れます.
host
ジョブが入力されたホスト名が与えられます.
acct-file
af
項目で指定されている課金データファイル
の名前が与えられます.
-xpixel-width -ypixel-height -n login -h host acct-file
ここで, pixel-width は, px
項目で指定され
た値 (デフォルトは0), pixel-height は, py
項
目で指定された値 (デフォルトは0) です.
-wwidth -llength
ここで, -w
と -l
は, テキストフィルタの場合
と同じです. フィルタは, 次に示すの終了状態をもってプログラムを exit するべきです.
フィルタがファイルを正常に印字した場合.
フィルタはファイルの印字に失敗したが, LPD に再度ファ イルの印字を試みて欲しい場合. この終了状態で終了した場 合, LPD はフィルタを再スタートします.
フィルタはファイルの印字に失敗し, かつ, LPD に再出力 を試みて欲しくない場合. この場合, LPD はそのファイル を放棄します.
FreeBSD に付属するテキストフィルタ
/usr/libexec/lpr/lpf
は, FROM FEED 文字が送られたと
きやプリンタ使用に対する課金をどのようにするかを決定するために,
ページ幅やページ長の引数を利用します. また, 課金用のエントリを
作成するため, ログイン名, ホスト名, 課金ファイル名の引数を利用
します.
もし, フィルタの購入を検討しているならば, LPD と互換性がある かどうかを確認してください. もしそうならば, 上述の引数リストをサ ポートしていなければなりません. 一般向けの使用のためにフィルタ を作成する計画をしている場合は, 同じ引数リストと終了コードをサ ポートしてください.
コンピュータと PostScript (または, 他の言語に対応し た) プリンタをあなたしか使用しない場合は, プリンタにプレ インテキストを絶対に送らない, そして, プリンタにプレインテキス トを送りたがっている様々なプログラムの機能を決して使わないこと にしてください. そうすれば, この節に書かれたことに心を煩わせる必 要はまったくなくなります.
しかし, PostScript とプレインテキストの両方のジョブをプリン
タへ送りたいと思っている場合は, プリンタ設定についての要求が増
えるでしょう. 両者をプリンタへ送信するためには, 到着
したジョブがプレインテキストであるか PostScript であるかを
検出するテキストフィルタが必要です. PostScript のジョブは
すべて %!
で始まらなければならないことになっています
(他のプリンタ言語に関しては, プリンタのドキュメントをご覧くだ
さい). ジョブの最初の2文字がこれならば, PostScript である
ことが分かります. したがって, ジョブのそれ以降の部分をプリンタに直
接送ることができます (訳注:PostScript では, %
以降はコメントとして扱われるので, 最初の %!
の行を
読み捨てても問題はない). 最初の2文字が %!
でない場
合は, フィルタはテキストを PostScript に変換し, その結果を
使って印字をおこないます.
この作業をどうやってやればよいのでしょうか.
シリアルポートにプリンタを接続した場合は, lprps
をインス
トールすることをお勧めします. lprps
は PostScript 用のフィルタで,
プリンタとの双方向通信をおこないます. このフィルタでは, プリンタか
らの冗長な情報を得ることで, プリンタの状況を示すファイルが更新
されていきます. したがって, ユーザや管理者は (「トナー残量少」や
「紙詰まり」といった) プリンタの状況を正確に知ることができます.
しかし, もっと重要なことは, psif
と呼ばれるプログラムが
含まれているということです. このプログラムは, 入力されたジョブ
がプレインテキストかどうかを検出し, これを PostScript に変
換するために, textps
(lprps
に付属する別のプログラ
ム) を呼び出します. そして, このジョブをプリンタに送るために,
lprps
が使われます.
lprps
は FreeBSD のポート集に含まれています (「
ポートコレクション」を参照してください).
もちろん,自分自身でプログラムを取ってきて, コンパイルし, インストールす
ることもできます. lprps
をインストールした後は,
lprps
の一部である psif
プログラムのパス名を指定する
だけです. ポート集から lprps
をインストールしたときは,
/etc/printcap
の中のシリアル接続した PostScript
プリンタのエントリに対して, 次を使ってください.
:if=/usr/local/libexec/psif:
LPD にプリンタをリード・ライトモードでオープンさせるために,
rw
項目も指定すべきです.
パラレルポートに接続したプリンタの場合 (すなわち, lprps
が
必要としているプリンタとの双方向通信ができない), テキストフィ
ルタとして次のシェルスクリプトを使うことができます.
<hr>
#!/bin/sh # # psif - Print PostScript or plain text on a PostScript printer # Script version; NOT the version that comes with lprps # Installed in /usr/local/libexec/psif # read first_line first_two_chars=`expr "$first_line" : '\(..\)'` if [ "$first_two_chars" = "%!" ]; then # # PostScript job, print it. # echo $first_line && cat && printf "\004" && exit 0 exit 2 else # # Plain text, convert it, then print it. # ( echo $first_line; cat ) | /usr/local/bin/textps && printf "\004" && exit 0 exit 2 fi<hr> 上記のスクリプトにおいて,
textps
はプレインテキストから
PostScript へ変換するために別にインストールしたプログラム
です. テキストから PostScript へ変換するのには, お好みのどんなプロ
グラムでも使うことができます. FreeBSD の ポート集 (「
ポートコレクション」を参照してください) には,
a2ps
と呼ばれるテキストから PostScript に変換するプログラムが
入っています.
訳注: 上記スクリプトでは, 先頭の行を読み込むために read を使っていますが, 困ったことに, read は読み込んだ文字列の先頭 の空白文字を取り除いてしまいます. 従って, これらの空白文字は印 字されないことになり, 印字結果がファイルのイメージと異なる場合 が出てきます. この事情は csh を利用した場合でも変わりません. 仮に, 先頭の空白文字を除去しない read コマンドを作ったとしても, 「echo $first_line」の $first_line 変数の内容をシェルが展開す る際に $first_line の先頭の空白文字が失われるため, 問題の解決 にはなりません. 残念ながら, 訳者はこの問題をシェルプログラムだ けで解決する方法をしりません. perl か C 言語の力を借りないと解 決できないと思います.
PostScript は質の高い組版と印字をおこなうための事実 上の標準です. しかしながら, PostScript は, 高価な標 準です. ありがたいことに, Alladin Enterprises から Ghostscript と呼ばれる, PostScript 互換の動作をするフリー のプログラムが出されていて, FreeBSDで動きます. Ghostscript はほとんどの PostScript ファイルを読むことができ, これらの 各ページをたくさんのブランドの非 PostScript プリンタを含む 様々なデバイス用に変換することができます. Ghostscript をイン ストールし, プリンタ用の特別なテキストフィルタを使うことによっ て, 非 PostScript プリンタをあたかも本物の PostScript プリンタであるかのように動作させることができます.
Ghostscript はポート集に入っていますので, そこからインストール することができます. また, 自分でソースプログラムを持ってきて, コンパイルし, インストー ルすることもできます. この作業はとても簡単にできます.
PostScript プリンタをシミュレートさせる場合は, テキストフィ ルタに PostScript ファイルを印字しようとしているかどうかを 検出させます. PostScript ファイルでない場合は, フィルタは そのファイルを直接プリンタに送ります (訳注:テキストファイルを直 接印字できない場合は, もちろん, 変換フィルタを通す必要がありま す). PostScript の場合は, まず, Ghostscript を使い, ファ イルをそのプリンタが理解できる形式へ変換します.
次の例のスクリプトは, Hewlett Packard DeskJet 500 プリンタ用
のテキストフィルタです. 他のプリンタで用いるときは,
-sDEVICE
引数を gs
(Ghostscript) コマンドに変えてくだ
さい. (gs -h
と入力すると, 現在インストールされている
Ghostscript でサポートされているデバイスのリストが得られます).
<hr>
#!/bin/sh # # ifhp - Print Ghostscript-simulated PostScript on a DeskJet 500 # Installed in /usr/local/libexec/hpif # # Treat LF as CR+LF: # printf "\033&k2G" || exit 2 # # Read first two characters of the file # read first_line first_two_chars=`expr "$first_line" : '\(..\)'` if [ "$first_two_chars" = "%!" ]; then # # It is PostScript; use Ghostscript to scan-convert and print it # /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 -sOutputFile=- - \ && exit 0 else # # Plain text or HP/PCL, so just print it directly; print a form # at the end to eject the last page. # echo $first_line && cat && printf "\f" && exit 2 fi exit 2<hr> 最後に,
if
項目を通して, LPD にこのフィルタを教えてやる
必要があります.
:if=/usr/local/libexec/hpif:
これでおしまいです. lpr plain.text
とか lpr
whatever.ps
と入力してみましょう. どちらも正常に印字されるは
ずです.
訳注: 日本語を印字する場合は, 日本語対応の Ghostscript が必要で す. 日本語対応版の Ghostscript もポート集に入っているはずです.
「 プリンタ設定導入編」 に書かれた簡単な設定が完了したら, 最初に, やってみたいと思 うことは, 多分(プレイン ASCII テキストに加えて) 好みのファイル形式 のための変換フィルタをインストールすることでしょう.
変換フィルタによって, 様々な種類のファイルを印字するこ とが簡単になります. 例えば, TeX 組版システムでたくさんの仕事 をしたと仮定しましょう. そして, PostScript プリンタが接続 されているとします. すると, TeX で DVI ファイルを作成する度に, DVI ファイルを印字するために, これを PostScript ファイルに 変換する必要があります. このコマンドは次のようになるでしょう.
dvips seaweed-analysis.dvi
lpr seaweed-analysis.ps
DVI ファイル用の変換フィルタがインストールしてあると, LPD に
変換を肩代わりさせることで毎回毎回おこなわなければならなかった面倒
な変換作業を省くことができます. つまり, DVI を生成したら,
次のような1回のコマンド入力だけで, これが印字されます.
lpr -d seaweed-analysis.dvi
LPD に DVI ファイルの変換をさせるためには, -d
オプション
を指定します. 変換オプションのリストは「
整形と変換に関するオプ ション」に載せてあります.
変化のオプションのそれぞれをプリンタにサポートさせるためには,
変換フィルタをインストールし, そのパス名を
/etc/printcap
の中で指定しなくてはなりません. 変換フィ
ルタは, プレインテキストを印字する代わりに, フィルタはファイル
をプリンタが理解できる形式に変換するところを除けば, 「プリンタ
の簡単な設定」で説明したテキストファイル (「
テキストフィルタのインストール」
を見て下さい) に似ています.
使いたいと思う変換フィルタをインストールすべきです. DVI のデータを頻繁に印字するならば, DVI 変換フィルタ をインストールするのが適切でしょう. 印字しなくてはなら ない troff を大量に抱えている場合は, 多分, troff フィ ルタが欲しくなるはずです.
次の表は, LPD で動作するフィルタと,
/etc/printcap
ファイルでのエントリする項目,
そして, lpr
コマンドで呼び出す方法をまとめたもの
です.
<hr>
/etc/printcap ファイル形式 項目 lpr オプション ------------ ------------- ---------- cifplot cf -c DVI df -d plot gf -g ditroff nf -n FORTRAN text rf -f troff tf -t raster vf -v プレインテキスト if なし, -p, または -l<hr>
先の例のように, lpr -d
を使うためには, 出力先の
プリンタの /etc/printcap
内のエントリで,
df
項目が必要であることが分かります.
反論はあるかも知れませんが,
FORTRAN テキストや plot のような形式は, 多分, 廃れ
てていくでしょう. あなたのサイトで, 自前のフィルタをイ
ンストールするだけで, プリントオプションのいくつか, あ
るいは, 全部に新しい意味を与えることができます. 例えば,
Prinerleaf ファイル (Interleaf デスクトップパブリッシン
グプログラムによるファイル) を直接印字したいとします.
そして, Printerleaf 用の変換フィルタを gf
項目で
指定したパスにインストールすれば, lpr -g
の意味
は「Printerleaf ファイルを印字する」意味だとユーザに教
えることができます.
変換フィルタは FreeBSD の基本システムのインストールとは別
にインストールするプログラムなので, 変換フィルタは, 多
分, /usr/local
ディレクトリの下に置くべ
きです. フィルタは LPD だけが実行する特別なプログラム,
すなわち, 一般ユーザが実行する必要すらない
プログラムなので, /usr/local/libexec
ディレ
クトリに置くのが普通です.
変換フィルタを使用可能にするためには,
/etc/printcap
の目的のプリンタの適切な項目に
フィルタがあるパス名を指定します.
DVI 変換フィルタをプリンタ bamboo
のエントリに加
えてみましょう. プリンタ bamboo
の df
項目を
新たに加えた/etc/printcap
ファイルの例を以下
に再掲します.
<hr>
# # /etc/printcap for host rose - added df filter for bamboo # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf:<hr> DVI フィルタは
/usr/local/libexec/psdf
という
名前のシェルスクリプトです. このスクリプトは次のように
なっています.
<hr>#!bin/sh # # psdf - DVI to PostScript printer filter # Installed in /usr/local/libexec/psdf # # Invoked by lpd when user runs lpr -d # exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@"<hr> このスクリプトでは,
dvips
をフィルタモード (引数
-f
) で, 標準入力上で起動しています. 標準入力は印字
するジョブです. それから, PostScript プリンタ用フィ
ルタ lprps
(これについては「
プレインテキス トのジョブを PostScript プリンタで印字する」
を参照してください) を LPD に与えられた引数を付けて起動
します. lprps
はこれらの引数を印字されたページ分
の課金をおこなうために使われます.
変換フィルタのインストールには決まったステップがないの で, その代わりに, 例をもっと挙げることにします. これを, 自分でフィルタを作る際のガイドにしてください. 適当な例が あったら, それをそのまま使ってください.
次のスクリプト例は, Hewlett Packard LaserJet III-Si の ための, raster (ええと・・実は, GIF ファイル) 用の変 換フィルタです. <hr>
#!/bin/sh # # hpvf - Convert GIF files into HP/PCL, then print # Installed in /usr/local/libexec/hpvf PATH=/usr/X11R6/bin:$PATH; export PATH giftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \ && exit 0 \ || exit 2<hr> ここでは, GIF ファイルから PNM (portable anymap) 形式 に変換し, 次に PGM (portable graymap) 形式に変換してか ら, LaserJet/PCL-互換データに変換しています.
上記のフィルタを使うプリンタのためのエントリを付け加え
た /etc/printcap
ファイルは次のようになります.
<hr>
# # /etc/printcap for host 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:<hr>
次のスクリプトは, PostScript プリンタ bamboo
のための groff 組版システムの troff データのための変換
フィルタです.
<hr>
#!/bin/sh # # pstf - Convert groff's troff data into PS, then print. # Installed in /usr/local/libexec/pstf # exec grops | /usr/local/libexec/lprps "$@"<hr> 上記のスクリプトではプリンタとの通信をおこなうため,
lprps
をまた利用しています. プリンタがパラレルポー
トに接続されている場合は, 代わりに, 次のスクリプトを使
うかもしれません.
<hr>#!/bin/sh # # pstf - Convert groff's troff data into PS, then print. # Installed in /usr/local/libexec/pstf # exec grops<hr> これで完成しました. 次に, フィルタを使用可能にするため に
/etc/printcap
に加える必要があるエントリを
示します.
:tf=/usr/local/libexec/pstf:
次の例をみたら, FORTRAN のベテランは赤面するかもしれ
ません. この FORTRAN テキストフィルタは, プレインテキ
ストを直接印字できるすべてのプリンタで利用できます. この
フィルタをプリンタ teak
にインストールすることに
しましょう.
<hr>
#!/bin/sh # # hprf - FORTRAN text filter for LaserJet 3si: # Installed in /usr/local/libexec/hprf # printf "\033&k2G" && fpr && printf "\f" && exit 0 exit 2<hr> そして, このフィルタを使用可能にするため, 以下の行を
/etc/printcap
のプリンタ teak
のエントリ
に加えます.
:rf=/usr/local/libexec/hprf:
これが最後の, そして, 若干複雑な例です. 前に紹介した
LaserJet プリンタ teak
に, DVI フィルタを加える
ことにしましょう. 最初に, 簡単な部分をおこないます. すなわ
ち, DVI フィルタの位置を /etc/printcap
に書
き加えます.
:df=/usr/local/libexec/hpdf:
さて, 難しい部分であるフィルタの作成をおこないます. このた
めに, DVI から LaserJet/PCL への変換プログラムが必要
です. FreeBSD のポート集 (「
ポー トコレクション」を参照してください) には, それがあ
ります. dvi2xx
というのがそのパッケージの名前で
す. これをインストールすると, 必要なプログラム
dvilj2p
が使えます. このプログラムは DVI を
LaserJet IIp, LaserJet III, そして LaserJet 2000 の互
換コードへ変換してくれます.
dvilj2p
はフィルタ hpdf
を極めて複雑にしてい
ます. なぜなら, dvilj2p
は標準入力からデータを読
み込むことができないからです. このプログラムを働かせる
ためには, ファイル名が必要です. もっと悪いことに, ファ
イル名は .dvi
で終わっている必要があり, 標準入力
の代わりに, /dev/fd/0
を使うのは問題がありま
す. この問題は, (.dvi
で終わる) 一時的なファイル名
から/dev/fd/0
に (シンボリックな) リンクを張る
ことで回避することができます. これで, dvilj2p
に
強制的に標準入力からデータを読み込ませることができます.
もう1つの問題は, 一時的なリンクを張るために /tmp ディ
レクトリを使うことができないという事実です. シンボリッ
クリンクはユーザ, グループが bin
であるユーザに所
有されています. フィルタはユーザ daemon
として起
動します. そして, /tmp
ディレクトリはスティッ
キービットが立っています. フィルタはリンクを作ることが
できます. しかし, リンクは別のユーザに所有されているた
め, 作業が終了したとき, このリンクを削除することができ
ません.
その代わりに, シンボリックリンクは現在の作業ディレクト
リ, すなわち, スプーリングディレクトリ
(/etc/printcap
の sd
項目で指定する) に作
ることにします. フィルタが作業するにはここの場所は完璧
な場所で, なぜなら, 特に, スプーリングディレクトリのディ
スクの空き容量は (ときどき) /tmp
ディレクトリ
よりもたくさんあるからです.
以下に示すのが最後のフィルタです. <hr>
#!/bin/sh # # hpdf - Print DVI data on HP/PCL printer # Installed in /usr/local/libexec/hpdf PATH=/usr/local/bin:$PATH; export PATH # # Define a function to clean up our temporary files. These exist # in the current directory, which will be the spooling directory # for the printer. # cleanup() { rm -f hpdf$$.dvi } # # Define a function to handle fatal errors: print the given message # and exit 2. Exiting with 2 tells LPD to do not try to reprint the # job. # fatal() { echo "$@" 1>&2 cleanup exit 2 } # # If user removes the job, LPD will send SIGINT, so trap SIGINT # (and a few other signals) to clean up after ourselves. # trap cleanup 1 2 15 # # Make sure we are not colliding with any existing files. # cleanup # # Link the DVI input file to standard input (the file to print). # ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0" # # Make LF = CR+LF # printf "\033&k2G" || fatal "Cannot initialize printer" # # Convert and print. Return value from dvilj2p does not seem to be # reliable, so we ignore it. # dvilj2p -M1 -q -e- dfhp$$.dvi # # Clean up and exit # cleanup exit 0<hr>
ここまでに述べてきたフィルタによって, 印字環境の能率が
上がったことと思います. しかし, これはどのフィルタを使
うかを (lpr
のコマンドライン上で) ユーザが指定しな
くてはならないという代価を支払って実現されています. コ
ンピュータの事情にあまり詳しくないユーザにとって, フィ
ルタのオプションを指定させられるということはいらいらさ
せられるものになるでしょう. 更に悪いことに, 間違ったフィ
ルタオプションを指定されると, 間違った形式のファイルが
そのフィルタに適用されることになり, その結果, 何百枚も
の紙を掃き出すことになるかもしれません.
そのような結果になるならば, 変換フィルタをインストール
するよりもむしろ, テキストフィルタ (これがデフォルトフィ
ルタなので) に印字するよう要求されたファイルの形式を検
出させ, 自動的に, 適切な変換フィルタを起動するようにし
たいと思うかもしれません. ここでは file
コマンド
のようなツールを役立たせることができます. もちろん,
いくつかのファイル形式の違いを見分けることは難しい
ことでしょう. そして, もちろん, それらのファイルに対し
ては, 変換フィルタを提供するだけで済ますこともできるの
です.
FreeBSD のポート集には, apsfilter
と呼ばれる自
動変換をおこなうテキストフィルタがあります. このフィルタは
プレインテキスト, PostScript, DVI ファイルを検
出し, 適当な変換をおこなった後, データを印字することができ
ます.
LPD スプーリングシステムでは, ここまでにまだ取り上げていな いフィルタ形式, 出力フィルタをサポートしています. 出力 フィルタは, テキストフィルタのように, プレインテキスト のみを印字するために意図されたものですが, 非常に簡単化 されています. テキストフィルタを用いずに, 出力フィルタ を使っている場合は, 次のようになります.
-wwidth -llength
ここで, width は対象となるプリンタの pw
項
目, length は pl
項目に指定された数です. 出力フィルタの簡便さに誘惑されてはいけません. もし, ジョ ブ中のそれぞれのファイルに別のページ番号を付加しようと しても, 出力フィルタはうまく動作しないでしょう. そのような動作を期待しているならば, (入力フィルタとし ても知られている) テキストフィルタを使ってください. 詳 しくは, 「 テキスト フィルタのインストール」をご覧ください. さらに, 出力 フィルタは, 実のところ, もっと複雑になっています. まず, 特殊なフラグ文字を検出するために, フィルタに送ら れてくるバイトストリームを検査する必要があります. また, LPD に代わって, 自分自身にシグナルを送らなければなりま せん.
しかしながら, ヘッダページの印字をおこないたい場合, また, エスケープシーケンスやヘッダページを印字できるようにす るその他の初期化文字列を送信する必要がある場合, 出力ファ イルが必要です.
1台のプリンタに対し, LPD では出力フィルタとテキスト, または, 他のフィルタを両方使うことができます. このよう な場合, LPD はヘッダページ (「 ヘッダページ」 を参照してください) だけを印字させるために, 出 力フィルタを起動させます. それから LPD では, アウトプッ トフィルタに2バイトの文字 (ASCII 031 の次に ASCII 001) を送ることで, 出力フィルタが自力で停止することを 期待しています. 2バイト (031, 001) が出力フィルタに送られ たとき, 出力フィルタは自分自身にシグナル SIGSTOP を送 ることによって停止するべきです. LPD がその他のフィル タの起動を完了したとき, LPD は出力フィルタにシグナル SIGCONT を送ることで, 出力フィルタを再起動させます.
出力フィルタがあり, テキストフィルタがない場合, LPD はプレインテキストのジョブをおこなう際に, 出力フィル タを使います. 前述したように, 出力フィルタでは, ジョブ 中の各ファイルの並びの間に FROM FEED 文字や紙を排出す る他の文字を入れることはしません. この動作は多分, あな たが求めているものとは異なっているでしょう. ほと んどすべての場合において, テキストフィルタが必要とされる はずです.
プログラム lpf
は, テキストフィルタの項で既に紹介
しましたが, 出力フィルタとしても動作させることができま
す. もし, 簡便で極悪な出力フィルタが必要で, かつ, バイ
トストリームを検査したりシグナルを送るコードを書きたく
ないときには, lpf
をお試しください. あるいは, プ
リントが要求する初期化コードを送るために, lpf
を
シェルスクリプトに包んで使うこともできます.
lpf
プログラム /usr/libexec/lpr/lpf
は, FreeBSD の
バイナリ配布に付属しているテキストフィルタ (入力フィル
タ) で, 出力を字下げしたり (lpr -i
でジョブが入力さ
れたとき), 文字を未処理のままプリンタに送ったり
(lpr -l
でジョブが入力されたとき), ジョブ中のバッ
クスペースやタブの印字位置を調節したり, 印字したページ
に対して課金したりすることができます. また, このフィル
タは出力フィルタとしても動作させることができます.
lpf
は多くの印字環境において使用することに適して
います. このフィルタには, プリンタに初期化文字列を送る
機能はありませんが, 必要とされる初期化をおこない, それから
lpf
を実行させるためのシェルスクリプトを作成する
のはたやすいことです.
lpf
に対して, 印字ページへの課金を正確におこなわせる
ためには, /etc/printcap
ファイルの中の
pw
と pl
の項目に正確な値を入れておく必要が
あります. これらの値は, どのくらいの量のテキストがペー
ジにフィットするか, また, ユーザのジョブが何ページある
のかを調べるために使われます. プリンタの課金についての
詳しい情報については, 「
プリンタの利用に対す る課金」をご覧ください.