PDF-Сервер на основе Samba.
Автор : Джон Брайт [John Bright]
Перевод : С. Скороходов
Введение
Формат PDF дает великолепную возможность пересылать документы через Интернет. Применений может быть много, например, рассылка котировок и счетов деловым партнерам. Причин, по которым PDF столь популярен, много, две главные: он в точности сохраняет внешний вид печатного документа и его можно просмотреть практически на любой платформе. Для многих пользователей, приверженных "парадигме" Windows, создание документов в PDF означает необходимость поделиться драгоценной наличностью с ребятами из Adobe. Эта статья, однако, объяснит, как с помощью Linux, Samba и Ghostscript создать сетевую службу по генерации документов в формате PDF сразу и для пользователей Windows, и для пользователей Linux. Все необходимые компоненты, естественно, можно получить бесплатно.
Начнем с общей схемы. С помощью Samba мы создадим "псевдо-принтер" (клиенты будут видеть его, как обычный сетевой принтер), который в свою очередь, будет получать вывод от любого Postscript-принтера и на его основе с помощью Ghostscript создавать документы PDF. Затем мы сконфигурируем машины Windows таким образом, чтобы они использовали этот созданный нами разделяемый "псевдо-принтер" и посылали на него задания в формате Postscript.
Samba
Samba -- это прекрасная программа, которая выполняется на Linux/UNIX и позволяет использовать файлы и принтеры совместно с Windows-компьютерами. Службы, обеспечиваемые Samba, совместимы со стандартными службами "Windows Networking", предоставляемыми Windows 95/98/NT и так далее. Прежде, чем мы приступим к конфигурации Samba для нашей задачи, надо убедиться, что сервер Samba установлен на нашей Linux-машине. Исходный код Samba может, как всегда, быть загружен с www.samba.org, но проще установить на вашу систему пакет "samba", который поставляется с Debian, Red Hat или другим дистрибутивом.
Если вы устанавливаете Samba в первый раз, то стоит просмотреть и отредактировать некоторые из основных параметров конфигурации в файле smb.conf (ищите его в /etc или /etc/samba). Основное, на что надо обратить внимание для того, чтобы сетевые службы работали без сбоев, это политика безопасности (security=share или security=user) и установки "гостевой" учетной записи [guest account]. С деталями настройки Samba можно ознакомится в документации на www.samba.org или в "КакСде" (SMB HOWTO). Ниже будет приведен полный пример конфигурационного файла с "низкими" установками политики безопасности.
Проверка соединения и метода аутентификации клиентов (если таковой используется) на пробном разделяемом файловом ресурсе будет хорошей идеей. В любом случае, если ваши клиенты могут подсоединяться к вашему серверу Samba, то мы готовы к созданию "псевдо-принтера" PDF. Но сначала убедитесь, что у нас имеются нужные для генерации PDF-документов утилиты.
Ghostscript
Ghostscript -- это еще одна превосходная программа для Linux. Часто его используют для правильной конвертации вывода Postscript в "сырой" формат конкретного принтера, но он может также превращать Postscript в PDF. Многие дистрибутивы устанавливают Ghostscript для обеспечения поддержки печати. Если в вашей системе доступна команда "gs", то Ghostscript, вероятно, уже установлен. В противном случае придется установить пакет из вашего дистрибутива: в Red Hat это ghostscript, а в Debian -- gs или gs-aladdin. Наконец, если хочется приключений, то можно скачать исходники с http://www.cs.wisc.edu/~ghost/.
В пакете Ghostscript имеется скрипт ps2pdf, который с легкостью выполнит преобразование из Postscript в PDF. Теперь, когда эта утилита у нас уже есть, мы можем приступить к разворачиванию службы PDF на Samba.
Собираем все вместе
Для начала рассмотрим скелет разделяемого принтера Samba (в файле smb.cnf):
[hpdeskjet]
path = /tmp
printable = yes
writeable = no
create mask = 0700
guest ok = yes
printer name = lp
(Обратите внимание на "немое е" на конце слова writeable
. В конфигуранционном файле оно обязательно, хотя и отсутствует в обычном написании. Тоже самое относится к параметру browseable
ниже.)
Обычно, когда задание ставится в очередь на такой разделяемый принтер, выполняется команда (скажем - lpr), которая переносить задание в подситстему печати Linux. Но мы воспользуемся отличными возможностями настройки Samba для того, чтобы вместо lpr указать альтернативную команду печати. Конкретная переменная конфигурации называется "print command". Указанная в ней команда будет выполнена, а все вхождения символов %f или %s в ней будут заменены именем файла с заданием, которое было послано с клиента Windows. Например, для того, чтобы просто проигнорировать задание, в раздел конфигурации принтера могла бы быть вставлена такая строка:
print command = /bin/rm %f
Тут нужно обратить внимание на следующее: какая бы команда печати не была указана, она должна удалять файлы заданий. Иначе они в конце концов "завалят" весь жесткий диск.
Скрипт печати
Наш скрипт печати будет принимать одни аргумент: имя файла задания, предполагается, что задание поступает в формате Postscript. Это файл будет конвертирован в документ PDF и помещен в доступное из локальной сети место. Клиенты смогут "забирать готовый продукт" с помощью Samba-службы общего доступа к файлам. Например, если в Samba "зашарена" (или "расшарена":) директория "/shr", мы можем "лОжить" законченные PDF-ы в /shr/pdfdropbox/. Выполните mkdir "имя_по_своему_вкусу". И убедитесь, что пользователю, под именем котороо выполняется Samba (в нашем случае пользователю nobody), предоставлены права на запись в эту директорию, или у него не выйдет создавать PDF-файлы. В этой учебной конфигурации нужно сделать следующее:
chown nobody /shr/pdfdropbox
chmod u+rwx /shr/pdfdropbox
Далее приводится полный, но достаточно простой скрипт printpdf, здесь он же в текстовом формате. У нас он лежит в /usr/bin/printpdf (а у нас -- в /usr/local/bin. Прим. пер.:)
#!/bin/sh
# Простой скрипт, преобразующйи файл Postscript в формат PDF
# и помещающий его в разделяемое по Samba место.
#
# Параметры запуска:
# 1-й - Имя файла с заданием на печать
#
# John Bright, 2001, [email protected]
# Мы будем создавать временный файл PDF, назвав его по дате и времени вызова скрипта
# После конвертации переименуем его в файл с названием, но с .pdf в конце имени
# Это делается потому, что при открытии pdf'а, который находится в процессе записи,
# выводится сообщение, что он испорчен, в то время, как он просто еще не готов.
DATE=date +%b%d-%H%M%S
# Директория, в которую помещаются файлы.
# Убедитесь, что она существует и доступна на запись для пользователя,
# от которого выполняется Samba (в нашем примере -- пользователь nobody)
OUTDIR=/shr/pdfdropbox
ps2pdf $1 $OUTDIR/$DATE.temp
mv $OUTDIR/$DATE.temp $OUTDIR/$DATE.pdf
rm $1
Вроде просто? Если все инструменты на месте, то дело и впрямь нехитрое.
Завершение настройки Samba
Теперь, когда мы разобрались со всеми компонентами сервиса PDF на стороне Linux, можно завершить конфигурационный файл Samba. Ниже приводиться пример "рабочего" smb.conf. Требования к безопасности несколько снижены, зато в файле просто разобраться. Его текстовая версия лежит здесь.
[global]
guest account = nobody
invalid users = root
; Немножко укрепим безопасность: будем пускать только пользователей из локальой сети
interfaces = 127.0.0.1 eth0
bind interfaces only = Yes
; Исходим из предположения, что в локальной сети используются IP 192.168.x.x
hosts allow = 192.168.
; Доступ на уровне ресурсов обычно проще настроить, хотя он не менее безопасен
security=share
workgroup=WORKGROUP
; Настройка общих разделяемых ресурсов, которые будут использоваться для "раздачи" PDF'ов
; Пользователи Windows будут его видеть как "shr"
[shr]
path = /shr
browseable = yes
writeable = yes
guest ok = yes
force user = nobody
; Настройка сервиса печати, создающего PDF
[pdf]
path = /tmp
printable = yes
guest ok = yes
print command = /usr/bin/printpdf %s
; Нет необходимости поддерживать вывод списка заданий или их удаление
; поскольку сервис приступает к их обработке немедленно "по прибытии"
; Поэтому оставляем команды lpq (список заданий в очереди) и
; lprm (удаление заданий из очереди) пустыми.
lpq command =
lprm command =
Естественно, после того, как вы приведете файл smb.conf в соответствие со своими желаниями, нужно перезапустить (или запустить:) сервис Samba.
Настройка клиета Windows
Теперь можно пойти дальше и установить разделяемый принтер PDF как сетевой принтер на клиентской машине с Windows. Для этого найдите соответствующую иконку в "Вашем сетевом окружении", щелкниет по ней правой клавишей мыши и выберите "Установить". Во время установки вам будет предложено выбрать драйвер принтера. Выберите какой-нибудь драйвер Postscript-притера, например, HP LaserJet 5P/5MP PostScript.
То, как все это работает, объясняется так: сервис PDF на Linux-машине ожидает данные в формате Postscript. Поскольку наш скрипт printpdf получет задание в том же виде, в каком оно было послано клиентом Windows, то этот клиент должен посылать задание на печать именно в формате Postscript. Как сказано выше, этого можно достичь выбрав во время установки сетевого PDF-принтера на Windows-клиенте драйвер любого Postscript-принтера. Обычно я выбираю какой-нибудь вариант HP Laserjet PS из списка принтеров Windows (например, HP LaserJet 5P/5MP PostScript, как было сказано выше). Конкретный выбор не имеет большого значения т.к. все Postscript-драйверы от Microsoft для генерации кода используют одно и тоже программное ядро.
Как только сетевой принтер PDF установлен на Windows-клиенте, можно просто печатать на него из любой программы, и PDF-документы не заставят себя ждать:)
Спрямляя пути
Если ваша контора заполнена "компьютерно-беспомощными" людьми, то заставлять их самих выбирать и устанавливать нужные драйверы принтеров создаст для вас больше проблем, чем сэкономит усилий. Если вам уже приходилось устанавливать сетевой принтер, расположенный на другой Windows-машине, то вы, должно быть, заметили, что файлы нужного драйвера автоматически копируется по сети к вам на компьютер. Вас при этом даже не спрашивают, какой драйвер устанавливать:). Мы можем сделать тоже самое и с помощью Samba. Во-первых, создайте на Linux-машине разделяемый ресурс "printer$" (без кавычек, конечно). Путь к "шаре" printer$ сделаем /etc/samba/printdrivers/ (директорию придется создать "в ручную"). Во время инсталляции, клиенты будут получать компоненты драйверов из этой разделяемой директории.
Теперь нам надо выяснить, какие файлы драйвера должны быть скопированы в директорию printer$. Также нужно будет предоставить "определение принтера" для Samba, и тогда она сможет сказать клиенту, какой ему нужен драйвер. Оказывается, это можно сделать "в один прием" благодаря утилите make_printerdef. Этой утилите нужен INF-файл Windows, который содержит определение вашего принтера и его полное название, такое как "HP LaserJet 5P/5MP PostScript". Нужно выяснить, в каком INF-файле определен ваш принтер. Например, Laserjet, о котором говориться выше, определен в файле C:\WINDOWS\INF\MSPRINT3.INF. Имейте в виду, что каталог C:\WINDOWS\INF -- "скрытый". Скопируйте нужный файл на вашу Linux-машину и, с помощью make_printerdef, создайте локальный файл определения принтера, который и будет читать Samba. Например так:
make_printerdef MSPRINT3.INF "HP LaserJet 5P/5MP PostScript" >> /etc/samba/printers.def
Мы перенаправили вывод команды в файл printers.def для задания конфигурации принтера. Помимо этого, make_printerdef выводит некоторые объяснения в стандартный поток сообщения об ошибках, где их и можно увидеть. Там говорится, какие файлы понадобятся. Их можно найти в C:\WINDOWS\SYSTEM или в C:\WINDOWS и скопировать в разделяемую папку printer$ на Linux машине (в нашем примере это /etc/samba/printerdrivers/). Делать созданный (или дописанный) файл printers.def доступным для машин Windows не нужно -- он читается только Samba. Теперь нам нужно сообщить Samba про printers.def и файлы драйверов. Это достигается установкой параметра "printer driver file" в глобальном разделе smb.conf и параметрами "printer driver" и "printer driver location" в разделах каждого принтера. Ниже приводится новая редакция smb.conf, в которой дается пример использования этих параметров и разделяемого ресурса printer$. Текстовую версию можно скачать отсюда.
[global]
guest account = nobody
invalid users = root
; Немножко укрепим безопасность: будем пускать только пользователей из локальой сети
interfaces = 127.0.0.1 eth0
bind interfaces only = Yes
; Исходим из предположения, что в локальной сети используются IP 192.168.x.x
hosts allow = 192.168.
; Доступ на уровне ресурсов обычно проще настроить, хотя он не менее безопасен
security=share
workgroup=WORKGROUP
printer driver file = /etc/samba/printers.def
; Настройка общих разделяемых ресурсов,
; которые будут использоваться для "раздачи" PDF'ов
; Пользователи Windows будут его видеть этот ресурс, как "shr"
[shr]
path = /shr
browseable = yes
writeable = yes
guest ok = yes
force user = nobody
; Настройка сервиса печати, создающего PDF
[pdf]
path = /tmp
printable = yes
guest ok = yes
print command = /usr/bin/printpdf %s
; Нет необходимости поддерживать вывод списка заданий или их удаление
; поскольку сервис приступает к их обработке немедленно "по прибытии"
; Поэтому оставляем команды lpq (список заданий в очереди) и
; lprm (удаление заданий из очереди) пустыми.
lpq command =
lprm command =
; Файл с определениями принтеров уже указан выше
; Здесь указывается то, какое определение надо использовать
; для данного конкретного принтера.
printer driver = HP LaserJet 5P/5MP PostScript
printer driver location = \\%h\printer$
; Разделяемая папка, из которой клиенты будут брать драйверы принтеров.
[printer$]
path = /etc/samba/printdrivers
guest ok = yes
read only = yes
Настройка клиентов с Linux
Для настройки предоставления услуг по созданию документов PDF Windows-клиентам, этот раздел не нужен. В нем описывается, как воспользоватся этой службой на машине с Linux. Для Linux-клиентов эта служба не очень-то и полезна, поскольку на них самих можно легко установить все нужные инструменты, но централизованная служба генерации PDF может все же оказаться полезной. (Отвлечемся немного: существует Ghostscript и для Windows, но большинство пользователей скорее всего сочтут, что им слишком неудобно пользоваться в сравнении с описанной технологии принт-сервера). Кроме того, техника, используемая для создания службы PDF, может быть использована для печати через любой разделяемый принт-сервер Samba или Windows, так что это полезная информация.
Существует множестово способов печати из Linux на разделяемый принтер Windows. Лучшим, возможно, является указание скрипта smbprint (который использует smbclient) в качестве фильтра в файле /etc/printcap. В этой методике разделяемый принтер Windows может быть использован стандартной командой lpr, к которой в Linux привыкли и пользователи, и программы. Убедитесь, что на вашем компьютере установлены и smbprint, и smbclient. В Debian smbclient можно найти в пакете "smbclient", а в Red Hat нужен пакет "samba-client". Скрипт smbprint включен в пакет Red Hat, а пользователи Debian найдут его в пакетах "samba-doc" и в разных версиях пакетов "printfilters-ppd" и "lprngtool". Повсюду можно обнаружить так много разных версий, что я счел за благо включить одну в эту статью. Ее можно скачать отсюда. В любом случае, я исхожу из предположения, что у вас есть работоспособный smbprint в /usr/bin/smbprint и что его разрешено выполнять (chmod +x /usr/bin/smbprint). Вот этот скрипт:
#!/bin/sh
# Это входной фильтр для печати UNIX через printcap.
# Он использует программу smbclient для печати файла
# на указанном samba-сервере или через основанную на samba службу.
# Например, в printcap может иметься такая запись
#
# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
#
# которая создает UNIX принтер "smb", который будет печатать с помощью
# этого скрипта. Вам потребуется создать директорию /usr/spool/smb
# и установить на нее соответствующие права доступа.
# Укажите настройки, соответствующие требуемому серверу или сетевой службе
# В этом примере используется компьютер с Windows for Workgroups "lapland",
# на котором имеется принтер "printer" без пароля.
#
# Скрипт был дополнительно изменен [email protected] (Michael Hamilton)
# таким образом, что сервер, служба или пароль могут быть получены
# из файла /usr/var/spool/lpd/PRINTNAME/.config.
#
# Для того, чтобы это работало, запись в /etc/printcap должна включать
# учетный файл [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:
#
# Файл /usr/var/spool/lpd/PRINTNAME/.config должен содержать следующую информацию:
# share=PC_SERVER
# user="user"
# password="password"
#
# Пожалуйста, не изменяйте порядок параметров.
# Пример:
# share=\\server\deskjet
# user="fred"
# password=""
#
# Последний паарметр фильтра -- имя учетного файла [accounting file].
# Выделяем имя директории из имени файла.
# Добавляем /.config для получения имени конфигурационного файла.
#
eval acct_file=\$$#
spool_dir=dirname $acct_file
config_file=$spool_dir/.config
# Из файла конфигурации читаются следующие параметры:
# share
# hostip
# user
# password
eval cat $config_file
share=echo $share | sed "s/[\]/\//g"
if [ "$user" != "" ]; then
usercmd="-U"
else
usercmd=""
fi
if [ "$workgroup" != "" ]; then
workgroupcmd="-W"
else
workgroupcmd=""
fi
if [ "$translate" = "yes" ]; then
command="translate ; print -"
else
command="print -"
fi
#echo $share $password $translate $x_command > /tmp/smbprint.log
cat | /usr/bin/smbclient "$share" "$password" -E ${hostip:+-I} \
$hostip -N -P $usercmd "$user" $workgroupcmd "$workgroup" \
-c "$command" 2>/dev/null
Следующий шаг добавляет новую запись в /etc/printcap и указывает скрипт smbprint в качестве фильтра. Далее следует пример записи printcap (или файл полностью), который можно получить и в текстовом формате:
# Сервис PDF
lp|pdf|PDF Printer:\
:lp=/dev/null:sh:\
:sd=/var/spool/lpd/pdf:\
:af=/var/spool/lpd/pdf/acct:\
:mx#0:sh:\
:if=/usr/bin/smbprint:
Потребуется создать директорию спула /var/spool/lpd/pdf/ (или, если у вас установлен LPRng, выполните команду checkpc -f). Убедитесь, что в записи printcap есть указание на учетный файл [accounting file] и что сам учетный файл находится в одной директории с файлом .config, поскольку smbprint ищет его именно там. Кроме того, обычно принято указывать системный принтер по умолчанию (с именем "lp"), как это описано выше. Если у вас в системе уже есть файл /etc/printcap и вы хотите сохранить существующий принтер по умолчанию, надо удалить "lp|" из начала приведенной записи. Далее, нужно создать конфигурационный файл .config. В примере он создается, как /var/spool/lpd/pdf/.config. Этот файл указывает, на какой сервер должно посылаться задание. Вот пример:
share=//yourserver/pdf
user=""
password=""
Замените yourserver на имя компьютера, предоставляющего сервис PDF. При возникновении проблем убедитесь, что smpprint имеет права на чтения файла .config, иначе придется какое-то время "чесать репу". Наиболее надожным способом, по крайней мере по началу, будет предоставление прав на чтение всем, например, так: chmod a+r /var/spool/lpd/pdf/.config
Наконец, в Linux печать через службу PDF выполняется командой:
lpr -Ppdf file_to_print.ps
через Postscript-файл. То же самое можно делать и из большинства приложений. Например, указание в качестве программы печати "lpr -Ppdf" в настройках Netscape позволит вам создавать документ PDF из веб-страниц.
Просмотр документов PDF
Последнее, о чем нужно рассказать -- как просматривать PDF-файлы. Все знают, что для Windows стандартом является Adobe Acrobat Reader, но в Linux существует намного больше возможностей. К сожалению, ни одна из имеющихся не кажется столь же надежной, как Reader для Windows, но, тем не менее, ими можно пользоваться. Таковы основные средства для чтения PDF:
- acroread - Adobe сделал милую версию Acrobat Reader для Linux
- gv - Программа просмотра PDF, использующая ghostscript
- gnome-gv - Тоже использует ghostscript, но с более приятным пользовательским интерфейсом
- xpdf - Симпатичный и компактный "вьюер" PDF, но интерфейс, что называется, "без наворотов"
По моему мнению, у gnome-gv самый удобный и красивый интерфейс. Он основан на GTK+, так что такие "приятности", как колесико мыши, работают без дополнительных усилий. К несчастью, он не может читать некоторые PDF-файлы и показывает устрашающие сообщения об ошибках ghostscript. По моему мнению, acroread особенно хорош при интерпретации документов. В прошлом я сталкивался с его "падучестью", но я думаю, с той поры он улучшился. Я редко пользую gv, но не удивлюсь, если у него обнаружаться те же проблемы, что и gnome-gv, поскольку обе программы основаны на ghostscript'е. Наконец, xpdf очень стабилен. Я не припоминаю, чтобы он когда-либо "падал", и обычно он беспроблем открывает документы. А вот качество отображение, увы, не всегда на высоте. Набор функций у него не полон, но эту программу просмотра хорошо иметь под рукой. Все это звучит немного пугающе, но "на круг по валу" с просмотром PDF в Linux проблем нет.
Так что учдачи и не скучайте!
Джон Брайт [John Bright]
Джон является совладельцем Winford Engineering и безупречно справляетя и со своей программистской работой, и с обязанностями администратора Linux:) Дополнительно он администрирует несколько компьютеров с Linux/UNIX в местном университете и всегда находит несколько связанных с Linux проектов для того, чтобы ему было чем в достаточной степени занять себя.
Copyright (C) 2001, John Bright.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 72 of Linux Gazette, November 2001
Комментарий переводчика
При попытке применить изложенные в статье идеи, русскоязычного:) пользователя могут подстерегать трудности, связанные с разными кириллическими страницами в Windows и Linux и с проблемами кириллических PDF документов в целом.
Я поинтересовался у активно использующих Samb'у знакомых, будут ли (по их мнению) предлагаемые решения работать с в сети с русской версией Windows. Ответ был положительный: да, будут. Это приятно.
Далее, следует подчеркнуть, что автоматическая установка драйвера сетевого принтера будет работать только с клиентами Window 9x, а с клиентами Windows NT 4 и Windows 2000 -- нет:( По крайней мере, никому из моих знакомых этого наладить не удалось. Я написал автору статьи письмо с этим вопросом, но ответа пока не получил...
Далее. PDF документы с кириллицей имеют свои проблемы. Во-первых, для создания "русских" PDF, на Linux-сервере должен быть установлен "русский" же Ghostscript (т.е. с кириллическими шрифтами и правильно настроенный для их использования). При использовании отечественных дистрибутивов (ALT Linux, Linux Mandrake RE, ASP Linux и т.д.) это так и есть. Я пробовал создавать PDF из созданного на Windows PS-файла на моей машине с Russian Mandrake Spring 2001 (Ghostscript 5.5) -- все получилось прекрасно: файл "смотрелся" и с помощью gv на Linux, и с в Acrobat Reader'е под Windows. Но... При создании PDF с помощью ghostscript версии ниже 7.0 русские шрифты встраиваются в виде растровых шрифтов Type 3. В результате получаемый файл имеет большой размер (тем больший, чем больше разрешение целевого устройства), а при просмотре документа в Acrobat'е он выглядит "не очень". GSView -- и для Windows, и для Linux -- показывает его вполне приемлимо т.к., в отличии от Acrobat'а, умеет сглаживать растровые шрифты. Не надо отчаиваться. При печати документ будет выглядеть нормально. GS 7 и выше умеет вставлять "векторную" кириллицу, но эта версия еще не "свободна" и его надо устанавливать самостоятельно. Впрочем, это вполне посильная задача:)
И последнее. У xpdf, который так "хвалит" автор статьи, могут быть проблемы при просмотре кириллических PDF-ок. Растровые шрифты он не показывает совсем, а в векторных могут выпадать отдельные буквы:( Так что лучше пользуйтесь gv. Это точно относится к той версии xpdf, которая стоит у меня на машине. Более новая, возможно, уже свободна от этого недостатка, но мне про нее ничего не известно:)