Windows Printing System にしか対応してないプリンタをLinuxから使う

はじめに

世の中のプリンタは「Windows対応!」とか「Mac対応!」といったマークつきの ものが目につきますが、大抵のものはLinuxでも使うことが出来ます。 それらは、 Linux ハードウェア実績リスト にありますが、基本的には ghostscript がいろんなプリンタに対応しているからです。 てな話はご存知でしょう。 Japanese Printing mini HOWTOに目を通されることをお勧めします。 オープンソースでもこうしたドライバが作られるのは、 ESC/PやLIPSといったオープンな規格に合った形でメーカーが供給している からです。 一般的でスマートな方法は Print2Win.eucにあります。 でも、プリンタの中にはどうしてもLinuxから使えないプリンタがあります。 それが「Windows Printing System(以下WPS)」という規格のもので、 大手プリンタメーカーからも売られています。 これらのプリンタは、価格か安いので、間違って買ってしまった人も 世の中にはいらっしゃると思います。 私の研究室はまさにその例です。うちだけかと思ったら、向かいの 研究室(Alpha Linuxを日本で最初期に導入したところ)も買ってしまい、 大学院生に安く転売していました。それは、なんと Windows NT 4.x でも、 その WPS プリンタが使えなかったからです。
規格(仕様)をオープンにしないからLinux(オープンソース)では使えない

という話はどこかで聞いたことがある。あ、 neomagic製のビデオカードで XFree86のドライバが 書けない(今はフリーで出ています)という話があった。

でも、neomagicと違って、WPSはMicrosoftが相手ですから、 Linux用WPSドライバが書かれるのは絶望的と言って良いでしょう。

WPSプリンタがどうして安いのか、というのは規格がオープンでないから 判らないのですが、体験的に思うのは、
これってプリンタ本体が非力なのでPCのCPUパワーを使ってるんじゃないか?
ということです。ローカルに接続されたWPSプリンタが動き始めると、 とたんに処理が重くなって、Windows上の作業が中断されてしまう。。 誰か暇だったら詳しい話を教えて下さい。

さて、そんなとんでもないプリンタを買ってしまった場合、どうするのか? というのが今回のお話で、
1. 向かいの研究室のように売り飛ばす
2. Linuxで使うのをあきらめる
という選択肢がまず考えられます。それでもあきらめられない私の方法を 紹介します。

基本的な考え方

WPS対応のプリンタはWindowsでしか使えないので、プリンタ専用の マシンを用意することから始めます。要はプリンタサーバーなのですが、 lpdを使わないところがミソです(この方法に成功したら printcap を 書き直せばいいと思いますが、私はやっていません)。 このマシンを仮にPrintServerとします。 次に、PrintServerとお使いのLinuxマシン(仮にLinuxClientとする)で TCP/IPおよび「マイクロソフトネットワーク共有サービス」が使えるようにします。 このあたりのことは詳しくは説明しません。 そして、たとえばPrintServerのDドライブを「共有ドライブ」にします。 基本的なアイディアは、LinuxClientから印刷したいファイルを PrintServerに送ってやって、そのあとでPrintServer側のGhostScriptで 受けとったファイルを印刷してやる、ということです。 このとき、PrintServerへのキューは、一般的な方法ではありませんが telnetを使って出します。図にすると、下のようになります。

     共有ドライブ D:                     nmbd(Samba)
     hostname:PrintServer                 hostname:LinuxClient

    |-----------|                       |----------|
    | Windows9x |                       | Linux	   |
    |           |----|  		|	   |
    |-----------| |----------|  	|----------|
	  |       | プリンタ |		   |
	  |       |----------|		   |
	  |                                | TCP/IP
    ------------------------------------------------------

                                        1. 印刷するファイルを
					   ポストスクリプト(PS)に変換

                        <-------------- 2. SambaClientを使って
					   PSファイルを送る


        4. PC telnetdが  <-------------- 3. telnetでprintserverに
	  GS for Winを  		    接続
	  起動

	5. GS for Winが
	  PSファイルを印刷

       	6. 「OK」のダイアログが
       	   出るのでAutoClickが
	   自動的に押す

       	7. プリントアウトされる

0. ネットワークの設定など

TCP/IPの設定はここでは省略しますが、基本的にLinuxClientとPrintServerを 同じネットワーク上に配置します。 注意点としては、後でPC telnetdをかなりセキュリティ的にいい加減な 使い方をしますので、WAN、いわゆるインターネットに直接接続している ようなタイプのマシンでは使わないほうが良いかもしれません。それから、 PC telnetdで通信を受け付けるクライアントを決めるネットマスクの設定 をしますので、IPアドレスが近くなる(IPアドレス XXX.XXX.XXX.XX? の ? の 下一桁が一致する)ようにします。

次に、PrintServer側で「Microsoftネットワーク共有サービス」 を使えるようにします。この方法も省略しますが、結果的に PSファイルを書き込むドライブ(この例ではD:)を パスワード付きで書き込み可能な状態にすればよいでしょう。

最後に、Linux側のMicrosoftネットワーク共有サービスの設定ですが、 Sambaパッケージに含まれているsmbclientコマンドを使います。 そこで、NetBIOSの名前解決のためのデーモンnmbdを起動しておくことが 必要です。この辺りは SMB-HOWTO を参考に設定します。

