Kwan L. Lowe
Date: 15 November 2002
The current version of this document is available at the author's website at:
http://www.digitalhermit.com/linux/printing/index.html
In the simplest case with a directly connected ASCII capable line printer, you can merely cat text files to the appropriate device and watch it print. 1
For example:
[klowe@omega] cat outfile.txt > /dev/lp0
This works fine if you're printing pure text to a locally attached device that supports it. Modern printers do a lot more, however, and to exploit their features such as graphics, Postscript, HP PCL (Printer Control Language) we need to filter the input to the printer. Of course, not all printers are Postscript or PCL compatible so the print system serves the purpose of translating the input into a format that is understood by the printer. This allows applications to be relatively ignorant of the capabilities and driver requirements of the printer, but still take full advantage of them. On another level, the printing system allows a client to submit jobs to printers across a network or even across the Internet.
The first step in the chain is the submitting of the file to the print queue via the lpr utility (or whatever the print front-end is for the printing system). Using a utility known as a magic filter 2, lpr determines the input file type and prepares the document for sending to the print device. This requires some knowledge of both the input format and the printer capabilities. For example, if a user sends a pure ASCII text document for printing to a remote Postscript printer, the print system will first convert the text to Postscript using Ghostscript 3then send it across the network to the remote printer. Once the file is in a format compatible with the print device, it is placed in a queue to await its turn.
BSD is considered by some to be more network friendly and better able to scale to large workgroups. BSD systems use lpr to submit jobs to the queue. lpq to show the contents of the queue, and lprm to remove jobs from the queue. SysV UNIX uses lp to submit, lpstat to show queue contents, and cancel to remove jobs.
In general, Linux has tended towards the BSD print system in earlier distributions. In more recent offerings from RedHat, SuSe, and Mandrake the print systems install compatibility layers that mimic both BSD and SysV commands. The example in the previous section used commands from the BSD system though the print system is actually LPRng, which we'll discuss next.
For an example of LPR/LP administration We'll send a file to be printed to a dummy printer and show what happens to the file as it passes through the system. The first thing we'll do is to create a dummy printer using the old-fashioned tool of a text editor. This dummy printer will do nothing to the input file except echo it verbatim to a temporary file.
1 dummy:\
2 :sd=/var/spool/lpd/dummy:\
3 :sh:\
4 :lp=|/usr/share/printconf/util/nofilter:
We'll use this opportunity to explain some basic options of the printcap file. dummy of course refers to the queue name. sd specifies the spool directory where jobs are held as they await printing. sh instructs the print system to suppress headers and banner pages. lp specifies the device name or file to which the output is sent. For a full explanation of all the printcap options, please refer to the printcap manual pages.
#!/bin/sh exec 1>"/tmp/outfile" /bin/cat
Once the dummy filter is created, we restart the lpd server. For example:
[root@omega]# /sbin/service lpd restart Stopping lpd: [ OK ] Starting lpd: [ OK ]
[root@omega]# fortune | lpr -P dummy
If everything worked correctly we should be able to look in /tmp/outfile for our text. Sure enough, a peek inside of /tmp/outfile shows the output from our fortune program:
[root@omega] cat /tmp/outfile
The camel died quite suddenly on the second day, and Selena
fretted sullenly and, buffing her already impeccable nails --
not for the first time since the journey begain -- pondered
snidely if this would dissolve into a vignette of minor
inconveniences like all the other holidays spent with Basil.
-- Winning sentence, 1983 Bulwer-Lytton bad fiction contest.
One is not limited to pure text printing, of course. Part of the print system is a series of filters that not only do the work of converting from one format to another, but also change the appearance of documents. There are a host of other input filters availabe. Some do nothing more than strip carriage returns and line feeds from the input text. Others will detect C source code and apply line-numbering and syntax highlighting. There are even filters to automatically arrange pages for making folded pamphets and to print multiple pages per sheet.
Though this was a trivial example, it does serve to show how the print system filters input before sending it to the print device. In a normal print queue, the print system will use a magic filter to first determine the input type. Without the magic filter, sending a Postscript file to a Postscript printer may result in the raw source code being printed. Unless one happens to be troubleshooting Postscript itself, this result is unlikely to be desirable.
The LPRng print spooler is an enhanced, extended, and portable implementation of the Berkeley lpr print spooler functionality. While providing the same interface and meeting RFC1179 requirements, the implementation is completely independent and provides support for the following features: lightweight (no databases needed) lpr, lpc, and lprm programs; dynamic redirection of print queues; printer pooling and load balancing; automatic job holding; highly verbose diagnostics; client programs do not need to run SETUID root; greatly enhanced security checks; load balancing across multiple printers; and a greatly improved permission and authorization mechanism.
CUPS uses IPP/1.1 5 to provide a complete, modern printing system for UNIX that can be extended to support new printers, devices, and protocols while providing compatibility with existing UNIX applications.
Clicking on the Do Administration Tasks link (Figure 2) will load the module that will allow the addition and deletion of printers, definition of classes, and queue/job management.
From the Admin page, click on the Add Printer link to define a printer on the system. A screen similar to Figure 3 will appear. Enter the name, location, and description of the printer.
Next, select the type of printing device from the drop-down menu. As of this writing, CUPS supports the following printing protocols:
The AppSocket/HPJetDirect option is used for many types of network-aware printers. The JetDirect devices, of which compatible devices are sold by different companies, is essentially a remote parallel port. JetDirect devices listen on TCP port 9100, and printing to them is a matter of sending the raw print commands directly to this port. The JetDirects can often support multiple parallel ports and can help eliminate some of the interrupt conflicts when dealing with legacy x86 equipment.
The Internet Printing Protocol, as mentioned previously, is a proposed standard for printing systems that will allow, among other things, the ability to print across the Internet. Besides making facsimile devices somewhat obsolete, it could allow easier and better printing networks. The downside is that it is a relatively new standard 7 and not widely supported.
LPD/LPR were discussed previously where we mentioned that the LPR system is a client/server model. As in most Linux servers, the clients need not be on the same physical machine and can be configured to listen for remote TCP connections. One main downside is the relatively poor authentication mechanisms available for this system.
Finally, shared Windows printers are also supported via the Samba 8 suite. Though Windows has gained a reputation for its inability to work with non-Windows applications, instability, bloat, anti-trust violations and general evil, it is somewhat ubiquitous in many corporate offices. In fact, there are some non-PC network printer devices (similar to the JetDirects) and even some printers, that advertise themselves on the network as a Windows printer.
For our example we'll choose an HP JetDirect printer. Like CUPS, the JetDirects can be administered via a browser. One can also telnet directly into the JetDirect to change passwords, IP information, and other features. Refer to the user manuals for more information.
Next, we are prompted for the Device URI. Becase we are printing to a socket on a remote device, we specify the URI as socket://192.168.1.100:9100. Of course, substitute the correct IP information for your device. If the JetDirect supports multiple printers they are often accessed by incrementing the port number. Thus, for the second printer on a single JetDirect device we'd use socket://192.168.1.100:9101.
Then, select the Model/Driver for the new device on next two screens. The list of supported printers is quite extensive. If however, you do not find your identical model, try one that seems close. On a related note, use the correct model if you do find it on the list. Though Postscript itself should create pages identically on different printers, there may be slight differences in margins and color/grayscale manipulation that can affect print quality. 9
[klowe@omicron klowe]$ lpstat -p printer print@omicron unknown state. enabled since Nov 13 21:33 2002. available Printer: print@omicron Queue: no printable jobs in queue Server: no server active Status: job 'klowe@omicron+62' removed at 16:00:11.980 Rank Owner/ID Class Job Files Size Time done klowe@omicron+11 A 11 printing.ps 60249 20:16:38
One notable example is the front-end shipped with the KDE desktop, called kprinter(Figure 5). For the most part, kprinter can be substituted in any instance where one would normally use lpr. Instead of having to remember the sometimes cryptic switches, one can use menus and shiny buttons to choose options such as multi-page output or pamphlet printing.
Our first goal is to define a print queue within Samba. The main configuration file is located in /etc/samba/smb.conf (this may vary according to your distribution). We add the following entries to create a pdfprinter resource:
[pdfprinter]
path = /tmp
printable = yes
writeable = no
create mask = 0700
guest ok = yes
printer name = PDFPrinter
print command = /usr/share/pdfconvert
As in our LPR/LP example, we see that Samba also allows customization of the printing script and filters. In this case, we define a pdfconvert script that will convert the input, in the form of Postscript, into the PDF format using the ps2pdf utility. It will then drop the converted document into an accessible part of the filesystem.
#!/bin/sh # Simple script to convert a specified postscript file into a PDF document # and place it in a location that is shared by the Samba server. # # Arguments: # 1st - The name of the spool file # # John Bright, 2001, jbright@winfordeng.com # We will create the pdf into a temporary file based upon the current # date and time. After we are finished, we'll rename it to a file with # the same date, but ending in .pdf. We do this because if a user tries # to open a PDF that is still being written, they will get a message # that it is corrupt, when it is actually just not done yet. 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=/shr/pdfdropbox ps2pdf $1 $OUTDIR/$DATE.temp mv $OUTDIR/$DATE.temp $OUTDIR/$DATE.pdf rm $1
%configure --disable-shared --enable-static
Add -gzip to the end of the line so it reads:
%configure --disable-shared --enable-static --with-gzip
Rebuild the package using: rpmbuild -ba xpdf.spec
Finally, reinstall the new package.
This document was generated using the LaTeX2HTML translator Version 2002 (1.62)
Copyright © 1993, 1994, 1995, 1996,
Nikos Drakos,
Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999,
Ross Moore,
Mathematics Department, Macquarie University, Sydney.
The command line arguments were:
latex2html -split 1 printing.latex
The translation was initiated by Kwan Lowe on 2002-11-15