summaryrefslogtreecommitdiffstats
path: root/share/doc/handbook/printing.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'share/doc/handbook/printing.sgml')
-rw-r--r--share/doc/handbook/printing.sgml3876
1 files changed, 0 insertions, 3876 deletions
diff --git a/share/doc/handbook/printing.sgml b/share/doc/handbook/printing.sgml
deleted file mode 100644
index 4dfda87..0000000
--- a/share/doc/handbook/printing.sgml
+++ /dev/null
@@ -1,3876 +0,0 @@
-<!-- This is an SGML document in the linuxdoc DTD describing
- Printing with FreeBSD. By Sean Kelly, 1995.
-
- $Id$
-
- The FreeBSD Documentation Project
-
-<!DOCTYPE linuxdoc PUBLIC "-//FreeBSD//DTD linuxdoc//EN">
-
- <article>
- <title> Printing with FreeBSD
- <author> Sean Kelly <tt/kelly@fsl.noaa.gov/
- <date> 30 September 1995, (c) 1995
-
- <abstract> This document describes printing with FreeBSD. It
- tells how to set up printer hardware, how to configure FreeBSD
- to use printers, and how to control the print queue and print
- a variety of file formats. </abstract>
-
- <toc>
--->
-
- <chapt><heading>Printing<label id="printing"></heading>
-
- <p><em>Contributed by &a.kelly;<newline>30 September 1995</em>
-
- 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 LPD spooling system. It is the
- standard printer control system in FreeBSD. This section
- introduces the LPD spooling system, often simply called LPD.
-
- If you are already familiar with LPD or another printer
- spooling system, you may wish to skip to section <ref
- id="printing:intro:setup" name="Setting up the spooling
- system">.
-
- <sect><heading>What the Spooler Does<label
- id="printing:intro:spooler"></heading>
-
- <p> LPD controls everything about a host's printers. It is
- responsible for a number of things:
-
- <itemize>
- <item>It controls access to attached printers and
- printers attached to other hosts on the network.
-
- <item>It enables users to submit files to be printed;
- these submissions are known as <em/jobs/.
-
- <item>It prevents multiple users from accessing a printer
- at the same time by maintaining a <em/queue/ for each
- printer.
-
- <item>It can print <em/header pages/ (also known as
- <em/banner/ or <em/burst/ pages) so users can easily
- find jobs they have printed in a stack of printouts.
-
- <item>It takes care of communications parameters for
- printers connected on serial ports.
-
- <item>It can send jobs over the network to another LPD
- spooler on another host.
-
- <item>It can run special filters to format jobs to be
- printed for various printer languages or printer
- capabilities.
-
- <item>It can account for printer usage.
- </itemize>
-
- Through a configuration file, and by providing the special
- filter programs, you can enable the LPD system to do all or
- some subset of the above for a great variety of printer
- hardware.
-
- <sect><heading>Why You Should Use the Spooler<label
- id="printing:intro:why"></heading>
-
- <p> 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
-
- <itemize>
- <item>LPD prints jobs in the background; you do not have
- to wait for data to be copied to the printer.
-
- <item>LPD 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.
-
- <item>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.
- </itemize>
-
- <sect><heading>Setting Up the Spooling System<label
- id="printing:intro:setup"></heading>
-
- <p> To use printers with the LPD spooling system, you will need
- to set up both your printer hardware and the LPD software.
- This document describes two levels of setup:
-
- <itemize>
- <item>See section <ref name="Simple Printer Setup"
- id="printing:simple"> to learn how to connect a
- printer, tell LPD how to communicate with it, and
- print plain text files to the printer.
-
- <item>See section <ref name="Advanced Printer Setup"
- id="printing:advanced"> 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.
- </itemize>
-
-
- <sect><heading>Simple Printer Setup<label
- id="printing:simple"></heading>
-
- <p> This section tells how to configure printer hardware and the
- LPD software to use the printer. It teaches the basics:
-
- <itemize>
- <item>Section <ref id="printing:hardware" name="Hardware
- Setup"> gives some hints on connecting the printer to a
- port on your computer.
-
- <item>Section <ref id="printing:software" name="Software
- Setup"> shows how to setup the LPD spooler configuration
- file <tt>/etc/printcap</tt>.
- </itemize>
-
- 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 <ref id="printing:advanced:network:net-if" name="Printers
- With Networked Data Stream Interaces">.
-
- Although this section is called ``Simple Printer Setup,'' it is
- actually fairly complex. Getting the printer to work with
- your computer and the LPD spooler is the hardest part. The
- advanced options like header pages and accounting are fairly
- easy once you get the printer working.
-
- <sect1><heading>Hardware Setup<label id="printing:hardware"></heading>
-
- <p> This section tells about the various ways you can connect a
- printer to your PC. It talks about the kinds of ports and
- cables, and also the kernel configuration you may need to
- enable FreeBSD to speak to the printer.
-
- If you have already connected your printer and have
- successfully printed with it under another operating system,
- you can probably skip to section <ref id="printing:software"
- name="Software Setup">.
-
- <sect2><heading>Ports and Cables<label
- id="printing:ports"></heading>
-
- <p> Nearly all printers you can get for a PC today support
- one or both of the following interfaces:
-
- <itemize>
- <item><em/Serial/ 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.
-
- <item><em/Parallel/ 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.
-
- <p> Parallel interfaces are sometimes known as
- ``Centronics'' interfaces, named after the connector
- type on the printer.
- </itemize>
-
- 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 can also
- receive data from the printer, but only few printers need
- to send data back to the computer. And FreeBSD does not
- support two-way parallel communication yet.
-
- 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.
-
- So, which interface should you use?
-
- <itemize>
- <item>If you need two-way communication, use a serial
- port. FreeBSD does not yet support two-way
- communication over a parallel port.
-
- <item>If you do not need two-way communication and can
- pick parallel or serial, prefer the parallel
- interface. It keeps a serial port free for other
- peripherals---such as a terminal or a modem---and is
- faster most of the time. It is also easier to
- configure.
-
- <item>Finally, use whatever works.
- </itemize>
-
-
- <sect2><heading>Parallel Ports<label id="printing:parallel"></heading>
-
- <p> To hook up a printer using a parallel interface, connect
- the Centronics cable between the printer and the
- computer. The instructions that came with the printer, the
- computer, or both should give you complete guidance.
-
- Remember which parallel port you used on the computer. The
- first parallel port is /dev/lpt0 to FreeBSD; the second is
- /dev/lpt1, and so on.
-
- <sect2><heading>Serial Ports<label id="printing:serial"></heading>
-
- <p> To hook up a printer using a serial interface, connect
- the proper serial cable between the printer and the
- computer. The instructions that came with the printer,
- the computer, or both should give you complete guidance.
-
- If you are unsure what the ``proper serial cable'' is, you
- may wish to try one of the following alternatives:
- <itemize>
- <item>A <em/modem/ cable connects each pin of the
- connector on one end of the cable straight through to
- its corresponding pin of the connector on the other
- end. This type of cable is also known as a DTE-to-DCE
- cable.
-
- <item>A <em/null-modem/ cable connects some pins
- straight through, swaps others (send data to receive
- data, for example), and shorts some internally in each
- connector hood. This type of cable is also known as a
- DTE-to-DTE cable.
-
- <item>A <em/serial printer/ cable, required for some
- unusual printers, is like the null modem cable, but
- sends some signals to their counterparts instead of
- being internally shorted.
- </itemize>
-
- You should also set up the communications parameters for
- the printer, usually through front-panel controls or DIP
- switches on the printer. Choose the highest bps (bits per
- second, sometimes <em/baud rate/) 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 <em/in-band/ or <em/software/)
- flow control. Remember these settings for the software
- configuration that follows.
-
- <sect1><heading>Software Setup<label id="printing:software"></heading>
-
- <p> This section describes the software setup necessary to
- print with the LPD spooling system in FreeBSD.
-
- Here is an outline of the steps involved:
- <enum>
- <item>Configure your kernel, if necessary, for the port
- you are using for the printer; section <ref
- id="printing:kernel" name="Kernel Configuration"> tells
- you what you need to do.
-
- <item>Set the communications mode for the parallel port,
- if you are using a parallel port; section <ref
- id="printing:parallel-port-mode" name = "Setting the
- Communication Mode for the Parallel Port"> gives
- details.
-
- <item>Test if the operating system can send data to the
- printer. Section <ref id="printing:testing"
- name="Checking Printer Communications"> gives some
- suggestions on how to do this.
-
- <item>Set up LPD for the printer by modifying the file
- <tt>/etc/printcap</tt>. Section <ref
- id="printing:printcap" name="The /etc/printcap File">
- shows you how.
- </enum>
-
- <sect2><heading>Kernel Configuration<label
- id="printing:kernel"></heading>
-
- <p> The operating system kernel is compiled to work with a
- specific set of devices. The serial or parallel interface
- for your printer is a part of that set. Therefore, it
- might be necessary to add support for an additional serial
- or parallel port if your kernel is not already configured
- for one.
-
- To find out if the kernel you are currently using supports a serial
- interface, type
-<tscreen>
-<tt>dmesg &verbar; grep sio</tt><it/N/
-</tscreen>
- where <it/N/ is the number of the serial port, starting
- from zero. If you see output similar to the following
-<tscreen><verb>
-sio2 at 0x3e8-0x3ef irq 5 on isa
-sio2: type 16550A
-</verb></tscreen>
- then the kernel supports the port.
-
- To find out if the kernel supports a parallel interface,
- type
-<tscreen>
-<tt>dmesg &verbar; grep lpt</tt><it/N/
-</tscreen>
- where <it/N/ is the number of the parallel port, starting
- from zero. If you see output similar to the following
-<tscreen><verb>
-lpt0 at 0x378-0x37f on isa
-</verb></tscreen>
- then the kernel supports the port.
-
- You might have to reconfigure your kernel in order for the
- operating system to recognize and use the parallel or
- serial port you are using for the printer.
-
- To add support for a serial port, see the section on
- kernel configuration. To add support for a parallel port,
- see that section <em/and/ the section that follows.
-
- <sect3><heading>Adding <tt>/dev</tt> Entries for the Ports
- <label id="printing:dev-ports"></heading>
-
- <p> 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
- <tt>/dev</tt> directory are for.
-
- <bf>To add a <tt>/dev</tt> entry for a port:</bf>
- <enum>
- <item>Become root with the <tt/su/ command. Enter
- the root password when prompted.
-
- <item>Change to the <tt>/dev</tt> directory:
-<tscreen><verb>
-cd /dev
-</verb></tscreen>
-
- <item>Type
-<tscreen>
-<tt> ./MAKEDEV</tt> <it/port/
-</tscreen>
- where <it/port/ is the device entry for the port you
- want to make. Use <tt/lpt0/ for the first parallel
- port, <tt/lpt1/ for the second, and so on; use
- <tt/ttyd0/ for the first serial port, <tt/ttyd1/ for
- the second, and so on.
-
- <item>Type
-<tscreen>
-<tt>ls -l</tt> <it/port/
-</tscreen>
- to make sure the device entry got created.
- </enum>
-
- <sect3><heading>Setting the Communication Mode for the Parallel Port
- <label id="printing:parallel-port-mode"></heading>
-
- <p> When you are using the parallel interface, you can
- choose whether FreeBSD should use interrupt-driven or
- polled communication with the printer.
-
- <itemize>
- <item>The <em/interrupt-driven/ method is the default
- with the GENERIC kernel. With this method, the
- operating system uses an IRQ line to determine when
- the printer is ready for data.
-
- <item>The <em/polled/ method directs the operating
- system to repeatedly ask the printer if it is ready
- for more data. When it responds ready, the kernel
- sends more data.
- </itemize>
-
- The interrupt-driven method is somewhat faster but uses
- up a precious IRQ line. You should use whichever one
- works.
-
- You can set the communications mode in two ways: by
- configuring the kernel or by using the <tt/lptcontrol/
- program.
-
- <bf>To set the communications mode by configuring the
- kernel:</bf>
- <enum>
- <item>Edit your kernel configuration file. Look for
- or add an <tt/lpt0/ entry. If you are setting up the
- second parallel port, use <tt/lpt1/ instead. Use
- <tt/lpt2/ for the third port, and so on.
- <itemize>
- <item>If you want interrupt-driven mode, add the <tt/irq/
- specifier:
-<tscreen>
-<tt>device lpt0 at isa? port? tty irq <it/N/ vector lptintr</tt>
-</tscreen>
- where <it/N/ is the IRQ number for your
- computer's parallel port.
-
- <item>If you want polled mode, do not add the
- <tt/irq/ specifier:
-<tscreen>
-<tt>device lpt0 at isa? port? tty vector lptintr</tt>
-</tscreen>
- </itemize>
- <item>Save the file. Then configure, build, and
- install the kernel, then reboot. See <ref id="kernelconfig"
- name="kernel configuration"> for more details.
- </enum>
-
- <bf>To set the communications mode with
- <tt/lptcontrol/:</bf>
- <itemize>
- <item>
- Type
-<tscreen>
-<tt>lptcontrol -i -u <it/N/</tt>
-</tscreen>
- to set interrupt-driven mode for <tt/lpt<it/N//.
-
- <item>
- Type
-<tscreen>
-<tt>lptcontrol -p -u <it/N/</tt>
-</tscreen>
- to set polled-mode for <tt/lpt<it/N//.
- </itemize>
- You could put these commands in your
- <tt>/etc/rc.local</tt> file to set the mode each time
- your system boots. See lptcontrol(8) for more
- information.
-
- <sect3><heading>Checking Printer Communications<label
- id="printing:testing"></heading>
-
- <p> Before proceeding to configure the spooling system,
- you should make sure the operating system can
- successfully send data to your printer. It is a lot
- easier to debug printer communication and the spooling
- system separately.
-
- To test the printer, we will send some text to it. For
- printers that can immediately print characters sent to
- them, the program <tt/lptest/ is perfect: it generates
- all 96 printable ASCII characters in 96 lines.
-
- For a PostScript (or other language-based) printer,
- we will need a more sophisticated test. A small
- PostScript program, such as the following, will suffice:
-<code>
-%!PS
-100 100 moveto 300 300 lineto stroke
-310 310 moveto
-/Helvetica findfont 12 scalefont setfont
-(Is this thing working?) show
-showpage
-</code>
- <em/Note:/ When this document refers to a printer
- language, I am 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.
-
- <sect4><heading>Checking a Parallel Printer<label
- id="printing:checking:parallel"></heading>
-
- <p> This section tells you how to check if FreeBSD can
- communicate with a printer connected to a parallel port.
-
- <bf>To test a printer on a parallel port:</bf>
- <enum>
- <item>Become root with <tt/su/.
- <item>Send data to the printer.
- <itemize>
- <item>If the printer can print plain text, then
- use <tt/lptest/. Type:
-<tscreen>
-<tt>lptest > /dev/lpt<it/N/</tt>
-</tscreen>
- where <it/N/ is the number of the parallel
- port, starting from zero.
-
- <item>If the printer understands PostScript or
- other printer language, then send a small
- program to the printer. Type
-<tscreen>
-<tt>cat > /dev/lpt<it/N/</tt>
-</tscreen>
- Then, line by line, type the program
- <em/carefully/ as you cannot edit a line once
- you have pressed RETURN or ENTER. When you have
- finished entering the program, press
- CONTROL+D, or whatever your end of file key
- is.
-
- <p> Alternatively, you can put the program in
- a file and type
-<tscreen>
-<tt>cat <it/file/ > /dev/lpt<it/N/</tt>
-</tscreen>
- where <it/file/ is the name of the file
- containing the program you want to send to
- the printer.
- </itemize>
- </enum>
-
- You should see something print. Do not worry if the
- text does not look right; we will fix such things later.
-
- <sect4><heading>Checking a Serial Printer<label
- id="printing:checking:serial"></heading>
-
- <p> This section tells you how to check if FreeBSD can
- communicate with a printer on a serial port.
-
- <bf>To test a printer on a serial port:</bf>
- <enum>
- <item>Become root with <tt/su/.
-
- <item>Edit the file <tt>/etc/remote</tt>. Add the
- following entry:
-<tscreen>
-<tt>printer:dv=/dev/<it/port/:br&num;<it/bps-rate/:pa=<it/parity/</tt>
-</tscreen>
- where <it/port/ is the device entry for the serial
- port (<tt/ttyd0/, <tt/ttyd1/, etc.), <it/bps-rate/
- is the bits-per-second rate at which the printer
- communicates, and <it/parity/ is the parity
- required by the printer (either <tt/even/,
- <tt/odd/, <tt/none/, or <tt/zero/).
- <p>
- Here is a sample entry for a printer connected
- via a serial line to the third serial port at
- 19200 bps with no parity:
-<code>
-printer:dv=/dev/ttyd2:br#19200:pa=none
-</code>
-
- <item>Connect to the printer with <tt/tip/. Type:
-<tscreen><verb>
-tip printer
-</verb></tscreen>
- If this step does not work, edit the file
- <tt>/etc/remote</tt> again and try using
- <tt>/dev/cuaa<it/N/</tt> instead of
- <tt>/dev/ttyd<it/N/</tt>.
-
- <item>Send data to the printer.
- <itemize>
- <item>If the printer can print plain text, then
- use <tt/lptest/. Type:
-<tscreen><verb>
-~$lptest
-</verb></tscreen>
-
- <item>If the printer understands PostScript or
- other printer language, then send a small
- program to the printer. Type the program,
- line by line, <em/very carefully/ as
- backspacing or other editing keys may be
- significant to the printer. You may also need
- to type a special end-of-file key for the
- printer so it knows it received the whole
- program. For PostScript printers, press
- CONTROL+D.
-
- <p> Alternatively, you can put the program in
- a file and type
-<tscreen>
-<tt>&tilde;&gt;<it/file/</tt>
-</tscreen>
- where <it/file/ is the name of the file
- containing the program. After <tt/tip/
- sends the file, press any required
- end-of-file key.
- </itemize>
- </enum>
-
- You should see something print. Do not worry if the
- text does not look right; we will fix that later.
-
- <sect2><heading>Enabling the Spooler: The <tt>/etc/printcap</tt> File
- <label id="printing:printcap"></heading>
-
- <p> At this point, your printer should be hooked up, your
- kernel configured to communicate with it (if necessary),
- and you have been able to send some simple data to the
- printer. Now, we are ready to configure LPD to control
- access to your printer.
-
- You configure LPD by editing the file
- <tt>/etc/printcap</tt>. The LPD spooling system reads
- this file each time the spooler is used, so updates to the
- file take immediate effect.
-
- The format of the <tt/printcap/ file is straightforward.
- Use your favorite text editor to make changes to
- <tt>/etc/printcap</tt>. The format is identical to other
- capability files like <tt>/usr/share/misc/termcap</tt> and
- <tt>/etc/remote</tt>. For complete information about the
- format, see the cgetent(3).
-
- The simple spooler configuration consists of the following steps:
- <enum>
- <item>Pick a name (and a few convenient aliases) for
- the printer, and put them in the
- <tt>/etc/printcap</tt> file; see <ref
- id="printing:naming" name="Naming the Printer">.
-
- <item>Turn off header pages (which are on by default)
- by inserting the <tt/sh/ capability; see <ref
- id="printing:no-header-pages" name="Suppressing Header
- Pages">.
-
- <item>Make a spooling directory, and specify its
- location with the <tt/sd/ capability; see <ref
- id="printing:spooldir" name="Making the Spooling
- Directory">.
-
- <item>Set the <tt>/dev</tt> entry to use for the
- printer, and note it in <tt>/etc/printcap</tt> with
- the <tt/lp/ capability; see <ref id="printing:device"
- name="Identifying the Printer Device">. Also, if the
- printer is on a serial port, set up the communication
- parameters with the <tt/fs/, <tt/fc/, <tt/xs/, and
- <tt/xc/ capabilities; see <ref id="printing:commparam"
- name="Configuring Spooler Communications Parameters">.
-
- <item>Install a plain text input filter; see <ref
- id="printing:textfilter" name="Installing the Text
- Filter">
-
- <item>Test the setup by printing something with the
- <tt/lpr/ command; see <ref id="printing:trying"
- name="Trying It Out"> and <ref
- id="printing:troubleshooting" name="Troubleshooting">.
- </enum>
-
- <em/Note:/ Language-based printers, such as PostScript
- printers, cannot directly print plain text. The simple
- setup outlined above and described in the following
- sections assumes that if you are installing such a printer
- you will print only files that the printer can understand.
-
- Users often expect that they can print plain text to any
- of the printers installed on your system. Programs that
- interface to LPD to do their printing usually make the
- same assumption. If you are installing such a printer and
- want to be able to print jobs in the printer language
- <em/and/ print plain text jobs, you are strongly urged to
- add an additional step to the simple setup outlined above:
- install an automatic plain-text--to--PostScript (or other
- printer language) conversion program. Section <ref
- id="printing:advanced:if-conversion" name="Accommodating
- Plain Text Jobs on PostScript Printers"> tells how to do
- this.
-
- <sect3><heading>Naming the Printer<label
- id="printing:naming"></heading>
-
- <p> 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 aliases for the printer.
-
- At least one of the printers specified in the
- <tt>/etc/printcap</tt> should have the alias
- <tt/lp/. This is the default printer's name. If users
- do not have the PRINTER environment variable nor
- specify a printer name on the command line of any of the
- LPD commands, then <tt/lp/ will be the default printer
- they get to use.
-
- Also, it is common practice to make the last alias for a
- printer be a full description of the printer, including
- make and model.
-
- Once you have picked a name and some common aliases, put
- them in the <tt>/etc/printcap</tt> file. The name of
- the printer should start in the leftmost column.
- Separate each alias with a vertical bar and put a colon
- after the last alias.
-
- In the following example, we start with a skeletal
- <tt>/etc/printcap</tt> that defines two printers (a
- Diablo 630 line printer and a Panasonic KX-P4455
- PostScript laser printer):
-<code>
-#
-# /etc/printcap for host rose
-#
-rattan|line|diablo|lp|Diablo 630 Line Printer:
-
-bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:
-</code>
- In this example, the first printer is named <tt/rattan/
- and has as aliases <tt/line/, <tt/diablo/, <tt/lp/, and
- <tt/Diablo 630 Line Printer/. Since it has the alias
- <tt/lp/, it is also the default printer. The second is
- named <tt/bamboo/, and has as aliases <tt/ps/, <tt/PS/,
- <tt/S/, <tt/panasonic/, and <tt/Panasonic KX-P4455
- PostScript v51.4/.
-
- <sect3><heading>Suppressing Header Pages<label
- id="printing:no-header-pages"></heading>
-
- <p> The LPD spooling system will by default print a
- <em/header page/ for each job. The header page contains
- the user name who requested the job, the host from which
- the job came, and the name of the job, in nice large
- letters. Unfortunately, all this extra text gets in the
- way of debugging the simple printer setup, so we will
- suppress header pages.
-
- To suppress header pages, add the <tt/sh/ capability to
- the entry for the printer in
- <tt>/etc/printcap</tt>. Here is the example
- <tt>/etc/printcap</tt> with <tt/sh/ added:
-<code>
-#
-# /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:
-</code>
- 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.
-
- <sect3><heading>Making the Spooling Directory<label
- id="printing:spooldir"></heading>
-
- <p> The next step in the simple spooler setup is to make a
- <em/spooling directory/, a directory where print jobs
- reside until they are printed, and where a number of
- other spooler support files live.
-
- Because of the variable nature of spooling directories,
- it is customary to put these directories under
- <tt>/var/spool</tt>. It is not necessary to backup the
- contents of spooling directories, either. Recreating
- them is as simple as running <tt/mkdir/.
-
- It is also customary to make the directory with a name
- that is identical to the name of the printer, as shown
- below:
-<tscreen>
-<tt>mkdir /var/spool/<it>printer-name</it></tt>
-</tscreen>
- However, if you have a lot of printers on your network,
- you might want to put the spooling directories under a
- single directory that you reserve just for printing with
- LPD. We will do this for our two example printers
- <tt/rattan/ and <tt/bamboo/:
-<tscreen><verb>
-mkdir /var/spool/lpd
-mkdir /var/spool/lpd/rattan
-mkdir /var/spool/lpd/bamboo
-</verb></tscreen>
-
- <em/Note:/ If you are concerned about the privacy of jobs
- that users print, you might want to protect the spooling
- directory so it is not publicly accessible. Spooling
- directories should be owned and be readable, writable,
- and searchable by user daemon and group daemon, and no
- one else. We will do this for our example printers:
-
-<tscreen><verb>
-chown daemon.daemon /var/spool/lpd/rattan
-chown daemon.daemon /var/spool/lpd/bamboo
-chmod 770 /var/spool/lpd/rattan
-chmod 770 /var/spool/lpd/bamboo
-</verb></tscreen>
-
- Finally, you need to tell LPD about these directories
- using the <tt>/etc/printcap</tt> file. You specify the
- pathname of the spooling directory with the <tt/sd/
- capability:
-<code>
-#
-# /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:
-</code>
- 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.
-
- If you do not specify a spooling directory with <tt/sd/,
- the spooling system will use <tt>/var/spool/lpd</tt> as
- a default.
-
- <sect3><heading>Identifying the Printer Device<label
- id="printing:device"></heading>
-
- <p> In section <ref id="printing:dev-ports" name="Adding
- /dev Entries for the Ports">, we identified which
- entry in the <tt>/dev</tt> directory FreeBSD will use
- to communicate with the printer. Now, we tell LPD
- that information. When the spooling system has a job
- to print, it will open the specified device on behalf
- of the filter program (which is responsible for
- passing data to the printer).
-
- List the <tt>/dev</tt> entry pathname in the
- <tt>/etc/printcap</tt> file using the <tt/lp/
- capability.
-
- In our running example, let us assume that <tt/rattan/ is
- on the first parallel port, and <tt/bamboo/ is on a
- sixth serial port; here are the additions to
- <tt>/etc/printcap</tt>:
-<code>
-#
-# /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:
-</code>
-
- If you do not specify the <tt/lp/ capability for a
- printer in your <tt>/etc/printcap</tt> file, LPD uses
- <tt>/dev/lp</tt> as a default. <tt>/dev/lp</tt>
- currently does not exist in FreeBSD.
-
- If the printer you are installing is connected to a
- parallel port, skip to the section <ref name="Installing
- the Text Filter" id="printing:textfilter">. Otherwise,
- be sure to follow the instructions in the next section.
-
- <sect3><heading>Configuring Spooler Communication
- Parameters<label id="printing:commparam"></heading>
-
- <p> For printers on serial ports, LPD can set up the bps
- rate, parity, and other serial communication parameters
- on behalf of the filter program that sends data to the
- printer. This is advantageous since
- <itemize>
- <item>It lets you try different communication
- parameters by simply editing the
- <tt>/etc/printcap</tt> file; you do not have to
- recompile the filter program.
-
- <item>It enables the spooling system to use the same
- filter program for multiple printers which may have
- different serial communication settings.
- </itemize>
-
- The following <tt>/etc/printcap</tt> capabilities
- control serial communication parameters of the device
- listed in the <tt/lp/ capability:
- <descrip>
- <tag/<tt>br&num;<it/bps-rate/</tt>/
-
- Sets the communications speed of the device to
- <it/bps-rate/, where <it/bps-rate/ can be 50, 75,
- 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
- 4800, 9600, 19200, or 38400 bits-per-second.
-
- <tag/<tt>fc&num;<it/clear-bits/</tt>/
-
- Clears the flag bits <it/clear-bits/ in the
- <tt/sgttyb/ structure after opening the device.
-
- <tag/<tt>fs&num;<it/set-bits/</tt>/
-
- Sets the flag bits <it/set-bits/ in the <tt/sgttyb/
- structure.
-
- <tag/<tt>xc&num;<it/clear-bits/</tt>/
-
- Clears local mode bits <it/clear-bits/ after opening
- the device.
-
- <tag/<tt>xs&num;<it/set-bits/</tt>/
-
- Sets local mode bits <it/set-bits/.
- </descrip>
- For more information on the bits for the <tt/fc/,
- <tt/fs/, <tt/xc/, and <tt/xs/ capabilities, see the file
- <tt>/usr/include/sys/ioctl_compat.h</tt>.
-
- When LPD opens the device specified by the <tt/lp/
- capability, it reads the flag bits in the <tt/sgttyb/
- structure; it clears any bits in the <tt/fc/ capability,
- then sets bits in the <tt/fs/ capability, then applies
- the resultant setting. It does the same for the local
- mode bits as well.
-
- 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 TANDEM, ANYP, LITOUT, FLUSHO, and
- PASS8 flags. For the local mode bits, we will set the
- LITOUT and PASS8 flags:
-<tscreen><verb>
-bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
- :sh:sd=/var/spool/lpd/bamboo:\
- :lp=/dev/ttyd5:fs#0x82000c1:xs#0x820:
-</verb></tscreen>
-
-
- <sect3><heading>Installing the Text Filter<label
- id="printing:textfilter"></heading>
-
- <p> We are now ready to tell LPD what text filter to use to
- send jobs to the printer. A <em/text filter/, also
- known as an <em/input filter/, is a program that LPD
- runs when it has a job to print. When LPD runs the text
- filter for a printer, it sets the filter's standard
- input to the job to print, and its standard output to
- the printer device specified with the <tt/lp/
- capability. The filter is expected to read the job from
- standard input, perform any necessary translation for the
- printer, and write the results to standard output, which
- will get printed. For more information on the text
- filter, see section <ref id="printing:advanced:filters"
- name="Filters">.
-
- For our simple printer setup, the text filter can be a
- small shell script that just executes <tt>/bin/cat</tt>
- to send the job to the printer. FreeBSD comes with
- another filter called <tt/lpf/ that handles backspacing
- and underlining for printers that might not deal with
- such character streams well. And, of course, you can
- use any other filter program you want. The filter
- <tt/lpf/ is described in detail in section <ref
- id="printing:advanced:lpf" name="lpf: a Text Filter">.
-
- First, let uss make the shell script
- <tt>/usr/local/libexec/if-simple</tt> be a simple text
- filter. Put the following text into that file with your
- favorite text editor:
-<code>
-#!/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 &amp;&amp; exit 0
-exit 2
-</code>
- Make the file executable:
-<tscreen><verb>
-chmod 555 /usr/local/libexec/if-simple
-</verb></tscreen>
-
- And then tell LPD to use it by specifying it with the
- <tt/if/ capability in <tt>/etc/printcap</tt>. We will add
- it to the two printers we have so far in the example
- <tt>/etc/printcap</tt>:
-<code>
-#
-# /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:
-</code>
-
- <sect3><heading>Trying It Out<label id="printing:trying"></heading>
-
- <p> You have reached the end of the simple LPD setup.
- Unfortunately, congratulations are not quite yet in
- order, since we still have to test the setup and
- correct any problems. To test the setup, try printing
- something. To print with the LPD system, you use the
- command <tt/lpr/, which submits a job for printing.
-
- You can combine <tt/lpr/ with the <tt/lptest/ program,
- introduced in section <ref id="printing:testing"
- name="Checking Printer Communications"> to generate some
- test text.
-
- <bf>To test the simple LPD setup:</bf>
-
- <p> Type:
-<tscreen>
-<tt>lptest 20 5 | lpr -P<it/printer-name/</tt>
-</tscreen>
- where <it/printer-name/ is a the name of a printer (or
- an alias) specified in <tt>/etc/printcap</tt>. To test
- the default printer, type <tt/lpr/ without any <tt/-P/
- argument. Again, if you are testing a printer that
- expects PostScript, send a PostScript program in that
- language instead of using <tt/lptest/. You can do so by
- putting the program in a file and typing <tt/lpr
- <it/file//.
-
- For a PostScript printer, you should get the results
- of the program. If you are using <tt/lptest/, then your
- results should look like the following:
-
-<tscreen><verb>
-!"#$%&amp;'()*+,-./01234
-"#$%&amp;'()*+,-./012345
-#$%&amp;'()*+,-./0123456
-$%&amp;'()*+,-./01234567
-%&amp;'()*+,-./012345678
-</verb></tscreen>
-
- To further test the printer, try downloading larger
- programs (for language-based printers) or running
- <tt/lptest/ with different arguments. For example,
- <tt/lptest 80 60/ will produce 60 lines of 80 characters
- each.
-
- If the printer did not work, see the next section, <ref
- id="printing:troubleshooting" name="Troubleshooting">.
-
- <sect3><heading>Troubleshooting<label
- id="printing:troubleshooting"></heading>
-
- <p> After performing the simple test with <tt/lptest/, you
- might have gotten one of the following results instead of
- the correct printout:
- <descrip>
- <tag/It worked, after awhile; or, it did not eject a full sheet./
-
- 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.
-
- 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.
-
- The following replacement for the shell script
- <tt>/usr/local/libexec/if-simple</tt> prints a form
- feed after it sends the job to the printer:
-<code>
-#!/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 &amp;&amp; printf "\f" &amp;&amp; exit 0
-exit 2
-</code>
-
- <tag/It produced the ``staircase effect.''/
-
- You got the following on paper:
-<tscreen><verb>
-!"#$%&amp;'()*+,-./01234
- "#$%&amp;'()*+,-./012345
- #$%&amp;'()*+,-./0123456
-</verb></tscreen>
- You have become another victim of the <em/staircase
- effect/, 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
- <em/and/ ASCII code 13 (the carriage return or CR).
- Many printers use the MS-DOS convention for
- representing new-lines.
-
- 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.
-
- Here is what FreeBSD wants your printer to do:
-<tscreen><verb>
-Printer received CR Printer prints CR
-Printer received LF Printer prints CR + LF
-</verb></tscreen>
-
- Here are some ways to achieve this:
- <itemize>
- <item>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.
-
- <p> <em/Note:/ If you boot your system into
- other operating systems besides FreeBSD, you
- may have to <em/reconfigure/ 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.
-
- <item>Have FreeBSD's serial line driver
- automatically convert LF to CR+LF. Of course,
- this works with printers on serial ports
- <em/only/. To enable this feature, set the
- CRMOD bit in <tt/fs/ capability in the
- <tt>/etc/printcap</tt> file for the printer.
-
- <item>Send an <em/escape code/ 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.
-
- <p> 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.
-
-<code>
-#!/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. Writes a form feed character
-# after printing job.
-
-printf "\033&amp;k2G" &amp;&amp; cat &amp;&amp; printf "\f" &amp;&amp; exit 0
-exit 2
-</code>
-
- Here is an example <tt>/etc/printcap</tt> from
- a host called orchid. It has a single printer
- attached to its first parallel port, a Hewlett
- Packard LaserJet 3Si named <tt/teak/. It is
- using the above script as its text filter:
-<code>
-#
-# /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:
-</code>
- </itemize>
-
- <tag/It overprinted each line./
-
- The printer never advanced a line. All of the lines
- of text were printed on top of each other on one
- line.
-
- This problem is the ``opposite'' 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.
-
- Use the printer's configuration switches or control
- panel to enforce the following interpretation of LF
- and CR characters:
-<tscreen><verb>
-Printer received CR Printer prints CR
-Printer received LF Printer prints CR + LF
-</verb></tscreen>
-
- <tag/The printer lost characters./
-
- While printing, the printer did nott print a few
- characters in each line. The problem might have
- gotten worse as the printer ran, losing more and
- more characters.
-
- 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:
- <itemize>
- <item>If the printer supports XON/XOFF flow
- control, have FreeBSD use it by specifying the
- TANDEM bit in the <tt/fs/ capability.
-
- <item>If the printer supports carrier flow
- control, specify the MDMBUF bit in the <tt/fs/
- capability. Make sure the cable connecting the
- printer to the computer is correctly wired for
- carrier flow control.
-
- <item>If the printer does not support any flow
- control, use some combination of the NLDELAY,
- TBDELAY, CRDELAY, VTDELAY, and BSDELAY bits in
- the <tt/fs/ capability to add appropriate delays
- to the stream of data sent to the printer.
- </itemize>
-
- <tag/It printed garbage./
-
- The printer printed what appeared to be random
- garbage, but not the desired text.
-
- This is usually another symptom of incorrect
- communications parameters with a serial printer.
- Double-check the bps rate in the <tt/br/ capability,
- and the parity bits in the <tt/fs/ and <tt/fc/
- capabilities; make sure the printer is using the
- same settings as specified in the
- <tt>/etc/printcap</tt> file.
-
- <tag/Nothing happened./
-
- If nothing happened, the problem is probably within
- FreeBSD and not the hardware. Add the log file
- (<tt/lf/) capability to the entry for the printer
- you are debugging in the <tt>/etc/printcap</tt> file.
- For example, here is the entry for <tt/rattan/, with
- the <tt/lf/ capability:
-<tscreen><verb>
-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
-</verb></tscreen>
- Then, try printing again. Check the log file (in
- our example, <tt>/var/log/rattan.log</tt>) to see
- any error messages that might appear. Based on the
- messages you see, try to correct the problem.
-
- If you do not specify a <tt/lf/ capability, LPD uses
- <tt>/dev/console</tt> as a default.
- </descrip>
-
- <sect><heading>Using Printers<label id="printing:using"></heading>
-
- <p> This section tells you how to use printers you have setup with
- FreeBSD. Here is an overview of the user-level commands:
- <descrip>
- <tag/<tt/lpr//
- Print jobs
-
- <tag/<tt/lpq//
- Check printer queues
-
- <tag/<tt/lprm//
- Remove jobs from a printer's queue
-
- </descrip>
-
- There is also an administrative command, <tt/lpc/, described in
- the section <ref id="printing:lpc" name="Administrating the
- LPD Spooler">, used to control printers and their queues.
-
- All three of the commands <tt/lpr/, <tt/lprm/, and <tt/lpq/
- accept an option ``<tt/-P/ <it/printer-name/'' to specify on
- which printer/queue to operate, as listed in the
- <tt>/etc/printcap</tt> file. This enables you to submit,
- remove, and check on jobs for various printers. If you do not
- use the <tt/-P/ option, then these commands use the printer
- specified in the PRINTER environment variable. Finally, if
- you do not have a PRINTER environment variable, these commands
- default to the printer named <tt/lp/.
-
- Hereafter, the terminology <em/default printer/ means the
- printer named in the PRINTER environment variable, or the
- printer named <tt/lp/ when there is no PRINTER environment
- variable.
-
- <sect1><heading>Printing Jobs<label id="printing:lpr"></heading>
- <p>
-
- To print files, type
-<tscreen>
-<tt>lpr <it/filename.../</tt>
-</tscreen>
- This prints each of the listed files to the default printer.
- If you list no files, <tt/lpr/ reads data to print from
- standard input. For example, this command prints some
- important system files:
-<tscreen><verb>
-lpr /etc/host.conf /etc/hosts.equiv
-</verb></tscreen>
- To select a specific printer, type
-<tscreen>
-<tt>lpr -P <it/printer-name/ <it/filename.../</tt>
-</tscreen>
- This example prints a long listing of the current directory
- to the printer named <tt/rattan/:
-<tscreen><verb>
-ls -l | lpr -P rattan
-</verb></tscreen>
- Because no files were listed for the <tt/lpr/ command,
- <tt/lpr/ read the data to print from standard input, which
- was the output of the <tt/ls -l/ command.
-
- The <tt/lpr/ 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 <ref id="printing:lpr:options"
- name="Printing Options">.
-
- <sect1><heading>Checking Jobs<label id="printing:lpq"></heading>
-
- <p> When you print with <tt/lpr/, the data you wish to print
- is put together in a package called a <em/print job/, which
- is sent to the LPD 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.
-
- To display the queue for the default printer, type <tt/lpq/.
- For a specific printer, use the <tt/-P/ option. For
- example, the command
-<tscreen><verb>
-lpq -P bamboo
-</verb></tscreen>
- shows the queue for the printer named <tt/bamboo/. Here is
- an example of the output of the <tt/lpq/ command:
-<tscreen><verb>
-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
-</verb></tscreen>
- This shows three jobs in the queue for <tt/bamboo/. The
- first job, submitted by user kelly, got assigned <em/job
- number/ 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
- <ref id="printing:lprm" name="Removing Jobs"> for details.
-
- Job number nine consists of two files; multiple files given
- on the <tt/lpr/ command line are treated as part of a single
- job. It is the currently active job (note the word
- <tt/active/ under the ``Rank'' column), which means the
- printer should be currently printing that job. The second
- job consists of data passed as the standard input to the
- <tt/lpr/ command. The third job came from user mary; it is a
- much larger job. The pathname of the files she's trying to
- print is too long to fit, so the <tt/lpq/ command just shows
- three dots.
-
- The very first line of the output from <tt/lpq/ is also
- useful: it tells what the printer is currently doing (or at
- least what LPD thinks the printer is doing).
-
- The <tt/lpq/ command also support a <tt/-l/ option to
- generate a detailed long listing. Here is an example of
- <tt/lpq -l/:
-<tscreen><verb>
-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
-</verb></tscreen>
-
- <sect1><heading>Removing Jobs<label
- id="printing:lprm"></heading>
-
- <p> If you change your mind about printing a job, you can
- remove the job from the queue with the <tt/lprm/ command.
- Often, you can even use <tt/lprm/ to remove an active job,
- but some or all of the job might still get printed.
-
- To remove a job from the default printer, first use <tt/lpq/
- to find the job number. Then type
-<tscreen>
-<tt/lprm <it/job-number//
-</tscreen>
- To remove the job from a specific printer, add the <tt/-P/
- option. The following command removes job number 10 from
- the queue for the printer <tt/bamboo/:
-<tscreen><verb>
-lprm -P bamboo 10
-</verb></tscreen>
- The <tt/lprm/ command has a few shortcuts:
- <descrip>
- <tag/lprm -/
-
- Removes all jobs (for the default printer) belonging to
- you.
-
- <tag/lprm <it/user//
-
- Removes all jobs (for the default printer) belonging to
- <it/user/. The superuser can remove other users' jobs;
- you can remove only your own jobs.
-
- <tag/lprm/
-
- With no job number, user name, or ``<tt/-/'' appearing
- on the command line, <tt/lprm/ removes the currently
- active job on the default printer, if it belongs to
- you. The superuser can remove any active job.
- </descrip>
-
- Just use the <tt/-P/ 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 <tt/rattan/:
-
-<tscreen><verb>
-lprm -P rattan -
-</verb></tscreen>
-
- <em/Note:/ If you are working in a networked environment,
- <tt/lprm/ 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:
-<code>
-rose% lpr -P rattan myfile
-rose% rlogin orchid
-orchid% lpq -P rattan
-Rank Owner Job Files Total Size
-active seeyan 12 ... 49123 bytes
-2nd kelly 13 myfile 12 bytes
-orchid% lprm -P rattan 13
-rose: Permission denied
-orchid% logout
-rose% lprm -P rattan 13
-dfA013rose dequeued
-cfA013rose dequeued
-rose%
-</code>
-
- <sect1><heading>Beyond Plain Text: Printing Options<label
- id="printing:lpr:options"></heading>
-
- <p> The <tt/lpr/ 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.
-
- <sect2><heading>Formatting and Conversion Options<label
- id="printing:lpr:options:format"></heading>
-
- <p> The following <tt/lpr/ 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 <tt/pr/ utility.
-
- For example, the following command prints a DVI file (from
- the TeX typesetting system) named <tt/fish-report.dvi/
- to the printer named <tt/bamboo/:
-<tscreen><verb>
-lpr -P bamboo -d fish-report.dvi
-</verb></tscreen>
- 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.
-
- <em/Note:/ All of these options except <tt/-p/ and <tt/-T/
- require conversion filters installed for the destination
- printer. For example, the <tt/-d/ option requires the DVI
- conversion filter. Section <ref
- id="printing:advanced:convfilters" name="Conversion
- Filters"> gives details.
-
- <descrip>
- <tag/<tt/-c// Print cifplot files.
-
- <tag/<tt/-d// Print DVI files.
-
- <tag/<tt/-f// Print FORTRAN text files.
-
- <tag/<tt/-g// Print plot data.
-
- <tag/<tt/-i <it/number///
-
- Indent the output by <it/number/ columns; if you omit
- <it/number/, indent by 8 columns. This option works
- only with certain conversion filters.
-
- <em/Note:/ Do not put any space between the <tt/-i/ and
- the number.
-
- <tag/<tt/-l//
-
- Print literal text data, including control characters.
-
- <tag/<tt/-n// Print ditroff (device independent troff) data.
-
- <tag/-p/
-
- Format plain text with <tt/pr/ before printing. See
- pr(1) for more information.
-
- <tag/<tt/-T <it/title///
-
- Use <it/title/ on the <tt/pr/ header instead of the
- file name. This option has effect only when used with
- the <tt/-p/ option.
-
- <tag/<tt/-t// Print troff data.
-
- <tag/<tt/-v// Print raster data.
-
- </descrip>
-
- Here is an example: this command prints a nicely
- formatted version of the <tt/ls/ manual page on the
- default printer:
-<tscreen><verb>
-zcat /usr/share/man/man1/ls.1.gz | troff -t -man | lpr -t
-</verb></tscreen>
- The <tt/zcat/ command uncompresses the source of the
- <tt/ls/ manual page and passes it to the <tt/troff/
- command, which formats that source and makes GNU troff
- output and passes it to <tt/lpr/, which submits the job to
- the LPD spooler. Because we used the <tt/-t/ option to
- <tt/lpr/, the spooler will convert the GNU troff output
- into a format the default printer can understand when it
- prints the job.
-
- <sect2><heading>Job Handling Options<label
- id="printing:lpr:options:job-handling"></heading>
-
- <p> The following options to <tt/lpr/ tell LPD to handle the
- job specially:
-
- <descrip>
- <tag/-&num; <it/copies//
-
- Produce a number of <it/copies/ 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 <ref
- id="printing:advanced:restricting:copies"
- name="Restricting Multiple Copies">.
-
- <p> This example prints three copies of <tt/parser.c/
- followed by three copies of <tt/parser.h/ to the
- default printer:
-<tscreen><verb>
-lpr -#3 parser.c parser.h
-</verb></tscreen>
-
- <tag/-m/
-
- Send mail after completing the print job. With this
- option, the LPD 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.
-
- <tag/-s/ Do not copy the files to the spooling directory,
- but make symbolic links to them instead.
-
- 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 LPD will not have to copy
- each and every byte of your job to the spooling
- directory.
-
- There is a drawback, though: since LPD will refer to
- the original files directly, you cannot modify or
- remove them until they have been printed.
-
- <em/Note:/ If you are printing to a remote printer, LPD
- will eventually have to copy files from the local host
- to the remote host, so the <tt/-s/ option will save
- space only on the local spooling directory, not the
- remote. It is still useful, though.
-
- <tag/-r/
-
- Remove the files in the job after copying them to the
- spooling directory, or after printing them with the
- <tt/-s/ option. Be careful with this option!
-
- </descrip>
-
- <sect2><heading>Header Page Options<label
- id="printing:lpr:options:misc"></heading>
-
- <p> These options to <tt/lpr/ 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 <ref name="Header Pages"
- id="printing:advanced:header-pages"> for information about
- setting up header pages.
-
- <descrip>
- <tag/-C <it/text//
-
- Replace the hostname on the header page with
- <it/text/. The hostname is normally the name of the
- host from which the job was submitted.
-
- <tag/-J <it/text//
-
- Replace the job name on the header page with
- <it/text/. The job name is normally the name of the
- first file of the job, or ``stdin'' if you are printing
- standard input.
-
- <tag/-h/
-
- Do not print any header page. <em/Note:/ At some
- sites, this option may have no effect due to the way
- header pages are generated. See <ref name="Header
- Pages" id="printing:advanced:header-pages"> for
- details.
-
- </descrip>
-
- <sect1><heading>Administrating Printers<label
- id="printing:lpc"></heading>
-
- <p> As an administrator for your printers, you have had to
- install, set up, and test them. Using the <tt/lpc/ command,
- you can interact with your printers in yet more ways. With
- <tt/lpc/, you can
-
- <itemize>
- <item>Start and stop the printers
-
- <item>Enable and disable their queues
-
- <item>Rearrange the order of the jobs in each queue.
- </itemize>
-
- First, a note about terminology: if a printer is
- <em/stopped/, it will not print anything in its queue. Users
- can still submit jobs, which will wait in the queue until
- the printer is <em/started/ or the queue is cleared.
-
- If a queue is <em/disabled/, no user (except root) can
- submit jobs for the printer. An <em/enabled/ queue allows
- jobs to be submitted. A printer can be <em/started/ for a
- disabled queue, in which case it will continue to print jobs
- in the queue until the queue is empty.
-
- In general, you have to have root privileges to use the
- <tt/lpc/ command. Ordinary users can use the <tt/lpc/
- command to get printer status and to restart a hung printer
- only.
-
- Here is a summary of the <tt/lpc/ commands. Most of the
- commands takes a <it/printer-name/ argument to tell on which
- printer to operate. You can use <tt/all/ for the
- <it/printer-name/ to mean all printers listed in
- <tt>/etc/printcap</tt>.
-
- <descrip>
- <tag/<tt/abort <it/printer-name///
-
- Cancel the current job and stop the printer. Users can
- still submit jobs if the queue's enabled.
-
- <tag/<tt/clean <it/printer-name///
-
- Remove old files from the printer's spooling directory.
- Occasionally, the files that make up a job are not
- properly removed by LPD, 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.
-
- <tag/<tt/disable <it/printer-name///
-
- Disable queuing of new jobs. If the printer's started,
- it will continue to print any jobs remaining in the
- queue. The superuser (root) can always submit jobs,
- even to a disabled queue.
-
- 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 <tt/enable/ command.
-
- <tag/<tt/down <it/printer-name/ <it/message...///
-
- Take a printer down. Equivalent to <tt/disable/
- followed by <tt/stop/. The <it/message/ appears as the
- printer's status whenever a user checks the printer's
- queue with <tt/lpq/ or status with <tt/lpc status/.
-
- <tag/<tt/enable <it/printer-name///
-
- Enable the queue for a printer. Users can submit jobs
- but the printer will not print anything until it is started.
-
- <tag/<tt/help <it/command-name///
-
- Print help on the command <it/command-name/. With no
- <it/command-name/, print a summary of the commands
- available.
-
- <tag/<tt/restart <it/printer-name///
-
- Start the printer. Ordinary users can use this command
- if some extraordinary circumstance hangs LPD, but they
- cannot start a printer stopped with either the <tt/stop/
- or <tt/down/ commands. The <tt/restart/ command is
- equivalent to <tt/abort/ followed by <tt/start/.
-
- <tag/<tt/start <it/printer-name///
-
- Start the printer. The printer will print jobs in its
- queue.
-
- <tag/<tt/stop <it/printer-name///
-
- 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.
-
- <tag/<tt/topq <it/printer-name/ <it/job-or-username...///
-
- Rearrange the queue for <it/printer-name/ by placing the
- jobs with the listed <it/job/ numbers or the jobs
- belonging to <it/username/ at the top of the queue. For
- this command, you cannot use <tt/all/ as the
- <it/printer-name/.
-
- <tag/<tt/up <it/printer-name///
-
- Bring a printer up; the opposite of the <tt/down/
- command. Equivalent to <tt/start/ followed by
- <tt/enable/.
-
- </descrip>
-
- <tt/lpc/ accepts the above commands on the command line. If
- you do not enter any commands, <tt/lpc/ enters an interactive
- mode, where you can enter commands until you type <tt/exit/,
- <tt/quit/, or end-of-file.
-
- <sect><heading>Advanced Printer Setup<label
- id="printing:advanced"></heading>
-
- <p> This section describes filters for printing specially
- formatted files, header pages, printing across networks, and
- restricting and accounting for printer usage.
-
- <sect1><heading>Filters<label
- id="printing:advanced:filter-intro"></heading>
-
- <p> Although LPD handles network protocols, queuing, access
- control, and other aspects of printing, most of the
- <em/real/ work happens in the <em/filters/. 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 <ref id="printing:textfilter" name="Installing the
- Text Filter">).
-
- 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 <em/you/ have to provide
- filters yourself. The good news is that many are generally
- available; when they are not, they are usually easy to write.
-
- Also, FreeBSD comes with one, <tt>/usr/libexec/lpr/lpf</tt>,
- 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.
-
- Here is what you will find in this section:
-
- <itemize>
- <item>Section <ref id="printing:advanced:filters"
- name="How Fitlers Work">, 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
- ``under the hood'' when LPD 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.
-
- <item>LPD 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 <ref
- id="printing:advanced:if-conversion" name="Accommodating
- Plain Text Jobs on PostScript Printers"> tells you what
- you should do to overcome this problem. I recommend
- reading this section if you have a PostScript printer.
-
- <item>PostScript is a popular output format for many
- programs. Even some people (myself included) write
- PostScript code directly. But PostScript printers are
- expensive. Section <ref id="printing:advanced:ps"
- name="Simulating PostScript on Non-PostScript Printers">
- tells how you can further modify a printer's text filter
- to accept and print PostScript data on a
- <em/non-PostScript/ printer. I recommend reading this
- section if you do not have a PostScript printer.
-
- <item>Section <ref id="printing:advanced:convfilters"
- name="Conversion Filters"> 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 <tt/lpr -t/ to print troff data, or
- <tt/lpr -d/ to print TeX DVI data, or <tt/lpr -v/ to
- print raster image data, and so forth. I recommend
- reading this section.
-
- <item>Section <ref id="printing:advanced:of" name="Output
- Filters"> tells all about a not often used feature of
- LPD: output filters. Unless you are printing header
- pages (see <ref id="printing:advanced:header-pages"
- name="Header Pages">), you can probably skip that
- section altogether.
-
- <item>Section <ref id="printing:advanced:lpf" name="lpf:
- a Text Filter"> describes <tt/lpf/, 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 <tt/lpf/.
- </itemize>
-
- <sect2><heading>How Filters Work<label
- id="printing:advanced:filters"></heading>
-
- <p> As mentioned before, a filter is an executable program
- started by LPD to handle the device-dependent part of
- communicating with the printer.
-
- When LPD 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 <tt/lf/ capability in <tt>/etc/printcap</tt>, or
- <tt>/dev/console</tt> by default).
-
- Which filter LPD starts and the filter's arguments depend
- on what is listed in the <tt>/etc/printcap</tt> file and
- what arguments the user specified for the job on the
- <tt/lpr/ command line. For example, if the user typed
- <tt/lpr -t/, LPD would start the troff filter, listed in
- the <tt/tf/ capability for the destination printer. If
- the user wanted to print plain text, it would start the
- <tt/if/ filter (this is mostly true: see <ref
- id="printing:advanced:of" name="Output Filters"> for
- details).
-
- There are three kinds filters you can specify in
- <tt>/etc/printcap</tt>:
- <itemize>
- <item>The <em/text filter/, confusingly called the
- <em/input filter/ in LPD documentation, handles
- regular text printing. Think of it as the default
- filter. LPD 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:
-<tscreen>
-<tt>[-c] -w<it/width/ -l<it/length/ -i<it/indent/ -n <it/login/ -h <it/host/ <it/acct-file/</tt>
-</tscreen>
- where
- <descrip>
- <tag/<tt/-c//
-
- appears if the job's submitted with <tt/lpr -l/
-
- <tag/<tt/<it/width///
-
- is the value from the <tt/pw/ (page width)
- capability specified in <tt>/etc/printcap</tt>,
- default 132
-
- <tag/<tt/<it/length///
-
- is the value from the <tt/pl/ (page length)
- capability, default 66
-
- <tag/<tt/<it/indent///
-
- is the amount of the indentation from <tt/lpr -i/,
- default 0
-
- <tag/<tt/<it/login///
-
- is the account name of the user printing the file
-
- <tag/<tt/<it/host///
-
- is the host name from which the job was submitted
-
- <tag/<tt/<it/acct-file///
-
- is the name of the accounting file from the <tt/af/
- capability.
-
- </descrip>
-
- <item>A <em/conversion filter/ 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
- <ref id="printing:advanced:convfilters"
- name="Conversion Filters"> tells all about them.
- Conversion filters also need to do accounting, if you
- need printer accounting.
-
- Conversion filters are started with the following
- arguments:
-<tscreen>
-<tt>-x<it/pixel-width/ -y<it/pixel-height/ -n <it/login/ -h <it/host/ <it/acct-file/</tt>
-</tscreen>
- where <it/pixel-width/ is the value from the <tt/px/
- capability (default 0) and <it/pixel-height/ is the
- value from the <tt/py/ capability (default 0).
-
- <item>The <em/output filter/ is used only if there is no
- text filter, or if header pages are enabled. In my
- experience, output filters are rarely used. Section
- <ref id="printing:advanced:of" name="Output Filters">
- describe them. There are only two arguments to an
- output filter:
-<tscreen>
-<tt>-w<it/width/ -l<it/length/</tt>
-</tscreen>
- which are identical to the text filters <tt/-w/ and
- <tt/-l/ arguments.
- </itemize>
-
- Filters should also <em/exit/ with the following exit
- status:
- <descrip>
- <tag/exit 0/
-
- If the filter printed the file successfully.
-
- <tag/exit 1/
-
- If the filter failed to print the file but wants LPD
- to try to print the file again. LPD will restart a
- filter if it exits with this status.
-
- <tag/exit 2/
-
- If the filter failed to print the file and does not
- want LPD to try again. LPD will throw out the file.
- </descrip>
-
- The text filter that comes with the FreeBSD release,
- <tt>/usr/libexec/lpr/lpf</tt>, 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.
-
- 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.
-
- <sect2><heading>Accommodating Plain Text Jobs on PostScript Printers
- <label id="printing:advanced:if-conversion"></heading>
-
- <p> 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.
-
- 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 <tt/&percnt;!/ (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.
-
- How do we do this?
-
- If you have got a serial printer, a great way to do it is to
- install <tt/lprps/. <tt/lprps/ 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 ``toner low'' or ``paper jam''). But
- more importantly, it includes a program called <tt/psif/
- which detects whether the incoming job is plain text and
- calls <tt/textps/ (another program that comes with
- <tt/lprps/) to convert it to PostScript. It then uses
- <tt/lprps/ to send the job to the printer.
-
- <tt/lprps/ is part of the FreeBSD ports collection
- (see <ref id="ports" name="The Ports Collection">).
- You can fetch, build and install it
- yourself, of course. After installing <tt/lprps/, just
- specify the pathname to the <tt/psif/ program that is part
- of <tt/lprps/. If you installed <tt/lprps/ from the ports
- collection, use the following in the serial PostScript
- printer's entry in <tt>/etc/printcap</tt>:
-<tscreen><verb>
- :if=/usr/local/libexec/psif:
-</verb></tscreen>
- You should also specify the <tt/rw/ capability; that tells
- LPD to open the printer in read-write mode.
-
- If you have a parallel PostScript printer (and therefore
- cannot use two-way communication with the printer, which
- <tt/lprps/ needs), you can use the following shell script
- as the text filter:
-<code>
-#!/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 &amp;&amp; cat &amp;&amp; printf "\004" &amp;&amp; exit 0
- exit 2
-else
- #
- # Plain text, convert it, then print it.
- #
- ( echo $first_line; cat ) | /usr/local/bin/textps &amp;&amp; printf "\004" &amp;&amp; exit 0
- exit 2
-fi
-</code>
- In the above script, <tt/textps/ 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 <ref id="ports" name="The Ports
- Collection">) includes a full featured text-to-PostScript
- program called <tt/a2ps/ that you might want to
- investigate.
-
- <sect2><heading>Simulating PostScript on Non-PostScript Printers
- <label id="printing:advanced:ps"></heading>
-
- <p> PostScript is the <it/de facto/ standard for high
- quality typesetting and printing. PostScript is, however,
- an <em/expensive/ standard. Thankfully, Alladin
- Enterprises has a free PostScript work-alike called
- <it/Ghostscript/ 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.
-
- Ghostscript should be 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.
-
- 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.
-
- Here is an example: the following script is a text filter
- for Hewlett Packard DeskJet 500 printers. For other
- printers, substitute the <tt/-sDEVICE/ argument to the
- <tt/gs/ (Ghostscript) command. (Type <tt/gs -h/ to get a
- list of devices the current installation of Ghostscript
- supports.)
-<code>
-#!/bin/sh
-#
-# ifhp - Print Ghostscript-simulated PostScript on a DeskJet 500
-# Installed in /usr/local/libexec/hpif
-
-#
-# Treat LF as CR+LF:
-#
-printf "\033&amp;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
- #
- /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 -sOutputFile=- - \
- &amp;&amp; exit 0
-
-else
- #
- # Plain text or HP/PCL, so just print it directly; print a form
- # at the end to eject the last page.
- #
- echo $first_line &amp;&amp; cat &amp;&amp; printf "\f" &amp;&amp; exit 2
-fi
-
-exit 2
-</code>
- Finally, you need to notify LPD of the filter via the
- <tt/if/ capability:
-<tscreen><verb>
- :if=/usr/local/libexec/hpif:
-</verb></tscreen>
- That is it. You can type <tt/lpr plain.text/ and <tt/lpr
- whatever.ps/ and both should print successfully.
-
-
- <sect2><heading>Conversion Filters<label
- id="printing:advanced:convfilters"></heading>
-
- <p> After completing the simple setup described in <ref
- name="Simple Printer Setup" id="printing:simple">, the
- first thing you will probably want to do is install
- conversion filters for your favorite file formats
- (besides plain ASCII text).
-
- <sect3><heading>Why Install Conversion Filters?</heading>
-
- <p> 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:
-<tscreen><verb>
-dvips seaweed-analysis.dvi
-lpr seaweed-analysis.ps
-</verb></tscreen>
- By installing a conversion filter for DVI files, we can
- skip the hand conversion step each time by having LPD do
- it for us. Now, each time we get a DVI file, we are just
- one step away from printing it:
-<tscreen><verb>
-lpr -d seaweed-analysis.dvi
-</verb></tscreen>
- We got LPD to do the DVI file conversion for us by
- specifying the <tt/-d/ option. Section <ref
- id="printing:lpr:options:format" name="Formatting and
- Conversion Options"> lists the conversion options.
-
- For each of the conversion options you want a printer to
- support, install a <em/conversion filter/ and specify
- its pathname in <tt>/etc/printcap</tt>. A conversion
- filter is like the text filter for the simple printer
- setup (see section <ref id="printing:textfilter"
- name="Installing the Text Filter">) except that instead
- of printing plain text, the filter converts the file
- into a format the printer can understand.
-
- <sect3><heading>Which Conversions Filters Should I Install?
- </heading>
-
- <p> 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.
-
- The following table summarizes the filters that LPD
- works with, their capability entries for the
- <tt>/etc/printcap</tt> file, and how to invoke them with
- the <tt/lpr/ command:
-<code>
- /etc/printcap
-File type Capability lpr option
------------- ------------- ----------
-cifplot cf -c
-DVI df -d
-plot gf -g
-ditroff nf -n
-FORTRAN text rf -f
-troff tf -t
-raster vf -v
-plain text if none, -p, or -l
-</code>
-
- In our example, using <tt/lpr -d/ means the printer
- needs a <tt/df/ capability in its entry in
- <tt>/etc/printcap</tt>.
-
- 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 <tt/gf/
- capability and then educate your users that <tt/lpr -g/
- mean ``print Printerleaf files.''
-
- <sect3><heading>Installing Conversion Filters</heading>
-
- <p> Since conversion filters are programs you install
- outside of the base FreeBSD installation, they should
- probably go under <tt>/usr/local</tt>. The directory
- <tt>/usr/local/libexec</tt> is a popular location, since
- they are specialized programs that only LPD will
- run; regular users should not ever need to run them.
-
- To enable a conversion filter, specify its pathname
- under the appropriate capability for the destination
- printer in <tt>/etc/printcap</tt>.
-
- In our example, we will add the DVI conversion filter to
- the entry for the printer named <tt/bamboo/. Here is the
- example <tt>/etc/printcap</tt> file again, with the new
- <tt/df/ capability for the printer <tt/bamboo/
-<code>
-#
-# /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:
-</code>
- The DVI filter is a shell script named
- <tt>/usr/local/libexec/psdf</tt>. Here is that script:
-<code>
-#!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 "$@"
-</code>
- This script runs <tt/dvips/ in filter mode (the <tt/-f/
- argument) on standard input, which is the job to print.
- It then starts the PostScript printer filter <tt/lprps/
- (see section <ref id="printing:advanced:if-conversion"
- name="Accommodating Plain Text Jobs on PostScript
- Printers">) with the arguments LPD passed to this script.
- <tt/lprps/ will use those arguments to account for the
- pages printed.
-
- <sect3><heading>More Conversion Filter Examples</heading>
-
- <p> 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.
-
- This example script is a raster (well, GIF file,
- actually) conversion filter for a Hewlett Packard
- LaserJet III-Si printer:
-<code>
-#!/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
-</code>
- 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.
-
- Here is the <tt>/etc/printcap</tt> file with an entry for
- a printer using the above filter:
-<code>
-#
-# /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:
-</code>
-
- The following script is a conversion filter for troff
- data from the groff typesetting system for the
- PostScript printer named <tt/bamboo/:
-<code>
-#!/bin/sh
-#
-# pstf - Convert groff's troff data into PS, then print.
-# Installed in /usr/local/libexec/pstf
-#
-exec grops | /usr/local/libexec/lprps "$@"
-</code>
- The above script makes use of <tt/lprps/ again to handle
- the communication with the printer. If the printer were
- on a parallel port, we would use this script instead:
-<code>
-#!/bin/sh
-#
-# pstf - Convert groff's troff data into PS, then print.
-# Installed in /usr/local/libexec/pstf
-#
-exec grops
-</code>
- That is it. Here is the entry we need to add to
- <tt>/etc/printcap</tt> to enable the filter:
-<tscreen><verb>
- :tf=/usr/local/libexec/pstf:
-</verb></tscreen>
-
- 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 <tt/teak/:
-<code>
-#!/bin/sh
-#
-# hprf - FORTRAN text filter for LaserJet 3si:
-# Installed in /usr/local/libexec/hprf
-#
-
-printf "\033&amp;k2G" &amp;&amp; fpr &amp;&amp; printf "\f" &amp;&amp; exit 0
-exit 2
-</code>
- And we will add this line to the <tt>/etc/printcap</tt>
- for the printer <tt/teak/ to enable this filter:
-<tscreen><verb>
- :rf=/usr/local/libexec/hprf:
-</verb></tscreen>
-
- Here is one final, somewhat complex example. We will add a
- DVI filter to the LaserJet printer <tt/teak/ introduced
- earlier. First, the easy part: updating
- <tt>/etc/printcap</tt> with the location of the DVI
- filter:
-<tscreen><verb>
- :df=/usr/local/libexec/hpdf:
-</verb></tscreen>
-
- Now, for the hard part: making the filter. For that, we
- need a DVI-to-LaserJet/PCL conversion program. The
- FreeBSD ports collection (see <ref id="ports" name="The
- Ports Collection">) has one: <tt/dvi2xx/ is the name of
- the package. Installing this package gives us the
- program we need, <tt/dvilj2p/, which converts DVI into
- LaserJet IIp, LaserJet III, and LaserJet 2000 compatible
- codes.
-
- <tt/dvilj2p/ makes the filter <tt/hpdf/ quite complex
- since <tt/dvilj2p/ cannot read from standard input. It
- wants to work with a filename. What is worse, the
- filename has to end in <tt/.dvi/ so using
- <tt>/dev/fd/0</tt> for standard input is problematic.
- We can get around that problem by linking (symbolically)
- a temporary file name (one that ends in <tt/.dvi/) to
- <tt>/dev/fd/0</tt>, thereby forcing <tt/dvilj2p/ to read
- from standard input.
-
- The only other fly in the ointment is the fact that we
- cannot use /tmp for the temporary link. Symbolic links
- are owned by user and group <tt/bin/. The filter runs
- as user <tt/daemon/. And the <tt>/tmp</tt> 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.
-
- Instead, the filter will make the symbolic link in the
- current working directory, which is the spooling
- directory (specified by the <tt/sd/ capability in
- <tt>/etc/printcap</tt>). 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 <tt>/tmp</tt>.
-
- Here, finally, is the filter:
-<code>
-#!/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>&amp;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&amp;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
-</code>
-
- <sect3><heading>Automated Conversion: An Alternative To Conversion Filters
- <label id="printing:advanced:autoconv"></heading>
-
- <p> All these conversion filters accomplish a lot for your
- printing environment, but at the cost forcing the user
- to specify (on the <tt/lpr/ 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.
-
- 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 <tt/file/ can be of help here.
- Of course, it will be hard to determine the differences
- between <em/some/ file types---and, of course, you can
- still provide conversion filters just for them.
-
- The FreeBSD ports collection has a text filter that
- performs automatic conversion called <tt/apsfilter/. It
- can detect plain text, PostScript, and DVI files, run
- the proper conversions, and print.
-
- <sect2><heading>Output Filters<label
- id="printing:advanced:of"></heading>
-
- <p> The LPD 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
- <itemize>
- <item>LPD starts an output filter once for the entire
- job instead of once for each file in the job.
-
- <item>LPD does not make any provision to identify the
- start or the end of files within the job for the
- output filter.
-
- <item>LPD 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:
-<tscreen>
-<tt>-w<it/width/ -l<it/length/</tt>
-</tscreen>
- where <it/width/ is from the <tt/pw/ capability and
- <it/length/ is from the <tt/pl/ capability for the
- printer in question.
- </itemize>
-
- 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 <em/will not work/. Use a text filter (also
- known as an input filter); see section <ref
- id="printing:textfilter" name="Installing the Text
- Filter">. Furthermore, an output filter is actually
- <em/more complex/ 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 LPD.
-
- However, an output filter is <em/necessary/ 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 <em/futile/ if you want to charge
- header pages to the requesting user's account, since LPD
- does not give any user or host information to the output
- filter.)
-
- On a single printer, LPD allows both an output filter and
- text or other filters. In such cases, LPD will start the
- output filter to print the header page (see section <ref
- id="printing:advanced:header-pages" name="Header Pages">)
- only. LPD then expects the output filter to <em/stop
- itself/ 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 SIGSTOP to
- itself. When LPD's done running other filters, it will
- restart the output filter by sending SIGCONT to it.
-
- If there is an output filter but <em/no/ text filter and
- LPD is working on a plain text job, LPD 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 <em/not/ what you want. In almost all
- cases, you need a text filter.
-
- The program <tt/lpf/, 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 <tt/lpf/. You
- can also wrap <tt/lpf/ in a shell script to handle any
- initialization codes the printer might require.
-
- <sect2><heading><tt/lpf/: a Text Filter<label
- id="printing:advanced:lpf"></heading>
-
- <p> The program <tt>/usr/libexec/lpr/lpf</tt> that comes
- with FreeBSD binary distribution is a text filter (input
- filter) that can indent output (job submitted with <tt/lpr
- -i/), allow literal characters to pass (job submitted with
- <tt/lpr -l/), adjust the printing position for backspaces
- and tabs in the job, and account for pages printed. It
- can also act like an output filter.
-
- <tt/lpf/ 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 <tt/lpf/.
-
- In order for <tt/lpf/ to do page accounting correctly, it
- needs correct values filled in for the <tt/pw/ and <tt/pl/
- capabilities in the <tt>/etc/printcap</tt> 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 <ref
- id="printing:advanced:acct" name="Accounting for Printer
- Usage">.
-
- <sect1><heading>Header Pages<label
- id="printing:advanced:header-pages"></heading>
-
- <p> If you have <em/lots/ of users, all of them using
- various printers, then you probably want to consider
- <em/header pages/ as a necessary evil.
-
- Header pages, also known as <em/banner/ or <em/burst pages/
- 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.)
-
- The LPD system can provide header pages automatically for
- your printouts <em/if/ 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 <ref
- id="printing:advanced:header-pages:ps" name="Header Pages on
- PostScript Printers">.
-
- <sect2><heading>Enabling Header Pages<label
- id="printing:advanced:header-pages:enabling"></heading>
-
- <p> In the <ref id="printing:simple" name="Simple Printer
- Setup">, we turned off header pages by specifying
- <tt/sh/ (meaning ``suppress header'') in the
- <tt>/etc/printcap</tt> file. To enable header pages for
- a printer, just remove the <tt/sh/ capability.
-
- Sounds too easy, right?
-
- You are right. You <em/might/ 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:
-<code>
-#!/bin/sh
-#
-# hpof - Output filter for Hewlett Packard PCL-compatible printers
-# Installed in /usr/local/libexec/hpof
-
-
-printf "\033&amp;k2G" || exit 2
-exec /usr/libexec/lpr/lpf
-</code>
- Specify the path to the output filter in the <tt/of/
- capability. See <ref id="printing:advanced:of"
- name="Output Filters"> for more information.
-
- Here is an example <tt>/etc/printcap</tt> file for the printer
- <tt/teak/ that we introduced earlier; we enabled header
- pages and added the above output filter:
-<code>
-#
-# /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:
-</code>
- Now, when users print jobs to <tt/teak/, 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 <tt/lpr -h/; see <ref
- id="printing:lpr:options:misc" name="Header Page Options">
- for more <tt/lpr/ options.
-
- <tt/Note:/ LPD 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 <tt/ff/ capability in <tt>/etc/printcap</tt>.
-
- <sect2><heading>Controlling Header Pages<label
- id="printing:advanced:header-pages:controlling"></heading>
-
- <p> By enabling header pages, LPD will produce a <em/long
- header/, a full page of large letters identifying the
- user, host, and job. Here is an example (kelly printed
- the job named outline from host rose):
-<tscreen><verb>
-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
-</verb></tscreen>
- LPD appends a form feed after this text so the job starts
- on a new page (unless you have <tt/sf/ (suppress form
- feeds) in the destination printer's entry in
- <tt>/etc/printcap</tt>).
-
- If you prefer, LPD can make a <em/short header/; specify
- <tt/sb/ (short banner) in the <tt>/etc/printcap</tt> file.
- The header page will look like this:
-<tscreen><verb>
-rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995
-</verb></tscreen>
- Also by default, LPD prints the header page first, then
- the job. To reverse that, specify <tt/hl/ (header last)
- in <tt>/etc/printcap</tt>.
-
- <sect2><heading>Accounting for Header Pages<label
- id="printing:advanced:header-pages:accounting"></heading>
-
- <p> Using LPD's built-in header pages enforces a particular
- paradigm when it comes to printer accounting: header pages
- must be <em/free of charge/.
-
- Why?
-
- 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
- <em/user or host/ information or an accounting file, so it
- has no idea whom to charge for printer use. It is also not
- enough to just ``add one page'' to the text filter or any
- of the conversion filters (which do have user and host
- information) since users can suppress header pages with
- <tt/lpr -h/. They could still be charged for header pages
- they did not print. Basically, <tt/lpr -h/ will be the
- preferred option of environmentally-minded users, but you
- cannot offer any incentive to use it.
-
- It is <em/still not enough/ 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 <tt/lpr -h/, they will
- still get them and be charged for them since LPD does not
- pass any knowledge of the <tt/-h/ option to any of the
- filters.
-
- So, what are your options?
-
- You can
- <itemize>
- <item>Accept LPD's paradigm and make header pages free.
-
- <item>Install an alternative to LPD, such as LPDng or
- PLP. Section <ref name="Alternatives to the Standard
- Spooler" id="printing:lpd-alternatives"> tells more
- about other spooling software you can substitute for
- LPD.
-
- <item>Write a <em/smart/ 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 LPD will start the output filter only for
- the header pages. And the output filter can parse the
- header page text that LPD 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 <tt/af/
- 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 <tt/sh/ (short
- header) capability in <tt>/etc/printcap</tt>.
-
- Then again, all that might be too much trouble, and
- users will certainly appreciate the more generous
- system administrator who makes header pages free.
- </itemize>
-
- <sect2><heading>Header Pages on PostScript Printers<label
- id="printing:advanced:header-pages:ps"></heading>
-
- <p> As described above, LPD 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 LPD is useless---or mostly so.
-
- One obvious way to get header pages is to have every
- conversion filter and the text filter generate the header
- page. The filters should 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 <tt/lpr -h/.
-
- 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:
-<code>
-#!/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>&amp;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
-</code>
- 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:
-<code>
-#!/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>&amp;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>&amp;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
-</code>
- 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 <ref id="printing:advanced:filters" name="How
- Filters Work">).
-
- As we have mentioned before, the above scheme, though fairly
- simple, disables the ``suppress header page'' option (the
- <tt/-h/ option) to <tt/lpr/. 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.
-
- To allow users to shut off header pages on a per-job
- basis, you will need to use the trick introduced in section
- <ref id="printing:advanced:header-pages:accounting"
- name="Accounting for Header Pages">: write an output
- filter that parses the LPD-generated header page and
- produces a PostScript version. If the user submits the
- job with <tt/lpr -h/, then LPD will not generate a header
- page, and neither will your output filter. Otherwise,
- your output filter will read the text from LPD and send
- the appropriate header page PostScript code to the
- printer.
-
- If you have a PostScript printer on a serial line, you
- can make use of <tt/lprps/, which comes with an output
- filter, <tt/psof/, which does the above. Note that
- <tt/psof/ does not charge for header pages.
-
- <sect1><heading>Networked Printing<label
- id="printing:advanced:network-printers"></heading>
-
- <p> FreeBSD supports networked printing: sending jobs to
- remote printers. Networked printing generally refers to two
- different things:
- <itemize>
- <item>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 LPD to
- enable access to the printer from other hosts on the
- network. Section <ref id="printing:advanced:network:rm"
- name="Printers Installed on Remote Hosts"> tells how to
- do this.
-
- <item>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:
-
- <itemize>
- <item>It might understand the LPD protocol and can
- even queue jobs from remote hosts. In this case, it
- acts just like a regular host running LPD. Follow
- the same procedure in section <ref
- id="printing:advanced:network:rm" name="Printers
- Installed on Remote Hosts"> to set up such a
- printer.
-
- <item>It might support a data stream network
- connection. In this case, you ``attach'' the
- printer to one host on the network by making that
- host responsible for spooling jobs and sending them
- to the printer. Section <ref
- id="printing:advanced:network:net-if" name="Printers
- with Networked Data Stream Interfaces"> gives some
- suggestions on installing such printers.
- </itemize>
- </itemize>
-
- <sect2><heading>Printers Installed on Remote Hosts<label
- id="printing:advanced:network:rm"></heading>
-
- <p> The LPD spooling system has built-in support for sending
- jobs to other hosts also running LPD (or are compatible
- with LPD). 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 LPD protocol.
-
- To enable this kind of remote printing, first install a
- printer on one host, the <em/printer host/, using the
- simple printer setup described in <ref
- id="printing:simple" name="Simple Printer Setup">. Do any
- advanced setup in <ref id="printing:advanced"
- name="Advanced Printer Setup"> that you need. Make sure
- to test the printer and see if it works with the features
- of LPD you have enabled.
-
- If you are using a printer with a network interface that is
- compatible with LPD, then the <em/printer host/ in the
- discussion below is the printer itself, and the
- <em/printer name/ is the name you configured for the
- printer. See the documentation that accompanied your
- printer and/or printer-network interface.
-
- Then, on the other hosts you want to have access to the
- printer, make an entry in their <tt>/etc/printcap</tt>
- files with the following:
- <enum>
- <item>Name the entry anything you want. For
- simplicity, though, you probably want to use the same
- name and aliases as on the printer host.
-
- <item>Leave the <tt/lp/ capability blank, explicitly
- (<tt/:lp=:/).
-
- <item>Make a spooling directory and specify its
- location in the <tt/sd/ capability. LPD will store
- jobs here before they get sent to the printer host.
-
- <item>Place the name of the printer host in the <tt/rm/
- capability.
-
- <item>Place the printer name on the <em/printer host/ in
- the <tt/rp/ capability.
- </enum>
- That is it. You do not need to list conversion filters,
- page dimensions, or anything else in the
- <tt>/etc/printcap</tt> file.
-
- Here is an example. The host rose has two printers,
- <tt/bamboo/ and <tt/rattan/. We will enable users on the
- host orchid to print to those printers. Here is the
- <tt>/etc/printcap</tt> file for orchid (back from section
- <ref id="printing:advanced:header-pages:enabling"
- name="Enabling Header Pages">). It already had the entry
- for the printer <tt/teak/; we have added entries for the two
- printers on the host rose:
-<code>
-#
-# /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:
-</code>
- Then, we just need to make spooling directories on orchid:
-<tscreen><verb>
-mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo
-chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo
-chown daemon.daemon /var/spool/lpd/rattan /var/spool/lpd/bamboo
-</verb></tscreen>
-
- Now, users on orchid can print to <tt/rattan/ and
- <tt/bamboo/. If, for example, a user on orchid typed
-<tscreen><verb>
-lpr -P bamboo -d sushi-review.dvi
-</verb></tscreen>
- the LPD system on orchid would copy the job to the
- spooling directory <tt>/var/spool/lpd/bamboo</tt> and note
- that it was a DVI job. As soon as the host rose has room
- in its <tt/bamboo/ spooling directory, the two
- LPDs would transfer the file to rose. The file would wait
- in rose's queue until it was finally printed. It would be
- converted from DVI to PostScript (since bamboo is a
- PostScript printer) on rose.
-
- <sect2><heading>Printers with Networked Data Stream Interfaces<label
- id="printing:advanced:network:net-if"></heading>
-
- <p> 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 <ref name="Printers
- Installed on Remote Hosts" id="printing:advanced:network:rm">.
-
- The format of the <tt>/etc/printcap</tt> 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.
-
- 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
- <tt/netprint/ 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
- <tt/netprint/. 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.).
-<code>
-#!/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', &amp;AF_INET, $printer_port, $address);
-
-socket(PRINTER, &amp;PF_INET, &amp;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;
-</code>
- 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:
-<code>
-#!/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
-</code>
-
-
- <sect1><heading>Restricting Printer Usage<label
- id="printing:advanced:restricting"></heading>
-
- <p> This section gives information on restricting printer
- usage. The LPD 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.
-
- <sect2><heading>Restricting Multiple Copies<label
- id="printing:advanced:restricting:copies"></heading>
-
- <p> The LPD system makes it easy for users to print multiple
- copies of a file. Users can print jobs with <tt/lpr -&num;5/
- (for example) and get five copies of each file in the job.
- Whether this is a good thing is up to you.
-
- If you feel multiple copies cause unnecessary wear and
- tear on your printers, you can disable the <tt/-&num;/ option
- to <tt/lpr/ by adding the <tt/sc/ capability to the
- <tt>/etc/printcap</tt> file. When users submit jobs
- with the <tt/-&num;/ option, they will see
-<tscreen><verb>
-lpr: multiple copies are not allowed
-</verb></tscreen>
-
- Note that if you have set up access to a printer remotely
- (see section <ref name="Printers Installed on Remote
- Hosts" id="printing:advanced:network:rm">), you need the
- <tt/sc/ capability on the remote <tt>/etc/printcap</tt>
- files as well, or else users will still be able to submit
- multiple-copy jobs by using another host.
-
- Here is an example. This is the <tt>/etc/printcap</tt>
- file for the host rose. The printer <tt/rattan/ is quite
- hearty, so we will allow multiple copies, but the laser
- printer <tt/bamboo/'s a bit more delicate, so we will
- disable multiple copies by adding the <tt/sc/ capability:
-<code>
-#
-# /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:
-</code>
- Now, we also need to add the <tt/sc/ capability on the
- host orchid's <tt>/etc/printcap</tt> (and while we are at
- it, let us disable multiple copies for the printer
- <tt/teak/):
-<code>
-#
-# /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:
-</code>
- By using the <tt/sc/ capability, we prevent the use of
- <tt/lpr -&num;/, but that still does not prevent users from
- running <tt/lpr/ multiple times, or from submitting the
- same file multiple times in one job like this:
-<tscreen><verb>
-lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.sign
-</verb></tscreen>
- There are many ways to prevent this abuse (including
- ignoring it) which you are free to explore.
-
- <sect2><heading>Restricting Access To Printers<label
- id="printing:advanced:restricting:access"></heading>
-
- <p> You can control who can print to what printers by using
- the UNIX group mechanism and the <tt/rg/ capability in
- <tt>/etc/printcap</tt>. Just place the users you want to
- have access to a printer in a certain group, and then name
- that group in the <tt/rg/ capability.
-
- Users outside the group (including root) will be greeted
- with
-<tscreen><verb>
-lpr: Not a member of the restricted group
-</verb></tscreen>
- if they try to print to the controlled printer.
-
- As with the <tt/sc/ (suppress multiple copies) capability,
- you need to specify <tt/rg/ on remote hosts that also have
- access to your printers, if you feel it is appropriate (see
- section <ref name="Printers Installed on Remote Hosts"
- id="printing:advanced:network:rm">).
-
- For example, we will let anyone access the printer
- <tt/rattan/, but only those in group <tt/artists/ can use
- <tt/bamboo/. Here is the familiar <tt>/etc/printcap</tt>
- for host rose:
-<code>
-#
-# /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:
-</code>
- Let us leave the other example <tt>/etc/printcap</tt> file
- (for the host orchid) alone. Of course, anyone on orchid
- can print to <tt/bamboo/. It might be the case that we
- only allow certain logins on orchid anyway, and want them
- to have access to the printer. Or not.
-
- <em/Note:/ there can be only one restricted group per
- printer.
-
- <sect2><heading>Controlling Sizes of Jobs Submitted<label
- id="printing:advanced:restricting:sizes"></heading>
-
- <p> 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.
-
- LPD enables you to limit the maximum byte size a file in a
- job can be with the <tt/mx/ capability. The units are in
- BUFSIZ blocks, which are 1024 bytes. If you put a zero
- for this capability, there will be no limit on file size.
- Note that the limit applies to <em/files/ in a job, and
- <em/not/ the total job size.
-
- LPD 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.
-
- Let us add limits to our example printers <tt/rattan/ and
- <tt/bamboo/. 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:
-<code>
-#
-# /etc/printcap for host rose
-#
-
-#
-# No limit on job size:
-#
-rattan|line|diablo|lp|Diablo 630 Line Printer:\
- :sh: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:
-</code>
- 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
- <tt/mx/ capability in the remote <tt>/etc/printcap</tt>
- files as well. See section <ref name="Printers Installed
- on Remote Hosts" id="printing:advanced:network:rm"> for
- more information on remote printing.
-
- There is another specialized way to limit job sizes from
- remote printers; see section <ref
- id="printing:advanced:restricting:remote"
- name="Restricting Jobs from Remote Printers">.
-
- <sect2><heading>Restricting Jobs from Remote Printers<label
- id="printing:advanced:restricting:remote"></heading>
-
- <p> The LPD spooling system provides several ways to restrict
- print jobs submitted from remote hosts:
-
- <descrip>
- <tag/Host restrictions/
-
- You can control from which remote hosts a local LPD
- accepts requests with the files
- <tt>/etc/hosts.equiv</tt> and <tt>/etc/hosts.lpd</tt>.
- LPD checks to see if an incoming request is from a
- host listed in either one of these files. If not, LPD
- refuses the request.
-
- The format of these files is simple: one host name per
- line. Note that the file <tt>/etc/hosts.equiv</tt> is
- also used by the ruserok(3) protocol, and affects
- programs like <tt/rsh/ and <tt/rcp/, so be careful.
-
- For example, here is the <tt>/etc/hosts.lpd</tt> file
- on the host rose:
-<code>
-orchid
-violet
-madrigal.fishbaum.de
-</code>
- This means rose will accept requests from the hosts
- orchid, violet, and madrigal.fishbaum.de. If any
- other host tries to access rose's LPD, LPD will
- refuse them.
-
- <tag/Size restrictions/
-
- You can control how much free space there needs to
- remain on the filesystem where a spooling directory
- resides. Make a file called <tt/minfree/ 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.
-
- 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 <tt/minfree/ file.
-
- For example, let us add a <tt/minfree/ file for the
- printer <tt/bamboo/. We examine
- <tt>/etc/printcap</tt> to find the spooling directory
- for this printer; here is <tt/bamboo/'s entry:
-<tscreen><verb>
-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:
-</verb></tscreen>
- The spooling directory is the given in the <tt/sd/
- capability. We will make three megabytes (which is 6144
- disk blocks) the amount of free disk space that must
- exist on the filesystem for LPD to accept remote jobs:
-<tscreen><verb>
-echo 6144 > /var/spool/lpd/bamboo/minfree
-</verb></tscreen>
- <tag/User restrictions/
-
- You can control which remote users can print to local
- printers by specifying the <tt/rs/ capability in
- <tt>/etc/printcap</tt>. When <tt/rs/ appears in the
- entry for a locally-attached printer, LPD will accept
- jobs from remote hosts <em/if/ the user submitting the
- job also has an account of the same login name on the
- local host. Otherwise, LPD refuses the job.
-
- 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 <em/only/ your printers and not your
- compute resources, you can give them ``token''
- accounts, with no home directory and a useless shell
- like <tt>/usr/bin/false</tt>.
- </descrip>
-
- <sect1><heading>Accounting for Printer Usage<label
- id="printing:advanced:acct"></heading>
-
- <p> 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?
-
- Well, the bad news is the LPD 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 <em/your/ requirements in charging for printer
- usage.
-
- 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 <ref name="Filters"
- id="printing:advanced:filter-intro">.
-
- Generally, there are two ways to do accounting:
- <itemize>
- <item><em/Periodic accounting/ 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.
-
- <item><em/Timely accounting/ 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 ``print quotas.''
- But this method requires some database code to track
- users and their quotas.
- </itemize>
-
- The LPD 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.
-
- <sect2><heading>Quick and Dirty Printer Accounting</heading>
-
- <p> FreeBSD comes with two programs that can get you set up
- with simple periodic accounting right away. They are the
- text filter <tt/lpf/, described in section <ref
- id="printing:advanced:lpf" name="lpf: a Text Filter">, and
- <tt/pac/, a program to gather and total entries from
- printer accounting files.
-
- As mentioned in the section on filters (<ref
- id="printing:advanced:filters" name="Filters">), LPD
- 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 <tt/af/ capability in
- <tt>/etc/printcap</tt>, and if not specified as an
- absolute path, is relative to the spooling directory.
-
- LPD starts <tt/lpf/ with page width and length arguments
- (from the <tt/pw/ and <tt/pl/ capabilities). <tt/lpf/
- 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:
-<tscreen><verb>
- 2.00 rose:andy
- 3.00 rose:kelly
- 3.00 orchid:mary
- 5.00 orchid:mary
- 2.00 orchid:zhang
-</verb></tscreen>
- You should use a separate accounting file for each
- printer, as <tt/lpf/ has no file locking logic built into
- it, and two <tt/lpf/s might corrupt each other's entries
- if they were to write to the same file at the same time.
- A easy way to insure a separate accounting file for each
- printer is to use <tt/af=acct/ in <tt>/etc/printcap</tt>.
- Then, each accounting file will be in the spooling directory
- for a printer, in a file named <tt/acct/.
-
- When you are ready to charge users for printouts, run the
- <tt/pac/ program. Just change to the spooling directory
- for the printer you want to collect on and type <tt/pac/.
- You will get a dollar-centric summary like the following:
-<code>
- 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
-</code>
- These are the arguments <tt/pac/ expects:
- <descrip>
- <tag/<tt/-P<it/printer///
-
- Which <it/printer/ to summarize. This option works
- only if there is an absolute path in the <tt/af/
- capability in <tt>/etc/printcap</tt>.
-
- <tag/<tt/-c//
-
- Sort the output by cost instead of alphabetically by
- user name.
-
- <tag/<tt/-m//
-
- Ignore host name in the accounting files. With this
- option, user smith on host alpha is the same user
- smith on host gamma. Without, they are different users.
-
- <tag/<tt/-p<it/price///
-
- Compute charges with <it/price/ dollars per page or
- per foot instead of the price from the <tt/pc/
- capability in <tt>/etc/printcap</tt>, or two cents (the
- default). You can specify <it/price/ as a floating
- point number.
-
- <tag/<tt/-r//
-
- Reverse the sort order.
-
- <tag/<tt/-s//
-
- Make an accounting summary file and truncate the
- accounting file.
-
- <tag/<tt/<it/names...///
-
- Print accounting information for the given user
- <it/names/ only.
- </descrip>
-
- In the default summary that <tt/pac/ 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 <tt/pac -m/, to produce the following
- summary:
-<code>
- 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
-</code>
- To compute the dollar amount due, <tt/pac/ uses the
- <tt/pc/ capability in the <tt>/etc/printcap</tt> 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 <tt/pac/ with the <tt/-p/
- option. The units for the <tt/-p/ option are in dollars,
- though, not hundredths of cents. For example,
-<tscreen><verb>
-pac -p1.50
-</verb></tscreen>
- makes each page cost one dollar and fifty cents. You can
- really rake in the profits by using this option.
-
- Finally, running <tt/pac -s/ will save the summary
- information in a summary accounting file, which is named
- the same as the printer's accounting file, but with
- <tt/_sum/ appended to the name. It then truncates the
- accounting file. When you run <tt/pac/ again, it rereads
- the summary file to get starting totals, then adds
- information from the regular accounting file.
-
-
- <sect2><heading>How Can You Count Pages Printed?</heading>
-
- <p> 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.
-
- For plain text jobs, the problem's 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.
-
- The text filter <tt/lpf/ (introduced in <ref
- id="printing:advanced:lpf" name="lpf: a Text Filter">)
- 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 <tt/lpf/'s source
- code.
-
- How do you handle other file formats, though?
-
- Well, for DVI-to-LaserJet or DVI-to-PostScript conversion,
- you can have your filter parse the diagnostic output of
- <tt/dvilj/ or <tt/dvips/ and look to see how many pages
- were converted. You might be able to do similar things
- with other file formats and conversion programs.
-
- 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.
-
- So, what can you do?
-
- There is only one <em/sure/ way to do <em/accurate/
- 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 <em/only/. There is no
- line counting nor error-prone file examination required.
-
- Of course, you can always be generous and make all
- printouts free.
-
- <sect><heading>Alternatives to the Standard Spooler<label
- id="printing:lpd-alternatives"></heading>
-
- <p> If you have been reading straight through this manual, by now
- you have learned just about everything there is to know about
- the LPD spooling system that comes with FreeBSD. You can
- probably appreciate many of its shortcomings, which naturally
- leads to the question: ``What other spooling systems are out
- there (and work with FreeBSD)?''
-
- Unfortunately, I have located only <em/two/ alternatives---and
- they are almost identical to each other! They are:
- <descrip>
- <tag/PLP, the Portable Line Printer Spooler System/
-
- PLP was based on software developed by Patrick Powell and
- then maintained by an Internet-wide group of developers.
- The main site for the software is at <htmlurl
- url="ftp://ftp.iona.ie/pub/plp"
- name="ftp://ftp.iona.ie/pub/plp">. There is also a <htmlurl
- url="http://www.iona.ie:8000/www/hyplan/jmason/plp.html"
- name="web page">.
-
- It is quite similar to the BSD LPD spooler, but boasts a
- host of features, including:
- <itemize>
- <item>Better network support, including built-in support
- for networked printers, NIS-maintained printcaps, and
- NFS-mounted spooling directories
-
- <item>Sophisticated queue management, allowing multiple
- printers on a queue, transfer of jobs between queues,
- and queue redirection
-
- <item>Remote printer control functions
-
- <item>Prioritization of jobs
-
- <item>Expansive security and access options
- </itemize>
-
- <tag/LPRng/
-
- LPRng, which purportedly means ``LPR: the Next
- Generation'' is a complete rewrite of PLP. Patrick Powell
- and Justin Mason (the principal maintainer of PLP)
- collaborated to make LPRng. The main site for LPRng is
- <htmlurl url="ftp://dickory.sdsu.edu/pub/LPRng"
- name="ftp://dickory.sdsu.edu/pub/LPRng">.
- </descrip>
-
-
- <sect><heading>Acknowledgments</heading>
-
- <p> I would like to thank the following people who have assisted in
- the development of this document:
-
- <descrip>
- <tag/Daniel Eischen <tt/&lt;deischen@iworks.interworks.org&gt;//
-
- For providing a plethora of HP filter programs for perusal.
-
- <tag/&a.jehamby;/
-
- For the Ghostscript-to-HP filter.
-
- <tag/My wife, Mary Kelly <tt/&lt;urquhart@argyre.colorado.edu&gt;//
-
- For allowing me to spend more time with FreeBSD than with her.
-
- </descrip>
OpenPOWER on IntegriCloud