|
9. Доступ к принтеру Windows с машин под LinuxДля доступа к принтеру на Windows машине, вы должны сделать следующее: a) ВЫ должны иметь правильные записи в файле /etc/printcap и они должны соответствовать локальной структуре директорий (для директории спула, и т.п.) b) У вас должен быть скрипт /usr/bin/smbprint. Он идет вместе с исходными текстами Samba, но не со всеми двоичными дистрибутивами Samba. Его немного модифицированная копия обсуждается ниже. c) Если вы хотите преобразовывать ASCII файлы в Postscript, вы должны иметь nenscript, или его эквивалент. nenscript -- это конвертор Postscript, он обычно устанавливается в директорию /usr/bin. d) Вы можете хотеть сделать печать через Samba более легкой с помощью программы-надстройки. Простой скрипт на perl, который обрабатывает ASCII, Postscript или преобразованный Postscript дан ниже. Запись в /etc/printcap ниже приведена для принтера HP 5MP на сервере Windows NT. Записи следующие:
cm - комментарий lp - имя устройства, открываемого для вывода sd - директория спула принтера (на локальной машине) af - файл учета пользования принтером mx - максимальный размер файла (ноль -- без ограничений) if - имя входного фильтра (скрипта) Для более детальной информации смотрите Printing HOWTO или справочные страницы по printcap.
# /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: Убедитесь, что директории спула и учета пользования существуют и
имеют право на запись. Убедитесь, что строка 'if' содержит
правильный путь к скрипту Далее идет сам скрипт Вы можете захотеть взглянуть на него внимательно. Есть некоторые мелкие изменения, которые показали себя полезными.
#!/bin/sh -x # Этот скрипт является входным фильтром для основанной на printcap # печати на unix-машинах. Он использует программу smbclient для # печати файла на указанный smb-сервер и сервис. # Например вы можете иметь запись в printcap подобную этой # # smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint # # которая создает unix-принтер названный "smb", который будет # печатать с помощью этого скрипта. Вам необходимо создать директорию # спула /usr/spool/smb с соответствующими правами и владельцем # Установите здесь сервер и сервис на который вы хотите печатать. В # этом примере я имею PC с WfWg PC, названную "lapland", которая # имеет экспортируемый принтер, называемый "printer" без пароля # # Далее скрипт был изменен hamiltom@ecnz.co.nz (Michael Hamilton) # так что сервер, сервис и пароль могут быть считаны из файла # /usr/var/spool/lpd/PRINTNAME/.config # # Для того чтобы это работало запись в /etc/printcap должна # включать файл учета использования (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: # # Файл /usr/var/spool/lpd/PRINTNAME/.config должен содержать # server=PC_SERVER # service=PR_SHARENAME # password="password" # # Например, # 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 >> $logfile Большинство дистрибутивов linux идет с программой
Использование: print [-a|c|p] <filename> -a печатает <filename> как ASCII -c печатает <filename> отформатированный как исходный код -p печатает <filename> как Postscript Если опции не заданы, программа попробует определить тип файла и печатать соответственно Используя smbprint для печати ASCII файлов, скрипт следит за длинными строками. Если возможно этот скрипт разрывает длинную строку на пробеле (вместо разрыва в середине слова). Форматирование исходного кода выполняется с помощью
Postscript-документы уже правильно отформатированы, так что они печатаются сразу.
#!/usr/bin/perl # Скрипт: print # Авторы: Brad Marshall, David Wood # Plugged In Communications # Дата: 960808 # # Используется для печати на сервис oreilly, который расположен на # сервере zimmerman # Назначение: Берет файлы разных типов как аргумент и обрабатывает # их соответственно для передачи на скрипт печать Samba. # # В настоящее время поддерживаются типы файлов: # # ASCII - Если длина строки длинее чем $line_length символов, то # переносит строку на пробеле # Postscript - Берет без обработки # Code- Форматирует в Postscript (используя nenscript), чтобы # отображать правильно (альбомный формат, фонт и т.п.) # # Установить максимальную длину строки ASCII текста $line_length = 76; # Установить путь к скрипту печати Samba $print_prog = "/usr/bin/smbprint"; # Установить путь и имя nenscript (конвертера ASCII-->Postscript) $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 " Использование: print [-a|c|p] <filename> -a печатает <filename> как ASCII -c печатает <filename> отформатированный как исходный код -p печатает <filename> как Postscript Если опции не заданы, программа попробует определить тип файла и печатать соответственно\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); }
|
|||||||||||||||||
With any suggestions or questions please feel free to contact us |