April 29, 2004

Building a Linux PDF Print Server for Legacy Line Printer Applications

Hey! Enki has moved his blog to Armyofevilrobots.com. Check it out after you are done here. This page is going nowhere though...

One of the biggest pains in the rear that I have to deal with on a day to day basis is the ancient, obsolete accounting system that we use here. This is a telnet based (upgraded to telnet from serial WYSE terminals) accounting system. Everything happens with keyboard interaction in a 80x24 window. The database is ancient, the interface is ancient, the system is written in 4GL, adding yet another useless skill to my roster.

The worst part is the reporting. Everything is set up to get spit out of an old fashioned dot-matrix line printer. This had to change. I hacked together a way to build a Redhat server that can receive standard LPD clients, and spit out standards compliant PDF files. Better yet, I have a method of printing multi-part carbon forms out as PDF files, or even directly to a Samba share.

This article is the story of that server.

In order to build this server, you will need a Redhat box, with the following installed:

Note: Most of these are available as RPM's, so install apt-rpm and do some apt-get loving.


Once the dependencies are resolved, you can start setting up the virtual printers. I wanted to have the ability for people in the building to print PDF files even if they didn't have Acrobat installed, so I started by generating a virtual Samba printer, named "pdf". This printer automagically generates a black and white PDF file, which is saved in a public Samba share. Here is the configuration for the Samba printer, inside of /etc/samba/smb.conf:

[pdf]
path = /tmp
printable = yes
guest ok = yes
print command = /usr/bin/printpdf %s
; There is no need to support listing or removing print jobs,
; since the server begins to process them as soon as they arrive.
; So, we set the lpq (list queued jobs) and lprm (remove jobs in queue)
; commands to be empty.
lpq command =
lprm command =
So now we have a Samba printer that saves the spooled print job to a file, and then calls the printpdf script on it. Here is the printpdf script (Note: I appear to have either duplicated or modified a script by John Bright)
:
DATE=`date +%b%d-%H%M%S`

# Directory in which to place the output
# Be sure this directory exists and is writable by the user that Samba
# is running as (for example, the nobody user)
OUTDIR=/opt/public/PDFPRINTER/

ps2pdf $1 $OUTDIR/$DATE.temp
mv $OUTDIR/$DATE.temp $OUTDIR/$DATE.pdf
rm $1

As you can see, the script prints to the OUTDIR directory, which we have configured separately in Samba as a share. The script is pretty simple. Input jobs have to be configured as postscript.

Hmmm, how do I print to postscript files for free in Windows? Pretty easily it turns out. Adobe makes a great generic Postscript driver for Windows, which is available as a free download. I get a kick out of using Adobe's free postscript driver to avoid paying for a full version of Acrobat, but you should check out Acrobat if you want to sign documents, or do more complicated work.



Next up, the managers liked the ability to generate PDF files, but the first question out of their mouths was "Does this work from the accounting system too?"

grrrrr.

So it turns out that it does (with a little work). The accounting box runs on the OS from the little satan, which can print to SMB on newer versions (using something called VisionFS), but only has lpr printing on the version we use. So I set up a print server on the Linux box using printconf.

