Windows マシン上のプリンタを共有するためには以下の作業が必要です。
/etc/printcap
に正しいエントリが必要で、それらはローカ
ルなディレクトリ構造に準じたものである必要があります(スプールディレク
トリの設定など)。
/usr/bin/smbprint
スクリプトが必要です。これは Samba の
ソースパッケージに付いてきますが、Samba のバイナリ配布パッケージには付
いてこないかもしれません。後でオリジナルを少々修正したものを載せます。
nenscript
などの Postscript コンバータを準備する必要があります。
nenscript
は通常は /usr/bin
にインストールされています。
以下に記すのは、Windows NT プリンタに接続された HP 5MP プリンタを利用
するための /etc/printcap
へのエントリです。それぞれの内容は以
下の通りです。
コメント
出力に使うデバイス名
このプリンタのためのスプールディレクトリ
アカウントファイル
最大のファイルサイズ(0 にすれば無制限になります)
入力に用いられるフィルタ(またはスクリプト)
さらに情報が必要なら、Printing HOWTO や printcap
の man ページを
見て下さい。
# /etc/printcap # # //zimmerman/oreilly via smbprint # lp:\ :cm=HP 5MP Postscript OReilly on zimmerman:\ :lp=/dev/lp1:\ :sd=/var/spool/lpd/lp:\ :af=/var/spool/lpd/lp/acct:\ :mx#0:\ :if=/usr/bin/smbprint:
スプールディレクトリとアカウントファイルが存在しており、書き込み可能で
あることを確認しておいて下さい。また printcap
の if
行に、以
下に記す smbprint
スクリプトへの正しいパスが設定されていること、
lp
行に /dev
ディレクトリにある正しいデバイスが設定され
ていることも確認して下さい。
次は smbprint
です。これは通常 /usr/bin
に置かれており、
Samba を作った Andrew Tridgell 本人によって書かれたものです(筆者の知
らない Samba の共作者が他にいらっしゃったらすみません)。これは Samba
のソースパッケージに入っていますが、バイナリ配布の場合には無いかも知れ
ませんので、以下に私が少々手を加えたものを示しておきます。
以下に記したスクリプトを注意深く見て下さい。これはオリジナルを修正した もので、多少使いやすくなっていると思います。
#!/bin/sh -x # This script is an input filter for printcap printing on a unix machine. It # uses the smbclient program to print the file to the specified smb-based # server and service. # For example you could have a printcap entry like this # # smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint # # which would create a unix printer called "smb" that will print via this # script. You will need to create the spool directory /usr/spool/smb with # appropriate permissions and ownerships for your system. # Set these to the server and service you wish to print to # In this example I have a WfWg PC called "lapland" that has a printer # exported called "printer" with no password. # # Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton) # so that the server, service, and password can be read from # a /usr/var/spool/lpd/PRINTNAME/.config file. # # In order for this to work the /etc/printcap entry must include an # accounting file (af=...): # # cdcolour:\ # :cm=CD IBM Colorjet on 6th:\ # :sd=/var/spool/lpd/cdcolour:\ # :af=/var/spool/lpd/cdcolour/acct:\ # :if=/usr/local/etc/smbprint:\ # :mx=0:\ # :lp=/dev/null: # # The /usr/var/spool/lpd/PRINTNAME/.config file should contain: # server=PC_SERVER # service=PR_SHARENAME # password="password" # # E.g. # server=PAULS_PC # service=CJET_371 # password="" # # Debugging log file, change to /dev/null if you like. # logfile=/tmp/smb-print.log # logfile=/dev/null # # The last parameter to the filter is the accounting file name. # spool_dir=/var/spool/lpd/lp config_file=$spool_dir/.config # Should read the following variables set in the config file: # server # service # password # user eval `cat $config_file` # # Some debugging help, change the >> to > if you want to same space. # echo "server $server, service $service" >> $logfile ( # NOTE You may wish to add the line `echo translate' if you want automatic # CR/LF translation when printing. echo translate echo "print -" cat ) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $user -N -P >> $log file
ほとんどの Linux パッケージには、ASCII 文書を Postscript にする
nenscript
コマンドが含まれています。以下の perl スクリプトは、
smbprint
を使って印刷する際に、よりシンプルなインターフェースを提
供するものです。
Usage: print [-a|c|p] <filename> -a prints <filename> as ASCII -c prints <filename> formatted as source code -p prints <filename> as Postscript If no switch is given, print attempts to guess the file type and print appropriately.
smbprint
を使って ASCII ファイルを印刷すると、長い行は改行されて
しまいます。このスクリプトでは、可能な限り単語の途中ではなく、空白で改
行するようにしています。
ソースコードのフォーマットには nenscript
を用いています。ASCII ファ
イルは 2 段組みに整形され、ヘッダ(日付、ファイル名など)がつきます。
このスクリプトを雛形にして、他の整形方法を用いることもできるでしょう。
Postscript の文書はすでに整形されているものとみなして、そのまま通すよ うになっています。
#!/usr/bin/perl # Script: print # Authors: Brad Marshall, David Wood # Plugged In Communications # Date: 960808 # # Script to print to oreilly which is currently on zimmerman # Purpose: Takes files of various types as arguments and # processes them appropriately for piping to a Samba print script. # # Currently supported file types: # # ASCII - ensures that lines longer than $line_length characters wrap on # whitespace. # Postscript - Takes no action. # Code - Formats in Postscript (using nenscript) to display # properly (landscape, font, etc). # # Set the maximum allowable length for each line of ASCII text. $line_length = 76; # Set the path and name of the Samba print script $print_prog = "/usr/bin/smbprint"; # Set the path and name to nenscript (the ASCII-->Postscript converter) $nenscript = "/usr/bin/nenscript"; unless ( -f $print_prog ) { die "Can't find $print_prog!"; } unless ( -f $nenscript ) { die "Can't find $nenscript!"; } &ParseCmdLine(@ARGV); # DBG print "filetype is $filetype\n"; if ($filetype eq "ASCII") { &wrap($line_length); } elsif ($filetype eq "code") { &codeformat; } elsif ($filetype eq "ps") { &createarray; } else { print "Sorry..no known file type.\n"; exit 0; } # Pipe the array to smbprint open(PRINTER, "|$print_prog") || die "Can't open $print_prog: $!\n"; foreach $line (@newlines) { print PRINTER $line; } # Send an extra linefeed in case a file has an incomplete last line. print PRINTER "\n"; close(PRINTER); print "Completed\n"; exit 0; # --------------------------------------------------- # # Everything below here is a subroutine # # --------------------------------------------------- # sub ParseCmdLine { # Parses the command line, finding out what file type the file is # Gets $arg and $file to be the arguments (if the exists) # and the filename if ($#_ < 0) { &usage; } # DBG # foreach $element (@_) { # print "*$element* \n"; # } $arg = shift(@_); if ($arg =~ /\-./) { $cmd = $arg; # DBG # print "\$cmd found.\n"; $file = shift(@_); } else { $file = $arg; } # Defining the file type unless ($cmd) { # We have no arguments if ($file =~ /\.ps$/) { $filetype = "ps"; } elsif ($file =~ /\.java$|\.c$|\.h$|\.pl$|\.sh$|\.csh$|\.m4$|\.inc$|\.html$|\.htm$/) { $filetype = "code"; } else { $filetype = "ASCII"; } # Process $file for what type is it and return $filetype } else { # We have what type it is in $arg if ($cmd =~ /^-p$/) { $filetype = "ps"; } elsif ($cmd =~ /^-c$/) { $filetype = "code"; } elsif ($cmd =~ /^-a$/) { $filetype = "ASCII" } } } sub usage { print " Usage: print [-a|c|p] <filename> -a prints <filename> as ASCII -c prints <filename> formatted as source code -p prints <filename> as Postscript If no switch is given, print attempts to guess the file type and print appropriately.\n "; exit(0); } sub wrap { # Create an array of file lines, where each line is < the # number of characters specified, and wrapped only on whitespace # Get the number of characters to limit the line to. $limit = pop(@_); # DBG #print "Entering subroutine wrap\n"; #print "The line length limit is $limit\n"; # Read in the file, parse and put into an array. open(FILE, "<$file") || die "Can't open $file: $!\n"; while(<FILE>) { $line = $_; # DBG #print "The line is:\n$line\n"; # Wrap the line if it is over the limit. while ( length($line) > $limit ) { # DBG #print "Wrapping..."; # Get the first $limit +1 characters. $part = substr($line,0,$limit +1); # DBG #print "The partial line is:\n$part\n"; # Check to see if the last character is a space. $last_char = substr($part,-1, 1); if ( " " eq $last_char ) { # If it is, print the rest. # DBG #print "The last character was a space\n"; substr($line,0,$limit + 1) = ""; substr($part,-1,1) = ""; push(@newlines,"$part\n"); } else { # If it is not, find the last space in the # sub-line and print up to there. # DBG #print "The last character was not a space\n"; # Remove the character past $limit substr($part,-1,1) = ""; # Reverse the line to make it easy to find # the last space. $revpart = reverse($part); $index = index($revpart," "); if ( $index > 0 ) { substr($line,0,$limit-$index) = ""; push(@newlines,substr($part,0,$limit-$index) . "\n"); } else { # There was no space in the line, so # print it up to $limit. substr($line,0,$limit) = ""; push(@newlines,substr($part,0,$limit) . "\n"); } } } push(@newlines,$line); } close(FILE); } sub codeformat { # Call subroutine wrap then filter through nenscript &wrap($line_length); # Pipe the results through nenscript to create a Postscript # file that adheres to some decent format for printing # source code (landscape, Courier font, line numbers). # Print this to a temporary file first. $tmpfile = "/tmp/nenscript$$"; open(FILE, "|$nenscript -2G -i$file -N -p$tmpfile -r") || die "Can't open nenscript: $!\n"; foreach $line (@newlines) { print FILE $line; } close(FILE); # Read the temporary file back into an array so it can be # passed to the Samba print script. @newlines = (""); open(FILE, "<$tmpfile") || die "Can't open $file: $!\n"; while(<FILE>) { push(@newlines,$_); } close(FILE); system("rm $tmpfile"); } sub createarray { # Create the array for postscript open(FILE, "<$file") || die "Can't open $file: $!\n"; while(<FILE>) { push(@newlines,$_); } close(FILE); }
===訳注===
nenscrpt
は日本語を通しませんが、JE には psconv
という日本語
に対応したコマンドが入っています。他にも a2ps
、ps2ascii
、
ps2txt
、toPS
など様々なものがネットワークから入手可能です。
なお、訳者はこの章のスクリプトをテストできる環境がありませんので、原文 にあったスクリプトをそのまま載せておきました。改造して日本語を通すこと に成功した方は、ご連絡下されば幸いです。
==訳注終==