次のページ 前のページ 目次へ

11. ネットワーク越しのプリンタへの印刷方法

lpd の特徴のひとつは、異なったマシンに物理的に接続しているプリンタに 対するネットワーク越しでの印刷をサポートしていることです。 フィルタスクリプトと様々なユーティリティを注意深く組み合わせることで、 あらゆる種類のネットワーク上のプリンタに透過的に lpr で印刷することが できます。

11.1 Unix/lpd のホストに対して

リモートのマシンからあなたのプリンタに印刷できるようにするためには、 そのマシンを /etc/hosts.equiv/etc/hosts.lpd に列挙しなければなりません (hosts.equiv は他にも多くの影響を及ぼすことに 注意してください - これにマシンを列挙する場合、自分が何をしているのか 必ずわかっておいてください)。 rs 属性を使うことで、他のマシン上のある特定のユーザ のみにあなたのプリンタへの印刷を許可するようにできます - これに関する情報は lpd の man ページをご覧ください。

lpd を使って

他のマシンで印刷するには、このような /etc/printcap エントリを 作成してください。

# REMOTE djet500
lp|dj|deskjet:\
        :sd=/var/spool/lpd/dj:\
        :rm=machine.out.there.com:\
        :rp=printername:\
        :lp=/dev/null:\
        :sh:
ローカルマシンには lpd によって管理されるスプールディレクトリが 依然としてあることに注意してください。 リモートマシンがビジーであったり、オフラインであったりした場合、 ローカルマシンからの印刷ジョブは送信可能になるまで そのスプール領域で待たされます。

rlpr を使って

ジョブ送信のために lpd を苦労して設定しなくても、 rlpr を使って印刷ジョブをリモートマシンのキューに 直接送信することもできます。 いろいろなプリンタに対してほんの時々印刷を行なうような状況では、 たいていこの方法が便利です。 rlpr の発表文によると -

rlpr は、TCP/IP を使ってネットワーク上のどこにある lpd サーバにでも、 印刷ジョブを送信します。

lpr と違い、リモートプリンタが印刷元のマシンにはっきりと (例えば /etc/printcap を介してのように)知られている必要は *ありません*。 このため、かなり柔軟性に優れ、管理の手間が少なくなります。

rlpr は従来の lpr が使用されるような場面ならどこでも 使うことができ、伝統的な BSD の lpr と下位互換性があります。

rlpr の最大の利点は、 印刷元のシステムがどのように設定されているかを考慮せずに *どこからでもどこにでも* 離れたところで印刷できるということです。 rlpr は従来の lpr と全く同じようにフィルタとして動作させることができ、 これによって リモートマシンで実行されている netscape や xemacs などのクライアント からあなたのローカルマシンへの印刷をわずかな手間で行なえます。

rlpr は Metalab から入手できます。

11.2 Win95 や WinNT、LanManager、Samba のプリンタに対して

Printing to Windows mini-HOWTO があり、 ここよりも豊富な情報が書かれています。

smbclient プログラム(samba の一部)によって lpd のキューを TCP/IP ベースの SMB 印刷サービスに向けることができます。 これを行なう smbprint というスクリプトが samba に含まれています。 簡単に言うと、対象となるプリンタのための設定ファイルをスプール ディレクトリに置いて、smbprint スクリプトを if として 設定してください。

/etc/printcap のエントリはこのような感じになります -

lp|remote-smbprinter:\
    :lp=/dev/null:sh:\
    :sd=/var/spool/lpd/lp:\
    :if=/usr/local/sbin/smbprint:

この設定方法に関するこれ以上の情報については smbprint スクリプトに含まれるドキュメントを読むべきでしょう。

smbclient を使って、lpd を介さずに SMB の印刷サービスにファイルを直接投げることもできます。 man ページをご覧ください。

11.3 NetWare のプリンタに対して

ncpfs スイートは、 nprint と呼ばれるユーティリティを含んでいます。 これは NetWare を対象としているという点を除けば smbprint と同じ機能を提供します。 Metalab から ncpfs を入手することができます。 バージョン 0.16 の LSM エントリより -

ncpfs を使って、NetWare サーバのボリュームを Linux にマウントする ことができます。NetWare の印刷キューに印刷したり、NetWare の印刷キューを Linux の印刷システムにスプールしたりすることもできます。 カーネルは 1.2.x または 1.3.54 以降のバージョンが必要です。 ncpfs は 1.3.54 より前の 1.3.x カーネルでは動作しません。

nprint を lpd 経由で動作させるには、標準入力を NetWare のプリンタに 印刷するためのちょっとしたシェルスクリプトを作成して lpd の印刷キュー の if として設定してください。 このような感じになるでしょう -

sub2|remote-NWprinter:\
        :lp=/dev/null:sh:\
        :sd=/var/spool/lpd/sub2:\
        :if=/var/spool/lpd/nprint-script:
