Online Documentation Server
 ПОИСК
ods.com.ua Web
 КАТЕГОРИИ
Home
Programming
Net technology
Unixes
Security
RFC, HOWTO
Web technology
Data bases
Other docs

 

 ПОДПИСКА

 О КОПИРАЙТАХ
Вся предоставленная на этом сервере информация собрана нами из разных источников. Если Вам кажется, что публикация каких-то документов нарушает чьи-либо авторские права, сообщите нам об этом.




Next Previous Contents


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' содержит правильный путь к скрипту smbprint (дан ниже) и будьте уверены, что указывается на правильное устройство (специальный файл /dev).

Далее идет сам скрипт smbprint. Он обычно находится в директории /usr/bin и относящийся к Andrew Tridgell, человеку кто создал Samba, насколько я знаю. Этот скрипт идет с дистрибутивом исходного кода Samba, но отсутствует в некоторых бинарных дистрибутивах, так что я воссоздал его здесь.

Вы можете захотеть взглянуть на него внимательно. Есть некоторые мелкие изменения, которые показали себя полезными.


#!/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 идет с программой nenscript для преобразования ASCII документов в Postscript. Следующий скрипт на perl делает жизнь легче, обеспечивая простой интерфейс для печати в liinux через smbprint.


Использование: print [-a|c|p] <filename>
 -a печатает <filename> как ASCII
 -c печатает <filename> отформатированный как исходный код
 -p печатает <filename> как Postscript
Если опции не заданы, программа попробует определить
тип файла и печатать соответственно

Используя smbprint для печати ASCII файлов, скрипт следит за длинными строками. Если возможно этот скрипт разрывает длинную строку на пробеле (вместо разрыва в середине слова).

Форматирование исходного кода выполняется с помощью nenscript. Он берет ASCII-файл и форматирует его в 2 колонки с с заголовком (дата, имя файла и т.п.). Он также нумерует строки. Используя этот скрипт как пример другие типы форматирования могут быть сделаны.

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);
}


Next Previous Contents



With any suggestions or questions please feel free to contact us