To use printers with the LPD spooling system, you will need
to set up both your printer hardware and the LPD software.
This document describes two levels of setup:
See section Simple Printer
Setup to learn how to connect a printer, tell LPD how to
communicate with it, and print plain text files to the printer.
See section Advanced Printer Setup to learn how
to print a variety of special file formats, to print header pages, to print across a
network, to control access to printers, and to do printer accounting.
Although this section is called “Simple Printer Setup”, it is actually
fairly complex. Getting the printer to work with your computer and the LPD spooler is the hardest part. The advanced options like header
pages and accounting are fairly easy once you get the printer working.
This section tells about the various ways you can connect a printer to your PC. It
talks about the kinds of ports and cables, and also the kernel configuration you may need
to enable FreeBSD to speak to the printer.
If you have already connected your printer and have successfully printed with it under
another operating system, you can probably skip to section Software Setup.
Printers sold for use on PC's today generally come with one or more of the following
three interfaces:
Serial interfaces, also known as
RS-232 or COM ports, use a serial port on your computer to send data to the printer.
Serial interfaces are common in the computer industry and cables are readily available
and also easy to construct. Serial interfaces sometimes need special cables and might
require you to configure somewhat complex communications options. Most PC serial ports
have a maximum transmission rate of 115200 bps, which makes printing large graphic
print jobs with them impractical.
Parallel interfaces use a
parallel port on your computer to send data to the printer. Parallel interfaces are
common in the PC market and are faster than RS-232 serial. Cables are readily available
but more difficult to construct by hand. There are usually no communications options with
parallel interfaces, making their configuration exceedingly simple.
Parallel interfaces are sometimes known as “Centronics” interfaces, named
after the connector type on the printer.
USB interfaces, named for the Universal Serial Bus, can run at even faster speeds than
parallel or RS-232 serial interfaces. Cables are simple and cheap. USB is superior to
RS-232 Serial and to Parallel for printing, but it is not as well supported under UNIX® systems. A way to avoid this problem is to purchase a
printer that has both a USB interface and a Parallel interface, as many printers do.
In general, Parallel interfaces usually offer just one-way communication (computer to
printer) while serial and USB gives you two-way. Newer parallel ports (EPP and ECP) and
printers can communicate in both directions under FreeBSD when a IEEE-1284-compliant
cable is used.
Two-way communication to the printer over a parallel port is generally done in one of
two ways. The first method uses a custom-built printer driver for FreeBSD that speaks the
proprietary language used by the printer. This is common with inkjet printers and can be
used for reporting ink levels and other status information. The second method is used
when the printer supports PostScript®.
PostScript jobs are actually programs sent to the
printer; they need not produce paper at all and may return results directly to the
computer. PostScript also uses two-way communication to
tell the computer about problems, such as errors in the PostScript program or paper jams. Your users may be appreciative
of such information. Furthermore, the best way to do effective accounting with a PostScript printer requires two-way communication: you ask the
printer for its page count (how many pages it has printed in its lifetime), then send the
user's job, then ask again for its page count. Subtract the two values and you know how
much paper to charge to the user.
To hook up a printer using a parallel interface, connect the Centronics cable between
the printer and the computer. The instructions that came with the printer, the computer,
or both should give you complete guidance.
Remember which parallel port you used on the computer. The first parallel port is ppc0 to FreeBSD; the second is ppc1, and
so on. The printer device name uses the same scheme: /dev/lpt0
for the printer on the first parallel ports etc.
To hook up a printer using a serial interface, connect the proper serial cable between
the printer and the computer. The instructions that came with the printer, the computer,
or both should give you complete guidance.
If you are unsure what the “proper serial cable” is, you may wish to try
one of the following alternatives:
A modem cable connects each pin
of the connector on one end of the cable straight through to its corresponding pin of the
connector on the other end. This type of cable is also known as a
“DTE-to-DCE” cable.
A null-modem cable connects some
pins straight through, swaps others (send data to receive data, for example), and shorts
some internally in each connector hood. This type of cable is also known as a
“DTE-to-DTE” cable.
A serial printer cable, required
for some unusual printers, is like the null-modem cable, but sends some signals to their
counterparts instead of being internally shorted.
You should also set up the communications parameters for the printer, usually through
front-panel controls or DIP switches on the printer. Choose the highest bps (bits per second, sometimes baud rate) that both your computer and the printer can
support. Choose 7 or 8 data bits; none, even, or odd parity; and 1 or 2 stop bits. Also
choose a flow control protocol: either none, or XON/XOFF (also known as
“in-band” or “software”) flow control. Remember these settings
for the software configuration that follows.
The operating system kernel is compiled to work with a specific set of devices. The
serial or parallel interface for your printer is a part of that set. Therefore, it might
be necessary to add support for an additional serial or parallel port if your kernel is
not already configured for one.
To find out if the kernel you are currently using supports a serial interface,
type:
#grep sioN/var/run/dmesg.boot
Where N is the number of the serial port, starting
from zero. If you see output similar to the following:
sio2 at port 0x3e8-0x3ef irq 5 on isa
sio2: type 16550A
then the kernel supports the port.
To find out if the kernel supports a parallel interface, type:
#grep ppcN /var/run/dmesg.boot
Where N is the number of the parallel port,
starting from zero. If you see output similar to the following:
ppc0: <Parallel port> at port 0x378-0x37f irq 7 on isa0
ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
ppc0: FIFO with 16/16/8 bytes threshold
then the kernel supports the port.
You might have to reconfigure your kernel in order for the operating system to
recognize and use the parallel or serial port you are using for the printer.
To add support for a serial port, see the section on kernel configuration. To add
support for a parallel port, see that section and the section that follows.
When you are using the parallel interface, you can choose whether FreeBSD should use
interrupt-driven or polled communication with the printer. The generic printer device
driver (lpt(4)) on FreeBSD
uses the ppbus(4) system, which
controls the port chipset with the ppc(4) driver.
The interrupt-driven method is
the default with the GENERIC kernel. With this method, the operating system uses an IRQ
line to determine when the printer is ready for data.
The polled method directs the
operating system to repeatedly ask the printer if it is ready for more data. When it
responds ready, the kernel sends more data.
The interrupt-driven method is usually somewhat faster but uses up a precious IRQ
line. Some newer HP printers are claimed not to work correctly in interrupt mode,
apparently due to some (not yet exactly understood) timing problem. These printers need
polled mode. You should use whichever one works. Some printers will work in both modes,
but are painfully slow in interrupt mode.
You can set the communications mode in two ways: by configuring the kernel or by using
the lptcontrol(8)
program.
To set the communications mode by
configuring the kernel:
Edit your kernel configuration file. Look for an ppc0 entry.
If you are setting up the second parallel port, use ppc1
instead. Use ppc2 for the third port, and so on.
If you want interrupt-driven mode, edit the following line:
hint.ppc.0.irq="N"
in the /boot/device.hints file and replace N with the right IRQ number. The kernel configuration
file must also contain the ppc(4) driver:
device ppc
If you want polled mode, remove in your /boot/device.hints
file, the following line:
hint.ppc.0.irq="N"
In some cases, this is not enough to put the port in polled mode under FreeBSD. Most
of time it comes from acpi(4) driver, this
latter is able to probe and attach devices, and therefore, control the access mode to the
printer port. You should check your acpi(4) configuration
to correct this problem.
Save the file. Then configure, build, and install the kernel, then reboot. See kernel configuration for more details.
Before proceeding to configure the spooling system, you should make sure the operating
system can successfully send data to your printer. It is a lot easier to debug printer
communication and the spooling system separately.
To test the printer, we will send some text to it. For printers that can immediately
print characters sent to them, the program lptest(1) is perfect:
it generates all 96 printable ASCII characters in 96 lines.
For a PostScript (or other language-based) printer, we
will need a more sophisticated test. A small PostScript
program, such as the following, will suffice:
The above PostScript code can be placed into a file and
used as shown in the examples appearing in the following sections.
Note: When this document refers to a printer language, it is assuming a
language like PostScript, and not Hewlett Packard's PCL.
Although PCL has great functionality, you can intermingle plain text with its escape
sequences. PostScript cannot directly print plain text,
and that is the kind of printer language for which we must make special
accommodations.
If the printer can print plain text, then use lptest(1). Type:
#lptest > /dev/lptN
Where N is the number of the parallel port,
starting from zero.
If the printer understands PostScript or other printer
language, then send a small program to the printer. Type:
#cat > /dev/lptN
Then, line by line, type the program carefully as you cannot edit a line once you have pressed RETURN or ENTER. When you have finished
entering the program, press CONTROL+D, or whatever your end of
file key is.
Alternatively, you can put the program in a file and type:
#cat file > /dev/lptN
Where file is the name of the file containing the
program you want to send to the printer.
You should see something print. Do not worry if the text does not look right; we will
fix such things later.
Edit the file /etc/remote. Add the following entry:
printer:dv=/dev/port:br#bps-rate:pa=parity
Where port is the device entry for the serial port
(ttyd0, ttyd1, etc.), bps-rate is the bits-per-second rate at which the printer
communicates, and parity is the parity required by
the printer (either even, odd, none, or zero).
Here is a sample entry for a printer connected via a serial line to the third serial
port at 19200 bps with no parity:
If this step does not work, edit the file /etc/remote again
and try using /dev/cuaaN
instead of /dev/ttydN.
Send data to the printer.
If the printer can print plain text, then use lptest(1). Type:
%$lptest
If the printer understands PostScript or other printer
language, then send a small program to the printer. Type the program, line by line, very carefully as backspacing or other
editing keys may be significant to the printer. You may also need to type a special
end-of-file key for the printer so it knows it received the whole program. For PostScript printers, press CONTROL+D.
Alternatively, you can put the program in a file and type:
%>file
Where file is the name of the file containing the
program. After tip(1) sends the file,
press any required end-of-file key.
You should see something print. Do not worry if the text does not look right; we will
fix that later.
At this point, your printer should be hooked up, your kernel configured to communicate
with it (if necessary), and you have been able to send some simple data to the printer.
Now, we are ready to configure LPD to control access to your
printer.
You configure LPD by editing the file /etc/printcap. The LPD spooling system
reads this file each time the spooler is used, so updates to the file take immediate
effect.
The format of the printcap(5) file is
straightforward. Use your favorite text editor to make changes to /etc/printcap. The format is identical to other capability files
like /usr/share/misc/termcap and /etc/remote. For complete information about the format, see the cgetent(3).
The simple spooler configuration consists of the following steps:
Pick a name (and a few convenient aliases) for the printer, and put them in the /etc/printcap file; see the Naming the Printer section for more
information on naming.
Turn off header pages (which are on by default) by inserting the sh capability; see the Suppressing Header Pages
section for more information.
Make a spooling directory, and specify its location with the sd capability; see the Making the Spooling Directory
section for more information.
Set the /dev entry to use for the printer, and note it in
/etc/printcap with the lp capability;
see the Identifying the Printer
Device for more information. Also, if the printer is on a serial port, set up the
communication parameters with the ms# capability which is
discussed in the Configuring
Spooler Communications Parameters section.
Test the setup by printing something with the lpr(1) command. More
details are available in the Trying
It Out and Troubleshooting sections.
Note: Language-based printers, such as PostScript printers, cannot directly print plain text. The
simple setup outlined above and described in the following sections assumes that if you
are installing such a printer you will print only files that the printer can
understand.
Users often expect that they can print plain text to any of the printers installed on
your system. Programs that interface to LPD to do their
printing usually make the same assumption. If you are installing such a printer and want
to be able to print jobs in the printer language and print plain text jobs, you are strongly urged to add an
additional step to the simple setup outlined above: install an automatic
plain-text-to-PostScript (or other printer language)
conversion program. The section entitled Accommodating Plain Text
Jobs on PostScript Printers tells how to do this.
The first (easy) step is to pick a name for your printer. It really does not matter
whether you choose functional or whimsical names since you can also provide a number of
aliases for the printer.
At least one of the printers specified in the /etc/printcap
should have the alias lp. This is the default printer's name. If
users do not have the PRINTER environment variable nor specify a
printer name on the command line of any of the LPD commands,
then lp will be the default printer they get to use.
Also, it is common practice to make the last alias for a printer be a full description
of the printer, including make and model.
Once you have picked a name and some common aliases, put them in the /etc/printcap file. The name of the printer should start in the
leftmost column. Separate each alias with a vertical bar and put a colon after the last
alias.
In the following example, we start with a skeletal /etc/printcap that defines two printers (a Diablo 630 line printer
and a Panasonic KX-P4455 PostScript laser printer):
#
# /etc/printcap for host rose
#
rattan|line|diablo|lp|Diablo 630 Line Printer:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:
In this example, the first printer is named rattan and has as
aliases line, diablo, lp, and Diablo 630 Line Printer. Since it
has the alias lp, it is also the default printer. The second is
named bamboo, and has as aliases ps,
PS, S, panasonic, and Panasonic KX-P4455 PostScript
v51.4.
The LPD spooling system will by default print a header page for each job. The header page
contains the user name who requested the job, the host from which the job came, and the
name of the job, in nice large letters. Unfortunately, all this extra text gets in the
way of debugging the simple printer setup, so we will suppress header pages.
To suppress header pages, add the sh capability to the entry
for the printer in /etc/printcap. Here is an example /etc/printcap with sh added:
#
# /etc/printcap for host rose - no header pages anywhere
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:
Note how we used the correct format: the first line starts in the leftmost column, and
subsequent lines are indented. Every line in an entry except the last ends in a backslash
character.
The next step in the simple spooler setup is to make a spooling directory, a directory where print jobs reside until
they are printed, and where a number of other spooler support files live.
Because of the variable nature of spooling directories, it is customary to put these
directories under /var/spool. It is not necessary to backup the
contents of spooling directories, either. Recreating them is as simple as running mkdir(1).
It is also customary to make the directory with a name that is identical to the name
of the printer, as shown below:
#mkdir /var/spool/printer-name
However, if you have a lot of printers on your network, you might want to put the
spooling directories under a single directory that you reserve just for printing with LPD. We will do this for our two example printers rattan and bamboo:
Note: If you are concerned about the privacy of jobs that users print, you
might want to protect the spooling directory so it is not publicly accessible. Spooling
directories should be owned and be readable, writable, and searchable by user daemon and group daemon, and no one
else. We will do this for our example printers:
Finally, you need to tell LPD about these directories using
the /etc/printcap file. You specify the pathname of the
spooling directory with the sd capability:
#
# /etc/printcap for host rose - added spooling directories
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:
Note that the name of the printer starts in the first column but all other entries
describing the printer should be indented and each line end escaped with a backslash.
If you do not specify a spooling directory with sd, the
spooling system will use /var/spool/lpd as a default.
In the Hardware Setup
section, we identified the port and the relevant /dev directory
entry that FreeBSD will use to communicate with the printer. Now, we tell LPD that information. When the spooling system has a job to
print, it will open the specified device on behalf of the filter program (which is
responsible for passing data to the printer).
List the /dev entry pathname in the /etc/printcap file using the lp
capability.
In our running example, let us assume that rattan is on the
first parallel port, and bamboo is on a sixth serial port; here
are the additions to /etc/printcap:
#
# /etc/printcap for host rose - identified what devices to use
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:\
:lp=/dev/lpt0:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:\
:lp=/dev/ttyd5:
If you do not specify the lp capability for a printer in your
/etc/printcap file, LPD uses /dev/lp as a default. /dev/lp currently
does not exist in FreeBSD.
If the printer you are installing is connected to a parallel port, skip to the section
entitled, Installing the Text
Filter. Otherwise, be sure to follow the instructions in the next section.
For printers on serial ports, LPD can set up the bps rate,
parity, and other serial communication parameters on behalf of the filter program that
sends data to the printer. This is advantageous since:
It lets you try different communication parameters by simply editing the /etc/printcap file; you do not have to recompile the filter
program.
It enables the spooling system to use the same filter program for multiple printers
which may have different serial communication settings.
The following /etc/printcap capabilities control serial
communication parameters of the device listed in the lp
capability:
br#bps-rate
Sets the communications speed of the device to bps-rate, where bps-rate can be 50, 75, 110, 134, 150, 200, 300, 600,
1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, or 115200 bits-per-second.
ms#stty-mode
Sets the options for the terminal device after opening the device. stty(1) explains the
available options.
When LPD opens the device specified by the lp capability, it sets the characteristics of the device to those
specified with the ms# capability. Of particular interest will
be the parenb, parodd, cs5, cs6, cs7, cs8, cstopb, crtscts, and ixon modes, which are
explained in the stty(1) manual
page.
Let us add to our example printer on the sixth serial port. We will set the bps rate
to 38400. For the mode, we will set no parity with -parenb,
8-bit characters with cs8, no modem control with clocal and hardware flow control with crtscts:
We are now ready to tell LPD what text filter to use to
send jobs to the printer. A text
filter, also known as an input
filter, is a program that LPD runs when it has a
job to print. When LPD runs the text filter for a printer, it
sets the filter's standard input to the job to print, and its standard output to the
printer device specified with the lp capability. The filter is
expected to read the job from standard input, perform any necessary translation for the
printer, and write the results to standard output, which will get printed. For more
information on the text filter, see the Filters section.
For our simple printer setup, the text filter can be a small shell script that just
executes /bin/cat to send the job to the printer. FreeBSD comes
with another filter called lpf that handles backspacing and
underlining for printers that might not deal with such character streams well. And, of
course, you can use any other filter program you want. The filter lpf is described in detail in section entitled lpf: a Text Filter.
First, let us make the shell script /usr/local/libexec/if-simple be a simple text filter. Put the
following text into that file with your favorite text editor:
#!/bin/sh
#
# if-simple - Simple text input filter for lpd
# Installed in /usr/local/libexec/if-simple
#
# Simply copies stdin to stdout. Ignores all filter arguments.
/bin/cat && exit 0
exit 2
Make the file executable:
#chmod 555 /usr/local/libexec/if-simple
And then tell LPD to use it by specifying it with the if
capability in /etc/printcap. We will add it to the two printers
we have so far in the example /etc/printcap:
#
# /etc/printcap for host rose - added text filter
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:\
:lp=/dev/lpt0:\
:if=/usr/local/libexec/if-simple:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:\
:lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:\
:if=/usr/local/libexec/if-simple:
Note: A copy of the if-simple script can be found in
the /usr/share/examples/printing directory.
You have reached the end of the simple LPD setup.
Unfortunately, congratulations are not quite yet in order, since we still have to test
the setup and correct any problems. To test the setup, try printing something. To print
with the LPD system, you use the command lpr(1), which submits
a job for printing.
Where printer-name is a the name of a printer (or
an alias) specified in /etc/printcap. To test the default
printer, type lpr(1) without any
-P argument. Again, if you are testing a printer that expects
PostScript, send a PostScript program in that language instead of using lptest(1). You can do
so by putting the program in a file and typing lpr file.
For a PostScript printer, you should get the results of
the program. If you are using lptest(1), then your
results should look like the following:
To further test the printer, try downloading larger programs (for language-based
printers) or running lptest(1) with
different arguments. For example, lptest 80 60 will produce 60
lines of 80 characters each.
If the printer did not work, see the Troubleshooting section.