nprint-script は大体このような感じになるでしょう -
#! /bin/sh
# You should try the guest account with no password first!
# まずはパスワードなしのゲストアカウントを試すべきです!
/usr/local/bin/nprint -S net -U name -P passwd -q printq-name -

11.4 EtherTalk (Apple) のプリンタに対して

netatalk パッケージは nprintsmbclient のようなものを含んでいます。 Apple のネットワークから、もしくは Apple のネットワークへ 印刷する手順を私がやろうとしているよりよっぽどうまく 文書にまとめられている方がいます - Linux Netatalk-HOWTO をご覧ください。

11.5 HP やその他のイーサネットプリンタに対して

HP や他のいくつかのプリンタには lpd を使って直接印刷できるようなイーサネット インタフェースがついてきます。 あなたのプリンタやネットワークアダプタに付属の説明書に従うべきですが、 一般的にはそのようなプリンタは lpd を「実行して」おり、 印刷可能なひとつかそれ以上のキューを提供しています。 例えば、HP ではこのような printcap で動作するかもしれません -

lj-5|remote-hplj:\
        :lp=/dev/null:sh:\
        :sd=/var/spool/lpd/lj-5:\
        :rm=printer.name.com:rp=raw:

Jet Direct インタフェースを備えた HP Laserjet プリンタは、 一般に二つの組み込み lpd キューをサポートしています -- PCL を(もしかしたら PostScript も)受け付ける "raw" と、 ただの ascii を受け付ける(また自動的に階段効果に対処する) "text" です。 JetDirect Plus3 3 ポートボックスを持っているなら、 キューは "raw1", "text2" などというように名付けられます。

ISS 会社が HP Jetdirect インタフェースをハングアップさせる 種々のサービス不能攻撃を確認していることに注意してください。 これらのほとんどは 98 年の初秋に明らかにされました。

大規模な環境、中でも特にいくつかのプリンタが PostScript を サポートしていないような環境では、ひとつの専用プリントサーバを設置して、 全てのマシンがそれに対して印刷を依頼し、全ての Ghostscript のジョブがそこで実行されるようにすると便利かもしれません。

また、 これは Linux ボックスをプリンタのスプールサーバとして動作させることで、 ネットワークのユーザが印刷ジョブを素早く完了させ、プリンタが 誰か他の人が送信した他のジョブを印刷している間待たずに済む ようにできます。 修正不可能な古い HP Jetdirect を持っている場合にも言えます - これによってプリンタが動かなくなってしまう頻度を低減します。

これを行なうためには、Linux ボックスのキューをイーサネットを装備した HP LJ を指すように(先述のように)設定してください。 次に LAN の全てのクライアントをその Linux キューを指すように 設定してください(例えば先述の例の lj-5 のように)。

いくつかの HP のネットワークプリンタは、クライアントによって送信 されたバナーページ設定に気づかないようです - プリンタに telnet してリターンキーを 2 回押し、 "banner: 0" と入力した後 "quit" と入力することで、 内部的に生成されたバナーページを取り消すことができます。 この方法で同様に変更できる設定が他にもあります - リストを見るには "?" と入力してください。

全ての設定は HP の WebJet ソフトウェアによって制御することが できます。このパッケージはデーモンとして動作し、指定されたポートに 対する HTTP リクエストを受け付けます。 また、ネットワーク上の HP のプリンタを制御できるフォームと Java アプレットを提供します。 理論的には Unix の印刷キューも制御できるのですが、 rexec サービスを使用して実現しており、 これは全く安全性に欠けているので、この機能を使用することはお勧めしません。

古い HP のプリンタに対して

いくつかのプリンタ (と、プリンタをネットワーク対応にする「ブラックボックス」の類) は、安っぽく貧弱でプロトコルなしの基本的な TCP 接続しかサポートしていません。 この種のもので有名なのは、JetDirect (いくつかの JetDirectEx を含む)の 初期モデルです。 基本的に、このプリンタに印刷するには、プリンタの決められたポート (一般的には 9100 か 3 ポートボックスでは 9100, 9101, 9102)に対して TCP コネクションをオープンし、印刷ジョブを流し込まなければいけません。 LPRng (この節を読んでいるならこちらを代わりに使うべきです) には 印刷ジョブを適当な(random) TCP ポートに流し込むためのサポートが 組み込まれています。しかし、 BSD lpd ではこれほど簡単にはいきません。 おそらく一番いい方法は、 netcat と呼ばれている小さなユーティリティを手にいれて使うことでしょう。 さもなくば、他の手を使って実装してしまうのもありです。Perl で書くなら -

#!/usr/bin/perl
# Thanks to Dan McLaughlin for writing the original version of this
# script (And to Jim W. Jones for sitting next to Dan when writing me
# for help ;)
# このスクリプトの最初のバージョンを書いた Dan MacLaughlin に
# 感謝します(それと Dan が私に助けを求めるメールを書いているときに
# Jim W. Jones が彼の隣に座っていてくれたことに ;-)


