4886 lines
195 KiB
Text
4886 lines
195 KiB
Text
<!--
|
|
The FreeBSD Documentation Project
|
|
|
|
$FreeBSD: doc/en_US.ISO8859-1/books/handbook/printing/chapter.sgml,v 1.47 2001/08/22 05:37:49 murray Exp $
|
|
-->
|
|
|
|
<chapter id="printing">
|
|
<chapterinfo>
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Sean</firstname>
|
|
<surname>Kelly</surname>
|
|
<contrib>Contributed by </contrib>
|
|
</author>
|
|
<!-- 30 Sept 1995 -->
|
|
</authorgroup>
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Jim</firstname>
|
|
<surname>Mock</surname>
|
|
<contrib>Restructured and updated by </contrib>
|
|
<!-- Mar 2000 -->
|
|
</author>
|
|
</authorgroup>
|
|
</chapterinfo>
|
|
|
|
<title>Printing</title>
|
|
|
|
<sect1>
|
|
<title>Synopsis</title>
|
|
<indexterm><primary>LPD spooling system</primary></indexterm>
|
|
<indexterm><primary>printing</primary></indexterm>
|
|
|
|
<para>FreeBSD can be used to print to a wide variety of printers, from the
|
|
oldest impact printer to the latest laser printers, and everything in
|
|
between, allowing you to produce high quality printed output from the
|
|
applications you run.</para>
|
|
|
|
<para>FreeBSD can also be configured to act as a print server on a
|
|
network; in this capacity FreeBSD can receive print jobs from a variety
|
|
of other computers, including other FreeBSD computers, Windows and MacOS
|
|
hosts. FreeBSD will ensure that one job at a time is printed, and can
|
|
keep statistics on which users and machines are doing the most printing,
|
|
produce <quote>banner</quote> pages showing who's printout is who's, and
|
|
more.</para>
|
|
|
|
<para>After reading this chapter you will know:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>How to configure the FreeBSD print spooler.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to install print filters, to handle special print jobs
|
|
differently, including converting incoming documents to print
|
|
formats that your printers understand.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to enable header, or banner pages on your printout.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to print to printers connected to other computers.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to print to printers connected directly to the
|
|
network.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to control printer restrictions, including limiting the size
|
|
of print jobs, and preventing certain users from printing.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to keep printer statistics, and account for printer
|
|
usage.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>How to troubleshoot printing problems.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Before reading this chapter you should:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Know how to configure and install a new kernel
|
|
(<xref linkend="kernelconfig">).</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</sect1>
|
|
|
|
<sect1 id="printing-intro-spooler">
|
|
<title>Introduction</title>
|
|
|
|
<para>In order to use printers with FreeBSD, you will need to set
|
|
them up to work with the Berkeley line printer spooling system,
|
|
also known as the <application>LPD</application> spooling system.
|
|
It is the standard printer control system in FreeBSD. This
|
|
chapter introduces the <application>LPD</application> spooling
|
|
system, often simply called <application>LPD</application>, and
|
|
will guide you through its configuration.</para>
|
|
|
|
<para>If you are already familiar with
|
|
<application>LPD</application> or another printer spooling
|
|
system, you may wish to skip to section <link
|
|
linkend="printing-intro-setup">Setting up the spooling
|
|
system</link>.</para>
|
|
|
|
<para><application>LPD</application> controls everything about a
|
|
host's printers. It is responsible for a number of things:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>It controls access to attached printers and printers
|
|
attached to other hosts on the network.</para>
|
|
</listitem>
|
|
|
|
<indexterm><primary>print jobs</primary></indexterm>
|
|
<listitem>
|
|
<para>It enables users to submit files to be printed; these
|
|
submissions are known as <emphasis>jobs</emphasis>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It prevents multiple users from accessing a printer at the
|
|
same time by maintaining a <emphasis>queue</emphasis> for each
|
|
printer.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It can print <emphasis>header pages</emphasis> (also known
|
|
as <emphasis>banner</emphasis> or <emphasis>burst</emphasis>
|
|
pages) so users can easily find jobs they have printed in a
|
|
stack of printouts.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It takes care of communications parameters for printers
|
|
connected on serial ports.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It can send jobs over the network to a
|
|
<application>LPD</application> spooler on another host.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It can run special filters to format jobs to be printed for
|
|
various printer languages or printer capabilities.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It can account for printer usage.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Through a configuration file
|
|
(<filename>/etc/printcap</filename>), and by providing the special
|
|
filter programs, you can enable the <application>LPD</application>
|
|
system to do all or some
|
|
subset of the above for a great variety of printer hardware.</para>
|
|
|
|
<sect2 id="printing-intro-why">
|
|
<title>Why You Should Use the Spooler</title>
|
|
|
|
<para>If you are the sole user of your system, you may be wondering
|
|
why you should bother with the spooler when you do not need access
|
|
control, header pages, or printer accounting. While it is
|
|
possible to enable direct access to a printer, you should use the
|
|
spooler anyway since:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><application>LPD</application> prints jobs in the background;
|
|
you do not have to wait
|
|
for data to be copied to the printer.</para>
|
|
</listitem>
|
|
|
|
<indexterm><primary>TeX</primary></indexterm>
|
|
<listitem>
|
|
<para><application>LPD</application> can conveniently run a job
|
|
to be printed through
|
|
filters to add date/time headers or convert a special file
|
|
format (such as a TeX DVI file) into a format the printer will
|
|
understand. You will not have to do these steps
|
|
manually.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Many free and commercial programs that provide a print
|
|
feature usually expect to talk to the spooler on your system.
|
|
By setting up the spooling system, you will more easily
|
|
support other software you may later add or already
|
|
have.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="printing-intro-setup">
|
|
<title>Basic Setup</title>
|
|
|
|
<para>To use printers with the <application>LPD</application> spooling
|
|
system, you will need to
|
|
set up both your printer hardware and the
|
|
<application>LPD</application> software. This
|
|
document describes two levels of setup:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>See section <link linkend="printing-simple">Simple Printer
|
|
Setup</link> to learn how to connect a printer, tell
|
|
<application>LPD</application> how to
|
|
communicate with it, and print plain text files to the
|
|
printer.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>See section <link linkend="printing-advanced">Advanced
|
|
Printer Setup</link> to find out 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.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<sect2 id="printing-simple">
|
|
<title>Simple Printer Setup</title>
|
|
|
|
<para>This section tells how to configure printer hardware and the
|
|
<application>LPD</application> software to use the printer.
|
|
It teaches the basics:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Section <link linkend="printing-hardware">Hardware
|
|
Setup</link> gives some hints on connecting the printer to a
|
|
port on your computer.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Section <link linkend="printing-software">Software
|
|
Setup</link> shows how to setup the
|
|
<application>LPD</application> spooler configuration
|
|
file (<filename>/etc/printcap</filename>).</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>If you are setting up a printer that uses a network protocol
|
|
to accept data to print instead of a serial or parallel interface,
|
|
see <link linkend="printing-advanced-network-net-if">Printers With
|
|
Networked Data Stream Interfaces</link>.</para>
|
|
|
|
<para>Although this section is called <quote>Simple Printer
|
|
Setup</quote>, it is actually fairly complex. Getting the printer
|
|
to work with your computer and the <application>LPD</application>
|
|
spooler is the hardest
|
|
part. The advanced options like header pages and accounting are
|
|
fairly easy once you get the printer working.</para>
|
|
|
|
<sect3 id="printing-hardware">
|
|
<title>Hardware Setup</title>
|
|
|
|
<para>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.</para>
|
|
|
|
<para>If you have already connected your printer and have
|
|
successfully printed with it under another operating system, you
|
|
can probably skip to section <link
|
|
linkend="printing-software">Software Setup</link>.</para>
|
|
|
|
<sect4 id="printing-ports">
|
|
<title>Ports and Cables</title>
|
|
|
|
<para>Nearly all printers you can get for a PC today support one
|
|
or both of the following interfaces:</para>
|
|
|
|
<itemizedlist>
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>serial</secondary>
|
|
</indexterm>
|
|
<listitem>
|
|
<para><emphasis>Serial</emphasis> interfaces 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.</para>
|
|
</listitem>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>parallel</secondary>
|
|
</indexterm>
|
|
<listitem>
|
|
<para><emphasis>Parallel</emphasis> interfaces use a
|
|
parallel port on your computer to send data to the
|
|
printer. Parallel interfaces are common in the PC market.
|
|
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.</para>
|
|
|
|
<indexterm>
|
|
<primary>centronics</primary>
|
|
<see>parallel printers</see>
|
|
</indexterm>
|
|
<para>Parallel interfaces are sometimes known as
|
|
<quote>Centronics</quote> interfaces, named after the
|
|
connector type on the printer.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>In general, serial interfaces are slower than parallel
|
|
interfaces. Parallel interfaces usually offer just
|
|
one-way communication (computer to printer) while serial
|
|
gives you two-way. Many newer parallel ports and printers
|
|
can communicate in both directions under FreeBSD when a
|
|
IEEE1284 compliant cable is used.</para>
|
|
|
|
<indexterm><primary>PostScript</primary></indexterm>
|
|
<para>Usually, the only time you need two-way communication with
|
|
the printer is if the printer speaks PostScript. PostScript
|
|
printers can be very verbose. In fact, 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 the
|
|
user.</para>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-parallel">
|
|
<title>Parallel Ports</title>
|
|
|
|
<para>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.</para>
|
|
|
|
<para>Remember which parallel port you used on the computer.
|
|
The first parallel port is <filename>/dev/lpt0</filename> to
|
|
FreeBSD; the second is <filename>/dev/lpt1</filename>, and so
|
|
on.</para>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-serial">
|
|
<title>Serial Ports</title>
|
|
|
|
<para>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.</para>
|
|
|
|
<para>If you are unsure what the <quote>proper serial
|
|
cable</quote> is, you may wish to try one of the following
|
|
alternatives:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>A <emphasis>modem</emphasis> 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
|
|
<quote>DTE-to-DCE</quote> cable.</para>
|
|
</listitem>
|
|
|
|
<indexterm><primary>null-modem cable</primary></indexterm>
|
|
<listitem>
|
|
<para>A <emphasis>null-modem</emphasis> 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
|
|
<quote>DTE-to-DTE</quote> cable.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>A <emphasis>serial printer</emphasis> cable, required
|
|
for some unusual printers, is like the null-modem cable,
|
|
but sends some signals to their counterparts instead of
|
|
being internally shorted.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<indexterm><primary>baud rate</primary></indexterm>
|
|
<indexterm><primary>parity</primary></indexterm>
|
|
<indexterm><primary>flow control protocol</primary></indexterm>
|
|
<para>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
|
|
<literal>bps</literal> (bits per second, sometimes
|
|
<emphasis>baud rate</emphasis>) 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
|
|
<quote>in-band</quote> or <quote>software</quote>) flow control.
|
|
Remember these settings for the software configuration that
|
|
follows.</para>
|
|
</sect4>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-software">
|
|
<title>Software Setup</title>
|
|
|
|
<para>This section describes the software setup necessary to print
|
|
with the <application>LPD</application> spooling system in FreeBSD.
|
|
</para>
|
|
|
|
<para>Here is an outline of the steps involved:</para>
|
|
|
|
<procedure>
|
|
<step>
|
|
<para>Configure your kernel, if necessary, for the port you
|
|
are using for the printer; section <link
|
|
linkend="printing-kernel">Kernel Configuration</link> tells
|
|
you what you need to do.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Set the communications mode for the parallel port, if
|
|
you are using a parallel port; section <link
|
|
linkend="printing-parallel-port-mode">Setting the
|
|
Communication Mode for the Parallel Port</link> gives
|
|
details.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Test if the operating system can send data to the printer.
|
|
Section <link linkend="printing-testing">Checking Printer
|
|
Communications</link> gives some suggestions on how to do
|
|
this.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Set up <application>LPD</application> for the printer by
|
|
modifying the file
|
|
<filename>/etc/printcap</filename>. You will find out how
|
|
to do this later in this chapter.</para>
|
|
</step>
|
|
</procedure>
|
|
|
|
<sect4 id="printing-kernel">
|
|
<title>Kernel Configuration</title>
|
|
|
|
<para>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.</para>
|
|
|
|
<para>To find out if the kernel you are currently using supports
|
|
a serial interface, type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>dmesg | grep sio<replaceable>N</replaceable></userinput></screen>
|
|
|
|
<para>Where <replaceable>N</replaceable> is the number of the
|
|
serial port, starting from zero. If you see output similar to
|
|
the following:</para>
|
|
|
|
<screen>sio2 at 0x3e8-0x3ef irq 5 on isa
|
|
sio2: type 16550A</screen>
|
|
|
|
<para>then the kernel supports the port.</para>
|
|
|
|
<para>To find out if the kernel supports a parallel interface,
|
|
type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>dmesg | grep lpt<replaceable>N</replaceable></userinput></screen>
|
|
|
|
<para>Where <replaceable>N</replaceable> is the number of the
|
|
parallel port, starting from zero. If you see output similar
|
|
to the following <screen>lpt0 at 0x378-0x37f on isa</screen>
|
|
then the kernel supports the port.</para>
|
|
|
|
<para>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.</para>
|
|
|
|
<para>To add support for a serial port, see the section on
|
|
kernel configuration. To add support for a parallel port, see
|
|
that section <emphasis>and</emphasis> the section that
|
|
follows.</para>
|
|
</sect4>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-dev-ports">
|
|
<title>Adding <filename>/dev</filename> Entries for the
|
|
Ports</title>
|
|
|
|
<para>Even though the kernel may support communication along a
|
|
serial or parallel port, you will still need a software
|
|
interface through which programs running on the system can
|
|
send and receive data. That is what entries in the
|
|
<filename>/dev</filename> directory are for.</para>
|
|
|
|
<para><emphasis>To add a <filename>/dev</filename> entry for a
|
|
port:</emphasis></para>
|
|
|
|
<procedure>
|
|
<step>
|
|
<para>Become root with the &man.su.1; command. Enter the
|
|
root password when prompted.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Change to the <filename>/dev</filename>
|
|
directory:</para>
|
|
|
|
<screen>&prompt.root; cd <filename>/dev</filename></screen>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>./MAKEDEV <replaceable>port</replaceable></userinput></screen>
|
|
|
|
<para>Where <replaceable>port</replaceable> is the device
|
|
entry for the port you want to make. Use
|
|
<literal>lpt0</literal> for the first parallel port,
|
|
<literal>lpt1</literal> for the second, and so on; use
|
|
<literal>ttyd0</literal> for the first serial port,
|
|
<literal>ttyd1</literal> for the second, and so on.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>ls -l <replaceable>port</replaceable></userinput></screen>
|
|
|
|
<para>to make sure the device entry got created.</para>
|
|
</step>
|
|
</procedure>
|
|
|
|
<sect4 id="printing-parallel-port-mode">
|
|
<title>Setting the Communication Mode for the Parallel
|
|
Port</title>
|
|
|
|
<para>When you are using the parallel interface, you can choose
|
|
whether FreeBSD should use interrupt-driven or polled
|
|
communication with the printer.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>The <emphasis>interrupt-driven</emphasis> 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.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The <emphasis>polled</emphasis> 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.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>The interrupt-driven method is somewhat faster but uses up
|
|
a precious IRQ line. You should use whichever one
|
|
works.</para>
|
|
|
|
<para>You can set the communications mode in two ways: by
|
|
configuring the kernel or by using the &man.lptcontrol.8;
|
|
program.</para>
|
|
|
|
<para><emphasis>To set the communications mode by configuring
|
|
the kernel:</emphasis></para>
|
|
|
|
<procedure>
|
|
<step>
|
|
<para>Edit your kernel configuration file. Look for or add
|
|
an <literal>lpt0</literal> entry. If you are setting up
|
|
the second parallel port, use <literal>lpt1</literal>
|
|
instead. Use <literal>lpt2</literal> for the third port,
|
|
and so on.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>If you want interrupt-driven mode, add the
|
|
<literal>irq</literal> specifier:</para>
|
|
|
|
<programlisting>device lpt0 at isa? port? tty irq <replaceable>N</replaceable> vector lptintr</programlisting>
|
|
|
|
<para>Where <replaceable>N</replaceable> is the IRQ
|
|
number for your computer's parallel port.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>If you want polled mode, do not add the
|
|
<literal>irq</literal> specifier:</para>
|
|
|
|
<programlisting>device lpt0 at isa? port? tty vector lptintr</programlisting>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Save the file. Then configure, build, and install the
|
|
kernel, then reboot. See <link
|
|
linkend="kernelconfig">kernel configuration</link> for
|
|
more details.</para>
|
|
</step>
|
|
</procedure>
|
|
|
|
<para><emphasis>To set the communications mode with</emphasis>
|
|
&man.lptcontrol.8;:</para>
|
|
|
|
<procedure>
|
|
<step>
|
|
<para>Type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>lptcontrol -i -u <replaceable>N</replaceable></userinput></screen>
|
|
|
|
<para>to set interrupt-driven mode for
|
|
<literal>lpt<replaceable>N</replaceable></literal>.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>lptcontrol -p -u <replaceable>N</replaceable></userinput></screen>
|
|
|
|
<para>to set polled-mode for
|
|
<literal>lpt<replaceable>N</replaceable></literal>.</para>
|
|
</step>
|
|
</procedure>
|
|
|
|
<para>You could put these commands in your
|
|
<filename>/etc/rc.local</filename> file to set the mode each
|
|
time your system boots. See &man.lptcontrol.8; for more
|
|
information.</para>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-testing">
|
|
<title>Checking Printer Communications</title>
|
|
|
|
<para>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.</para>
|
|
|
|
<para>To test the printer, we will send some text to it. For
|
|
printers that can immediately print characters sent to them,
|
|
the program &man.lptest.1; is perfect: it generates all 96
|
|
printable ASCII characters in 96 lines.</para>
|
|
|
|
<indexterm><primary>PostScript</primary></indexterm>
|
|
<para>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:</para>
|
|
|
|
<programlisting>%!PS
|
|
100 100 moveto 300 300 lineto stroke
|
|
310 310 moveto /Helvetica findfont 12 scalefont setfont
|
|
(Is this thing working?) show
|
|
showpage</programlisting>
|
|
|
|
<para>The above PostScript code can be placed into a file and
|
|
used as shown in the examples appearing in the following
|
|
sections.</para>
|
|
|
|
<indexterm><primary>PCL</primary></indexterm>
|
|
<note>
|
|
<para>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.</para>
|
|
</note>
|
|
|
|
<sect5 id="printing-checking-parallel">
|
|
<title>Checking a Parallel Printer</title>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>parallel</secondary>
|
|
</indexterm>
|
|
<para>This section tells you how to check if FreeBSD can
|
|
communicate with a printer connected to a parallel
|
|
port.</para>
|
|
|
|
<para><emphasis>To test a printer on a parallel
|
|
port:</emphasis></para>
|
|
|
|
<procedure>
|
|
<step>
|
|
<para>Become root with &man.su.1;.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Send data to the printer.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>If the printer can print plain text, then use
|
|
&man.lptest.1;. Type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>lptest > /dev/lpt<replaceable>N</replaceable></userinput></screen>
|
|
|
|
<para>Where <replaceable>N</replaceable> is the number
|
|
of the parallel port, starting from zero.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>If the printer understands PostScript or other
|
|
printer language, then send a small program to the
|
|
printer. Type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>cat > /dev/lpt<replaceable>N</replaceable></userinput></screen>
|
|
|
|
<para>Then, line by line, type the program
|
|
<emphasis>carefully</emphasis> as you cannot edit a
|
|
line once you have pressed <literal>RETURN</literal>
|
|
or <literal>ENTER</literal>. When you have finished
|
|
entering the program, press
|
|
<literal>CONTROL+D</literal>, or whatever your end
|
|
of file key is.</para>
|
|
|
|
<para>Alternatively, you can put the program in a file
|
|
and type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>cat <replaceable>file</replaceable> > /dev/lpt<replaceable>N</replaceable></userinput></screen>
|
|
|
|
<para>Where <replaceable>file</replaceable> is the
|
|
name of the file containing the program you want to
|
|
send to the printer.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</step>
|
|
</procedure>
|
|
|
|
<para>You should see something print. Do not worry if the
|
|
text does not look right; we will fix such things
|
|
later.</para>
|
|
</sect5>
|
|
|
|
<sect5 id="printing-checking-serial">
|
|
<title>Checking a Serial Printer</title>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>serial</secondary>
|
|
</indexterm>
|
|
<para>This section tells you how to check if FreeBSD can
|
|
communicate with a printer on a serial port.</para>
|
|
|
|
<para><emphasis>To test a printer on a serial
|
|
port:</emphasis></para>
|
|
|
|
<procedure>
|
|
<step>
|
|
<para>Become root with &man.su.1;.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Edit the file <filename>/etc/remote</filename>. Add
|
|
the following entry:</para>
|
|
|
|
<programlisting>printer:dv=/dev/<replaceable>port</replaceable>:br#<replaceable>bps-rate</replaceable>:pa=<replaceable>parity</replaceable></programlisting>
|
|
|
|
<indexterm><primary>bits-per-second</primary></indexterm>
|
|
<indexterm><primary>serial port</primary></indexterm>
|
|
<indexterm><primary>parity</primary></indexterm>
|
|
<para>Where <replaceable>port</replaceable> is the device
|
|
entry for the serial port (<literal>ttyd0</literal>,
|
|
<literal>ttyd1</literal>, etc.),
|
|
<replaceable>bps-rate</replaceable> is the
|
|
bits-per-second rate at which the printer communicates,
|
|
and <replaceable>parity</replaceable> is the parity
|
|
required by the printer (either <literal>even</literal>,
|
|
<literal>odd</literal>, <literal>none</literal>, or
|
|
<literal>zero</literal>).</para>
|
|
|
|
<para>Here is a sample entry for a printer connected via
|
|
a serial line to the third serial port at 19200 bps with
|
|
no parity:</para>
|
|
|
|
<programlisting>printer:dv=/dev/ttyd2:br#19200:pa=none</programlisting>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Connect to the printer with &man.tip.1;.
|
|
Type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>tip printer</userinput></screen>
|
|
|
|
<para>If this step does not work, edit the file
|
|
<filename>/etc/remote</filename> again and try using
|
|
<filename>/dev/cuaa<replaceable>N</replaceable></filename>
|
|
instead of
|
|
<filename>/dev/ttyd<replaceable>N</replaceable></filename>.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Send data to the printer.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>If the printer can print plain text, then use
|
|
&man.lptest.1;. Type:</para>
|
|
|
|
<screen><prompt>~</prompt><userinput>$lptest</userinput></screen>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>If the printer understands PostScript or other
|
|
printer language, then send a small program to the
|
|
printer. Type the program, line by line,
|
|
<emphasis>very carefully</emphasis> 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 <literal>CONTROL+D</literal>.</para>
|
|
|
|
<para>Alternatively, you can put the program in a file
|
|
and type:</para>
|
|
|
|
<screen><prompt>~</prompt><userinput>><replaceable>file</replaceable></userinput></screen>
|
|
|
|
<para>Where <replaceable>file</replaceable> is the
|
|
name of the file containing the program. After
|
|
&man.tip.1; sends the file, press any required
|
|
end-of-file key.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</step>
|
|
</procedure>
|
|
|
|
<para>You should see something print. Do not worry if the
|
|
text does not look right; we will fix that later.</para>
|
|
</sect5>
|
|
</sect4>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-printcap">
|
|
<title>Enabling the Spooler: The <filename>/etc/printcap</filename>
|
|
File</title>
|
|
|
|
<para>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 <application>LPD</application> to control access
|
|
to your printer.</para>
|
|
|
|
<para>You configure <application>LPD</application> by editing the file
|
|
<filename>/etc/printcap</filename>. The
|
|
<application>LPD</application> spooling system
|
|
reads this file each time the spooler is used, so updates to the
|
|
file take immediate effect.</para>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>capabilities</secondary>
|
|
</indexterm>
|
|
<para>The format of the &man.printcap.5; file is straightforward.
|
|
Use your favorite text editor to make changes to
|
|
<filename>/etc/printcap</filename>. The format is identical to
|
|
other capability files like
|
|
<filename>/usr/share/misc/termcap</filename> and
|
|
<filename>/etc/remote</filename>. For complete information
|
|
about the format, see the &man.cgetent.3;.</para>
|
|
|
|
<para>The simple spooler configuration consists of the following
|
|
steps:</para>
|
|
|
|
<procedure>
|
|
<step>
|
|
<para>Pick a name (and a few convenient aliases) for the
|
|
printer, and put them in the
|
|
<filename>/etc/printcap</filename> file; see the
|
|
<link linkend="printing-naming">Naming the Printer</link>
|
|
section for more information on naming.</para>
|
|
</step>
|
|
|
|
<indexterm><primary>header pages</primary></indexterm>
|
|
<step>
|
|
<para>Turn off header pages (which are on by default) by
|
|
inserting the <literal>sh</literal> capability; see the
|
|
<link linkend="printing-no-header-pages">Suppressing Header
|
|
Pages</link> section for more information.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Make a spooling directory, and specify its location with
|
|
the <literal>sd</literal> capability; see the <link
|
|
linkend="printing-spooldir">Making the Spooling
|
|
Directory</link> section for more information.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Set the <filename>/dev</filename> entry to use for the
|
|
printer, and note it in <filename>/etc/printcap</filename>
|
|
with the <literal>lp</literal> capability; see the <link
|
|
linkend="printing-device">Identifying the Printer
|
|
Device</link> for more information. Also, if the printer is
|
|
on a serial port, set up the communication parameters with
|
|
the <literal>fs</literal>, <literal>fc</literal>,
|
|
<literal>xs</literal>, and <literal>xc</literal>
|
|
capabilities; which is discussed in the <link
|
|
linkend="printing-commparam">Configuring Spooler
|
|
Communications Parameters</link> section.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Install a plain text input filter; see the <link
|
|
linkend="printing-textfilter">Installing the Text
|
|
Filter</link> section for details.</para>
|
|
</step>
|
|
|
|
<step>
|
|
<para>Test the setup by printing something with the
|
|
&man.lpr.1; command. More details are available in the
|
|
<link linkend="printing-trying">Trying It Out</link> and
|
|
<link
|
|
linkend="printing-troubleshooting">Troubleshooting</link>
|
|
sections.</para>
|
|
</step>
|
|
</procedure>
|
|
|
|
<note>
|
|
<para>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.</para>
|
|
</note>
|
|
|
|
<para>Users often expect that they can print plain text to any of
|
|
the printers installed on your system. Programs that interface
|
|
to <application>LPD</application> 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 <emphasis>and</emphasis>
|
|
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 <link
|
|
linkend="printing-advanced-if-conversion">Accommodating Plain
|
|
Text Jobs on PostScript Printers</link> tells how to do
|
|
this.</para>
|
|
|
|
<sect4 id="printing-naming">
|
|
<title>Naming the Printer</title>
|
|
|
|
<para>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.</para>
|
|
|
|
<para>At least one of the printers specified in the
|
|
<filename>/etc/printcap</filename> should have the alias
|
|
<literal>lp</literal>. This is the default printer's name.
|
|
If users do not have the <envar>PRINTER</envar> environment
|
|
variable nor specify a printer name on the command line of any
|
|
of the <application>LPD</application> commands,
|
|
then <literal>lp</literal> will be the
|
|
default printer they get to use.</para>
|
|
|
|
<para>Also, it is common practice to make the last alias for a
|
|
printer be a full description of the printer, including make
|
|
and model.</para>
|
|
|
|
<para>Once you have picked a name and some common aliases, put
|
|
them in the <filename>/etc/printcap</filename> 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.</para>
|
|
|
|
<para>In the following example, we start with a skeletal
|
|
<filename>/etc/printcap</filename> that defines two printers
|
|
(a Diablo 630 line printer and a Panasonic KX-P4455 PostScript
|
|
laser printer):</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host rose
|
|
#
|
|
rattan|line|diablo|lp|Diablo 630 Line Printer:
|
|
|
|
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:</programlisting>
|
|
|
|
<para>In this example, the first printer is named
|
|
<literal>rattan</literal> and has as aliases
|
|
<literal>line</literal>, <literal>diablo</literal>,
|
|
<literal>lp</literal>, and <literal>Diablo 630 Line
|
|
Printer</literal>. Since it has the alias
|
|
<literal>lp</literal>, it is also the default printer. The
|
|
second is named <literal>bamboo</literal>, and has as aliases
|
|
<literal>ps</literal>, <literal>PS</literal>,
|
|
<literal>S</literal>, <literal>panasonic</literal>, and
|
|
<literal>Panasonic KX-P4455 PostScript v51.4</literal>.</para>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-no-header-pages">
|
|
<title>Suppressing Header Pages</title>
|
|
<indexterm>
|
|
<primary>printing</primary>
|
|
<secondary>header pages</secondary>
|
|
</indexterm>
|
|
|
|
<para>The <application>LPD</application> spooling system will
|
|
by default print a
|
|
<emphasis>header page</emphasis> 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.</para>
|
|
|
|
<para>To suppress header pages, add the <literal>sh</literal>
|
|
capability to the entry for the printer in
|
|
<filename>/etc/printcap</filename>. Here is an example
|
|
<filename>/etc/printcap</filename> with <literal>sh</literal>
|
|
added:</para>
|
|
|
|
<programlisting>#
|
|
# /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:</programlisting>
|
|
|
|
<para>Note how we used the correct format: the first line starts
|
|
in the leftmost column, and subsequent lines are indented with
|
|
a single TAB. Every line in an entry except the last ends in
|
|
a backslash character.</para>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-spooldir">
|
|
<title>Making the Spooling Directory</title>
|
|
<indexterm><primary>printer spool</primary></indexterm>
|
|
<indexterm><primary>print jobs</primary></indexterm>
|
|
|
|
<para>The next step in the simple spooler setup is to make a
|
|
<emphasis>spooling directory</emphasis>, a directory where
|
|
print jobs reside until they are printed, and where a number
|
|
of other spooler support files live.</para>
|
|
|
|
<para>Because of the variable nature of spooling directories, it
|
|
is customary to put these directories under
|
|
<filename>/var/spool</filename>. It is not necessary to
|
|
backup the contents of spooling directories, either.
|
|
Recreating them is as simple as running &man.mkdir.1;.</para>
|
|
|
|
<para>It is also customary to make the directory with a name
|
|
that is identical to the name of the printer, as shown
|
|
below:</para>
|
|
|
|
<screen>&prompt.root; <userinput>mkdir /var/spool/<replaceable>printer-name</replaceable></userinput></screen>
|
|
|
|
<para>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
|
|
<application>LPD</application>. We
|
|
will do this for our two example printers
|
|
<literal>rattan</literal> and
|
|
<literal>bamboo</literal>:</para>
|
|
|
|
<screen>&prompt.root; <userinput>mkdir /var/spool/lpd</userinput>
|
|
&prompt.root; <userinput>mkdir /var/spool/lpd/rattan</userinput>
|
|
&prompt.root; <userinput>mkdir /var/spool/lpd/bamboo</userinput></screen>
|
|
|
|
<note>
|
|
<para>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:</para>
|
|
|
|
<screen>&prompt.root; <userinput>chown daemon:daemon /var/spool/lpd/rattan</userinput>
|
|
&prompt.root; <userinput>chown daemon:daemon /var/spool/lpd/bamboo</userinput>
|
|
&prompt.root; <userinput>chmod 770 /var/spool/lpd/rattan</userinput>
|
|
&prompt.root; <userinput>chmod 770 /var/spool/lpd/bamboo</userinput></screen>
|
|
</note>
|
|
|
|
<para>Finally, you need to tell <application>LPD</application>
|
|
about these directories
|
|
using the <filename>/etc/printcap</filename> file. You
|
|
specify the pathname of the spooling directory with the
|
|
<literal>sd</literal> capability:</para>
|
|
|
|
<programlisting>#
|
|
# /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:</programlisting>
|
|
|
|
<para>Note that the name of the printer starts in the first
|
|
column but all other entries describing the printer should be
|
|
indented with a tab and each line escaped with a
|
|
backslash.</para>
|
|
|
|
<para>If you do not specify a spooling directory with
|
|
<literal>sd</literal>, the spooling system will use
|
|
<filename>/var/spool/lpd</filename> as a default.</para>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-device">
|
|
<title>Identifying the Printer Device</title>
|
|
|
|
<para>In the <link linkend="printing-dev-ports">Adding
|
|
<filename>/dev</filename> Entries for the Ports</link>
|
|
section, we identified which entry in the
|
|
<filename>/dev</filename> directory FreeBSD will use to
|
|
communicate with the printer. Now, we tell
|
|
<application>LPD</application> 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).</para>
|
|
|
|
<para>List the <filename>/dev</filename> entry pathname in the
|
|
<filename>/etc/printcap</filename> file using the
|
|
<literal>lp</literal> capability.</para>
|
|
|
|
<para>In our running example, let us assume that
|
|
<literal>rattan</literal> is on the first parallel port, and
|
|
<literal>bamboo</literal> is on a sixth serial port; here are
|
|
the additions to <filename>/etc/printcap</filename>:</para>
|
|
|
|
<programlisting>#
|
|
# /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:</programlisting>
|
|
|
|
<para>If you do not specify the <literal>lp</literal> capability
|
|
for a printer in your <filename>/etc/printcap</filename> file,
|
|
<application>LPD</application> uses <filename>/dev/lp</filename>
|
|
as a default.
|
|
<filename>/dev/lp</filename> currently does not exist in
|
|
FreeBSD.</para>
|
|
|
|
<para>If the printer you are installing is connected to a
|
|
parallel port, skip to the section entitled, <link
|
|
linkend="printing-textfilter">Installing the Text
|
|
Filter</link>. Otherwise, be sure to follow the instructions
|
|
in the next section.</para>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-commparam">
|
|
<title>Configuring Spooler Communication Parameters</title>
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>serial</secondary>
|
|
</indexterm>
|
|
|
|
<para>For printers on serial ports, <application>LPD</application>
|
|
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:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>It lets you try different communication parameters by
|
|
simply editing the <filename>/etc/printcap</filename>
|
|
file; you do not have to recompile the filter
|
|
program.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It enables the spooling system to use the same filter
|
|
program for multiple printers which may have different
|
|
serial communication settings.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>The following <filename>/etc/printcap</filename>
|
|
capabilities control serial communication parameters of the
|
|
device listed in the <literal>lp</literal> capability:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><literal>br#<replaceable>bps-rate</replaceable></literal></term>
|
|
|
|
<listitem>
|
|
<para>Sets the communications speed of the device to
|
|
<replaceable>bps-rate</replaceable>, where
|
|
<replaceable>bps-rate</replaceable> can be 50, 75, 110,
|
|
134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600,
|
|
19200, or 38400 bits-per-second.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>fc#<replaceable>clear-bits</replaceable></literal></term>
|
|
|
|
<listitem>
|
|
<para>Clears the flag bits
|
|
<replaceable>clear-bits</replaceable> in the
|
|
<replaceable>sgttyb</replaceable> structure after
|
|
opening the device.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>fs#<replaceable>set-bits</replaceable></literal></term>
|
|
|
|
<listitem>
|
|
<para>Sets the flag bits
|
|
<replaceable>set-bits</replaceable> in the
|
|
<replaceable>sgttyb</replaceable> structure.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>xc#<replaceable>clear-bits</replaceable></literal></term>
|
|
|
|
<listitem>
|
|
<para>Clears local mode bits
|
|
<replaceable>clear-bits</replaceable> after opening the
|
|
device.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>xs#<replaceable>set-bits</replaceable></literal></term>
|
|
|
|
<listitem>
|
|
<para>Sets local mode bits
|
|
<replaceable>set-bits</replaceable>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>For more information on the bits for the
|
|
<literal>fc</literal>, <literal>fs</literal>,
|
|
<literal>xc</literal>, and <literal>xs</literal> capabilities,
|
|
see the file
|
|
<filename>/usr/include/sys/ioctl_compat.h</filename>.</para>
|
|
|
|
<para>When <application>LPD</application> opens the device
|
|
specified by the
|
|
<literal>lp</literal> capability, it reads the flag bits in
|
|
the <literal>sgttyb</literal> structure; it clears any bits in
|
|
the <literal>fc</literal> capability, then sets bits in the
|
|
<literal>fs</literal> capability, then applies the resultant
|
|
setting. It does the same for the local mode bits as
|
|
well.</para>
|
|
|
|
<para>Let us add to our example printer on the sixth serial
|
|
port. We will set the bps rate to 38400. For the flag bits,
|
|
we will set the <literal>TANDEM</literal>,
|
|
<literal>ANYP</literal>, <literal>LITOUT</literal>,
|
|
<literal>FLUSHO</literal>, and <literal>PASS8</literal> flags.
|
|
For the local mode bits, we will set the
|
|
<literal>LITOUT</literal> and <literal>PASS8</literal>
|
|
flags:</para>
|
|
|
|
<programlisting>bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
|
|
:sh:sd=/var/spool/lpd/bamboo:\
|
|
:lp=/dev/ttyd5:fs#0x82000c1:xs#0x820:</programlisting>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-textfilter">
|
|
<title>Installing the Text Filter</title>
|
|
<indexterm><primary>print filters</primary></indexterm>
|
|
|
|
<para>We are now ready to tell <application>LPD</application>
|
|
what text filter to use to
|
|
send jobs to the printer. A <emphasis>text filter</emphasis>,
|
|
also known as an <emphasis>input filter</emphasis>, is a
|
|
program that <application>LPD</application> runs when it
|
|
has a job to print. When <application>LPD</application>
|
|
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 <literal>lp</literal>
|
|
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 <link linkend="printing-advanced-filters">Filters</link>
|
|
section.</para>
|
|
|
|
<para>For our simple printer setup, the text filter can be a
|
|
small shell script that just executes
|
|
<command>/bin/cat</command> to send the job to the printer.
|
|
FreeBSD comes with another filter called
|
|
<filename>lpf</filename> 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 <command>lpf</command> is
|
|
described in detail in section entitled <link
|
|
linkend="printing-advanced-lpf">lpf: a Text
|
|
Filter</link>.</para>
|
|
|
|
<para>First, let us make the shell script
|
|
<filename>/usr/local/libexec/if-simple</filename> be a simple
|
|
text filter. Put the following text into that file with your
|
|
favorite text editor:</para>
|
|
|
|
<programlisting>#!/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</programlisting>
|
|
|
|
<para>Make the file executable:</para>
|
|
|
|
<screen>&prompt.root; <userinput>chmod 555 /usr/local/libexec/if-simple</userinput></screen>
|
|
|
|
<para>And then tell LPD to use it by specifying it with the
|
|
<literal>if</literal> capability in
|
|
<filename>/etc/printcap</filename>. We will add it to the two
|
|
printers we have so far in the example
|
|
<filename>/etc/printcap</filename>:</para>
|
|
|
|
<programlisting>#
|
|
# /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:fs#0x82000e1:xs#0x820:\
|
|
:if=/usr/local/libexec/if-simple:</programlisting>
|
|
</sect4>
|
|
|
|
<sect4>
|
|
<title>Turn on <application>LPD</application></title>
|
|
|
|
<para>&man.lpd.8; is run from <filename>/etc/rc</filename>,
|
|
controlled by the <literal>lpd_enable</literal> variable. This
|
|
variable defaults to <literal>NO</literal>. If you have not done
|
|
so already, add the line:</para>
|
|
|
|
<programlisting>lpd_enable="YES"</programlisting>
|
|
|
|
<para>to <filename>/etc/rc.conf</filename>, and then either restart
|
|
your machine, or just run &man.lpd.8;.</para>
|
|
|
|
<screen>&prompt.root; <userinput>lpd</userinput></screen>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-trying">
|
|
<title>Trying It Out</title>
|
|
|
|
<para>You have reached the end of the simple
|
|
<application>LPD</application> 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 <application>LPD</application> system, you
|
|
use the command &man.lpr.1;,
|
|
which submits a job for printing.</para>
|
|
|
|
<para>You can combine &man.lpr.1; with the &man.lptest.1;
|
|
program, introduced in section <link
|
|
linkend="printing-testing">Checking Printer
|
|
Communications</link> to generate some test text.</para>
|
|
|
|
<para><emphasis>To test the simple <application>LPD</application>
|
|
setup:</emphasis></para>
|
|
|
|
<para>Type:</para>
|
|
|
|
<screen>&prompt.root; <userinput>lptest 20 5 | lpr -P<replaceable>printer-name</replaceable></userinput></screen>
|
|
|
|
<para>Where <replaceable>printer-name</replaceable> is a the
|
|
name of a printer (or an alias) specified in
|
|
<filename>/etc/printcap</filename>. To test the default
|
|
printer, type &man.lpr.1; without any <option>-P</option>
|
|
argument. Again, if you are testing a printer that expects
|
|
PostScript, send a PostScript program in that language instead
|
|
of using &man.lptest.1;. You can do so by putting the program
|
|
in a file and typing <command>lpr
|
|
<replaceable>file</replaceable></command>.</para>
|
|
|
|
<para>For a PostScript printer, you should get the results of
|
|
the program. If you are using &man.lptest.1;, then your
|
|
results should look like the following:</para>
|
|
|
|
<programlisting>!"#$%&'()*+,-./01234
|
|
"#$%&'()*+,-./012345
|
|
#$%&'()*+,-./0123456
|
|
$%&'()*+,-./01234567
|
|
%&'()*+,-./012345678</programlisting>
|
|
|
|
<para>To further test the printer, try downloading larger
|
|
programs (for language-based printers) or running
|
|
&man.lptest.1; with different arguments. For example,
|
|
<command>lptest 80 60</command> will produce 60 lines of 80
|
|
characters each.</para>
|
|
|
|
<para>If the printer did not work, see the <link
|
|
linkend="printing-troubleshooting">Troubleshooting</link>
|
|
section.</para>
|
|
</sect4>
|
|
</sect3>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="printing-advanced">
|
|
<title>Advanced Printer Setup</title>
|
|
|
|
<para>This section describes filters for printing specially formatted
|
|
files, header pages, printing across networks, and restricting and
|
|
accounting for printer usage.</para>
|
|
|
|
<sect2 id="printing-advanced-filter-intro">
|
|
<title>Filters</title>
|
|
<indexterm><primary>print filters</primary></indexterm>
|
|
|
|
<para>Although <application>LPD</application> handles network protocols,
|
|
queuing, access control,
|
|
and other aspects of printing, most of the <emphasis>real</emphasis>
|
|
work happens in the <emphasis>filters</emphasis>. Filters are
|
|
programs that communicate with the printer and handle its device
|
|
dependencies and special requirements. In the simple printer setup,
|
|
we installed a plain text filter—an extremely simple one that
|
|
should work with most printers (section <link
|
|
linkend="printing-textfilter">Installing the Text
|
|
Filter</link>).</para>
|
|
|
|
<para>However, in order to take advantage of format conversion, printer
|
|
accounting, specific printer quirks, and so on, you should understand
|
|
how filters work. It will ultimately be the filter's responsibility
|
|
to handle these aspects. And the bad news is that most of the time
|
|
<emphasis>you</emphasis> have to provide filters yourself. The good
|
|
news is that many are generally available; when they are not, they are
|
|
usually easy to write.</para>
|
|
|
|
<para>Also, FreeBSD comes with one,
|
|
<filename>/usr/libexec/lpr/lpf</filename>, that works with many
|
|
printers that can print plain text. (It handles backspacing and tabs
|
|
in the file, and does accounting, but that is about all it does.)
|
|
There are also several filters and filter components in the FreeBSD
|
|
Ports Collection.</para>
|
|
|
|
<para>Here is what you will find in this section:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Section <link linkend="printing-advanced-filters">How Filters
|
|
Work</link>, tries to give an overview of a filter's role in the
|
|
printing process. You should read this section to get an
|
|
understanding of what is happening <quote>under the hood</quote>
|
|
when <application>LPD</application> uses filters. This knowledge
|
|
could help you anticipate
|
|
and debug problems you might encounter as you install more and
|
|
more filters on each of your printers.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><application>LPD</application> expects every printer to be
|
|
able to print plain text by
|
|
default. This presents a problem for PostScript (or other
|
|
language-based printers) which cannot directly print plain text.
|
|
Section <link
|
|
linkend="printing-advanced-if-conversion">Accommodating
|
|
Plain Text Jobs on PostScript Printers</link> tells you what you
|
|
should do to overcome this problem. You should read this
|
|
section if you have a PostScript printer.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>PostScript is a popular output format for many programs. Even
|
|
some people (myself included) write PostScript code directly. But
|
|
PostScript printers are expensive. Section <link
|
|
linkend="printing-advanced-ps">Simulating PostScript on
|
|
Non-PostScript Printers</link> tells how you can further modify
|
|
a printer's text filter to accept and print PostScript data on a
|
|
<emphasis>non-PostScript</emphasis> printer. You should read
|
|
this section if you do not have a PostScript printer.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Section <link
|
|
linkend="printing-advanced-convfilters">Conversion
|
|
Filters</link> tells about a way you can automate the conversion
|
|
of specific file formats, such as graphic or typesetting data,
|
|
into formats your printer can understand. After reading this
|
|
section, you should be able to set up your printers such that
|
|
users can type <command>lpr -t</command> to print troff data, or
|
|
<command>lpr -d</command> to print TeX DVI data, or <command>lpr
|
|
-v</command> to print raster image data, and so forth. I
|
|
recommend reading this section.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Section <link linkend="printing-advanced-of">Output
|
|
Filters</link> tells all about a not often used feature of
|
|
<application>LPD</application>:
|
|
output filters. Unless you are printing header pages (see <link
|
|
linkend="printing-advanced-header-pages">Header Pages</link>),
|
|
you can probably skip that section altogether.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Section <link linkend="printing-advanced-lpf">lpf: a Text
|
|
Filter</link> describes <command>lpf</command>, a fairly
|
|
complete if simple text filter for line printers (and laser
|
|
printers that act like line printers) that comes with FreeBSD. If
|
|
you need a quick way to get printer accounting working for plain
|
|
text, or if you have a printer which emits smoke when it sees
|
|
backspace characters, you should definitely consider
|
|
<command>lpf</command>.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<sect3 id="printing-advanced-filters">
|
|
<title>How Filters Work</title>
|
|
|
|
<para>As mentioned before, a filter is an executable program started
|
|
by <application>LPD</application> to handle the device-dependent part of
|
|
communicating with the printer.</para>
|
|
|
|
<para>When <application>LPD</application> wants to print a file in a
|
|
job, it starts a filter
|
|
program. It sets the filter's standard input to the file to print,
|
|
its standard output to the printer, and its standard error to the
|
|
error logging file (specified in the <literal>lf</literal>
|
|
capability in <filename>/etc/printcap</filename>, or
|
|
<filename>/dev/console</filename> by default).</para>
|
|
|
|
<indexterm>
|
|
<primary><command>troff</command></primary>
|
|
</indexterm>
|
|
<para>Which filter <application>LPD</application> starts and the
|
|
filter's arguments depend on
|
|
what is listed in the <filename>/etc/printcap</filename> file and
|
|
what arguments the user specified for the job on the
|
|
&man.lpr.1; command line. For example, if the user typed
|
|
<command>lpr -t</command>, <application>LPD</application> would
|
|
start the troff filter, listed
|
|
in the <literal>tf</literal> capability for the destination printer.
|
|
If the user wanted to print plain text, it would start the
|
|
<literal>if</literal> filter (this is mostly true: see <link
|
|
linkend="printing-advanced-of">Output Filters</link> for
|
|
details).</para>
|
|
|
|
<para>There are three kinds of filters you can specify in
|
|
<filename>/etc/printcap</filename>:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>The <emphasis>text filter</emphasis>, confusingly called the
|
|
<emphasis>input filter</emphasis> in
|
|
<application>LPD</application> documentation, handles
|
|
regular text printing. Think of it as the default filter.
|
|
<application>LPD</application>
|
|
expects every printer to be able to print plain text by default,
|
|
and it is the text filter's job to make sure backspaces, tabs,
|
|
or other special characters do not confuse the printer. If you
|
|
are in an environment where you have to account for printer
|
|
usage, the text filter must also account for pages printed,
|
|
usually by counting the number of lines printed and comparing
|
|
that to the number of lines per page the printer supports. The
|
|
text filter is started with the following argument list:
|
|
|
|
<cmdsynopsis>
|
|
<command>filter-name</command>
|
|
<arg>-c</arg>
|
|
<arg choice="plain">-w<replaceable>width</replaceable></arg>
|
|
<arg choice="plain">-l<replaceable>length</replaceable></arg>
|
|
<arg choice="plain">-i<replaceable>indent</replaceable></arg>
|
|
<arg choice="plain">-n <replaceable>login</replaceable></arg>
|
|
<arg choice="plain">-h <replaceable>host</replaceable></arg>
|
|
<arg choice="plain"><replaceable>acct-file</replaceable></arg>
|
|
</cmdsynopsis>
|
|
|
|
where
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>-c</option></term>
|
|
|
|
<listitem>
|
|
<para>appears if the job is submitted with <command>lpr
|
|
-l</command></para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><replaceable>width</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>is the value from the <literal>pw</literal> (page
|
|
width) capability specified in
|
|
<filename>/etc/printcap</filename>, default 132</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><replaceable>length</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>is the value from the <literal>pl</literal> (page
|
|
length) capability, default 66</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><replaceable>indent</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>is the amount of the indentation from <command>lpr
|
|
-i</command>, default 0</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><replaceable>login</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>is the account name of the user printing the
|
|
file</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><replaceable>host</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>is the host name from which the job was
|
|
submitted</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><replaceable>acct-file</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>is the name of the accounting file from the
|
|
<literal>af</literal> capability.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</listitem>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>filters</secondary>
|
|
</indexterm>
|
|
<listitem>
|
|
<para>A <emphasis>conversion filter</emphasis> converts a specific
|
|
file format into one the printer can render onto paper. For
|
|
example, ditroff typesetting data cannot be directly printed,
|
|
but you can install a conversion filter for ditroff files to
|
|
convert the ditroff data into a form the printer can digest and
|
|
print. Section <link
|
|
linkend="printing-advanced-convfilters">Conversion
|
|
Filters</link> tells all about them. Conversion filters also
|
|
need to do accounting, if you need printer accounting.
|
|
Conversion filters are started with the following arguments:
|
|
|
|
<cmdsynopsis>
|
|
<command>filter-name</command>
|
|
<arg
|
|
choice="plain">-x<replaceable>pixel-width</replaceable></arg>
|
|
<arg choice="plain">-y<replaceable>pixel-height</replaceable></arg>
|
|
<arg choice="plain">-n <replaceable>login</replaceable></arg>
|
|
<arg choice="plain">-h <replaceable>host</replaceable></arg>
|
|
<arg choice="plain"><replaceable>acct-file</replaceable></arg>
|
|
</cmdsynopsis>
|
|
|
|
where <replaceable>pixel-width</replaceable> is the value
|
|
from the <literal>px</literal> capability (default 0) and
|
|
<replaceable>pixel-height</replaceable> is the value from the
|
|
<literal>py</literal> capability (default 0).</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The <emphasis>output filter</emphasis> is used only if there
|
|
is no text filter, or if header pages are enabled. In my
|
|
experience, output filters are rarely used. Section <link
|
|
linkend="printing-advanced-of">Output Filters</link> describe
|
|
them. There are only two arguments to an output filter:
|
|
|
|
<cmdsynopsis>
|
|
<command>filter-name</command>
|
|
<arg choice="plain">-w<replaceable>width</replaceable></arg>
|
|
<arg choice="plain">-l<replaceable>length</replaceable></arg>
|
|
</cmdsynopsis>
|
|
|
|
which are identical to the text filters <option>-w</option> and
|
|
<option>-l</option> arguments.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Filters should also <emphasis>exit</emphasis> with the
|
|
following exit status:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>exit 0</term>
|
|
|
|
<listitem>
|
|
<para>If the filter printed the file successfully.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>exit 1</term>
|
|
|
|
<listitem>
|
|
<para>If the filter failed to print the file but wants
|
|
<application>LPD</application> to
|
|
try to print the file again. <application>LPD</application>
|
|
will restart a filter if it exits with this status.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>exit 2</term>
|
|
|
|
<listitem>
|
|
<para>If the filter failed to print the file and does not want
|
|
<application>LPD</application> to try again.
|
|
<application>LPD</application> will throw out the file.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>The text filter that comes with the FreeBSD release,
|
|
<filename>/usr/libexec/lpr/lpf</filename>, takes advantage of the
|
|
page width and length arguments to determine when to send a form
|
|
feed and how to account for printer usage. It uses the login, host,
|
|
and accounting file arguments to make the accounting entries.</para>
|
|
|
|
<para>If you are shopping for filters, see if they are LPD-compatible.
|
|
If they are, they must support the argument lists described above.
|
|
If you plan on writing filters for general use, then have them
|
|
support the same argument lists and exit codes.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-if-conversion">
|
|
<title>Accommodating Plain Text Jobs on PostScript Printers</title>
|
|
<indexterm><primary>print jobs</primary></indexterm>
|
|
|
|
<para>If you are the only user of your computer and PostScript (or
|
|
other language-based) printer, and you promise to never send plain
|
|
text to your printer and to never use features of various programs
|
|
that will want to send plain text to your printer, then you do not
|
|
need to worry about this section at all.</para>
|
|
|
|
<para>But, if you would like to send both PostScript and plain text
|
|
jobs to the printer, then you are urged to augment your printer
|
|
setup. To do so, we have the text filter detect if the arriving job
|
|
is plain text or PostScript. All PostScript jobs must start with
|
|
<literal>%!</literal> (for other printer languages, see your printer
|
|
documentation). If those are the first two characters in the job,
|
|
we have PostScript, and can pass the rest of the job directly. If
|
|
those are not the first two characters in the file, then the filter
|
|
will convert the text into PostScript and print the result.</para>
|
|
|
|
<para>How do we do this?</para>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>serial</secondary>
|
|
</indexterm>
|
|
<para>If you have got a serial printer, a great way to do it is to
|
|
install <command>lprps</command>. <command>lprps</command> is a
|
|
PostScript printer filter which performs two-way communication with
|
|
the printer. It updates the printer's status file with verbose
|
|
information from the printer, so users and administrators can see
|
|
exactly what the state of the printer is (such as <errorname>toner
|
|
low</errorname> or <errorname>paper jam</errorname>). But more
|
|
importantly, it includes a program called <command>psif</command>
|
|
which detects whether the incoming job is plain text and calls
|
|
<command>textps</command> (another program that comes with
|
|
<command>lprps</command>) to convert it to PostScript. It then uses
|
|
<command>lprps</command> to send the job to the printer.</para>
|
|
|
|
<para><command>lprps</command> is part of the FreeBSD Ports Collection
|
|
(see <link linkend="ports">The Ports Collection</link>). You can
|
|
fetch, build and install it yourself, of course. After installing
|
|
<command>lprps</command>, just specify the pathname to the
|
|
<command>psif</command> program that is part of
|
|
<command>lprps</command>. If you installed <command>lprps</command>
|
|
from the ports collection, use the following in the serial
|
|
PostScript printer's entry in
|
|
<filename>/etc/printcap</filename>:</para>
|
|
|
|
<programlisting>:if=/usr/local/libexec/psif:</programlisting>
|
|
|
|
<para>You should also specify the <literal>rw</literal> capability;
|
|
that tells <application>LPD</application> to open the printer in
|
|
read-write mode.</para>
|
|
|
|
<para>If you have a parallel PostScript printer (and therefore cannot
|
|
use two-way communication with the printer, which
|
|
<command>lprps</command> needs), you can use the following shell
|
|
script as the text filter:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# psif - Print PostScript or plain text on a PostScript printer
|
|
# Script version; NOT the version that comes with lprps
|
|
# Installed in /usr/local/libexec/psif
|
|
#
|
|
|
|
read first_line
|
|
first_two_chars=`expr "$first_line" : '\(..\)'`
|
|
|
|
if [ "$first_two_chars" = "%!" ]; then
|
|
#
|
|
# PostScript job, print it.
|
|
#
|
|
echo "$first_line" && cat && printf "\004" && exit 0
|
|
exit 2
|
|
else
|
|
#
|
|
# Plain text, convert it, then print it.
|
|
#
|
|
( echo "$first_line"; cat ) | /usr/local/bin/textps && printf "\004" && exit 0
|
|
exit 2
|
|
fi</programlisting>
|
|
|
|
<para>In the above script, <command>textps</command> is a program we
|
|
installed separately to convert plain text to PostScript. You can
|
|
use any text-to-PostScript program you wish. The FreeBSD Ports
|
|
Collection (see <link linkend="ports">The Ports Collection</link>)
|
|
includes a full featured text-to-PostScript program called
|
|
<literal>a2ps</literal> that you might want to investigate.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-ps">
|
|
<title>Simulating PostScript on Non-PostScript Printers</title>
|
|
<indexterm>
|
|
<primary>PostScript</primary>
|
|
<secondary>emulating</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>Ghostscript</primary></indexterm>
|
|
<para>PostScript is the <emphasis>de facto</emphasis> standard for
|
|
high quality typesetting and printing. PostScript is, however, an
|
|
<emphasis>expensive</emphasis> standard. Thankfully, Alladin
|
|
Enterprises has a free PostScript work-alike called
|
|
<application>Ghostscript</application> that runs with FreeBSD.
|
|
Ghostscript can read most PostScript files and can render their
|
|
pages onto a variety of devices, including many brands of
|
|
non-PostScript printers. By installing Ghostscript and using a
|
|
special text filter for your printer, you can make your
|
|
non-PostScript printer act like a real PostScript printer.</para>
|
|
|
|
<para>Ghostscript is in the FreeBSD Ports Collection, if you
|
|
would like to install it from there. You can fetch, build, and
|
|
install it quite easily yourself, as well.</para>
|
|
|
|
<para>To simulate PostScript, we have the text filter detect if it is
|
|
printing a PostScript file. If it is not, then the filter will pass
|
|
the file directly to the printer; otherwise, it will use Ghostscript
|
|
to first convert the file into a format the printer will
|
|
understand.</para>
|
|
|
|
<para>Here is an example: the following script is a text filter
|
|
for Hewlett Packard DeskJet 500 printers. For other printers,
|
|
substitute the <option>-sDEVICE</option> argument to the
|
|
<command>gs</command> (Ghostscript) command. (Type <command>gs
|
|
-h</command> to get a list of devices the current installation of
|
|
Ghostscript supports.)</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# ifhp - Print Ghostscript-simulated PostScript on a DeskJet 500
|
|
# Installed in /usr/local/libexec/hpif
|
|
|
|
#
|
|
# Treat LF as CR+LF:
|
|
#
|
|
printf "\033&k2G" || exit 2
|
|
|
|
#
|
|
# Read first two characters of the file
|
|
#
|
|
read first_line
|
|
first_two_chars=`expr "$first_line" : '\(..\)'`
|
|
|
|
if [ "$first_two_chars" = "%!" ]; then
|
|
#
|
|
# It is PostScript; use Ghostscript to scan-convert and print it.
|
|
#
|
|
# Note that PostScript files are actually interpreted programs,
|
|
# and those programs are allowed to write to stdout, which will
|
|
# mess up the printed output. So, we redirect stdout to stderr
|
|
# and then make descriptor 3 go to stdout, and have Ghostscript
|
|
# write its output there. Exercise for the clever reader:
|
|
# capture the stderr output from Ghostscript and mail it back to
|
|
# the user originating the print job.
|
|
#
|
|
exec 3>&1 1>&2
|
|
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
|
|
-sOutputFile=/dev/fd/3 - && exit 0
|
|
|
|
#
|
|
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 -sOutputFile=- - \
|
|
&& exit 0
|
|
else
|
|
#
|
|
# Plain text or HP/PCL, so just print it directly; print a form feed
|
|
# at the end to eject the last page.
|
|
#
|
|
echo $first_line && cat && printf "\033&l0H" &&
|
|
exit 0
|
|
fi
|
|
|
|
exit 2</programlisting>
|
|
|
|
<para>Finally, you need to notify <application>LPD</application> of
|
|
the filter via the <literal>if</literal> capability:</para>
|
|
|
|
<programlisting>:if=/usr/local/libexec/hpif:</programlisting>
|
|
|
|
<para>That is it. You can type <command>lpr plain.text</command> and
|
|
<filename>lpr whatever.ps</filename> and both should print
|
|
successfully.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-convfilters">
|
|
<title>Conversion Filters</title>
|
|
|
|
<para>After completing the simple setup described in <link
|
|
linkend="printing-simple">Simple Printer Setup</link>, the first
|
|
thing you will probably want to do is install conversion filters for
|
|
your favorite file formats (besides plain ASCII text).</para>
|
|
|
|
<sect4>
|
|
<title>Why Install Conversion Filters?</title>
|
|
<indexterm>
|
|
<primary>TeX</primary>
|
|
<secondary>printing dvi files</secondary>
|
|
</indexterm>
|
|
|
|
<para>Conversion filters make printing various kinds of files easy.
|
|
As an example, suppose we do a lot of work with the TeX
|
|
typesetting system, and we have a PostScript printer. Every time
|
|
we generate a DVI file from TeX, we cannot print it directly until
|
|
we convert the DVI file into PostScript. The command sequence
|
|
goes like this:</para>
|
|
|
|
<screen>&prompt.user; <userinput>dvips seaweed-analysis.dvi</userinput>
|
|
&prompt.user; <userinput>lpr seaweed-analysis.ps</userinput></screen>
|
|
|
|
<para>By installing a conversion filter for DVI files, we can skip
|
|
the hand conversion step each time by having
|
|
<application>LPD</application> do it for us.
|
|
Now, each time we get a DVI file, we are just one step away from
|
|
printing it:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lpr -d seaweed-analysis.dvi</userinput></screen>
|
|
|
|
<para>We got <application>LPD</application> to do the DVI file
|
|
conversion for us by specifying
|
|
the <option>-d</option> option. Section <link
|
|
linkend="printing-lpr-options-format">Formatting and Conversion
|
|
Options</link> lists the conversion options.</para>
|
|
|
|
<para>For each of the conversion options you want a printer to
|
|
support, install a <emphasis>conversion filter</emphasis> and
|
|
specify its pathname in <filename>/etc/printcap</filename>. A
|
|
conversion filter is like the text filter for the simple printer
|
|
setup (see section <link linkend="printing-textfilter">Installing
|
|
the Text Filter</link>) except that instead of printing plain
|
|
text, the filter converts the file into a format the printer can
|
|
understand.</para>
|
|
</sect4>
|
|
|
|
<sect4>
|
|
<title>Which Conversions Filters Should I Install?</title>
|
|
|
|
<para>You should install the conversion filters you expect to use.
|
|
If you print a lot of DVI data, then a DVI conversion filter is in
|
|
order. If you have got plenty of troff to print out, then you
|
|
probably want a troff filter.</para>
|
|
|
|
<para>The following table summarizes the filters that
|
|
<application>LPD</application> works
|
|
with, their capability entries for the
|
|
<filename>/etc/printcap</filename> file, and how to invoke them
|
|
with the <command>lpr</command> command:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>File type</entry>
|
|
<entry><filename>/etc/printcap</filename> capability</entry>
|
|
<entry><command>lpr</command> option</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry>cifplot</entry>
|
|
<entry><literal>cf</literal></entry>
|
|
<entry><option>-c</option></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>DVI</entry>
|
|
<entry><literal>df</literal></entry>
|
|
<entry><option>-d</option></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>plot</entry>
|
|
<entry><literal>gf</literal></entry>
|
|
<entry><option>-g</option></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>ditroff</entry>
|
|
<entry><literal>nf</literal></entry>
|
|
<entry><option>-n</option></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>FORTRAN text</entry>
|
|
<entry><literal>rf</literal></entry>
|
|
<entry><option>-f</option></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>troff</entry>
|
|
<entry><literal>rf</literal></entry>
|
|
<entry><option>-f</option></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>raster</entry>
|
|
<entry><literal>vf</literal></entry>
|
|
<entry><option>-v</option></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>plain text</entry>
|
|
<entry><literal>if</literal></entry>
|
|
<entry>none, <option>-p</option>, or
|
|
<option>-l</option></entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>In our example, using <command>lpr -d</command> means the
|
|
printer needs a <literal>df</literal> capability in its entry in
|
|
<filename>/etc/printcap</filename>.</para>
|
|
|
|
<indexterm><primary>fortran</primary></indexterm>
|
|
<para>Despite what others might contend, formats like FORTRAN text
|
|
and plot are probably obsolete. At your site, you can give new
|
|
meanings to these or any of the formatting options just by
|
|
installing custom filters. For example, suppose you would like to
|
|
directly print Printerleaf files (files from the Interleaf desktop
|
|
publishing program), but will never print plot files. You could
|
|
install a Printerleaf conversion filter under the
|
|
<literal>gf</literal> capability and then educate your users that
|
|
<command>lpr -g</command> mean <quote>print Printerleaf
|
|
files.</quote></para>
|
|
</sect4>
|
|
|
|
<sect4>
|
|
<title>Installing Conversion Filters</title>
|
|
|
|
<para>Since conversion filters are programs you install outside of
|
|
the base FreeBSD installation, they should probably go under
|
|
<filename>/usr/local</filename>. The directory
|
|
<filename>/usr/local/libexec</filename> is a popular location,
|
|
since they are specialized programs that only
|
|
<application>LPD</application> will run;
|
|
regular users should not ever need to run them.</para>
|
|
|
|
<para>To enable a conversion filter, specify its pathname under the
|
|
appropriate capability for the destination printer in
|
|
<filename>/etc/printcap</filename>.</para>
|
|
|
|
<para>In our example, we will add the DVI conversion filter to the
|
|
entry for the printer named <literal>bamboo</literal>. Here is
|
|
the example <filename>/etc/printcap</filename> file again, with
|
|
the new <literal>df</literal> capability for the printer
|
|
<literal>bamboo</literal>.</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host rose - added df filter for bamboo
|
|
#
|
|
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:fs#0x82000e1:xs#0x820:rw:\
|
|
:if=/usr/local/libexec/psif:\
|
|
:df=/usr/local/libexec/psdf:</programlisting>
|
|
|
|
<para>The DVI filter is a shell script named
|
|
<filename>/usr/local/libexec/psdf</filename>. Here is that
|
|
script:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# psdf - DVI to PostScript printer filter
|
|
# Installed in /usr/local/libexec/psdf
|
|
#
|
|
# Invoked by lpd when user runs lpr -d
|
|
#
|
|
exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@"</programlisting>
|
|
|
|
<para>This script runs <command>dvips</command> in filter mode (the
|
|
<option>-f</option> argument) on standard input, which is the job
|
|
to print. It then starts the PostScript printer filter
|
|
<command>lprps</command> (see section <link
|
|
linkend="printing-advanced-if-conversion">Accommodating Plain
|
|
Text Jobs on PostScript Printers</link>) with the arguments
|
|
<application>LPD</application>
|
|
passed to this script. <command>lprps</command> will use those
|
|
arguments to account for the pages printed.</para>
|
|
</sect4>
|
|
|
|
<sect4>
|
|
<title>More Conversion Filter Examples</title>
|
|
|
|
<para>Since there is no fixed set of steps to install conversion
|
|
filters, let me instead provide more examples. Use these as
|
|
guidance to making your own filters. Use them directly, if
|
|
appropriate.</para>
|
|
|
|
<para>This example script is a raster (well, GIF file, actually)
|
|
conversion filter for a Hewlett Packard LaserJet III-Si
|
|
printer:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# hpvf - Convert GIF files into HP/PCL, then print
|
|
# Installed in /usr/local/libexec/hpvf
|
|
|
|
PATH=/usr/X11R6/bin:$PATH; export PATH
|
|
giftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \
|
|
&& exit 0 \
|
|
|| exit 2</programlisting>
|
|
|
|
<para>It works by converting the GIF file into a portable anymap,
|
|
converting that into a portable graymap, converting that into a
|
|
portable bitmap, and converting that into LaserJet/PCL-compatible
|
|
data.</para>
|
|
|
|
<para>Here is the <filename>/etc/printcap</filename> file with an
|
|
entry for a printer using the above filter:</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host orchid
|
|
#
|
|
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
|
|
:lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\
|
|
:if=/usr/local/libexec/hpif:\
|
|
:vf=/usr/local/libexec/hpvf:</programlisting>
|
|
|
|
<para>The following script is a conversion filter for troff data
|
|
from the groff typesetting system for the PostScript printer named
|
|
<literal>bamboo</literal>:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# pstf - Convert groff's troff data into PS, then print.
|
|
# Installed in /usr/local/libexec/pstf
|
|
#
|
|
exec grops | /usr/local/libexec/lprps "$@"</programlisting>
|
|
|
|
<para>The above script makes use of <command>lprps</command> again
|
|
to handle the communication with the printer. If the printer were
|
|
on a parallel port, we would use this script instead:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# pstf - Convert groff's troff data into PS, then print.
|
|
# Installed in /usr/local/libexec/pstf
|
|
#
|
|
exec grops</programlisting>
|
|
|
|
<para>That is it. Here is the entry we need to add to
|
|
<filename>/etc/printcap</filename> to enable the filter:</para>
|
|
|
|
<programlisting>:tf=/usr/local/libexec/pstf:</programlisting>
|
|
|
|
<para>Here is an example that might make old hands at FORTRAN blush.
|
|
It is a FORTRAN-text filter for any printer that can directly
|
|
print plain text. We will install it for the printer
|
|
<literal>teak</literal>:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# hprf - FORTRAN text filter for LaserJet 3si:
|
|
# Installed in /usr/local/libexec/hprf
|
|
#
|
|
|
|
printf "\033&k2G" && fpr && printf "\033&l0H" &&
|
|
exit 0
|
|
exit 2</programlisting>
|
|
|
|
<para>And we will add this line to the
|
|
<filename>/etc/printcap</filename> for the printer
|
|
<literal>teak</literal> to enable this filter:</para>
|
|
|
|
<programlisting>:rf=/usr/local/libexec/hprf:</programlisting>
|
|
|
|
<para>Here is one final, somewhat complex example. We will add a
|
|
DVI filter to the LaserJet printer <literal>teak</literal>
|
|
introduced earlier. First, the easy part: updating
|
|
<filename>/etc/printcap</filename> with the location of the DVI
|
|
filter:</para>
|
|
|
|
<programlisting>:df=/usr/local/libexec/hpdf:</programlisting>
|
|
|
|
<para>Now, for the hard part: making the filter. For that, we need
|
|
a DVI-to-LaserJet/PCL conversion program. The FreeBSD Ports
|
|
Collection (see <link linkend="ports">The Ports Collection</link>)
|
|
has one: <command>dvi2xx</command> is the name of the package.
|
|
Installing this package gives us the program we need,
|
|
<command>dvilj2p</command>, which converts DVI into LaserJet IIp,
|
|
LaserJet III, and LaserJet 2000 compatible codes.</para>
|
|
|
|
<para><command>dvilj2p</command> makes the filter
|
|
<command>hpdf</command> quite complex since
|
|
<command>dvilj2p</command> cannot read from standard input. It
|
|
wants to work with a filename. What is worse, the filename has to
|
|
end in <filename>.dvi</filename> so using
|
|
<filename>/dev/fd/0</filename> for standard input is problematic.
|
|
We can get around that problem by linking (symbolically) a
|
|
temporary file name (one that ends in <filename>.dvi</filename>)
|
|
to <filename>/dev/fd/0</filename>, thereby forcing
|
|
<command>dvilj2p</command> to read from standard input.</para>
|
|
|
|
<para>The only other fly in the ointment is the fact that we cannot
|
|
use <filename>/tmp</filename> for the temporary link. Symbolic
|
|
links are owned by user and group <username>bin</username>. The
|
|
filter runs as user <username>daemon</username>. And the
|
|
<filename>/tmp</filename> directory has the sticky bit set. The
|
|
filter can create the link, but it will not be able clean up when
|
|
done and remove it since the link will belong to a different
|
|
user.</para>
|
|
|
|
<para>Instead, the filter will make the symbolic link in the current
|
|
working directory, which is the spooling directory (specified by
|
|
the <literal>sd</literal> capability in
|
|
<filename>/etc/printcap</filename>). This is a perfect place for
|
|
filters to do their work, especially since there is (sometimes)
|
|
more free disk space in the spooling directory than under
|
|
<filename>/tmp</filename>.</para>
|
|
|
|
<para>Here, finally, is the filter:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# hpdf - Print DVI data on HP/PCL printer
|
|
# Installed in /usr/local/libexec/hpdf
|
|
|
|
PATH=/usr/local/bin:$PATH; export PATH
|
|
|
|
#
|
|
# Define a function to clean up our temporary files. These exist
|
|
# in the current directory, which will be the spooling directory
|
|
# for the printer.
|
|
#
|
|
cleanup() {
|
|
rm -f hpdf$$.dvi
|
|
}
|
|
|
|
#
|
|
# Define a function to handle fatal errors: print the given message
|
|
# and exit 2. Exiting with 2 tells LPD to do not try to reprint the
|
|
# job.
|
|
#
|
|
fatal() {
|
|
echo "$@" 1>&2
|
|
cleanup
|
|
exit 2
|
|
}
|
|
|
|
#
|
|
# If user removes the job, LPD will send SIGINT, so trap SIGINT
|
|
# (and a few other signals) to clean up after ourselves.
|
|
#
|
|
trap cleanup 1 2 15
|
|
|
|
#
|
|
# Make sure we are not colliding with any existing files.
|
|
#
|
|
cleanup
|
|
|
|
#
|
|
# Link the DVI input file to standard input (the file to print).
|
|
#
|
|
ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0"
|
|
|
|
#
|
|
# Make LF = CR+LF
|
|
#
|
|
printf "\033&k2G" || fatal "Cannot initialize printer"
|
|
|
|
#
|
|
# Convert and print. Return value from dvilj2p does not seem to be
|
|
# reliable, so we ignore it.
|
|
#
|
|
dvilj2p -M1 -q -e- dfhp$$.dvi
|
|
|
|
#
|
|
# Clean up and exit
|
|
#
|
|
cleanup
|
|
exit 0</programlisting>
|
|
</sect4>
|
|
|
|
<sect4 id="printing-advanced-autoconv">
|
|
<title>Automated Conversion: An Alternative To Conversion
|
|
Filters</title>
|
|
|
|
<para>All these conversion filters accomplish a lot for your
|
|
printing environment, but at the cost forcing the user to specify
|
|
(on the &man.lpr.1; command line) which one to use.
|
|
If your users are not particularly computer literate, having to
|
|
specify a filter option will become annoying. What is worse,
|
|
though, is that an incorrectly specified filter option may run a
|
|
filter on the wrong type of file and cause your printer to spew
|
|
out hundreds of sheets of paper.</para>
|
|
|
|
<para>Rather than install conversion filters at all, you might want
|
|
to try having the text filter (since it is the default filter)
|
|
detect the type of file it has been asked to print and then
|
|
automatically run the right conversion filter. Tools such as
|
|
<command>file</command> can be of help here. Of course, it will
|
|
be hard to determine the differences between
|
|
<emphasis>some</emphasis> file types—and, of course, you can
|
|
still provide conversion filters just for them.</para>
|
|
|
|
<indexterm><primary>apsfilter</primary></indexterm>
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>filters</secondary>
|
|
<tertiary>apsfilter</tertiary>
|
|
</indexterm>
|
|
<para>The FreeBSD Ports Collection has a text filter that performs
|
|
automatic conversion called <command>apsfilter</command>. It can
|
|
detect plain text, PostScript, and DVI files, run the proper
|
|
conversions, and print.</para>
|
|
</sect4>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-of">
|
|
<title>Output Filters</title>
|
|
|
|
<para>The <application>LPD</application> spooling system supports one
|
|
other type of filter that
|
|
we have not yet explored: an output filter. An output filter is
|
|
intended for printing plain text only, like the text filter, but
|
|
with many simplifications. If you are using an output filter but no
|
|
text filter, then:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><application>LPD</application> starts an output filter once
|
|
for the entire job instead
|
|
of once for each file in the job.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><application>LPD</application> does not make any provision
|
|
to identify the start or the
|
|
end of files within the job for the output filter.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><application>LPD</application> does not pass the user's
|
|
login or host to the filter, so
|
|
it is not intended to do accounting. In fact, it gets only two
|
|
arguments:</para>
|
|
|
|
<cmdsynopsis>
|
|
<command>filter-name</command>
|
|
<arg choice="plain">-w<replaceable>width</replaceable></arg>
|
|
<arg choice="plain">-l<replaceable>length</replaceable></arg>
|
|
</cmdsynopsis>
|
|
|
|
<para>Where <replaceable>width</replaceable> is from the
|
|
<literal>pw</literal> capability and
|
|
<replaceable>length</replaceable> is from the
|
|
<literal>pl</literal> capability for the printer in
|
|
question.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Do not be seduced by an output filter's simplicity. If you
|
|
would like each file in a job to start on a different page an output
|
|
filter <emphasis>will not work</emphasis>. Use a text filter (also
|
|
known as an input filter); see section <link
|
|
linkend="printing-textfilter">Installing the Text Filter</link>.
|
|
Furthermore, an output filter is actually <emphasis>more
|
|
complex</emphasis> in that it has to examine the byte stream being
|
|
sent to it for special flag characters and must send signals to
|
|
itself on behalf of <application>LPD</application>.</para>
|
|
|
|
<para>However, an output filter is <emphasis>necessary</emphasis> if
|
|
you want header pages and need to send escape sequences or other
|
|
initialization strings to be able to print the header page. (But it
|
|
is also <emphasis>futile</emphasis> if you want to charge header
|
|
pages to the requesting user's account, since
|
|
<application>LPD</application> does not give any
|
|
user or host information to the output filter.)</para>
|
|
|
|
<para>On a single printer, <application>LPD</application>
|
|
allows both an output filter and text or other filters. In
|
|
such cases, <application>LPD</application> will start the
|
|
output filter
|
|
to print the header page (see section <link
|
|
linkend="printing-advanced-header-pages">Header Pages</link>)
|
|
only. <application>LPD</application> then expects the
|
|
output filter to <emphasis>stop
|
|
itself</emphasis> by sending two bytes to the filter: ASCII 031
|
|
followed by ASCII 001. When an output filter sees these two bytes
|
|
(031, 001), it should stop by sending <literal>SIGSTOP</literal>
|
|
to itself. When
|
|
<application>LPD</application>'s
|
|
done running other filters, it will restart the output filter by
|
|
sending <literal>SIGCONT</literal> to it.</para>
|
|
|
|
<para>If there is an output filter but <emphasis>no</emphasis> text
|
|
filter and <application>LPD</application> is working on a plain
|
|
text job, <application>LPD</application> uses the output
|
|
filter to do the job. As stated before, the output filter will
|
|
print each file of the job in sequence with no intervening form
|
|
feeds or other paper advancement, and this is probably
|
|
<emphasis>not</emphasis> what you want. In almost all cases, you
|
|
need a text filter.</para>
|
|
|
|
<para>The program <command>lpf</command>, which we introduced earlier
|
|
as a text filter, can also run as an output filter. If you need a
|
|
quick-and-dirty output filter but do not want to write the byte
|
|
detection and signal sending code, try <command>lpf</command>. You
|
|
can also wrap <command>lpf</command> in a shell script to handle any
|
|
initialization codes the printer might require.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-lpf">
|
|
<title><command>lpf</command>: a Text Filter</title>
|
|
|
|
<para>The program <filename>/usr/libexec/lpr/lpf</filename> that comes
|
|
with FreeBSD binary distribution is a text filter (input filter)
|
|
that can indent output (job submitted with <command>lpr
|
|
-i</command>), allow literal characters to pass (job submitted
|
|
with <command>lpr -l</command>), adjust the printing position for
|
|
backspaces and tabs in the job, and account for pages printed. It
|
|
can also act like an output filter.</para>
|
|
|
|
<para><command>lpf</command> is suitable for many printing
|
|
environments. And although it has no capability to send
|
|
initialization sequences to a printer, it is easy to write a shell
|
|
script to do the needed initialization and then execute
|
|
<command>lpf</command>.</para>
|
|
|
|
<indexterm><primary>page accounting</primary></indexterm>
|
|
<indexterm>
|
|
<primary>accounting</primary>
|
|
<secondary>printer</secondary>
|
|
</indexterm>
|
|
<para>In order for <command>lpf</command> to do page accounting
|
|
correctly, it needs correct values filled in for the
|
|
<literal>pw</literal> and <literal>pl</literal> capabilities in the
|
|
<filename>/etc/printcap</filename> file. It uses these values to
|
|
determine how much text can fit on a page and how many pages were in
|
|
a user's job. For more information on printer accounting, see <link
|
|
linkend="printing-advanced-acct">Accounting for Printer
|
|
Usage</link>.</para>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="printing-advanced-header-pages">
|
|
<title>Header Pages</title>
|
|
|
|
<para>If you have <emphasis>lots</emphasis> of users, all of them using
|
|
various printers, then you probably want to consider <emphasis>header
|
|
pages</emphasis> as a necessary evil.</para>
|
|
|
|
<indexterm>
|
|
<primary>banner pages</primary>
|
|
<see>header pages</see>
|
|
</indexterm>
|
|
<indexterm><primary>header pages</primary></indexterm>
|
|
<para>Header pages, also known as <emphasis>banner</emphasis> or
|
|
<emphasis>burst pages</emphasis> identify to whom jobs belong after
|
|
they are printed. They are usually printed in large, bold letters,
|
|
perhaps with decorative borders, so that in a stack of printouts they
|
|
stand out from the real documents that comprise users' jobs. They
|
|
enable users to locate their jobs quickly. The obvious drawback to a
|
|
header page is that it is yet one more sheet that has to be printed
|
|
for every job, their ephemeral usefulness lasting not more than a few
|
|
minutes, ultimately finding themselves in a recycling bin or rubbish
|
|
heap. (Note that header pages go with each job, not each file in a
|
|
job, so the paper waste might not be that bad.)</para>
|
|
|
|
<para>The <application>LPD</application> system can provide header
|
|
pages automatically for your
|
|
printouts <emphasis>if</emphasis> your printer can directly print
|
|
plain text. If you have a PostScript printer, you will need an
|
|
external program to generate the header page; see <link
|
|
linkend="printing-advanced-header-pages-ps">Header Pages on
|
|
PostScript Printers</link>.</para>
|
|
|
|
<sect3 id="printing-advanced-header-pages-enabling">
|
|
<title>Enabling Header Pages</title>
|
|
|
|
<para>In the <link linkend="printing-simple">Simple Printer
|
|
Setup</link>, we turned off header pages by specifying
|
|
<literal>sh</literal> (meaning <quote>suppress header</quote>) in the
|
|
<filename>/etc/printcap</filename> file. To enable header pages for
|
|
a printer, just remove the <literal>sh</literal> capability.</para>
|
|
|
|
<para>Sounds too easy, right?</para>
|
|
|
|
<para>You are right. You <emphasis>might</emphasis> have to provide
|
|
an output filter to send initialization strings to the printer.
|
|
Here is an example output filter for Hewlett Packard PCL-compatible
|
|
printers:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# hpof - Output filter for Hewlett Packard PCL-compatible printers
|
|
# Installed in /usr/local/libexec/hpof
|
|
|
|
printf "\033&k2G" || exit 2
|
|
exec /usr/libexec/lpr/lpf</programlisting>
|
|
|
|
<para>Specify the path to the output filter in the
|
|
<literal>of</literal> capability. See <link
|
|
linkend="printing-advanced-of">Output Filters</link> for more
|
|
information.</para>
|
|
|
|
<para>Here is an example <filename>/etc/printcap</filename> file for
|
|
the printer <literal>teak</literal> that we introduced earlier; we
|
|
enabled header pages and added the above output filter:</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host orchid
|
|
#
|
|
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
|
|
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\
|
|
:if=/usr/local/libexec/hpif:\
|
|
:vf=/usr/local/libexec/hpvf:\
|
|
:of=/usr/local/libexec/hpof:</programlisting>
|
|
|
|
<para>Now, when users print jobs to <literal>teak</literal>, they get
|
|
a header page with each job. If users want to spend time searching
|
|
for their printouts, they can suppress header pages by submitting
|
|
the job with <command>lpr -h</command>; see <link
|
|
linkend="printing-lpr-options-misc">Header Page Options</link> for
|
|
more &man.lpr.1; options.</para>
|
|
|
|
<note>
|
|
<para><application>LPD</application> prints a form feed character
|
|
after the header page. If
|
|
your printer uses a different character or sequence of characters
|
|
to eject a page, specify them with the <literal>ff</literal>
|
|
capability in <filename>/etc/printcap</filename>.</para>
|
|
</note>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-header-pages-controlling">
|
|
<title>Controlling Header Pages</title>
|
|
|
|
<para>By enabling header pages, <application>LPD</application> will
|
|
produce a <emphasis>long
|
|
header</emphasis>, a full page of large letters identifying the
|
|
user, host, and job. Here is an example (kelly printed the job
|
|
named outline from host <hostid>rose</hostid>):</para>
|
|
|
|
<programlisting> k ll ll
|
|
k l l
|
|
k l l
|
|
k k eeee l l y y
|
|
k k e e l l y y
|
|
k k eeeeee l l y y
|
|
kk k e l l y y
|
|
k k e e l l y yy
|
|
k k eeee lll lll yyy y
|
|
y
|
|
y y
|
|
yyyy
|
|
|
|
|
|
ll
|
|
t l i
|
|
t l
|
|
oooo u u ttttt l ii n nnn eeee
|
|
o o u u t l i nn n e e
|
|
o o u u t l i n n eeeeee
|
|
o o u u t l i n n e
|
|
o o u uu t t l i n n e e
|
|
oooo uuu u tt lll iii n n eeee
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r rrr oooo ssss eeee
|
|
rr r o o s s e e
|
|
r o o ss eeeeee
|
|
r o o ss e
|
|
r o o s s e e
|
|
r oooo ssss eeee
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Job: outline
|
|
Date: Sun Sep 17 11:04:58 1995</programlisting>
|
|
|
|
<para><application>LPD</application> appends a form feed after this
|
|
text so the job starts on a
|
|
new page (unless you have <literal>sf</literal> (suppress form
|
|
feeds) in the destination printer's entry in
|
|
<filename>/etc/printcap</filename>).</para>
|
|
|
|
<para>If you prefer, <application>LPD</application> can make a
|
|
<emphasis>short header</emphasis>;
|
|
specify <literal>sb</literal> (short banner) in the
|
|
<filename>/etc/printcap</filename> file. The header page will look
|
|
like this:</para>
|
|
|
|
<programlisting>rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995</programlisting>
|
|
|
|
<para>Also by default, <application>LPD</application> prints the
|
|
header page first, then the job.
|
|
To reverse that, specify <literal>hl</literal> (header last) in
|
|
<filename>/etc/printcap</filename>.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-header-pages-accounting">
|
|
<title>Accounting for Header Pages</title>
|
|
|
|
<para>Using <application>LPD</application>'s built-in header pages
|
|
enforces a particular paradigm
|
|
when it comes to printer accounting: header pages must be
|
|
<emphasis>free of charge</emphasis>.</para>
|
|
|
|
<para>Why?</para>
|
|
|
|
<para>Because the output filter is the only external program that will
|
|
have control when the header page is printed that could do
|
|
accounting, and it is not provided with any <emphasis>user or
|
|
host</emphasis> information or an accounting file, so it has no
|
|
idea whom to charge for printer use. It is also not enough to just
|
|
<quote>add one page</quote> to the text filter or any of the
|
|
conversion filters (which do have user and host information) since
|
|
users can suppress header pages with <command>lpr -h</command>.
|
|
They could still be charged for header pages they did not print.
|
|
Basically, <command>lpr -h</command> will be the preferred option of
|
|
environmentally-minded users, but you cannot offer any incentive to
|
|
use it.</para>
|
|
|
|
<para>It is <emphasis>still not enough</emphasis> to have each of the
|
|
filters generate their own header pages (thereby being able to
|
|
charge for them). If users wanted the option of suppressing the
|
|
header pages with <command>lpr -h</command>, they will still get
|
|
them and be charged for them since <application>LPD</application>
|
|
does not pass any knowledge
|
|
of the <option>-h</option> option to any of the filters.</para>
|
|
|
|
<para>So, what are your options?</para>
|
|
|
|
<para>You can:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Accept <application>LPD</application>'s paradigm and make
|
|
header pages free.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Install an alternative to <application>LPD</application>,
|
|
such as
|
|
<application>LPRng</application>. Section
|
|
<link linkend="printing-lpd-alternatives">Alternatives to the
|
|
Standard Spooler</link> tells more about other spooling
|
|
software you can substitute for <application>LPD</application>.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Write a <emphasis>smart</emphasis> output filter. Normally,
|
|
an output filter is not meant to do anything more than
|
|
initialize a printer or do some simple character conversion. It
|
|
is suited for header pages and plain text jobs (when there is no
|
|
text (input) filter). But, if there is a text filter for the
|
|
plain text jobs, then <application>LPD</application> will start
|
|
the output filter only for
|
|
the header pages. And the output filter can parse the header
|
|
page text that <application>LPD</application> generates to
|
|
determine what user and host to
|
|
charge for the header page. The only other problem with this
|
|
method is that the output filter still does not know what
|
|
accounting file to use (it is not passed the name of the file
|
|
from the <literal>af</literal> capability), but if you have a
|
|
well-known accounting file, you can hard-code that into the
|
|
output filter. To facilitate the parsing step, use the
|
|
<literal>sh</literal> (short header) capability in
|
|
<filename>/etc/printcap</filename>. Then again, all that might
|
|
be too much trouble, and users will certainly appreciate the
|
|
more generous system administrator who makes header pages
|
|
free.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-header-pages-ps">
|
|
<title>Header Pages on PostScript Printers</title>
|
|
|
|
<para>As described above, <application>LPD</application> can generate
|
|
a plain text header page
|
|
suitable for many printers. Of course, PostScript cannot directly
|
|
print plain text, so the header page feature of
|
|
<application>LPD</application> is
|
|
useless—or mostly so.</para>
|
|
|
|
<para>One obvious way to get header pages is to have every conversion
|
|
filter and the text filter generate the header page. The filters
|
|
should use the user and host arguments to generate a suitable
|
|
header page. The drawback of this method is that users will always
|
|
get a header page, even if they submit jobs with <command>lpr
|
|
-h</command>.</para>
|
|
|
|
<para>Let us explore this method. The following script takes three
|
|
arguments (user login name, host name, and job name) and makes a
|
|
simple PostScript header page:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# make-ps-header - make a PostScript header page on stdout
|
|
# Installed in /usr/local/libexec/make-ps-header
|
|
#
|
|
|
|
#
|
|
# These are PostScript units (72 to the inch). Modify for A4 or
|
|
# whatever size paper you are using:
|
|
#
|
|
page_width=612
|
|
page_height=792
|
|
border=72
|
|
|
|
#
|
|
# Check arguments
|
|
#
|
|
if [ $# -ne 3 ]; then
|
|
echo "Usage: `basename $0` <user> <host> <job>" 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
#
|
|
# Save these, mostly for readability in the PostScript, below.
|
|
#
|
|
user=$1
|
|
host=$2
|
|
job=$3
|
|
date=`date`
|
|
|
|
#
|
|
# Send the PostScript code to stdout.
|
|
#
|
|
exec cat <<EOF
|
|
%!PS
|
|
|
|
%
|
|
% Make sure we do not interfere with user's job that will follow
|
|
%
|
|
save
|
|
|
|
%
|
|
% Make a thick, unpleasant border around the edge of the paper.
|
|
%
|
|
$border $border moveto
|
|
$page_width $border 2 mul sub 0 rlineto
|
|
0 $page_height $border 2 mul sub rlineto
|
|
currentscreen 3 -1 roll pop 100 3 1 roll setscreen
|
|
$border 2 mul $page_width sub 0 rlineto closepath
|
|
0.8 setgray 10 setlinewidth stroke 0 setgray
|
|
|
|
%
|
|
% Display user's login name, nice and large and prominent
|
|
%
|
|
/Helvetica-Bold findfont 64 scalefont setfont
|
|
$page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto
|
|
($user) show
|
|
|
|
%
|
|
% Now show the boring particulars
|
|
%
|
|
/Helvetica findfont 14 scalefont setfont
|
|
/y 200 def
|
|
[ (Job:) (Host:) (Date:) ] {
|
|
200 y moveto show /y y 18 sub def }
|
|
forall
|
|
|
|
/Helvetica-Bold findfont 14 scalefont setfont
|
|
/y 200 def
|
|
[ ($job) ($host) ($date) ] {
|
|
270 y moveto show /y y 18 sub def
|
|
} forall
|
|
|
|
%
|
|
% That is it
|
|
%
|
|
restore
|
|
showpage
|
|
EOF</programlisting>
|
|
|
|
<para>Now, each of the conversion filters and the text filter can call
|
|
this script to first generate the header page, and then print the
|
|
user's job. Here is the DVI conversion filter from earlier in this
|
|
document, modified to make a header page:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# psdf - DVI to PostScript printer filter
|
|
# Installed in /usr/local/libexec/psdf
|
|
#
|
|
# Invoked by lpd when user runs lpr -d
|
|
#
|
|
|
|
orig_args="$@"
|
|
|
|
fail() {
|
|
echo "$@" 1>&2
|
|
exit 2
|
|
}
|
|
|
|
while getopts "x:y:n:h:" option; do
|
|
case $option in
|
|
x|y) ;; # Ignore
|
|
n) login=$OPTARG ;;
|
|
h) host=$OPTARG ;;
|
|
*) echo "LPD started `basename $0` wrong." 1>&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[ "$login" ] || fail "No login name"
|
|
[ "$host" ] || fail "No host name"
|
|
|
|
( /usr/local/libexec/make-ps-header $login $host "DVI File"
|
|
/usr/local/bin/dvips -f ) | eval /usr/local/libexec/lprps $orig_args</programlisting>
|
|
|
|
<para>Notice how the filter has to parse the argument list in order to
|
|
determine the user and host name. The parsing for the other
|
|
conversion filters is identical. The text filter takes a slightly
|
|
different set of arguments, though (see section <link
|
|
linkend="printing-advanced-filters">How Filters
|
|
Work</link>).</para>
|
|
|
|
<para>As we have mentioned before, the above scheme, though fairly
|
|
simple, disables the <quote>suppress header page</quote> option (the
|
|
<option>-h</option> option) to <command>lpr</command>. If users
|
|
wanted to save a tree (or a few pennies, if you charge for header
|
|
pages), they would not be able to do so, since every filter's going
|
|
to print a header page with every job.</para>
|
|
|
|
<para>To allow users to shut off header pages on a per-job basis, you
|
|
will need to use the trick introduced in section <link
|
|
linkend="printing-advanced-header-pages-accounting">Accounting for
|
|
Header Pages</link>: write an output filter that parses the
|
|
LPD-generated header page and produces a PostScript version. If the
|
|
user submits the job with <command>lpr -h</command>, then
|
|
<application>LPD</application> will
|
|
not generate a header page, and neither will your output filter.
|
|
Otherwise, your output filter will read the text from
|
|
<application>LPD</application> and send
|
|
the appropriate header page PostScript code to the printer.</para>
|
|
|
|
<para>If you have a PostScript printer on a serial line, you can make
|
|
use of <command>lprps</command>, which comes with an output filter,
|
|
<command>psof</command>, which does the above. Note that
|
|
<command>psof</command> does not charge for header pages.</para>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="printing-advanced-network-printers">
|
|
<title>Networked Printing</title>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>network</secondary>
|
|
</indexterm>
|
|
<indexterm><primary>network printing</primary></indexterm>
|
|
<para>FreeBSD supports networked printing: sending jobs to remote
|
|
printers. Networked printing generally refers to two different
|
|
things:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Accessing a printer attached to a remote host. You install a
|
|
printer that has a conventional serial or parallel interface on
|
|
one host. Then, you set up <application>LPD</application> to
|
|
enable access to the printer
|
|
from other hosts on the network. Section <link
|
|
linkend="printing-advanced-network-rm">Printers Installed on
|
|
Remote Hosts</link> tells how to do this.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Accessing a printer attached directly to a network. The
|
|
printer has a network interface in addition (or in place of) a
|
|
more conventional serial or parallel interface. Such a printer
|
|
might work as follows:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>It might understand the <application>LPD</application>
|
|
protocol and can even queue
|
|
jobs from remote hosts. In this case, it acts just like a
|
|
regular host running <application>LPD</application>. Follow
|
|
the same procedure in
|
|
section <link linkend="printing-advanced-network-rm">Printers
|
|
Installed on Remote Hosts</link> to set up such a
|
|
printer.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It might support a data stream network connection. In this
|
|
case, you <quote>attach</quote> the printer to one host on the
|
|
network by making that host responsible for spooling jobs and
|
|
sending them to the printer. Section <link
|
|
linkend="printing-advanced-network-net-if">Printers with
|
|
Networked Data Stream Interfaces</link> gives some
|
|
suggestions on installing such printers.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<sect3 id="printing-advanced-network-rm">
|
|
<title>Printers Installed on Remote Hosts</title>
|
|
|
|
<para>The <application>LPD</application> spooling system has built-in
|
|
support for sending jobs to
|
|
other hosts also running <application>LPD</application> (or are
|
|
compatible with <application>LPD</application>). This
|
|
feature enables you to install a printer on one host and make it
|
|
accessible from other hosts. It also works with printers that have
|
|
network interfaces that understand the
|
|
<application>LPD</application> protocol.</para>
|
|
|
|
<para>To enable this kind of remote printing, first install a printer
|
|
on one host, the <emphasis>printer host</emphasis>, using the simple
|
|
printer setup described in <link linkend="printing-simple">Simple
|
|
Printer Setup</link>. Do any advanced setup in <link
|
|
linkend="printing-advanced">Advanced Printer Setup</link> that you
|
|
need. Make sure to test the printer and see if it works with the
|
|
features of <application>LPD</application> you have enabled.
|
|
Also ensure that the
|
|
<emphasis>local host</emphasis> has authorization to use the
|
|
<application>LPD</application>
|
|
service in the <emphasis>remote host</emphasis> (see <link
|
|
linkend="printing-advanced-restricting-remote">Restricting Jobs
|
|
from Remote Printers</link>).</para>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>network</secondary>
|
|
</indexterm>
|
|
<indexterm><primary>network printing</primary></indexterm>
|
|
<para>If you are using a printer with a network interface that is
|
|
compatible with <application>LPD</application>, then the
|
|
<emphasis>printer host</emphasis> in
|
|
the discussion below is the printer itself, and the
|
|
<emphasis>printer name</emphasis> is the name you configured for the
|
|
printer. See the documentation that accompanied your printer and/or
|
|
printer-network interface.</para>
|
|
|
|
<tip>
|
|
<para>If you are using a Hewlett Packard Laserjet then the printer
|
|
name <literal>text</literal> will automatically perform the LF to
|
|
CRLF conversion for you, so you will not require the
|
|
<filename>hpif</filename> script.</para>
|
|
</tip>
|
|
|
|
<para>Then, on the other hosts you want to have access to the printer,
|
|
make an entry in their <filename>/etc/printcap</filename> files with
|
|
the following:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>Name the entry anything you want. For simplicity, though,
|
|
you probably want to use the same name and aliases as on the
|
|
printer host.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Leave the <literal>lp</literal> capability blank, explicitly
|
|
(<literal>:lp=:</literal>).</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Make a spooling directory and specify its location in the
|
|
<literal>sd</literal> capability. <application>LPD</application>
|
|
will store jobs here
|
|
before they get sent to the printer host.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Place the name of the printer host in the
|
|
<literal>rm</literal> capability.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Place the printer name on the <emphasis>printer
|
|
host</emphasis> in the <literal>rp</literal>
|
|
capability.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>That is it. You do not need to list conversion filters, page
|
|
dimensions, or anything else in the
|
|
<filename>/etc/printcap</filename> file.</para>
|
|
|
|
<para>Here is an example. The host <hostid>rose</hostid> has two
|
|
printers, <literal>bamboo</literal> and <literal>rattan</literal>.
|
|
We will enable users on the host <hostid>orchid</hostid> to print
|
|
to those printers.
|
|
Here is the <filename>/etc/printcap</filename> file for
|
|
<hostid>orchid</hostid> (back from section <link
|
|
linkend="printing-advanced-header-pages-enabling">Enabling Header
|
|
Pages</link>). It already had the entry for the printer
|
|
<literal>teak</literal>; we have added entries for the two printers
|
|
on the host <hostid>rose</hostid>:</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host orchid - added (remote) printers on rose
|
|
#
|
|
|
|
#
|
|
# teak is local; it is connected directly to orchid:
|
|
#
|
|
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
|
|
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\
|
|
:if=/usr/local/libexec/ifhp:\
|
|
:vf=/usr/local/libexec/vfhp:\
|
|
:of=/usr/local/libexec/ofhp:
|
|
|
|
#
|
|
# rattan is connected to rose; send jobs for rattan to rose:
|
|
#
|
|
rattan|line|diablo|lp|Diablo 630 Line Printer:\
|
|
:lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan:
|
|
|
|
#
|
|
# bamboo is connected to rose as well:
|
|
#
|
|
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
|
|
:lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:</programlisting>
|
|
|
|
<para>Then, we just need to make spooling directories on
|
|
<hostid>orchid</hostid>:</para>
|
|
|
|
<screen>&prompt.root; <userinput>mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput>
|
|
&prompt.root; <userinput>chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput>
|
|
&prompt.root; <userinput>chown daemon:daemon /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput></screen>
|
|
|
|
<para>Now, users on <hostid>orchid</hostid> can print to
|
|
<literal>rattan</literal> and <literal>bamboo</literal>. If, for
|
|
example, a user on <hostid>orchid</hostid> typed
|
|
|
|
<screen>&prompt.user; <userinput>lpr -P bamboo -d sushi-review.dvi</userinput></screen>
|
|
|
|
the <application>LPD</application> system on <hostid>orchid</hostid>
|
|
would copy the job to the spooling
|
|
directory <filename>/var/spool/lpd/bamboo</filename> and note that it was a
|
|
DVI job. As soon as the host <hostid>rose</hostid> has room in its
|
|
<literal>bamboo</literal> spooling directory, the two
|
|
<application>LPDs</application> would transfer the
|
|
file to <hostid>rose</hostid>. The file would wait in <hostid>rose</hostid>'s
|
|
queue until it was finally printed. It would be converted from DVI to
|
|
PostScript (since <literal>bamboo</literal> is a PostScript printer) on
|
|
<hostid>rose</hostid>.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-network-net-if">
|
|
<title>Printers with Networked Data Stream Interfaces</title>
|
|
|
|
<para>Often, when you buy a network interface card for a printer, you
|
|
can get two versions: one which emulates a spooler (the more
|
|
expensive version), or one which just lets you send data to it as if
|
|
you were using a serial or parallel port (the cheaper version).
|
|
This section tells how to use the cheaper version. For the more
|
|
expensive one, see the previous section <link
|
|
linkend="printing-advanced-network-rm">Printers Installed on
|
|
Remote Hosts</link>.</para>
|
|
|
|
<para>The format of the <filename>/etc/printcap</filename> file lets
|
|
you specify what serial or parallel interface to use, and (if you
|
|
are using a serial interface), what baud rate, whether to use flow
|
|
control, delays for tabs, conversion of newlines, and more. But
|
|
there is no way to specify a connection to a printer that is
|
|
listening on a TCP/IP or other network port.</para>
|
|
|
|
<para>To send data to a networked printer, you need to develop a
|
|
communications program that can be called by the text and conversion
|
|
filters. Here is one such example: the script
|
|
<command>netprint</command> takes all data on standard input and
|
|
sends it to a network-attached printer. We specify the hostname of
|
|
the printer as the first argument and the port number to which to
|
|
connect as the second argument to <command>netprint</command>. Note
|
|
that this supports one-way communication only (FreeBSD to printer);
|
|
many network printers support two-way communication, and you might
|
|
want to take advantage of that (to get printer status, perform
|
|
accounting, etc.).</para>
|
|
|
|
<programlisting>#!/usr/bin/perl
|
|
#
|
|
# netprint - Text filter for printer attached to network
|
|
# Installed in /usr/local/libexec/netprint
|
|
#
|
|
$#ARGV eq 1 || die "Usage: $0 <printer-hostname> <port-number>";
|
|
|
|
$printer_host = $ARGV[0];
|
|
$printer_port = $ARGV[1];
|
|
|
|
require 'sys/socket.ph';
|
|
|
|
($ignore, $ignore, $protocol) = getprotobyname('tcp');
|
|
($ignore, $ignore, $ignore, $ignore, $address)
|
|
= gethostbyname($printer_host);
|
|
|
|
$sockaddr = pack('S n a4 x8', &AF_INET, $printer_port, $address);
|
|
|
|
socket(PRINTER, &PF_INET, &SOCK_STREAM, $protocol)
|
|
|| die "Can't create TCP/IP stream socket: $!";
|
|
connect(PRINTER, $sockaddr) || die "Can't contact $printer_host: $!";
|
|
while (<STDIN>) { print PRINTER; }
|
|
exit 0;</programlisting>
|
|
|
|
<para>We can then use this script in various filters. Suppose we had
|
|
a Diablo 750-N line printer connected to the network. The printer
|
|
accepts data to print on port number 5100. The host name of the
|
|
printer is scrivener. Here is the text filter for the
|
|
printer:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# diablo-if-net - Text filter for Diablo printer `scrivener' listening
|
|
# on port 5100. Installed in /usr/local/libexec/diablo-if-net
|
|
#
|
|
exec /usr/libexec/lpr/lpf "$@" | /usr/local/libexec/netprint scrivener 5100</programlisting>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="printing-advanced-restricting">
|
|
<title>Restricting Printer Usage</title>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>restricting access to</secondary>
|
|
</indexterm>
|
|
<para>This section gives information on restricting printer usage. The
|
|
<application>LPD</application> system lets you control who can access
|
|
a printer, both locally or
|
|
remotely, whether they can print multiple copies, how large their jobs
|
|
can be, and how large the printer queues can get.</para>
|
|
|
|
<sect3 id="printing-advanced-restricting-copies">
|
|
<title>Restricting Multiple Copies</title>
|
|
|
|
<para>The <application>LPD</application> system makes it easy for
|
|
users to print multiple copies
|
|
of a file. Users can print jobs with <command>lpr -#5</command>
|
|
(for example) and get five copies of each file in the job. Whether
|
|
this is a good thing is up to you.</para>
|
|
|
|
<para>If you feel multiple copies cause unnecessary wear and tear on
|
|
your printers, you can disable the <option>-#</option> option to
|
|
&man.lpr.1; by adding the <literal>sc</literal> capability to the
|
|
<filename>/etc/printcap</filename> file. When users submit jobs
|
|
with the <option>-#</option> option, they will see:</para>
|
|
|
|
<screen>lpr: multiple copies are not allowed</screen>
|
|
|
|
|
|
<para>Note that if you have set up access to a printer remotely (see
|
|
section <link linkend="printing-advanced-network-rm">Printers
|
|
Installed on Remote Hosts</link>), you need the
|
|
<literal>sc</literal> capability on the remote
|
|
<filename>/etc/printcap</filename> files as well, or else users will
|
|
still be able to submit multiple-copy jobs by using another
|
|
host.</para>
|
|
|
|
<para>Here is an example. This is the
|
|
<filename>/etc/printcap</filename> file for the host
|
|
<hostid>rose</hostid>. The printer <literal>rattan</literal> is
|
|
quite hearty, so we will allow multiple copies, but the laser
|
|
printer <literal>bamboo</literal> is a bit more delicate, so we will
|
|
disable multiple copies by adding the <literal>sc</literal>
|
|
capability:</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host rose - restrict multiple copies on bamboo
|
|
#
|
|
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:sc:\
|
|
:lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\
|
|
:if=/usr/local/libexec/psif:\
|
|
:df=/usr/local/libexec/psdf:</programlisting>
|
|
|
|
<para>Now, we also need to add the <literal>sc</literal> capability on
|
|
the host <hostid>orchid</hostid>'s
|
|
<filename>/etc/printcap</filename> (and while we are at it, let us
|
|
disable multiple copies for the printer
|
|
<literal>teak</literal>):</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host orchid - no multiple copies for local
|
|
# printer teak or remote printer bamboo
|
|
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
|
|
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:sc:\
|
|
:if=/usr/local/libexec/ifhp:\
|
|
:vf=/usr/local/libexec/vfhp:\
|
|
:of=/usr/local/libexec/ofhp:
|
|
|
|
rattan|line|diablo|lp|Diablo 630 Line Printer:\
|
|
:lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan:
|
|
|
|
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
|
|
:lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:sc:</programlisting>
|
|
|
|
<para>By using the <literal>sc</literal> capability, we prevent the
|
|
use of <command>lpr -#</command>, but that still does not prevent
|
|
users from running &man.lpr.1;
|
|
multiple times, or from submitting the same file multiple times in
|
|
one job like this:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.sign</userinput></screen>
|
|
|
|
<para>There are many ways to prevent this abuse (including ignoring
|
|
it) which you are free to explore.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-restricting-access">
|
|
<title>Restricting Access To Printers</title>
|
|
|
|
<para>You can control who can print to what printers by using the Unix
|
|
group mechanism and the <literal>rg</literal> capability in
|
|
<filename>/etc/printcap</filename>. Just place the users you want
|
|
to have access to a printer in a certain group, and then name that
|
|
group in the <literal>rg</literal> capability.</para>
|
|
|
|
<para>Users outside the group (including root) will be greeted with
|
|
|
|
<errorname>lpr: Not a member of the restricted group</errorname>
|
|
|
|
if they try to print to the controlled printer.</para>
|
|
|
|
<para>As with the <literal>sc</literal> (suppress multiple copies)
|
|
capability, you need to specify <literal>rg</literal> on remote
|
|
hosts that also have access to your printers, if you feel it is
|
|
appropriate (see section <link
|
|
linkend="printing-advanced-network-rm">Printers Installed on
|
|
Remote Hosts</link>).</para>
|
|
|
|
<para>For example, we will let anyone access the printer
|
|
<literal>rattan</literal>, but only those in group
|
|
<literal>artists</literal> can use <literal>bamboo</literal>. Here
|
|
is the familiar <filename>/etc/printcap</filename> for host
|
|
<hostid>rose</hostid>:</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host rose - restricted group for bamboo
|
|
#
|
|
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:sc:rg=artists:\
|
|
:lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\
|
|
:if=/usr/local/libexec/psif:\
|
|
:df=/usr/local/libexec/psdf:</programlisting>
|
|
|
|
<para>Let us leave the other example
|
|
<filename>/etc/printcap</filename> file (for the host
|
|
<hostid>orchid</hostid>) alone. Of course, anyone on
|
|
<hostid>orchid</hostid> can print to <literal>bamboo</literal>. It
|
|
might be the case that we only allow certain logins on
|
|
<hostid>orchid</hostid> anyway, and want them to have access to the
|
|
printer. Or not.</para>
|
|
|
|
<note>
|
|
<para>There can be only one restricted group per printer.</para>
|
|
</note>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-restricting-sizes">
|
|
<title>Controlling Sizes of Jobs Submitted</title>
|
|
|
|
<indexterm><primary>print jobs</primary></indexterm>
|
|
<para>If you have many users accessing the printers, you probably need
|
|
to put an upper limit on the sizes of the files users can submit to
|
|
print. After all, there is only so much free space on the
|
|
filesystem that houses the spooling directories, and you also need
|
|
to make sure there is room for the jobs of other users.</para>
|
|
|
|
<indexterm>
|
|
<primary>print jobs</primary>
|
|
<secondary>controlling</secondary>
|
|
</indexterm>
|
|
<para><application>LPD</application> enables you to limit the maximum
|
|
byte size a file in a job
|
|
can be with the <literal>mx</literal> capability. The units are in
|
|
<literal>BUFSIZ</literal> blocks, which are 1024 bytes. If you put
|
|
a zero for this
|
|
capability, there will be no limit on file size; however, if no
|
|
<literal>mx</literal> capability is specified, then a default limit
|
|
of 1000 blocks will be used.</para>
|
|
|
|
<note>
|
|
<para>The limit applies to <emphasis>files</emphasis> in a job, and
|
|
<emphasis>not</emphasis> the total job size.</para>
|
|
</note>
|
|
|
|
<para><application>LPD</application> will not refuse a file that is
|
|
larger than the limit you
|
|
place on a printer. Instead, it will queue as much of the file up
|
|
to the limit, which will then get printed. The rest will be
|
|
discarded. Whether this is correct behavior is up for
|
|
debate.</para>
|
|
|
|
<para>Let us add limits to our example printers
|
|
<literal>rattan</literal> and <literal>bamboo</literal>. Since
|
|
those artists' PostScript files tend to be large, we will limit them
|
|
to five megabytes. We will put no limit on the plain text line
|
|
printer:</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host rose
|
|
#
|
|
|
|
#
|
|
# No limit on job size:
|
|
#
|
|
rattan|line|diablo|lp|Diablo 630 Line Printer:\
|
|
:sh:mx#0:sd=/var/spool/lpd/rattan:\
|
|
:lp=/dev/lpt0:\
|
|
:if=/usr/local/libexec/if-simple:
|
|
|
|
#
|
|
# Limit of five megabytes:
|
|
#
|
|
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
|
|
:sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\
|
|
:lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\
|
|
:if=/usr/local/libexec/psif:\
|
|
:df=/usr/local/libexec/psdf:</programlisting>
|
|
|
|
<para>Again, the limits apply to the local users only. If you have
|
|
set up access to your printers remotely, remote users will not get
|
|
those limits. You will need to specify the <literal>mx</literal>
|
|
capability in the remote <filename>/etc/printcap</filename> files as
|
|
well. See section <link
|
|
linkend="printing-advanced-network-rm">Printers Installed on
|
|
Remote Hosts</link> for more information on remote
|
|
printing.</para>
|
|
|
|
<para>There is another specialized way to limit job sizes from remote
|
|
printers; see section <link
|
|
linkend="printing-advanced-restricting-remote">Restricting Jobs
|
|
from Remote Printers</link>.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-advanced-restricting-remote">
|
|
<title>Restricting Jobs from Remote Printers</title>
|
|
|
|
<para>The <application>LPD</application> spooling system provides
|
|
several ways to restrict print
|
|
jobs submitted from remote hosts:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>Host restrictions</term>
|
|
|
|
<listitem>
|
|
<para>You can control from which remote hosts a local
|
|
<application>LPD</application> accepts requests with the files
|
|
<filename>/etc/hosts.equiv</filename> and
|
|
<filename>/etc/hosts.lpd</filename>.
|
|
<application>LPD</application> checks to see if an
|
|
incoming request is from a host listed in either one of these
|
|
files. If not, <application>LPD</application> refuses the
|
|
request.</para>
|
|
|
|
<para>The format of these files is simple: one host name per
|
|
line. Note that the file
|
|
<filename>/etc/hosts.equiv</filename> is also used by the
|
|
&man.ruserok.3; protocol, and affects programs like
|
|
&man.rsh.1; and &man.rcp.1;, so be careful.</para>
|
|
|
|
<para>For example, here is the
|
|
<filename>/etc/hosts.lpd</filename> file on the host
|
|
<hostid>rose</hostid>:</para>
|
|
|
|
<programlisting>orchid
|
|
violet
|
|
madrigal.fishbaum.de</programlisting>
|
|
|
|
<para>This means <hostid>rose</hostid> will accept requests from
|
|
the hosts <hostid>orchid</hostid>, <hostid>violet</hostid>,
|
|
and <hostid role="fqdn">madrigal.fishbaum.de</hostid>. If any
|
|
other host tries to access <hostid>rose</hostid>'s
|
|
<application>LPD</application>, the job will be refused.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>Size restrictions</term>
|
|
|
|
<listitem>
|
|
<para>You can control how much free space there needs to remain
|
|
on the filesystem where a spooling directory resides. Make a
|
|
file called <filename>minfree</filename> in the spooling
|
|
directory for the local printer. Insert in that file a number
|
|
representing how many disk blocks (512 bytes) of free space
|
|
there has to be for a remote job to be accepted.</para>
|
|
|
|
<para>This lets you insure that remote users will not fill your
|
|
filesystem. You can also use it to give a certain priority to
|
|
local users: they will be able to queue jobs long after the
|
|
free disk space has fallen below the amount specified in the
|
|
<filename>minfree</filename> file.</para>
|
|
|
|
<para>For example, let us add a <filename>minfree</filename>
|
|
file for the printer <literal>bamboo</literal>. We examine
|
|
<filename>/etc/printcap</filename> to find the spooling
|
|
directory for this printer; here is <literal>bamboo</literal>'s
|
|
entry:</para>
|
|
|
|
<programlisting>bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
|
|
:sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\
|
|
:lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:mx#5000:\
|
|
:if=/usr/local/libexec/psif:\
|
|
:df=/usr/local/libexec/psdf:</programlisting>
|
|
|
|
<para>The spooling directory is given in the <literal>sd</literal>
|
|
capability. We will make three megabytes (which is 6144 disk blocks)
|
|
the amount of free disk space that must exist on the filesystem for
|
|
<application>LPD</application> to accept remote jobs:</para>
|
|
|
|
<screen>&prompt.root; <userinput>echo 6144 > /var/spool/lpd/bamboo/minfree
|
|
</userinput></screen>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>User restrictions</term>
|
|
|
|
<listitem>
|
|
<para>You can control which remote users can print to local
|
|
printers by specifying the <literal>rs</literal> capability in
|
|
<filename>/etc/printcap</filename>. When
|
|
<literal>rs</literal> appears in the entry for a
|
|
locally-attached printer, <application>LPD</application> will
|
|
accept jobs from remote
|
|
hosts <emphasis>if</emphasis> the user submitting the job also
|
|
has an account of the same login name on the local host.
|
|
Otherwise, <application>LPD</application> refuses the job.</para>
|
|
|
|
<para>This capability is particularly useful in an environment
|
|
where there are (for example) different departments sharing a
|
|
network, and some users transcend departmental boundaries. By
|
|
giving them accounts on your systems, they can use your
|
|
printers from their own departmental systems. If you would
|
|
rather allow them to use <emphasis>only</emphasis> your
|
|
printers and not your computer resources, you can give them
|
|
<quote>token</quote> accounts, with no home directory and a
|
|
useless shell like <filename>/usr/bin/false</filename>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="printing-advanced-acct">
|
|
<title>Accounting for Printer Usage</title>
|
|
|
|
<indexterm>
|
|
<primary>accounting</primary>
|
|
<secondary>printer</secondary>
|
|
</indexterm>
|
|
<para>So, you need to charge for printouts. And why not? Paper and ink
|
|
cost money. And then there are maintenance costs—printers are
|
|
loaded with moving parts and tend to break down. You have examined
|
|
your printers, usage patterns, and maintenance fees and have come up
|
|
with a per-page (or per-foot, per-meter, or per-whatever) cost. Now,
|
|
how do you actually start accounting for printouts?</para>
|
|
|
|
<para>Well, the bad news is the <application>LPD</application> spooling
|
|
system does not provide
|
|
much help in this department. Accounting is highly dependent on the
|
|
kind of printer in use, the formats being printed, and
|
|
<emphasis>your</emphasis> requirements in charging for printer
|
|
usage.</para>
|
|
|
|
<para>To implement accounting, you have to modify a printer's text
|
|
filter (to charge for plain text jobs) and the conversion filters (to
|
|
charge for other file formats), to count pages or query the printer
|
|
for pages printed. You cannot get away with using the simple output
|
|
filter, since it cannot do accounting. See section <link
|
|
linkend="printing-advanced-filter-intro">Filters</link>.</para>
|
|
|
|
<para>Generally, there are two ways to do accounting:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Periodic accounting</emphasis> is the more common
|
|
way, possibly because it is easier. Whenever someone prints a
|
|
job, the filter logs the user, host, and number of pages to an
|
|
accounting file. Every month, semester, year, or whatever time
|
|
period you prefer, you collect the accounting files for the
|
|
various printers, tally up the pages printed by users, and charge
|
|
for usage. Then you truncate all the logging files, starting with
|
|
a clean slate for the next period.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><emphasis>Timely accounting</emphasis> is less common,
|
|
probably because it is more difficult. This method has the
|
|
filters charge users for printouts as soon as they use the
|
|
printers. Like disk quotas, the accounting is immediate. You can
|
|
prevent users from printing when their account goes in the red,
|
|
and might provide a way for users to check and adjust their
|
|
<quote>print quotas.</quote> But this method requires some database
|
|
code to track users and their quotas.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>The <application>LPD</application> spooling system supports both
|
|
methods easily: since you
|
|
have to provide the filters (well, most of the time), you also have to
|
|
provide the accounting code. But there is a bright side: you have
|
|
enormous flexibility in your accounting methods. For example, you
|
|
choose whether to use periodic or timely accounting. You choose what
|
|
information to log: user names, host names, job types, pages printed,
|
|
square footage of paper used, how long the job took to print, and so
|
|
forth. And you do so by modifying the filters to save this
|
|
information.</para>
|
|
|
|
<sect3>
|
|
<title>Quick and Dirty Printer Accounting</title>
|
|
|
|
<para>FreeBSD comes with two programs that can get you set up with
|
|
simple periodic accounting right away. They are the text filter
|
|
<command>lpf</command>, described in section <link
|
|
linkend="printing-advanced-lpf">lpf: a Text Filter</link>, and
|
|
&man.pac.8;, a program to gather and total
|
|
entries from printer accounting files.</para>
|
|
|
|
<para>As mentioned in the section on filters (<link
|
|
linkend="printing-advanced-filters">Filters</link>),
|
|
<application>LPD</application> starts
|
|
the text and the conversion filters with the name of the accounting
|
|
file to use on the filter command line. The filters can use this
|
|
argument to know where to write an accounting file entry. The name
|
|
of this file comes from the <literal>af</literal> capability in
|
|
<filename>/etc/printcap</filename>, and if not specified as an
|
|
absolute path, is relative to the spooling directory.</para>
|
|
|
|
<para><application>LPD</application> starts <command>lpf</command>
|
|
with page width and length
|
|
arguments (from the <literal>pw</literal> and <literal>pl</literal>
|
|
capabilities). <command>lpf</command> uses these arguments to
|
|
determine how much paper will be used. After sending the file to
|
|
the printer, it then writes an accounting entry in the accounting
|
|
file. The entries look like this:</para>
|
|
|
|
<programlisting>2.00 rose:andy
|
|
3.00 rose:kelly
|
|
3.00 orchid:mary
|
|
5.00 orchid:mary
|
|
2.00 orchid:zhang</programlisting>
|
|
|
|
<para>You should use a separate accounting file for each printer, as
|
|
<command>lpf</command> has no file locking logic built into it, and
|
|
two <command>lpf</command>s might corrupt each other's entries if
|
|
they were to write to the same file at the same time. An easy way
|
|
to insure a separate accounting file for each printer is to use
|
|
<literal>af=acct</literal> in <filename>/etc/printcap</filename>.
|
|
Then, each accounting file will be in the spooling directory for a
|
|
printer, in a file named <filename>acct</filename>.</para>
|
|
|
|
<para>When you are ready to charge users for printouts, run the
|
|
&man.pac.8; program. Just change to the spooling directory for
|
|
the printer you want to collect on and type <literal>pac</literal>.
|
|
You will get a dollar-centric summary like the following:</para>
|
|
|
|
<screen> Login pages/feet runs price
|
|
orchid:kelly 5.00 1 $ 0.10
|
|
orchid:mary 31.00 3 $ 0.62
|
|
orchid:zhang 9.00 1 $ 0.18
|
|
rose:andy 2.00 1 $ 0.04
|
|
rose:kelly 177.00 104 $ 3.54
|
|
rose:mary 87.00 32 $ 1.74
|
|
rose:root 26.00 12 $ 0.52
|
|
|
|
total 337.00 154 $ 6.74</screen>
|
|
|
|
<para>These are the arguments &man.pac.8; expects:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>-P<replaceable>printer</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>Which <replaceable>printer</replaceable> to summarize.
|
|
This option works only if there is an absolute path in the
|
|
<literal>af</literal> capability in
|
|
<filename>/etc/printcap</filename>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-c</option></term>
|
|
|
|
<listitem>
|
|
<para>Sort the output by cost instead of alphabetically by user
|
|
name.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-m</option></term>
|
|
|
|
<listitem>
|
|
<para>Ignore host name in the accounting files. With this
|
|
option, user <username>smith</username> on host
|
|
<hostid>alpha</hostid> is the same user
|
|
<username>smith</username> on host <hostid>gamma</hostid>.
|
|
Without, they are different users.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-p<replaceable>price</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>Compute charges with <replaceable>price</replaceable>
|
|
dollars per page or per foot instead of the price from the
|
|
<literal>pc</literal> capability in
|
|
<filename>/etc/printcap</filename>, or two cents (the
|
|
default). You can specify <replaceable>price</replaceable> as
|
|
a floating point number.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-r</option></term>
|
|
|
|
<listitem>
|
|
<para>Reverse the sort order.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-s</option></term>
|
|
|
|
<listitem>
|
|
<para>Make an accounting summary file and truncate the
|
|
accounting file.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><replaceable>name</replaceable>
|
|
<replaceable>…</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>Print accounting information for the given user
|
|
<replaceable>names</replaceable> only.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>In the default summary that &man.pac.8; produces, you see the
|
|
number of pages printed by each user from various hosts. If, at
|
|
your site, host does not matter (because users can use any host),
|
|
run <command>pac -m</command>, to produce the following
|
|
summary:</para>
|
|
|
|
<screen> Login pages/feet runs price
|
|
andy 2.00 1 $ 0.04
|
|
kelly 182.00 105 $ 3.64
|
|
mary 118.00 35 $ 2.36
|
|
root 26.00 12 $ 0.52
|
|
zhang 9.00 1 $ 0.18
|
|
|
|
total 337.00 154 $ 6.74</screen>
|
|
|
|
|
|
<para>To compute the dollar amount due,
|
|
&man.pac.8; uses the <literal>pc</literal> capability in the
|
|
<filename>/etc/printcap</filename> file (default of 200, or 2 cents
|
|
per page). Specify, in hundredths of cents, the price per page or
|
|
per foot you want to charge for printouts in this capability. You
|
|
can override this value when you run &man.pac.8; with the
|
|
<option>-p</option> option. The units for the <option>-p</option>
|
|
option are in dollars, though, not hundredths of cents. For
|
|
example,
|
|
|
|
<screen>&prompt.root; <userinput>pac -p1.50</userinput></screen>
|
|
|
|
makes each page cost one dollar and fifty cents. You can really
|
|
rake in the profits by using this option.</para>
|
|
|
|
<para>Finally, running <command>pac -s</command> will save the summary
|
|
information in a summary accounting file, which is named the same as
|
|
the printer's accounting file, but with <literal>_sum</literal>
|
|
appended to the name. It then truncates the accounting file. When
|
|
you run &man.pac.8; again, it rereads the
|
|
summary file to get starting totals, then adds information from the
|
|
regular accounting file.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>How Can You Count Pages Printed?</title>
|
|
|
|
<para>In order to perform even remotely accurate accounting, you need
|
|
to be able to determine how much paper a job uses. This is the
|
|
essential problem of printer accounting.</para>
|
|
|
|
<para>For plain text jobs, the problem is not that hard to solve: you
|
|
count how many lines are in a job and compare it to how many lines
|
|
per page your printer supports. Do not forget to take into account
|
|
backspaces in the file which overprint lines, or long logical lines
|
|
that wrap onto one or more additional physical lines.</para>
|
|
|
|
<para>The text filter <command>lpf</command> (introduced in <link
|
|
linkend="printing-advanced-lpf">lpf: a Text Filter</link>) takes
|
|
into account these things when it does accounting. If you are
|
|
writing a text filter which needs to do accounting, you might want
|
|
to examine <command>lpf</command>'s source code.</para>
|
|
|
|
<para>How do you handle other file formats, though?</para>
|
|
|
|
<para>Well, for DVI-to-LaserJet or DVI-to-PostScript conversion, you
|
|
can have your filter parse the diagnostic output of
|
|
<command>dvilj</command> or <command>dvips</command> and look to see
|
|
how many pages were converted. You might be able to do similar
|
|
things with other file formats and conversion programs.</para>
|
|
|
|
<para>But these methods suffer from the fact that the printer may not
|
|
actually print all those pages. For example, it could jam, run out
|
|
of toner, or explode—and the user would still get
|
|
charged.</para>
|
|
|
|
<para>So, what can you do?</para>
|
|
|
|
<para>There is only one <emphasis>sure</emphasis> way to do
|
|
<emphasis>accurate</emphasis> accounting. Get a printer that can
|
|
tell you how much paper it uses, and attach it via a serial line or
|
|
a network connection. Nearly all PostScript printers support this
|
|
notion. Other makes and models do as well (networked Imagen laser
|
|
printers, for example). Modify the filters for these printers to
|
|
get the page usage after they print each job and have them log
|
|
accounting information based on that value
|
|
<emphasis>only</emphasis>. There is no line counting nor
|
|
error-prone file examination required.</para>
|
|
|
|
<para>Of course, you can always be generous and make all printouts
|
|
free.</para>
|
|
</sect3>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="printing-using">
|
|
<title>Using Printers</title>
|
|
|
|
<indexterm>
|
|
<primary>printer</primary>
|
|
<secondary>usage</secondary>
|
|
</indexterm>
|
|
<para>This section tells you how to use printers you have setup with
|
|
FreeBSD. Here is an overview of the user-level commands:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>&man.lpr.1;</term>
|
|
|
|
<listitem>
|
|
<para>Print jobs</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>&man.lpq.1;</term>
|
|
|
|
<listitem>
|
|
<para>Check printer queues</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>&man.lprm.1;</term>
|
|
|
|
<listitem>
|
|
<para>Remove jobs from a printer's queue</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>There is also an administrative command, &man.lpc.8;, described in
|
|
the section <link linkend="printing-lpc">Administrating the
|
|
<application>LPD</application>
|
|
Spooler</link>, used to control printers and their queues.</para>
|
|
|
|
<para>All three of the commands &man.lpr.1;, &man.lprm.1;, and &man.lpq.1;
|
|
accept an option <option>-P
|
|
<replaceable>printer-name</replaceable></option> to specify on which
|
|
printer/queue to operate, as listed in the
|
|
<filename>/etc/printcap</filename> file. This enables you to submit,
|
|
remove, and check on jobs for various printers. If you do not use the
|
|
<option>-P</option> option, then these commands use the printer
|
|
specified in the <envar>PRINTER</envar> environment variable. Finally,
|
|
if you do not have a <envar>PRINTER</envar> environment variable, these
|
|
commands default to the printer named <literal>lp</literal>.</para>
|
|
|
|
<para>Hereafter, the terminology <emphasis>default printer</emphasis>
|
|
means the printer named in the <envar>PRINTER</envar> environment
|
|
variable, or the printer named <literal>lp</literal> when there is no
|
|
<envar>PRINTER</envar> environment variable.</para>
|
|
|
|
<sect2 id="printing-lpr">
|
|
<title>Printing Jobs</title>
|
|
|
|
<para>To print files, type:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lpr <replaceable>filename</replaceable> <replaceable>...</replaceable></userinput></screen>
|
|
|
|
<indexterm><primary>printing</primary></indexterm>
|
|
<para>This prints each of the listed files to the default printer. If
|
|
you list no files, &man.lpr.1; reads data to
|
|
print from standard input. For example, this command prints some
|
|
important system files:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lpr /etc/host.conf /etc/hosts.equiv</userinput></screen>
|
|
|
|
<para>To select a specific printer, type:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lpr -P <replaceable>printer-name</replaceable> <replaceable>filename</replaceable> <replaceable>...</replaceable></userinput></screen>
|
|
|
|
<para>This example prints a long listing of the current directory to the
|
|
printer named <literal>rattan</literal>:</para>
|
|
|
|
<screen>&prompt.user; <userinput>ls -l | lpr -P rattan</userinput></screen>
|
|
|
|
<para>Because no files were listed for the
|
|
&man.lpr.1; command, <command>lpr</command> read the data to print
|
|
from standard input, which was the output of the <command>ls
|
|
-l</command> command.</para>
|
|
|
|
<para>The &man.lpr.1; command can also accept a wide variety of options
|
|
to control formatting, apply file conversions, generate multiple
|
|
copies, and so forth. For more information, see the section <link
|
|
linkend="printing-lpr-options">Printing Options</link>.</para>
|
|
</sect2>
|
|
|
|
<sect2 id="printing-lpq">
|
|
<title>Checking Jobs</title>
|
|
|
|
<indexterm><primary>print jobs</primary></indexterm>
|
|
<para>When you print with &man.lpr.1;, the data you wish to print is put
|
|
together in a package called a <quote>print job</quote>, which is sent
|
|
to the <application>LPD</application> spooling system. Each printer
|
|
has a queue of jobs, and
|
|
your job waits in that queue along with other jobs from yourself and
|
|
from other users. The printer prints those jobs in a first-come,
|
|
first-served order.</para>
|
|
|
|
<para>To display the queue for the default printer, type &man.lpq.1;.
|
|
For a specific printer, use the <option>-P</option> option. For
|
|
example, the command
|
|
|
|
<screen>&prompt.user; <userinput>lpq -P bamboo</userinput></screen>
|
|
|
|
shows the queue for the printer named <literal>bamboo</literal>. Here
|
|
is an example of the output of the <command>lpq</command>
|
|
command:</para>
|
|
|
|
<screen>bamboo is ready and printing
|
|
Rank Owner Job Files Total Size
|
|
active kelly 9 /etc/host.conf, /etc/hosts.equiv 88 bytes
|
|
2nd kelly 10 (standard input) 1635 bytes
|
|
3rd mary 11 ... 78519 bytes</screen>
|
|
|
|
<para>This shows three jobs in the queue for <literal>bamboo</literal>.
|
|
The first job, submitted by user kelly, got assigned <quote>job
|
|
number</quote> 9. Every job for a printer gets a unique job number.
|
|
Most of the time you can ignore the job number, but you will need it
|
|
if you want to cancel the job; see section <link
|
|
linkend="printing-lprm">Removing Jobs</link> for details.</para>
|
|
|
|
<para>Job number nine consists of two files; multiple files given on the
|
|
&man.lpr.1; command line are treated as part of a single job. It
|
|
is the currently active job (note the word <literal>active</literal>
|
|
under the <quote>Rank</quote> column), which means the printer should
|
|
be currently printing that job. The second job consists of data
|
|
passed as the standard input to the &man.lpr.1; command. The third
|
|
job came from user <username>mary</username>; it is a much larger
|
|
job. The pathname of the file she is trying to print is too long to
|
|
fit, so the &man.lpq.1; command just shows three dots.</para>
|
|
|
|
<para>The very first line of the output from &man.lpq.1; is also useful:
|
|
it tells what the printer is currently doing (or at least what
|
|
<application>LPD</application> thinks the printer is doing).</para>
|
|
|
|
<para>The &man.lpq.1; command also support a <option>-l</option> option
|
|
to generate a detailed long listing. Here is an example of
|
|
<command>lpq -l</command>:</para>
|
|
|
|
<screen>waiting for bamboo to become ready (offline ?)
|
|
kelly: 1st [job 009rose]
|
|
/etc/host.conf 73 bytes
|
|
/etc/hosts.equiv 15 bytes
|
|
|
|
kelly: 2nd [job 010rose]
|
|
(standard input) 1635 bytes
|
|
|
|
mary: 3rd [job 011rose]
|
|
/home/orchid/mary/research/venus/alpha-regio/mapping 78519 bytes</screen>
|
|
</sect2>
|
|
|
|
<sect2 id="printing-lprm">
|
|
<title>Removing Jobs</title>
|
|
|
|
<para>If you change your mind about printing a job, you can remove the
|
|
job from the queue with the &man.lprm.1; command. Often, you can
|
|
even use &man.lprm.1; to remove an active job, but some or all of the
|
|
job might still get printed.</para>
|
|
|
|
<para>To remove a job from the default printer, first use
|
|
&man.lpq.1; to find the job number. Then type:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lprm <replaceable>job-number</replaceable></userinput></screen>
|
|
|
|
<para>To remove the job from a specific printer, add the
|
|
<option>-P</option> option. The following command removes job number
|
|
10 from the queue for the printer <literal>bamboo</literal>:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lprm -P bamboo 10</userinput></screen>
|
|
|
|
<para>The &man.lprm.1; command has a few shortcuts:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>lprm -</term>
|
|
|
|
<listitem>
|
|
<para>Removes all jobs (for the default printer) belonging to
|
|
you.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>lprm <replaceable>user</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>Removes all jobs (for the default printer) belonging to
|
|
<replaceable>user</replaceable>. The superuser can remove other
|
|
users' jobs; you can remove only your own jobs.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>lprm</term>
|
|
|
|
<listitem>
|
|
<para>With no job number, user name, or <option>-</option>
|
|
appearing on the command line,
|
|
&man.lprm.1; removes the currently active job on the
|
|
default printer, if it belongs to you. The superuser can remove
|
|
any active job.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>Just use the <option>-P</option> option with the above shortcuts
|
|
to operate on a specific printer instead of the default. For example,
|
|
the following command removes all jobs for the current user in the
|
|
queue for the printer named <literal>rattan</literal>:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lprm -P rattan -</userinput></screen>
|
|
|
|
<note>
|
|
<para>If you are working in a networked environment, &man.lprm.1; will
|
|
let you remove jobs only from the
|
|
host from which the jobs were submitted, even if the same printer is
|
|
available from other hosts. The following command sequence
|
|
demonstrates this:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lpr -P rattan myfile</userinput>
|
|
&prompt.user; <userinput>rlogin orchid</userinput>
|
|
&prompt.user; <userinput>lpq -P rattan</userinput>
|
|
Rank Owner Job Files Total Size
|
|
active seeyan 12 ... 49123 bytes
|
|
2nd kelly 13 myfile 12 bytes
|
|
&prompt.user; <userinput>lprm -P rattan 13</userinput>
|
|
rose: Permission denied
|
|
&prompt.user; <userinput>logout</userinput>
|
|
&prompt.user; <userinput>lprm -P rattan 13</userinput>
|
|
dfA013rose dequeued
|
|
cfA013rose dequeued
|
|
</screen>
|
|
</note>
|
|
</sect2>
|
|
|
|
<sect2 id="printing-lpr-options">
|
|
<title>Beyond Plain Text: Printing Options</title>
|
|
|
|
<para>The &man.lpr.1; command supports a number of options that control
|
|
formatting text, converting graphic and other file formats, producing
|
|
multiple copies, handling of the job, and more. This section
|
|
describes the options.</para>
|
|
|
|
<sect3 id="printing-lpr-options-format">
|
|
<title>Formatting and Conversion Options</title>
|
|
|
|
<para>The following &man.lpr.1; options control formatting of the
|
|
files in the job. Use these options if the job does not contain
|
|
plain text or if you want plain text formatted through the
|
|
&man.pr.1; utility.</para>
|
|
|
|
<indexterm><primary>TeX</primary></indexterm>
|
|
<para>For example, the following command prints a DVI file (from the
|
|
TeX typesetting system) named <filename>fish-report.dvi</filename>
|
|
to the printer named <literal>bamboo</literal>:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lpr -P bamboo -d fish-report.dvi</userinput></screen>
|
|
|
|
<para>These options apply to every file in the job, so you cannot mix
|
|
(say) DVI and ditroff files together in a job. Instead, submit the
|
|
files as separate jobs, using a different conversion option for each
|
|
job.</para>
|
|
|
|
<note>
|
|
<para>All of these options except <option>-p</option> and
|
|
<option>-T</option> require conversion filters installed for the
|
|
destination printer. For example, the <option>-d</option> option
|
|
requires the DVI conversion filter. Section <link
|
|
linkend="printing-advanced-convfilters">Conversion
|
|
Filters</link> gives details.</para>
|
|
</note>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>-c</option></term>
|
|
|
|
<listitem>
|
|
<para>Print cifplot files.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-d</option></term>
|
|
|
|
<listitem>
|
|
<para>Print DVI files.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-f</option></term>
|
|
|
|
<listitem>
|
|
<para>Print FORTRAN text files.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-g</option></term>
|
|
|
|
<listitem>
|
|
<para>Print plot data.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-i <replaceable>number</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>Indent the output by <replaceable>number</replaceable>
|
|
columns; if you omit <replaceable>number</replaceable>, indent
|
|
by 8 columns. This option works only with certain conversion
|
|
filters.</para>
|
|
|
|
<note>
|
|
<para>Do not put any space between the <option>-i</option> and
|
|
the number.</para>
|
|
</note>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-l</option></term>
|
|
|
|
<listitem>
|
|
<para>Print literal text data, including control
|
|
characters.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-n</option></term>
|
|
|
|
<listitem>
|
|
<para>Print ditroff (device independent troff) data.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-p</term>
|
|
|
|
<listitem>
|
|
<para>Format plain text with &man.pr.1; before printing. See
|
|
&man.pr.1; for more information.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-T <replaceable>title</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>Use <replaceable>title</replaceable> on the
|
|
&man.pr.1; header instead of the file name. This option has
|
|
effect only when used with the <option>-p</option>
|
|
option.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-t</option></term>
|
|
|
|
<listitem>
|
|
<para>Print troff data.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-v</option></term>
|
|
|
|
<listitem>
|
|
<para>Print raster data.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>Here is an example: this command prints a nicely formatted
|
|
version of the &man.ls.1; manual page on the default printer:</para>
|
|
|
|
<screen>&prompt.user; <userinput>zcat /usr/share/man/man1/ls.1.gz | troff -t -man | lpr -t</userinput></screen>
|
|
|
|
<para>The &man.zcat.1; command uncompresses the source of the
|
|
&man.ls.1; manual page and passes it to the &man.troff.1;
|
|
command, which formats that source and makes GNU troff
|
|
output and passes it to &man.lpr.1;, which submits the job
|
|
to the <application>LPD</application> spooler. Because we
|
|
used the <option>-t</option>
|
|
option to &man.lpr.1;, the spooler will convert the GNU
|
|
troff output into a format the default printer can
|
|
understand when it prints the job.</para>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-lpr-options-job-handling">
|
|
<title>Job Handling Options</title>
|
|
|
|
<para>The following options to &man.lpr.1; tell
|
|
<application>LPD</application> to handle the job
|
|
specially:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>-# <replaceable>copies</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>Produce a number of <replaceable>copies</replaceable> of
|
|
each file in the job instead of just one copy. An
|
|
administrator may disable this option to reduce printer
|
|
wear-and-tear and encourage photocopier usage. See section
|
|
<link
|
|
linkend="printing-advanced-restricting-copies">Restricting
|
|
Multiple Copies</link>.</para>
|
|
|
|
<para>This example prints three copies of
|
|
<filename>parser.c</filename> followed by three copies of
|
|
<filename>parser.h</filename> to the default printer:</para>
|
|
|
|
<screen>&prompt.user; <userinput>lpr -#3 parser.c parser.h</userinput></screen>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-m</term>
|
|
|
|
<listitem>
|
|
<para>Send mail after completing the print job. With this
|
|
option, the <application>LPD</application> system will send
|
|
mail to your account when it
|
|
finishes handling your job. In its message, it will tell you
|
|
if the job completed successfully or if there was an error,
|
|
and (often) what the error was.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-s</term>
|
|
|
|
<listitem>
|
|
<para>Do not copy the files to the spooling directory, but make
|
|
symbolic links to them instead.</para>
|
|
|
|
<para>If you are printing a large job, you probably want to use
|
|
this option. It saves space in the spooling directory (your
|
|
job might overflow the free space on the filesystem where the
|
|
spooling directory resides). It saves time as well since
|
|
<application>LPD</application>
|
|
will not have to copy each and every byte of your job to the
|
|
spooling directory.</para>
|
|
|
|
<para>There is a drawback, though: since
|
|
<application>LPD</application> will refer to the
|
|
original files directly, you cannot modify or remove them
|
|
until they have been printed.</para>
|
|
|
|
<note>
|
|
<para>If you are printing to a remote printer,
|
|
<application>LPD</application> will
|
|
eventually have to copy files from the local host to the
|
|
remote host, so the <option>-s</option> option will save
|
|
space only on the local spooling directory, not the remote.
|
|
It is still useful, though.</para>
|
|
</note>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-r</term>
|
|
|
|
<listitem>
|
|
<para>Remove the files in the job after copying them to the
|
|
spooling directory, or after printing them with the
|
|
<option>-s</option> option. Be careful with this
|
|
option!</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect3>
|
|
|
|
<sect3 id="printing-lpr-options-misc">
|
|
<title>Header Page Options</title>
|
|
|
|
<para>These options to &man.lpr.1; adjust the text that normally
|
|
appears on a job's header page. If header pages are suppressed for
|
|
the destination printer, these options have no effect. See section
|
|
<link linkend="printing-advanced-header-pages">Header Pages</link>
|
|
for information about setting up header pages.</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>-C <replaceable>text</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>Replace the hostname on the header page with
|
|
<replaceable>text</replaceable>. The hostname is normally the
|
|
name of the host from which the job was submitted.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-J <replaceable>text</replaceable></term>
|
|
|
|
<listitem>
|
|
<para>Replace the job name on the header page with
|
|
<replaceable>text</replaceable>. The job name is normally the
|
|
name of the first file of the job, or
|
|
<filename>stdin</filename> if you are printing standard
|
|
input.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>-h</term>
|
|
|
|
<listitem>
|
|
<para>Do not print any header page.</para>
|
|
|
|
<note>
|
|
<para>At some sites, this option may have no effect due to the
|
|
way header pages are generated. See <link
|
|
linkend="printing-advanced-header-pages">Header
|
|
Pages</link> for details.</para>
|
|
</note>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="printing-lpc">
|
|
<title>Administrating Printers</title>
|
|
|
|
<para>As an administrator for your printers, you have had to install,
|
|
set up, and test them. Using the &man.lpc.8; command, you
|
|
can interact with your printers in yet more ways. With &man.lpc.8;,
|
|
you can</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Start and stop the printers</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Enable and disable their queues</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Rearrange the order of the jobs in each queue.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>First, a note about terminology: if a printer is
|
|
<emphasis>stopped</emphasis>, it will not print anything in its queue.
|
|
Users can still submit jobs, which will wait in the queue until the
|
|
printer is <emphasis>started</emphasis> or the queue is
|
|
cleared.</para>
|
|
|
|
<para>If a queue is <emphasis>disabled</emphasis>, no user (except root)
|
|
can submit jobs for the printer. An <emphasis>enabled</emphasis>
|
|
queue allows jobs to be submitted. A printer can be
|
|
<emphasis>started</emphasis> for a disabled queue, in which case it
|
|
will continue to print jobs in the queue until the queue is
|
|
empty.</para>
|
|
|
|
<para>In general, you have to have root privileges to use the
|
|
&man.lpc.8; command. Ordinary users can use the &man.lpc.8; command
|
|
to get printer status and to restart a hung printer only.</para>
|
|
|
|
<para>Here is a summary of the &man.lpc.8; commands. Most of the
|
|
commands take a <replaceable>printer-name</replaceable> argument to
|
|
tell on which printer to operate. You can use <literal>all</literal>
|
|
for the <replaceable>printer-name</replaceable> to mean all printers
|
|
listed in <filename>/etc/printcap</filename>.</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><command>abort
|
|
<replaceable>printer-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Cancel the current job and stop the printer. Users can
|
|
still submit jobs if the queue is enabled.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>clean
|
|
<replaceable>printer-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Remove old files from the printer's spooling directory.
|
|
Occasionally, the files that make up a job are not properly
|
|
removed by <application>LPD</application>, particularly if
|
|
there have been errors during
|
|
printing or a lot of administrative activity. This command
|
|
finds files that do not belong in the spooling directory and
|
|
removes them.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>disable
|
|
<replaceable>printer-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Disable queuing of new jobs. If the printer is running, it
|
|
will continue to print any jobs remaining in the queue. The
|
|
superuser (root) can always submit jobs, even to a disabled
|
|
queue.</para>
|
|
|
|
<para>This command is useful while you are testing a new printer
|
|
or filter installation: disable the queue and submit jobs as
|
|
root. Other users will not be able to submit jobs until you
|
|
complete your testing and re-enable the queue with the
|
|
<command>enable</command> command.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>down <replaceable>printer-name</replaceable>
|
|
<replaceable>message</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Take a printer down. Equivalent to
|
|
<command>disable</command> followed by <command>stop</command>.
|
|
The <replaceable>message</replaceable> appears as the printer's
|
|
status whenever a user checks the printer's queue with
|
|
&man.lpq.1; or status with <command>lpc
|
|
status</command>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>enable
|
|
<replaceable>printer-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Enable the queue for a printer. Users can submit jobs but
|
|
the printer will not print anything until it is started.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>help
|
|
<replaceable>command-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Print help on the command
|
|
<replaceable>command-name</replaceable>. With no
|
|
<replaceable>command-name</replaceable>, print a summary of the
|
|
commands available.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>restart
|
|
<replaceable>printer-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Start the printer. Ordinary users can use this command if
|
|
some extraordinary circumstance hangs
|
|
<application>LPD</application>, but they cannot start
|
|
a printer stopped with either the <command>stop</command> or
|
|
<command>down</command> commands. The
|
|
<command>restart</command> command is equivalent to
|
|
<command>abort</command> followed by
|
|
<command>start</command>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>start
|
|
<replaceable>printer-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Start the printer. The printer will print jobs in its
|
|
queue.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>stop
|
|
<replaceable>printer-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Stop the printer. The printer will finish the current job
|
|
and will not print anything else in its queue. Even though the
|
|
printer is stopped, users can still submit jobs to an enabled
|
|
queue.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>topq <replaceable>printer-name</replaceable>
|
|
<replaceable>job-or-username</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Rearrange the queue for
|
|
<replaceable>printer-name</replaceable> by placing the jobs with
|
|
the listed <replaceable>job</replaceable> numbers or the jobs
|
|
belonging to <replaceable>username</replaceable> at the top of
|
|
the queue. For this command, you cannot use
|
|
<literal>all</literal> as the
|
|
<replaceable>printer-name</replaceable>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><command>up
|
|
<replaceable>printer-name</replaceable></command></term>
|
|
|
|
<listitem>
|
|
<para>Bring a printer up; the opposite of the
|
|
<command>down</command> command. Equivalent to
|
|
<command>start</command> followed by
|
|
<command>enable</command>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>&man.lpc.8; accepts the above commands on the command line. If
|
|
you do not enter any commands, &man.lpc.8; enters an interactive mode,
|
|
where you can enter commands until you type <command>exit</command>,
|
|
<command>quit</command>, or end-of-file.</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="printing-lpd-alternatives">
|
|
<title>Alternatives to the Standard Spooler</title>
|
|
|
|
<para>If you have been reading straight through this manual, by now you
|
|
have learned just about everything there is to know about the
|
|
<application>LPD</application>
|
|
spooling system that comes with FreeBSD. You can probably appreciate
|
|
many of its shortcomings, which naturally leads to the question:
|
|
<quote>What other spooling systems are out there (and work with
|
|
FreeBSD)?</quote></para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>LPRng</term>
|
|
|
|
<indexterm><primary>LPRng</primary></indexterm>
|
|
<listitem>
|
|
<para><application>LPRng</application>, which purportedly means
|
|
<quote>LPR: the Next
|
|
Generation</quote> is a complete rewrite of PLP. Patrick Powell
|
|
and Justin Mason (the principal maintainer of PLP) collaborated to
|
|
make <application>LPRng</application>. The main site for
|
|
<application>LPRng</application> is <ulink
|
|
url="http://www.astart.com/lprng/LPRng.html">http://www.astart.com/lprng/LPRng.html</ulink>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect1>
|
|
|
|
<sect1 id="printing-troubleshooting">
|
|
<title>Troubleshooting</title>
|
|
|
|
<para>After performing the simple test with &man.lptest.1;, you might
|
|
have gotten one of the following results instead of the correct
|
|
printout:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>It worked, after awhile; or, it did not eject a full
|
|
sheet.</term>
|
|
|
|
<listitem>
|
|
<para>The printer printed the above, but it sat for awhile and
|
|
did nothing. In fact, you might have needed to press a
|
|
PRINT REMAINING or FORM FEED button on the printer to get any
|
|
results to appear.</para>
|
|
|
|
<para>If this is the case, the printer was probably waiting to
|
|
see if there was any more data for your job before it printed
|
|
anything. To fix this problem, you can have the text filter
|
|
send a FORM FEED character (or whatever is necessary) to the
|
|
printer. This is usually sufficient to have the printer
|
|
immediately print any text remaining in its internal buffer.
|
|
It is also useful to make sure each print job ends on a full
|
|
sheet, so the next job does not start somewhere on the middle
|
|
of the last page of the previous job.</para>
|
|
|
|
<para>The following replacement for the shell script
|
|
<filename>/usr/local/libexec/if-simple</filename> prints a
|
|
form feed after it sends the job to the printer:</para>
|
|
|
|
<programlisting>#!/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.
|
|
# Writes a form feed character (\f) after printing job.
|
|
|
|
/bin/cat && printf "\f" && exit 0
|
|
exit 2</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>It produced the <quote>staircase effect.</quote></term>
|
|
|
|
<listitem>
|
|
<para>You got the following on paper:</para>
|
|
|
|
<programlisting>!"#$%&'()*+,-./01234
|
|
"#$%&'()*+,-./012345
|
|
#$%&'()*+,-./0123456</programlisting>
|
|
|
|
<indexterm><primary>MS-DOS</primary></indexterm>
|
|
<indexterm><primary>OS/2</primary></indexterm>
|
|
<indexterm><primary>ASCII</primary></indexterm>
|
|
<para>You have become another victim of the <emphasis>staircase
|
|
effect</emphasis>, caused by conflicting interpretations of
|
|
what characters should indicate a new line. Unix-style
|
|
operating systems use a single character: ASCII code 10, the
|
|
line feed (LF). MS-DOS, OS/2, and others uses a pair of
|
|
characters, ASCII code 10 <emphasis>and</emphasis> ASCII code
|
|
13 (the carriage return or CR). Many printers use the MS-DOS
|
|
convention for representing new-lines.</para>
|
|
|
|
<para>When you print with FreeBSD, your text used just the line
|
|
feed character. The printer, upon seeing a line feed
|
|
character, advanced the paper one line, but maintained the
|
|
same horizontal position on the page for the next character
|
|
to print. That is what the carriage return is for: to move
|
|
the location of the next character to print to the left edge
|
|
of the paper.</para>
|
|
|
|
<para>Here is what FreeBSD wants your printer to do:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<tbody>
|
|
<row>
|
|
<entry>Printer received CR</entry>
|
|
<entry>Printer prints CR</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>Printer received LF</entry>
|
|
<entry>Printer prints CR + LF</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Here are some ways to achieve this:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Use the printer's configuration switches or control
|
|
panel to alter its interpretation of these characters.
|
|
Check your printer's manual to find out how to do
|
|
this.</para>
|
|
|
|
<note>
|
|
<para>If you boot your system into other operating systems
|
|
besides FreeBSD, you may have to
|
|
<emphasis>reconfigure</emphasis> the printer to use a an
|
|
interpretation for CR and LF characters that those other
|
|
operating systems use. You might prefer one of the other
|
|
solutions, below.</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Have FreeBSD's serial line driver automatically
|
|
convert LF to CR+LF. Of course, this works with printers
|
|
on serial ports <emphasis>only</emphasis>. To enable this
|
|
feature, set the <literal>CRMOD</literal> bit
|
|
in <literal>fs</literal>
|
|
capability in the <filename>/etc/printcap</filename> file
|
|
for the printer.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Send an <emphasis>escape code</emphasis> to the
|
|
printer to have it temporarily treat LF characters
|
|
differently. Consult your printer's manual for escape
|
|
codes that your printer might support. When you find the
|
|
proper escape code, modify the text filter to send the
|
|
code first, then send the print job.</para>
|
|
|
|
<indexterm><primary>PCL</primary></indexterm>
|
|
<para>Here is an example text filter for printers that
|
|
understand the Hewlett-Packard PCL escape codes. This
|
|
filter makes the printer treat LF characters as a LF and
|
|
CR; then it sends the job; then it sends a form feed to
|
|
eject the last page of the job. It should work with
|
|
nearly all Hewlett Packard printers.</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
#
|
|
# hpif - Simple text input filter for lpd for HP-PCL based printers
|
|
# Installed in /usr/local/libexec/hpif
|
|
#
|
|
# Simply copies stdin to stdout. Ignores all filter arguments.
|
|
# Tells printer to treat LF as CR+LF. Ejects the page when done.
|
|
|
|
printf "\033&k2G" && cat && printf "\033&l0H" && exit 0
|
|
exit 2</programlisting>
|
|
|
|
<para>Here is an example <filename>/etc/printcap</filename>
|
|
from a host called <hostid>orchid</hostid>. It has a single printer
|
|
attached to its first parallel port, a Hewlett Packard
|
|
LaserJet 3Si named <literal>teak</literal>. It is using the
|
|
above script as its text filter:</para>
|
|
|
|
<programlisting>#
|
|
# /etc/printcap for host orchid
|
|
#
|
|
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
|
|
:lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\
|
|
:if=/usr/local/libexec/hpif:</programlisting>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>It overprinted each line.</term>
|
|
|
|
<listitem>
|
|
<para>The printer never advanced a line. All of the lines of
|
|
text were printed on top of each other on one line.</para>
|
|
|
|
<para>This problem is the <quote>opposite</quote> of the
|
|
staircase effect, described above, and is much rarer.
|
|
Somewhere, the LF characters that FreeBSD uses to end a line
|
|
are being treated as CR characters to return the print
|
|
location to the left edge of the paper, but not also down a
|
|
line.</para>
|
|
|
|
<para>Use the printer's configuration switches or control panel
|
|
to enforce the following interpretation of LF and CR
|
|
characters:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<thead>
|
|
<row>
|
|
<entry>Printer receives</entry>
|
|
<entry>Printer prints</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry>CR</entry>
|
|
<entry>CR</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>LF</entry>
|
|
<entry>CR + LF</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>The printer lost characters.</term>
|
|
|
|
<listitem>
|
|
<para>While printing, the printer did not print a few characters
|
|
in each line. The problem might have gotten worse as the
|
|
printer ran, losing more and more characters.</para>
|
|
|
|
<para>The problem is that the printer cannot keep up with the
|
|
speed at which the computer sends data over a serial line
|
|
(this problem should not occur with printers on parallel
|
|
ports). There are two ways to overcome the problem:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>If the printer supports XON/XOFF flow control, have
|
|
FreeBSD use it by specifying the TANDEM bit in the
|
|
<literal>fs</literal> capability.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>If the printer supports carrier flow control, specify
|
|
the <literal>MDMBUF</literal> bit in the
|
|
<literal>fs</literal> capability.
|
|
Make sure the cable connecting the printer to the computer
|
|
is correctly wired for carrier flow control.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>If the printer does not support any flow control, use
|
|
some combination of the <literal>NLDELAY</literal>,
|
|
<literal>TBDELAY</literal>, <literal>CRDELAY</literal>,
|
|
<literal>VTDELAY</literal>, and <literal>BSDELAY</literal>
|
|
bits in the <literal>fs</literal> capability
|
|
to add appropriate delays to the stream of data sent to
|
|
the printer.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>It printed garbage.</term>
|
|
|
|
<listitem>
|
|
<para>The printer printed what appeared to be random garbage,
|
|
but not the desired text.</para>
|
|
|
|
<para>This is usually another symptom of incorrect
|
|
communications parameters with a serial printer. Double-check
|
|
the bps rate in the <literal>br</literal> capability, and the
|
|
parity bits in the <literal>fs</literal> and
|
|
<literal>fc</literal> capabilities; make sure the printer is
|
|
using the same settings as specified in the
|
|
<filename>/etc/printcap</filename> file.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>Nothing happened.</term>
|
|
|
|
<listitem>
|
|
<para>If nothing happened, the problem is probably within
|
|
FreeBSD and not the hardware. Add the log file
|
|
(<literal>lf</literal>) capability to the entry for the
|
|
printer you are debugging in the
|
|
<filename>/etc/printcap</filename> file. For example, here is
|
|
the entry for <literal>rattan</literal>, with the
|
|
<literal>lf</literal> capability:</para>
|
|
|
|
<programlisting>rattan|line|diablo|lp|Diablo 630 Line Printer:\
|
|
:sh:sd=/var/spool/lpd/rattan:\
|
|
:lp=/dev/lpt0:\
|
|
:if=/usr/local/libexec/if-simple:\
|
|
:lf=/var/log/rattan.log</programlisting>
|
|
|
|
<para>Then, try printing again. Check the log file (in our
|
|
example, <filename>/var/log/rattan.log</filename>) to see any
|
|
error messages that might appear. Based on the messages you
|
|
see, try to correct the problem.</para>
|
|
|
|
<para>If you do not specify a <literal>lf</literal> capability,
|
|
<application>LPD</application> uses
|
|
<filename>/dev/console</filename> as a default.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect1>
|
|
</chapter>
|
|
|
|
<!--
|
|
Local Variables:
|
|
mode: sgml
|
|
sgml-declaration: "../chapter.decl"
|
|
sgml-indent-data: t
|
|
sgml-omittag: nil
|
|
sgml-always-quote-attributes: t
|
|
sgml-parent-document: ("../book.sgml" "part" "chapter")
|
|
End:
|
|
-->
|
|
|
|
|