diff options
Diffstat (limited to 'share/doc/handbook/printing.sgml')
-rw-r--r-- | share/doc/handbook/printing.sgml | 3876 |
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 | 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 | 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#<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>˜><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#<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#<it/clear-bits/</tt>/ - - Clears the flag bits <it/clear-bits/ in the - <tt/sgttyb/ structure after opening the device. - - <tag/<tt>fs#<it/set-bits/</tt>/ - - Sets the flag bits <it/set-bits/ in the <tt/sgttyb/ - structure. - - <tag/<tt>xc#<it/clear-bits/</tt>/ - - Clears local mode bits <it/clear-bits/ after opening - the device. - - <tag/<tt>xs#<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 && 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> -!"#$%&'()*+,-./01234 -"#$%&'()*+,-./012345 -#$%&'()*+,-./0123456 -$%&'()*+,-./01234567 -%&'()*+,-./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 && printf "\f" && exit 0 -exit 2 -</code> - - <tag/It produced the ``staircase effect.''/ - - You got the following on paper: -<tscreen><verb> -!"#$%&'()*+,-./01234 - "#$%&'()*+,-./012345 - #$%&'()*+,-./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&k2G" && cat && printf "\f" && 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/-# <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/%!/ (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 && cat && printf "\004" && exit 0 - exit 2 -else - # - # Plain text, convert it, then print it. - # - ( echo $first_line; cat ) | /usr/local/bin/textps && printf "\004" && exit 0 - exit 2 -fi -</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&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=- - \ - && 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 && cat && printf "\f" && 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&k2G" && fpr && printf "\f" && 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>&2 - cleanup - exit 2 -} - -# -# If user removes the job, LPD will send SIGINT, so trap SIGINT -# (and a few other signals) to clean up after ourselves. -# -trap cleanup 1 2 15 - -# -# Make sure we are not colliding with any existing files. -# -cleanup - -# -# Link the DVI input file to standard input (the file to print). -# -ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0" - -# -# Make LF = CR+LF -# -printf "\033&k2G" || fatal "Cannot initialize printer" - -# -# Convert and print. Return value from dvilj2p does not seem to be -# reliable, so we ignore it. -# -dvilj2p -M1 -q -e- dfhp$$.dvi - -# -# Clean up and exit -# -cleanup -exit 0 -</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&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>&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>&2 - exit 2 -} - -while getopts "x:y:n:h:" option; do - case $option in - x|y) ;; # Ignore - n) login=$OPTARG ;; - h) host=$OPTARG ;; - *) echo "LPD started `basename $0` wrong." 1>&2 - exit 2 - ;; - esac -done - -[ "$login" ] || fail "No login name" -[ "$host" ] || fail "No host name" - -( /usr/local/libexec/make-ps-header $login $host "DVI File" - /usr/local/bin/dvips -f ) | eval /usr/local/libexec/lprps $orig_args -</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', &AF_INET, $printer_port, $address); - -socket(PRINTER, &PF_INET, &SOCK_STREAM, $protocol) - || die "Can't create TCP/IP stream socket: $!"; -connect(PRINTER, $sockaddr) || die "Can't contact $printer_host: $!"; -while (<STDIN>) { print PRINTER; } -exit 0; -</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 -#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/-#/ option - to <tt/lpr/ by adding the <tt/sc/ capability to the - <tt>/etc/printcap</tt> file. When users submit jobs - with the <tt/-#/ 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 -#/, 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/<deischen@iworks.interworks.org>// - - 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/<urquhart@argyre.colorado.edu>// - - For allowing me to spend more time with FreeBSD than with her. - - </descrip> |