$fileName = @ARGV[0];

open(IN,"$fileName") || die "Can't open file $fileName";

$dpi300     = "\x1B*t300R";
$dosCr      = "\x1B&k3G";
$ends = "\x0A";

$port =  9100 unless $port;
$them = "bach.sr.hp.com" unless $them;

$AF_INET = 2;
$SOCK_STREAM = 1;
$SIG{'INT'} = 'dokill';
$sockaddr = 'S n a4 x8';

chop($hostname = `hostname`);
($name,$aliases,$proto) = getprotobyname('tcp');
($name,$aliases,$port) = getservbyname($port,'tcp')
    unless $port =~ /^\d+$/;;
($name,$aliases,$type,$len,$thisaddr) =
        gethostbyname($hostname);
($name,$aliases,$type,$len,$thataddr) = gethostbyname($them);
$this = pack($sockaddr, $AF_INET, 0, $thisaddr);
$that = pack($sockaddr, $AF_INET, $port, $thataddr);

if (socket(S, $AF_INET, $SOCK_STREAM, $proto)) {
#    print "socket ok\n";
}
else {
    die $!;
}
# Give the socket an address.
# ソケットにアドレスを与えます。
if (bind(S, $this)) {
#    print "bind ok\n";
}
else {
    die $!;
}

# Call up the server.
# サーバに接続します。

if (connect(S,$that)) {
#    print "connect ok\n";
}
else {
    die $!;
}

# Set socket to be command buffered.
# ソケットをコマンドバッファリングするように設定します。

select(S); $| = 1; select(STDOUT);

#    print S "@PJL ECHO Hi $hostname! $ends";
#    print S "@PJL OPMSG DISPLAY=\"Job $whoami\" $ends";
#    print S $dpi300;

# Avoid deadlock by forking.
# fork してデッドロックを避けます。

if($child = fork) {
    print S $dosCr;
    print S $TimesNewR;

    while (<IN>) {
        print S;
    }
    sleep 3;
    do dokill();
} else {
    while(<S>) {
        print;
    }
}

sub dokill {
    kill 9,$child if $child;
}

11.6 リモートプリンタに if を実行する

lpd の奇妙な点のひとつは、if がリモートプリンタのためには実行されない ということです。if を実行する必要があるとわかった場合、 キューを二重に設定し、ジョブを再度キューに入れることで実現できます。 例えば、このような printcap を考えてみてください -

lj-5:\
        :lp=/dev/null:sh:\
        :sd=/var/spool/lpd/lj-5:\
        :if=/usr/lib/lpd/filter-lj-5:
lj-5-remote:lp=/dev/null:sh:rm=printer.name.com:\
        :rp=raw:sd=/var/spool/lpd/lj-5-raw:
このような filter-lj-5 スクリプトがあるとします -
#!/bin/sh
gs <options> -q -dSAFER -sOutputFile=- - | \
        lpr -Plj-5-remote -U$5

lpr の -U オプションは lpr がデーモンとして実行されているときに のみ、機能します。これは、再送されたキュー中のジョブに関して 投げた人の名前を正確に設定します。 ユーザ名が第 5 引数ではない場合があるので、 ユーザ名を取得するにはもっと頑健な手段を使用するべきでしょう。 printcap の man ページをご覧ください。

11.7 Windows から

Windows (とおそらく OS/2 も)クライアントから Linux サーバ への印刷は samba パッケージを使用することにより SMB 越しに直接 サポートされています。 また samba パッケージは Windows クライアントとの Linux ファイルシステムのファイルの共有もサポートしています。

samba はかなり完成度の高いドキュメントを含んでおり、 それをカバーする優れた samba FAQ もあります。 Linux ボックスのマジックフィルタを設定してそれに対して PostScript を 印刷することもできますし、 全ての Windows マシンにプリンタ固有のドライバをインストール してまわってそれらに対してフィルタなしのキューを用意することもできます。 Windows のドライバにまかせるほうがより良い出力を得ることができる 場合もありますが、 Windows ボックスがたくさんあるときには、 少々管理の苦労は増えることになります。 ですから、まず PostScript を先に試してみてください。

11.8 Apple から

Netatalk は、 Apple クライアントからの EtherTalk 越しの印刷を サポートします。 さらなる情報が必要ならば Netatalk HOWTO Page をご覧ください。

(訳注: Linux Netatalk 日本語版もどうぞ)

11.9 Netware から

ncpfs パッケージは、NetWare の印刷キューに対するサービスを提供する ために使用できる pserver という名前のデーモンを含んでいます。 私の理解するところでは、 このシステムは Bindery-based NetWare すなわち bindery アクセスを 有効にしている 2.x か 3.x, 4.x を必要とします。

ncpfs と pserver プログラムに関してもっと知りたければ、 ncpfs の FTP サイト をご覧ください。


次のページ 前のページ 目次へ