Table of Contents
This chapter describes a simple configuration for printing, using an HP Deskjet 690C connected to the first parallel port as and the lpd printing system that comes with NetBSD an example. First, the system will be configured to print text documents, and next the configuration will be extended to print PostScript documents using the Ghostscript program. Please note that there are other, alternative printing systems available in the packages collection, like lprng and the Common Unix Printing System (CUPS), which are not covered here.
After installation it is not yet possible to print, because the
lpd printer spooler daemon is not enabled.
To enable lpd, one line in the
/etc/rc.conf
file must be changed from:
lpd=NO
to
lpd=YES
The change will come into effect at the next boot, but the daemon can be started manually now:
#
sh /etc/rc.d/lpd start
To check if lpd is active, type the following command:
#
ps ax | grep lpd
179 ?? Is 0:00.01 lpd
If you don't see an entry for lpd in the output of the previous command, the daemon is not active.
The lpd system is configured via
/etc/printcap.
Before configuring
/etc/printcap
it is a good idea
to make a printer test, to check if the physical connection
between your computer and the printer is working.
The test sends out some data directly to the printer
device. Assuming you use a printer connected to the parallel
port, this is /dev/lpt0
; if you use an USB
printer try /dev/ulpt0
. Please check the
manpages of these devices (lpt(4), ulpt(4)) for more
information!
In our example we have a printer attached to the parallel port, so we run this:
#
lptest 70 5 > /dev/lpt0
To see what the output should look like, try the same command without redirecting the output to the printer:
#
lptest 70 5
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg #$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh $%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghi %&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij
A frequent problem is that the output on the printer is not correctly aligned in columns but has a “staircase” configuration. This usually means that the printer is configured to begin a new line at the left margin after receiving both a <CR> (carriage return, ASCII 13) character and a <LF> (line feed, ASCII 10) character. NetBSD only sends a <LF> character. You can fix this problem in two ways:
by changing the configuration of the printer
by using a simple printer filter (described later)
In the previous example the lpd
spooler is not involved because the program output is sent
directly to the printer device (/dev/lpt0
)
and is not spooled.
This section explains how to configure the example printer to print text documents.
The printer must have an entry in the
/etc/printcap
file; the entry contains the
printer id (the name of the printer) and the printer
description. The lp id is the default
used by many programs. Here is an example entry:
Example 12.1. /etc/printcap
lp|local printer|HP DeskJet 690C:\ :lp=/dev/lpa0:sd=/var/spool/lpd/lp:lf=/var/log/lpd-errs:\ :sh:pl#66:pw#80:if=/usr/local/libexec/lpfilter:
The file format and options are described in detail in the printcap(5) manpage. Please note that an input filter has been specified (with the if option) which will take care of eliminating the staircase problem:
if=/usr/local/libexec/lpfilter
Example 12.1, “/etc/printcap
” uses the
lpa0 device (polled driver) for the
printer, instead of the lpd0 (interrupt
driven driver). Using interrupts there is a communication
problem with some printers, and the HP Deskjet 690C is one of
them: printing is very slow and one PostScript page can take
hours. The problem is solved using the
lpa driver. It is also possible to
compile a custom kernel where lpt is polled.
The printcap entry for the printer also specifies a spool directory, which must be created; this directory will be used by the lpd daemon to accumulate the data to be printed:
#
cd /var/spool/lpd
#
mkdir lp
#
chown daemon:daemon lp
#
chmod 770 lp
The only missing part is the
lpfilter
input filter, which must be written.
The only task performed by this filter is to configure the printer for
the elimination of the staircase problem before sending the text to be
printed.
The printer used in this example requires the following initialization
string:
“<ESC>&k2G
”.
Example 12.2. /usr/local/libexec/lpfilter
#!/bin/sh # Treat LF as CR+LF printf "\033&k2G" && cat && exit 0 exit 2
After saving this script into the name you used in
/etc/printcap
, you need to make sure it's
executable:
#
chmod 755 /usr/local/libexec/lpfilter*
There is another filter that can be used:
if=/usr/libexec/lpr/lpf:
This filter is much more complex than the one presented before.
It is written to process the output of nroff
and handles underline and overprinting, expands tab characters
and converts LF to CR + LF.
The source to this filter program can be found in
/usr/src/usr.sbin/lpr/filters/lpf.c
.
After everything is in place now, the lptest command can be run again now, this time using the lpr command, which will first send the data to the lpd spooler, then runs the filter and sends the data off to the printer:
#
lptest 70 5 | lpr -h
The lpr program prints text using the
spooler to send data to the printer; the -h
option turns off the printing of a banner page (not really
necessary, because of the sh option in
/etc/printcap
). Users more familiar with
the System V printing system can also use the lp(1) command
that comes as an alternative to lpr(1).
Now that basic printing works, the functionality for printing PostScript files can be added. The simple printer used in this example does not support native printing of PostScript files; a program must be used which is capable of converting a PostScript document in a sequence of commands that the printer understands. The Ghostscript program, which can be found in packages collection, can be used to this purpose (see Chapter 30, The package collection). This section explains how to configure lpd to use Ghostscript to print PostScript files on the HP Deskjet 690C.
A second id for the printer will be created in
/etc/printcap
: this new id will use a different
input filter, which will call Ghostscript to perform the actual print
of the PostScript document.
Therefore, text documents will be printed on the
lp printer and PostScript documents on the
ps printer: both entries use the same physical
printer but have different printing filters.
The same result can be achieved using different configurations. For example, a single entry with only one filter could be used. For this, the filter should be able to automatically determine the format of the document being printed, and use the appropriate printing program. This approach is simpler but leads to a more complex filter; if you like it you should consider installing the magicfilter program from the packages collection: it does this and many other things automatically.
For our approach, the new /etc/printcap
file looks like this:
Example 12.3. /etc/printcap
lp|local printer|HP DeskJet 690C:\ :lp=/dev/lpa0:sd=/var/spool/lpd/lp:lf=/var/log/lpd-errs:\ :sh:pl#66:pw#80:if=/usr/local/libexec/lpfilter: ps|Ghostscript driver:\ :lp=/dev/lpa0:sd=/var/spool/lpd/ps:lf=/var/log/lpd-errs:\ :mx#0:sh:if=/usr/local/libexec/lpfilter-ps:
Option mx#0
is very important for printing PostScript
files because it eliminates size restrictions on the input file;
PostScript documents tend to be very big.
The if
option points to the new filter.
There is also a new spool directory.
The next steps are the creation of the new spool directory and of the filter program. The procedure for the spool directory is the same as above:
#
cd /var/spool/lpd
#
mkdir ps
#
chown daemon:daemon ps
#
chmod 770 ps
The filter program for PostScript output is more complex than
the text base one: the file to be printed is fed to the
interpreter which converts it into a sequence of
commands in the printer's control language, and then sends that
off to the printer. We have achieved to
transform a cheap color printer in a device suitable for
PostScript output, by virtue of the NetBSD operating system and
some powerful freeware packages. The options used to configure
Ghostscript are described in the
Ghostscript documentation: cdj550
is the
device used to drive the HP printer.
Example 12.4. /usr/local/libexec/lpfilter-ps
#!/bin/sh # Treat LF as CR+LF printf "\033&k2G" || exit 2 # Print the postscript file /usr/pkg/bin/gs -dSAFER -dBATCH -dQUIET -dNOPAUSE -q -sDEVICE=cdj550 \ -sOutputFile=- -sPAPERSIZE=a4 - && exit 0 exit 2
To summarize: two different printer names have been created on the system, which point to the same physical printer but use different options, different filters and different spool directories. Text files and PostScript files can be printed. To print PostScript files the Ghostscript package must be installed on the system.
This section lists some useful BSD commands for printer and print jobs administration. Besides the already mentioned lpr and lpd commands, we have:
examine the printer job queue.
delete jobs from the printer's queue.
check the printing system, enable/disable printers and printer features.
It is possible to configure the printing system in order to
print on a printer connected to a remote host.
Let's say that, for example, you work on the wotan
host and you want to print on the printer connected to the
loge host.
The /etc/printcap
file of loge is the one
of Example 12.3, “/etc/printcap
”.
From wotan it will be possible to print Postscript files using
Ghostscript on loge.
The first step is to accept the print jobs submitted
from the wotan host to the loge host.
To accomplish this, a line with the wotan host name must be added
to the /etc/hosts.lpd
file on loge:
#
hostname
loge#
cat /etc/hosts.lpd
wotan
The format of this file is very simple: each line contains the
name of a host which is permitted to print on the local system.
By default the lpd daemon only listens on UNIX domain sockets
for local connections, it won't accept any network connects.
To ensure the daemon also accepts incoming network traffic, the
following will need to be added to
/etc/rc.conf
:
lpd_flags=""
Next, the /etc/printcap
file on wotan
must be configured in order to send print jobs to loge.
For example:
lp|line printer on loge:\ :lp=:sd=/var/spool/lpd/lp:lf=/var/log/lp-errs:\ :rm=loge:rp=lp ps|Ghostscript driver on loge:\ :lp=:sd=/var/spool/lpd/ps:lf=/var/log/lp-errs:\ :mx#0:\ :rm=loge:rp=ps
There are four main differences between this configuration and
the one of Example 12.3, “/etc/printcap
”.
The definition of “lp” is empty.
The “rm” (remote machine) entry defines the name of the host to which the printer is connected.
The “rp” (remote printer) entry defines the name of the printer connected to the remote host.
It is not necessary to specify input filters because the definitions on the loge host will be used.
The spool directories must still be created locally on wotan:
#
cd /var/spool/lpd
#
mkdir lp
#
chown daemon:daemon lp
#
chmod 770 lp
#
mkdir ps
#
chown daemon:daemon ps
#
chmod 770 ps
Now the print jobs for the “lp” and “ps” queues on wotan will be sent automatically to the printer connected to loge.