Linux側で
smbclient -L PrintServer
として、該当するホストが「見る」ことが出来ればOKです。 実際の出力は以下のような感じになります。
$ smbclient -L PrintServer
Added interface ip=XXX.XX.XX.XX bcast=XXX.XX.XX.255 nmask=255.255.254.0
Server time is Mon Dec 14 17:27:28 1998
Timezone is UTC+9.0
security=share

Server=[PRINTSERVER] User=[] Workgroup=[OURGROUP] Domain=[OURDOMAIN]

        Sharename      Type      Comment
        ---------      ----      -------
        D              Disk      
        LP-700W        Printer   lp-700w

このLP-700Wというのが、ネットワーク上のプリンタの名前です。

1. 印刷するファイルはポストスクリプトに

この方法だと、当然プリント出来るファイルはPostscriptフォーマットに限定 されます。もっとも、ほとんどのファイルはPostscriptに変換出来ますので、 この制限は実用上問題ないかと思われます。
たとえば、プレーンテキストをPostscriptに変換するフィルタとして 私はperl版のa2psを使っています。こんな具合です。
a2ps -p -ns -nt -nh -f9.8 -nf TEXTFILE > TEXTFILE.ps
他には、Netscape Communicator 4.xでは、ナビゲーションツールバーの 「印刷」をクリックすると、Postscrips形式でHTMLファイルなどを落すことが 出来ます。

2. SambaClientを使ってファイルを転送

はじめは、以下のようにprint.psファイルをPrintServerに転送出来るかどうか 確認してみます。
smbclient '\\PrintServer\D' PassWord -D 'MYHOME' -c "put print.ps; quit"
ここで、PassWordは、「Microsoftネットワーク共有サービス」で設定した パスワード、MYHOMEはこの例では、ファイルを置きに行く場所である D:\MYHOMEというディレクトリの指定です。
うまくいくことが確認できたら、後でshスクリプトにしてしまいます。

3. 4. telnetで印刷のキューを出す

さて、これで PrintServer の D:\MYHOME\print.ps にプリントアウトしたい ファイルを置くことが出来ました。で、次にこのファイルを PrintServer上の Windows版Ghostscriptでもって印刷したいのですが、そのための キューを出すために、少しトリッキーな方法でやります。 本当は rshd (リモートシェルデーモン)がWindows9x上で走ればいいのですが、 RSHD どうもうまく 動いてくれませんでした。ということで、 PC Telenet Daemon を使いました。これは、一回のセッションで20個のコマンドを打ち込むまでは フリーウェアとして使って良いということでしたので、PrintServer上で 起動しておきます。で、インストールするとPCTelD.exeという本体と 同じディレクトリに PCTelD.ini という初期化ファイルが出来ます。 これを以下のように変更することによってログインと同時に バッチ処理が行なわれるように出来ます。
; PC Telnet Daemon

[Network]
telnetPortNo=23
subnetMask=FFFFFFF0
supressGA=0
echoMode=N
lineMode=Y
crToCrLf=A

[System]
defaultInitDir=D:\MYHOME
defaultInitPgmFN=print.bat print.ps ; exit
consolePgmFN=
ここの
defaultInitPgmFN=print.bat print.ps ; exit
の行が実際にバッチ処理を行なう部分です。
そして、D:\MYHOME\print.bat という名前で以下の内容のバッチファイルを 作ります。

5. 6. Ghostscript for Winで印刷

@echo off
SET PATH=D:\MYHOME\gstools\gs5.03
SET GS_FONTPATH=C:\windows\fonts
SET GS_LIB=D:\MYHOME\gstools\gs5.03;d:\MYHOME\gstools\gs5.03\kanji;D:\MYHOME\gstools\gs5.03\fonts
D:\MYHOME\gstools\gs5.03\gswin32c -q -r600 -sDEVICE=mswinpr2 -dNOPAUSE -dSAFER -sOutputFile=\\spool\lp-700w %1 -c quit
要するにコンソールモードの Ghostscript for Win を呼び出して、 -sDEVICE=mswinpr2 でWindowsのプリンタドライバによりlp-700wに書き込んで いるだけです。
このときに、一つ問題があって、「プリントアウトしますか?」という 確認のダイアログがPrintServerのWindows9xに出てしまいます。 この「はい」をクリックしないことには先に進んでくれません。そこで、
AutoClick
をPrintServerに仕込んでおきます。これは1000円のシェアウェアですが 私は買って使わせていただいています。うーむ、これだけのために。。

ということで、Linux側に以下のようなシェルスクリプト(printという名前に しています)を作ってやって、コマンドサーチパスの通っているところに 置いて実行フラグを立ててやれば
#!/bin/sh
cp $1 print.ps
smbclient '\\PrintServer\D' PassWord -D 'MYHOME' -c "put print.ps; quit"
telnet PrintServer
/bin/rm print.ps

% print TEXTFILE
で一連の印刷作業をやってくれるように出来るわけです。

この情報は、いろいろ探しまわったけど結局見つからなかったので 自分で考えた方法です。なぜこの情報が見つからないのか、ということを 考えてみますと、方法自体があまりに無理矢理なのと、PC Telenet Daemon の セキュリティの問題などもありますし、あまりお勧めの方法でないことを明記し ておきます。

普通は、ボロいPCとメインのPCと2台のPCがあったら、ボロい方をLinux BOX にして各種サーバとして使い倒すのがよくある話だと思うのですが、 この場合はボロいWindows9xマシンをプリンタサーバにしてしまうという話でした。