I SSHed into the server (you do use SSH don't you)? and used printconf-tui to add a new print spool, named pdf-txt. This was a raw print spool, since I had some problems with controlling the formatting when I used the automatic text to postscript features built into magic-filter. You can set a raw print spool up to print to a Samba destination (a printer which does not yet exist, named //yourservername/txtpdf/).
***NEW*** Here is a screenshot:

 +-------------------------¦ Red Hat Printer Config +-------------------------+
 ¦                                                                            ¦
 ¦    Queue        Aliases          Type      Details                         ¦
 ¦    pd+------------------------¦ Edit Queue +------------------------+    ¦ ¦
 ¦ +  pd¦                                                              ¦    ¦ ¦
 ¦    po¦                     Name: pdfsamba                           ¦    ¦ ¦
 ¦      ¦                  Aliases: pdf-txt                            ¦    # ¦
 ¦      ¦                     Type: Windows Print Queue                ¦    ¦ ¦
 ¦      ¦                    Share: //[server]/txtpdf                  ¦    ¦ ¦
 ¦      ¦                       IP: [serveriphere]                     ¦    ¦ ¦
 ¦      ¦                Workgroup: [yourworkgrouphere]                ¦    ¦ ¦
 ¦      ¦                     User: [yourusernamehere]                 ¦    ¦ ¦
 ¦      ¦                   Driver: Raw Print Queue                    ¦    ¦ ¦
 ¦      ¦  +-------+   +------+   +--------+   +------+   +--------+   ¦    ¦ ¦
 ¦      ¦  ¦ Names ¦   ¦ Type ¦   ¦ Driver ¦   ¦ Done ¦   ¦ Cancel ¦   ¦    ¦ ¦
 ¦    +-¦  +-------+   +------+   +--------+   +------+   +--------+   ¦      ¦
 ¦    ¦ ¦                                                              ¦      ¦
 ¦    +-¦                                                              ¦      ¦
 ¦      +--------------------------------------------------------------+      ¦
 ¦                                                                            ¦
 +----------------------------------------------------------------------------+

Next I set up yet another virtual Samba printer, as below:

[txtpdf]
path = /tmp
printable = yes
guest ok = yes
print command = /usr/bin/printtxtpdf %s
lpq command =
lprm command =
This time we are calling the script printtxtpdf, which is shown below:

DATE=`date +%b%d-%H%M%S`
OUTDIR=/opt/public/PDFPRINTER/
enscript --margins=6:6:16:16 -F Courier8 -f Courier-Bold@7.4/12 -p $OUTDIR/$DATE.temp.ps $1
ps2pdf $OUTDIR/$DATE.temp.ps $OUTDIR/$DATE.temp
rm $OUTDIR/$DATE.temp.ps
mv $OUTDIR/$DATE.temp $OUTDIR/$DATE.pdf
rm $1
This script calls enscript to generate very controlled formatting of the text, including a monospace font, and the same exact positioning as the dot-matrix printer that it is replacing.


So now all was good in Enkiland, except that the managers asked "Can you make it print the multipart forms too"?

grrrrr...

Yep. I can.

First I scanned the original form as a PNG file, and placed it in my Home dir on the Linux box. Next, I made a new script, shown below that did the following steps:

  • Make a PS file from the pages of text
  • Break that PS file into multiple single page PS files using ghostscript
  • Merge each page with the PNG template form using ImageMagick
  • Merge the separate pages back into a single PS file using ghostscript
  • Generate a PDF file from the PS.
  • Copy it to the destination directory
  • Optional (not shown here): Make multiple copies with different templates for the different recipients.
Whew!

First of all, the script that makes the forms merge with the text print job:


DATE=`date +%b%d-%H%M%S`
# Directory in which to place the output
# Be sure this directory exists and is writable by the user that Samba
# is running as (for example, the nobody user)
OUTDIR=/opt/public/PDFPRINTER/
#First we make the PS of the text file.
enscript -B --margins=6:6:10:16 -F Courier8 -f Courier-Bold@8.2/11 -p /tmp/$DATE.temp.ps $1
#Get the page count for generating the PDF...
PAGECOUNT=`grep -c %%Page: /tmp/$DATE.temp.ps`

for PAGE in `seq 1 $PAGECOUNT`;
do
echo "Printing page $PAGE to ps"
#Get the correct page...
psselect -q $PAGE /tmp/$DATE.temp.ps /tmp/$DATE.$PAGE.ps
#THen we make a PNG (lame).
gs -sDEVICE=pngmono -q -dBATCH -dNOPAUSE -r300 -sOutputFile=/tmp/$DATE.png /tmp/$DATE.$PAGE.ps
#Now we overlay the other crap.
composite -page "letter+0+0!" -dither -quality 0 /home/enki/po-bg.png /tmp/$DATE.png /tmp/$DATE.$PAGE.final.ps
PAGELIST="$PAGELIST /tmp/$DATE.$PAGE.final.ps"
done
#Print the result...
gs -sDEVICE=pdfwrite -q -dBATCH -dNOPAUSE -r300 -sOutputFile=/tmp/$DATE.final.ps $PAGELIST
ps2pdf /tmp/$DATE.final.ps /tmp/$DATE.temp
mv /tmp/$DATE.temp $OUTDIR/$DATE.pdf
rm /tmp/$DATE.* -f
rm $1


Whew! Finally, just do the same thing again with the smb.conf file, only calling the appropriate script, as below:

[po2pdf]
path = /tmp
printable = yes
guest ok = yes
valid users = sharlene,enki,cathy.tamara,rmarander,leigh
print command = /usr/bin/printpopdf %s

; There is no need to support listing or removing print jobs,
; since the server begins to process them as soon as they arrive.
; So, we set the lpq (list queued jobs) and lprm (remove jobs in queue)
; commands to be empty.
lpq command =
lprm command =

Still waiting for the next response from management.



PostScript: Possible Gotchas....
  • I fought for a while with ImageMagick and Ghostscript. Make sure that you are using a fairly new version. The ones with Redhat 8.0 would occasionally munch a print job using these scripts.
  • Make sure the source data is raw text!!!!! I can't stress this enough. Print codes or PS data, or whatever could cause problems with enscript. Prefixing old printer command codes is pretty common in legacy console applications (since they usually had to build their own printer drivers). Fortunately you could pipe the whole print job through an awk or sed script to remove the offending formatting, but unfortunately, you would have to write it yourself

Posted by Enki at April 29, 2004 01:16 PM | TrackBack
Comments

Your ultimate video on demand solutions

Posted by: at September 13, 2004 07:07 PM

Online Cialis information site.

Posted by: Cialis at October 9, 2004 02:12 AM

Levaquin online information.

Posted by: Levaquin at October 13, 2004 01:37 AM

Seasonale online site.

Posted by: Seasonale at October 14, 2004 12:15 PM

Generic Fioricet online site.

Posted by: cheap Generic Fioricet at October 16, 2004 02:02 AM

Online Fioricet information site.

Posted by: Fioricet at October 17, 2004 12:37 PM

Remeron online site.

Posted by: Remeron at October 22, 2004 08:12 AM

Effexor online information site.

Posted by: Effexor at October 23, 2004 12:02 PM

View Celexa online information.

Posted by: Celexa at October 25, 2004 02:48 AM

Hello.

I've been looking around and came across your site by accident. The information you link to from your home page is quite informative so thanks for taking the time to post it.

Joe
discontinue use of trimspa if adverse side effects

Posted by: discontinue use of trimspa if adverse side effects at October 28, 2004 05:20 PM

Hello there,

Iwas browsing the web and found this blog. Some interesting quotes. Keep them coming!

Alice
propolene

Posted by: propolene at October 29, 2004 11:20 AM

Elidel info site.

Posted by: Cheap Elidel at November 3, 2004 06:54 AM

Found your site through blogspot and wanted to say hi

Posted by: Johnny at November 4, 2004 12:31 AM

Hi - I was looking for some information on weight loss. Do you know a good site to visit?

Thanks for your help
Martin Brown

Posted by: free zone diet at November 5, 2004 01:13 PM

hi

Posted by: adult dvd movies at November 6, 2004 03:07 PM
Post a comment









Remember personal info?