PDF-Сервер на основе Samba
Создание службы генерации документов в формате PDF на основе Свободно Распространяемых Программ
Формат PDF дает великолепную возможность пересылать документы через Интернет. Применений может быть много, например, рассылка котировок и счетов деловым партнерам. Причин, по которым PDF столь популярен, много, две главные: он в точности сохраняет внешний вид печатного документа и его можно просмотреть практически на любой платформе. Для многих пользователей, приверженных "парадигме" Windows, создание документов в PDF означает необходимость поделиться драгоценной наличностью с ребятами из Adobe. Эта статья, однако, объяснит, как с помощью Linux, Samba и Ghostscript создать сетевую службу по генерации документов в формате PDF сразу и для пользователей Windows, и для пользователей Linux. Все необходимые компоненты, естественно, можно получить бесплатно.
Начнем с общей схемы. С помощью Samba мы создадим "псевдо-принтер" (клиенты будут видеть его, как обычный сетевой принтер), который в свою очередь, будет получать вывод от любого Postscript-принтера и на его основе с помощью Ghostscript создавать документы PDF. Затем мы сконфигурируем машины Windows таким образом, чтобы они использовали этот созданный нами разделяемый "псевдо-принтер" и посылали на него задания в формате Postscript.
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 -- это еще одна превосходная программа для 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
Вроде просто? Если все инструменты на месте, то дело и впрямь нехитрое.
Теперь, когда мы разобрались со всеми компонентами сервиса 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.
Теперь можно пойти дальше и установить разделяемый принтер 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
Для настройки предоставления услуг по созданию документов 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-файлы. Все знают, что для Windows стандартом является Adobe Acrobat Reader, но в Linux существует намного больше возможностей. К сожалению, ни одна из имеющихся не кажется столь же надежной, как Reader для Windows, но, тем не менее, ими можно пользоваться. Таковы основные средства для чтения PDF:
По моему мнению, у gnome-gv самый удобный и красивый интерфейс. Он основан на GTK+, так что такие "приятности", как колесико мыши, работают без дополнительных усилий. К несчастью, он не может читать некоторые PDF-файлы и показывает устрашающие сообщения об ошибках ghostscript. По моему мнению, acroread особенно хорош при интерпретации документов. В прошлом я сталкивался с его "падучестью", но я думаю, с той поры он улучшился. Я редко пользую gv, но не удивлюсь, если у него обнаружаться те же проблемы, что и gnome-gv, поскольку обе программы основаны на ghostscript'е. Наконец, xpdf очень стабилен. Я не припоминаю, чтобы он когда-либо "падал", и обычно он беспроблем открывает документы. А вот качество отображение, увы, не всегда на высоте. Набор функций у него не полон, но эту программу просмотра хорошо иметь под рукой. Все это звучит немного пугающе, но "на круг по валу" с просмотром PDF в Linux проблем нет.
Так что учдачи и не скучайте!
Джон является совладельцем Winford Engineering и безупречно справляетя и со своей программистской работой, и с обязанностями администратора Linux:) Дополнительно он администрирует несколько компьютеров с Linux/UNIX в местном университете и всегда находит несколько связанных с Linux проектов для того, чтобы ему было чем в достаточной степени занять себя.
Комментарий переводчика
При попытке применить изложенные в статье идеи, русскоязычного:) пользователя могут подстерегать трудности, связанные с разными кириллическими страницами в 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, которая стоит у меня на машине. Более новая, возможно, уже свободна от этого недостатка, но мне про нее ничего не известно:)
Сергей Скороходов [email protected]