Easy PDF Creation on a Samba Server

An increasingly common requirement is to convert the printed output of applications into Adobe's Portable Document Format. Many Linux applications, like OpenOffice.org, can directly generate PDF's; for others, it is possible to work around the lack of direct support for PDF by using tools like ps2pdf at the command line. But what about, say, the commercial office with a mixture of Windows workstations and Linux on the server?

An automated solution that can be used by non-technical users is to set up, on a Samba server, a print queue that uses a bit of scripting to convert a print job to a PDF and then email it back as an attachment. Here's one way to do it.

First, you'll need to add the printer to the Samba configuration. Edit /etc/samba/smb.conf, and add a stanza at the bottom that looks like this:

Listing 1 - A smb.conf stanza which creates a PDF generation print queue

[pdf]
       comment = Print to create PDF
       printing = LPRNG
       path = /var/spool/samba
       printable = yes
# Parameters below: spool file name, job name, user name, user home dir
       print command = /usr/local/bin/printpdf %s %u %H "%J"

Here's what this does, line by line: the first line is the stanza heading, and is the name of the printer as it will appear to Windows clients. The second line is a comment which will appear when you mouse over the printer in "My Network Places".

The "printing = LPRNG" setting is important. Most modern Linux distributions use CUPS - the Common Unix Printing System - to spool print jobs. However, the "print command" setting is not supported for CUPS print queues, yet we need it for this application. To get around this, we specify the printer subsystem as being LPRng - even though it's really not. This doesn't matter, since we won't be invoking any of the LPRng programs.

The "path =" parameter specifies the location of the print spool directory, while the "printable = yes" setting tells Samba that this is a printer, so that the clients can create and write to spool files there. Finally, the last line sets a command which will be invoked after each print job spool file. Samba is able to substitute some parameters which it knows into the command line (see Table 1). In this case, the parameters being passed are the spool file name, the user name (the user should exist and have a home directory on this server), the user's home directory location, and the job name, which was set by the client program.

Table 1 - Useful Samba variables which can be passed to a print command
ParameterMeaning
%uThe username for this service
%HThe home directory for the user
%s, %fThe pathname of the spool file
%pThe printer name
%TThe current date and time
%JThe print job name, as sent by the client - this is usually the document name or title
%cThe number of pages (not always known)
%zThe size of the print job
Save your modified smb.conf file, and test it by running the testparm command - you should see it processing the various sections of your smb.conf file, including the "[pdf]" section, then when you press Enter, it should output the service definitions, finishing with the "[pdf]" section. If there are any error messages or warnings, for example if you missed the "printing = lprng" line, go back and fix the file.

The PDF Creation Script

Now we can turn our attention to the script which will do the job of turning Postscript into an Adobe Acrobat file. The bulk of the work is done by the ps2pdf program, which is part of the Ghostscript package.

There are two approaches to how this script might work. The simplest approach is to have the script simply dump the generated file into the user's home directory, or into a directory below that. Here's a script that will do just that:

Listing 2 - A shell script to drop generated PDF's into a user's home directory

#!/bin/sh
# Shell script to print to PDF file
# Parameters $1 = spool file (smbprn . . .)
# $2 = user name
# $3 = user home directory
# $4 = print job name

OUTDIR=$3/pdfs
echo Converting $1 to "$4" for user $2 in $3 >> pdfprint.log
ps2pdf $1 "$OUTDIR/$4.pdf"
rm $1

This script is very simple. It just sets up the output directory to be a pdfs directory under the user's home directory, then runs ps2pdf, writing the output directly into that location. We use the job name as the output file name, as this is most likely to make sense to the user. One slight drawback is that Samba seems to limit the job name to just 31 characters, so you should take care with similar long file names. Finally, the script deletes the spool file.

A more sophisticated approach is to have the script email the document back to the user. My first attempt at this was an increasingly complex Perl program which made use of the MIME-tools Perl module to create an email with the PDF file attached, but then a colleague pointed out that the mutt email client can send email attachments from the command line. I slapped my forehead and tossed the nightmare Perl code in the wastebasket. Then I created the following small shell script:

Listing 3 - A shell script which emails the generated PDF file back to the user

#!/bin/sh
# Shell script to print to PDF file
# Parameters $1 = spool file (smbprn . . .)
# $2 = user name
# $3 = user home directory
# $4 = print job name
ps2pdf $1 "$4.pdf"
echo Mailing $4.pdf to $2 >> pdfprint.log
mutt -s "$4" -a "$4.pdf" $2
rm $1 "$4.pdf"

This script only uses the first, second and fourth parameters - it doesn't care about the user's home directory (but I've passed it in as a parameter for easy compatibility). This version uses the job name as the basis of the generated file, and also uses it as the subject line of the email. The last line simply cleans up the temporary files.

If this server is the office mail server, then no further configuration is required. However, if it isn't, you will need to redirect the email to the user's proper email address. For example, my office Samba server needs to forward emails to me at a completely different server; the easiest way to set this up is to create a file called .forward in each user's home directory, and put the correct email address in there.

Save either of the scripts above as /usr/local/bin/printpdf, and make it executable with the command chmod +x /usr/local/bin/printpdf.

Configuring Windows Clients

You should use the Windows "Add Printer" Wizard to add the printer on Windows clients that will use it. Obviously, this will be a network printer, and you should be able to browse to it by finding the server and double-clicking on it to list the print queues. You probably don't want to make it the default printer, obviously.

For a suitable driver, virtually any Postscript printer driver will do. If you want to create monochrome PDF's, then you could use an Apple Laserwriter printer driver - I use an IBM 4029 PS 39 driver, because I used to have one of those printers and the driver was already installed on my system. For colour PDF's, I use the "IBM 4079 Color Jetprinter PS" driver, which seems to work quite well.

Once the printer has been created, you can customise settings such as the paper size.

If you are using the first version of the script, create a folder called "pdfs" in the user's home directory.

Testing

Once you have a client set up, you should open a bash prompt on your Samba server (ssh to it or use PuTTY) and then su to root. Give the command tail -f /var/spool/samba/pdfprint.log and then print a document to the pdf printer. The echo command in each version of the script will output a message - something like

Converting smbprn.00000093.lrjlz3 to Easy PDF Creation on a Samba Se for user les in /home/les

or

Mailing MYOB Print Job.pdf to les

Now, depending on which script you are using, check for a new PDF file having been created in the user's pdfs folder, or a new email arriving. If there's a problem, check the messages from the script.

Once everything is working fine, you can stop monitoring the log, and then comment out the echo command in the script.

To summarise, this is an extremely useful little hack - I use it a lot in my office, to generate PDF files of course notes, invoices to be emailed. Perhaps more importantly, it's also a very nice illustration of how standard Linux commands like ps2pdf and mutt, along with a little scripting to glue them together, can produce an application that is difficult or expensive to reproduce on Windows servers.
Page last updated: 04/Jul/2006 Back to Home Copyright © 1987-2010 Les Bell and Associates Pty Ltd. All rights reserved. webmaster@lesbell.com.au

...........................