1<!DOCTYPE book
2  SYSTEM "LPRng-Reference.dtd"
3 -- PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN" --
4 -- PUBLIC "-//OASIS//DTD DocBook V3.1//EN" --
5[
6  <!ENTITY LPRng "<application/LPRng/">
7  <!ENTITY LPRngTool "<application/LPRngTool/">
8  <!ENTITY lpd "<application/lpd/">
9  <!ENTITY lpr "<application/lpr/">
10  <!ENTITY ifhp "<application/ifhp/">
11  <!ENTITY license SYSTEM "license.enc">
12  <!ENTITY y2k SYSTEM "y2k.txt">
13  <!ENTITY genindex.sgml SYSTEM "genindex.sgml">
14]>
15
16<book>
17<bookinfo><title> LPRng Reference Manual</title>
18<subtitle> 5 Sep 2003 (For LPRng-3.8.22)</subtitle>
19
20<author>
21<firstname>Patrick</firstname>
22<othername role=mi>A</othername>
23<surname>Powell</surname>
24<affiliation>
25<address>
26<email>papowell@lprng.com</email>
27AStArt Technologies
286741 Convoy Court,
29San Diego, CA 92111
30Phone <phone>858-874-6543</phone>
31Fax <fax>858-751-2435</fax>
32</address>
33</affiliation>
34</author>
35<copyright>
36<year>1996-2001</year>
37<holder role="mailto:papowell@lprng.com">Patrick Powell</holder>
38</copyright>
39
40<releaseinfo>$Id: LPRng-Reference.sgml,v 1.1.1.1 2008/10/15 03:28:11 james26_jang Exp $</releaseinfo>
41
42    <legalnotice>
43     <important>
44    <para>
45<!-- <mediaobject> -->
46<!-- <imageobject> -->
47<!-- <imagedata fileref="somegraphic.eps"> -->
48<!-- </imageobject> -->
49<!-- <imageobject> -->
50<!-- <imagedata fileref="somegraphic.jpg"> -->
51<!-- </imageobject> -->
52<!-- </mediaobject> -->
53        THIS DOCUMENTATION AND THE DESCRIBED SOFTWARE IS PROVIDED BY
54      THE AUTHORS "AS IS" AND ANY
55      EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56      IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57      PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
58      ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59      CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60      SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
61      BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
62      LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
63      NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64      DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
65      DAMAGE.</para>
66      </important>
67    </legalnotice>
68
69<abstract>
70<para>The LPRng; Printing Software consists of the &LPRng; print spooler,
71the &ifhp; print filter, and
72the &LPRngTool; graphical user interface.
73</para>
74<para>The &LPRng; print spooler is an enhanced, extended, and portable implementation
75of the Berkeley <application/lpr/ print spooler functionality. While providing the same
76interface and meeting RFC1179 requirements, the implementation is completely
77independent and provides support for the following features: lightweight (no databases
78needed) lpr, lpc, and lprm programs; dynamic redirection of print queues;
79printer pooling and load balancing;
80automatic job holding; highly verbose diagnostics;
81client programs do not need to run SETUID root; greatly enhanced
82security checks; load balancing across multiple printers;
83and a greatly improved permission and authorization mechanism.
84The source software compiles and runs on a wide variety of UNIX systems,
85and is compatible with other print spoolers and network printers that use
86the <application/lpr/ interface and meet RFC1179 requirements.
87Included in the &LPRng; print spooler distribution is
88a set of customizable banner page generation programs.
89</para>
90<para>
91The SVR4 lp and lpstat functionality is provided by a set of emulator
92programs,
93and &LPRng; can be easily integrated with the Samba SMB support package.
94For users that require secure and/or authenticated printing support,
95&LPRng; supports
96SSL (using <application/OpenSSL/),
97Kerberos 5,
98MIT Kerberos 4 extensions to LPR,
99PGP,
100and simple MD5 based authentication.
101Additional authentication support is extremely simple to add.
102</para>
103<para>
104The &ifhp; print filter converts
105print jobs into formats compatible with
106PostScript, PCL, text, and other printers and
107provides diagnostic and error information as well as
108accounting information.
109</para>
110<para>
111The ;LPRngTool& Graphical User Interface provides a simple to use
112configuration and monitoring tool.
113It allows users to monitor printers and generate printcap entries
114in a simple manner,  as well as providing extensive help and diagnostics.
115</para>
116</abstract>
117</bookinfo>
118
119<preface><title>Preface</title>
120
121<sect1><title>Introduction</title>
122<para>
123The &LPRng; Print Spooler provides the essential printing services
124for UNIX and UNIX-like operating systems.
125It can be configured to work in small,
126large,
127or enterprise level environments.
128The &ifhp; Print Filter
129is used with &LPRng; to convert print jobs into a format compatible
130with a particular printer and the
131while it may briefly describe the &ifhp; operation,
132Finally,
133the &LPRngTool; Graphical User Interface  provides an easy to use
134configuration and monitoring tool for the &LPRng; print spooler.
135</para>
136<para>
137This document is the basic reference for the &LPRng; print spooler software;
138the &ifhp; documentation
139and &LPRngTool;
140should be consulted for details about their operation.
141</para>
142</sect1>
143
144
145<sect1><title>Acknowledgements</title>
146<para>I would like to thank all of the &LPRng; users
147who so relentlessly tried the incredible number of permutations and
148combinations of printers and software,
149and whose requests for <emphasis>just one more feature</emphasis>
150led to the development of the software.
151</para>
152</sect1>
153
154<sect1><title>Shell Prompts</title>
155
156      <para>The following table shows the default system prompt and superuser
157    prompt. The examples will use this prompt to indicate which user you
158    should be running the example as.</para>
159
160      <informaltable frame="none">
161    <tgroup cols="2">
162      <thead>
163        <row>
164          <entry>User</entry>
165          <entry>Prompt</entry>
166        </row>
167      </thead>
168
169      <tbody>
170        <row>
171          <entry>Normal user</entry>
172          <entry><prompt>%</prompt></entry>
173        </row>
174
175        <row>
176          <entry><literal>root</literal></entry>
177          <entry><prompt>#</prompt></entry>
178        </row>
179      </tbody>
180    </tgroup>
181      </informaltable>
182    </sect1>
183
184<sect1><title>Typographic Conventions</title>
185
186      <para>The following table describes the typographic conventions used in
187    this book.</para>
188
189      <informaltable frame="none">
190    <tgroup cols="2">
191      <thead>
192        <row>
193          <entry>Meaning</entry>
194          <entry>Examples</entry>
195        </row>
196      </thead>
197
198      <tbody>
199        <row>
200          <entry>The name of commands, files, and directories. On screen
201        computer output.</entry>
202          <entry><para>Edit your <filename>.login</filename>
203          file.</para><para>Use <command>ls -a</command> to list all
204          files.</para><para><screen>You have mail.</screen>
205        </para></entry>
206        </row>
207
208        <row>
209          <entry>What you type, when contrasted with on-screen computer
210        output.</entry>
211
212          <entry><screen><prompt>%</prompt> <userinput>su</userinput>
213Password:</screen></entry>
214        </row>
215
216        <row>
217          <entry>Manual page references.</entry>
218
219          <entry>Use <citerefentry>
220          <refentrytitle>su</refentrytitle>
221          <manvolnum>1</manvolnum>
222        </citerefentry> to change user names.</entry>
223        </row>
224
225        <row>
226          <entry>User and group names</entry>
227
228          <entry>Only <literal>root</literal> can do this.</entry>
229        </row>
230
231        <row>
232          <entry>Emphasis</entry>
233
234          <entry>You <emphasis>must</emphasis>
235do this.</entry>
236        </row>
237
238        <row>
239          <entry>Command line variables; replace with the real name or
240        variable.</entry>
241
242          <entry>To delete a file, type <command>rm <filename><replaceable>filename</replaceable></filename></command></entry>
243        </row>
244
245        <row>
246          <entry>Environment variables</entry>
247
248          <entry><envar>$HOME</envar> is your home directory.</entry>
249        </row>
250      </tbody>
251    </tgroup>
252      </informaltable>
253    </sect1>
254
255<sect1><title>Notes, warnings, and examples</title>
256
257      <para>Within the text appear notes, warnings, and examples.</para>
258
259      <note>
260    <para>Notes are represented like this, and contain information that
261      you should take note of, as it may affect what you do.</para>
262      </note>
263
264      <warning>
265    <para>Warnings are represented like this, and contain information
266      warning you about possible damage if you do not follow the
267      instructions. This damage may be physical, to your hardware or to
268      you, or it may be non-physical, such as the inadvertent deletion of
269      important files.</para>
270      </warning>
271
272      <informalexample>
273    <para>Examples are represented like this, and typically contain
274      examples you should walk through, or show you what the results of a
275      particular action should be.</para>
276      </informalexample>
277    </sect1>
278
279  </preface>
280
281
282<chapter id=introduction><title>Introduction</title>
283
284<para>Printing is one of the essential services provided by computer systems.
285Users want reliable and easy to use methods of printing
286that require a minimum amount of effort to used and understand.
287On single user systems with a directly attached printer they
288perceive that the printing process is simply a matter of
289<emphasis>storing</emphasis>
290or
291<emphasis>spooling</emphasis>
292a file,
293and then transferring it to the printer in a timely manner.
294In the classical
295<emphasis>multi-user</emphasis>
296systems,
297each user expects to share a common printer with one or more users;
298the print
299<emphasis>spooling</emphasis>
300system provides arbitration and sharing of the printer among the various users.
301In a <emphasis>network</emphasis>
302based multi-user system,
303there may be one or more printers shared by multiple users on many different
304systems.
305The print <emphasis>spoolers</emphasis>
306will need to cooperate to provide print services to
307the users in a simple an predictable manner.</para>
308
309<sect1 id="secfeatures"><title>What is &LPRng;?</title>
310<indexterm/<primary/History//
311<para>The &LPRng; print spooler software was developed to be robust,
312reliable,
313secure,
314scalable,
315and portable.
316It has been used since 1988 in extremely demanding
317academic printing environments such as University of Minnesota, MIT,
318and Rutgers,
319commercial companies such as Dow Jones and Abbot Pharmaceuticals,
320as well as being distributed with Linux, FreeBSD, and other systems.
321Each of these environments has a unique set of problems,
322demanding various configuration and administrative capabilities.
323For example,
324the simple single user system with a single or limited number of printers
325requires easy configuration and simple diagnostic procedures,
326while the network based printing system requires highly robust
327error logging,
328authentication,
329and failover support.
330&LPRng; provides a highly flexible configuration system that
331allows it to perform optimally in all of these environments.
332</para>
333
334<para>
335The &LPRng; software has three components:
336the &lpd; print spooler and the user client applications
337<application/lpr/,
338<application/lpq/,
339<application/lprm/,
340etc.;
341the IFHP print filter (<application/ifhp/) which is used to convert
342jobs into a suitable for a particular printer,
343and the
344the LPRngTool Graphic User Interface (<application/lprngtool/) which provides
345a simple and easy to use configuration and monitoring tool for the &LPRng; print spooler.
346</para>
347
348<para>
349&LPRng; mimics many of the features of the
350<emphasis>vintage</emphasis>
351or <emphasis>legacy</emphasis>
352Berkeley (University of California - Berkeley) Line Printer (LPR)
353package found on Berkeley derivatives of the Unix operating
354system.
355&LPRng; will print a document with little or no knowledge of the content
356or special processing required to print the document on a stand-alone machine
357or in a distributed printing environment.
358New (as compared to Berkeley LPR) features include: lightweight <application>lpr</application>,
359<application>lpc</application> and <application>lprm</application>
360programs, dynamic redirection of print queues, automatic job holding,
361highly verbose diagnostics, load balancing queues; enhanced
362security (SUID not required in most environments),
363and easy configuration.</para>
364
365<para>&LPRng; started life at the University of Waterloo in 1986
366as PLP (Public Line Printer), a replacement for the original BSD <application/lpd/ code.
367This was a one-shot effort by the author,
368Patrick Powell,
369to develop
370freely redistributed
371code
372without the restrictions of the BSD/AT&amp;T license
373and would allow non-licensed sites to fix and patch problems.
374From 1988 to 1992
375individuals and groups added features, hacked, slashed, and modified the
376PLP code, coordinated largely by Justin Mason (<email>jmason@iona.ie</email>)
377who started the &LPRng; mailing list.
378</para>
379
380<para>In 1992 while at San Diego State University
381Prof. Powell redesigned and reimplemented the PLP code
382and named the result &LPRng;.
383The goals of the &LPRng; project were to build a server system that was as
384close to user abuse proof as possible,
385that would provide services limited only by the inherent capacities of the
386support system,
387RFC1179 compliant,
388and with extensive debugging capabilities to allow
389quick and easy diagnostics of problems.
390</para>
391
392<para>In 1999
393the code base for &LPRng; was again reorganized in order to provide a common
394method for running on non-UNIX platforms such as Microsoft Windows NT,
395Apple Rhapsody, and embedded systems.</para>
396
397<para>As a side effect of this work,
398many security problems that could develop were identified and steps
399taken to ensure that they were not present in &LPRng;.
400For example,
401&LPRng; clients such as lpr, lprm, lpc, and lpq can run as
402ordinary users programs,
403the lpd server can run as a non-root user once a network port has
404been opened,
405and all text formatting operations done by &LPRng; use a very restricted and
406highly secure version of the <application/snprintf/ function.
407</para>
408</sect1>
409
410<sect1 id="maillist"><title>Additional Resources </title>
411
412<para>The main &LPRng; documentation is the LPRng Reference Manual,
413which is available in several formats.
414Information
415about &LPRng; and the latest release
416can be found on the &LPRng; web page
417<ulink URL="http://www.lprng.com/LPRng.html">http://www.lprng.com/LPRng.html</ulink></para>
418<indexterm/<primary/download//
419<indexterm/<primary/FTP site//
420
421<para>The &ifhp; documentation is the IFHP-HOWTO,
422which is available in the &ifhp; distribution.
423Information
424about &ifhp; and the latest release
425can be found on the &LPRng; web page
426<ulink URL="http://www.lprng.com/LPRng.html">http://www.lprng.com/LPRng.html</ulink></para>
427<indexterm/<primary/download//
428<indexterm/<primary/FTP site//
429
430<para>There is also a mailing list at
431<ulink URL="mailto:lprng-request@lprng.com?subject=subscribe">lprng@lprng.com</ulink>.
432To post to the list you must subscribe by sending send an email to
433<ulink URL="mailto:lprng-request@lprng.com?subject=subscribe">lprng-request@lprng.com</ulink>,
434with the message subject or body containing the word `subscribe' or `help'.</para>
435<indexterm/<primary/Mailing List//
436
437<para>Several presentations of &LPRng; and print spooling software have been made
438at the Large Installation System Administrator (LISA) conferences.
439The presentation at the LISA 98 conference
440is in the PowerPoint file <filename>LISA98.ppt</filename>
441in the &LPRng; distribution documentation.
442<indexterm/<primary/Tutorial notes//
443</para>
444</sect1>
445
446<sect1><title>Frequently Asked Questions</title>
447<para>There are a list of Frequently Asked Questions that appear regularly
448on the &LPRng; mailing list.
449See
450<link linkend="FAQ">The Most Frequently Asked Questions</link>.</para>
451<indexterm/<primary/FAQ//
452<indexterm/<primary/Frequently Asked Questions//
453</sect1>
454<sect1><title>License, Copyright, and Disclaimer</title>
455
456<para>The &LPRng; Print Spooler and the ifhp Print Filter software
457are distributed under the
458<ulink URL="license.txt">GNU Public License (GPL) and the Artistic License</ulink>.
459Users can choose to redistribute or use the software under a license
460that is appropriate for their purpose.
461Other licenses and distribution agreements are available by contacting
462<ulink URL="http://www.astart.com">AStArt Technologies</ulink>
463for information.</para>
464
465<para>THE MATERIAL IN THESE SOFTWARE PACKAGES AND DOCUMENTS
466IS PROVIDED WITHOUT FEE AND AS-IS WITH NO
467WARRANTY REGARDING FITNESS OF USE FOR ANY PURPOSE.
468THE AUTHOR AND ALL
469CONTRIBUTORS ARE NOT LIABLE FOR ANY DAMAGES, DIRECT OR INDIRECT,
470RESULTING FROM THE USE OF THE SOFTWARE OR ANY
471INFORMATION PROVIDED IN THIS DOCUMENT.
472</para>
473</sect1>
474
475<sect1><title>Commercial Support</title>
476
477<para><ulink URL="http://www.astart.com">AStArt Technologies</ulink>
478provides commercial support and enhancements for
479the &LPRng; and other network software.
480AStArt provides network and system consulting services for UNIX and NT
481systems, as well as real time and network software.</para>
482
483</sect1>
484
485<sect1><title>Web Site</title>
486
487<para>Web Page:
488<ulink URL="http://www.lprng.com">http://www.lprng.com</ulink></para>
489
490</sect1>
491
492<sect1 id="secftp"><title>FTP Sites </title>
493
494<para>Main FTP Site:
495<simplelist type=vert columns=1>
496<member>
497<ulink URL="ftp://ftp.lprng.com/pub/LPRng">ftp://ftp.lprng.com/pub/LPRng</ulink> (US)
498</member>
499</simplelist>
500</para>
501
502<!-- MIRRORSTART -->
503<para>Mirrors:<!-- <br> -->
504<simplelist type=vert columns=1>
505<member><ulink URL="ftp://ftp.u-aizu.ac.jp/pub/net/lpr/LPRng">ftp://ftp.u-aizu.ac.jp/pub/net/lpr/LPRng</ulink> (JA) </member>
506<member><ulink URL="ftp://ftp.cs.columbia.edu/pub/archives/pkg/LPRng">ftp://ftp.cs.columbia.edu/pub/archives/pkg/LPRng</ulink> (US) </member>
507<member><ulink URL="ftp://ftp.cise.ufl.edu/pub/mirrors/LPRng">ftp://ftp.cise.ufl.edu/pub/mirrors/LPRng</ulink> (US) </member>
508<member><ulink URL="ftp://ftp.cs.umn.edu/pub/LPRng">ftp://ftp.cs.umn.edu/pub/LPRng</ulink> (US) </member>
509<member><ulink URL="ftp://uiarchive.uiuc.edu/pub/ftp/ftp.lprng.com/pub/LPRng">ftp://uiarchive.uiuc.edu/pub/ftp/ftp.lprng.com/pub/LPRng</ulink> (US) </member>
510<member><ulink URL="ftp://ftp.sage-au.org.au/pub/printing/spooler/lprng/">ftp://ftp.sage-au.org.au/pub/printing/spooler/lprng/</ulink> (AU) </member>
511<member><ulink URL="ftp://mirror.aarnet.edu.au/pub/LPRng/">ftp://mirror.aarnet.edu.au/pub/LPRng/</ulink> (AU/NZ) </member>
512<member><ulink URL="http://mirror.aarnet.edu.au/pub/LPRng/">http://mirror.aarnet.edu.au/pub/LPRng/</ulink> (AU/NZ) </member>
513<member><ulink URL="ftp://sunsite.ualberta.ca/pub/Mirror/LPRng">ftp://sunsite.ualberta.ca/pub/Mirror/LPRng</ulink> (CA) </member>
514<member><ulink URL="ftp://ftp.informatik.uni-hamburg.de/pub/os/unix/utils/LPRng">ftp://ftp.informatik.uni-hamburg.de/pub/os/unix/utils/LPRng</ulink> (DE) </member>
515<member><ulink URL="ftp://ftp.uni-paderborn.de/pub/unix/printer/LPRng">ftp://ftp.uni-paderborn.de/pub/unix/printer/LPRng</ulink> (DE) </member>
516<member><ulink URL="ftp://ftp.mono.org/pub/LPRng">ftp://ftp.mono.org/pub/LPRng</ulink> (UK) </member>
517<member><ulink URL="ftp://ftp.iona.com/pub/plp/LPRng">ftp://ftp.iona.com/pub/plp/LPRng</ulink> (IE) </member>
518<member><ulink URL="ftp://uabgate.uab.ericsson.se/pub/unix/LPRng">ftp://uabgate.uab.ericsson.se/pub/unix/LPRng</ulink> (SE) </member>
519</simplelist>
520</para>
521<!-- MIRROREND -->
522
523</sect1>
524
525<sect1><title>Mailing List</title>
526
527<para>To join the &LPRng; mailing list, please send mail to
528<ulink URL="mailto: lprng-request@lprng.com">lprng-request@lprng.com</ulink>
529with the word 'subscribe' in the BODY.</para>
530
531<para>The &LPRng; mailing list is archived on<!-- <br> -->
532<ulink URL="http://www.findmail.com/list/lprng">http://www.findmail.com/list/lprng</ulink></para>
533
534</sect1>
535
536<sect1 id="faqref"><title>PGP Public Key </title>
537
538<para>The &LPRng; distributions have an MD5 checksum calculated,
539which is then signed with a PGP public key.
540Here is the key for validating the checksums:
541<informalexample>
542<screen>Type Bits/KeyID    Date       User ID
543pub  1024/00D95C9D 1997/01/31 Patrick A. Powell \
544   &lt;papowell@lprng.com&gt;
545
546-----BEGIN PGP PUBLIC KEY BLOCK-----
547Version: 2.6.3i
548
549mQCNAzLygTQAAAEEANBW5fPYjN3wSAnP9xWOUc3CvsMUxjip0cN2sY5qrdoJyIhn
550qbAspBopR+tGQfyp5T7C21yfWRRnfXmoJ3FVtgToAsJUYmzoSFY08eDx+rmSqCLe
551rdJjX8aG8jVXpGipEo9U4QsUK+OKzx3/y/OaK4cizoWqKvy1l4lEzDsA2VydAAUT
552tCdQYXRyaWNrIEEuIFBvd2VsbCA8cGFwb3dlbGxAYXN0YXJ0LmNvbT6JAJUDBRA0
553XonoiUTMOwDZXJ0BAQ2cBAC7zU9Fn3sC3x0USJ+3vjhg/qA+Gjb5Fi1dJd4solc4
554vJvtf0UL/1/rGipbR+A0XHpHzJUMP9ZfJzKZjaK/d0ZBNlS3i+JnypypeQiAqo9t
555FV0OyUCwDfWybgAORuAa2V6UJnAhvj/7TpxMmCApolaIb4yFyKunHa8aBxN+17Ro
556rrQlUGF0cmljayBBLiBQb3dlbGwgPHBhcG93ZWxsQHNkc3UuZWR1PokAlQMFEDLy
557gTSJRMw7ANlcnQEBYBYD/0zTeoiDNnI+NjaIei6+6z6oakqO70qFVx0FG3aP3kRH
558WlDhdtFaAuaMRh+RItHfFfcHhw5K7jiJdgKiTgGfj5Vt3OdHYkeeh/sddqgf9YnS
559tpj0u5NfrotPTUw39n6YTgS5/aW0PQfO9dx7jVUcGeod1TGXTe9mIhDMwDJI4J14
560=3Zbp
561-----END PGP PUBLIC KEY BLOCK-----</screen>
562</informalexample>
563</para>
564
565</sect1>
566
567<sect1><title>References and Standards</title>
568
569<para>The following references and standards have been used
570in the development of the &LPRng; software.</para>
571
572
573<sect2><title>RFCs</title>
574
575<para>During the early development of the Internet
576developers did not want to go through the laborious process of
577developing formal standards and applying to a standards body such as the
578EIA, IEEE, or ISO.
579Instead,
580they called the standards documents they developed
581<citation>Requests for Comments</citation>.
582These soon became <emphasis>de facto</emphasis>
583standards,
584and with the formal acceptance of the TCP/IP protocol as a
585network standard,
586<emphasis>de jure</emphasis>
587as well.</para>
588
589<para>You can get copies of the RFCs from literally
590hundreds of network sites,
591including
592<ulink URL="http://www.isi.edu">http://www.isi.edu</ulink>,
593<ulink URL="http://www.faqs.org/rfcs">http://www.faqs.org/rfcs</ulink>,
594<ulink URL="ftp://NIS.NSF.NET">NIS.NSF.NET</ulink>,
595<ulink URL="ftp://RFC.JVNC.NET">RFC.JVNC.NET</ulink>,
596or
597<ulink URL="ftp://FTP.ISI.EDU">FTP.ISI.EDU</ulink>.</para>
598
599<para>The <citation>RFC1179 - Line Printer Daemon Protocol</citation>
600describes the protocol used to transfer jobs from client program to
601print server.
602See
603<link linkend="rfc1179ref">RFC1179</link>
604for more a discussion of this protocol and more details about the RFC.
605The <ulink URL="rfc1179.txt">rfc1179.txt</ulink> file is included
606in the &LPRng; distribution documentation.</para>
607
608</sect2>
609
610<sect2 id="postscript"><title>PostScript </title>
611
612<para>PostScript is one of the <emphasis>de facto</emphasis>
613standards for print jobs.
614The
615Adobe Corporation
616(<ulink URL="http://www.adobe.com">http://www.adobe.com</ulink>)
617provides an excellent set of references for the PostScript language.
618They have made many of these available for downloading from their
619web sites or have published them in book form.</para>
620
621<para>The <citation>PostScript Language Reference Manual</citation>
622contains a great deal of technical information about the PostScript Language,
623and is the language reference manual.</para>
624
625<para>The <citation>PostScript Language Tutorial and Cookbook</citation>
626is a very nice and easy to read introduction to PostScript programming,
627and has some very useful utilities.
628Combined with
629<link linkend="ghostscript"> GhostScript </link>
630and the
631<link linkend="gv"> gv </link>
632display program
633you can very easily learn to write your own small PostScript programs,
634and more importantly,
635can learn to understand the contents of PostScript files.</para>
636
637<para> The <citation>PostScript Language Program Design</citation>
638is the companion to the
639<citation>PostScript Language Tutorial and Cookbook</citation>,
640and has more complex examples of PostScript programs.
641More importantly,
642it also introduces,
643although without explanation,
644the PostScript Document Structuring Conventions described in Appendix G
645of the
646The <citation>PostScript Language Reference Manual</citation>.
647This alone makes it useful.</para>
648
649</sect2>
650
651<sect2 id="pcl"><title>HP PCL 5 </title>
652
653<para>The Hewlett-Packard (HP) PCL Printer Language is the second de-facto
654standard for print jobs.
655Currently,
656Hewlett-Packard
657makes documentation for PCL available through their
658<citation>Developer Program</citation>.
659You will need to register and then search their site for the
660<citation>PCL 5 Printer Language Reference Manual</citation>.</para>
661
662</sect2>
663
664<sect2 id="pjl"><title>HP PJL </title>
665
666<para>The Hewlett-Packard (HP) Printer Job Language is used
667to control various features of HP printers.
668The <citation>Printer Job Language Reference Manual</citation>
669is also available from
670Hewlett-Packard
671(<ulink URL="http://www.hp.com">http://www.hp.com</ulink>)
672through their
673<citation>Developer Program</citation>.</para>
674
675</sect2>
676
677<sect2><title>PDF</title>
678
679<para>The Portable Document Format (<literal>pdf</literal>) was developed by Adobe to be
680a more useful method of distributing documentation for view
681by online systems and software.
682The
683<citation>Portable Document Format Reference Manual</citation>
684is available from
685Adobe
686(<ulink URL="http://www.adobe.com">http://www.adobe.com</ulink>).
687While <literal>pdf</literal> is not used directly as a print job language,
688it is one of the more common formats for files that need to be printed.
689It can be converted to PostScript by most <literal>pdf</literal> viewers such
690as GhostScript and
691Adobe Acrobat.</para>
692
693</sect2>
694</sect1>
695</chapter>
696
697<chapter id=installation><title>Installation
698</title>
699
700<para>The basic components of the &LPRng; system are the executables
701and the database files.
702This section deals with generating and installing the executable
703files.</para>
704
705
706<sect1><title>Getting Source Code and Support Programs</title>
707
708<para>
709<orderedlist>
710
711<listitem>
712<para>Obtain the latest or stable version of the &LPRng; source code from a
713
714<link linkend="secftp">&LPRng; FTP Site</link>.</para>
715</listitem>
716
717<listitem>
718<para>Obtain the latest or stable version of the <application>ifhp</application> filter source code from a
719
720<link linkend="secftp">&LPRng; FTP Site</link>.
721This filter is used to support
722PostScript,
723PCL,
724and text printers.</para>
725</listitem>
726
727<listitem>
728<para>Obtain the following GNU programs from one of the many
729<ulink URL="http://www.gnu.org">GNU Software Mirror Sites</ulink>
730and install them.
731See the directions in the GNU Zip distribution for details.
732
733<variablelist>
734<varlistentry><term>GNU <application>gzip</application> Compression Utility</term>
735<listitem>
736<para>Used to generate the compressed &LPRng; distribution.</para>
737
738</listitem>
739</varlistentry>
740
741<varlistentry><term>GNU <application>tar</application> Archive Utility</term>
742<listitem>
743<para>
744<ulink URL="http://www.gnu.org">GNU</ulink>
745<application>tar</application> supports
746<application>gzip</application> compression and decompression
747and is used to generate the &LPRng; distribution.</para>
748</listitem>
749</varlistentry>
750
751<varlistentry><term>GNU <application>make</application></term>
752<listitem>
753<para>&LPRng; requires
754<ulink URL="http://www.gnu.org">GNU</ulink>
755<application>make</application>
756for configuration and installation.</para>
757</listitem>
758</varlistentry>
759
760<varlistentry><term>GNU <application>gcc</application> Compiler or ANSI C Compiler</term>
761<listitem>
762<para>
763&LPRng; requires and ANSI C compiler.
764If you do not have an ANSI C compiler
765then please use the
766<ulink URL="http://www.gnu.org">GNU</ulink>
767<application>gcc</application> compiler.</para>
768</listitem>
769</varlistentry>
770
771</variablelist>
772</para>
773</listitem>
774
775
776<listitem>
777<para>Solaris Sparc and X86 Binaries for GCC and Make  can be obtained from
778<ulink URL="http://sunfreeware.com/">http://sunfreeware.com/</ulink>.</para>
779</listitem>
780
781<listitem>
782<para>While the following are not essential to &LPRng;
783they are used by the <application>ifhp</application> filter.
784<variablelist>
785<varlistentry><term><application>file</application> - File Identification Utility</term>
786<listitem>
787<anchor id=fileprog>
788<para>The Open Source <application/file/ utility by Ian F. Darwin
789can be obtained from
790<ulink URL="ftp://ftp.astron.com/pub/file/">
791ftp://ftp.astron.com/pub/file/
792</ulink>.
793or
794<ulink URL="ftp://ftp.lprng.com/pub/LPRng/UNIXTOOLS/file/">
795ftp://ftp.lprng.com/pub/LPRng/UNIXTOOLS/file/
796</ulink>.
797This is a greatly improved version of the original UNIX file utility and
798may be used by the <application>ifhp</application> filter to do file recognition.</para>
799
800</listitem>
801</varlistentry>
802
803<varlistentry><term><application>gs</application> - GhostScript</term>
804<listitem>
805<anchor id="ghostscript">
806<para>
807GhostScript
808can be obtained from
809<ulink URL="http://www.cs.wisc.edu/~ghost/">http://www.cs.wisc.edu/~ghost/</ulink>
810or
811<ulink URL="http://www.ghostscript.com">http://www.ghostscript.com</ulink>.
812GhostScript is a PostScript interpreter that allows you to translate
813PostScript to various printer compatible formats such as PCL,
814as well as displaying the code on a terminal.
815You might also want to get the PDF extensions that allows GhostScript to
816read and print PDF files.</para>
817
818</listitem>
819</varlistentry>
820
821<varlistentry><term><application>gv</application> - GhostView</term>
822<listitem>
823<anchor id="gv">
824<para>
825Of course you will want to get the <application>gv</application> program that
826uses GhostScript to display PostScript on an X terminal.
827It can be obtained from
828<ulink URL="http://wwwthep.physik.uni-mainz.de/~plass/gv/">http://wwwthep.physik.uni-mainz.de/~plass/gv/</ulink></para>
829</listitem>
830</varlistentry>
831</variablelist>
832</para>
833</listitem>
834
835</orderedlist>
836</para>
837
838</sect1>
839
840<sect1><title><envar>PATH</envar> Environment Variable and Utilities</title>
841
842<para>
843Make sure that directory where you
844you have installed
845the GNU tools
846is one of the first entries in the shell search <envar>PATH</envar>
847environment variable.
848For example,
849if you have installed the utilities in the (default) directory
850<filename>/usr/local/bin</filename>,
851this should be one of the first entries in the <envar>PATH</envar>.
852For example:
853<informalexample>
854<screen>PATH=/usr/local/bin:/bin:/sbin:/usr/bin
855</screen>
856</informalexample>
857</para>
858
859<para>If you are compiling the distribution on a Solaris system
860you will need to use the utilities in the
861<filename>/usr/ccs/bin</filename>
862directory.
863This directory must be in the <envar>PATH</envar>
864<emphasis>after</emphasis>
865the directory where the GNU utilities have been installed.
866For example:
867<informalexample>
868<screen>PATH=/usr/local/bin:/bin:/sbin:/usr/bin:/usr/ccs/bin
869</screen>
870</informalexample>
871</para>
872
873<para>
874Check to see that the GNU <application>make</application> utility
875and not the default OS <application>make</application> is being used by default.
876Use <command>make -v</command> to determine what version you are using:
877<informalexample>
878<literallayout><prompt>h4: {1} % </prompt><userinput>make -v</userinput>
879GNU Make version 3.78, by Richard Stallman and Roland McGrath.
880Copyright (C) 1988-1999</literallayout>
881</informalexample>
882</para>
883
884</sect1>
885<sect1 id="nfsmount"><title>Network Mounted File System and Spool Directories</title>
886<warning>
887<para>
888It is strongly recommended that the print spool directories
889and essential printer configuration file files
890should <emphasis/NOT/ be in an NFS mounted file system
891or on a file system which is NFS exported.
892</para>
893</warning>
894<para>
895The
896&LPRng;
897<application/lpd/
898print server makes heavy use of
899file locking to coordinate and synchronize
900process activities.
901Given the historical and ongoing problems of file locking on
902and NFS mounted file system,
903not to mention the high overhead for doing file locking in a
904distributed environment,
905it is strongly recommended that spool directories <emphasis/NOT/
906be on an NFS mounted partition or on a partition that is
907NFS exported.
908</para>
909<para>
910This warning extends to other network file systems as well.
911</para>
912<para>
913In addition,
914the configuration file such as <filename>/etc/printcap</filename>
915must be available or printing will not function.
916Care should be taken to ensure that these files are stable and
917available at all times.
918</para>
919
920</sect1>
921<sect1 id="usergroup"><title>Daemon User and Daemon Group </title>
922
923<para>The <application>lpd</application> server is started at system initialization time and initially runs as ROOT (Effective <acronym>UID</acronym> 0).
924It performs all file and other operations with
925<emphasis/non-privileged/ user <literal>daemon</literal> Effective <acronym/UID/
926and group <literal>daemon</literal> Effective GID,
927and does a <function/setuid()/ to these UID and GID values when
928running programs.
929The client programs such as
930<application>lpr</application>
931operate with the effective user IDs of the user which started them.
932</para>
933<para>
934Most UNIX systems already have
935user <literal>daemon</literal> and group <literal>daemon</literal>,
936or a similar ones.
937If suitable user and group IDs are not present then
938the appropriate system administration tools should be used to create them.
939The configuration
940<literal>--with-userid=UID</literal>
941and
942<literal>--with-groupid=GID</literal>
943can be used to specify the user and group IDs.
944The user ID must <emphasis>not</emphasis>
945have login capability.
946</para>
947
948</sect1>
949
950<sect1><title>Configuration</title>
951
952<para>The &LPRng; package consists of the following executables and configuration files:
953<itemizedlist>
954<listitem>
955<para><application>lpd</application> - the <application/lpd/ print server program</para>
956</listitem>
957<listitem>
958<para><application>lpr</application>,
959<application>lpq</application>,
960<application>lprm</application>,
961<application>lpc</application>,
962and
963<application>lpstat</application>
964client programs for printing,
965status queries, job removal, server configuration,
966and System V <application>lpstat</application> emulation respectively.</para>
967</listitem>
968
969<listitem>
970<para><filename>printcap</filename> print queue database file
971which is used by all the server and client programs</para>
972</listitem>
973
974<listitem>
975<para><filename>lpd.conf</filename> &LPRng; configuration options
976which is used by all the server and client programs</para>
977</listitem>
978
979<listitem>
980<para><filename>lpd.perms</filename> permission information
981which is used by the <application>lpd</application> server to control user actions.</para>
982</listitem>
983
984</itemizedlist>
985</para>
986
987<para>
988&LPRng; uses the <application>configure</application>
989script generated by the
990<ulink URL="http://www.gnu.org">GNU</ulink>
991<application/autoconf/ utility
992to generate a set of <filename>Makefiles</filename>.
993These are used by
994<ulink URL="http://www.gnu.org">GNU</ulink>
995<application>make</application>
996to compile and install the &LPRng; software.
997The following <filename>Makefile</filename>
998variables and values are set by <application>configure</application>
999to specify the location of the &LPRng; software:
1000</para>
1001<informaltable>
1002<tgroup cols=4 align=left>
1003<thead>
1004<row><entry>Configure Variable</entry><entry>Default Value</entry>
1005<entry>Expanded Default Value</entry>
1006<entry>Override</entry> </row>
1007</thead>
1008<tbody>
1009<row><entry><literal>${prefix}</literal></entry><entry><literal>/usr/local</literal></entry><entry><literal>--prefix=PATH</literal></entry></row>
1010<row><entry><literal>${exec_prefix}</literal></entry><entry><literal>${prefix}</literal></entry><entry><literal>/usr/local</literal></entry><entry><literal>--execprefix= PATH</literal></entry></row>
1011<row><entry><literal>${bindir}</literal></entry><entry><literal>${exec_prefix}/bin</literal></entry><entry><literal>/usr/local/bin</literal></entry><entry><literal>--bindir= PATH</literal></entry></row>
1012<row><entry><literal>${sbindir}</literal></entry><entry><literal>${exec_prefix}/sbin</literal></entry><entry><literal>/usr/local/sbin</literal></entry><entry><literal>--sbindir= PATH</literal></entry></row>
1013<row><entry><literal>${libexecdir}</literal></entry><entry><literal>${exec_prefix} /libexec</literal></entry><entry><literal>/usr/local/libexec</literal></entry><entry><literal>--libexecdir= PATH</literal></entry></row>
1014<row><entry><literal>${sysconfdir}</literal></entry><entry><literal>${prefix}/etc</literal></entry><entry><literal>/usr/local/etc</literal></entry><entry><literal>--sysconfdir= PATH</literal></entry></row>
1015<row><entry><literal>${mandir}</literal></entry><entry><literal>${prefix}/man</literal></entry><entry><literal>/usr/local/man</literal></entry><entry><literal>--mandir= PATH</literal></entry></row>
1016</tbody>
1017</tgroup>
1018</informaltable>
1019
1020<para>These are used to install the following files:</para>
1021<informaltable>
1022<tgroup cols=2 align=left>
1023<thead>
1024<row><entry>Configure Variable</entry><entry>Files</entry></row>
1025</thead>
1026<tbody>
1027<row><entry><literal>${bindir}</literal></entry><entry><literal>lpr, lprm, lpq, lpstat</literal></entry></row>
1028<row><entry><literal>${sbindir}</literal></entry><entry><literal>lpc, checkpc, lpd</literal></entry></row>
1029<row><entry><literal>${libexecdir}/filters</literal></entry><entry><literal>lpf, pclbanner, psbanner, lpbanner</literal></entry></row>
1030<row><entry><literal>${sysconfdir}</literal></entry><entry><literal>lpd.conf, lpd.perms, printcap</literal></entry></row>
1031<row><entry><literal>${mandir}/man[1-9]</literal></entry><entry><literal>man pages</literal></entry></row>
1032</tbody>
1033</tgroup>
1034</informaltable>
1035
1036<para>You can set explicit values for the
1037paths by using the override <literal>--name=PATH</literal>.
1038For example:
1039<informalexample>
1040<screen>./configure --prefix=/usr --sysconfdir=/etc \
1041    --mandir=/usr/share/man</screen>
1042</informalexample>
1043</para>
1044<informaltable>
1045<tgroup cols=3 align=left>
1046<thead>
1047<row><entry>Variable</entry><entry>Value</entry><entry>Files</entry></row>
1048</thead>
1049<tbody>
1050<row><entry>${bindir}</entry><entry>/usr/bin</entry><entry>/usr/bin/{lpr,lprm,lpq,lpstat}</entry></row>
1051<row><entry>${sbindir}</entry><entry>/usr/sbin</entry><entry>/usr/sbin/{lpc,checkpc,lpd}</entry></row>
1052<row><entry>${libexecdir}/filters</entry><entry>/usr/libexec/filters</entry><entry>/usr/libexec/filters{lpf, pclbanner, psbanner, lpbanner}</entry></row>
1053<row><entry>${sysconfdir}</entry><entry>/etc</entry><entry>/etc/{lpd.conf,lpd.perms,printcap}</entry></row>
1054<row><entry>${mandir}/man[1-9]</entry><entry>/usr/share/man</entry><entry>/usr/share/man/man[1-9]/{man pages}</entry></row>
1055</tbody>
1056</tgroup>
1057</informaltable>
1058
1059<para>In addition to these standard <application>configure</application>
1060options the following options provided.
1061<variablelist>
1062
1063<varlistentry><term><literal> --disable-setuid </literal></term>
1064
1065<listitem>
1066<para>Install the executables without setuid ROOT permissions.
1067Non-setuid clients and programs are inherently more secure than SETUID programs,
1068and system administrators would be well advised to install them without
1069SETUID root permissions.
1070Please see
1071<link linkend="setuid">Security Considerations</link>
1072for more details about this option.</para>
1073</listitem>
1074</varlistentry>
1075
1076<varlistentry><term><literal> --enable-priv_ports  </literal></term>
1077
1078<listitem>
1079<para>Require connections to the <application>lpd</application> server
1080to come from a privileged port (range 1-1023).
1081By default
1082&LPRng; will allow connections from any port.
1083Please see
1084<link linkend="setuid">Security Considerations</link>
1085
1086for more details about this option.</para>
1087
1088
1089</listitem>
1090</varlistentry>
1091
1092<varlistentry><term><literal>--disable-force_localhost</literal></term>
1093
1094<listitem>
1095<para>The default &LPRng; configuration assumes that all printing will be done
1096via a <application>lpd</application> print spooler running on the local host system.
1097However,
1098many larger sites prefer that all users do their printing via a
1099few central servers,
1100and do not run
1101<application>lpd</application> servers on user systems.
1102The
1103<literal>--disable-force_localhost</literal>
1104configuration sets the default value of the <literal>force_localhost</literal>
1105value to
1106<literal remap=tt>false</literal>,
1107by default allowing the &LPRng; clients to connect directly to <application>lpd</application> servers
1108on remote hosts.</para>
1109
1110
1111</listitem>
1112</varlistentry>
1113
1114<varlistentry><term><literal>--disable-require_configfiles</literal></term>
1115
1116<listitem>
1117<para>By default, the
1118<application>lpr</application>,
1119<application>lpq</application>,
1120<application>lprm</application>,
1121and
1122<application>lpc</application>
1123clients require the <filename>lpd.conf</filename> and <filename>printcap</filename> files
1124to be present on the localhost.
1125The <literal>--disable-require_configfiles</literal> literal removes this requirement.</para>
1126
1127</listitem>
1128</varlistentry>
1129
1130<varlistentry><term><literal>--enable-kerberos</literal></term>
1131
1132<listitem>
1133<para>Include support for Kerberos 5 authenticated transfers.</para>
1134
1135</listitem>
1136</varlistentry>
1137
1138<varlistentry><term><literal>--enable-mit_kerberos4</literal></term>
1139
1140<listitem>
1141<para>Include support for MIT Kerberos 4 authenticated transfers.</para>
1142
1143</listitem>
1144</varlistentry>
1145
1146<varlistentry><term><literal>--disable-kerberos_checks</literal></term>
1147
1148<listitem>
1149<para>Disable checks for kerberos support libraries, etc.</para>
1150
1151</listitem>
1152</varlistentry>
1153
1154<varlistentry><term><literal> --with-lpddir=DIR </literal></term>
1155
1156<listitem>
1157<para>lpd executable directory (default ${sbindir}).
1158For historical configuration compatibility.</para>
1159
1160</listitem>
1161</varlistentry>
1162
1163<varlistentry><term><literal> --with-filterdir=DIR </literal></term>
1164
1165<listitem>
1166<para>Filter directory (default ${libexecdir}/filters).
1167For historical configuration compatibility.</para>
1168
1169</listitem>
1170</varlistentry>
1171
1172<varlistentry><term><literal> --with-lpd_conf_path=PATH </literal></term>
1173
1174<listitem>
1175<para>Path of <filename>lpd.conf</filename> file.
1176For historical configuration compatibility.</para>
1177
1178</listitem>
1179</varlistentry>
1180
1181<varlistentry><term><literal> --with-lpd_perms_path=PATH </literal></term>
1182
1183<listitem>
1184<para>Path of <filename>lpd.perms</filename> file.
1185For historical configuration compatibility.</para>
1186
1187</listitem>
1188</varlistentry>
1189
1190<varlistentry><term><literal> --with-printcap_path=PATH </literal></term>
1191
1192<listitem>
1193<para>Path of <filename>printcap</filename> file.
1194For historical configuration compatibility.</para>
1195
1196</listitem>
1197</varlistentry>
1198
1199<varlistentry><term><literal> --with-ld_library_path=PATHLIST </literal></term>
1200
1201<listitem>
1202<para>Set the LD_LIBRARY_PATH environment variable of filters to this value.</para>
1203
1204</listitem>
1205</varlistentry>
1206
1207<varlistentry><term><literal> --with-filter_path=PATHLIST </literal></term>
1208
1209<listitem>
1210<para>Set the PATH environment variable of filters to this value.</para>
1211
1212</listitem>
1213</varlistentry>
1214
1215<varlistentry><term><literal> --with-userid=NAME</literal></term>
1216
1217<listitem>
1218<para>Run &LPRng; as this user, default daemon</para>
1219
1220</listitem>
1221</varlistentry>
1222
1223<varlistentry><term><literal> --with-groupid=NAME</literal></term>
1224
1225<listitem>
1226<para>Run &LPRng; as this group, default daemon</para>
1227
1228</listitem>
1229</varlistentry>
1230
1231<varlistentry><term><literal> --with-lockfile=PATH </literal></term>
1232
1233<listitem>
1234<para>The lockfile path.  This will be expanded to PATH.server or PATH.port
1235allowing multiple &LPRng; servers to run on a single host.</para>
1236
1237</listitem>
1238</varlistentry>
1239
1240<varlistentry><term><literal> --with-filterdir=PATH </literal></term>
1241
1242<listitem>
1243<para>Location of the filters installed by &LPRng;.</para>
1244
1245
1246</listitem>
1247</varlistentry>
1248
1249<varlistentry><term><literal> --with-done_jobs=N </literal></term>
1250
1251<listitem>
1252<para>retain status of last N done jobs.</para>
1253
1254
1255</listitem>
1256</varlistentry>
1257
1258<varlistentry><term><literal> --with-done_jobs_max_age=N </literal></term>
1259
1260<listitem>
1261<para>remove status of done jobs older than N seconds.</para>
1262
1263
1264</listitem>
1265</varlistentry>
1266
1267<varlistentry><term><literal>--with-chooser_routine=NAME </literal></term>
1268<listitem>
1269<para>name of chooser routine provided by user</para>
1270</listitem>
1271</varlistentry>
1272
1273<varlistentry><term><literal>--with-order_routine=NAME </literal></term>
1274
1275<listitem>
1276<para>name of order routine provided by user</para>
1277
1278</listitem>
1279</varlistentry>
1280
1281<varlistentry><term><literal>--with-user_objs=NAME </literal></term>
1282
1283<listitem>
1284<para>object file with routines provided by user</para>
1285
1286</listitem>
1287</varlistentry>
1288
1289<varlistentry><term><literal>--with-user_include=NAME </literal></term>
1290
1291<listitem>
1292<para>include file with templates for routines provided by user</para>
1293
1294
1295</listitem>
1296</varlistentry>
1297
1298<varlistentry><term><literal> --disable-strip </literal></term>
1299
1300<listitem>
1301<para>Do not strip the executables before installing.
1302For debugging and diagnostic purposes.</para>
1303
1304</listitem>
1305</varlistentry>
1306
1307<varlistentry><term><literal>--with-unixsocketpath=PATHNAME</literal></term>
1308<listitem>
1309<para>the pathname of the UNIX socket (off or blank to disable)</para>
1310</listitem>
1311</varlistentry>
1312
1313<varlistentry><term><literal>--disable-ssl</literal></term>
1314<listitem>
1315<para>disable ssl support</para>
1316</listitem>
1317</varlistentry>
1318
1319<varlistentry><term><literal>--with-openssl=DIR</literal></term>
1320<listitem>
1321<para>root location for OpenSSL</para>
1322</listitem>
1323</varlistentry>
1324
1325<varlistentry><term><literal>--with-openssl-inc</literal></term>
1326<listitem>
1327<para>OpenSSL include files</para>
1328</listitem>
1329</varlistentry>
1330
1331<varlistentry><term><literal>--with-openssl-lib</literal></term>
1332<listitem>
1333<para>OpenSSL library files</para>
1334</listitem>
1335</varlistentry>
1336
1337<varlistentry><term><literal>--with-ssl_ca_file=FILE</literal></term>
1338<listitem>
1339<para>ssl Certificate Authority CERT file (default ${sysconfdir}/lpd/ssl.ca/ca.crt)</para>
1340</listitem>
1341</varlistentry>
1342
1343<varlistentry><term><literal>--with-ssl_ca_key=KEY</literal></term>
1344<listitem>
1345<para>ssl Certificate Authority private key file (default ${sysconfdir}/lpd/ssl.ca/ca.key)</para>
1346</listitem>
1347</varlistentry>
1348
1349<varlistentry><term><literal>--with-ssl_certs_dir=DIR</literal></term>
1350<listitem>
1351<para>ssl Certificate Authority certs working directory (default ${sysconfdir}/lpd/ssl.certs/)</para>
1352</listitem>
1353</varlistentry>
1354
1355<varlistentry><term><literal>--with-ssl_server_cert=FILE</literal></term>
1356<listitem>
1357<para>ssl server certificate file (default ${sysconfdir}/lpd/ssl.server/server.crt)</para>
1358</listitem>
1359</varlistentry>
1360
1361<varlistentry><term><literal>--with-ssl_server_password_file=FILE</literal></term>
1362<listitem>
1363<para>ssl server private key in password file (default ${sysconfdir}/lpd/ssl.server/server.pwd)</para>
1364</listitem>
1365</varlistentry>
1366
1367
1368</variablelist>
1369</para>
1370
1371<para>It is recommended that you use one of the following
1372configurations:
1373<orderedlist>
1374
1375<listitem>
1376<para>If you already have a print spooling system installed and
1377want to install &LPRng; for testing purposes or as an alternative
1378to the existing system and keep your existing print spooling system, use:
1379<informalexample>
1380<screen>./configure
1381
1382use defaults for file locations and permissions:
1383  /usr/local/{bin,sbin,libexec/filters,man}
1384requires lpd to run on the local host
1385executables installed setuid ROOT</screen>
1386</informalexample>
1387</para>
1388</listitem>
1389
1390<listitem>
1391<para>If you have manual pages in <filename>/usr/share/man</filename>,
1392your existing print spooling system has executables in
1393<filename>/usr/bin</filename> and <filename>/usr/sbin</filename>,
1394and you want to replace your existing print spooling system, use:
1395<informalexample>
1396<screen>./configure --prefix=/usr --sysconfdir=/etc \
1397  --mandir=/usr/share/man
1398
1399executables and files in
1400   /usr/{bin,sbin,libexec/filters}
1401   /usr/share/man/man[0-9]
1402requires lpd to run on the local host
1403everything installed setuid ROOT</screen>
1404</informalexample>
1405</para>
1406</listitem>
1407
1408<listitem>
1409<para>If you have manual pages in <filename>/usr/share/man</filename>
1410and allow jobs (by default) to be sent directly to the server host
1411(lightweight operation), use:
1412<informalexample>
1413<screen>./configure --prefix=/usr --sysconfdir=/etc \
1414   --mandir=/usr/share/man --disable-force_localhost
1415
1416executables and files in
1417   /usr/{bin,sbin,libexec/filters}
1418   /usr/share/man/man[0-9]
1419does not require lpd to run on the local host
1420everything installed setuid ROOT</screen>
1421</informalexample>
1422</para>
1423</listitem>
1424
1425</orderedlist>
1426</para>
1427
1428</sect1>
1429
1430<sect1 id="requireconfig"><title>System and User Printcap, lpd.conf, and lpd.perms files </title>
1431
1432<para>The
1433system <filename>printcap</filename> file contains the
1434definitions of the print queues used by &LPRng;,
1435and is located in the directory specified by the
1436configuration
1437<literal>${sysconfdir}</literal>
1438value.
1439For a complete description of the <filename>printcap</filename> file see
1440<link linkend="printcapref">Printcap Database</link>.
1441If your system does not have an existing <filename>printcap</filename> file
1442then a <emphasis>dummy</emphasis>
1443file similar to the following is
1444installed by default:
1445<informalexample>
1446<screen># dummy printcap file
1447lp:cm=Dummy Printcap Entry:
1448 :lp=/dev/null
1449 :sd=/var/spool/lpd/%P</screen>
1450</informalexample>
1451</para>
1452
1453<para>
1454In addition to the system <filename/printcap/ file,
1455each user can have a <literal>${HOME}/.printcap</literal>
1456which contains printcap entries as well.
1457The the user <filename/printcap/ file is in effect appended to the
1458system printcap file, and values in the user printcap file override the
1459system printcap file.
1460However,
1461in order to allow users to specify a default printer
1462after reading the printcap file information the entries are
1463sorted so that printcap entries defined by users come first.
1464</para>
1465
1466<para>The <filename>lpd.conf</filename>
1467is located in the
1468<literal>${sysconfdir}</literal>
1469directory
1470and provides configuration settings for both the &LPRng; client and server
1471programs.
1472For a complete description of the <filename>lpd.conf</filename> file see
1473<link linkend="configfile">
1474Configuration File, Defaults and Overrides</link>.
1475During installation the
1476<filename>${sysconfdir}/lpd.conf.template</filename>
1477is created with the default &LPRng; information
1478and if there is not an existing <filename>${sysconfdir}/lpd.conf</filename> file
1479is copied to it.
1480</para>
1481
1482<para>The <filename>lpd.perms</filename>
1483is located in the
1484<literal remap=tt>${sysconfdir}</literal>
1485directory
1486and is only by <application>lpd</application> to determine user permissions
1487for printing activities.
1488For a complete description of the <filename>lpd.perms</filename> file see
1489<link linkend="permsref">
1490Permissions and Authentication
1491</link> for details.
1492During installation the
1493<filename>lpd.perms.template</filename> file
1494is installed in the
1495<filename>${sysconfdir}/lpd.perms.template</filename>
1496and if there is not an existing <filename>lpd.perms</filename> file
1497is copied to it.
1498</para>
1499
1500<para>By default,
1501the &LPRng; client programs
1502<application>lpr</application>,
1503<application>lpq</application>,
1504<application>lprm</application>,
1505and
1506<application>lprc</application>
1507will require a <filename>lpd.conf</filename> and <filename>printcap</filename>
1508file to be installed on the local host.
1509You can relax this requirement by setting
1510using the
1511<literal>--disable-require_configfile</literal>
1512configuration option.
1513You can also create empty files to satisfy the program requirements.</para>
1514</sect1>
1515
1516<sect1><title>Checking System Installation with <application>checkpc</application></title>
1517<para>The
1518<application>checkpc</application>
1519program is used to make sure that
1520the spool directories and files used by &LPRng; have the correct permissions
1521and are in place.
1522By default,
1523<application>checkpc</application> will check permissions and report if there are any problems.
1524You should run this as
1525<literal remap=tt>root</literal>.
1526For example:
1527<informalexample>
1528<screen><prompt>h4: {2} # </prompt><userinput>checkpc</userinput>
1529Warning - No configuration file '/etc/lpd.conf'
1530Warning - No lpd only printcap file found in '/etc/lpd_printcap'
1531Warning -  ** cannot open '/var/run/lpd.printer' - 'Permission denied'
1532Warning -  bad directory - /var/spool/lpd/lp
1533Warning -   Printer 'lp' spool dir '/var/spool/lpd/lp' needs fixing</screen>
1534</informalexample>
1535</para>
1536
1537<para>In the above example,
1538<application>checkpc</application> has discovered that the <filename>lpd.conf</filename>
1539file is missing.
1540This is a serious problem and indicates that the
1541software may be incorrectly installed.
1542</para>
1543
1544<para>The <literal/lpd only printcap/
1545message is usually of concern to administrators who wish to use some of
1546&LPRng;'s more exotic configuration options.
1547It is possible to have separate <filename/printcap/
1548files for client and server programs.
1549This is useful when <filename/printcap/ files get extremely large and cuts down
1550substantially on system management problems.</para>
1551
1552<para>The <literal/permission denied/ message for <filename>/var/run/lpd.printer</filename> is serious,
1553as the <application/lpd/ server uses this as a lock file.</para>
1554
1555<para>The <literal/bad directory/
1556message about the spool directory is usually caused by
1557wrong permissions or a missing directory.</para>
1558
1559<para>The <command>checkpc -f</command> (fix) option causes <application>checkpc</application> to take action to rectify errors.
1560The <command>checkpc -f -V</command> (verbose) option causes the fixup activity to be displayed a well:
1561<informalexample>
1562<screen><prompt>h4: {3} # </prompt><userinput>checkpc -f -V</userinput>
1563Checking for configuration files '/etc/lpd.conf'
1564  found '/usr/local/etc/lpd.conf', mod 0100644
1565Checking for printcap files '/etc/printcap'
1566  found '/usr/local/etc/printcap', mod 0100644
1567Checking for lpd only printcap files '/etc/lpd_printcap'
1568 DaemonUID 1, DaemonGID 1
1569Using Config file '/etc/lpd.conf'
1570LPD lockfile '/var/run/lpd.printer'
1571 Checking directory: '/var/run'
1572   directory '/var'
1573   directory '/var/run'
1574  checking '/var/run/lpd.printer' file
1575
1576Checking printer 'lp'
1577 Checking directory: '/var/spool/lp'
1578   directory '/var'
1579   directory '/var/spool'
1580   directory '/var/spool/lp'
1581  file 'control.lp', zero length file unchanged in 1 hours
1582  file 'status.lp', zero length file unchanged in 1 hours
1583  file 'status', zero length file unchanged in 1 hours
1584  file 'log', zero length file unchanged in 1 hours
1585  file 'acct', zero length file unchanged in 1 hours
1586  checking 'control.lp' file
1587  checking 'status.lp' file
1588  checking 'status' file
1589  cleaning 'status' file, 0K bytes: no truncation
1590  checking 'log' file
1591  cleaning 'log' file, 0K bytes: no truncation
1592  checking 'acct' file
1593  cleaning 'acct' file, 0K bytes: no truncation</screen>
1594</informalexample>
1595</para>
1596<para><application>checkpc</application> will create the spool directories
1597and any missing files, and fix the permissions of existing files.
1598</para>
1599</sect1>
1600
1601<sect1><title>Compilation and Install</title>
1602
1603<para>Once you have decided on the configuration you want and
1604understand what files need to be installed,
1605then you are ready  to do the install.
1606It is extremely simple to
1607extract the files,
1608configure, compile and install the software:
1609<informalexample>
1610<screen><prompt>h4: {4} % </prompt><userinput>gunzip -c LPRng-&lt;version&gt;.tgz | tar xvf -</userinput>
1611<prompt>h4: {5} % </prompt><userinput>cd LPRng-&lt;version&gt;</userinput>
1612<prompt>h4: {6} % </prompt><userinput>./configure  [ ... configuration options ]</userinput>
1613<prompt>h4: {7} % </prompt><userinput>make clean all</userinput>
1614<prompt>h4: {8} % </prompt><userinput>su   # you must do the following commands as root</userinput>
1615<prompt>h4: {9} # </prompt><userinput>make install</userinput>
1616<prompt>h4: {10} # </prompt><userinput># if checkpc did not run, do the next command</userinput>
1617<prompt>h4: {11} # </prompt><userinput># make sure checkpc and lpq are in your paths</userinput>
1618<prompt>h4: {12} # </prompt><userinput># if using CSH, use 'rehash' as well</userinput>
1619<prompt>h4: {13} # </prompt><userinput>checkpc -f</userinput>
1620<prompt>h4: {14} # </prompt><userinput># check to see if the server is running</userinput>
1621<prompt>h4: {15} # </prompt><userinput>lpq</userinput>
1622</screen>
1623</informalexample>
1624</para>
1625<para>
1626During installation you may get an error
1627message indicating that the <application/lpd/ file could
1628not be installed or the <application/lpd/ server could not be
1629started.
1630If this is the case,
1631then carry out the appropriate steps in
1632<link linkend=update>
1633Updating Print Spooler Software and Startup Scripts
1634</link>
1635to remove the existing print spooling software and then
1636try to reinstall &LPRng;.
1637You should also to check the
1638<link linkend=systemspecific>
1639System Specific Notes
1640</link>
1641section for any system specific installation requirements.
1642</para>
1643<para>
1644While the &LPRng; installation scripts try hard to set up the
1645<application/lpd/ server in place,
1646you will still need to reboot your host and make sure that the
1647various printing facilities are working correctly after reboot.
1648</para>
1649</sect1>
1650
1651<sect1><title>Installation Problems</title>
1652<para>Read the notes for your OS in section
1653<link linkend="systemspecific">System-dependent notes</link>
1654for specific installation help (if any).</para>
1655
1656<para>The following is a list of commonly encountered problems
1657and their solution.
1658If these do not solve your problem,
1659then send mail to the 
1660<link linkend="maillist">lprng@lprng.com</link>
1661mailing list.
1662You will have to subscribe to the list in order to post to the list.
1663<orderedlist>
1664
1665<listitem>
1666<para>
1667<application>Make</application>
1668complains about a malformed <filename>make</filename> or
1669<filename>Makefile</filename> file,
1670illegal syntax in the file,
1671or illegal entries in the file.
1672You are most likely not running GNU Make.
1673You <emphasis>must</emphasis>
1674use GNU <application>make</application>
1675or you should be a Unix Wizard able to master
1676the mysteries of converting GNU Makefiles to your local system
1677<application>make</application>.
1678It is easier to simply install GNU <application>make</application>.</para>
1679</listitem>
1680
1681<listitem>
1682<para>The C Compiler complains about missing files or has a large number of
1683errors.
1684Use
1685<application>gcc</application>
1686instead of your vendor's C compiler.
1687<informalexample>
1688<screen>configure --with-cc=gcc</screen>
1689</informalexample>
1690</para>
1691<para>
1692If there are messages about missing system files,
1693then you most likely have an incomplete set of system
1694<filename>include</filename> files,
1695or the <filename>include</filename> do not properly reference other
1696required include files,
1697or the include files are located in an <emphasis>unusual</emphasis>
1698location.
1699If you are using <application>gcc</application>
1700then make sure that the <application>gcc</application> was carried out
1701correctly on your system.
1702The easiest way to assure this is to recompile and reinstall the
1703<application>gcc</application> compiler.
1704</para>
1705</listitem>
1706
1707<listitem>
1708<para>If you have checked your compiler installation and are still
1709missing libraries or files
1710then the <filename>include</filename> files may be in
1711<filename>/usr/local/include</filename>
1712and libraries may be in
1713<filename>/usr/local/include</filename>
1714and these directories may not searched or used by the compiler
1715by default.
1716This can be fixed by using the
1717<literal>--with-cppopts=</literal>
1718and
1719<literal>--with-ldopts=</literal>
1720configure options.
1721<informalexample>
1722<screen>configure \
1723  --with-cppopts="-I/usr/local/include -I/usr/include/kerberosIV" \
1724  --with-ldopts="-L/usr/local/lib -L/usr/lib/kerberosIV"</screen>
1725</informalexample>
1726</para>
1727</listitem>
1728<listitem>
1729<para>
1730The software compiles
1731but will not run on the system.
1732Make sure that you have followed your system specific
1733rules for compiling and installing <literal>setuid ROOT</literal>
1734programs on your system.  You may need to statically link your
1735executables.
1736</para>
1737</listitem>
1738<listitem>
1739<para>
1740The software was compiled on one system and copied to another
1741system,
1742but will not run on the other system.
1743Try compiling the software on the target system.
1744If it compiles and runs,
1745then you most likely have an issue with libraries
1746or Operating System Versions.
1747</para>
1748</listitem>
1749</orderedlist>
1750</para>
1751<para>
1752After you have installed the
1753LPRng software
1754and rebooted your system,
1755do the following commands:
1756<informalexample>
1757<screen><prompt>h4: {16} # </prompt><userinput>lpq</userinput>
1758Printer: lp@astart
1759 Queue: no printable jobs in queue</screen>
1760</informalexample>
1761</para>
1762<para>
1763If you do not get status displayed,
1764or you get some other error message,
1765then the following are a series of tests can use to check that
1766&LPRng; is installed correctly.
1767</para>
1768<para>First we will run <application>lpd</application> in the
1769<emphasis>foreground</emphasis>
1770and are used to make sure that our system configuration is
1771correct.
1772You will need <literal>root</literal> permissions to do
1773the following steps.
1774Stop the running currently running <application>lpd</application> process.
1775Next,
1776run <application>lpd</application> in foreground mode:
1777<informalexample>
1778<screen><prompt>h4: {17} # </prompt><userinput>ps -aux | grep lpd </userinput>
1779daemon   240  0.0  0.0  1292  0  ??  IWs  -     0:00.00 lpd: lpd Waiting
1780<prompt>h4: {18} # </prompt><userinput>kill 240</userinput>
1781<prompt>h4: {19} # </prompt><userinput>checkpc -f</userinput>
1782<prompt>h4: {20} # </prompt><userinput>/usr/local/bin/lpd -F -D1</userinput>
1783Fatal error - Another print spooler is using TCP printer port</screen>
1784</informalexample>
1785</para>
1786
1787<para>If you get the above error message,
1788then you have either not terminated the running
1789<application>lpd</application> server,
1790there is another process using TCP/IP port 515,
1791or you are not starting the <application>lpd</application> server as ROOT.
1792See the 
1793<link linkend=systemspecific>
1794System Specific Notes
1795</link>
1796for details on how to resolve these issues.
1797</para>
1798<para>
1799Correct the problem and then restart the server.
1800You should see the output indicated below:
1801<informalexample>
1802<screen><prompt>h4: {21} # </prompt><userinput>/usr/local/bin/lpd -F -D1</userinput>
18031999-04-05-14:35:14.023 astart27 [2667] Waiting  lpd: LOOP START
18041999-04-05-14:35:14.024 astart27 [2667] Waiting  Get_max_servers: \
1805   getrlimit returns 256
18061999-04-05-14:35:14.024 astart27 [2667] Waiting  Get_max_servers: \
1807   returning 128
18081999-04-05-14:35:14.025 astart27 [2667] Waiting  lpd: \
1809   max_servers 128, active 0
18101999-04-05-14:35:14.025 astart27 [2667] Waiting  lpd: \
1811   starting select timeout 'yes', 600 sec</screen>
1812</informalexample>
1813</para>
1814
1815<para>Now from another window do the following commands:
1816<informalexample>
1817<screen><prompt>h4: {22} # </prompt><userinput>lpq</userinput>
1818Printer: lp@astart
1819 Queue: no printable jobs in queue</screen>
1820</informalexample>
1821</para>
1822
1823<para>At this point your &LPRng; software has been installed and tested.
1824See the
1825<link linkend=update>
1826Updating Print Spooler Software and Startup Scripts
1827</link>
1828for details on how
1829to automatically start <application/lpd/ at boot time.
1830</para>
1831
1832</sect1>
1833
1834
1835<sect1 id=update><title>Updating Print Spooler Software and Startup Scripts</title>
1836<para>If you are replacing your
1837existing print spooling spooling system,
1838you must shut down and remove the existing print spooler
1839software before installing the &LPRng; software.
1840This process is fairly system dependent,
1841and requires a small amount of system expertise.
1842</para>
1843
1844<para>
1845To assist in this process the &LPRng; installation
1846has a set of
1847<literal>preinstall</literal>,
1848<literal>postinstall</literal>,
1849<literal>preremove</literal>,
1850and
1851<literal>postremove</literal>
1852scripts in the distribution that may be suitable for your local
1853system use.
1854If these fail to work during the system installation,
1855you will need to carry out the steps described here by hand.
1856</para>
1857<sect2><title>SunOS, Linux, and BSD Derived Systems</title>
1858
1859<para>The
1860<literal/SunOS/,
1861<literal/Linux/,
1862and
1863<literal/BSD/ derived systems such as
1864<literal/BSDi/,
1865<literal/FreeBSD/,
1866<literal/OpenBSD/,
1867and others use a version of the <emphasis/legacy/
1868or <emphasis/vintage/
1869<application>lpd</application> print server and the
1870<application/lpr/,
1871<application/lprm/,
1872<application/lpq/,
1873and
1874<application/lpc/ client programs.
1875By convention,
1876most of the printing related programs are in the
1877<filename>/usr/bin</filename>,
1878<filename>/usr/sbin</filename>,
1879<filename>/usr/libexec</filename>,
1880and
1881<filename>/usr/ucb</filename> directories.</para>
1882
1883<para>The <application/lpd/ print spooler is started by
1884either the <command>rc</command> startup script
1885or by a <emphasis>startup script</emphasis>
1886file in the
1887<filename>/etc/rc.d/init.d</filename>
1888or
1889<filename>/etc/init.d</filename> directory.
1890You can first locate the startup commands as follows.
1891<orderedlist>
1892
1893<listitem>
1894<para>Use the
1895<citerefentry/<refentrytitle/find/<manvolnum/1//
1896utility to search the <filename>/etc</filename>
1897directory for the file that contains the startup command.
1898<informalexample>
1899<screen><prompt>h4: {23} # </prompt><userinput>cd /etc</userinput>
1900<prompt>h4: {24} # </prompt><userinput>find . -type f -exec grep -l lpd {} \; -print</userinput>
1901./rc.local</screen>
1902</informalexample>
1903</para>
1904</listitem>
1905
1906<listitem>
1907<para>Examine each of the files found find the one
1908that starts the <application>lpd</application> print spooler.
1909You can simply comment out the command or change it
1910to start the &LPRng; <application/lpd/ print server.
1911<informalexample>
1912<screen><prompt>h4: {25} # </prompt><userinput>more /etc/rc.local</userinput>
1913if [ -f /etc/printcap  -a -f /usr/libexec/lpd ] ; then
1914  /usr/libexec/lpd ;
1915fi
1916
1917--- change this to
1918if [ -f /etc/printcap  -a -f /usr/sbin/lpd ] ; then
1919  /usr/sbin/lpd ;
1920fi</screen>
1921</informalexample>
1922</para>
1923</listitem>
1924
1925<listitem>
1926<para>If you have an existing <filename>printcap</filename> file,
1927then you should either copy this to the location used by &LPRng;
1928or make a symbolic link to it.</para>
1929</listitem>
1930
1931</orderedlist>
1932</para>
1933
1934<para>Next we kill the currently running <application>lpd</application> process.
1935<informalexample>
1936<screen><prompt>h4: {26} # </prompt><userinput>ps -auxw |grep lpd</userinput>
1937papowell 23932  0.0  0.3  224  184  p3  S+  10:40AM  0:00.01 grep lpd
1938daemon  17763  0.0  0.2  448  120  ??  IWs  29Mar99  0:01.35 (lpd)
1939<prompt>h4: {27} % </prompt><userinput>kill 135</userinput>
1940<prompt>h4: {28} % </prompt><userinput>kill 135</userinput>
1941135: No such process</screen>
1942</informalexample>
1943</para>
1944
1945<para>Next,
1946you should remove or rename the existing print system executables.
1947The following example shows how to use the
1948<application>find</application> utility to track down candidates.
1949<informalexample>
1950<screen><prompt>h4: {29} # </prompt><userinput>find /usr -type f -name lp\*  -print &gt;/tmp/candidates</userinput>
1951<prompt>h4: {30} # </prompt><userinput>find /sbin -type f -name lp\*  -print &gt;&gt;/tmp/candidates</userinput>
1952<prompt>h4: {31} # </prompt><userinput>cat /tmp/candidates</userinput>
1953/usr/bin/lpunlock
1954/usr/bin/lpqall.faces
1955/usr/bin/lpq             &lt;---- old
1956/usr/bin/lpr             &lt;---- old
1957/usr/bin/lprm            &lt;---- old
1958/usr/bin/lptest
1959/usr/doc/samba-1.9.18p10/examples/printer-accounting/lp-acct
1960/usr/man/man1/lpq.1
1961/usr/man/man1/lpr.1
1962/usr/man/man1/lprm.1
1963/usr/man/man1/lptest.1
1964/usr/man/man4/lp.4
1965/usr/man/man8/lpc.8
1966/usr/man/man8/lpd.8
1967/usr/sbin/lpc            &lt;--- old
1968/usr/sbin/lpd            &lt;--- old
1969/usr/sbin/lpf            &lt;--- old
1970<prompt>h4: {32} # </prompt><userinput>mv /usr/bin/lpq  /usr/bin/lpq.old</userinput>
1971<prompt>h4: {33} # </prompt><userinput>mv /usr/bin/lpr  /usr/bin/lpr.old</userinput>
1972<prompt>h4: {34} # </prompt><userinput>mv /usr/bin/lprm /usr/bin/lprm.old</userinput>
1973<prompt>h4: {35} # </prompt><userinput>mv /usr/sbin/lpc /usr/sbin/lpc.old</userinput>
1974<prompt>h4: {36} # </prompt><userinput>mv /usr/sbin/lpd /usr/sbin/lpd.old</userinput>
1975<prompt>h4: {37} # </prompt><userinput>mv /usr/sbin/lpf /usr/sbin/lpf.old</userinput>
1976</screen>
1977</informalexample>
1978</para>
1979
1980<para>After all this,
1981you should now run <command>checkpc -f</command>
1982(as root) to make sure that the &LPRng; configuration is present and
1983correctly set up,
1984and then start <application>lpd</application> by hand.
1985You should try to use <application>lpq</application> to see if the spool queues are present
1986and set up correctly and the system is functional.</para>
1987
1988<para>
1989<informalexample>
1990<screen><prompt>h4: {38} #</prompt> <userinput>checkpc -f</userinput>
1991<prompt>h4: {39} #</prompt> <userinput>lpd</userinput>
1992<prompt>h4: {40} #</prompt> <userinput>lpq</userinput>
1993Printer: lw4@h2  'Hp : LaserWriter'
1994 Queue: no printable jobs in queue
1995 Status: job 'root@h2+884' removed at 11:27:25.864
1996 Filter_status: done at 11:27:25.766
1997<prompt>h4: {41} #</prompt> <userinput>lpr /etc/motd</userinput>
1998<prompt>h4: {42} #</prompt> <userinput>lpq</userinput>
1999Printer: lw4@h2  'Hp : LaserWriter'
2000 Queue: no printable jobs in queue
2001 Status: job 'root@h2+888' removed at 11:27:25.864
2002 Filter_status: done at 11:33:17.020</screen>
2003</informalexample>
2004</para>
2005
2006<para>Finally,
2007you should reboot your machine and make sure that the <application>lpd</application>
2008print server starts correctly.</para>
2009
2010</sect2>
2011
2012<sect2 id="solarisinstall"><title>Solaris, HP-UX, and other SysVR4 Derived Systems </title>
2013
2014<para>The original SysVR4 (System V, Release 4)
2015software did not have
2016any support for RFC1179 network printing (Berkeley <application/lpd/).
2017Support for this was added in a wide variety of different ways.
2018There are a wide range of different ways that this was done,
2019but most are based on the following system or process structure.</para>
2020
2021<para>The
2022<literal remap=tt>lpsched</literal>
2023process (<filename>/usr/lib/lp/lpsched/</filename>)
2024process performs many of the functions of the &LPRng; and BSD
2025<application>lpd</application>
2026server.
2027This process is responsible for overseeing job printing
2028and starting processes for handling the print queues on the local host.
2029This process must be shut down and the running print spooling
2030servers terminated before &LPRng; can be correctly installed.
2031While
2032there is no simple
2033and reliable method of shutting down a running
2034<literal remap=tt>lpsched</literal>
2035process and the associated network services,
2036it is simple to <emphasis>prevent</emphasis>
2037the process from being started.</para>
2038
2039<para>The <filename>preinstall.solaris</filename>
2040script is a file in the &LPRng; distribution
2041that contains most of the commands needed to
2042remove the Solaris System V printing software.
2043These are explained in detail in the sections below.
2044The procedures outlined below can be used on other SystemVR4
2045systems.
2046<informalexample>
2047<screen>#!/bin/sh
2048# This is an effort to automate the setup
2049#  needed to install the &LPRng; software on the
2050#  Solaris OS.  This is effectively a one way path.
2051#  You are warned.
2052PATH=/etc:/usr/etc:/usr/bin:/bin:/sbin:/usr/sbin:$PATH
2053# remove the init.d entry and links
2054for i in /etc/rc*.d/*lp ; do
2055    b=`basename $i`;
2056    d=`dirname $i`;
2057    mv $i $d/UNUSED.$b.UNUSED
2058done
2059# rename files
2060renameit () {
2061    for i in $* ; do
2062        if [ -f $i -a '!' -f $i.old ] ; then
2063            echo "renaming $i $i.old";
2064            mv $i $i.old
2065        fi
2066    done
2067}
2068renameit /usr/bin/lp /usr/bin/lpstat /usr/sbin/lpadmin \
2069  /usr/sbin/lpfilter /usr/sbin/lpforms /usr/sbin/lpmove \
2070  /usr/sbin/lpshut /usr/sbin/lpsystem /usr/sbin/lpusers \
2071  /usr/ucb/lpc /usr/ucb/lpq /usr/ucb/lpr /usr/ucb/lprm \
2072  /usr/ucb/lptest /usr/lib/lp/lpsched /usr/lib/lp/lpNet
2073# remove the cron entry
2074if [ -f /var/spool/cron/crontabs/lp ] ; then
2075    mv /var/spool/cron/crontabs/lp \
2076       /var/spool/cron/UNUSED.crontabs.lp
2077fi
2078# comment out inetd.conf entry
2079if egrep '^printer' /etc/inetd.conf &gt;/dev/null 2&gt;&amp; ; then
2080    mv /etc/inetd.conf /etc/inetd.conf.bak
2081    sed -e 's/^printer/# printer/' &lt;/etc/inetd.conf.bak \
2082       &gt;/etc/inetd.conf
2083fi
2084# remove the nlsadmin entry
2085nlsadmin -r lpd tcp
2086nlsadmin -r lp tcp
2087echo REBOOT SYSTEM and then install LPRng</screen>
2088</informalexample>
2089</para>
2090
2091<para>First,
2092you will need to remove the <filename>/etc/rc</filename> startup files in the <filename>/etc/rc*.d</filename>
2093directories that start the
2094<literal remap=tt>lpsched</literal>
2095process;
2096see the
2097<literal remap=tt>init</literal>
2098program man page for details.
2099You can find these files by using:
2100<informalexample>
2101<screen><prompt>h4: {43} # </prompt><userinput>cd /</userinput>
2102<prompt>h4: {44} # </prompt><userinput>find . -type f -exec grep -l lpsched {} \; -print &gt;/tmp/files</userinput>
2103<prompt>h4: {45} # </prompt><userinput>cat /tmp/files</userinput>
2104/etc/rc0.d/K20lp
2105/etc/rc2.d/K20lp
2106/etc/rc2.d/S80lp
2107/etc/init.d/lp
2108<prompt>h4: {46} # </prompt><userinput>ls -l ` cat /tmp/files `</userinput>
2109lrwxrwxr-x 1 root bin 1 Dec 29 23:39 /etc/rc0.d/K20lp -&gt; ../../init.d/lp
2110lrwxrwxr-x 1 root bin 1 Dec 29 23:39 /etc/rc2.d/K20lp -&gt; ../../init.d/lp
2111lrwxrwxr-x 1 root bin 1 Dec 29 23:39 /etc/rc2.d/S80lp -&gt; ../../init.d/lp
2112-rwxr--r-- 5 root sys 460 Sep 1 1998 /etc/rcS.d/K39lp</screen>
2113</informalexample>
2114</para>
2115
2116<para>You can remove these files,
2117or simply comment out all of the executable commands in the
2118<filename>/etc/init.d/lp</filename> file.
2119Next,
2120find all of the printing related commands and rename them.
2121For example:
2122<informalexample>
2123<screen><prompt>h4: {47} # </prompt><userinput>find /usr -type f -name lp\* -print &gt;/etc/printingfiles</userinput>
2124<prompt>h4: {48} # </prompt><userinput>cat /tmp/printingfiles</userinput>
2125/usr/bin/lp
2126/usr/bin/lpstat
2127/usr/lib/lp/bin/lp.cat
2128/usr/lib/lp/bin/lp.set
2129/usr/lib/lp/bin/lp.tell
2130/usr/lib/lp/lpNet
2131/usr/lib/lp/lpsched
2132/usr/lib/lp/lpdata
2133/usr/sbin/lpadmin
2134/usr/sbin/lpfilter
2135/usr/sbin/lpforms
2136/usr/sbin/lpmove
2137/usr/sbin/lpshut
2138/usr/sbin/lpsystem
2139/usr/sbin/lpusers
2140/usr/ucb/lpc
2141/usr/ucb/lpq
2142/usr/ucb/lpr
2143/usr/ucb/lprm
2144/usr/ucb/lptest
2145<prompt>h4: {49} # </prompt><userinput>vi /tmp/printingfiles  # remove ones you want to save</userinput>
2146<prompt>h4: {50} # </prompt><userinput>for i in ` cat /tmp/printingfiles ` ; do</userinput>
2147<prompt>&gt;</prompt> <userinput>  if [ -f $i -a '!' -f $i.old ] ; then  mv $i $i.old ; fi;</userinput>
2148<prompt>&gt;</prompt> <userinput>done</userinput></screen>
2149</informalexample>
2150</para>
2151
2152<para>On some systems there may be a <command>cron</command>
2153file
2154<filename>/var/spool/cron/crontabs/lp</filename>
2155which is used to to periodically update and roll over error logs.
2156You may want to remove this file or comment out its contents.</para>
2157
2158<para>Check the <filename>/etc/inetd.conf</filename> file for a line like the one below
2159and comment it out.
2160This line is not present on all systems.
2161<informalexample>
2162<screen>printer stream tcp nowait root /usr/lib/print/in.lpd in.lpd</screen>
2163</informalexample>
2164</para>
2165
2166<para>Use
2167<command remap=tt>nlsadmin</command>
2168to force the
2169<literal>TCP/IP listener</literal>
2170to release the port, as illustrated below.
2171This may not be present on all system.
2172<informalexample>
2173<screen><prompt>h4: {51} # </prompt><userinput>nlsadmin -v tcp</userinput>
2174lpd  \x00020203000000000000000000000000  ENABLED  \
2175  NORPC  root  NOMODULES  /var/spool/lp/fifos/listenBSD  #
21760  \x00020ACE000000000000000000000000  ENABLED    \
2177  NORPC  root  NOMODULES  /usr/lib/saf/nlps_server  #
2178lp  NOADDR  ENABLED  NORPC  root  NOMODULES \
2179  /var/spool/lp/fifos/listenS5  #
2180<prompt>h4: {52} # </prompt><userinput>nlsadmin -r lpd tcp</userinput>
2181<prompt>h4: {53} # </prompt><userinput>nlsadmin -r lp tcp</userinput></screen>
2182</informalexample>
2183</para>
2184
2185<para>Run
2186<command>pmadm -l</command> as shown below.
2187<informalexample>
2188<screen><prompt>h2.private: {2} # </prompt><userinput>pmadm -l</userinput>
2189PMTAG    PMTYPE   SVCTAG   FLGS ID    &lt;PMSPECIFIC&gt;
2190zsmon    ttymon   ttya     u    root  /dev/term/a I - /usr/bin/login ...
2191zsmon    ttymon   ttyb     u    root  /dev/term/b I - /usr/bin/login ...</screen>
2192</informalexample>
2193
2194If you see
2195<command remap=tt>zsmon</command>
2196entries for SystemV
2197<command remap=tt>lpsched</command>
2198support,
2199then use <command>pmadm -r </command>to remove them.
2200These may not be present on all system.
2201See the
2202<command remap=tt>pmadm</command>
2203man page for details on the <literal>-r</literal> literal.</para>
2204
2205<para>You must now <command>reboot</command>
2206the host.
2207<informalexample>
2208<screen><prompt>h4: {54} # </prompt><userinput>shutdown -y "Whooga! Whooga! Dive! Dive! System going down."</userinput></screen>
2209</informalexample>
2210</para>
2211
2212<para>When the system reboots,
2213make sure that there is no process listening on port 515 (printer port)
2214by using:
2215<informalexample>
2216<screen><prompt>h4: {55} # </prompt><userinput>telnet localhost 515</userinput></screen>
2217</informalexample>
2218</para>
2219
2220<para>If you can connect,
2221then there is a problem beyond the scope of these instructions.</para>
2222
2223<para>Compile and/or install the &LPRng; software.
2224Make sure that the &LPRng; startup files have been
2225installed correctly in <filename>/etc/init.d/lprng</filename>
2226and that the symbolic links to the file have been made correctly.
2227The &LPRng; startup file will usually have the following contents and
2228you should use the same filename formats that the
2229<application remap=tt>lp</application>
2230startup files had for the
2231links to the <filename>/etc/init.d/lprng</filename> startup file:
2232<informalexample>
2233<screen>LPD_PATH=/usr/sbin/lpd
2234SHOWALL=-e
2235case "$1" in
2236  start)
2237        # Start daemons.
2238        /bin/echo "Starting lpd: \c"
2239        ${LPD_PATH}
2240        /bin/echo ""
2241        ;;
2242  stop)
2243        # Stop daemons.
2244        /bin/echo "Shutting down lpd: \c"
2245        kill -INT `ps ${SHOWALL} \
2246           | awk '/lpd/{ print $1;}'` &gt;/dev/null 2&gt;&amp;1
2247        /bin/echo " server stopped";
2248        ;;
2249  *)
2250        echo "Usage: $0 {start|stop}"
2251        exit 1
2252        ;;
2253esac</screen>
2254</informalexample>
2255
2256Start the <application>lpd</application> server and then test it:
2257<informalexample>
2258<screen><prompt>h4: {56} # </prompt><userinput>checkpc -f</userinput>
2259<prompt>h4: {57} # </prompt><userinput>/usr/sbin/lpd (or /usr/local/sbin/lpd)</userinput>
2260<prompt>h4: {58} # </prompt><userinput>lpq</userinput>
2261Printer: lp
2262 Queue: no printable jobs in queue</screen>
2263</informalexample>
2264</para>
2265
2266</sect2>
2267</sect1>
2268<sect1 id="lpsimulation"><title>Emulation for UNIX SystemV <application/lp/ and <application/lpstat/ </title>
2269
2270<para>Many utilities in the UNIX System V environment require the
2271<application remap=tt>lp</application>,
2272<application remap=tt>lpstat</application>,
2273and
2274<application remap=tt>cancel</application>
2275programs.
2276It is almost impossible to modify these utilities,
2277as many are <emphasis>vintage</emphasis>
2278software which is unsupported or which would
2279be too costly to update.
2280In order to support these applications
2281&LPRng; emulates the
2282<application remap=tt>lp</application>,
2283<application remap=tt>lpstat</application>,
2284and
2285<application remap=tt>clean</application>
2286programs.
2287See the &LPRng; man pages for
2288<application/lp/, <application/lpstat/,
2289and <application/cancel/ in the &LPRng; distribution for details
2290and compatibility.</para>
2291
2292<para>The &LPRng;
2293<application remap=tt>lpstat</application> emulator
2294accepts the
2295<application remap=tt>lpstat</application>
2296command line options returns
2297status in a format that is close to the one that common
2298<application/lpstat/
2299implementations return.
2300Unfortunately,
2301due to the wide variety of different modifications
2302and vendor versions of
2303<application/lpstat/
2304there are slight differences between the
2305this status and the status returned by the original
2306<application/lpstat/.
2307If this is the case,
2308then there is little to do but to modify the source code
2309for <application/lpstat/ and compile a version that implements
2310the required format.
2311</para>
2312<para>If the <application>lpr</application> program is invoked with the name
2313<application remap=tt>lp</application>,
2314it will simulate the
2315<application remap=tt>lp</application>
2316options.
2317This can be done by making a symbolic link to the <application/lpr/
2318program or by making a copy of the
2319<application/lpr/ program with the name <application/lp/.
2320<informalexample>
2321<screen><prompt>h4: {59} # </prompt><userinput>cd /usr/bin</userinput>
2322<prompt>h4: {60} # </prompt><userinput>ln -s lpr lp</userinput>
2323<prompt>h4: {61} # </prompt><userinput>lp /tmp/hi</userinput>
2324request id is root@h4+489</screen>
2325</informalexample>
2326</para>
2327<para>
2328Finally, if the <application>lprm</application> program is invoked with the name
2329<application remap=tt>cancel</application>
2330it will simulate the
2331<application remap=tt>cancel</application>
2332command.
2333This can be done by making a symbolic link to the <application/lprm/
2334program or by making a copy of the <application/lprm/ program
2335with the name <application/cancel/.
2336<informalexample>
2337<screen><prompt>h4: {62} # </prompt><userinput>cd /usr/bin</userinput>
2338<prompt>h4: {63} # </prompt><userinput>ln -s lprm cancel</userinput>
2339<prompt>h4: {64} # </prompt><userinput>cancel 489</userinput>
2340cancel 513
2341Printer lp@h9:
2342  checking perms 'root@h9+513'
2343  dequeued 'root@h9+513'</screen>
2344</informalexample>
2345</para>
2346
2347<para>Many
2348<emphasis>vintage</emphasis>
2349or
2350<emphasis>legacy</emphasis>
2351applications have fully qualified paths to the
2352<application remap=tt>lp</application>
2353and
2354<application remap=tt>lpstat</application>
2355executables,
2356and it may be necessary to make additional symbolic links or copies
2357of the &LPRng; executables to satisfy their pathname requirements.
2358<informalexample>
2359<screen><prompt>h4: {65} # </prompt><userinput>ln -s /usr/bin/lpr /usr/ucb/lpr</userinput></screen>
2360</informalexample>
2361</para>
2362</sect1>
2363
2364<sect1 id="smb"><title>SAMBA and &LPRng;</title>
2365
2366<para>The SMB network protocol
2367is used by many Microsoft Operating Systems
2368to implement file and printer sharing.
2369SAMBA is a UNIX package that implements the SMB protocol and provides
2370a simple and easy way to import and export file systems and printer
2371facilities.
2372The web site for SAMBA is
2373<ulink URL="http://www.samba.org">http://www.samba.org</ulink>.
2374The SAMBA code is extremely easy to install
2375and the <acronym>SWAT</acronym> (Samba Web Administration Tool)
2376makes configuration almost trivial.</para>
2377
2378<para>
2379See the SAMBA
2380<filename>doc/text/Printing.txt</filename> and related documentation for details on
2381printing.
2382In the
2383<filename>samba.conf</filename> file
2384<literal remap=tt>[global]</literal>
2385section
2386or in the SWAT page for printing configuration
2387you need to specify the that you want to have
2388Samba handle printing,
2389the
2390<literal remap=tt>print</literal>, <application>lpq</application>, and <application>lprm</application> commands to be used when a user
2391prints a job,
2392asks for status,
2393or removes a job,
2394and a temporary directory to hold print jobs when they are submitted.
2395The following is a simple example of to set up printing for
2396authenticated users.
2397<informalexample>
2398<screen>[printers]
2399    path = /var/spool/lpd/samba
2400    #  ---  do not use the Samba default path = /tmp
2401    print ok = yes
2402    printing = lprng
2403    load printers = yes
2404    guest ok = no
2405    printcap name = /etc/printcap
2406    print command =      /usr/bin/lpr  -P%p -r %s
2407    lpq command   =      /usr/bin/lpq  -P%p
2408    lprm command  =      /usr/bin/lprm -P%p %j
2409    lppause command =    /usr/sbin/lpc hold %p %j
2410    lpresume command =   /usr/sbin/lpc release %p %j
2411    queuepause command = /usr/sbin/lpc  stop %p
2412    queueresume command = /usr/sbin/lpc start %p
2413</screen>
2414</informalexample>
2415</para>
2416
2417
2418<orderedlist>
2419<listitem>
2420<para>Samba will make a copy of the files to be printed
2421in the directory specified by <literal>path</literal>.
2422If the print operation fails then sometimes the print file
2423is left in the directory.
2424</para></listitem>
2425<listitem><para>
2426The directory should have
2427the same ownership and permissions as
2428<filename>/tmp</filename>,
2429i.e.- owner and group <literal/root/ and <literal/bin/,
2430with
2431<literal/01777/ permissions,
2432where <literal/01000/ is the sticky bit.
2433</para><para>
2434A directory whose `sticky bit' is set becomes an append-only directory,
2435or, more accurately, a directory in which the deletion of files is re-
2436stricted.  A file in a sticky directory may only be removed or renamed by
2437a user if the user has write permission for the directory and the user is
2438the owner of the file, the owner of the directory, or the super-user.
2439This feature is usefully applied to directories such as /tmp which must
2440be publicly writable but should deny users the license to arbitrarily
2441delete or rename each others' files.
2442</para></listitem>
2443<listitem><para>
2444The directory should be examined periodically and files
2445older then a day should be removed.  The following command
2446can be used to do this,  and should be put in a file that
2447is periodically (one a day) executed by the <application/cron/
2448facility:
2449<informalexample>
2450<screen>find /var/spool/lpd/samba -type f -mtime 2d -exec rm -f {} \;</screen>
2451</informalexample>
2452</para>
2453</listitem>
2454
2455<listitem>
2456<para>You must specify the print method as <literal>printing = lprng</literal>.
2457This will allow Samba to parse the
2458&LPRng; <application/lpq/ status format correctly.</para>
2459</listitem>
2460
2461<listitem>
2462<para>You must put all of the printers which Samba has access to
2463in the <filename>printcap</filename> file.
2464Your Samba server may support reading the printcap file by
2465using a program.  In this case the printcap file entry can
2466be one of the following:
2467<informalexample>
2468<screen>[printers]
2469  #
2470    printcap name = |/usr/local/libexec/filters/getpc
2471  # or
2472    printcap name = |/usr/bin/lpc client all 
2473
2474#!/bin/sh
2475# getpc program
2476/usr/bin/lpq -as | /bin/sed -e 's/[@:].*//p'
2477
2478</screen>
2479</informalexample>
2480</para>
2481<para>
2482The <literal/lpc client all/ command
2483will generate the printcap entries for all of the printers.
2484This was done to support Samba and other printer gateway systems.
2485You can also use a simple script to modify the output of the
2486printer status command as shown in the example.
2487</para>
2488</listitem>
2489
2490<listitem>
2491<para>
2492Samba can be configured to allow guests or non-authenticated users
2493to spool print jobs.
2494Unfortunately,
2495by default <application/lpr/ will mark the jobs
2496as submitted by the Samba server, not the remote users. 
2497To solve this problem,
2498the <command>lpr -U%U@%M</command> option causes
2499<application/lpr/ to mark the jobs as submitted by user <literal/%U/ on host <literal/%M/,
2500instead of the Samba server process.
2501The use of this option is restricted to root and a set of userids listed
2502in the
2503<link linkend="allowusersetting">allow_user_setting</link>
2504configuration option.
2505If the userid of the submitter is not in this list,
2506then the option is quietly ignored.
2507The <command>-U%U@M</command> can also be used with the other LPRng commands as well.
2508For example:
2509<informalexample>
2510<screen>[printers]
2511    guest ok = yes
2512    print command =       /usr/bin/lpr  -U%U@%M -P%p -r %s
2513    lpq command   =       /usr/bin/lpq  -U%U@%M -P%p
2514    lprm command  =       /usr/bin/lprm -U%U@%M -P%p %j
2515    lppause command =     /usr/sbin/lpc -U%U@%M hold %p %j
2516    lpresume command =    /usr/sbin/lpc -U%U@%M release %p %j
2517    queuepause command =  /usr/sbin/lpc -U%U@%M stop %p
2518    queueresume command = /usr/sbin/lpc -U%U@%M start %p
2519</screen>
2520</informalexample>
2521</para>
2522</listitem>
2523
2524</orderedlist>
2525
2526<para>
2527When Samba gets a request for print queue status,
2528it runs the <literal/lpq command/ program and then
2529parses the output of this command.
2530Unfortunately,
2531different versions of Samba have different ways of parsing
2532the output - some are more flexible than others.
2533<para/>
2534<para>
2535One of the problems that might occur is when the
2536&LPRng; <literal/done_jobs/ feature is enabled.
2537This causes that status of the last few jobs to be retained
2538so that users can see what happened to their jobs.
2539For example:
2540<informalexample>
2541<screen>
2542h110: {588} % lpq
2543Printer: t1@h110 'Test Printer 1'
2544 Queue: no printable jobs in queue
2545 Server: no server active
2546 Status: job 'papowell@h110+336' saved at 14:42:54.607
2547 Filter_status: FILTER DONE
2548 Rank   Owner/ID         Class Job Files    Size Time
2549done   papowell@h110+336   A   336 /tmp/hi     3 14:42:53
2550</screen>
2551</informalexample>
2552</para>
2553<para>
2554In this example, the <literal/done/ job will have its status
2555displayed by the lpq command.
2556However, this may confuse Samba, and it may report odd or
2557unusual status for your jobs. 
2558If the
2559<application/lpq/ command reports that your job has completed
2560but Samba reports that it is printing or is stopped,
2561then you should disable the <literal/done_jobs/ option
2562in the printcap entry:
2563<informalexample>
2564<screen>
2565lp:
2566  :done_jobs=0
2567  :...
2568</screen>
2569</informalexample>
2570</para>
2571
2572</sect1>
2573
2574<sect1 id="setuid"><title>Security Concerns </title>
2575
2576<para>While the &LPRng; software has been written with security as the primary goal
2577there is always the problem with undetected errors in the &LPRng;
2578software that
2579when exploited
2580could compromise system security.
2581The most serious concern is that of gaining ROOT (UID 0) permissions.</para>
2582<para>
2583The simplest way to handle this problem is to not install
2584LPRng with <literal>setuid ROOT</literal> permissions.
2585Client programs will be able to connect to the <application/lpd/
2586server.
2587Since the <application/lpd/ server is started by the system
2588startup script with effective UID root,
2589it is the only program in this suite that will have an privileged
2590user id.
2591</para>
2592
2593<para>
2594A more radical step is to run the <application/lpd/
2595server as a non-privileged user entirely.
2596However,
2597the RFC1179 protocol specifies
2598that the <application/lpd/ TCP/IP port is 515
2599and
2600<application>lpd</application>
2601requires root permissions to open and bind to port 515.
2602The <application>lpd</application>
2603server can use the <function/setuid()/ system call
2604after binding to this port do drop ROOT capabilities.
2605However,
2606in order to fully compatible with RFC1179,
2607<application>lpd</application> must originate connections from a <emphasis>reserved</emphasis>
2608port in the range 721-731,
2609although in practice port 1-1023 seems to be acceptable.</para>
2610
2611<para>If inter-operability with non-&LPRng; print spoolers is not desired,
2612then it is <emphasis>trivial</emphasis>
2613to configure &LPRng; to use a non-privileged
2614port by using the <filename>lpd.conf</filename> file.
2615For example,
2616in the <filename>/etc/lpd.conf</filename> file,
2617you only need to change the indicated lines:
2618<informalexample>
2619<screen># Purpose: lpd port
2620#   default lpd_port=printer
2621lpd_port=2000
2622# or lpd_port=localhost%2000</screen>
2623</informalexample>
2624The <literal>lpd_port</literal> specifies the (optional)
2625IP address and port to which the <application/lpd/ server binds
2626and to which the clients will connect.
2627&LPRng; applications will connect to port 2000
2628to transfer jobs and ask for status.
2629You can also use this facility to establish a
2630<emphasis>private</emphasis>
2631set of print spoolers which can be used for testing
2632See
2633<link linkend=testing>Testing and Diagnostic Facilities</link>
2634for more details.</para>
2635
2636<para>Some <emphasis>legacy</emphasis> print filters
2637are not <emphasis>meta-char-escape</emphasis> proof.
2638For example,
2639suppose that a user decided to spool a job as follows:
2640<informalexample>
2641<screen><prompt>h4: {66} #</prompt> <userinput>lpr "-J`;rm -rf /;`" /tmp/a</userinput></screen>
2642</informalexample>
2643This would create a job file with the line:
2644<informalexample>
2645<screen>J`rm -rf /;`</screen>
2646</informalexample>
2647and gets passed to a print filter as
2648<informalexample>
2649<screen>/usr/local/printfilter  -J`rm -rf /;`</screen>
2650</informalexample>
2651The observant reader will observe that the above line
2652may have the most hideous consequences if it is processed
2653by a shell.
2654For this reason the &LPRng; software takes extreme precautions
2655and <emphasis/sanitizes/ control file contents and file names
2656so that they do not contain any control or metacharacters.
2657</para>
2658
2659<para>
2660Finally,
2661you can use a Unix socket (i.e. - FIFO) for connections to the server on
2662the localhost,
2663and disable the &lpd; listening socket by setting the
2664<literal/lpd_listen_port/ value to <literal/off/.
2665</para>
2666</sect1>
2667</chapter>
2668
2669<chapter id=systemspecific><title>System Specific Notes </title>
2670
2671<para>The following are a set of suggestions and recommendations for
2672specific systems.</para>
2673
2674
2675<sect1 id="solaris"><title>Solaris</title>
2676
2677<para>The Sun Microsystems Solaris printing system is derived from the
2678System V UNIX system.
2679Please see the
2680
2681<link linkend="solarisinstall">Solaris, HP, and SysVR4 Derived Systems</link>
2682
2683installation information for a detailed description of how
2684to install &LPRng; and remove the Solaris Print Services.
2685</para>
2686
2687<para>
2688If you want to simply forward jobs from a Solaris system to a
2689BSD print spooling system you can use the following commands to
2690create a printer.  Check your specific system references and man
2691pages for options:
2692<informalexample>
2693<screen><prompt>h4: {67} # </prompt><userinput>lpsystem -t bsd servername</userinput>   # add server
2694<prompt>h4: {68} # </prompt><userinput>lpadmin -p pr -s servername -T unknown -I any</userinput> # set up printer
2695<prompt>h4: {69} # </prompt><userinput>accept pr</userinput>   # enable queueing
2696<prompt>h4: {70} # </prompt><userinput>enable pr</userinput>   # enable printing
2697<prompt>h4: {71} # </prompt><userinput>lpstat -t</userinput>   # show status
2698scheduler is running
2699system for pr: servername
2700lp accepting requests since Mon Aug  6 12:00:00 PST 2000
2701Printer: pr@servername  'Hp : Laserwriter' (printing disabled)
2702 Queue: 1 printable job
2703 Rank  Owner/ID            Class Job Files            Size Time
27041      papowell@h4+207       A   207 h4.023205           3 18:24:54</screen>
2705</informalexample>
2706</para>
2707<para>
2708The above commands will create the necessary directories and files
2709for the printer.
2710If you want to use the <literal/lp -o option/ syntax to pass options
2711to the LPRng print spooler you will have to enable this
2712by hand.
2713The <filename>/etc/printers.conf</filename> (this may be in some other
2714directory besides <filename>/etc</filename>) needs to be modified
2715so that it allows options to be passed using the Solaris convention,
2716which is to put them on the <literal/S/ or <literal/O/ line of the 
2717control file.
2718For example:
2719<informalexample>
2720<screen>
2721#
2722# The preferred method of modifying this file is through the use of
2723# lpset(1M) or fncreate_printer(1M)
2724#
2725pr:bsdaddr=servername,pr,Solaris:
2726_default:use=pr:</screen>
2727</informalexample>
2728</para>
2729<para>
2730The <literal/bsdaddr=host,printer[,Solaris]/
2731indicates that the entry is for a remote RFC1179 printer
2732on server <literal/host/ with name <literal/printer/.
2733The <literal/Solaris/ option indicates that the Solars extensions
2734to the RFC1179 protocol are to be used.
2735</para>
2736</sect1>
2737
2738<sect1 id="linux"><title>Linux</title>
2739
2740<para>
2741There is no universal way to install &LPRng; cleanly on all of the different
2742Linux systems.
2743The major difficulty is the fragmentation in the various libraries,
2744location of files,
2745and system dependencies.
2746If the &LPRng; installation procedure does not install the software
2747correctly,
2748please use the following remedial steps.
2749<orderedlist>
2750<listitem>
2751<para>Check the &LPRng; web site
2752<ulink URL="http://www.lprng.com">http://www.lprng.com</ulink>
2753and see if there is a Linux Release RPM or other binary distribution
2754for your version of Linux.
2755If not, then you will have to do a source install.</para>
2756</listitem>
2757
2758<listitem>
2759<para>Obtain the source distribution and follow
2760the instructions outlined in other sections to compile and
2761install the software.
2762Use the following configuration options
2763which correspond to Linux:
2764<informalexample>
2765<screen><prompt>h4: {72} # </prompt><userinput>./configure --prefix=/usr \
2766  --sysconfdir=/etc --mandir=/usr/share/man</userinput>
2767<prompt>h4: {73} # </prompt><userinput>make clean all install</userinput>
2768<prompt>h4: {74} # </prompt><userinput>checkpc -f</userinput></screen>
2769</informalexample>
2770</para>
2771</listitem>
2772<listitem>
2773<para>
2774You may need to modify your existing printcap file by adding the
2775<option/:bkf/ flag as shown below,
2776or replace the entries with other filters.
2777<informalexample>
2778<screen>lp:\
2779  :if=/usr/local/libexec/lpr/hplaserjet3:\
2780  :bkf:\     # added to the printcap by hand
2781  :...</screen>
2782</informalexample>
2783</para>
2784</listitem>
2785<listitem>
2786<para>
2787Test the system by printing a file.
2788If this does not work,
2789then you will have to determine if the problem is in the print spooling
2790software or in the filter.
2791See the section on
2792<application remap=tt>ifhp</application>
2793for directions on how to replace the vendor
2794supplied filters with
2795<application remap=tt>ifhp</application>.</para>
2796</listitem>
2797</orderedlist>
2798</para>
2799
2800</sect1>
2801
2802<sect1 id="aix"><title>AIX</title>
2803
2804<para>This information was supplied by
2805<ulink URL="mailto:nitschke@math.unihamburg.de">Dirk Nitschke</ulink>,
2806as of August 1997,
2807and describes how to install the &LPRng; package on a workstation
2808running AIX 4.1.x and possibly 3.x.x as well.
2809Dirk would be interested in any comments or corrections.</para>
2810
2811<para>Printing on AIX systems is different. AIX provides a general
2812queueing facility and printing is only one way to use it. You submit a
2813print job to a print queue using one of the commands
2814<command remap=tt>qprt</command> or
2815<command remap=tt>enq</command>.
2816You can use the BSD or
2817System V printing commands <application>lpr</application> or
2818<application remap=tt>lp</application>, too. The
2819<command>qdaemon</command>
2820watches all (general) queues and knows how to handle your
2821job. A (general) queue is defined in the file
2822<filename>/etc/qconfig</filename>. The format of this file is different from
2823the <filename>printcap</filename> format.</para>
2824
2825<para>OK, how to replace the AIX printing system? There is no group
2826<literal>daemon</literal> on AIX. Therefore you have to change the default
2827group for file ownership and process permissions
2828or create a <literal>daemon</literal> user and group.
2829We decided to use the
2830<literal remap=tt>printq</literal>
2831group;
2832on reflection it would have been easier
2833to have created a <literal>daemon</literal> group.
2834The user <literal>daemon</literal> exists on
2835AIX but we have chosen <application>lpd</application> as the user who runs
2836<application>lpd</application> and all filters and owns the spooling directories.
2837You can change the values for
2838<literal remap=tt>group</literal>
2839and
2840<literal remap=tt>user</literal>
2841in your
2842<filename>lpd.conf</filename> file or in the sources
2843<filename>src/common/vars.c</filename>. This is an example for
2844<filename>lpd.conf</filename>:
2845<informalexample>
2846<screen># Purpose: group to run SUID ROOT programs
2847#   default group=daemon
2848group=printq
2849# Purpose: server user for SUID purposes
2850#   default user=daemon
2851user=lpd</screen>
2852</informalexample>
2853
2854Compile and install the &LPRng; package. Create your
2855<filename>printcap</filename>, spooling directories, accounting and logfiles
2856and so on.
2857Don't forget to use
2858
2859<link linkend="checkpc">checkpc</link>
2860to make sure that all the
2861permissions are set correctly and the necessary files
2862are created.</para>
2863
2864<para>Then stop all print queues defined on your workstation. Use
2865<informalexample>
2866<screen># chque -q queuename -a "up = FALSE"</screen>
2867</informalexample>
2868
2869for this (yes, blanks around <literal>=</literal> are needed).</para>
2870
2871<para>If you have local printers attached to your system you will have an
2872<application>lpd</application> running. Stop this daemon using SMIT (Print Spooling,
2873Manage Print Server, Stop the Print Server Subsystem). Choosing
2874<emphasis>both</emphasis>
2875also removes <application>lpd</application> from
2876<filename>/etc/inittab</filename>. Maybe it's faster to do this by hand:
2877<informalexample>
2878<screen><prompt>h4: {75} # </prompt><userinput>topsrc -p'pid of /usr/sbin/lpd'</userinput>
2879<prompt>h4: {76} # </prompt><userinput>rmitab "lpd"</userinput></screen>
2880</informalexample>
2881</para>
2882
2883<para>Now delete all print queues managed by <literal>qdaemon</literal> defined on your
2884system. You can use <command/SMIT/ for this or the commands
2885<command remap=tt>{mk,ch,rm}que</command>,
2886<command remap=tt>{mk,ch,rm}quedev</command>,
2887<command remap=tt>{mk,ch,rm}virprt</command>. The <command/SMIT/ fast path is
2888<command remap=tt>smit rmpq</command>.</para>
2889
2890<para>To start the new <application>lpd</application> at system startup you have to add
2891an entry to <filename>/etc/inittab</filename>:
2892<informalexample>
2893<screen><prompt>h4: {77} # </prompt><userinput>mkitab "lpd:2:once:/full/path/lpd"</userinput></screen>
2894</informalexample>
2895</para>
2896
2897<para>Some work has to be done if have have a local printer attached to
2898your workstation. You have to create a device file like
2899<filename>/dev/lp0</filename>. The <command/SMIT/ fast path for this is
2900<command remap=tt>smit mkdev</command>.
2901Choose <literal>Printer/Plotter</literal>,
2902then
2903<literal remap=tt>Printer/Plotter Devices</literal>,
2904then
2905<literal remap=tt>Add a Printer/Plotter</literal>.
2906To create a parallel printer device select the following:
2907<informalexample>
2908<screen>Plotter type:              opp Other parallel printer
2909Printer/Plotter Interface: parallel
2910Parent Adapter:            ppa0 Available</screen>
2911</informalexample>
2912Now define the characteristics of the device:
2913<informalexample>
2914<screen>Port Number: p</screen>
2915</informalexample>
2916Option <literal remap=tt>p</literal>
2917is for parallel.
2918Go to the field:
2919<informalexample>
2920<screen>Send all characters to printer UNMODIFIED   no</screen>
2921</informalexample>
2922</para>
2923<para>
2924and select
2925<literal remap=tt>yes</literal>! We have had a lot of trouble with
2926<literal remap=tt>no</literal>.
2927This is very important! Expect erroneous output if
2928you choose
2929<literal remap=tt>no</literal>. If you have already created a device
2930file, change the characteristics! SMIT's fast path is
2931<command remap=tt>smit chdev</command>.</para>
2932
2933<para>Finally remove all AIX printing commands like
2934<application remap=tt>qprt</application>,
2935<application remap=tt>lp</application>,
2936<application remap=tt>cancel</application>, <application>lpq</application>,
2937and
2938<application>lprm</application>. You will find a lot of them in
2939<filename>/usr/bin</filename>. Do not remove
2940<application remap=tt>enq</application>
2941and friends if
2942you want to use the general queueing facility.</para>
2943
2944<para>Now you can start your new <application>lpd</application>.</para>
2945
2946</sect1>
2947
2948<sect1 id="appletalk"><title>AppleTalk Support </title>
2949
2950<para>Netatalk is used to communicate from TCP/IP to
2951AppleTalk printers and vice versa.
2952The Netatalk distribution FAQ is at:
2953<ulink URL="http://www.umich.edu/~rsug/netatalk">http://www.umich.edu/~rsug/netatalk</ulink>.
2954Also,
2955The University of Melbourne web site
2956<ulink URL="http://www.cs.mu.oz.au/appletalk/">http://www.cs.mu.oz.au/appletalk/</ulink>
2957has additional tutorial and installation information.
2958In addition,
2959Anders Brownworth's Web page
2960<ulink URL="http://thehamptons.com/anders/netatalk/">http://thehamptons.com/anders/netatalk/</ulink>
2961has a useful collection of information for Linux users.</para>
2962
2963<para>
2964The University of Michigan doesn't seem to be doing anything more
2965for <application/netatalk/, and Adrian Sun has continued development.  You'll
2966find his updates at
2967<ulink URL="ftp://ftp.cobaltnet.com/pub/users/asun/testing/">
2968ftp://ftp.cobaltnet.com/pub/users/asun/testing/</ulink>
2969He has improved <application/netatalk/ considerably over the last UMich version.
2970Documentation on <application/netatalk/ is,
2971unfortunately,
2972almost non-existent.
2973</para>
2974<para>
2975There are a couple of very active mail lists for Netatalk:
2976<ulink URL="mailto:netatalk-admins@umich.edu">netatalk-admins@umich.edu</ulink>
2977and
2978<ulink URL="mailto:linux-atalk@netspace.org">linux-atalk@netspace.org</ulink>.
2979</para>
2980
2981<para>After you have installed and gotten <application/netatalk/ working
2982you can use the following AppleTalk configuration file to print
2983from a Macintosh to an &LPRng; printer.
2984<informalexample>
2985<screen>Your 32 Character Printer Name:\
2986        :pr=|/your/path/to/lpr -Pprintername:\
2987        :op=username.for.printing:\
2988        :pd=/your/path/to/ppd/files/yourprinter.ppd:
2989
2990Examples:
2991
2992Student Printers:\
2993        :pr=|/usr/bin/lpr -Pstudent:\
2994        :op=root:\
2995        :pd=/var/spool/lpd/student/HP4000.PPD:
2996HP 2500c:\
2997        :pr=|/usr/bin/lpr -Php2500c:\
2998        :op=root:\
2999        :pd=/var/spool/lpd/hp2500c/HP2500.PPD:</screen>
3000</informalexample>
3001</para>
3002
3003</sect1>
3004</chapter>
3005
3006<chapter id=tutorial><title>Print Spooling Tutorial </title>
3007
3008<para>A print spooler is a program that accepts
3009<emphasis>print jobs</emphasis>
3010(which are usually one or more files)
3011from a program or network interface,
3012stores them in a
3013<emphasis>spool queue</emphasis>,
3014and then sends them to a printer or another
3015print spooler.
3016Usually there are facilities to submit jobs,
3017check on the current job status,
3018remove jobs from spool queues,
3019and perform administrative functions such as starting or
3020stopping printing.</para>
3021
3022<para>A print spooler is a client/server application.
3023The client programs are used to submit jobs to the print spooler
3024program which performs the actual printing operations.
3025In order to carry out these operations,
3026the server may need to use other programs to convert print job files
3027into a format acceptable to a printer,
3028or perform various accounting or administrative functions.</para>
3029
3030
3031<sect1 id=overview><title>Overview</title>
3032
3033<para>
3034<informalexample>
3035<screen>
3036+---------+    +-----+    +-----+     +--------+    +---------+
3037| program | -&gt; | lpr | -&gt; | lpd |  -&gt; | filter | -&gt; | printer |
3038+---------+    +-----+  * +-----+     +--------+    +---------+
3039                  *    *     |
3040               printcap      V
3041                          +-----+     +--------+    +---------+
3042                          | lpd |  -&gt; | filter | -&gt; | printer |
3043                          +-----+     +--------+    +---------+
3044
3045                           Figure 1</screen>
3046</informalexample>
3047</para>
3048
3049<para>Figure 1 shows the flow of data between the individual components of the
3050&LPRng; print spooling system.
3051A program (or user) will use the <application>lpr</application> program to send a file
3052to the <application>lpd</application> server over a TCP/IP connection.
3053The <application>lpd</application> server will store the file temporarily in a
3054spool queue directory.
3055The information needed by the <application>lpr</application> and <application>lpd</application> programs to carry
3056out this activity is stored in the
3057<filename>printcap</filename>  (usually called the <filename>/etc/printcap</filename>) database file.</para>
3058
3059<para>The <application>lpd</application> server sorts the queue entries and determines the print order.
3060It will select a job to be printed,
3061open a connection to the printer,
3062and then use a <emphasis>filter</emphasis>
3063program to convert the file contents into a
3064format suitable for the printer.
3065If the file does not need conversion,
3066then the <application>lpd</application> server will send the file directly to the printer.</para>
3067
3068<para>The <application>lpd</application> server can also
3069<emphasis>forward</emphasis>
3070jobs to another print server
3071over a network connection,
3072optionally sending them through a filter as well.
3073The destination server can in turn forward the job or send it to a printer.</para>
3074
3075<para>The protocol or commands used to do this job forward and transfer are
3076specified by
3077
3078<link linkend="rfc1179ref">RFC1179</link>.
3079This protocol specifies how the <application>lpr</application> client program sends a job
3080to the <application>lpd</application> server,
3081as well as how the <application>lpd</application> server forwards jobs to another server.
3082In addition to job submission,
3083RFC1179 specifies commands to obtain queue status,
3084to remove jobs from the queue,
3085and to start and stop print queues.</para>
3086
3087</sect1>
3088
3089<sect1 id="sampleprintcap"><title>Sample Printcap Entry</title>
3090
3091<para>As described in the
3092
3093<link linkend="overview">Print Spooling Overview</link>,
3094the information in the <filename>printcap</filename> database is used control printing
3095operations.
3096While there is no RFC specifying its format or content,
3097there is a strong <emphasis>de facto</emphasis>
3098standard for its format.
3099For a complete description of the <filename>printcap</filename> database see
3100<link linkend="printcapref">Printcap Database</link>.
3101For a list of all of the <filename>printcap</filename> and configuration options see
3102<link linkend="optionindex">Index To All The Configuration and Printcap Options</link>.</para>
3103
3104<para>Here is a sample printcap suitable for use by the &LPRng; clients:
3105<informalexample>
3106<screen>LPRng use :lp for destination (device and spool queue)
3107   lp:lp=lp@h4.private
3108   lpreal:lp=/dev/lp0
3109
3110Vintage BSD uses :rp:rm for spooler queue and :lp for device
3111  lp:rp=lp:rm=h4.private
3112  lpdev:lp=/dev/lp0
3113</screen>
3114</informalexample>
3115</para>
3116
3117<para>The <literal>:lp=lp@h4.private</literal> printcap entry
3118tells the <emphasis>client</emphasis>
3119programs that jobs for the
3120<application remap=tt>lp</application>
3121printer or print queue are sent to the
3122<application remap=tt>lp</application>
3123print queue queue on host <filename>h4.private</filename>.
3124This can also be specified using the
3125The <emphasis>legacy</emphasis>
3126BSD <literal>:rp</literal>
3127and <literal>:rm</literal>.
3128The
3129<literal remap=tt>:rp=</literal><emphasis>queue</emphasis>
3130option
3131specifies the <emphasis>print queue</emphasis>
3132<literal remap=tt>:rm=</literal><emphasis>host</emphasis>
3133option
3134specifies the host.
3135When both
3136<literal remap=tt>lp</literal>
3137and
3138<literal>:rp:rm</literal> are present the
3139<literal remap=tt>:lp</literal>
3140option has precedence.</para>
3141
3142<para>On the printserver
3143the following is a sample printcap entry
3144suitable for the <application>lpd</application> server:
3145<informalexample>
3146<screen>lp:
3147  :lp=/dev/lp0
3148  :sd=/var/spool/lpd/%P
3149  :filter=/usr/local/libexec/filters/ifhp</screen>
3150</informalexample>
3151</para>
3152
3153<para>The
3154<literal remap=tt>:sd=</literal><emphasis>directory</emphasis>
3155option
3156(spool queue directory) specifies the directory where
3157print jobs will be placed.
3158The <literal>%P</literal> will be replaced with the name of the spool queue.
3159The
3160<literal remap=tt>:lp</literal> literal
3161is now the path to the output device
3162the <application>lpd</application> server will use to print the job.
3163The <literal>:filter</literal> literal specifies the filter
3164program to use to process the job before sending to the output device.
3165</para>
3166<para> Here is another example of a printcap entry using the
3167<literal remap=tt>%P</literal>
3168notation:
3169<informalexample>
3170<screen>lp:lp=%P@h4.private</screen>
3171</informalexample>
3172This entry will cause all jobs sent to the
3173<literal>lp</literal>
3174spool queue to be sent to the
3175<literal>lp</literal> queue on <literal>server</literal>.
3176<literal remap=tt>%X</literal>
3177strings in the printcap entries are expanded as shown:
3178<informaltable frame=all>
3179<tgroup cols=2 align=left rowsep=1 colsep=1>
3180<thead>
3181<row><entry>Key</entry><entry>Replaced By</entry></row>
3182</thead>
3183<tbody>
3184<row><entry><literal/%P/</entry><entry>printcap entry primary name (printer)</entry></row>
3185<row><entry><literal/%Q/</entry><entry>queue requested</entry></row>
3186<row><entry><literal/%h/</entry><entry>short host name  (host)</entry></row>
3187<row><entry><literal/%H/</entry><entry>fully qualified host name  (host.dns.whatever)</entry></row>
3188<row><entry><literal/%R/</entry><entry>remote printer (rp value)</entry></row>
3189<row><entry><literal/%M/</entry><entry>remote host (rm value)</entry></row>
3190<row><entry><literal/%D/</entry><entry>date in YYYY-MM-DD format</entry></row>
3191</tbody>
3192</tgroup>
3193</informaltable>
3194</para>
3195
3196</sect1>
3197
3198<sect1 id="tutorialconfig"><title>Setting Up the Tutorial Configuration</title>
3199
3200<para>The previous section has given a very high level view of printing
3201operations and shown a sample of some printcap files.
3202In order to do experiment with these LPRng facilities,
3203we will need to be able to modify the
3204<filename>printcap</filename>
3205information and try various system configurations.
3206</para>
3207
3208<para>We will use a series of simple printcap entries during this tutorial.
3209We will assume that the &LPRng; system is using
3210the <filename>/etc/printcap</filename> file.
3211If your system is configured to use another one,
3212then you can make a symbolic link from <filename>/etc/printcap</filename>
3213or you can simply use your default
3214<filename>printcap</filename> file.
3215</para>
3216<para>
3217Save the existing <filename>printcap</filename> file and then
3218create a new printcap file
3219with the contents as shown below.
3220You will need to have ROOT (superuser) permissions to change
3221the file and perform some of the maintenance operations.
3222<informalexample>
3223<screen>
3224<prompt>h4: {78} # </prompt><userinput>cd /etc </userinput>
3225<prompt>h4: {79} # </prompt><userinput>mv printcap printcap.orig</userinput>
3226<prompt>h4: {80} # </prompt><userinput>vi printcap</userinput>
3227<userinput>#  printcap file contents:</userinput>
3228<userinput>lp:sd=/var/spool/lpd/%P</userinput>
3229<userinput>  :force_localhost</userinput>
3230<userinput>  :lp=/tmp/lp</userinput>
3231<userinput>lp2:sd=/var/spool/lpd/%P</userinput>
3232<userinput>  :force_localhost</userinput>
3233<userinput>  :lp=/tmp/lp2</userinput>
3234<prompt>h4: {81} # </prompt><userinput>#  set permissions so everybody can read file</userinput>
3235<prompt>h4: {82} # </prompt><userinput>chmod 666 printcap</userinput></screen>
3236</informalexample>
3237</para>
3238
3239<para>
3240We save the original <filename>printcap</filename> file
3241and create a new one.
3242We give the file world writable permissions so that later we can modify this
3243file without needing to have root permissions.
3244The <filename>printcap</filename> file has two entries:
3245<literal remap=tt>lp</literal>
3246and
3247<literal remap=tt>lp2</literal>.
3248Each print queue on the server needs a spool file to hold print jobs,
3249jobs,
3250and the
3251<literal remap=tt>:sd</literal>
3252value specifies its location.
3253The
3254<literal remap=tt>%P</literal>
3255value is replaced with the name of the printer
3256when it is used.
3257In classical BSD operation
3258each host has an <application>lpd</application> print spooler running on the local host
3259(we use localhost in this manual for simplicity).
3260Files were copied to spool directories on the localhost and then then
3261print spooler would send them to the destination,
3262which could be another print spooler.
3263This meant that each localhost machine had to have a print spooler
3264and spool queue directory structure.
3265Management of this becomes very difficult in large organizations.
3266The <literal>force_localhost</literal> forces this mode of
3267operation
3268and means that the <application/lpd/ server and clients must run
3269on the same host.
3270</para>
3271<para>
3272We use files
3273for the output devices (<literal>:lp=</literal>)
3274so that we can see easily view the output
3275(and also to save trees).
3276We will also need to have some simple test files.
3277Create the files using the following commands.
3278<informalexample>
3279<screen><prompt>h4: {83} # </prompt><userinput>cp /dev/null /tmp/lp</userinput>
3280<prompt>h4: {84} # </prompt><userinput>cp /dev/null /tmp/lp2</userinput>
3281<prompt>h4: {85} # </prompt><userinput>chmod 666  /tmp/lp /tmp/lp2</userinput>
3282<prompt>h4: {86} # </prompt><userinput>echo hi &gt;/tmp/hi</userinput>
3283<prompt>h4: {87} # </prompt><userinput>echo there &gt;/tmp/there</userinput></screen>
3284</informalexample>
3285</para>
3286
3287<para>We will use
3288a <emphasis>dummy</emphasis>
3289<filename>lpd.perms</filename>
3290file that allows all users to do anything.
3291This is useful for testing,
3292but dangerous in a working environment.
3293<informalexample>
3294<screen><prompt>h4: {88} # </prompt><userinput>#  we modify the lpd.perms to allow an ordinary user to control</userinput>
3295<prompt>h4: {89} # </prompt><userinput>mv lpd.perms lpd.perms.orig</userinput>
3296<prompt>h4: {90} # </prompt><userinput>echo "DEFAULT ACCEPT" &gt;lpd.perms</userinput>
3297<prompt>h4: {91} # </prompt><userinput>chmod 666 lpd.perms</userinput></screen>
3298</informalexample>
3299</para>
3300
3301<para>Finally we run <command>checkpc</command>
3302to make sure that our printcap is correct and to create the
3303necessary spool directories:
3304<informalexample>
3305<screen><prompt>h4: {92} # </prompt><userinput>checkpc -f -V</userinput>
3306Checking printer 'lp'
3307 Checking directory: '/var/spool/lp'
3308   directory '/var'
3309   directory '/var/spool'
3310   directory '/var/spool/lp'
3311 Warning -   changing ownership '/var/spool/lp' to 1/1
3312   checking 'control.lp' file
3313   checking 'status.lp' file
3314   checking 'status' file
3315   cleaning 'status' file, 0K bytes: no truncation
3316   checking 'log' file
3317   cleaning 'log' file, 0K bytes: no truncation
3318   checking 'acct' file
3319   cleaning 'acct' file, 0K bytes: no truncation
3320Checking printer 'lp2'
3321  Checking directory: '/var/spool/lp2'
3322    directory '/var'
3323  ....
3324<prompt>h4: {93} # </prompt><userinput>lpc reread</userinput>
3325<prompt>h4: {94} # </prompt><userinput>lpd</userinput>
3326<prompt>h4: {95} # </prompt><userinput>lpq</userinput>
3327Printer: lp@h4
3328   Queue: no printable jobs in queue</screen>
3329</informalexample>
3330</para>
3331
3332<para>
3333<link linkend="checkpc"><application/Checkpc/</link>
3334performs consistency checks on the printcap file and spool queue entries.
3335The
3336<command>checkpc -f</command> (fix) option will change permissions and create
3337directories and can only be executed by ROOT.
3338<link linkend="checkpc"><application/Checkpc/</link>
3339has other functions as well - you can view printcap information,
3340see default configuration values,
3341and
3342remove junk files from spool queues with it.</para>
3343
3344<para>The
3345<command remap=tt>lpc reread</command>
3346command sends a request to the <application/lpd/ server to reread the configuration
3347and printcap information.
3348The <application>lpd</application> command is added as insurance in case your <application>lpd</application>
3349server is not running.
3350The
3351<command remap=tt>exit</command>
3352command restores ordinary user privileges,
3353and the <application>lpq</application> command is used to check that the server is running.
3354Finally,
3355we check to see that the
3356<command remap=tt>lpc reread</command>
3357command is accepted
3358from an ordinary user.</para>
3359
3360</sect1>
3361
3362<sect1 id="restoring"><title>Restoring Original Configuration</title>
3363
3364<para>To restore the original configuration,
3365you simply need to restore the original <filename>printcap</filename>
3366and <filename>lpd.perms</filename> file and then restart the <application>lpd</application> server.
3367These operations require ROOT permissions.
3368<informalexample>
3369<screen><prompt>h4: {96} # </prompt><userinput>su</userinput>
3370<prompt>h4: {97} # </prompt><userinput>cd /etc    OR    cd /usr/local/etc</userinput>
3371<prompt>h4: {98} # </prompt><userinput>mv printcap.orig printcap</userinput>
3372<prompt>h4: {99} # </prompt><userinput>mv lpd.perms.orig lpd.perms</userinput>
3373<prompt>h4: {100} # </prompt><userinput>checkpc -f</userinput>
3374<prompt>h4: {101} # </prompt><userinput>lpc reread</userinput>
3375<prompt>h4: {102} # </prompt><userinput>rm -rf /var/spool/lpd/lp /var/spool/lpd/lp2</userinput>
3376<prompt>h4: {103} # </prompt><userinput>rm -f /tmp/lp /tmp/lp2</userinput></screen>
3377</informalexample>
3378</para>
3379
3380</sect1>
3381
3382<sect1 id="printingandchecking"><title>Printing a File and Checking Status</title>
3383
3384<para>Try the following commands.  The commands appear after the prompt,
3385and sample output that you might see is shown.
3386<informalexample>
3387<screen><prompt>h4: {104} % </prompt><userinput>lpr -V /tmp/hi</userinput>
3388Version LPRng-3.6.14
3389sending job 'papowell@h4+238' to lp@localhost
3390connecting to 'localhost', attempt 1
3391connected to 'localhost'
3392requesting printer lp@localhost
3393sending control file 'cfA238h4.private' to lp@localhost
3394completed sending 'cfA238h4.private' to lp@localhost
3395sending data file 'dfA238h4.private' to lp@localhost
3396completed sending 'dfA238h4.private' to lp@localhost
3397done job 'papowell@h4+238' transfer to lp@localhost</screen>
3398</informalexample>
3399</para>
3400
3401<para>The <command>lpr -V</command> (Verbose) option causes <application/lpr/ to print
3402status output.
3403As you can see from the above lines,
3404it first tries to connect to the <application>lpd</application> server on host
3405<literal remap=tt>localhost</literal>,
3406then sends a print request (which is accepted),
3407then sends a <emphasis>control</emphasis>
3408file
3409containing information about the job
3410and a
3411<emphasis>data</emphasis>
3412file or files which are copies of the files to be
3413printed.</para>
3414
3415<para>If you check the <filename>/tmp/lp</filename> file
3416and you will find that a copy of <filename>/tmp/hi</filename>
3417has been written to it.
3418By default,
3419the <application>lpd</application> print spooler acts as a store and forward system,
3420accepting files to be printed,
3421holding them in the print queue,
3422and then forwarding them to the destination system or output device.</para>
3423
3424<para>You can use the <application>lpq</application> command to view the status of the print job.
3425<informalexample>
3426<screen><prompt>h4: {105} % </prompt><userinput>lpq</userinput>
3427Printer: lp@h4
3428 Queue: no printable jobs in queue
3429 Status: job 'papowell@h4+238' removed at 09:39:03.256</screen>
3430</informalexample>
3431</para>
3432
3433<para>If you want to see more status information,
3434use <command>lpq -l</command>, <command>lpq -ll</command>, or even <command>lpq -L</command>.
3435The <literal>-L</literal> provides
3436al<literal remap=tt>L</literal>
3437the status.
3438<informalexample>
3439<screen><prompt>h4: {106} % </prompt><userinput>lpq -l</userinput>
3440Printer: lp@h4
3441 Queue: no printable jobs in queue
3442 Status: lp@h4.private: job 'papowell@h4+238' printed at 09:39:03.112
3443 Status: job 'papowell@h4+238' removed at 09:39:03.256
3444<prompt>h4: {107} % </prompt><userinput>lpq -ll</userinput>
3445Printer: lp@h4
3446 Queue: no printable jobs in queue
3447 Status: finished 'papowell@h4+238', status 'JSUCC' at 09:39:03.108
3448 Status: subserver pid 8240 exit status 'JSUCC' at 09:39:03.110
3449 Status: lp@h4.private: job 'papowell@h4+238' printed at 09:39:03.112
3450 Status: job 'papowell@h4+238' removed at 09:39:03.256
3451<prompt>h4: {108} % </prompt><userinput>lpq -L</userinput>
3452Printer: lp@h4
3453 Queue: no printable jobs in queue
3454 Status: subserver pid 8240 starting at 09:39:03.105
3455 Status: accounting at start at 09:39:03.105
3456 Status: opening device '/tmp/lp' at 09:39:03.105
3457 Status: printing job 'papowell@h4+238' at 09:39:03.106
3458 Status: no banner at 09:39:03.107
3459 Status: printing data file 'dfA238h4.private', size 3 at 09:39:03.107
3460 Status: printing done 'papowell@h4+238' at 09:39:03.107
3461 Status: accounting at end at 09:39:03.108
3462 Status: finished 'papowell@h4+238', status 'JSUCC' at 09:39:03.108
3463 Status: subserver pid 8240 exit status 'JSUCC' at 09:39:03.110
3464 Status: lp@h4.private: job 'papowell@h4+238' printed at 09:39:03.112
3465 Status: job 'papowell@h4+238' removed at 09:39:03.256</screen>
3466</informalexample>
3467</para>
3468
3469<para>There are different status formats available as well.
3470The <command>lpq -s</command> (summary) produces a single line of status per spool queue,
3471while the <command>lpq -v</command> (verbose)
3472produces output that is very suitable for processing with
3473programs such as
3474<application remap=tt>Perl</application>
3475or
3476<application remap=tt>awk</application>:
3477<informalexample>
3478<screen><prompt>h4: {109} % </prompt><userinput>lpq -s</userinput>
3479lp@h4  0 jobs
3480<prompt>h4: {110} % </prompt><userinput>lpq -v</userinput>
3481Printer: lp@h4
3482 Printing: no
3483 Aborted: no
3484 Spooling: no
3485 Queue: no printable jobs in queue
3486 SPOOLCONTROL=
3487 Status: subserver pid 8240 starting at 09:39:03.105
3488 Status: accounting at start at 09:39:03.105
3489 Status: opening device '/tmp/lp' at 09:39:03.105
3490 Status: printing job 'papowell@h4+238' at 09:39:03.106
3491 Status: no banner at 09:39:03.107
3492 Status: printing data file 'dfA238h4.private', size 3 at 09:39:03.107
3493 Status: printing done 'papowell@h4+238' at 09:39:03.107
3494 Status: accounting at end at 09:39:03.108
3495 Status: finished 'papowell@h4+238', status 'JSUCC' at 09:39:03.108
3496 Status: subserver pid 8240 exit status 'JSUCC' at 09:39:03.110
3497 Status: lp@h4.private: job 'papowell@h4+238' printed at 09:39:03.112
3498 Status: job 'papowell@h4+238' removed at 09:39:03.256</screen>
3499</informalexample>
3500</para>
3501
3502<para>If you check the <filename>/tmp/lp</filename> file
3503and you will find that a copy of <filename>/tmp/hi</filename>
3504has been written to it.
3505By default,
3506the <application>lpd</application> print spooler acts as a store and forward system,
3507accepting files to be printed,
3508holding them in the print queue,
3509and then forwarding them to the destination system or output device.</para>
3510
3511</sect1>
3512
3513<sect1 id="selectingprintqueue"><title>Selecting the Print Queue</title>
3514
3515<para>In the previous section we used the default print queue.
3516How does &LPRng; determine what print queue to use?
3517First,
3518you can explicitly specify the printer using the  <command>lpq -Pprintqueue</command>
3519option
3520and the <command>lpq -a</command> or <command>lpq -Pall</command> to select all print queues:
3521<informalexample>
3522<screen><prompt>h4: {111} % </prompt><userinput>lpq -Plp</userinput>
3523Printer: lp@h4
3524 Queue: no printable jobs in queue
3525<prompt>h4: {112} % </prompt><userinput>lpq -Plp2</userinput>
3526Printer: lp2@h4
3527 Queue: no printable jobs in queue
3528<prompt>h4: {113} % </prompt><userinput>lpq -a</userinput>
3529Printer: lp@h4
3530 Queue: no printable jobs in queue
3531Printer: lp2@h4
3532 Queue: no printable jobs in queue</screen>
3533</informalexample>
3534</para>
3535
3536<para>You can combine the <command>lpq -a</command> with the <command>lpq -s</command> option for a summary listing:
3537<informalexample>
3538<screen><prompt>h4: {114} % </prompt><userinput>lpq -a</userinput>
3539Printer: lp@h4
3540 Queue: no printable jobs in queue
3541Printer: lp2@h4
3542 Queue: no printable jobs in queue
3543<prompt>h4: {115} % </prompt><userinput>lpq -s -a</userinput>
3544lp@h4  0 jobs
3545lp2@h4  0 jobs</screen>
3546</informalexample>
3547</para>
3548
3549<para>There is another way to explicitly specify the printqueues
3550listed by <command>lpq -a</command>;
3551see the
3552
3553<link linkend="allpc"><literal>all</literal> Printcap Entry</link>
3554
3555for details.</para>
3556
3557<para>Users can set their default printer by using the
3558<envar>PRINTER</envar> (highest priority),
3559<envar>LPDEST</envar> (next),
3560<envar>NPRINTER</envar> (next),
3561and
3562<envar>NGPRINTER</envar> (lowest priority),
3563environment variables.
3564For example:
3565<informalexample>
3566<screen><prompt>h4: {116} % </prompt><userinput>setenv PRINTER lp2</userinput>
3567<prompt>h4: {117} % </prompt><userinput>lpq</userinput>
3568Printer: lp2@h4
3569 Queue: no printable jobs in queue
3570<prompt>h4: {118} % </prompt><userinput>unsetenv PRINTER</userinput>
3571<prompt>h4: {119} % </prompt><userinput>lpq</userinput>
3572Printer: lp@h4
3573 Queue: no printable jobs in queue</screen>
3574</informalexample>
3575</para>
3576
3577<para>
3578If the printer is not specified on the command line or by the environment
3579variables,
3580then the first printer in the printcap database will be used
3581and then the default printer in the configuration database,
3582and finally the compile time default.
3583
3584<link linkend="printerinfo">Printer and Server Information</link>
3585
3586for details.</para>
3587
3588</sect1>
3589
3590<sect1 id="controllingprintqueue"><title>Controlling the Print Queue</title>
3591
3592<para>The <application>lpc</application> command is used to examine and control the
3593print server operation.
3594The
3595<command remap=tt>lpc status</command>
3596command displays the administrative status of a print queue.
3597The <application/lpd/ program caches status and job information
3598in order to improve performance.
3599The
3600<command remap=tt>lpc flush</command>
3601command will flush the cached information
3602and cause the server to regenerate it.
3603
3604The
3605<command remap=tt>lpc enable</command>
3606and
3607<command remap=tt>lpc disable</command>
3608commands
3609enable or disable spooling to the print queue,
3610and the
3611
3612<command remap=tt>lpc stop</command>
3613and
3614
3615<command remap=tt>lpc start</command>
3616commands
3617stop and start printing (or transfers) of jobs in the print queue.</para>
3618
3619<para>Let's look at the status displayed when we use these commands:
3620<informalexample>
3621<screen><prompt>h4: {120} % </prompt><userinput>lpc status</userinput>
3622 Printer  Printing Spooling Jobs Server Subserver Redirect Status/(Debug)
3623lp@h4      enabled  enabled    0   none    none
3624<prompt>h4: {121} % </prompt><userinput>lpc status all</userinput>
3625 Printer  Printing Spooling Jobs Server Subserver Redirect Status/(Debug)
3626lp@h4      enabled  enabled    0    none    none
3627lp2@h4     enabled  enabled    0    none    none
3628<prompt>h4: {122} % </prompt><userinput>lpc</userinput>
3629lpc&gt;status
3630 Printer  Printing Spooling Jobs Server Subserver Redirect Status/(Debug)
3631lp@h4      enabled  enabled    0    none    none
3632lpc&gt;status all
3633 Printer  Printing Spooling Jobs Server Subserver Redirect Status/(Debug)
3634lp@h4      enabled  enabled    0    none    none
3635lp2@h4     enabled  enabled    0    none    none
3636lpc&gt;quit
3637</screen>
3638</informalexample>
3639</para>
3640
3641<para>The <application>lpc</application>
3642command can be used in command line or interactive mode as shown above.
3643When used with no parameters it will run in interactive mode,
3644reading one or more commands from its standard input (<acronym/STDIN/).
3645The
3646<command remap=tt>lpc status</command>
3647command shows the administrative status of the select print queue.
3648The
3649<literal remap=tt>all</literal>
3650queue name selects all print queues for display.
3651As shown in the above example,
3652both print queues have printing and spooling enabled
3653and there are no jobs in the print queue.
3654The
3655<emphasis>Server</emphasis>
3656and
3657<emphasis>Subserver</emphasis>
3658information shows if there is a process which is printing jobs,
3659and its helper process that does the actual communication with the printer.</para>
3660
3661<para>It might be puzzling at first why &LPRng; uses two processes for this operation,
3662but the reason is very simple.
3663Many operating system implementations have <emphasis>memory leaks</emphasis>
3664that cause the actual process size to grow as it runs.
3665This is especially true if a large number of databases such as the
3666password,  Domain Name Server, or other system database is consulted
3667frequently with different queries.
3668Since this is usually done quite a lot by the process which deals with the
3669actual printing,
3670the printing process would soon grow very large and then die when it could
3671no longer obtain more memory.
3672The
3673<emphasis>Server</emphasis>
3674process will fork or create a child process
3675<emphasis>Subserver</emphasis>
3676process that is
3677responsible for the printing of a single job.
3678When the job printing has been completed,
3679the
3680<emphasis>Subserver</emphasis>
3681process will exit and the
3682<emphasis>Server</emphasis>
3683process will then create another child until there are no
3684more jobs to be printed.
3685The
3686<emphasis>Redirect</emphasis>
3687and
3688<emphasis>Debug</emphasis>
3689fields will be discussed in later sections.</para>
3690
3691<para>Now let's use the basic spool queue control commands:
3692<informalexample>
3693<screen><prompt>h4: {123} % </prompt><userinput>lpc disable</userinput>
3694Printer: lp@h4
3695lp@h4.private: disabled
3696<prompt>h4: {124} % </prompt><userinput>lpq</userinput>
3697Printer: lp@h4  (spooling disabled)
3698 Queue: no printable jobs in queue
3699<prompt>h4: {125} % </prompt><userinput>lpc enable</userinput>
3700Printer: lp@h4
3701lp@h4.private: enabled
3702<prompt>h4: {126} % </prompt><userinput>lpq</userinput>
3703Printer: lp@h4
3704 Queue: no printable jobs in queue
3705<prompt>h4: {127} % </prompt><userinput>lpc stop</userinput>
3706Printer: lp@h4
3707lp@h4.private: stopped
3708<prompt>h4: {128} % </prompt><userinput>lpq</userinput>
3709Printer: lp@h4  (printing disabled)
3710 Queue: no printable jobs in queue
3711<prompt>h4: {129} % </prompt><userinput>lpc start</userinput>
3712Printer: lp@h4
3713lp@h4.private: started
3714<prompt>h4: {130} % </prompt><userinput>lpq</userinput>
3715Printer: lp@h4
3716 Queue: no printable jobs in queue</screen>
3717</informalexample>
3718</para>
3719
3720<para>As we can see,
3721the <application>lpc</application> command also reports on the status of the print queue.
3722Let's see what happens when we print to a stopped queue:
3723<informalexample>
3724<screen><prompt>h4: {131} % </prompt><userinput>lpc stop</userinput>
3725Printer: lp@h4
3726lp@h4.private: stopped
3727<prompt>h4: {132} % </prompt><userinput>lpr /tmp/hi</userinput>
3728<prompt>h4: {133} % </prompt><userinput>lpr /tmp/hi /tmp/there</userinput>
3729<prompt>h4: {134} % </prompt><userinput>lpq</userinput>
3730Printer: lp@h4  (printing disabled)
3731 Queue: 2 printable jobs
3732 Server: no server active
3733 Rank   Owner/ID               Class Job Files            Size Time
37341      papowell@h4+17920         A 17920 /tmp/hi             3 18:14:22
37352      papowell@h4+17922         A 17922 /tmp/hi,/tmp/there  9 18:14:30
3736<prompt>h4: {135} % </prompt><userinput>lpc status</userinput>
3737 Printer  Printing Spooling Jobs  Server Subserver Redirect Status/(Debug)
3738lp@h4     disabled  enabled    2    none    none</screen>
3739</informalexample>
3740</para>
3741
3742<para>The <application>lpc</application> status shows that we have two jobs spooled.
3743The
3744<emphasis>Rank</emphasis>
3745field shows the order,
3746the <filename>Owner/ID</filename> shows the unique job ID that is assigned to the
3747job
3748and
3749the
3750<emphasis>Class</emphasis>
3751field is the job class (this may be changed with the <command>lpr -C class</command>
3752option).
3753The
3754<emphasis>Job</emphasis>
3755field shows the <emphasis>job number</emphasis>
3756assigned to this job in this
3757particular spool queue.
3758While the <acronym>ID</acronym> value never changes as a job moves through the &LPRng; system,
3759the <emphasis>job number</emphasis>
3760is specific to a particular spool queue and may change
3761if a job is <emphasis>forwarded</emphasis>
3762to another spool queue that has a job with the
3763same job number.
3764The
3765<emphasis>Size</emphasis>
3766field is the total number of printable bytes in the job,
3767and the
3768<emphasis>Time</emphasis>
3769field shows the timestamp associated with the job.</para>
3770
3771<para>Now let's start the print queue and watch what happens.
3772<informalexample>
3773<screen><prompt>h4: {136} % </prompt><userinput>lpc start</userinput>
3774Printer: lp@h4
3775lp@h4.private: started
3776<prompt>h4: {137} % </prompt><userinput>lpq</userinput>
3777Printer: lp@h4
3778 Queue: 2 printable jobs
3779 Server: pid 17928 active
3780 Unspooler: pid 17929 active
3781 Status: opening device '/tmp/lp' at 18:14:43.921
3782 Rank   Owner/ID             Class Job Files            Size Time
3783active papowell@h4+17920       A 17920 /tmp/hi             3 18:14:22
37842      papowell@h4+17922       A 17922 /tmp/hi,/tmp/there  9 18:14:30
3785<prompt>h4: {138} % </prompt><userinput>lpq -ll</userinput>
3786Printer: lp@h4
3787 Queue: 2 printable jobs
3788 Server: pid 17928 active
3789 Unspooler: pid 17929 active
3790 Status: printing job 'papowell@h4+17920' at 18:14:43.921
3791 Status: no banner at 18:14:43.921
3792 Status: printing data file 'dfA017920h4.private', size 57 at 18:14:43.922
3793 Rank   Owner/ID             Class Job Files            Size Time
3794active papowell@h4+17920       A 17920 /tmp/hi             3 18:14:22
37952      papowell@h4+17922       A 17922 /tmp/hi,/tmp/there  9 18:14:30</screen>
3796</informalexample>
3797</para>
3798
3799<para>The
3800<emphasis>Rank</emphasis>
3801value of the first job has been changed to
3802<literal remap=tt>active</literal>
3803and there is new
3804<emphasis>Status</emphasis>
3805information.
3806If we use <command>lpq -ll</command>  we can see the times that the various print operations
3807are carried out,
3808and details of their success or failure.</para>
3809
3810<para>We can also use the <application>lpc</application> command to see the status of a particular job.
3811We can select jobs by the user name, the ID, or the job number.
3812For example:
3813<informalexample>
3814<screen><prompt>h4: {139} % </prompt><userinput>lpc stop</userinput>
3815Printer: lp@h4
3816lp@h4.private: stopped
3817<prompt>h4: {140} % </prompt><userinput>echo hi |lpr</userinput>
3818<prompt>h4: {141} % </prompt><userinput>echo there | lpr</userinput>
3819<prompt>h4: {142} % </prompt><userinput>echo test |lpr</userinput>
3820<prompt>h4: {143} % </prompt><userinput>lpq</userinput>
3821Printer: lp@h4  (printing disabled)
3822 Queue: 3 printable jobs
3823 Server: no server active
3824 Status: job 'papowell@h4+17922' removed at 18:15:13.981
3825 Rank   Owner/ID            Class Job Files           Size Time
38261      papowell@h4+17959      A 17959 (stdin)            3 18:23:24
38272      papowell@h4+17962      A 17962 (stdin)            6 18:23:30
38283      papowell@h4+17970      A 17970 (stdin)            5 18:23:35
3829<prompt>h4: {144} % </prompt><userinput>lpq 17970</userinput>
3830Printer: lp@h4  (printing disabled)
3831 Queue: 3 printable jobs
3832 Server: no server active
3833 Status: job 'papowell@h4+17922' removed at 18:15:13.981
3834 Rank   Owner/ID            Class Job Files           Size Time
38353      papowell@h4+17970      A 17970 (stdin)            5 18:23:35
3836<prompt>h4: {145} % </prompt><userinput>lpq papowell</userinput>
3837Printer: lp@h4  (printing disabled)
3838 Queue: 3 printable jobs
3839 Server: no server active
3840 Status: job 'papowell@h4+17922' removed at 18:15:13.981
3841 Rank   Owner/ID            Class Job Files           Size Time
38421      papowell@h4+17959      A 17959 (stdin)            3 18:23:24
38432      papowell@h4+17962      A 17962 (stdin)            6 18:23:30
38443      papowell@h4+17970      A 17970 (stdin)            5 18:23:35
3845<prompt>h4: {146} % </prompt><userinput>lpq -s 17970</userinput>
3846lp@h4  1 jobs
3847<prompt>h4: {147} % </prompt><userinput>lpq -s papowell</userinput>
3848lp@h4  3 jobs
3849<prompt>h4: {148} % </prompt><userinput>lpq -s nobody</userinput>
3850lp@h4  0 jobs</screen>
3851</informalexample>
3852</para>
3853
3854<para>We use <command>lpq -Pqueuename</command> to select a specific
3855print queue
3856and <command>lpq -a</command> or <command>lpq -Pall</command> to select all queues:
3857<informalexample>
3858<screen><prompt>h4: {149} % </prompt><userinput>lpc -a stop</userinput>
3859Printer: lp@h4
3860lp@h4.private: stopped
3861Printer: lp2@h4
3862lp2@h4.private: stopped
3863<prompt>h4: {150} % </prompt><userinput>lpc -Pall start</userinput>
3864Printer: lp@h4
3865lp@h4.private: started
3866Printer: lp2@h4
3867lp2@h4.private: started</screen>
3868</informalexample>
3869</para>
3870
3871<para>You can use the <application>lpc</application> command in <emphasis>interactive</emphasis>
3872mode:
3873<informalexample>
3874<screen><prompt>h4: {151} % </prompt><userinput>lpc</userinput>
3875lpc&gt;status
3876 Printer  Printing Spooling Jobs  Server Subserver Redirect Status/(Debug)
3877lp@h4      enabled  enabled    3    17990   17993
3878lpc&gt;status all
3879 Printer  Printing Spooling Jobs  Server Subserver Redirect Status/(Debug)
3880lp@h4      enabled  enabled    3    17990   17993
3881lp2@h4     enabled  enabled    3    none    none
3882lpc&gt;stop lp
3883Printer: lp@h4
3884lp@h4.private: stopped
3885lpc&gt;start lp
3886Printer: lp@h4
3887lp@h4.private: started
3888lpc&gt;quit</screen>
3889</informalexample>
3890</para>
3891
3892<para> The
3893
3894<command remap=tt>lpc topq</command>
3895
3896command can be used to put a job (or jobs) at the head of the spool queue.
3897This command is very useful when some job requires priority service.
3898You can select the job by using the job number or the job ID.
3899<informalexample>
3900<screen><prompt>h4: {152} % </prompt><userinput>lpc topq lp 17970</userinput>
3901Printer: lp@h4
3902lp: selected 'papowell@h4+17970'
3903lp@h4.private: started
3904<prompt>h4: {153} % </prompt><userinput>lpq</userinput>
3905Printer: lp@h4
3906 Queue: 3 printable jobs
3907 Server: pid 17999 active
3908 Rank   Owner/ID          Class Job Files      Size Time
3909active papowell@h4+17970    A 17970 (stdin)      5 18:23:35
39101      papowell@h4+17959    A 17959 (stdin)      3 18:23:24
39112      papowell@h4+17962    A 17962 (stdin)      6 18:23:30</screen>
3912</informalexample>
3913</para>
3914
3915</sect1>
3916
3917<sect1 id="jobremoval"><title>Job Removal</title>
3918
3919<para>Occasionally we print a file
3920and then change our mind and want to cancel the job.
3921The <application>lprm</application> command allows us to do this.
3922<informalexample>
3923<screen><prompt>h4: {154} % </prompt><userinput>lpq</userinput>
3924Printer: lp@h4  (printing disabled)
3925 Queue: 3 printable jobs
3926 Server: no server active
3927 Status: job 'papowell@h4+17922' removed at 18:15:13.981
3928 Rank   Owner/ID          Class Job Files      Size Time
39291      papowell@h4+17959    A 17959 (stdin)       3 18:23:24
39302      papowell@h4+17962    A 17962 (stdin)       6 18:23:30
39313      papowell@h4+17970    A 17970 (stdin)       5 18:23:35
3932<prompt>h4: {155} % </prompt><userinput>lprm</userinput>
3933Printer lp@h4:
3934  checking perms 'papowell@h4+17959'
3935  dequeued 'papowell@h4+17959'
3936<prompt>h4: {156} % </prompt><userinput>lpq</userinput>
3937Printer: lp@h4  (printing disabled)
3938 Queue: 2 printable jobs
3939 Server: no server active
3940 Status: job 'papowell@h4+17922' removed at 18:15:13.981
3941 Rank   Owner/ID          Class Job Files      Size Time
39421      papowell@h4+17962    A 17962 (stdin)       6 18:23:30
39432      papowell@h4+17970    A 17970 (stdin)       5 18:23:35
3944<prompt>h4: {157} % </prompt><userinput>lprm 17970</userinput>
3945Printer lp@h4:
3946  checking perms 'papowell@h4+17970'
3947  dequeued 'papowell@h4+17970'
3948<prompt>h4: {158} % </prompt><userinput>lpq</userinput>
3949Printer: lp@h4  (printing disabled)
3950 Queue: 1 printable job
3951 Server: no server active
3952 Status: job 'papowell@h4+17922' removed at 18:15:13.981
3953 Rank   Owner/ID          Class Job Files     Size Time
39541      papowell@h4+17962    A 17962 (stdin)      6 18:23:30</screen>
3955</informalexample>
3956</para>
3957
3958<para>By default,
3959the <application>lprm</application>
3960command removes the first job in the queue that the user has permission to
3961remove.
3962Also,
3963as shown in the example,
3964you can remove a job by specifying the job ID or the job number.
3965If you specify a user name,
3966you remove <literal remap=bf>all</literal>
3967of the user's jobs.
3968This can be dangerous:
3969<informalexample>
3970<screen><prompt>h4: {159} % </prompt><userinput>lpq</userinput>
3971Printer: lp@h4  (printing disabled)
3972 Queue: 3 printable jobs
3973 Server: no server active
3974 Status: job 'papowell@h4+17922' removed at 18:15:13.981
3975 Rank   Owner/ID          Class Job Files     Size Time
39761      papowell@h4+17962    A 17962 (stdin)      6 18:23:30
39772      papowell@h4+18499    A 18499 /tmp/hi      3 18:56:00
39783      papowell@h4+18501    A 18501 /tmp/there   6 18:56:02
3979<prompt>h4: {160} % </prompt><userinput>lprm papowell</userinput>
3980Printer lp@h4:
3981  checking perms 'papowell@h4+17962'
3982  dequeued 'papowell@h4+17962'
3983  checking perms 'papowell@h4+18499'
3984  dequeued 'papowell@h4+18499'
3985  checking perms 'papowell@h4+18501'
3986  dequeued 'papowell@h4+18501'
3987<prompt>h4: {161} % </prompt><userinput>lpq</userinput>
3988Printer: lp@h4  (printing disabled)
3989 Queue: no printable jobs in queue
3990 Status: job 'papowell@h4+17922' removed at 18:15:13.981</screen>
3991</informalexample>
3992</para>
3993
3994<para>The special user
3995<literal remap=tt>all</literal>
3996matches all jobs in a print queue.
3997Clearly you should be careful not to specify
3998<command remap=tt>lprm all</command>
3999by accident.
4000Even more dangerous is the following command:
4001<informalexample>
4002<screen><prompt>h4: {162} % </prompt><userinput>lprm -a all</userinput></screen>
4003</informalexample>
4004</para>
4005
4006<para>As you might surmise,
4007this removes <literal remap=bf>all</literal>
4008print jobs in <literal remap=bf>all</literal>
4009queues,
4010which is an excellent way to purge print queues of all jobs.</para>
4011
4012</sect1>
4013
4014<sect1 id="printjobfilters"><title>Print Job Filters</title>
4015
4016<para>A printer usually understands one or more
4017<emphasis>Print Job Languages</emphasis>.
4018Files sent to this printer must be in one of these languages
4019and have the appropriate
4020<emphasis>job format</emphasis>.
4021The most common Print Job Languages are
4022
4023<link linkend="postscript">PostScript</link>
4024
4025and
4026
4027<link linkend="pcl">PCL</link>.
4028
4029Text files are PCL with no special PCL control sequences.
4030</para>
4031
4032<para>In order for a printer to reliably print a job
4033it needs to be reset to a known configuration and then
4034at the end of job having it flush all of the output to the
4035printing device.
4036This is done by sending it
4037<emphasis>start of job</emphasis>
4038and
4039<emphasis>end of job</emphasis>
4040commands.
4041These commands differ from printer to printer
4042and depend on the print job language as well.
4043Some <emphasis>vintage</emphasis>
4044line printers also have a set of
4045proprietary <emphasis>escape sequences</emphasis>
4046that are used to set up margins,
4047form size,
4048and other printing characteristics.
4049Usually a
4050<emphasis>setup string</emphasis>
4051with these escape sequences must be sent to the printer before
4052a file can be printed.</para>
4053
4054<para>
4055When sending a job to the printer the print spooler will first
4056process the job using a <emphasis/print job filter/ or
4057<emphasis/filter/ program.
4058This program reads the job file and then produces output
4059in the format required for the printer.
4060</para>
4061
4062<para>
4063When a print job is created the files in the print job are assigned
4064a <emphasis/format/.
4065This format was meant as a guide to the print spooler and was to be
4066used to select the filter program for the files in the job.
4067The format was a lower case letter;
4068the <literal remap=tt>f</literal>
4069is the de<literal remap=tt>f</literal>ault format
4070and indicates normal processing
4071and the
4072<literal remap=tt>l</literal>
4073format indicates a
4074literal or binary file.
4075Job files that are flagged as having
4076literal or binary format
4077are usually passed directly to the printer
4078or have at the most a minimal amount of processing.
4079See
4080
4081<link linkend="printjobformats">Print Job Formats</link>
4082
4083for more information about formats and their use with filters.</para>
4084
4085<para>
4086There are two ways to specify filters:  the default <literal/:filter=.../
4087option and the more specific <literal/Xf=.../ option.
4088The <literal/X/ is a lower case letter corresponding to a format.
4089Here is a sample printcap entry with a filter specification:
4090<informalexample>
4091<screen>lp:sd=/var/spool/lpd/%P
4092  :filter=/usr/local/lib/filters/ifhp
4093  :rf=/usr/local/lib/filters/rfilter
4094</screen>
4095</informalexample>
4096All jobs with formats other than <literal/r/ will be processed using the
4097<literal/ifhp/ program
4098while the jobs with the <literal/r/ format will be processed using the
4099<literal/rfilter/ program.
4100</para>
4101
4102<para>We will set up a very simple filter and use it to demonstrate
4103how filtering is done by the <application/lpd/ print spooler.
4104First,
4105set up the <filename>/tmp/testf</filename> file as shown below.
4106<informalexample>
4107<screen>#!/bin/sh
4108# /tmp/testf - test filter for LPRng
4109PATH=/bin:/usr/bin; export PATH
4110echo TESTF $0 "$@" &gt;&amp;2
4111echo TESTF $0 "$@"
4112echo ENV
4113set
4114echo LEADER
4115/bin/cat
4116echo TRAILER
4117exit 0</screen>
4118</informalexample>
4119</para>
4120
4121<para>Let us carefully examine the script line by line.
4122The first couple of lines are <emphasis/boilerplate/.
4123You should
4124<emphasis/always/
4125set the <envar/PATH/
4126value in a filter script or use full pathnames for executable programs.
4127This is a good practice
4128as it ensures that only the specified directories will be
4129searched for commands.</para>
4130
4131<para>The next lines echo the command line
4132arguments to file descriptor 2 (<acronym/STDERR/) and to <acronym/STDOUT/.
4133We will soon see how this information is displayed by the &LPRng; software.
4134We then use the
4135<command remap=tt>set</command>
4136command to list the shell variables to
4137<acronym/STDOUT/,
4138print <acronym>LEADER</acronym> to <acronym/STDOUT/,
4139copy <acronym/STDIN/ to <acronym/STDOUT/,
4140and print <acronym>TRAILER</acronym> to <acronym/STDOUT/.
4141We exit with a zero result code.</para>
4142
4143<para>We can test our script, with the results shown below:
4144<informalexample>
4145<screen><prompt>h4: {163} % </prompt><userinput>chmod 755 /tmp/testf</userinput>
4146<prompt>h4: {164} % </prompt><userinput>echo hi |/tmp/testf -a1</userinput>
4147TESTF /tmp/testf -a1
4148TESTF /tmp/testf -a1
4149ENV
4150USER=papowell
4151HOSTNAME=h4
4152...
4153PATH=/bin:/usr/bin
4154LEADER
4155hi
4156TRAILER</screen>
4157</informalexample>
4158</para>
4159
4160<para>Let's now use this filter.
4161Edit the
4162<literal remap=tt>lp</literal>
4163printcap entry so it has contents indicated below,
4164use <command>checkpc -f</command> to check the printcap,
4165and then use
4166<command remap=tt>lpc reread</command>
4167to restart the <application>lpd</application> server.
4168<informalexample>
4169<screen>lp:sd=/var/spool/lpd/%P
4170  :force_localhost
4171  :lp=/tmp/lp
4172  :filter=/tmp/testf</screen>
4173</informalexample>
4174</para>
4175
4176<para>Execute the following commands
4177to print the <filename>/tmp/hi</filename> file
4178and observe the results:
4179<informalexample>
4180<screen><prompt>h4: {165} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
4181<prompt>h4: {166} % </prompt><userinput>lpr /tmp/hi</userinput>
4182<prompt>h4: {167} % </prompt><userinput>lpq -llll</userinput>
4183Printer: lp@h4
4184 Queue: no printable jobs in queue
4185 Status: lp@h4.private: job 'papowell@h4+26593' printed at 21:37:21.312
4186 Status: job 'papowell@h4+26593' removed at 21:37:21.323
4187 Status: subserver pid 26683 starting at 21:39:21.908
4188 Status: accounting at start at 21:39:21.908
4189 Status: opening device '/tmp/lp' at 21:39:21.909
4190 Status: printing job 'papowell@h4+26681' at 21:39:21.909
4191 Status: no banner at 21:39:21.909
4192 Status: printing data file 'dfA026681h4.private', size 3, \
4193    IF filter 'testf' at 21:39:21.909
4194 Status: IF filter msg - 'TESTF /tmp/testf -Apapowell@h4+26681 \
4195     -CA -D2000-04 -11-21:39:21.877 -Ff -Hh4.private -J/tmp/hi \
4196      -Lpapowell -Plp -Qlp -aacct -b3 -d/var/tmp/LPD/lp \
4197      -edfA026681h4.private -f/tmp/hi -hh4.private -j026681 \
4198      -kcfA026681h4.private -l66 -npapowell -sstatus \
4199      -t2000-04-11-21:39:21.000 -w80 -x0 -y0 acct' \
4200       at 21:39:21.914
4201 Status: IF filter finished at 21:39:22.070
4202 Status: printing done 'papowell@h4+26681' at 21:39:22.070
4203 Status: accounting at end at 21:39:22.070
4204 Status: finished 'papowell@h4+26681', status 'JSUCC' at 21:39:22.070
4205 Status: subserver pid 26683 exit status 'JSUCC' at 21:39:22.072
4206 Status: lp@h4.private: job 'papowell@h4+26681' printed at 21:39:22.072
4207 Status: job 'papowell@h4+26681' removed at 21:39:22.085
4208<prompt>h4: {168} % </prompt><userinput>more /tmp/lp</userinput>
4209TESTF /tmp/testf -Apapowell@h4+26681 -CA -D2000-04-11-21:39:21.877 \
4210 -Ff -Hh4.private -J/tmp/hi -Lpapowell -Plp -Qlp -aacct -b3 \
4211 -d/var/tmp/LPD/lp -edfA026681h4.private -f/tmp/hi -hh4.private \
4212 -j026681 -kcfA026681h4.private -l66 -npapowell -sstatus \
4213 -t2000-04-11-21:39:21.000 -w80 -x0 -y0 acct
4214ENV
4215USER=papowell
4216LD_LIBRARY_PATH=/lib:/usr/lib:/usr/5lib:/usr/ucblib
4217HOME=/home/papowell
4218PRINTCAP_ENTRY=lp
4219 :force_localhost
4220 :filter=/tmp/testf
4221 :lp=/var/tmp/lp
4222 :sd=/var/tmp/LPD/lp
4223
4224PS1=$
4225OPTIND=1
4226PS2=&gt;
4227SPOOL_DIR=/var/tmp/LPD/lp
4228LOGNAME=papowell
4229
4230CONTROL=Hh4.private
4231 Ppapowell
4232 J/tmp/hi
4233 CA
4234 Lpapowell
4235 Apapowell@h4+15850
4236 D2000-04-26-18:13:55.505
4237 Qlp
4238 N/tmp/hi
4239 fdfA015850h4.private
4240 UdfA015850h4.private
4241
4242PATH=/bin:/usr/bin
4243SHELL=/bin/sh
4244LOGDIR=/home/papowell
4245IFS=
4246PRINTER=lp
4247LEADER
4248test Test
4249TRAILER</screen>
4250</informalexample>
4251</para>
4252
4253<para>The
4254<command remap=tt>cp</command>
4255command clears out the <filename>/tmp/lp</filename>
4256file we are using as a dummy output device.
4257The <command>lpr</command> command prints the <filename>/tmp/hi</filename> file
4258and the <command>lpq -llll</command> command shows the status information.
4259The status information now contains
4260the line that the
4261<command remap=tt>testf</command>
4262script wrote to <acronym/STDERR/.
4263The <application>lpd</application> server captures filter <acronym/STDERR/
4264messages and puts it them in the spool queue status file.</para>
4265
4266<para>As we see from the lpq status,
4267<application>lpd</application>
4268passes a large number of command line options to our filter.
4269These options and their meanings are discussed in detail in
4270
4271<link linkend="filteroptions">Filter Command Line Options and Environment Variables</link>.
4272We will discuss these in more detail in the next section.</para>
4273
4274<para>If we look at the <filename>/tmp/lp</filename> file,
4275we see the command line options and
4276values of the shell variables.
4277For a full discussion of the environment variables passed to a
4278filter see
4279
4280<link linkend="filteroptions">Filter Command Line Options and Environment Variables</link>.
4281The more interesting environment variables include the
4282<envar>PRINTCAP_ENTRY</envar>
4283variable,
4284which is a copy of the printcap entry for this printer,
4285and the <envar>CONTROL</envar> variable,
4286which is a copy of the control file for the the print job.</para>
4287
4288<sect2 id="controlfiles"><title>Control Files and Filter Options</title>
4289
4290<para>
4291When you submit a print job the <application/lpd/ print spooler
4292stores it in the spool queue as two or more files:
4293a <emphasis>control</emphasis>
4294file that contains information about
4295the job and the <emphasis>data</emphasis>
4296files that contain the information to be printed.
4297Here is sample control file:
4298<informalexample>
4299<screen>Hh4.private
4300Ppapowell
4301J/tmp/hi
4302CA
4303Lpapowell
4304Apapowell@h4+15850
4305D2000-04-26-18:13:55.505
4306Qlp
4307N/tmp/hi
4308fdfA015850h4.private
4309UdfA015850h4.private</screen>
4310</informalexample>
4311</para>
4312
4313<para>Lines starting with upper case letters contain
4314job information such as the user who submitted the job.
4315Lines starting with lower case letters indicate the data file
4316to be printed and the corresponding format.
4317For full details about the exact format of the control file
4318see
4319<link linkend="jobfiles">Job Files</link>.
4320</para>
4321<para><xref linkend=filteroptionstable> shows the correspondence
4322between lines in the control file and <application/lpr/ command line options.
4323The <literal/N/ values are the names of the files that are printed.
4324The <literal remap=tt>U</literal> indicates a data file
4325is in a job and is present to meet RCF1179 and
4326<emphasis>vintage</emphasis>
4327print spooler requirements.</para>
4328
4329<table frame=all id=filteroptionstable><title>Filter Options</title>
4330<tgroup cols=3 colsep=1 rowsep=1 align=left>
4331<thead>
4332<row><entry>Control File </entry><entry> Filter Option </entry><entry> Purpose or Value </entry></row>
4333</thead>
4334<tbody>
4335<row><entry></entry><entry> <literal>-P</literal><emphasis>Printer</emphasis>
4336</entry><entry> Print queue name - printcap information </entry></row>
4337<row><entry><emphasis>H</emphasis>
4338</entry><entry> <literal>-H</literal><emphasis>Host</emphasis>
4339</entry><entry> Host Name </entry></row>
4340<row><entry><literal remap=tt>P</literal>
4341</entry><entry> <literal>-n</literal><emphasis>User</emphasis>
4342</entry><entry> User Login Name of job originator </entry></row>
4343<row><entry><literal remap=tt>J</literal>
4344</entry><entry> <literal>-J</literal><emphasis>Job name</emphasis>
4345</entry><entry> lpr -J option or file name </entry></row>
4346<row><entry><literal remap=tt>C</literal>
4347</entry><entry> <literal>-C</literal><emphasis>Class</emphasis>
4348</entry><entry> Print class (lpr -C option) </entry></row>
4349<row><entry><literal remap=tt>L</literal>
4350</entry><entry> <literal>-L</literal><emphasis>Banner</emphasis>
4351</entry><entry> Banner page request</entry></row>
4352<row><entry><literal remap=tt>A</literal>
4353</entry><entry> <literal>-A</literal><emphasis>Jobid</emphasis>
4354</entry><entry> Job Id </entry></row>
4355<row><entry><literal remap=tt>D</literal>
4356</entry><entry> <literal>-D</literal><emphasis>Date</emphasis>
4357</entry><entry> Date or time information </entry></row>
4358<row><entry><literal remap=tt>Q</literal>
4359</entry><entry> <literal>-Q</literal><emphasis>Queue</emphasis>
4360</entry><entry> Original Print queue job was sent to </entry></row>
4361<row><entry><literal remap=tt>N</literal>
4362</entry><entry> <literal>-N</literal><emphasis>Filename</emphasis>
4363</entry><entry> Filename </entry></row>
4364<row><entry><literal remap=tt>f,l,p,...</literal>
4365</entry><entry> <literal>-F</literal><emphasis>f</emphasis>
4366</entry><entry>Datafile format </entry></row>
4367<row><entry><literal remap=tt>U</literal>
4368</entry><entry>
4369</entry><entry>Datafile (historical)</entry></row>
4370</tbody>
4371</tgroup>
4372</table>
4373
4374<para>
4375When a print filter processes these jobs the values in the control
4376file are passed on the command line as options starting with
4377upper case letters:
4378<informalexample>
4379<screen>/tmp/testf -Apapowell@h4+26681 -CA \
4380   -D2000-04-11-21:39:21.877 -Ff -Hh4.private ....
4381</screen>
4382</informalexample>
4383
4384Sometimes we want to pass only a small subset of these command line options
4385to a filter or provide them in a specific order in order to be compatible
4386with
4387<emphasis>legacy</emphasis>
4388print filters.
4389&LPRng; provides several different ways to do this
4390and we will explore how to control command line options.</para>
4391
4392<para>If the filter entry starts with <literal>-$</literal>,
4393this suppresses the automatic addition of command line options;
4394we can then add our own options to the command line.
4395Modify the printcap entry to have the following form:
4396<informalexample>
4397<screen>lp:sd=/var/spool/lpd/%P
4398  :force_localhost
4399  :lp=/tmp/lp
4400  :filter= -$ /tmp/testf '$P' $0P -X$-P ${lp} G\072 or \:</screen>
4401</informalexample>
4402</para>
4403
4404<para>Lets print our <filename>/tmp/hi</filename> test file and then look at
4405the <application>lpq</application> status:
4406<informalexample>
4407<screen><prompt>h4: {169} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
4408<prompt>h4: {170} % </prompt><userinput>lpr /tmp/hi</userinput>
4409<prompt>h4: {171} % </prompt><userinput>lpq -llll</userinput>
4410Printer: lp@h4
4411 ....
4412 Status: IF filter msg - 'TESTF /tmp/testf -Plp -P lp -Xlp \
4413    -Ylp /tmp/lp G: or :' at 01:20:21.560</screen>
4414</informalexample>
4415</para>
4416
4417<para>The <literal>-$</literal> suppresses the adding the default literals to the
4418filter command line.
4419You can pass specific options using
4420<literal remap=tt>$X</literal>;
4421if the option has a non-null value then it will be expanded in the following
4422format:
4423<informalexample>
4424<screen>Option    Value Expansion
4425$X        -X&lt;value&gt;
4426$'X       -X'&lt;value&gt;'
4427$0X       -X '&lt;value&gt;'
4428$-X       &lt;value&gt;
4429$'-X      '&lt;value&gt;'
4430${X}      control file X option value
4431$'{X}     control file X option value (in quotes)
4432${name}   printcap option value if value nonzero length
4433$'{name}  printcap option value if value nonzero length in quotes
4434\nnn      single printable character
4435$*        all options in control file expanded using $X</screen>
4436</informalexample>
4437</para>
4438
4439<para>Command line options can be grouped and passed as a single argument
4440by enclosing them in single or double quotes.
4441You should be aware that &LPRng; has an
4442<emphasis>extremely</emphasis>
4443primitive
4444way of handling quotes.
4445When the
4446<command remap=tt>/bin/sh -c</command>
4447parameter is not used,
4448the the command line is broken on spaces and each unit
4449is passed as an individual argument.
4450If the first character after a space is a quote (single or double),
4451the next quote is found,
4452and then entire element is then used as a single parameter.
4453Substitution of
4454<literal remap=tt>$X</literal>
4455parameters is then done.
4456As a special case,
4457when you have a
4458<literal remap=tt>$0X</literal>,
4459this causes a split and all of the string previous and including the <literal>-X</literal>
4460flag is passed as a single option and all of the option value and following
4461are passed as another option.
4462If the result of the expansion is a zero length parameter then it is
4463removed from the parameter list.
4464When the
4465<command remap=tt>/bin/sh -c</command>
4466is used
4467the command line is not broken,
4468and all non-empty option values are enclosed in single quotes.</para>
4469
4470<para>The
4471<literal remap=tt>${name}</literal>
4472option is used to pass a printcap option value.
4473For example,
4474you can pass the value of the printcap option
4475<literal remap=tt>form</literal>
4476as shown
4477below.
4478You can experiment with this by using the <filename>/tmp/testf</filename>
4479filter and printcap shown below.
4480<informalexample>
4481<screen>printcap:
4482lp:sd=/var/spool/lpd/%P
4483  :force_localhost
4484  :lp=/tmp/lp
4485  :filter=/tmp/testf -F ${form}
4486  :form=payroll
4487
4488<prompt>h4: {172} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
4489<prompt>h4: {173} % </prompt><userinput>lpr /tmp/hi</userinput>
4490<prompt>h4: {174} % </prompt><userinput>lpq -llll</userinput>
4491Printer: lp@h4
4492 ...
4493 Status: IF filter msg - 'TESTF /tmp/testf -F payroll' at 09:55:31.276
4494 ...</screen>
4495</informalexample>
4496</para>
4497
4498<para>If we have a
4499<emphasis>legacy</emphasis>
4500print filter that was originally written
4501for the <acronym>BSD</acronym> print spooler,
4502then we may find that it requires a small number of command line options in
4503a very specific order.
4504We can use the
4505<literal remap=tt>:bkf</literal>
4506(BSD Kompatible Filter or BacKwards compatible Filter)
4507flag to pass suitable options.
4508Modify the printcap entry to have the following form:
4509<informalexample>
4510<screen>lp:sd=/var/spool/lpd/%P
4511  :force_localhost
4512  :lp=/tmp/lp
4513  :filter=/tmp/testf
4514  :bk</screen>
4515</informalexample>
4516</para>
4517
4518<para>Lets print our <filename>/tmp/hi</filename> test file and then look at
4519the <application>lpq</application> status:
4520<informalexample>
4521<screen><prompt>h4: {175} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
4522<prompt>h4: {176} % </prompt><userinput>lpr /tmp/hi</userinput>
4523<prompt>h4: {177} % </prompt><userinput>lpq -llll</userinput>
4524Printer: lp@h4
4525 ....
4526 Status: IF filter msg - 'TESTF /tmp/testf -Plp -w80 -l66 \
4527    -x0 -y0 -Ff -Lpapowell -J/tmp/hi -CA -n papowell \
4528    -h h4.private acct' at 08:07:46.583</screen>
4529</informalexample>
4530</para>
4531
4532<para>Finally,
4533there are times when we would like the print filter to be
4534a simple shell command or to chain several programs together
4535in a simple pipeline.
4536While this is possible using a print filter,
4537you can also do this in the filter specification.
4538If your filter specification starts with a
4539parenthesis (<literal remap=tt>(</literal>)
4540or contains the IO redirection for
4541pipeto (<literal remap=tt>|</literal>),
4542input redirection (<literal remap=tt>&lt;</literal>),
4543or
4544output redirection (<literal>&gt;</literal>)
4545then the <application>lpd</application> server will use the
4546<literal remap=tt>:shell</literal>
4547configuration option value (default <filename>/bin/sh</filename>)
4548and execute it using:
4549<informalexample>
4550<screen>${shell} -c "( ${if} )"</screen>
4551</informalexample>
4552</para>
4553<para>If this is done,
4554then no command line options are added to the command.
4555However,
4556expansion of
4557<literal remap=tt>$X</literal>
4558parameters are still done.
4559Modify the printcap entry to have the following form:
4560<informalexample>
4561<screen>lp:sd=/var/spool/lpd/%P
4562  :force_localhost
4563  :lp=/tmp/lp
4564  :filter=(echo "PREAMBLE"; /tmp/testf; echo "APPENDIX")</screen>
4565</informalexample>
4566</para>
4567
4568<para>Lets print our <filename>/tmp/hi</filename> test file and then look at
4569the <application>lpq</application> status:
4570<informalexample>
4571<screen><prompt>h4: {178} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
4572<prompt>h4: {179} % </prompt><userinput>lpr /tmp/hi</userinput>
4573<prompt>h4: {180} % </prompt><userinput>lpq -llll</userinput>
4574Printer: lp@h4
4575 ....
4576 Status: printing data file 'dfA018881h4.private', size 3, \
4577   IF filter 'echo' at 09:22:11.476
4578 Status: IF filter msg - 'TESTF /tmp/testf' at 09:22:11.510
4579 Status: IF filter finished at 09:22:11.514</screen>
4580</informalexample>
4581</para>
4582
4583<para>If we examine the <filename>/tmp/lp</filename> file we find:
4584<informalexample>
4585<screen>PREAMBLE
4586TESTF /tmp/testf
4587ENV
4588USER=papowell
4589LD_LIBRARY_PATH=/lib:/usr/lib:/usr/5lib:/usr/ucblib
4590...
4591PRINTER=lp
4592LEADER
4593hi
4594TRAILER
4595APPENDIX</screen>
4596</informalexample>
4597</para>
4598
4599<para>As we expected, no options were passed on the command line.
4600If the printcap is modified to have the following contents,
4601then you will see:
4602<informalexample>
4603<screen>lp:sd=/var/spool/lpd/%P
4604  :force_localhost
4605  :lp=/tmp/lp
4606  :filter=(echo "PREAMBLE"; /tmp/testf $*; echo "APPENDIX")
4607
4608<prompt>h4: {181} % </prompt><userinput>lpr /tmp/hi</userinput>
4609<prompt>h4: {182} % </prompt><userinput>lpq -llll</userinput>
4610Printer: lp@h4
4611 ....
4612 Status: IF filter msg - 'TESTF /tmp/testf -Apapowell@h4+18941 \
4613   -CA -D2000-04-29-09:27:30.700 -Ff -Hh4.private -J/tmp/hi \
4614   -Lpapowell -Plp -Qlp -aacct -b3 -d/var/tmp/LPD/lp \
4615   -edfA018941h4.private -f/tmp/hi -hh4.private -j018941 \
4616   -kcfA018941h4.private -l66 -npapowell -sstatus \
4617   -t2000-04-29-09:27:30.864 -w80 -x0 -y0 acct' at 09:27:30.879</screen>
4618</informalexample>
4619</para>
4620
4621<para>Using the shell invocation is especially useful when you may have a parameter
4622that has an empty string value,
4623and need to pass this as a command line parameter.
4624Modify the <filename>/tmp/testf</filename> filter,
4625the printcap, and execute the following commands:
4626<informalexample>
4627<screen>printcap:
4628  lp:sd=/var/spool/lpd/%P
4629    :force_localhost
4630    :lp=/tmp/lp
4631    :filter=( /tmp/testf -F '${form}' )
4632    :form=
4633
4634#!/bin/sh
4635# /tmp/testf - test filter for LPRng
4636PATH=/bin:/usr/bin; export PATH
4637echo TESTF $0 "$@" &gt;&amp;2
4638echo TESTF $0 "$@"
4639while test $# -gt 0 ; do
4640  echo "PARM '$1'";
4641  shift;
4642done
4643echo LEADER
4644/bin/cat
4645echo TRAILER
4646exit 0
4647
4648<prompt>h4: {183} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
4649<prompt>h4: {184} % </prompt><userinput>lpr /tmp/hi</userinput>
4650<prompt>h4: {185} % </prompt><userinput>lpq -llll</userinput>
4651Printer: lp@h4
4652 ...
4653 Status: IF filter msg - 'TESTF /tmp/testf -F' at 09:59:27.365
4654
4655<prompt>h4: {186} % </prompt><userinput>more /tmp/lp</userinput>
4656TESTF /tmp/testf -F
4657PARM '-F'
4658PARM ''
4659LEADER
4660hi
4661TRAILER</screen>
4662</informalexample>
4663</para>
4664
4665<para>As you can see,
4666there are <emphasis/empty/ parameters passed to the filter.
4667This is due to the combination of the
4668<literal remap=tt>$'{form}</literal>
4669and using the <literal>:filter=(...)</literal>
4670form.</para>
4671
4672</sect2>
4673
4674<sect2 id="filterenvironmentvars"><title>Filter Environment Variables</title>
4675
4676<para>In this section we will look further at the environment variables
4677passed to the filter.
4678We printed the shell variable values for the filter at the start
4679of the file:
4680<informalexample>
4681<screen><prompt>h4: {187} % </prompt><userinput>cat /tmp/lp</userinput>
4682/tmp/testf -Plp -P lp -Xlp -Ylp /tmp/lp G:' at 01:20:21.560
4683ENV
4684CONTROL=Hh4.private
4685 Ppapowell
4686 J/tmp/hi
4687 CA
4688 Lpapowell
4689 Apapowell@h4+105
4690 D2000-04-12-15:27:26.662
4691 Qlp
4692 N/tmp/hi
4693 fdfA105h4.private
4694 UdfA105h4.private
4695HOME=/home/daemon
4696LD_LIBRARY_PATH=/lib:/usr/lib:/usr/5lib:/usr/ucblib
4697LOGDIR=/home/daemon
4698LOGNAME=daemon
4699OPTIND=1
4700PATH=/bin:/usr/bin:/usr/local/bin
4701PRINTCAP_ENTRY=lp
4702 :force_localhost
4703 :filter=/tmp/testf
4704 :lp=/tmp/lp
4705 :sd=/tmp/LPD/lp
4706PRINTER=lp
4707PS1=$
4708PS2=&gt;
4709SHELL=/bin/sh
4710SPOOL_DIR=/tmp/LPD/lp
4711USER=daemon
4712
4713LEADER
4714hi
4715TRAILER</screen>
4716</informalexample>
4717</para>
4718
4719<para>The <envar>HOME</envar>,
4720<envar>USER</envar>,
4721<envar>SHELL</envar>,
4722<envar remap=tt>PS1</envar>,
4723and
4724<envar remap=tt>PS2</envar>
4725variables are usually set by the shell,
4726and are reflect the information for the <acronym>UID</acronym> of the user
4727running the shell.</para>
4728
4729<para>The
4730<envar>PATH</envar>
4731and
4732<literal>LP_LIBRARY_PATH</literal>
4733are set by the <application>lpd</application> server to values specified in the
4734printcap or configuration information.
4735It is recommended that users set these to site specific values
4736if the defaults are not suitable for their sites.</para>
4737
4738<para>The <application>lpd</application> server sets the
4739<literal/PRINTER/,
4740<literal/PRINTCAP_ENTRY/,
4741and
4742<literal/CONTROL/
4743environment variables to the printer name,
4744printcap entry, and control file for the print job.
4745This information is very useful to filters that must
4746make decisions based on values passed to the print server
4747in the control file
4748and which use parameters in the printcap entry
4749to control their actions.</para>
4750
4751</sect2>
4752
4753<sect2 id="usingcommandlineandprintcap"><title>Using Command Line and Printcap Options In Filters</title>
4754
4755<para>One of the problems commonly encountered problem
4756in writing a filter is getting the command line values.
4757The UNIX POSIX Standard provides a C Language
4758<function remap=tt>getopt</function>
4759function that can be used for command line options,
4760and some, but not all shell implementations have a corresponding
4761shell
4762<function remap=tt>getopt</function>
4763function.
4764Also,
4765many times it would be useful to get the values of the printcap
4766options.
4767These could be used to specify options or operations that are
4768not easily done by passing command lines.
4769<itemizedlist>
4770
4771<listitem>
4772<para>Observe that all the command line options are single letters.
4773If we set the shell variables to the corresponding option value,
4774then we could access them by using
4775<literal remap=tt>$x</literal>, where
4776<literal remap=tt>x</literal>
4777is the option letter.
4778There is an exception to this rule,
4779which is the <literal>-c</literal> command line literal,
4780which for various historical and compatibility reasons does not take a value.
4781But if it is present,
4782we might as well assign it the value
4783<literal remap=tt>1</literal>.</para>
4784</listitem>
4785
4786<listitem>
4787<para>Observe that by convention all printcap options have
4788lowercase names of two or more letters,
4789and that all environment variables have all upper case letters.
4790If we set shell variables with the corresponding printcap entry values,
4791then we can access them using
4792<literal remap=tt>$literal</literal>.
4793If we need to create a local shell variable for use,
4794we can use <literal>mIxEd</literal>
4795case and not have a conflict.</para>
4796</listitem>
4797
4798</itemizedlist>
4799</para>
4800
4801<para>The <literal>decode_args_with_sh</literal>
4802script which is in the <acronym>UTILS</acronym> directory of the &LPRng; distribution
4803follows these conventions and sets the appropriate shell variables.
4804We have also include a bit of code that will extract the
4805control file control line values and put them into variables
4806as well.</para>
4807
4808<para>Save the current <filename>/tmp/testf</filename> filter file in
4809<filename>/tmp/testf.old</filename>
4810and replace it with the following:
4811<informalexample>
4812<screen>#!/bin/sh
4813# this is an example of how to use /bin/sh and LPRng
4814# to get the command line and printcap option values
4815# and set shell variables from them
4816#  Note that we use a couple of variables
4817#PATH=/bin:/usr/bin
4818Args=""
4819vAr=""
4820vAlue=""
4821vAls=""
4822iI=""
4823Tf=""
4824Debug=1
4825if -n $Debug ; then
4826    set &gt;/tmp/before
4827fi
4828Args="$@"
4829if -n $Debug ; then
4830    echo "$@" &gt;&gt;/tmp/before
4831fi
4832while expr "$1" : '-.*' &gt;/dev/null ; do
4833  vAr=`expr "$1" : '-\(.\).*'`;
4834  vAlue=`expr "$1" : '-.\(.*\)`;
4835  case "$vAr" in
4836    - ) break;;
4837    c ) c=1;;
4838    [a-zA-Z] )
4839      if test "X$vAlue" = "X" ; then shift; vAlue=$1; fi;
4840      eval $vAr='$vAlue';
4841      #setvar $vAr "$vAlue"
4842      ;;
4843  esac;
4844  shift;
4845done
4846
4847# set shell variables to the printcap options
4848#  flag   -&gt;  flag=1
4849#  flag@  -&gt;  flag=0
4850#  option=value -&gt;  option='value'
4851#
4852setpcvals () {
4853    while test "$#" -gt 0 ; do
4854      iI=$1
4855      if expr "$iI" : " *\:" &gt;/dev/null ; then
4856        vAr=`expr "$iI" : " *\:\([^=][^=]*\)=.*"`;
4857        vAlue=`expr "$iI" : " *\:[^=][^=]*=\(.*\)"`;
4858        if test "X$vAr" = "X" ; then
4859          vAr=`expr "$iI" : " *:\(.*\)@"`;
4860          vAlue=0;
4861        fi
4862        if test "X$vAr" = "X" ; then
4863          vAr=`expr "$iI" : " *:\(.*\)"`;
4864          vAlue=1;
4865        fi
4866        if test "X$vAr" != "X" ; then
4867          eval $vAr='$vAlue';
4868          #setvar $vAr "$vAlue"
4869        fi
4870      else
4871        vAr=`expr "$iI" : " *\([^|][^|]*\).*"`;
4872        if test "X$vAr" != "X" ; then
4873          eval Printer="$vAr"
4874        fi
4875      fi;
4876      shift
4877    done
4878}
4879
4880# set shell variables to the printcap options
4881#  flag   -&gt;  flag=1
4882#  flag@  -&gt;  flag=0
4883#  option=value -&gt;  option='value'
4884#
4885setcontrolvals () {
4886    while test "$#" -gt 0 ; do
4887      iI=$1
4888      vAr=`expr "$iI" : " *\([A-Z]\).*"`;
4889      vAlue=`expr "$iI" : " *[A-Z]\(.*\)"`;
4890      if test "X$vAr" != "X" ; then
4891        eval $vAr='$vAlue';
4892        #setvar $vAr "$vAlue";
4893      fi;
4894      shift
4895    done
4896}
4897
4898Tf=$IFS
4899IFS="
4900"
4901setpcvals $PRINTCAP_ENTRY
4902setcontrolvals $CONTROL
4903IFS=$Tf
4904
4905#
4906# restore argument list
4907set -- $Args
4908Args=""
4909vAr=""
4910vAlue=""
4911vAls=""
4912iI=""
4913Tf=""
4914
4915if test -n "$Debug" ; then
4916    set &gt;/tmp/after
4917    echo "$@" &gt;&gt;/tmp/after
4918    diff /tmp/before /tmp/after
4919fi
4920/bin/cat
4921exit 0</screen>
4922</informalexample>
4923</para>
4924
4925<para>Lets print our <filename>/tmp/hi</filename> test file and then look at
4926the results in <filename>/tmp/lp</filename>:
4927<informalexample>
4928<screen><prompt>h4: {188} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
4929<prompt>h4: {189} % </prompt><userinput>lpr /tmp/hi</userinput>
4930<prompt>h4: {190} % </prompt><userinput>more /tmp/lp</userinput>
49310a1
4932&gt; e=dfA021771h4.private
49332a4,6
4934&gt; l=66
4935&gt; s=status
4936&gt; L=papowell
493710a15,17
4938&gt; j=021771
4939&gt; C=A
4940&gt; J=/tmp/hi
494112a20
4942&gt; a=acct
4943...
494433a58
4945&gt; Printer=lp
4946...
4947hi</screen>
4948</informalexample>
4949</para>
4950
4951<para>As we see from the output,
4952shell variables have the values of our command line and printcap options.
4953It is left as an exercise for the reader to add the necessary
4954<literal remap=tt>export</literal>
4955statements to cause these values to be exported to
4956subshells.
4957It is <emphasis>not</emphasis>
4958recommended that a wholesale export of the shell variables
4959be done,
4960but only selected ones.</para>
4961
4962<para>The paranoid and security minded reader
4963will see some possible security problem with this script.
4964The <literal>eval $vAr='$vAlue'</literal> command sets
4965the value of the shell variable
4966<literal remap=tt>$vAr</literal>
4967to the value
4968<literal remap=tt>$vAlue</literal>.
4969The
4970<literal remap=tt>$vAr</literal>
4971variable is always taken from either a single letter or is the
4972name of an option in the printcap file.
4973Clearly the printcap file must not be modifiable by users,
4974and should have the same security considerations as any other
4975system configuration file.
4976The values of the
4977<literal remap=tt>$vAlue</literal>
4978are taken directly from the control file,
4979whose contents are under the control of the originator of the
4980print job request.</para>
4981
4982<para>For this reason &LPRng; takes the rather brutal step of <emphasis>sanitizing</emphasis>
4983the control file.
4984Only alphanumerics or a character in the list <literal>@/:()=,+-%_</literal>
4985are used in the control file; all others replaced by the underscore (<literal/_/)
4986character.
4987In addition,
4988all filters are run as the <application>lpd</application> user specified in the <filename>lpd.conf</filename>
4989configuration file.</para>
4990
4991<para>The following is an example of how to extract the same information
4992in Perl:
4993<informalexample>
4994<screen>#!/usr/bin/perl
4995eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
4996    if $running_under_some_shell;
4997            # this emulates #! processing on NIH machines.
4998            # (remove #! line above if indigestible)
4999
5000use Getopt::Std;
5001my(%args,%options);
5002# get the arguments
5003getopt(
5004    "a:b:cd:e:f:g:h:i:j:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z:" .
5005    "A:B:C:D:E:F:G:H:I:J:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z:",
5006    \%args );
5007
5008# set :key=value  -&gt; $option{$key}=$value
5009# set :key@       -&gt; $option{$key}="0"
5010# set :key        -&gt; $option{$key}="1"
5011 map {
5012    if( m/^\s*:([^=]+)=(.*)/ ){
5013     $options{$1}=$2;
5014    } elsif( m/^\s*:([^=]+)\@$/ ){
5015     $options{$1}="0";
5016    } elsif( m/^\s*:([^=]+)/ ){
5017     $options{$1}="1";
5018    } elsif( m/^\s*([^|]+)/ ){
5019     $options{"Printer"}=$1;
5020    }
5021 } split( "\n", $ENV{'PRINTCAP_ENTRY'});
5022
5023# get the control file entries
5024 map {
5025    if( m/^\s*([A-Z])(.*)/ ){
5026     $options{$1}=$2;
5027    } elsif( m/^\s*([a-z])/ ){
5028     $options{'Format'}=$1;
5029    }
5030 } split( "\n", $ENV{'CONTROL'});</screen>
5031</informalexample>
5032</para>
5033
5034<para>The Perl
5035<literal remap=tt>Getopt::Std</literal>
5036routine
5037parses the command line options and puts their values in the
5038<literal remap=tt>%args</literal>
5039hash variable
5040where they can be accessed using <literal>$args{'x'}</literal>.
5041Similarly,
5042the
5043<literal remap=tt>map</literal>
5044and
5045<literal remap=tt>split</literal>
5046functions process the PRINTCAP_ENTRY
5047and CONTROL environment variable and set
5048<literal remap=tt>%options</literal>
5049with the printcap entry options and the values from the control file.
5050The
5051<function remap=tt>map</function>
5052function could be replaced by a
5053<function remap=tt>foreach</function>
5054loop,
5055but this is Perl: <emphasis>There is more than one way to do it</emphasis>
5056and no
5057tutorial would be complete without at least one mind stretching
5058example that has the reader reaching for the reference manual.</para>
5059
5060</sect2>
5061
5062<sect2 id="filterexitcodes"><title>Filter Exit Codes</title>
5063
5064<para>The <application>lpd</application>
5065server uses the exit code of the filter to determine if
5066the filter was successful or unsuccessful.
5067The
5068
5069<link linkend="exitcodes">Filter Exit Codes</link>
5070
5071section discusses these values in detail,
5072but here are the most important:
5073<variablelist>
5074<varlistentry><term> 0 - JSUCC </term>
5075<listitem>
5076<para>A JSUCC exit code indicates that the filter was successful
5077in doing its work.</para>
5078
5079</listitem>
5080</varlistentry>
5081
5082<varlistentry><term> 1 - JFAIL </term>
5083
5084<listitem>
5085<para>A JFAIL exit code indicates that the filter was unsuccessful
5086in doing its work,
5087possibly due to a transient condition such as out of paper,
5088printer jam, etc.,
5089but an additional attempt might be successful.
5090Usually the <application>lpd</application> server will try at most
5091
5092<link linkend="abnormalterm">send_try</link>
5093
5094attempts before giving up.</para>
5095
5096</listitem>
5097</varlistentry>
5098
5099<varlistentry><term> 2 - JABORT </term>
5100
5101<listitem>
5102<para>A JABORT exit code indicates that the filter was unsuccessful
5103in doing its work
5104and has detected a condition that would make it impossible
5105to print the job.
5106In addition,
5107the printer may require administrative attention,
5108and the print queue operation may need to be suspended
5109until the problem is rectified. </para>
5110
5111</listitem>
5112</varlistentry>
5113
5114<varlistentry><term> 3 - JREMOVE </term>
5115
5116<listitem>
5117<para>The JREMOVE exit code will cause the job to be removed
5118from the print queue.</para>
5119
5120</listitem>
5121</varlistentry>
5122
5123<varlistentry><term> 6 - JHOLD </term>
5124
5125<listitem>
5126<para>The JHOLD exit code will cause the job to be
5127temporarily prevented from printing until release by
5128the
5129<command remap=tt>lpc release</command>
5130command.</para>
5131
5132</listitem>
5133</varlistentry>
5134
5135<varlistentry><term> Other Values</term>
5136
5137<listitem>
5138<para>Usually any other value,
5139including exit due to a signal,
5140is treated as a JABORT exit,
5141and the same action is taken.</para>
5142
5143</listitem>
5144</varlistentry>
5145</variablelist>
5146</para>
5147
5148<para>It should be obvious that the filter exit code
5149is very important,
5150and that care needs to be taken to return the
5151correct value.</para>
5152
5153</sect2>
5154
5155<sect2 id="jobformatsandfilterselection"><title>Job Formats and Filter Selection</title>
5156
5157<para>In the previous sections we discussed how a print filter was
5158executed and how it could be used.
5159Now we will look at how the <application>lpd</application> spooler chooses a print filter program.
5160Let us re-examine our example print job control file:
5161<informalexample>
5162<screen>Hh4.private
5163Ppapowell
5164J/tmp/hi
5165CA
5166Lpapowell
5167Apapowell@h4+105
5168D2000-04-12-15:27:26.662
5169Qlp
5170N/tmp/hi
5171fdfA105h4.private
5172UdfA105h4.private</screen>
5173</informalexample>
5174</para>
5175
5176<para>Each data file for a print job has a name with the format
5177<literal remap=tt>df</literal><emphasis>X</emphasis>nnn<filename>h4.private</filename>.
5178The
5179<literal remap=tt>df</literal>
5180is used to indicate that the file is a <emphasis>data file</emphasis>,
5181and the remainder is a unique name for the file in the job.
5182The
5183<literal remap=tt>X</literal>
5184part of the name must be an upper or lower case letter,
5185setting a limit of 52 different files in a single print job.</para>
5186
5187<para>The <filename>fdfA105h4.private</filename> line in the control file
5188specifies that we are to print the job using the filter for the
5189<literal remap=tt>f</literal>
5190format;
5191the file printing information consists of the format assigned to the file
5192and the name of the file.
5193In the legacy BSD print spoolers,
5194this format was used to select the print filter
5195to be used.
5196&LPRng; has expanded this by providing a <emphasis/default/ filter specification.
5197</para>
5198<table id=jobformat frame=all><title>Job Formats and Filter Selection</title>
5199<tgroup cols=3 align=left colsep=1 rowsep=1>
5200<thead>
5201<row><entry><application/lpr/ command line option </entry><entry> Control File Line </entry><entry> Printcap Option For Filter </entry><entry> Filter Command Line </entry></row>
5202</thead>
5203<tbody>
5204<row><entry>(default) </entry><entry> fdfAnnn </entry><entry> :if=/path </entry><entry> /path -Ff ... </entry></row>
5205<row><entry>-b or -l </entry><entry> ldfAnnn </entry><entry> :if=/path </entry><entry> /path ... -Ff -c </entry></row>
5206<row><entry>-p </entry><entry> pdfAnnn </entry><entry> :if=/path </entry><entry> pr | format f filter </entry></row>
5207<row><entry>-c, -d, -n, -r, -t, -v, -FX </entry><entry> XdfAnnn </entry><entry> :Xf=/path ... </entry><entry> /path -FX </entry></row>
5208<row><entry>any format</entry><entry> XdfAnnn </entry><entry>:filter=/path ... </entry><entry> /path -FX </entry></row>
5209</tbody>
5210</tgroup>
5211</table>
5212
5213<para><xref linkend=jobformat> shows the rather baroque relationship between the
5214format options specified by the <application>lpr</application>
5215command
5216and the way that <application>lpd</application>
5217uses them.
5218The reason for this complexity lies in the various implementations and
5219variations that occurred during the development and deployment of the
5220original BSD print spooling software.
5221</para>
5222
5223<para>Here is the complete,
5224arcane,
5225and baroque set of rules that are used to select
5226and print filters.
5227The de<literal remap=bf>f</literal>ault format used by <application/lpr/
5228is <literal remap=tt>f</literal>;
5229unless some other format is specified this is used.
5230The
5231<command>lpr -b</command> and <command>lpr -l</command>
5232(<literal/b/inary and <literal/l/iteral literals)
5233are a request to <application>lpd</application>
5234to do as little processing as possible of this file before printing it.
5235<application/Lpd/ use the <literal/:if/ filter for formats
5236<literal/f/
5237and
5238<literal/l/;
5239the <literal/l/ literal causes the the <literal>-c</literal>
5240filter command line flag to be used as well.
5241The <command/lpr/ <literal/-c/,
5242<literal/-d/,
5243<literal/-n/,
5244<literal/-r/,
5245<literal/-t/,
5246and <literal/-v/
5247options cause the corresponding format to be used,
5248and for <application/lpd/ to use the filter specified by the printcap option
5249<literal/:Xf/, where <literal/X/ is the specified format.
5250</para>
5251<para>
5252The
5253<command>lpr -p</command>
5254(<literal remap=bf>p</literal>retty-print literal)
5255selects <literal/p/ format,
5256and <application>lpd</application> is supposed
5257to use the program specified by the
5258<literal remap=tt>:pr</literal> printcap
5259option to format the file and then process the output of this
5260program according to format <literal/f/.
5261Unpredictable results may occur using this facility.
5262</para>
5263<para>
5264the <command>lpr -FX</command> allows you to explicitly specify format
5265<literal remap=tt>X</literal> where <literal/X/ is a lower case letter,
5266and <application/lpd/ will use the filter specified by printcap option
5267<literal/:Xf/, where <literal/X/ is the specified format.
5268If there is no <literal/:Xf/ printcap literal value then the printcap
5269<literal/:filter/ literal value will be used as the filter,
5270and if this is undefined then the file will be passed without processing
5271through to the printing device.
5272</para>
5273<para>
5274If a filter is not specified for the format
5275then the default filter specified by
5276<literal remap=tt>:filter=/path</literal>
5277filter is used,
5278and if there is no default,
5279then the output is sent directly to the output device.
5280</para>
5281
5282<para>
5283If the <literal/:fx=/<emphasis/formats/ is present in a printcap entry,
5284it specifies the formats that are allowed.
5285For example, <literal/:fx=lfv/ would allow only formats
5286<literal/l/,
5287<literal/f/,
5288and
5289<literal/v/ to be used on a particular spool queue.
5290</para>
5291<para>
5292Some
5293<literal remap=tt>Xf</literal>
5294options have pre-assigned meanings
5295and cannot be used for filter selection.
5296</para>
5297<informaltable>
5298<tgroup cols=2>
5299<thead>
5300<row><entry>Printcap Option </entry><entry> Purpose </entry></row>
5301</thead>
5302<tbody>
5303<row><entry>Printcap Option </entry><entry> Purpose </entry></row>
5304<row><entry>:af=/path </entry><entry> Accounting File </entry></row>
5305<row><entry>:ff=formfeed </entry><entry> Form Feed String </entry></row>
5306<row><entry>:if=/path </entry><entry> filter (l,b,p,f formats) </entry></row>
5307<row><entry>:filter=/path </entry><entry> Default filter </entry></row>
5308<row><entry>:lf=/path </entry><entry> Log file </entry></row>
5309<row><entry>:of=/path </entry><entry> OF filter </entry></row>
5310<row><entry>:sf </entry><entry> suppress form feed between job files </entry></row>
5311</tbody>
5312</tgroup>
5313</informaltable>
5314<para>The
5315<literal remap=tt>:of</literal>
5316filter is a special case
5317and is used for banner printing and accounting purposes.
5318See <link linkend="ofdetails"> OF Filter </link> for details.
5319</para>
5320</sect2>
5321</sect1>
5322
5323<sect1 id="jobfileformatconversion"><title>Job File Format Conversion with Filters</title>
5324
5325<para>One of the major problems that face new users to UNIX printing
5326is when they have a printer that has a proprietary
5327print job format such as the HP DeskJet series of printers.
5328The solution to this problem is quite simple:
5329generate your output in PostScript,
5330and then use the
5331<link linkend="ghostscript"> GhostScript </link>
5332program to convert the GhostScript output to
5333a format compatible with your printer.
5334<informalexample>
5335<screen>lp:filter=/usr/local/lib/filters/myfilter:...
5336
5337/tmp/myfilter:
5338
5339#!/bin/sh
5340/usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
5341    -sOutputFile=- - &amp;&amp; exit 0
5342exit 2</screen>
5343</informalexample>
5344</para>
5345
5346<para>This simple
5347<emphasis>tutorial</emphasis>
5348example suffers from some serious problems.
5349If you accidentally send a non-PostScript file to the printer
5350GhostScript will detect this and exit with an error message
5351but only after trying to interpret the input file as PostScript.
5352If the input file was a text file,
5353this can result in literally thousands of error messages and hundreds
5354of pages of useless output.</para>
5355
5356<para>In order to make a more robust filter we need to meet
5357the following minimum requirements:
5358<orderedlist>
5359
5360<listitem>
5361<para>The file type should be determined,
5362and only files that are PostScript should be passed to GhostScript.</para>
5363</listitem>
5364
5365<listitem>
5366<para>We may have some conversion routines that can convert files into PostScript
5367files and then we can send them to GhostScript for raster conversion.</para>
5368</listitem>
5369
5370<listitem>
5371<para>If we cannot convert a file,
5372then we should simply terminate the printing and cause the spooler
5373to remove the job.</para>
5374</listitem>
5375
5376</orderedlist>
5377</para>
5378
5379<para>
5380The <application/ifhp/ Print Filter program is a companion to the
5381&LPRng; software and does this type of operation.
5382If you are using Linux,
5383then you may find the <emphasis/RedHat Print Filters/
5384(<ulink URL="http://www.debian.org">http://www.debian.org</ulink>)
5385installed and
5386in use on your system.
5387The <emphasis>magicfilter</emphasis>
5388developed by  H. Peter Anvin
5389<ulink URL="http://www.debian.org">http://www.debian.org</ulink>
5390is distributed with Debian Linux.
5391The
5392<application remap=tt>apsfilter</application>
5393by Andreas Klemm
5394<ulink URL="http://www.freebsd.org/~andreas/index.html">http://www.freebsd.org/~andreas/index.html</ulink>
5395is also widely used,
5396although now most of its functionality is directly available in &LPRng;.
5397Finally,
5398the
5399<application remap=tt>a2ps</application>
5400(Ascii to PostScript)
5401converter by
5402<ulink URL="demaille@inf.enst.fr">Akim Demaille</ulink>
5403and
5404<ulink URL="santana@st.com">Miguel Santana</ulink> is available from
5405<ulink URL="www-inf.enst.fr/~demaille/a2ps">www-inf.enst.fr/~demaille/a2ps</ulink>.
5406This package provides a very nice set of facilities for
5407massaging,
5408mangling,
5409bending,
5410twisting,
5411and being downright nasty with text or other files.
5412</para>
5413<sect2><title>Simple Filter with File Format Detection</title>
5414<para>
5415Since this is a tutorial,
5416we will demonstrate a simple way to make your own
5417<emphasis>multi-format</emphasis>
5418print filter,
5419and provide insight into how more complex filters work.</para>
5420
5421<para>The
5422<link linkend="fileprog">file</link> utility  developed
5423by Ian F. Darwin uses a database of file signatures to determine
5424what the contents of a file are.
5425For example:
5426<informalexample>
5427<screen><prompt>h4: {191} % </prompt><userinput>cd /tmp</userinput>
5428<prompt>h4: {192} % </prompt><userinput>echo hi &gt;hi</userinput>
5429<prompt>h4: {193} % </prompt><userinput>gzip -c hi &gt;hi.gz</userinput>
5430<prompt>h4: {194} % </prompt><userinput>echo "%!PS-Adobe-3.0" &gt;test.ps</userinput>
5431<prompt>h4: {195} % </prompt><userinput>gzip -c test.ps &gt;test.ps.gz</userinput>
5432<prompt>h4: {196} % </prompt><userinput>file hi hi.gz test.ps test.ps.gz</userinput>
5433hi:        ASCII text
5434hi.gz:     gzip compressed data, deflated
5435test.ps:   PostScript document text conforming at level 3.0
5436test.ps.gz: gzip compressed data, deflated
5437<prompt>h4: {197} % </prompt><userinput>file - &lt;test.ps</userinput>
5438standard input: PostScript document text conforming at level 3.0</screen>
5439</informalexample>
5440</para>
5441
5442<para>If we are given a file,
5443we can now use <application/file/ to recognize the file type
5444and if the file type is suitable for our printer
5445we can send it to the printer,
5446otherwise we can reject it.
5447The following is a simple
5448yet very powerful shell script that does this.
5449<informalexample>
5450<screen>#!/bin/sh
5451# set up converters
5452gs="/usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
5453    -sOutputFile=/dev/fd/3 - 3&gt;&amp;1 1&gt;&amp;2"
5454a2ps="/usr/local/bin/a2ps -q -B -1 -M Letter --borders=no -o-"
5455decompress=""
5456# get the file type
5457type=`file - | tr A-Z a-z | sed -e 's/  */_/g'`;
5458echo TYPE $type &gt;&amp;2
5459case "$type" in
5460  *gzip_compressed* ) decompress="gunzip -c |" compressed="compressed" ;;
5461esac
5462
5463# we need to rewind the file
5464perl -e "seek STDIN, 0, 0;"
5465
5466if test "X$decompress" != "X" ; then
5467    type=`$decompress head | file - | tr A-Z a-z | sed -e 's/  */_/g'`;
5468    echo COMPRESSED TYPE $type &gt;&amp;2
5469    # we need to rewind the file
5470    perl -e "seek STDIN, 0, 0;"
5471fi
5472case "$type" in
5473  *postscript* ) process="$gs" ;;
5474  *text* )       process="$a2ps | $gs" ;;
5475  * )
5476    echo "Cannot print type $compressed '$type'" &gt;&amp;2
5477    # exit with JREMOVE status
5478    exit 3
5479    ;;
5480esac
5481# in real life, replace 'echo' with 'exec'
5482echo "$decompress $process"
5483# exit with JABORT if this fails
5484exit 2</screen>
5485</informalexample>
5486</para>
5487
5488<para>Copy this to the <filename>/tmp/majik</filename> file,
5489and give it
5490<literal remap=tt>0755</literal>
5491(executable) permissions.
5492Here is an example of the output of the script:
5493<informalexample>
5494<screen><prompt>h4: {198} % </prompt><userinput>/tmp/majik &lt;test.ps.gz</userinput>
5495TYPE standard_input:_gzip_compressed_data,_deflated...
5496COMPRESSED TYPE standard_input:_postscript_document_level_3.0
5497gunzip -c | /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
5498   -sOutputFile=/dev/fd/3 - 3&gt;&amp;1 1&gt;&amp;2
5499<prompt>h4: {199} % </prompt><userinput>/tmp/majik &lt;/tmp/hi</userinput>
5500TYPE standard_input:_ascii_text
5501 /usr/local/bin/a2ps -q -B -1 -M Letter --borders=no -o- \
5502  | /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
5503   -sOutputFile=/dev/fd/3 - 3&gt;&amp;1 1&gt;&amp;2</screen>
5504</informalexample>
5505</para>
5506
5507<para>The first part of the script sets up a standard set of commands that
5508we will use in the various conversions.
5509A full blown package for conversion would use a database or setup file
5510to get these values.
5511We then use the
5512<application remap=tt>file</application>
5513utility to determine the input file type.
5514The output of the
5515<application remap=tt>file</application>
5516utility is translated to lower case
5517and multiple blanks and tabs are removed.</para>
5518
5519<para>We use a simple shell
5520<literal remap=tt>case</literal>
5521statement to determine if we have a
5522compressed file and get a decompression program to use.
5523We reapply the
5524<application remap=tt>file</application>
5525utility to the decompressed file (if it was compressed)
5526and get the file type.</para>
5527
5528<para>Finally we use another
5529<literal remap=tt>case</literal>
5530statement to get the output converter
5531and then we run the command.
5532For tutorial purposes,
5533we use an
5534<command remap=tt>echo</command>
5535rather than an
5536<command remap=tt>exec</command>
5537so we can see the actual
5538command, rather than the output.</para>
5539
5540<para>Just for completeness,
5541here is
5542<application remap=tt>majikperl</application>:
5543<informalexample>
5544<screen>#!/usr/bin/perl
5545eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
5546    if $running_under_some_shell;
5547            # this emulates #! processing on NIH machines.
5548            # (remove #! line above if indigestible)
5549my($gs) = "/usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
5550    -sOutputFile=/dev/fd/3 - 3&gt;&amp;1 1&gt;&amp;2";
5551my($a2ps)="/usr/local/bin/a2ps -q -B -1 -M Letter --borders=no -o-";
5552
5553my($decompress,$compressed,$process,$type);
5554$decompress=$compressed=$process=$type="";
5555
5556# get the file type
5557$type = ` file - `;
5558$type =~ tr /A-Z/a-z/;
5559$type =~ s/\s+/_/g;
5560print STDERR "TYPE $type\n";
5561($decompress,$compressed) = ("gunzip -c |", "gzipped")
5562  if( $type =~ /gzip_compressed/ );
5563print STDERR "decompress $decompress\n";
5564unless( seek STDIN, 0, 0 ){
5565    print "seek STDIN failed - $!\n"; exit 2; }
5566if( $decompress ne "" ){
5567    $type = ` $decompress file - `;
5568    $type =~ tr /A-Z/a-z/;
5569    $type =~ s/\s+/_/g;
5570    print STDERR "COMPRESSED TYPE $type\n";
5571    unless( seek STDIN, 0, 0 ){
5572        print "seek STDIN failed - $!\n"; exit 2; }
5573}
5574$_ = $type;
5575if( /postscript/ ){
5576    $process="$gs";
5577} elsif( /_text_/ ){
5578    $process="$a2ps | $gs" ;;
5579} else {
5580    print STDERR "Cannot print $compressed '$type'" &gt;&amp;2;
5581    # JREMOVE
5582    exit 3;
5583}
5584exec "$decompress $process";
5585print "exec failed - $!\n";
5586exit 2;</screen>
5587</informalexample>
5588</para>
5589
5590</sect2>
5591
5592<sect2><title>The <application/ifhp/ Filter</title>
5593
5594<para>
5595The
5596<link linkend="secftp">ifhp</link>
5597Print Filter is the companion print filter supplied with &LPRng;
5598and is normally
5599installed together with the &LPRng; software.
5600<application remap=tt>Ifhp</application>
5601supports a wide range of PostScript,
5602PCL, text, and raster printers,
5603and can be configured to support almost any type of printer
5604with a stream based interface.
5605It provides diagnostic and error information as well as
5606accounting information.
5607It recognizes a wide range of file types by using
5608the
5609<application remap=tt>file</application>
5610utility and the pattern matching technique
5611demonstrated in the previous section,
5612and can do selective conversions from one format to others.</para>
5613
5614<para>The
5615<link linkend="postscript">PostScript</link>
5616and
5617<link linkend="pcl">PCL</link>
5618printer job languages are supported by most printer manufacturers.
5619However,
5620in order to have a job printed correctly the following steps must be taken.
5621<orderedlist>
5622
5623<listitem>
5624<para>The printer must be put into a known <emphasis/initial/
5625state by sending it the appropriate
5626reset strings or performing a correct set of IO operations.</para>
5627</listitem>
5628
5629<listitem>
5630<para>If accounting is being done,
5631then the printer accounting information must be obtained
5632and recorded.
5633See
5634<link linkend="accountingref">Accounting</link>
5635for more information about &LPRng; support for accounting.</para>
5636</listitem>
5637
5638<listitem>
5639<para>The file to be printed must be checked to see if it is
5640compatible with the printer,
5641and if not,
5642a format conversion program invoked to convert it to
5643the required format.</para>
5644</listitem>
5645
5646<listitem>
5647<para>If the user selects a set of printer specific options such
5648as
5649landscape mode,
5650duplex printing,
5651multiple copies,
5652or
5653special paper,
5654the
5655appropriate commands must be sent to the
5656printer to select these options.</para>
5657</listitem>
5658
5659<listitem>
5660<para>The file must be transferred to the printer
5661and the printer is monitored for any error conditions.</para>
5662</listitem>
5663
5664<listitem>
5665<para> Any required end of job commands are sent to the printer,
5666and the printer monitored for error conditions while the job finishes printing.</para>
5667</listitem>
5668
5669<listitem>
5670<para>If accounting is being done,
5671the printer accounting information such as page count and time used
5672must be obtained and recorded.
5673See
5674<link linkend="accountingref">Accounting</link>
5675for more information about &LPRng; support for accounting.</para>
5676</listitem>
5677
5678</orderedlist>
5679</para>
5680
5681<para>The
5682<application remap=tt>ifhp</application>
5683filter uses the <filename>ifhp.conf</filename> configuration file
5684to determine the actions and commands
5685appropriate for various models of printers.
5686See the
5687<application remap=tt>ifhp</application>
5688documentation for details about the
5689format and contents of this file.
5690This file contains entries for a large number of PostScript,
5691PJL, and other printers.
5692The default printer used by <application/ifhp/
5693is the HP LaserJet 4M Plus which supports PostScript,  PCL, and PJL.
5694The commands and formats used by this printer
5695is compatible with a large number of other HP printers.
5696</para>
5697
5698<para>We will demonstrate how to add the
5699<application remap=tt>ifhp</application>
5700filter to your printcap entry.
5701Find the path to the
5702<application remap=tt>ifhp</application>
5703filter using the
5704<application>find</application> command as we did in the previous exercise.
5705Modify the printcap as shown below
5706and use
5707<command remap=tt>lpc lpd</command>
5708to restart <application>lpd</application>.
5709<informalexample>
5710<screen>lp:sd=/var/spool/lpd/%P
5711  :force_localhost
5712  :lp=/tmp/lp
5713  :ifhp=model=default
5714  # modify the path to ifhp appropriately
5715  :filter=/usr/local/libexec/filters/ifhp</screen>
5716</informalexample>
5717</para>
5718
5719<para>Now print the <filename>/tmp/hi</filename>
5720and then display <filename>/tmp/lp</filename>
5721using a text editor such as
5722<application remap=tt>vi</application>
5723or
5724<application remap=tt>emacs</application>
5725that shows
5726control characters:
5727<informalexample>
5728<screen><prompt>h4: {200} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
5729<prompt>h4: {201} % </prompt><userinput>lpr /tmp/hi</userinput>
5730<prompt>h4: {202} % </prompt><userinput>vi /tmp/lp</userinput>
5731^[%-12345X@PJL
5732@PJL JOB NAME = "PID 405" DISPLAY = "papowell"
5733@PJL RDYMSG DISPLAY = "papowell"
5734@PJL USTATUSOFF
5735@PJL USTATUS JOB = ON
5736@PJL USTATUS DEVICE = ON
5737@PJL USTATUS PAGE = ON
5738@PJL USTATUS TIMED = 10
5739@PJL ENTER LANGUAGE = PCL
5740^]E^]&amp;^]&amp;k2G^]&amp;s0C^]&amp;l0O^]9^](s0P^](s10.00H^](s4099Thi
5741^]E^]%-12345X@PJL
5742@PJL RDYMSG DISPLAY = "papowell"
5743@PJL EOJ NAME = "PID 405"
5744@PJL USTATUSOFF
5745@PJL USTATUS JOB = ON
5746@PJL USTATUS DEVICE = ON
5747@PJL USTATUS PAGE = ON
5748@PJL USTATUS TIMED = 10
5749@PJL RDYMSG DISPLAY = ""
5750^[%-12345X</screen>
5751</informalexample>
5752</para>
5753
5754<para>The output now contains all of the control sequences and setup
5755codes needed to print a text file on the default printer.
5756The <literal/:ifhp=model=default/ printcap entry is used by <application/ifhp/
5757to get the information it needs to perform its operation.
5758The following options are commonly provided in the
5759<literal/:ifhp=/ option to configure the <application/ifhp/
5760filter.
5761</para>
5762<table id=ifhpopts frame=all><title><application/:ifhp=/ Options</title>
5763<tgroup cols=2 align=left colsep=1 rowsep=1>
5764<thead>
5765<row><entry>
5766Option</entry><entry>
5767Purpose</entry></row>
5768</thead>
5769<tbody>
5770<row><entry>
5771<literal/model=/<emphasis/name/</entry><entry>
5772Use <emphasis/name/ entry in <literal/ifhp.conf/</entry></row>
5773<row><entry>
5774<literal/status/ or <literal/status@/</entry><entry>
5775Printer does or does not provide status information</entry></row>
5776<row><entry>
5777<literal/sync/, <literal/sync@/, <literal/sync=/<emphasis/(ps|pjl)/ </entry><entry>
5778Printer does or does not indicate ready to operate at start of job,
5779or use PostScript or PJL code sequence to determine if printer is ready.
5780</entry></row>
5781<row><entry>
5782<literal/pagecount/, <literal/pagecount@/, <literal/pagecount=/<emphasis/(ps|pjl)/ </entry><entry>
5783Printer does or does not have pagecount support,
5784or use PostScript or PJL code sequence to determine pagecount.
5785</entry></row>
5786<row><entry>
5787<literal/waitend/, <literal/waitend@/, <literal/waitend=/<emphasis/(ps|pjl)/ </entry><entry>
5788Wait or do not wait for end of job,  or send PostScript or PJL code sequence
5789to have printer report end of job.
5790</entry></row>
5791</tbody>
5792</tgroup>
5793</table>
5794<para>
5795The 
5796<literal/model=/<emphasis/name/
5797entry is used to specify the configuration entry in the <literal/ifhp.conf/
5798file to be used by <application/ifhp/.
5799This entry usually has all of the specific information needed by the
5800<application/ifhp/ filter.
5801</para>
5802
5803<para>
5804The <literal/status/
5805option is the most common option usually provided in a printcap entry.
5806This option is needed when the communication with the printer is
5807<emphasis/write-only/
5808and no status information will be returned.
5809If a printer normally supports returning status information then the
5810<literal/ifhp.conf/ configuration entry will indicate this
5811and the <application/ifhp/ filter will try to get status.
5812When no status is returned it will either terminate operation after
5813a timeout or sit in an endless loop waiting for status.
5814By specifying <literal/status@/ you will suppress getting status.
5815This also has the effect of doing
5816<literal/sync@/,
5817<literal/pagecount@/,
5818and
5819<literal/waitend@/
5820</para>
5821<para>
5822The <literal/sync/ option is used to cause <application/ifhp/
5823to wait for an <emphasis/end of job/ indication from the printer
5824before starting the next job.
5825This is usually done in order to make sure that all jobs have been
5826flushed from a printer before starting another job.
5827If you specify <literal/sync@/ then you may get slightly faster startup
5828but at the expense of losing the ends of previous print jobs.
5829</para>
5830<para>
5831The <literal/pagecount/ option is used to cause <application/ifhp/
5832to get the value of a hardware pagecounter from the printer.
5833If your printer supports such an item then the <literal/ifhp.conf/
5834configuration option usually indicates this.
5835However,
5836it takes a small amount of time to get the pagecounter information from
5837the printer and you may not need it.
5838Use <literal/sync@/ if you do not want page counts.
5839</para>
5840
5841<para>
5842Finally,  <literal/waitend/ option is used to cause <application/ifhp/
5843to wait for an <emphasis/end of job/ indication from the printer before
5844exiting.
5845If you specify <literal/waitend@/ then the filter will exit
5846immediately after sending the job,
5847but you will possibly lose any error information or status reports from
5848the printer.
5849</para>
5850
5851<para>
5852For a complete list of all of the <application/ifhp/ options please
5853see the IFHP documentation.
5854</para>
5855
5856</sect2>
5857
5858<sect2 id="jaggies"><title>The Jaggies - LF to CR-LF Conversion With lpf</title>
5859
5860<para>When printing to vintage hard copy devices or to
5861printers that support a <emphasis>text</emphasis>
5862mode,
5863many UNIX users discover that their output suffers from
5864a case of the jaggies.
5865<informalexample>
5866<screen>Input file:
5867
5868  This is
5869  a nice day
5870
5871Output:
5872
5873  This is
5874         a nice day</screen>
5875</informalexample>
5876</para>
5877
5878<para>UNIX systems terminate lines with a single <acronym>NL</acronym> (new line) character.
5879This causes the printer to move down one line on the printing page
5880but does not change its horizontal position
5881and print the next character at the left margin.
5882This is done by using the <acronym>CR</acronym> (carriage return) character.
5883You need to convert the single <acronym>NL</acronym> to a
5884<literal remap=tt>CR-LF</literal>
5885combination and the
5886<application remap=tt>lpf</application>
5887filter supplied with &LPRng; does this.</para>
5888
5889<para>First,
5890locate the
5891<application remap=tt>lpf</application>
5892filter.
5893You can find it by using the command:
5894<informalexample>
5895<screen><prompt>h9: {160} % </prompt><userinput>find /usr/ -type f -name lpf -print</userinput>
5896/usr/libexec/lpr/lpf</screen>
5897</informalexample>
5898</para>
5899
5900<para>We will first see what the output is like without
5901<application remap=tt>lpf</application>,
5902and then see what it does.
5903Modify the
5904<application remap=tt>lp</application>
5905printcap entry as shown below
5906and then use
5907<command remap=tt>lpc restart</command>
5908to restart the <application>lpd</application> server.
5909<informalexample>
5910<screen>lp:sd=/var/spool/lpd/%P
5911  :force_localhost
5912  :lp=/tmp/lp</screen>
5913</informalexample>
5914</para>
5915
5916<para>Print a file and view the output using the following
5917commands.
5918If you do not have the
5919<application remap=tt>od</application>
5920(octal dump) program,
5921try using
5922<application remap=tt>hexdump</application>
5923or some other appropriate program
5924that displays the numerical contents of the file.
5925<informalexample>
5926<screen><prompt>h4: {203} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
5927<prompt>h4: {204} % </prompt><userinput>lpr /tmp/hi</userinput>
5928<prompt>h4: {205} % </prompt><userinput>od -bc /tmp/lp</userinput>
59290000000  150 151 012
5930           h   i  \n
59310000003</screen>
5932</informalexample>
5933</para>
5934
5935<para>Now we will use the
5936<application remap=tt>lpf</application>
5937filter.
5938Modify the printcap as shown below
5939and use
5940<command remap=tt>lpc reread</command>
5941to cause <application>lpd</application> to reread the configuration information.
5942<informalexample>
5943<screen>lp:sd=/var/spool/lpd/%P
5944  :force_localhost
5945  :lp=/tmp/lp
5946  # modify the path to lpf appropriately
5947  :filter=/usr/local/libexec/filters/lpf</screen>
5948</informalexample>
5949</para>
5950
5951<para>Now reprint the file:
5952<informalexample>
5953<screen><prompt>h4: {206} % </prompt><userinput>cp /dev/null /tmp/lp</userinput>
5954<prompt>h4: {207} % </prompt><userinput>lpr /tmp/hi</userinput>
5955<prompt>h4: {208} % </prompt><userinput>od -bc /tmp/lp</userinput>
5956od -bc /tmp/lp
59570000000  150 151 015 012
5958           h   i  \r  \n
59590000004</screen>
5960</informalexample>
5961</para>
5962
5963<para>As you see,
5964<application remap=tt>lpf</application>
5965changes the <literal/LF/ to a
5966<literal remap=tt>CR-LF</literal>
5967sequence.</para>
5968
5969</sect2>
5970
5971<sect2><title>Store and Forward Spool Queues</title>
5972
5973<para>Up to now we have assumed that associated with each spool
5974queue is a hardware printing device.
5975When a job is sent to the spool queue the <application>lpd</application>
5976server will take actions to filter it and then send it to the printing
5977device.</para>
5978
5979<para>However,
5980we can also have <emphasis>store and forward</emphasis>
5981spool queues.
5982These queue act to simply buffer jobs and then forward them
5983to another spooler.
5984The following printcap entry shows how you can specify a store and
5985forward queue.
5986<informalexample>
5987<screen># store and forward using classical BSD :rm:rp
5988lp:rp=pr:rm=host
5989  :sd=/var/spool/lpd/%P
5990  :server
5991# store and forward using &LPRng; lp=pr@host
5992lp:lp=pr@host
5993  :sd=/var/spool/lpd/%P
5994  :server</screen>
5995</informalexample>
5996</para>
5997
5998<para>The legacy
5999<literal remap=tt>:rp</literal>
6000(remote printer) and
6001<literal remap=tt>:rm</literal>
6002(remote host)
6003format can be used to specify the print queue and destination host
6004for jobs sent to this queue.
6005The &LPRng; <literal>:lp=pr@host</literal> format serves the same function,
6006and has precedence over the
6007<literal remap=tt>:rm:rp</literal>
6008form.</para>
6009
6010<para>Edit the printcap file so it has contents indicated below,
6011use <command>checkpc -f</command> to check the printcap,
6012and then use
6013<command remap=tt>lpc reread</command>
6014to restart the <application>lpd</application> server.
6015<informalexample>
6016<screen>lp:force_localhost
6017lp:server
6018  :sd=/var/spool/lpd/%P
6019  :lp=lp2@localhost
6020lp2:force_localhost
6021lp2:server
6022  :sd=/var/spool/lpd/%P
6023  :lp=/tmp/lp2</screen>
6024</informalexample>
6025
6026Execute the following commands
6027to print the <filename>/tmp/hi</filename> file
6028and observe the results:
6029<informalexample>
6030<screen><prompt>h4: {209} % </prompt><userinput>lpr /tmp/hi</userinput>
6031<prompt>h4: {210} % </prompt><userinput>lpq -lll</userinput>
6032Printer: lp@h4 (dest lp2@localhost)
6033 Queue: no printable jobs in queue
6034 Status: sending control file 'cfA029h4.private' \
6035    to lp2@localhost at 09:39:57.719
6036 Status: completed sending 'cfA029h4.private' \
6037    to lp2@localhost at 09:39:57.724
6038 Status: sending data file 'dfA029h4.private' \
6039    to lp2@localhost at 09:39:57.727
6040 Status: completed sending 'dfA029h4.private' \
6041    to lp2@localhost at 09:39:57.925
6042 Status: done job 'papowell@h4+29' transfer \
6043    to lp2@localhost at 09:39:57.926
6044 Status: subserver pid 29031 exit status 'JSUCC' at 09:39:57.953
6045 Status: lp@h4.private: job 'papowell@h4+29' printed at 09:39:57.961
6046 Status: job 'papowell@h4+29' removed at 09:39:57.993
6047Printer: lp2@h4
6048 Queue: no printable jobs in queue
6049 Status: no banner at 09:39:58.054
6050 Status: printing data file 'dfA029h4.private', size 3 at 09:39:58.054
6051 Status: printing done 'papowell@h4+29' at 09:39:58.054
6052 Status: accounting at end at 09:39:58.054
6053 Status: finished 'papowell@h4+29', status 'JSUCC' at 09:39:58.054
6054 Status: subserver pid 29033 exit status 'JSUCC' at 09:39:58.056
6055 Status: lp2@h4.private: job 'papowell@h4+29' printed at 09:39:58.056
6056 Status: job 'papowell@h4+29' removed at 09:39:58.069</screen>
6057</informalexample>
6058</para>
6059
6060<para>As we see from the status,
6061our job was sent to the
6062<literal remap=tt>lp</literal>
6063spool queue first.
6064It was store there and then the <application>lpd</application> server transferred it to the
6065<literal remap=tt>lp2</literal>
6066spool queue,
6067where it was printed to the file <filename>/tmp/lp2</filename>.</para>
6068
6069</sect2>
6070
6071<sect2><title>Filtering Job Files In Transit</title>
6072
6073<para>One of the major problems with store and forward operation
6074is that the destination spool queue may not actually be a
6075spool queue - it can be a printer.
6076Many network printers provide an RFC1179 compatible network
6077interface and act,
6078for job forwarding purposes,
6079like a host running a limited capability BSD print spooler.</para>
6080
6081<para>
6082By adding a filter to the printcap information we can
6083modify the format of a job file so that it is compatible with
6084the destination printer.
6085</para>
6086
6087<para>Edit the printcap and <filename>/tmp/testf</filename>
6088files so they have the contents indicated below,
6089give <filename>/tmp/testf</filename> executable permissions,
6090use <command>checkpc -f</command> to check the printcap,
6091and then use
6092<command remap=tt>lpc reread</command>
6093to restart the <application>lpd</application> server.
6094<informalexample>
6095<screen># set /tmp/testf to contain the following
6096#   and chmod 755 /tmp/testf
6097#!/bin/sh
6098echo TESTF $0 $@
6099/bin/cat
6100exit 0
6101
6102# printcap
6103lp:force_localhost
6104lp:server
6105  :sd=/var/spool/lpd/%P
6106  :lp=lp2@localhost
6107  :filter=/tmp/testf
6108  :bq_format=ffl
6109lp2:force_localhost
6110lp2:server
6111  :sd=/var/spool/lpd/%P
6112  :lp=/tmp/lp2</screen>
6113</informalexample>
6114
6115Execute the following commands
6116to print the <filename>/tmp/hi</filename> file
6117and observe the results:
6118<informalexample>
6119<screen><prompt>h4: {211} % </prompt><userinput>lpr /tmp/hi</userinput>
6120<prompt>h4: {212} % </prompt><userinput>lpq -llll</userinput>
6121<prompt>h4: {213} % </prompt><userinput>lpq -llll</userinput>
6122Printer: lp@h4 (dest lp2@localhost)
6123 Queue: no printable jobs in queue
6124 Status: no banner at 09:55:53.681
6125 Status: printing data file 'dfA086h4.private', size 3, \
6126    IF filter 'testf' at 09:55:53.683
6127 Status: IF filter finished at 09:55:53.713
6128 Status: printing done 'papowell@h4+86' at 09:55:53.714
6129 Status: sending job 'papowell@h4+86' to lp2@localhost at 09:55:53.734
6130 Status: connecting to 'localhost', attempt 1 at 09:55:53.735
6131 Status: connected to 'localhost' at 09:55:53.739
6132 Status: requesting printer lp2@localhost at 09:55:53.740
6133 Status: sending control file 'cfA086h4.private' 
6134      to lp2@localhost at 09:55:53.752
6135 Status: completed sending 'cfA086h4.private' 
6136      to lp2@localhost at 09:55:53.757
6137 Status: sending data file 'dfA086h4.private' 
6138      to lp2@localhost at 09:55:53.758
6139 Status: completed sending 'dfA086h4.private' 
6140      to lp2@localhost at 09:55:53.939
6141 Status: done job 'papowell@h4+86' transfer 
6142      to lp2@localhost at 09:55:53.940
6143 Status: subserver pid 29088 exit status 'JSUCC' at 09:55:53.980
6144 Status: lp@h4.private: job 'papowell@h4+86' printed at 09:55:53.983
6145 Status: job 'papowell@h4+86' removed at 09:55:53.998
6146Printer: lp2@h4
6147 Queue: no printable jobs in queue
6148 Status: subserver pid 29092 starting at 09:55:54.005
6149 Status: accounting at start at 09:55:54.005
6150 Status: opening device '/tmp/lp2' at 09:55:54.005
6151 Status: printing job 'papowell@h4+86' at 09:55:54.005
6152 Status: no banner at 09:55:54.006
6153 Status: printing data file 'dfA086h4.private', size 298 at 09:55:54.006
6154 Status: printing done 'papowell@h4+86' at 09:55:54.006
6155 Status: accounting at end at 09:55:54.006
6156 Status: finished 'papowell@h4+86', status 'JSUCC' at 09:55:54.006
6157 Status: subserver pid 29092 exit status 'JSUCC' at 09:55:54.008
6158 Status: lp2@h4.private: job 'papowell@h4+86' printed at 09:55:54.008
6159 Status: job 'papowell@h4+86' removed at 09:55:54.020</screen>
6160</informalexample>
6161</para>
6162
6163<para>We have displayed a bit more status information so that we can see
6164what the actions the
6165<literal remap=tt>lp</literal>
6166queue carries out.
6167It first <emphasis>processes</emphasis>
6168the job data file
6169using the
6170<application remap=tt>testf</application>
6171filter and puts the results in a temporary file.
6172Then it sends the contents of the temporary file to the
6173<literal remap=tt>lp2</literal>
6174queue.
6175The
6176<literal remap=tt>lp2</literal>
6177queue receives the converted job file and then prints it
6178to the <filename>/tmp/lp2</filename> file in turn.</para>
6179
6180<para>By default,
6181each file in a job is processed by a print file and the processed output
6182is then sent to the destintion as individual job files,
6183each with the format specified by the value of the
6184<literal/bq_format/ (default
6185<literal/f/) option.
6186The
6187<literal/bq_format/ option has the format
6188<literal/iOiO...d/;
6189each <literal/i/ is the original format and the corresponding <literal/O/
6190is the output format.
6191If there is an odd number of characters then the last unmatched character
6192is used as the default format,
6193otherwise no translation is done.
6194For example,
6195<literal/flrfl/ will cause the <literal/f/ format to be mapped to
6196<literal/l/,
6197<literal/r/ to <literal/f/,
6198and any others to
6199<literal/l/.
6200</para>
6201
6202</sect2>
6203</sect1>
6204
6205<sect1><title>Printcap Basics</title>
6206
6207<para>In the previous sections we have used simple printcap entries to
6208define how to set up filters and pass parameters to them.
6209We will now examine the printcap database in more detail.</para>
6210
6211<para>The &LPRng; server and client software
6212gets their configuration information from:
6213<itemizedlist>
6214
6215<listitem>
6216<para>Compile time settings which set the default values for the
6217configuration information.</para>
6218</listitem>
6219
6220<listitem>
6221<para>A <filename>lpd.conf</filename> file that contains values that override the
6222compile time defaults.
6223This information can effect the behavior of the <application>lpd</application>
6224server and clients.</para>
6225</listitem>
6226
6227<listitem>
6228<para>Printcap entries which have configuration information for individual
6229print queues.
6230The information in the printcap entries for the queue override the
6231<filename>lpd.conf</filename> and compile time defaults.
6232The system printcap file is read first,
6233followed by the user printcap file.
6234</para>
6235</listitem>
6236
6237<listitem>
6238<para>Command line and environment variable values.
6239These can be used to override or select particular configuration
6240information or to select one of a set of options for use.</para>
6241</listitem>
6242
6243</itemizedlist>
6244</para>
6245
6246<para>Each print queue or printer has a name which is used to look up
6247the printcap information for the printer.
6248The <filename>/etc/printcap</filename> file is the default location for the
6249printcap information,
6250although it can also be obtained from database servers,
6251or generated by programs.
6252See the
6253
6254<link linkend="secnis">Using Programs To Get Printcap Information</link>
6255
6256section for details.</para>
6257
6258<para>We will use a more complex printcap file to explore how &LPRng;
6259gets the printcap information.
6260Put the following lines in the <filename>/etc/printcap</filename>
6261file:
6262<informalexample>
6263<screen># client entry
6264lp:tc=.client
6265lp2:tc=.client
6266.client:
6267  :lp=%P@localhost
6268  :force_localhost
6269
6270lp:server
6271  :cm=The Main Print Queue
6272  :lp=/tmp/lp
6273  :tc=.common
6274
6275lp2:server
6276  :cm=The Second Print Queue
6277  :lp=/tmp/lp2
6278  :tc=.common
6279
6280.common:
6281  :sd=/var/spool/lpd/%P
6282  :mx=0</screen>
6283</informalexample>
6284
6285The
6286<command>lpc client</command>
6287command is very useful to see how &LPRng; uses this
6288printcap information:
6289<informalexample>
6290<screen><prompt>h4: {214} % </prompt><userinput>lpc client</userinput>
6291Config
6292<prompt>h4: {215} % </prompt><userinput>lpc client all</userinput>
6293Config
6294 :lpd_port=2000
6295 :printcap_path=/var/tmp/LPD/printcap
6296
6297Names
6298 :.client=.client
6299 :.common=.common
6300 :lp=lp
6301 :lp2=lp2
6302 :main=lp
6303
6304All
6305 :lp
6306 :lp2
6307
6308Printcap Information
6309lp|main
6310 :force_localhost
6311 :lp=lp@localhost
6312lp2
6313 :force_localhost
6314 :lp=lp2@localhost
6315</screen>
6316</informalexample>
6317</para>
6318
6319<para>The
6320<command remap=tt>lpc client all</command>
6321command shows all of the configuration
6322and printcap information,
6323and is the handiest one for system debugging and diagnostics.
6324The
6325<emphasis>Name</emphasis>
6326information is the names of the printcap
6327entries that have been found in the database and
6328is listed in sorted order.
6329The
6330<emphasis >All</emphasis>
6331are entries that correspond to actual queues or printers
6332and are listed in the order that they appear in the printcap or
6333according to an order specified by the system administrator.
6334(See the
6335
6336<link linkend="allpc"><literal/all/ Printcap Entry</link>
6337
6338for details.)</para>
6339
6340<sect2><title>Printcap Processing Format</title>
6341
6342<para>Queue or printer names must start with an alphanumeric character,
6343and contain only alphanumerics,  hyphens (<literal>-</literal>) and underscores (<literal>_</literal>).
6344To avoid known and nasty problems with sending and receiving print jobs from
6345case sensitive and case insensitive systems,
6346&LPRng; brutally lowercases all printcap entry names and printer names.</para>
6347
6348<para>The printcap file is processed by reading it line by line and
6349composing the individual printcap entries.
6350Each entry has an name and one or more aliases.
6351The entries in the printcap assign values to options.
6352These can have the format:
6353<informalexample>
6354<screen>option=string value \n with escapes
6355flag         # equivalent to flag=1
6356flag@        # equivalent to flag=0
6357option#value # equivalent to option=value</screen>
6358</informalexample>
6359</para>
6360
6361<para>An option will have the last value that occurs in the printcap entry.</para>
6362
6363<para>Our example shows the use of the
6364<literal remap=tt>tc</literal>
6365(<emphasis>t</emphasis>ermcap in<emphasis>c</emphasis>lude)
6366facility.
6367The
6368<literal remap=tt>:tc</literal>
6369value is a list of printcap entries that should be prefixed
6370to the <emphasis>start</emphasis>
6371of the printcap entry in which it appears.
6372This allows options to be set in the printcap entry which will
6373override the values in the
6374<literal remap=tt>:tc</literal>
6375included entry.
6376For convenience,
6377the options are displayed in sorted order.</para>
6378
6379<para>The &LPRng; clients and <application>lpd</application> server may require a different set of
6380options for the same spool queue.
6381The clients require options whose values tell the clients how the
6382contact the <application>lpd</application> server and transfer a print job or query to it.
6383The <application>lpd</application> server needs options that tell it how to either print
6384a job or forward it to another <application>lpd</application> server.
6385The
6386<literal remap=tt>:client</literal>
6387or
6388<literal remap=tt>:server</literal>
6389option
6390marks a printcap entry as for client or <application>lpd</application> server use only;
6391unmarked entries are used by both server and client.
6392The
6393<command remap=tt>lpc client</command>
6394command shows the printcap information that  the
6395&LPRng; clients would use.
6396For example, here is what the <application>lpd</application> server would use:
6397<informalexample>
6398<screen><prompt>h4: {216} % </prompt><userinput>lpc server all</userinput>
6399Config
6400 :lpd_port=2000
6401 :printcap_path=/var/tmp/LPD/printcap
6402
6403Names
6404 :.client=.client
6405 :.common=.common
6406 :lp=lp
6407 :lp2=lp2
6408 :main=lp
6409
6410All
6411 :lp
6412 :lp2
6413
6414Printcap Information
6415lp|main
6416 :cm=The Main Print Queue
6417 :force_localhost
6418 :lp=/tmp/lp
6419 :mx=0
6420 :sd=/var/spool/lpd/%P
6421 :server
6422lp2
6423 :cm=The Second Print Queue
6424 :force_localhost
6425 :lp=/tmp/lp2
6426 :mx=0
6427 :sd=/var/spool/lpd/%P
6428 :server</screen>
6429</informalexample>
6430</para>
6431
6432<para>When we select the
6433<literal remap=tt>server</literal>
6434printcap information,
6435we see that the
6436<literal remap=tt>:sd</literal>
6437option has been added,
6438and the
6439<literal remap=tt>:lp</literal>
6440replaced with new values.</para>
6441
6442<para>We can use the
6443<literal remap=tt>:oh</literal>
6444(<literal remap=bf>o</literal>n this <literal remap=bf>h</literal>ost)
6445option to mark printcap entries for use by a selected set of hosts.
6446For example:
6447<informalexample>
6448<screen>lp:oh=10.0.0.0/255.255.255.0,*.private,!10.0.0.10
6449  :lp=%P@10.0.0.10</screen>
6450</informalexample>
6451</para>
6452
6453<para>The
6454<literal remap=tt>:oh</literal>
6455option takes a list of IP addresses and masks or
6456glob patterns,
6457and applies these to the IP addresses or list of Fully Qualified
6458Domain Names for the current host.
6459If there is a for at least one IP address or pattern
6460in the list match then the entry is used.
6461An exclamation mark (<literal remap=tt>!</literal>) inverts the sense of the match,
6462and the entry is used if the match fails.</para>
6463
6464<para>Finally,
6465we can use the
6466<literal remap=tt>wildcard</literal>
6467facility to cause a default printcap
6468entry to be used:
6469<informalexample>
6470<screen>lp|*:cm=Wildcard Alias - %P=lp, %Q=wanted
6471  :lp=%P@10.0.0.10
6472*:cm=Wildcard Name- %P=wanted, %Q=wanted
6473  :lp=%P@10.0.0.10</screen>
6474</informalexample>
6475</para>
6476
6477<para>The &LPRng; software first searches the printcap information for
6478an exact match.
6479If none is found then it searches for the first wildcard entry that matches
6480the printer name.
6481If the wildcard is used as an alias,
6482then the printcap entry is simply selected for use,
6483with the printer name and queue name selected as shown above.
6484We can also use partial matching as well:
6485<informalexample>
6486<screen>lp|lp_*
6487  :lp=%P@10.0.0.10
6488qt|qt_*
6489  :lp=%P@10.0.0.12</screen>
6490</informalexample>
6491</para>
6492<para>
6493In the example above the first entry
6494matches <literal/lp/ and all printer names starting with <literal/lp_/,
6495while the second entry
6496matches <literal/qt/ and all printer names starting with <literal/qt_/.
6497This can be useful when setting up a family of spool queues as discussed in
6498later sections.
6499</para>
6500
6501</sect2>
6502
6503<sect2><title>Printcap Information From Programs and Databases</title>
6504
6505<para>There many administrators store system information on a
6506database server
6507and having programs or utilities get their configuration information
6508from this server.
6509The use of the database allows easier system administration and
6510also centralizes the administration.
6511Rather than build in the various types of database access,
6512the LPRng software allows the use of programs to obtain printcap
6513information.
6514This not only allows any type of database to be used,
6515but also removes any legal or license restrictions on the redistribution
6516of the actual software.</para>
6517
6518<para>We will use very simple example to show how you can use a program
6519to get printcap information.
6520First,
6521you must configure the &LPRng; software to use a program to get the
6522filter information.
6523This is done by setting a value in the <filename>lpc.conf</filename> file
6524(usually <filename>/etc/lpd.conf</filename> or <filename>/usr/local/etc/lpd.conf</filename>).
6525Copy your <filename>lpd.conf</filename> file to <filename>lpd.conf.bak</filename> and then
6526add the following line to the end of the file:
6527<informalexample>
6528<screen>printcap_path=|/tmp/getpc
6529
6530<prompt>h4: {217} % </prompt><userinput>cd /etc</userinput>
6531<prompt>h4: {218} % </prompt><userinput>cp lpd.conf lpd.conf.bak</userinput>
6532<prompt>h4: {219} % </prompt><userinput>echo 'printcap_path=|/tmp/getpc' &gt;&gt;lpd.conf</userinput></screen>
6533</informalexample>
6534</para>
6535
6536<para>Next,
6537edit the <filename>/tmp/getpc</filename>
6538file and set its values as shown below.
6539<informalexample>
6540<screen>set /tmp/getpc:
6541
6542  #!/bin/sh
6543  # /tmp/getpc
6544  echo PROG $0 "$@" &gt;&gt;/tmp/trace
6545  cat &gt;&gt;/tmp/trace
6546  cat &lt;&lt;EOF
6547  lp:lp=test@host
6548  EOF
6549  exit 0
6550
6551<prompt>h4: {220} % </prompt><userinput>chmod 755 /tmp/getpc</userinput>
6552<prompt>h4: {221} % </prompt><userinput>echo testing | /tmp/getpc -aoption</userinput>
6553lp:lp=test@host
6554<prompt>h4: {222} % </prompt><userinput>cat /tmp/trace</userinput>
6555PROG /tmp/getpc -aoption
6556testing</screen>
6557</informalexample>
6558</para>
6559
6560<para>After you have tested the
6561<application remap=tt>getpc</application>
6562script,
6563use the
6564<command remap=tt>lpc client all</command>
6565command:
6566<informalexample>
6567<screen><prompt>h4: {223} % </prompt><userinput>lpc client all</userinput>
6568Config
6569 :lockfile=/var/tmp/LPD/lpd
6570 :lpd_port=2000
6571 :printcap_path=|/tmp/getpc
6572
6573Names
6574 :lp=lp
6575
6576All
6577 :lp
6578
6579Printcap Information
6580lp
6581 :lp=test@host
6582<prompt>h4: {224} % </prompt><userinput>cat /tmp/trace</userinput>
6583<prompt>h4: {225} % </prompt><userinput>cat /tmp/trace</userinput>
6584PROG /tmp/getpc -Pall -aacct -l66 -sstatus \
6585  -t2000-05-05-08:40:51.000 -w80 -x0 -y0 acct
6586all
6587PROG /tmp/getpc -Pall -aacct -l66 -sstatus \
6588  -t2000-05-05-08:40:51.000 -w80 -x0 -y0 acct
6589*</screen>
6590</informalexample>
6591</para>
6592
6593<para>As seen from the <filename>/tmp/trace</filename> file,
6594the
6595<command remap=tt>getpc</command>
6596program is invoked with the standard filter
6597parameters.
6598The <literal>-P</literal> command line literal is set to the name of the printcap
6599entry and the name of the entry is written to
6600the filter's <acronym/STDIN/.
6601If the entry is not found,
6602then the wildcard printcap entry will be requested.
6603The <literal>-P</literal> literal is <emphasis>not</emphasis>
6604set to
6605<literal remap=tt>*</literal>,
6606as this has the possibility of opening a security loophole
6607when a shell script parses the filter's command line options.</para>
6608
6609<para>You restore the original <filename>lpd.conf</filename>
6610file to restore the system to normal operation.
6611<informalexample>
6612<screen><prompt>h4: {226} % </prompt><userinput>cd /etc</userinput>
6613<prompt>h4: {227} % </prompt><userinput>cp lpd.conf.bak lpd.conf</userinput></screen>
6614</informalexample>
6615</para>
6616
6617<para>When using the program method to return information,
6618special consideration should be given to the
6619<literal remap=tt>all</literal>
6620request.
6621If there is not an explicit
6622<literal remap=tt>all</literal>
6623entry,
6624then the program should take appropriate steps to enumerate the
6625values in the database,
6626or report that there is a missing
6627<literal remap=tt>all</literal>
6628entry to the appropriate
6629administrative authority.</para>
6630
6631</sect2>
6632<sect2><title>User Printcap Information</title>
6633<para>
6634In addition to the system printcap,
6635each user can define a private printcap file that will be read
6636after the system printcap.
6637Users can define &LPRng; client entries and can augment the system
6638printcap information.
6639</para>
6640
6641<para>
6642By default, <filename>${HOME}/.printcap</filename> is the
6643the user printcap file.
6644Here is a simple example of a user printcap file.
6645</para>
6646
6647<informalexample>
6648<screen># remote printer - default
6649lp:lp=raw@localhost
6650  :ifhp=model=laserjet4
6651  :filter=/usr/local/libexec/filters/ifhp
6652# direct connection to printer over TCP/IP connection
6653lp:lp=10.0.0.5%9100
6654  :direct
6655  :ifhp=model=phaser
6656  :filter=/usr/local/libexec/filters/ifhp
6657</screen>
6658</informalexample>
6659
6660<para>
6661The two examples show how a simple printer definition can be created.
6662The first example shows how to create a simple way to send a file directly
6663to a remote print queue after passing it through a filter.
6664This is usually called <emphasis/client side/ filtering.
6665</para>
6666
6667<para>
6668The second example is more interesting.
6669Here we do the same thing,  but we open a connection to the remote
6670port on a host and send the print job.
6671We do not spool the print job but send it directly.
6672This is called <emphasis/lightweight lpr/ printing.
6673</para>
6674
6675<para>
6676While the user printcap file is read after the system printcap file,
6677the order of printcap entries is modified so that any entries that
6678appeared in the user printcap file will appear before entries in the
6679system printcap file.
6680This allows users to  modify the order in which printer entries are
6681displayed.
6682</para>
6683</sect2>
6684
6685</sect1>
6686
6687<sect1><title>Banner Printing and the OF filter</title>
6688
6689<para>Banner or header pages can be printed at the beginning,
6690end, or both at the beginning or end.
6691The following flags control how and where banners are printed.
6692These flags are listed in order of precedence.
6693<variablelist>
6694<varlistentry><term> <literal>:sh</literal>
6695</term>
6696<listitem>
6697<para>Suppress all banner printing or header pages.
6698This prevents any banners from being generated by the <application>lpd</application>
6699print spooler and if present in a client printcap entry,
6700will cause <application>lpr</application> not to put any banner printing information in the
6701control file.
6702Even if this flag is not present,
6703then &LPRng; will not print a banner unless a banner printing
6704program is specified with the
6705<literal remap=tt>:bp,</literal>
6706<literal remap=tt>:bs</literal>,
6707<literal remap=tt>:be</literal>,
6708or
6709<literal remap=tt>:sb</literal>
6710option.</para>
6711
6712</listitem>
6713</varlistentry>
6714
6715<varlistentry><term>
6716<literal remap=tt>:ab</literal>
6717</term>
6718
6719<listitem>
6720<para>Print a banner or header page,
6721even if the user has not requested one.
6722The
6723<literal remap=tt>:sh</literal>
6724option has precedence over the
6725<literal remap=tt>:ab</literal>
6726option.</para>
6727
6728</listitem>
6729</varlistentry>
6730
6731<varlistentry><term>
6732<literal remap=tt>:hl</literal>
6733</term>
6734
6735<listitem>
6736<para>The banner (header) is at the end (last page) of the job.</para>
6737
6738</listitem>
6739</varlistentry>
6740
6741<varlistentry><term> <literal>:bs=/... </literal> and  <literal>:be=/... </literal> and  </term>
6742
6743<listitem>
6744<para>The
6745<literal remap=tt>:bs</literal>
6746and
6747<literal remap=tt>:be</literal>
6748options specify that a banner page
6749is to be generated at the start and end of the job respectively,
6750using indicated filter program.
6751If the
6752<literal remap=tt>:hl</literal>
6753flag has been set,
6754only the
6755<literal remap=tt>:be</literal>
6756will be used.</para>
6757
6758</listitem>
6759</varlistentry>
6760
6761<varlistentry><term> <literal>:bp=</literal>... </term>
6762
6763<listitem>
6764<para>If there is no
6765<literal remap=tt>:bs</literal>
6766or
6767<literal remap=tt>:be</literal>
6768value when printing
6769a banner at the start or end of the job respectively,
6770then use the indicated filter program to generate a banner.</para>
6771
6772</listitem>
6773</varlistentry>
6774
6775<varlistentry><term>
6776<literal remap=tt>:sb</literal>
6777and <literal>:bl=....</literal></term>
6778
6779<listitem>
6780<para>If there is no program specified to generate the banner
6781and the
6782<literal remap=tt>:sb</literal>
6783flag is set,
6784send the
6785<literal remap=tt>:bl</literal>
6786 (banner line) string
6787to the printer.</para>
6788
6789</listitem>
6790</varlistentry>
6791
6792<varlistentry><term> <literal>:of=filter</literal> </term>
6793
6794<listitem>
6795<para>A filter used to process banners and other non-job file information.</para>
6796
6797</listitem>
6798</varlistentry>
6799
6800<varlistentry><term>
6801<literal remap=tt>:suspend_of_filter</literal>
6802</term>
6803
6804<listitem>
6805<para>Controls whether the
6806<literal remap=tt>:of</literal>
6807filter is suspended or has its input terminated.</para>
6808
6809</listitem>
6810</varlistentry>
6811</variablelist>
6812</para>
6813
6814<para>The
6815<application remap=tt>pclbanner</application>,
6816<application remap=tt>psbanner</application>,
6817and
6818<application remap=tt>lpbanner</application>
6819programs are part of the &LPRng; distribution and are usually
6820installed in the same location as the &LPRng; supported filters.
6821They produce a PCL,
6822PostScript,
6823or text banner respectively.</para>
6824
6825<para>The OF filter (<literal>:of=/path</literal>)
6826is used to process banner pages and to do any necessary
6827setup to initialize the printer to handle banner pages.
6828This filter has the following unusual  behavior:
6829<itemizedlist>
6830
6831<listitem>
6832<para>It must be explicitly specified in the printcap file.
6833It is not run by default.
6834</para>
6835
6836<para>If specified,
6837it is started at the beginning of job printing
6838and stays present throughout the entire job printing session.</para>
6839</listitem>
6840
6841<listitem>
6842<para>When printing individual files,
6843the
6844<literal remap=tt>:of</literal>
6845filter is sent a special <emphasis>suspend yourself</emphasis>
6846two character string,
6847<literal remap=tt>\031\001</literal>.
6848This will cause the
6849<literal remap=tt>:of</literal>
6850filter to send itself a <acronym>SIGSUSP</acronym>
6851(suspend) signal.</para>
6852</listitem>
6853
6854<listitem>
6855<para>The
6856<literal remap=tt>:of</literal>
6857filter is restarted when any information not part of a
6858print job file,
6859such as the
6860initialization string (<literal remap=tt>:ld</literal>
6861option),
6862termination string (<literal remap=tt>:ld</literal>
6863option),
6864or form feeds at
6865start (<literal remap=tt>:fo</literal>),
6866end (<literal remap=tt>:fq</literal>),
6867and between job files (<literal remap=tt>:ff_separator</literal>),
6868and when banners
6869are generated by the
6870<literal remap=tt>:bp</literal>,
6871<literal remap=tt>:bs</literal>,
6872<literal remap=tt>:be</literal>,
6873or
6874<literal remap=tt>:sb</literal>
6875option and need to be sent to the printer.</para>
6876</listitem>
6877
6878</itemizedlist>
6879</para>
6880
6881<para>This rather baroque behavior is mostly historical in origin,
6882and is very much embedded in the existing documentation and methodologies
6883of the BSD print spooling system.
6884Originally,
6885when a printer port was opened,
6886a special device initialization string was sent by the printer port device
6887driver;
6888this usually resulted in an extra page of paper being ejected by the printer.
6889By opening the device once and then keeping it open,
6890the print spooler would avoid the wasted paper.
6891The reason for suspending the
6892<literal remap=tt>:of</literal>
6893filter was simply to save the overhead
6894of creating an extra processes.</para>
6895
6896<para>Unfortunately,
6897the
6898<literal remap=tt>:of</literal>
6899filter suspension behavior is now a problem rather than
6900a benefit.
6901For example,
6902for many devices to finish printing a page correctly the filter
6903must be closed in order for it to flush buffers and for the low level
6904drivers to properly finish.
6905In order to provide this functionality,
6906the <literal>suspend_of_filter@</literal> flag can be used.
6907This will cause the <application>lpd</application> server to close the
6908<literal remap=tt>:of</literal>
6909filters input,
6910rather than sending it the suspend string,
6911and to restart a new
6912<literal remap=tt>:of</literal>
6913filter process when necessary.</para>
6914
6915</sect1>
6916
6917<sect1><title>Printing from <application/lpr/ Directly To A Device</title>
6918<para>
6919While the most reliable way to print is to send jobs to a print spooler,
6920sometimes it is desirable to print directly to a printer.
6921This method is supported by the special
6922<literal/:direct/
6923printcap flag or the
6924<application/lpr/
6925<literal/-Y/ command line flag.
6926The following shows the effects of this flag:
6927</para>
6928<informalexample>
6929<screen>lpr -Y -Phost%port file1 file2 ...
6930Eqivalent to:
6931  ( for i in file1 file2 ... ; do
6932    $filter $i
6933  done ) | tcpip_connection( host%port)
6934
6935lpr -Y -P/dev/lp file1 file2 ...
6936Eqivalent to:
6937  ( for i in file1 file2 ... ; do
6938    $filter $i
6939  done ) >>/dev/lp
6940
6941lpr -Y -P '|/program' file1 file2 ...
6942Eqivalent to:
6943  ( for i in file1 file2 ... ; do
6944    $filter $i
6945  done ) | /program
6946</screen>
6947</informalexample>
6948<para>
6949The above examples show how we can use the command line
6950options to send files directly to a printer.
6951You can also create a printcap that will do the same:
6952</para>
6953<informalexample>
6954<screen>lp:direct:lp=/tmp/a:remote_support=R
6955Command:
6956  lpr -Plp file1 file2 ...
6957Equivalent to:
6958lpr -P/tmp/a -Y file1 file2 ...
6959
6960Example:
6961<prompt>h4: {228} % </prompt><userinput>lp -P/tmp/a /tmp/hi</userinput>
6962<prompt>h4: {229} % </prompt><userinput>cat /tmp/a /tmp/hi</userinput>
6963hi
6964<prompt>h4: {230} % </prompt><userinput>lp -Plp /tmp/hi</userinput>
6965<prompt>h4: {231} % </prompt><userinput>cat /tmp/a /tmp/hi</userinput>
6966hi
6967hi
6968</screen>
6969</informalexample>
6970<para>
6971The <application/lpr/ <literal/-X filter/ option allows us to specify
6972a user filter on the command line.
6973We will use a simple example to show how this capability could be used
6974in practice.
6975Create the <filename>/tmp/pass</filename> file with the
6976following contents, and give it executable permissions as shown
6977below:
6978<informalexample>
6979<screen>#!/bin/sh
6980# /tmp/pass file
6981echo LEADER
6982cat
6983echo TRAILER
6984exit 0
6985</screen>
6986</informalexample>
6987</para>
6988<para>
6989Execute the following commands
6990to print the <filename>/tmp/hi</filename> file
6991and observe the results:
6992<informalexample><screen><prompt>h4: {232} % </prompt><userinput>cp /dev/null /tmp/a</userinput>
6993<prompt>h4: {233} % </prompt><userinput>lpr -P/tmp/a -X /tmp/pass /tmp/hi</userinput>
6994<prompt>h4: {234} % </prompt><userinput>cat /tmp/a</userinput>
6995LEADER
6996hi
6997TRAILER
6998</screen>
6999</informalexample>
7000</para>
7001<para>
7002As we see from the example,
7003our filter has processed the input file and added the <literal/LEADER/
7004and <literal/TRAILER/ strings.
7005In practice,
7006the actual processing of the input job would be far more elaborate,
7007and may do such things as incorporate files or other material
7008available only on the local system.
7009We can also use a printcap entry:
7010</para>
7011<informalexample><screen>lp:direct:lp=/tmp/a:filter=/tmp/pass
7012
7013<prompt>h4: {235} % </prompt><userinput>cp /dev/null /tmp/a</userinput>
7014<prompt>h4: {236} % </prompt><userinput>lpr -Plp /tmp/hi</userinput>
7015<prompt>h4: {237} % </prompt><userinput>cat /tmp/a</userinput>
7016LEADER
7017hi
7018TRAILER
7019</screen>
7020</informalexample>
7021</sect1>
7022
7023<sect1><title>Moving Jobs From Queue to Queue and Redirecting Queues</title>
7024
7025<para>The
7026<command remap=tt>lpc move</command>
7027command is used to move jobs in one queue to another queue on
7028an individual basis,
7029while the
7030<command remap=tt>lpc redirect</command>
7031command redirects all incoming jobs
7032to a new queue.
7033Edit the printcap file so it has contents indicated below,
7034use <command>checkpc -f</command> to check the printcap,
7035and then use
7036<command remap=tt>lpc reread</command>
7037to restart the <application>lpd</application> server.
7038<informalexample>
7039<screen>lp:force_localhost
7040lp:server
7041  :sd=/var/spool/lpd/%P
7042  :lp=lp2@localhost
7043lp2:force_localhost
7044lp2:server
7045  :sd=/var/spool/lpd/%P
7046  :lp=/tmp/lp2</screen>
7047</informalexample>
7048
7049Execute the following commands
7050to print the <filename>/tmp/hi</filename> file
7051and observe the results:
7052<informalexample>
7053<screen><prompt>h4: {238} % </prompt><userinput>lpc stop lp lp2</userinput>
7054Printer: lp@h4
7055lp@h4.private: stopped
7056Printer: lp2@h4
7057lp2@h4.private: stopped
7058<prompt>h4: {239} % </prompt><userinput>lpr /tmp/hi</userinput>
7059<prompt>h4: {240} % </prompt><userinput>lpq -a</userinput>
7060Printer: lp@h4  (printing disabled)
7061 Queue: 1 printable job
7062 Server: no server active
7063 Rank   Owner/ID           Class Job Files      Size Time
70641      papowell@h4+659       A   659 /tmp/hi       3 08:04:03
7065Printer: lp2@h4  (printing disabled)
7066 Queue: no printable jobs in queue
7067<prompt>h4: {241} % </prompt><userinput>lpc move lp papowell lp2</userinput>
7068Printer: lp@h4
7069lp: selected 'papowell@h4+659'
7070lp@h4.private: move done
7071<prompt>h4: {242} % </prompt><userinput>lpq -a</userinput>
7072Printer: lp@h4  (printing disabled)
7073 Queue: no printable jobs in queue
7074 Status: job 'papowell@h4+659' removed at 08:19:24.962
7075Printer: lp2@h4  (printing disabled)
7076 Queue: 1 printable job
7077 Server: no server active
7078 Rank   Owner/ID           Class Job Files       Size Time
70791      papowell@h4+659       A   659 /tmp/hi        3 08:19:24</screen>
7080</informalexample>
7081</para>
7082
7083<para>We first stop the queues so that the jobs will remain in them.
7084We then use the
7085<command remap=tt>lpc move fromqueue id toqueue</command>
7086command to select a job
7087in the
7088<emphasis>fromqueue</emphasis>
7089and move it to the
7090<emphasis>toqueue</emphasis>.
7091A list of job numbers, job IDs, or glob patterns to match job
7092IDs can be used to select the job.</para>
7093
7094<para>The
7095<command remap=tt>lpc redirect fromqueue toqueue</command>
7096will cause all incoming
7097jobs to be redirected to the specified queue.
7098You can execute the following commands and observe the results.
7099<informalexample>
7100<screen><prompt>h4: {243} % </prompt><userinput>lpc redirect lp lp2</userinput>
7101Printer: lp@h4
7102forwarding to 'lp2'
7103lp@h4.private: redirected
7104<prompt>h4: {244} % </prompt><userinput>lpq -a</userinput>
7105Printer: lp@h4  (printing disabled) (redirect lp2)
7106 Queue: no printable jobs in queue
7107Printer: lp2@h4  (printing disabled)
7108 Queue: no printable jobs in queue
7109<prompt>h4: {245} % </prompt><userinput>lpr /tmp/hi</userinput>
7110<prompt>h4: {246} % </prompt><userinput>lpq -a</userinput>
7111Printer: lp@h4  (printing disabled) (redirect lp2)
7112 Queue: no printable jobs in queue
7113 Status: job 'papowell@h4+935' removed at 09:08:21.410
7114Printer: lp2@h4  (printing disabled)
7115 Queue: 1 printable job
7116 Server: no server active
7117 Rank   Owner/ID           Class Job Files        Size Time
71181      papowell@h4+935       A   935 /tmp/hi         3 09:08:21</screen>
7119</informalexample>
7120</para>
7121
7122<para>To turn redirection off, use
7123<command remap=tt>lpc redirect queue off</command>
7124as shown in the example below:
7125<informalexample>
7126<screen><prompt>h4: {247} % </prompt><userinput>lpc redirect lp off</userinput>
7127Printer: lp@h4
7128forwarding off
7129<prompt>h4: {248} % </prompt><userinput>lpq</userinput>
7130Printer: lp@h4  (printing disabled)
7131 Queue: no printable jobs in queue
7132 Status: job 'papowell@h4+935' removed at 09:08:21.410</screen>
7133</informalexample>
7134</para>
7135
7136</sect1>
7137
7138<sect1><title>Print Job Classes, User Requested Job Priority, and Form Support</title>
7139
7140<para>The &LPRng; software allows users to assign a class name to print
7141jobs using the <command>lpr -Cname</command> option.
7142This causes the <application>lpr</application> command to put the line
7143<literal remap=tt>Cname</literal>
7144in the control file.
7145By default,
7146the (upper cased) first letter of the class name is used to
7147assign a user requested priority to the job,
7148with
7149<literal remap=tt>A</literal>
7150being the default lowest priority and
7151<literal remap=tt>Z</literal>
7152being the highest.</para>
7153
7154<para>The <literal>ignore_requested_user_priority</literal>
7155printcap option can be used to ignore the user requested priority
7156and jobs will be printed in the normal first-in first-out order.</para>
7157
7158<para>&LPRng; also makes use of the class information to do form support
7159and restrict printing to a specific set of classes.
7160By default the job class information is ignored,
7161but the
7162<command remap=tt>lpc class</command>
7163command can be used to specify one or
7164more classes (actually glob patterns) to be printed.
7165This facility can be used to do support printing of jobs that
7166require a specific form setup.
7167Here is a simple example of how to use this facility.</para>
7168
7169<para>Edit the printcap file so it has contents indicated below,
7170use <command>checkpc -f</command> to check the printcap,
7171and then use
7172<command remap=tt>lpc reread</command>
7173to restart the <application>lpd</application> server.
7174<informalexample>
7175<screen>lp:force_localhost
7176lp:server
7177  :sd=/var/spool/lpd/%P
7178  :lp=lp2@localhost
7179lp2:force_localhost
7180lp2:server
7181  :sd=/var/spool/lpd/%P
7182  :lp=/tmp/lp2</screen>
7183</informalexample>
7184
7185Execute the following commands
7186to print the <filename>/tmp/hi</filename> file
7187and observe the results:
7188<informalexample>
7189<screen><prompt>h4: {249} % </prompt><userinput>lpc class lp red</userinput>
7190Printer: lp@h4
7191classes printed 'red'
7192lp@h4.private: class updated
7193<prompt>h4: {250} % </prompt><userinput>lpq</userinput>
7194Printer: lp@h4  (classes red)
7195 Queue: no printable jobs in queue
7196<prompt>h4: {251} % </prompt><userinput>lpr /tmp/hi</userinput>
7197<prompt>h4: {252} % </prompt><userinput>lpq</userinput>
7198Printer: lp@h4  (classes red)
7199 Queue: no printable jobs in queue
7200 Holding: 1 held jobs in queue
7201 Server: no server active
7202 Rank   Owner/ID           Class Job Files        Size Time
7203holdclass papowell@h4+82     A    82 /tmp/hi         3 09:29:52
7204<prompt>h4: {253} % </prompt><userinput>lpr -Cred /tmp/hi</userinput>
7205<prompt>h4: {254} % </prompt><userinput>lpq</userinput>
7206Printer: lp@h4  (classes red)
7207 Queue: no printable jobs in queue
7208 Holding: 1 held jobs in queue
7209 Server: no server active
7210 Status: job 'papowell@h4+89' removed at 09:30:13.569
7211 Rank   Owner/ID           Class Job Files        Size Time
7212holdclass papowell@h4+82     A    82 /tmp/hi         3 09:29:52</screen>
7213</informalexample>
7214</para>
7215
7216<para>As seen in the example,
7217we set the queue class to
7218<literal remap=tt>red</literal>,
7219and then sent a (default) class
7220<literal remap=tt>A</literal>
7221job to the printer.
7222It was not printed, and is listed with
7223<literal remap=tt>holdclass</literal>
7224status.
7225We sent another job which was immediately printed.</para>
7226
7227<para>We can change the print queue class at any time,
7228and then new class will then control what jobs are printed.
7229To disable the class selection, use the
7230<command remap=tt>lpc class queue off</command>
7231command.
7232<informalexample>
7233<screen><prompt>h4: {255} % </prompt><userinput>lpc class lp off</userinput>
7234Printer: lp@h4
7235all classes printed
7236lp@h4.private: class updated</screen>
7237</informalexample>
7238</para>
7239
7240</sect1>
7241
7242<sect1><title>Holding and Releasing Jobs</title>
7243
7244<para>The &LPRng; software has a wide range of facilities to hold or
7245temporarily prevent jobs from printing.
7246Jobs can be individually held
7247or all jobs submitted to a queue can be held
7248until released by an operator.
7249Some administrators use the
7250<command remap=tt>holdall</command>
7251facility and a
7252<application remap=tt>cron</application>
7253script to cause jobs to be printed
7254at specific times.
7255The
7256<command remap=tt>lpc holdall</command>
7257command causes all jobs submitted
7258to a queue to be held until released with the
7259<command remap=tt>lpc release</command>
7260command.
7261The
7262<command remap=tt>lpc noholdall</command>
7263command disables the
7264<command remap=tt>holdall</command>
7265operation.</para>
7266
7267<para>Edit the printcap file so it has contents indicated below,
7268use <command>checkpc -f</command> to check the printcap,
7269and then use
7270<command remap=tt>lpc reread</command>
7271to restart the <application>lpd</application> server.
7272<informalexample>
7273<screen>lp:force_localhost
7274lp:server
7275  :sd=/var/spool/lpd/%P
7276  :lp=lp2@localhost
7277lp2:force_localhost
7278lp2:server
7279  :sd=/var/spool/lpd/%P
7280  :lp=/tmp/lp2</screen>
7281</informalexample>
7282</para>
7283
7284<para>Execute the following commands
7285to print the <filename>/tmp/hi</filename> file
7286and observe the results:
7287<informalexample>
7288<screen><prompt>h4: {256} % </prompt><userinput>lpc holdall lp</userinput>
7289Printer: lp@h4
7290lp@h4.private: holdall on
7291<prompt>h4: {257} % </prompt><userinput>lpq</userinput>
7292Printer: lp@h4  (holdall)
7293 Queue: no printable jobs in queue
7294<prompt>h4: {258} % </prompt><userinput>lpr /tmp/hi</userinput>
7295<prompt>h4: {259} % </prompt><userinput>lpq</userinput>
7296Printer: lp@h4  (holdall)
7297 Queue: no printable jobs in queue
7298 Holding: 1 held jobs in queue
7299 Server: no server active
7300 Rank   Owner/ID           Class Job Files        Size Time
7301hold   papowell@h4+213       A   213 /tmp/hi         3 09:45:05
7302<prompt>h4: {260} % </prompt><userinput>lpc release lp 213</userinput>
7303Printer: lp@h4
7304lp: selected 'papowell@h4+213'
7305lp@h4.private: started
7306<prompt>h4: {261} % </prompt><userinput>lpq</userinput>
7307Printer: lp@h4  (holdall)
7308 Queue: no printable jobs in queue
7309 Status: job 'papowell@h4+213' removed at 09:45:22.570</screen>
7310</informalexample>
7311</para>
7312
7313<para>The
7314<command remap=tt>lpc holdall</command>
7315command causes all jobs to be held.
7316We spool a job,
7317and then use the
7318<command remap=tt>lpc release</command>
7319command to release the selected job.
7320We disable the
7321<command remap=tt>holdall</command>
7322operation using the
7323<command remap=tt>lpc noholdall</command>
7324command.
7325<informalexample>
7326<screen><prompt>h4: {262} % </prompt><userinput>lpc noholdall lp</userinput>
7327Printer: lp@h4
7328lp@h4.private: holdall off</screen>
7329</informalexample>
7330</para>
7331
7332<para>You can also use the
7333<command remap=tt>lpc hold</command>
7334command
7335to select individual jobs in a spool queue to be held.
7336This command is useful if there is a set of jobs which require
7337special handling or printing at a later date.
7338The following example shows how this command is used.
7339We use the
7340<command remap=tt>lpc stop</command>
7341and
7342<command remap=tt>lpc start</command>
7343commands
7344to simulate the normal delays in print spooling operations.
7345<informalexample>
7346<screen><prompt>h4: {263} % </prompt><userinput>lpc stop lp</userinput>
7347Printer: lp@h4
7348lp@h4.private: stopped
7349<prompt>h4: {264} % </prompt><userinput>lpq</userinput>
7350Printer: lp@h4  (printing disabled)
7351 Queue: no printable jobs in queue
7352 Status: job 'papowell@h4+495' removed at 10:10:50.629
7353<prompt>h4: {265} % </prompt><userinput>lpr /tmp/hi</userinput>
7354<prompt>h4: {266} % </prompt><userinput>lpr /tmp/hi</userinput>
7355<prompt>h4: {267} % </prompt><userinput>lpq</userinput>
7356Printer: lp@h4  (printing disabled)
7357 Queue: 2 printable jobs
7358 Server: no server active
7359 Rank   Owner/ID           Class Job Files        Size Time
73601      papowell@h4+459       A   459 /tmp/hi         3 10:40:32
73612      papowell@h4+461       A   461 /tmp/hi         3 10:40:34
7362<prompt>h4: {268} % </prompt><userinput>lpc hold lp 459</userinput>
7363Printer: lp@h4
7364lp: selected 'papowell@h4+459'
7365lp@h4.private: updated
7366<prompt>h4: {269} % </prompt><userinput>lpq</userinput>
7367Printer: lp@h4  (printing disabled)
7368 Queue: 1 printable job
7369 Holding: 1 held jobs in queue
7370 Server: no server active
7371 Rank   Owner/ID           Class Job Files        Size Time
73721      papowell@h4+461       A   461 /tmp/hi         3 10:40:34
7373hold   papowell@h4+459       A   459 /tmp/hi         3 10:40:32</screen>
7374</informalexample>
7375</para>
7376
7377<para>In the next example
7378we show how to use the
7379<command remap=tt>lpc hold</command>
7380command to select and hold an individual job.
7381Then we start the queue and see what happens:
7382<informalexample>
7383<screen><prompt>h4: {270} % </prompt><userinput>lpc start</userinput>
7384Printer: lp@h4
7385lp@h4.private: started
7386<prompt>h4: {271} % </prompt><userinput>lpq</userinput>
7387Printer: lp@h4
7388 Queue: no printable jobs in queue
7389 Holding: 1 held jobs in queue
7390 Server: no server active
7391 Status: job 'papowell@h4+461' removed at 10:41:24.873
7392 Rank   Owner/ID           Class Job Files        Size Time
7393hold   papowell@h4+459       A   459 /tmp/hi         3 10:40:32
7394<prompt>h4: {272} % </prompt><userinput>lpc release lp 459</userinput>
7395Printer: lp@h4
7396lp: selected 'papowell@h4+459'
7397lp@h4.private: started
7398<prompt>h4: {273} % </prompt><userinput>lpq</userinput>
7399Printer: lp@h4
7400 Queue: no printable jobs in queue
7401 Status: job 'papowell@h4+459' removed at 10:41:39.457</screen>
7402</informalexample>
7403</para>
7404
7405<para>As we see,
7406the held job is not printed until we release it,
7407and then is processed normally.</para>
7408
7409<para>The printcap
7410<literal remap=tt>:ah</literal>
7411(autohold)
7412option has the same effect as the
7413<command remap=tt>lpc holdall</command>
7414command
7415but its actions cannot be disabled by the
7416<command remap=tt>lpc noholdall</command>
7417command.</para>
7418
7419</sect1>
7420
7421<sect1><title>Load Balance Queues and Printer Pools</title>
7422
7423<para>A Load Balance Queue provides a way to use multiple printers
7424for a single print queue.
7425All jobs are normally sent to the main or
7426load balance queue
7427which then dispatches the jobs to
7428<emphasis>server</emphasis>
7429queues or printers that do the actual printing
7430as they become available.
7431You can also send jobs to the individual server printers
7432if they have special processing or setups required for a particular
7433job.
7434Because all of the server printers are shared by the
7435load balance queue,
7436they are said to be in a <emphasis>printer pool</emphasis>.</para>
7437
7438<para>Edit the printcap file so it have the contents indicated below,
7439create the <filename>/tmp/lp2</filename> and <filename>/tmp/lp3</filename>
7440files with
7441<literal remap=tt>0777</literal>
7442permissions,
7443use <command>checkpc -f</command> to check the printcap,
7444and then use
7445<command remap=tt>lpc reread</command>
7446to restart the <application>lpd</application> server.
7447<informalexample>
7448<screen># printcap
7449lp:force_localhost
7450lp:server
7451  :sd=/var/spool/lpd/%P
7452  :sv=lp2,lp3
7453lp2:force_localhost
7454lp2:server
7455  :ss=lp
7456  :sd=/var/spool/lpd/%P
7457  :lp=/tmp/lp2
7458lp3:force_localhost
7459lp3:server
7460  :ss=lp
7461  :sd=/var/spool/lpd/%P
7462  :lp=/tmp/lp2</screen>
7463</informalexample>
7464</para>
7465
7466<para>The <literal>:sv=...</literal> option flags the queue as a load balance queue
7467and lists the queues that are used for load balancing.
7468The <literal>:ss=...</literal> option flags the queue as a server for a load balance
7469queue and specifies the name of the load balance queue.
7470When a job is sent to the load balance queue
7471the <application>lpd</application> server checks to see which server queues are available
7472and then the first one to become available.</para>
7473
7474<para>Execute the following commands
7475to print the <filename>/tmp/hi</filename> file
7476and observe the results:
7477<informalexample>
7478<screen><prompt>h4: {274} % </prompt><userinput>lpq</userinput>
7479Printer: lp@h4  (subservers lp2, lp3)
7480 Queue: no printable jobs in queue
7481 Status: job 'papowell@h4+42' removed at 07:29:57.924
7482Server Printer: lp2@h4  (serving lp)
7483 Queue: no printable jobs in queue
7484Server Printer: lp3@h4  (serving lp)
7485 Queue: no printable jobs in queue
7486<prompt>h4: {275} % </prompt><userinput>lpr /tmp/hi</userinput>
7487<prompt>h4: {276} % </prompt><userinput>lpq</userinput>
7488Printer: lp@h4  (subservers lp2, lp3)
7489 Queue: 1 printable job
7490 Server: pid 4063 active
7491 Status: waiting for subserver to finish at 07:31:08.074
7492 Rank   Owner/ID           Class Job Files        Size Time
74931      papowell@h4+62        A    62 /tmp/hi         3 07:31:07
7494Server Printer: lp2@h4  (serving lp)
7495 Queue: no printable jobs in queue
7496Server Printer: lp3@h4  (serving lp)
7497 Queue: no printable jobs in queue
7498<prompt>h4: {277} % </prompt><userinput>lpq</userinput>
7499Printer: lp@h4  (subservers lp2, lp3)
7500 Queue: no printable jobs in queue
7501 Status: no more jobs to process in load balance queue at 07:31:12.317
7502Server Printer: lp2@h4  (serving lp)
7503 Queue: no printable jobs in queue
7504Server Printer: lp3@h4  (serving lp)
7505 Queue: no printable jobs in queue
7506 Status: job 'papowell@h4+62' removed at 07:31:10.311</screen>
7507</informalexample>
7508</para>
7509
7510<para>The first <application>lpq</application> command shows how the status is displayed for a load balance
7511queue - the queue and its server queues are shown as well.
7512Next,
7513we use <application>lpr</application> to print a job (job id <literal>papowell@h4+62</literal>).
7514We then use a couple of <application>lpq</application> commands to see how the job is first
7515sent to the
7516<literal remap=tt>lp</literal>
7517queue,
7518which then forwards it to the
7519<literal remap=tt>lp3</literal>
7520queue,
7521which then processes it and removes it.
7522(For purposes of demonstration we have artificially slowed down the operation
7523of the load balance queue so that the jobs will remain in the queue
7524for sufficient time for us to display their status.)
7525We can send another job to the load balance queue:
7526<informalexample>
7527<screen><prompt>h4: {278} % </prompt><userinput>lpr /tmp/hi</userinput>
7528<prompt>h4: {279} % </prompt><userinput>lpq</userinput>
7529Printer: lp@h4  (subservers lp2, lp3)
7530 Queue: no printable jobs in queue
7531 Status: no more jobs to process in load balance queue at 07:37:17.953
7532Server Printer: lp2@h4  (serving lp)
7533 Queue: no printable jobs in queue
7534 Status: job 'papowell@h4+89' removed at 07:37:15.936
7535Server Printer: lp3@h4  (serving lp)
7536 Queue: no printable jobs in queue
7537 Status: job 'papowell@h4+81' removed at 07:36:40.116</screen>
7538</informalexample>
7539</para>
7540
7541<para>This time we see that the job was put in
7542<literal remap=tt>lp2</literal>.
7543The normal load balance queue operation is to use the server queues in round robin order.</para>
7544
7545<para>While this simple configuration is suitable for a large number of
7546configurations,
7547there are situations where server queue must be chosen
7548<emphasis>dynamically</emphasis>.
7549For example,
7550if the server queues are actually transferring jobs to remote clients
7551then as soon as the job is sent to the remote client the
7552queue appears empty and available for use.
7553To correctly check to see if the queue is available,
7554the status of the remote queue or destination of the server queue must
7555be checked.</para>
7556
7557<para>To handle this situation,
7558a
7559<literal remap=tt>:chooser</literal>
7560program or filter can be used.
7561When the load balance queue is trying to decide where to send a job,
7562it first checks the server queues to see if they are enabled for printing.
7563If a
7564<literal remap=tt>:chooser</literal>
7565program is specified in the load balance queue printcap
7566entry,
7567then it is started with the normal filter options and environment variables,
7568supplemented as discussed below.
7569The
7570<literal remap=tt>:chooser</literal>
7571program will read a list of candidate queues from its
7572<acronym/STDIN/,
7573write the chosen one to its <acronym/STDOUT/,
7574and then exit.
7575The <application>lpd</application> server checks the
7576<literal remap=tt>:chooser</literal>
7577exit code -
7578if it is zero (successful) then the chosen queue is used otherwise
7579the exit code is used for the result value of processing the job.
7580This allows the chooser process to not only control the destination of the job
7581but also to hold, remove, or abort the job handling process.
7582If the
7583<literal remap=tt>:chooser</literal>
7584does not specify a queue,
7585then the job is skipped and another job is chosen.</para>
7586
7587<para>One side effect of the using a chooser program is that while there are jobs
7588that can be processed in the queue the <application>lpd</application> server needs to periodically
7589check to see if a server queue has become available.
7590If it did this continually then a very high load would be put on the system.
7591Instead,
7592the <literal>chooser_interval</literal> option specifies a maximum time in seconds (default 10 seconds)
7593between the times that the <application>lpd</application> server checks to see if there is an
7594available server.</para>
7595
7596<para>Edit the printcap file so it have the contents indicated below,
7597create the <filename>/tmp/lp2</filename> and <filename>/tmp/lp3</filename>
7598files with
7599<literal remap=tt>0777</literal>
7600permissions.
7601Then create the <filename>/tmp/chooser.script</filename>
7602with the contents indicated below,
7603and give it
7604<literal remap=tt>0755</literal>
7605(executable) permissions.
7606Make sure that the path to the
7607<application remap=tt>head</application>
7608program used in
7609<filename>chooser.script</filename> is correct.
7610Use <command>checkpc -f</command> to check the printcap,
7611and then use
7612<command remap=tt>lpc reread</command>
7613to restart the <application>lpd</application> server.
7614<informalexample>
7615<screen># printcap
7616lp:force_localhost
7617lp:server
7618  :sd=/var/spool/lpd/%P
7619  :sv=lp2,lp3
7620  :chooser=/tmp/chooser.script
7621lp2:force_localhost
7622lp2:server
7623  :ss=lp
7624  :sd=/var/spool/lpd/%P
7625  :lp=/tmp/lp2
7626lp3:force_localhost
7627lp3:server
7628  :ss=lp
7629  :sd=/var/spool/lpd/%P
7630  :lp=/tmp/lp2
7631
7632# /tmp/chooser.script
7633
7634#!/bin/sh
7635echo CHOOSER $0 $@ &gt;&gt;/tmp/chooser
7636set &gt;&gt;/tmp/chooser
7637/usr/bin/head -1
7638exit 0</screen>
7639</informalexample>
7640</para>
7641
7642<para>Now run the following commands:
7643<informalexample>
7644<screen><prompt>h4: {280} % </prompt><userinput>lpr /tmp/hi</userinput>
7645<prompt>h4: {281} % </prompt><userinput>lpq -lll</userinput>
7646Printer: lp@h4  (subservers lp2, lp3)
7647 Queue: no printable jobs in queue
7648 Status: CHOOSER selected 'lp3' at 14:02:50.605
7649 Status: transferring 'papowell@h4+178' 
7650      to subserver 'lp3' at 14:02:50.614
7651 Status: transfer 'papowell@h4+178' 
7652      to subserver 'lp3' finished at 14:02:50.624
7653 Status: job 'papowell@h4+178' removed at 14:02:50.632
7654 Status: starting subserver 'lp3' at 14:02:50.632
7655 Status: waiting for server queue process to exit at 14:02:50.651
7656 Status: subserver pid 10182 exit status 'JSUCC' at 14:02:52.872
7657 Status: no more jobs to process in load balance queue at 14:02:52.879
7658Server Printer: lp2@h4  (serving lp)
7659 Queue: no printable jobs in queue
7660Server Printer: lp3@h4  (serving lp)
7661 Queue: no printable jobs in queue
7662 Status: waiting for subserver to exit at 14:02:50.748
7663 Status: subserver pid 10183 starting at 14:02:50.820
7664 Status: accounting at start at 14:02:50.821
7665 Status: opening device '/tmp/lp3' at 14:02:50.833
7666 Status: printing job 'papowell@h4+178' at 14:02:50.834
7667 Status: processing 'dfA178h4.private', size 3, format 'f', \
7668      IF filter 'none - passthrough' at 14:02:50.838
7669 Status: printing finished at 14:02:50.839
7670 Status: accounting at end at 14:02:50.839
7671 Status: finished 'papowell@h4+178', status 'JSUCC' at 14:02:50.841
7672 Status: subserver pid 10183 exit status 'JSUCC' at 14:02:50.843
7673 Status: lp3@h4.private: job 'papowell@h4+178' printed at 14:02:50.856
7674 Status: job 'papowell@h4+178' removed at 14:02:50.871</screen>
7675</informalexample>
7676</para>
7677
7678<para>As you see from the example above,
7679the <acronym>CHOOSER</acronym> selected
7680<literal remap=tt>lp3</literal>
7681for use.
7682Let us look at the <filename>/tmp/chooser</filename> file and see how the
7683<filename>chooser.script</filename> program was run:
7684<informalexample>
7685<screen>CHOOSER -Apapowell@h4+113 -CA -D2000-06-01-14:02:13.313 -Hh4.private \
7686   -J/tmp/hi -Lpapowell -Plp -Qlp -aacct -b3 -d/var/tmp/LPD/lp \
7687   -hh4.private -j113 -kcfA113h4.private -l66 -npapowell -sstatus \
7688   -t2000-06-01-14:02:13.379 -w80 -x0 -y0 acct
7689USER=papowell
7690LD_LIBRARY_PATH=/lib:/usr/lib:/usr/5lib:/usr/ucblib
7691HOME=/home/papowell
7692PRINTCAP_ENTRY=lp
7693 :chooser=/var/tmp/LPD/chooser
7694 :lp=/tmp/lp
7695 :sd=/var/tmp/LPD/lp
7696 :server
7697 :sv=lp2,lp3
7698
7699lp2=change=0x0
7700 done_time=0x1
7701 held=0x0
7702 move=0x0
7703 printable=0x0
7704 printer=lp2
7705 printing_aborted=0x0
7706 printing_disabled=0x0
7707 queue_control_file=control.lp2
7708 server=0
7709 spooldir=/var/tmp/LPD/lp2
7710lp3=change=0x0
7711 done_time=0x2
7712 held=0x0
7713 move=0x0
7714 printable=0x0
7715 printer=lp3
7716 printing_aborted=0x0
7717 printing_disabled=0x0
7718 queue_control_file=control.lp3
7719 server=0
7720 spooldir=/var/tmp/LPD/lp3
7721PS1=$
7722OPTIND=1
7723PS2=&gt;
7724SPOOL_DIR=/var/tmp/LPD/lp
7725LOGNAME=papowell
7726CONTROL=Hh4.private
7727Ppapowell
7728J/tmp/hi
7729CA
7730Lpapowell
7731Apapowell@h4+113
7732D2000-06-01-14:02:13.313
7733Qlp
7734N/tmp/hi
7735fdfA113h4.private
7736UdfA113h4.private</screen>
7737</informalexample>
7738</para>
7739
7740<para>As you can see,
7741the program is invoked with the same options as a normal filter.
7742In addition,
7743the printcap information for each server queue is passed in an environment
7744variable with the name of the server queue.
7745This means that if there is information needed by the chooser program to test
7746for the availability of hardware,
7747etc., this can be placed in the printcap information.</para>
7748
7749<para>One of the limitations of using the
7750<literal remap=tt>:chooser</literal>
7751program is that you
7752may have a high overhead associated with running the program.
7753The &LPRng; software provides support for linking in a user provided routine
7754that does the same thing as the
7755<literal remap=tt>:chooser</literal>
7756program.
7757This routine has the following API or interface:
7758<informalexample>
7759<screen>Printcap Option: chooser_routine
7760   chooser_routine@  - default - do not use chooser routine
7761   chooser_routine   - use chooser routine
7762
7763Configuration:
7764   configure --with-chooser_routine=name --with-user_objs=objectfile.o
7765      defines the CHOOSER_ROUTINE compilation option to name
7766      includes the objectfile.o in the library.
7767
7768extern int CHOOSER_ROUTINE( struct line_list *servers,
7769    struct line_list *available, int *use_subserver );
7770  servers:    all subserver queues for this load balance queue
7771  available:  subserver queues to choose from
7772  use_subserver: chosen subserver queue
7773  RETURNS:
7774     0 - use the 'use_subserver' value as index into servers
7775         list for server to use
7776     != 0 - set job status to value returned.</screen>
7777</informalexample>
7778</para>
7779
7780<para>See the <filename>LPRng/src/common/lpd_jobs.c</filename> and
7781<filename>LPRng/src/common/user_objs.c</filename> files
7782for details of the servers, available, and user_subserver
7783parameters.
7784The <filename>user_objs.c</filename> file provides a simple template that
7785can be used as a starting point for a more complex routine.
7786You should modify the code in the <filename>user_objs.c</filename> file
7787and then use the configure options shown above to cause the
7788<filename>user_objs.c</filename> file to be compiled and linked into the &LPRng; executables.</para>
7789
7790</sect1>
7791
7792<sect1><title>Routing Jobs To Print Queues</title>
7793
7794<para>A <emphasis>routing queue</emphasis>
7795is similar in concept to a load balance queue
7796in that it transfers a job to a (different) print queue,
7797but the job destination is chosen at the time the job is submitted
7798to the queue
7799rather than at the time the job is
7800removed from the queue.
7801A routing queue can modify the job control file,
7802multiple copies of the same job can be sent to the same or different
7803printers,
7804and the job can be held,
7805rejected,
7806or processed immediately.</para>
7807
7808<para>Edit the printcap file so it have the contents indicated below,
7809create the <filename>/tmp/lp2</filename> and <filename>/tmp/lp3</filename>
7810files with
7811<literal remap=tt>0777</literal>
7812permissions.
7813Create the <filename>/tmp/router.script</filename>
7814with the contents indicated below,
7815and give it
7816<literal remap=tt>0755</literal>
7817(executable) permissions.
7818Use <command>checkpc -f</command> to check the printcap,
7819and then use
7820<command remap=tt>lpc reread</command>
7821to restart the <application>lpd</application> server.
7822<informalexample>
7823<screen># printcap
7824lp:force_localhost
7825lp:server
7826  :lp=/dev/null
7827  :sd=/var/spool/lpd/%P
7828  :router=/tmp/router.script
7829lp2:force_localhost
7830lp2:server
7831  :sd=/var/spool/lpd/%P
7832  :lp=/tmp/lp2
7833lp3:force_localhost
7834lp3:server
7835  :sd=/var/spool/lpd/%P
7836  :lp=/tmp/lp2
7837
7838# /tmp/router.script
7839
7840#!/bin/sh
7841/bin/cat &lt;&lt;EOF
7842dest lp2
7843copies 2
7844Cred
7845end
7846dest lp3
7847end
7848EOF
7849exit 0</screen>
7850</informalexample>
7851</para>
7852
7853<para>The <filename>router.script</filename>
7854will write the routing information to its <acronym/STDOUT/.
7855For our example,
7856we want the destination
7857<literal remap=tt>lp2</literal>
7858to get two copies of the job
7859and we want to change the class to
7860<literal remap=tt>red</literal>.
7861Now run the following commands:
7862<informalexample>
7863<screen><prompt>h4: {282} % </prompt><userinput>lpc stop all</userinput>
7864Printer: lp@h4
7865lp@h4.private: stopped
7866Printer: lp2@h4
7867lp2@h4.private: stopped
7868Printer: lp3@h4
7869lp3@h4.private: stopped
7870<prompt>h4: {283} % </prompt><userinput>lpq</userinput>
7871Printer: lp@h4 (dest lp@localhost) (printing disabled) (dest lp2, lp3)
7872 Queue: no printable jobs in queue
7873Printer: lp2@h4  (printing disabled)
7874 Queue: no printable jobs in queue
7875Printer: lp3@h4  (printing disabled)
7876 Queue: no printable jobs in queue
7877<prompt>h4: {284} % </prompt><userinput>lpr /tmp/hi</userinput>
7878<prompt>h4: {285} % </prompt><userinput>lpq</userinput>
7879Printer: lp@h4 (dest lp@localhost) (printing disabled) (dest lp2, lp3)
7880 Queue: 1 printable job
7881 Server: no server active
7882 Rank   Owner/ID           Class Job Files        Size Time
78831      papowell@h4+235       A   235 /tmp/hi         3 16:14:22
7884 -          papowell@h4+235.1       -&gt;lp2 &lt;cpy 0/2&gt;
7885 -          papowell@h4+235.2       -&gt;lp3
7886Printer: lp2@h4  (printing disabled)
7887 Queue: no printable jobs in queue
7888Printer: lp3@h4  (printing disabled)
7889 Queue: no printable jobs in queue</screen>
7890</informalexample>
7891</para>
7892
7893<para>The status reported for the spooled job indicates that the job
7894is routed to
7895<literal remap=tt>lp2</literal>,
7896and that two copies will be sent.
7897The
7898<literal remap=tt>:destinations</literal>
7899option in the printcap entry causes
7900<application>lpq</application> to display the contents of the specified queues.
7901Now execute the following commands:
7902<informalexample>
7903<screen><prompt>h4: {286} % </prompt><userinput>lpc start</userinput>
7904Printer: lp@h4
7905lp@h4.private: started
7906<prompt>h4: {287} % </prompt><userinput>lpq</userinput>
7907Printer: lp@h4 (dest lp@localhost) (destinations lp2, lp3)
7908 Queue: no printable jobs in queue
7909 Status: job 'papowell@h4+235' removed at 16:14:37.491
7910Printer: lp2@h4  (printing disabled)
7911 Queue: 2 printable jobs
7912 Server: no server active
7913 Rank   Owner/ID           Class Job Files        Size Time
79141      papowell@h4+235.1C1   A   235 /tmp/hi         3 16:14:36
79152      papowell@h4+235.1C2   A   236 /tmp/hi         3 16:14:37
7916Printer: lp3@h4  (printing disabled)
7917 Queue: 1 printable job
7918 Server: no server active
7919 Rank   Owner/ID           Class Job Files        Size Time
79201      papowell@h4+235.2     A   237 /tmp/hi         3 16:14:37
7921<prompt>h4: {288} % </prompt><userinput>more /var/spool/lpd/lp2/cfA235*</userinput>
7922Hh4.private
7923Ppapowell
7924J/tmp/hi
7925Cred
7926Lpapowell
7927Apapowell@h4+235.1C1
7928D2000-06-01-16:03:25.237
7929Qlp
7930N/tmp/hi
7931fdfA235h4.private
7932UdfA235h4.private</screen>
7933</informalexample>
7934</para>
7935
7936<para>As you can see, two copies of the job has been transferred to
7937<literal remap=tt>lp2</literal>
7938and one to
7939<literal remap=tt>lp3</literal>,
7940each with a different job number,
7941If we examine the control file for the jobs in the
7942<literal remap=tt>lp2</literal>
7943spool queue,
7944we will find that the
7945<literal remap=tt>C</literal>
7946or class information has been changed to
7947<literal remap=tt>red</literal>.</para>
7948
7949<para>For details about all of the capabilities of the routing filter,
7950see
7951<link linkend="destinations">Dynamic Routing</link>.
7952Here is a summary of the information that the routing filter can put into
7953the routing file.
7954<variablelist>
7955<varlistentry><term> dest queue </term>
7956<listitem>
7957<para>Route this job to
7958<literal remap=tt>queue</literal>.
7959The <literal>queue@host</literal> form will transfer the job to the queue on the named host.</para>
7960
7961</listitem>
7962</varlistentry>
7963
7964<varlistentry><term> copies N </term>
7965
7966<listitem>
7967<para>Send N copies of this job to the destination.</para>
7968
7969</listitem>
7970</varlistentry>
7971
7972<varlistentry><term> priority C </term>
7973
7974<listitem>
7975<para>Set the job priority letter to
7976<literal remap=tt>C</literal>,
7977where C is a single upper case letter.</para>
7978
7979</listitem>
7980</varlistentry>
7981
7982<varlistentry><term> Cvalue </term>
7983
7984<listitem>
7985<para>Set the control file line starting with
7986<literal remap=tt>C</literal>
7987to
7988<literal remap=tt>Cvalue</literal>.</para>
7989
7990</listitem>
7991</varlistentry>
7992</variablelist>
7993</para>
7994
7995<para>The exit status of the routing filter controls how the job will be processed.
7996If the exit code is JSUCC (0),
7997then the job will be processed normally,
7998JHOLD will hold the job until released,
7999JREMOVE will remove the job,
8000and so forth.</para>
8001
8002</sect1>
8003
8004<sect1><title>Job Options and the Z Control File Entry</title>
8005
8006<para>Many printers have special capabilities such as
8007printing in landscape mode,
8008duplex printing,
8009binding,
8010or stapling.
8011These capabilities are usually invoked or enabled by the print spooler
8012sending special printer control commands to the printer
8013based on values it finds in the control file.
8014The &LPRng; print spooler uses the
8015<literal/Z/
8016line in the control file to specify these options,
8017while other print spoolers such as the Sun Microsystems Solaris <application/lp/
8018system pass them on the <literal/S/ line.
8019</para>
8020<para>
8021Job formatting options are specified using the <command>lpr -Z</command> option.
8022The <application>lpr</application> program concatenates the <literal>-Z</literal> options and puts them
8023in the control file as a single
8024<literal remap=tt>Z</literal>
8025line.
8026For example:
8027<informalexample>
8028<screen><prompt>h4: {289} % </prompt><userinput>lpc stop</userinput>
8029Printer: lp@h4
8030lp@h4.private: stopped
8031<prompt>h4: {290} % </prompt><userinput>lpr -Zthis -Zthat /tmp/hi</userinput>
8032<prompt>h4: {291} % </prompt><userinput>cat /var/spool/lp/cf*</userinput>
8033Hh4.private
8034Ppapowell
8035J/tmp/hi
8036CA
8037Lpapowell
8038Zthis,that
8039Apapowell@h4+115
8040D2000-05-05-10:05:41.351
8041Qlp
8042N/tmp/hi
8043fdfA115h4.private
8044UdfA115h4.private</screen>
8045</informalexample>
8046</para>
8047
8048<para>As we see, the
8049<literal remap=tt>Z</literal>
8050options have been put into the control file on the <literal/Z/  line.
8051The <literal/Z/ option values are passed to filters on the command line
8052as the <literal/-Z/ command line option.
8053These values are used by the <application/ifhp/ filter to determine what control
8054commands to send to the printer and how to format the print job output.
8055Because each printer is different and supports a different set
8056of capabilities
8057it is impossible to have a set of job options supported across all printers.
8058The following are supported by the
8059<application remap=tt>ifhp</application>
8060configuration
8061where possible.
8062Many of these options rely on the printer supporting PostScript
8063or having the appropriate PCL commands to do the indicated operation.
8064<itemizedlist>
8065
8066<listitem>
8067<para>-Zlandscape -Zportrait<!-- <br> --> -
8068select landscape or portrait orientation.</para>
8069</listitem>
8070
8071<listitem>
8072<para>-Zduplex -Zsimplex<!-- <br> --> -
8073select duplex (both sides of a page) or simplex (single side
8074of a page) printing.</para>
8075</listitem>
8076
8077<listitem>
8078<para>-Zletter -Zlegal -Zledger -Za4 -Za5 -Zenvelope -Ztransparency<!-- <br> --> -
8079select a paper size</para>
8080</listitem>
8081
8082<listitem>
8083<para>-Zinupper -Zinmiddle -Zinlower<!-- <br> --> -
8084select input media from the appropriate input tray</para>
8085</listitem>
8086
8087<listitem>
8088<para>-Zmanual<!-- <br> --> -
8089select input from the manual feed</para>
8090</listitem>
8091
8092</itemizedlist>
8093</para>
8094
8095<sect2><title>Setting Job Options Using the Printcap</title>
8096<para>
8097An alternative to this method of using <application/lpr/ and the <literal/-Z/ option
8098is to define a set of spool queues which will put the necessary options into the job
8099control file.
8100This can be done by the <application/lpr/ program when the job is generated,
8101or by the <application/lpd/ spooler when the job is processed.
8102The
8103The options specified by the
8104<literal>:prefix_z</literal>, <literal>:append_z</literal>, and <literal>:delete_z</literal>
8105are prefixed, appended, or deleted from the current set of
8106<literal remap=tt>Z</literal> control file options by the <application/lpr/
8107program when the job is submitted and they are specified in the printcap
8108for the queue,
8109or by the <application/lpd/ spooler when the job is submitted to the queue.
8110We can use this capapbility to configure print queues to
8111a desired set of <literal/Z/ options into the control file.
8112For example:
8113<informalexample>
8114<screen>landscape:lp=%P@server
8115landscape:server:tc=.common
8116  :lp=raw@server:append_z=landscape:delete_z=portrait
8117raw:server:tc=.common:lp=....
8118  :filter=/usr/local/libexec/filters/ifhp
8119.common:sd=/var/spool/lpd/%P</screen>
8120</informalexample>
8121</para>
8122
8123<para>
8124When a job is sent to the <literal/landscape/ queue,
8125the control file <literal/Z/ line will have the <literal/portrait/
8126option removed and the <literal/landscape/ option appended.
8127The <literal/:delete_z/ values are glob patterns
8128and options that match are removed from the option list.
8129Options are assumed to be separated by commas or semicolons in the option list.
8130</para>
8131
8132</sect2>
8133<sect2><title>Converting SystemV Options to LPRng Options</title>
8134<para>On some SystemV <application>lp</application> print spoolers,
8135the
8136<command>lp -o option</command>,
8137puts the option information into the control file
8138<literal remap=tt/S/
8139line,
8140and on other systems on the
8141puts the option information into the control file
8142<literal remap=tt/O/
8143line.
8144
8145To convert these options to &LPRng; <literal/Z/ options use the
8146<literal>:prefix_option_to_option=from,from... to</literal>
8147facility
8148to prefix the <emphasis/from/ control file lines to the <emphasis/to/
8149control file line.
8150For example:
8151<informalexample>
8152<screen># System V to LPRng - S and O to Z options
8153convert:server:tc=.common
8154  :lp=raw@server:prefix_option_to_option=S,O Z
8155# LPRng to System V O options
8156convert:server:tc=.common
8157    :lp=raw@server:prefix_option_to_option=Z O</screen>
8158</informalexample>
8159</para>
8160</sect2>
8161<sect2><title>Selecting a Single Option - Muliple Queues</title>
8162
8163<para>
8164Here is an example of how you can set up queues that will append the
8165appropriate <literal/Z/ option to select landscape mode,
8166do duplex printing, or select
8167legal or ledger size paper:
8168<informalexample>
8169<screen>
8170landscape:lp=%P@server
8171landscape:server:tc=.common
8172    :lp=raw@server:append_z=landscape
8173duplex:lp=%P@server
8174duplex:server:tc=.common
8175    :lp=raw@server:append_z=duplex
8176ledger:lp=%P@server
8177ledger:server:tc=.common
8178    :lp=raw@server:append_z=ledger
8179legal:lp=%P@server
8180legal:server:tc=.common
8181    :lp=raw@server:append_z=legal
8182raw:server:tc=.common:lp=....
8183  :filter=/usr/local/libexec/filters/ifhp
8184.common:sd=/var/spool/lpd/%P</screen>
8185</informalexample>
8186</para>
8187<para>
8188The problem with this method is that for each option we need to define a queue
8189whose only purpose is to append the appropriate option and then forward this
8190to the main print queue.
8191</para>
8192</sect2>
8193<sect2 id=incomingcontrolfilter><title>Selecting Multiple Options - Single Queue </title>
8194
8195<para>
8196In the previous section,
8197we showed how to set up a queue that would append a single option
8198to the control file <literal/Z/ line.
8199If we want to have combinations of option options specified by the printer name
8200then we will have to create a large number of queues
8201each with a different set of options and each appending a different
8202set of values.
8203The problem becomes compounded when we have many printers,
8204each of which requires these options.
8205</para>
8206
8207<para>
8208The solution to this problem originated with the
8209<application/apsfilter/ program written by
8210Andreas Klemm and Thomas Bueschgens.
8211They made the observeration that if we know the name of the print queue
8212then we can use this name to select options for the printer.
8213The &LPRng; provides this functionality by
8214using wildcard queues and <emphasis/editing/ or <emphasis/filtering/ the control file when the job is
8215submitted to the spool queue.
8216</para>
8217<para>
8218The <literal>incoming_control_filter=/path</literal> option specifies a filter
8219that processes the incoming job control file.
8220It should be used to update and/or modify information on the option lines of
8221the control files of incoming jobs.
8222It reads the control file on its <acronym/STDIN/,
8223writes the new control file on its <acronym/STDOUT/,
8224and then exits.
8225A 0 exit code value causes normal processing of the job,
8226<literal/JHOLD/ will hold the job,
8227and any other value will cause the job to be discarded.
8228</para>
8229<para>
8230The following shows how we can set up a single queue that will
8231allow various combinations of options to be selected by the format
8232of the queue name:
8233<informalexample>
8234<screen># for clients
8235pr|pr_*:lp=%Q@server
8236# for server
8237pr|pr_*:server
8238  :tc=.common:lp=....
8239  :incoming_control_filter=/usr/local/libexec/filters/update_z
8240  :filter=/usr/local/libexec/filters/ifhp
8241.common:sd=/var/spool/lpd/%P</screen>
8242</informalexample>
8243</para>
8244<para>
8245The <literal/pr/ and <literal/pr_*/ aliases will match printer <literal/pr/
8246all print queue names starting with <literal/pr_/.
8247We can then use various suffixes to select job options.
8248The following filter program uses the
8249<literal/_landscape/,
8250<literal/_legal/,
8251and
8252<literal/_ledger/ suffixes to set the corresponding option
8253in the <literal/Z/ file.
8254This program and other are available in the &LPRng; distribution
8255in the <filename>UTILS</filename> directory.
8256You should note that additional options can be specified
8257as desired.
8258<informalexample>
8259<screen>#
8260#!/usr/bin/perl
8261# update_z script:
8262# Determine the options according to the format of the queue name
8263#  Inspired by the psfilter code of Andreas Klemm
8264#  and Thomas Bueschgens 
8265# First, get command line arguments
8266#
8267use Getopt::Std;
8268my(%args,$Q,$Zopts,@file);
8269getopts(
8270"A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z:" .
8271"a:b:cd:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z:",
8272\%args );
8273# read stdin
8274@file = &lt;STDIN&gt;;
8275$Zopts = "";
8276# first use command line Queue name
8277$Q = $args{"Q"};
8278if( not $Q and (($Q) = grep(/^Q/,@file)) ){
8279   # next use control file Queue name
8280    chomp $Q if $Q;
8281}
8282# now we split up the name and use as parameters for Z options
8283while( $Q =~ /_([^_]+)/g ){
8284    # you can add them or test and then add them
8285    if( $1 eq "landscape"
8286        or $1 eq "legal"
8287        or $1 eq "ledger" ){
8288        $Zopts .= ",$1"
8289    }
8290}
8291if( $Zopts ){
8292    # remove leading comma
8293    $Zopts = substr( $Zopts, 1 );
8294    #replace or prefix Z options
8295    if( not (grep { s/$/,$Zopts/ if /^Z/; } @file) ){
8296        print "Z" . $Zopts . "\n";
8297    }
8298}
8299print @file if( @file );
8300exit 0
8301
8302Example Input Control file:
8303
8304...
8305Zover
8306Qlp_landscape_ledger
8307...
8308
8309Modified output:
8310
8311...
8312Zover,landscape,ledger
8313Qlp_landscape_ledger
8314...</screen>
8315</informalexample>
8316</para>
8317<para>
8318The Perl script first uses the <function/getopts/ function to
8319parse the command line options.
8320If there is not a command line <literal/-Q/ option then the
8321control file <literal/Q/ line is used after stripping the trailing
8322newline.
8323The queue name is then split up into parts separated by underscores
8324(<literal/_/) and those used as option names.
8325As shown in the example,  the literal values are placed in the control file.
8326You can also use the following code segment to translate short forms of
8327options into longer ones:
8328
8329<informalexample>
8330<screen>while( $Q =~ /_([^_]+)/g ){
8331    # you can add them or test and then add them
8332    Zopts .= ",landscape" if( $1 eq "ld" );
8333    Zopts .= ",ledger" if( $1 eq "11" );
8334    Zopts .= ",legal" if( $1 eq "15" );
8335    Zopts .= ",a4" if( $1 eq "a4" );
8336}</screen>
8337</informalexample>
8338</para>
8339</sect2>
8340</sect1>
8341<sect1><title>Interfacing to Non-LPRng Spoolers</title>
8342
8343<para>
8344Given the large number of defective RFC1179 implementations that are
8345currently in use,
8346there will come a time when the administrator will discover that their
8347printer with its built-in network interface,
8348the non-UNIX based print spooler on a mainframe,
8349or even a new print spooler on a new OS distribution will not accept
8350jobs from the &LPRng; system.
8351Usually this is caused by the presence,
8352absence,
8353or order of lines in the control file being sent to the remote system.
8354To deal with this particular problem,
8355the
8356<literal remap=tt>:bk</literal>,
8357<literal remap=tt>:control_file_line_order</literal>,
8358<literal remap=tt>:nline_after_file</literal>,
8359and
8360<literal remap=tt>:control_filter</literal>
8361options are used.</para>
8362
8363<para>The
8364<literal remap=tt>:bk</literal>
8365(BSD Kompatibility) option causes the lpd server to
8366remove all but an extremely small subset of lines from the control file,
8367and to put the lines in the most commonly used order.
8368In addition
8369it will make the control and data files names extremely short and simple.
8370This almost always solves compatibility problems when sending jobs to older
8371<emphasis>vintage</emphasis>
8372print spoolers or UNIX systems.</para>
8373
8374<para>If this does not solve the problem,
8375then you can specify the allowed control file lines and their order using the
8376<literal>control_file_line_order=...</literal> option.
8377For example,
8378<literal>control_file_line_order=CJPMD</literal>
8379would allow only control file lines starting with
8380<literal remap=tt>C</literal>,
8381<literal remap=tt>J</literal>,
8382<literal remap=tt>P</literal>,
8383<literal remap=tt>M</literal>,
8384and
8385<literal remap=tt>D</literal>,
8386and this order in the control file.
8387Note that this does not provide <emphasis>missing</emphasis>
8388line values,
8389it only controls line values that are present in the control file.
8390You should also use the
8391<literal remap=tt>:bk</literal>
8392option as well.</para>
8393
8394<para>You might run into some <emphasis>really</emphasis>
8395unusual implementations where
8396the control file
8397<literal remap=tt>N</literal>
8398(file name) information must come <emphasis>after</emphasis>
8399the control file name.
8400This is forced by the
8401<literal remap=tt>:nline_after_file</literal>
8402option.</para>
8403
8404<para>If these horrible kludges do not solve your compatibility problems
8405then we turn to the very large hammer and edit the control file.
8406The very last step before transfering
8407the control file to the remote server is to filter it using the
8408<literal>:control_filter=/path</literal> program specified in the printcap.
8409The <literal>:control_filter</literal> reads the control file from <acronym/STDIN/
8410and writes the modified control file to <acronym/STDOUT/.
8411No consistency checking or validity checks are done on the new control file
8412and the result is transferred directly to the remote system.
8413If the
8414<literal>:control_filter</literal> exits with a 0 status,
8415then the normal processing continues.
8416Any other status will cause the transfer operation to be aborted
8417and an error reported.
8418</para>
8419
8420</sect1>
8421
8422<sect1><title>Debugging, Tracing, and Log Files</title>
8423
8424<para>The &LPRng; software was designed and written to provide as high a level
8425of diagnostic information as possible.
8426This was largely in part due to the problems with portability,
8427coding errors,
8428and other human frailties.
8429Approximately 80% of the &LPRng; source code concerns itself with
8430checking return values from system functions and producing error messages,
8431debugging and tracing information,
8432and various facilities used for regression testing and diagnosis.</para>
8433
8434<para>The approach used by &LPRng; is to produce
8435<emphasis>trace</emphasis>
8436output for the
8437&LPRng; clients or
8438<emphasis>log</emphasis>
8439files for the <application>lpd</application> server
8440that show the various events or flow of information through the &LPRng; system.
8441There are several classes or types of actions that can be traced,
8442and various levels of trace information generated.
8443The interface used to control these actions are the command line
8444<literal>-D literals</literal> flags and the
8445<command remap=tt>lpc debug</command>
8446command.</para>
8447
8448<para>First,
8449we will look at how you can use the debugging facilities for the clients.
8450Enter the following commands:
8451<informalexample>
8452<screen><prompt>h4: {292} % </prompt><userinput>lpr -D=</userinput>
8453debug usage: -D [ num | key=num | key=str | flag | flag@ | flag+N ]*
8454  keys recognized: network[+N,@], database[+N,@], lpr[+N,@],
8455   lpc[+N,@], lprm[+N,@], lpq[+N,@], test=num, job=num, log[+N,@]
8456<prompt>h4: {293} % </prompt><userinput>lpr -V /tmp/hi</userinput>
8457LPRng-3.7.2, Copyright 1988-2000 Patrick Powell, &lt;papowell@lprng.com&gt;
8458sending job 'papowell@h4+981' to lp@localhost
8459connecting to 'localhost', attempt 1
8460connected to 'localhost'
8461requesting printer lp@localhost
8462sending control file 'cfA981h4.private' to lp@localhost
8463completed sending 'cfA981h4.private' to lp@localhost
8464sending data file 'dfA981h4.private' to lp@localhost
8465completed sending 'dfA981h4.private' to lp@localhost
8466done job 'papowell@h4+981' transfer to lp@localhost
8467<prompt>h4: {294} % </prompt><userinput>lpr -D1 /tmp/hi</userinput>
846809:38:08.707 h4 [13991] lpr  Get_printer: original printer '&lt;NULL&gt;'
846909:38:08.708 h4 [13991] lpr  Get_all_printcap_entries: starting
847009:38:08.708 h4 [13991] lpr  Select_pc_info: looking for 'all', depth 0
847109:38:08.708 h4 [13991] lpr  Select_pc_info: returning '&lt;NULL&gt;'
847209:38:08.708 h4 [13991] lpr  Select_pc_info: looking for '*', depth 0
847309:38:08.708 h4 [13991] lpr  Select_pc_info: returning '&lt;NULL&gt;'
847409:38:08.708 h4 [13991] lpr  Dump_line_list: Get_all_printcap_entries
8475...</screen>
8476</informalexample>
8477</para>
8478
8479<para>The <command>lpr -D=</command> causes the <application>lpr</application> (and other &LPRng; programs) to show what debugging flags
8480are available.
8481The <command>lpr -V</command> flag causes <application>lpr</application> to run in verbose mode and show its activities.
8482Finally,
8483we use <command>lpr -D1</command> to enable the simplest level of debugging.
8484This will produce a trace of the various activities that <application>lpr</application> carries out.
8485Try <command>lpr -D2</command>,
8486<command>lpr -D3</command>,
8487and so forth to see the increasing amount of detail that you get.</para>
8488
8489<para>The
8490<emphasis>network</emphasis>
8491and
8492<emphasis>database</emphasis>
8493debug flags turn on debugging for the network facilities
8494and the database (<filename>lpd.conf</filename>, <filename>printcap</filename>, and <filename>lpd.perms</filename>) lookups.
8495Lets see what <command>lpr -Dnetwork</command> shows us:
8496<informalexample>
8497<screen>
8498C<prompt>h4: {295} % </prompt><userinput>lpr -Dnetwork /tmp/hi</userinput>
8499lp: getconnection: START host localhost, timeout 10, connection_type 1
8500lp: getconnection: fqdn found localhost.private, h_addr_list count 1
8501lp: Link_dest_port_num: port 2000 = 2000
8502lp: getconnection: sock 3, src ip 127.0.0.1, port 65209
8503lp: getconnection: dest ip 127.0.0.1, port 2000
8504lp: getconnection: connection to 'localhost' sock 3, errmsg 'No Error'
8505lp: Link_send: host 'localhost' socket 3, timeout 6000
8506lp: Link_send: str '^Blp
8507', count 4, ack 0x80447a0
8508lp: Link_send: final status NO ERROR
8509lp: Link_send: host 'localhost' socket 3, timeout 6000
8510lp: Link_send: str '^B135 cfA276h4.private
8511', count 22, ack 0x8044370
8512lp: Link_send: final status NO ERROR
8513lp: Link_send: host 'localhost' socket 3, timeout 6000
8514lp: Link_send: str 'Hh4.private
8515Ppapowell
8516J/tmp/hi
8517CA
8518Lpapowell
8519Apapowell@h4+276
8520D2000-06-02-09:44:52.369
8521Qlp
8522N/tmp/hi
8523fdfA276h4.private
8524UdfA276h4.private
8525', count 136, ack 0x8044370
8526lp: Link_send: final status NO ERROR
8527lp: Link_send: host 'localhost' socket 3, timeout 6000
8528lp: Link_send: str '^C3 dfA276h4.private
8529', count 20, ack 0x8044310
8530lp: Link_send: final status NO ERROR
8531lp: Link_send: host 'localhost' socket 3, timeout 6000
8532lp: Link_send: str '', count 1, ack 0x8044310
8533lp: Link_send: final status NO ERROR</screen>
8534</informalexample>
8535</para>
8536
8537<para>As we see,
8538we get a detailed exposition of the network connection and transfer steps.
8539If you need or want more detail,
8540try using
8541<command>lpr -Dnetwork+2</command> or
8542<command>lpr -Dnetwork+3</command>.
8543You may want to try
8544<command>lpr -Ddatabase</command> and observe the actions of the <application>lpr</application> program as it
8545extracts information from the <filename>lpd.conf</filename> and <filename>printcap</filename> files.
8546If you need or want more detail,
8547try using
8548<command>lpr -Ddatabase+2</command> or
8549<command>lpr -Ddatabase+3</command>.</para>
8550
8551<para>If you need to trace the activities of the <application>lpd</application> server,
8552it becomes a little more complex.
8553The lpd server has a single <emphasis>listening</emphasis>
8554process that forks and creates
8555individual processes to handle incoming requests.
8556Debug or diagnose the main process actions by using <command>lpd -D...</command>.
8557You may also want to use <command>lpd -F</command> to keep the server in the foreground so you
8558can kill it off easily.
8559Needless to say,  you should also redirect the <acronym/STDERR/ and <acronym/STDOUT/ so that it
8560goes to a file so that you can examine the voluminous records at your
8561leisure.  The following shows a typical main <application>lpd</application> process debugging session
8562using the C Shell.
8563<informalexample>
8564<screen><prompt>h4: {296} % </prompt><userinput>lpd -F -D1 &gt;&amp;/tmp/logfile &amp;</userinput>
8565[2] 14299
8566<prompt>h4: {297} % </prompt><userinput>tail -f /tmp/logfile</userinput>
85672000-06-02-09:53:39.716 h4 [1200] Waiting Read_server_status: \
8568                         select status 1
85692000-06-02-09:53:39.716 h4 [1200] Waiting Read_server_status: \
8570                         read status 1
85712000-06-02-09:53:39.716 h4 [1200] Waiting Dump_line_list: \
8572    Read_server_status - input - 0x8047980, count 0, max 0, list 0x0
85732000-06-02-09:53:39.716 h4 [1200] Waiting Read_server_status: \
8574                         select status 0
85752000-06-02-09:53:39.716 h4 [1200] Waiting lpd: LOOP START
85762000-06-02-09:53:39.716 h4 [1200] Waiting Get_max_servers: \ 
8577                         getrlimit returns 64
85782000-06-02-09:53:39.716 h4 [1200] Waiting Get_max_servers: \
8579                         returning 32
85802000-06-02-09:53:39.716 h4 [1200] Waiting lpd: \
8581                         max_servers 32, active 0
85822000-06-02-09:53:39.716 h4 [1200] Waiting lpd: \
8583                         starting select timeout 'yes'
8584
8585^C
8586<prompt>h4: {298} % </prompt><userinput>jobs</userinput>
8587[1]  - Running                lpd -F -D1 &gt;&amp; /tmp/logfile
8588<prompt>h4: {299} % </prompt><userinput>kill %1</userinput></screen>
8589</informalexample>
8590</para>
8591
8592<para>We start the debugging session by running the <application>lpd</application> server in foreground mode.
8593This causes it to send its output to <acronym/STDOUT/ and <acronym/STDERR/.
8594We redirect both of these to a file and put the <application>lpd</application> server in the background.
8595Then we use <command>tail -f</command> to read from the log file.
8596Finally,
8597we kill off the <application>lpd</application> server.</para>
8598
8599<para>This method is extremely difficult to use,
8600as all of the output produced by the server and its subprocesses is sent to
8601a single output file.
8602If we want to debug the actions concerning a single queue,
8603then we can use the queue
8604<emphasis>log file</emphasis>
8605and
8606<command remap=tt>lpc debug</command>
8607command instead.
8608The following options control debugging of an individual print queue.
8609<variablelist>
8610<varlistentry><term>lf=log</term>
8611<listitem>
8612<para>The log file for the queue.
8613The queue server process will open this file and place debugging information
8614into this file.</para>
8615
8616</listitem>
8617</varlistentry>
8618
8619<varlistentry><term>max_log_file_size=nnn</term>
8620
8621<listitem>
8622<para>The maximum size of the log file in K bytes.
8623When the queue server process first opens this file it will check to see
8624if the file is larger than the maximum size.
8625If it is, then it will truncate it.  A zero (0) value suppress truncation.</para>
8626
8627</listitem>
8628</varlistentry>
8629
8630<varlistentry><term>min_log_file_size=nnn</term>
8631
8632<listitem>
8633<para>When the log file is truncated only the the last nnn K bytes are retained.</para>
8634
8635</listitem>
8636</varlistentry>
8637
8638<varlistentry><term>db=options</term>
8639
8640<listitem>
8641<para>These are debugging options for the spool queue.
8642These options are permanent and cannot be changed by using the
8643<command remap=tt>lpc debug</command>
8644facility.</para>
8645
8646</listitem>
8647</varlistentry>
8648</variablelist>
8649</para>
8650
8651<para>The
8652<command remap=tt>lpc debug</command>
8653command is used to set the debugging options in force for
8654the spool queue.
8655This is done by writing the debug options into the spool queue control file.
8656Let us see how we can use this facility to trace the actions of printing a file.</para>
8657
8658<para>Edit the printcap file so it have the contents indicated below,
8659create the <filename>/tmp/lp</filename> and <filename>/tmp/lp2</filename>
8660files with
8661<literal remap=tt>0777</literal>
8662permissions.
8663Use <command>checkpc -f</command> to check the printcap,
8664and then use
8665<command remap=tt>lpc reread</command>
8666to restart the <application>lpd</application> server.
8667<informalexample>
8668<screen># printcap
8669lp:force_localhost
8670lp:server
8671  :lp=/dev/null
8672  :sd=/var/spool/lpd/%P
8673  :lf=log
8674lp2:force_localhost
8675lp2:server
8676  :sd=/var/spool/lpd/%P
8677  :lp=/tmp/lp2
8678  :lf=log</screen>
8679</informalexample>
8680</para>
8681
8682<para>Now execute the following commands:
8683<informalexample>
8684<screen><prompt>h4: {300} % </prompt><userinput>lpq</userinput>
8685Printer: lp@h4
8686 Queue: no printable jobs in queue
8687<prompt>h4: {301} % </prompt><userinput>lpc debug lp 1</userinput>
8688Printer: lp@h4
8689debugging override set to '1'
8690lp@h4.private: updated
8691<prompt>h4: {302} % </prompt><userinput>lpc status</userinput>
8692 Printer Printing Spooling Jobs Server Subserver Redirect Status/(Debug)
8693lp@h4    enabled  enabled    0    none    none          (1)
8694<prompt>h4: {303} % </prompt><userinput>lpr /tmp/hi</userinput>
8695<prompt>h4: {304} % </prompt><userinput>more /var/spool/lpd/lp2/log</userinput>
86962000-06-02-10:10:50.589 h4 [1201] (Server) lp: \
8697   Update_spool_info: printer 'lp'
86982000-06-02-10:10:50.590 h4 [1201] (Server) lp: \
8699   Do_queue_jobs: printable 1, held 0, move 0
87002000-06-02-10:10:50.590 h4 [1201] (Server) lp: \
8701   Do_queue_jobs: after Scan_queue next fd 5
87022000-06-02-10:10:50.590 h4 [1201] (Server) lp: \
8703   Do_queue_jobs: MAIN LOOP
87042000-06-02-10:10:50.590 h4 [1201] (Server) lp: \
8705   Do_queue_jobs: Susr1 before scan 0
87062000-06-02-10:10:50.591 h4 [1201] (Server) lp: \
8707   Do_queue_jobs: chooser '&lt;NULL&gt;', chooser_routine 0</screen>
8708</informalexample>
8709</para>
8710
8711<para>The
8712<command remap=tt>lpc debug</command>
8713command sets the debug level to 1.
8714We can use the
8715<command remap=tt>lpc status</command>
8716command to see what debug flags or actions are
8717currently specified for the spool queue.
8718We then send a job to the spool queue and examine the log file contents.</para>
8719
8720<para>Each line in the log file has a timestamp,
8721the name of the host, the process id that produced it,
8722and a heading that tells the action or activity that the process is performing,
8723and the name of the print queue that is being processed and a trace message.
8724By convention,
8725the trace message lists the name of the routine that processed it
8726and then the actual information.
8727Some messages may extend over several lines,
8728but each line has the standard header at the start of the line.</para>
8729
8730<para>The default debug or trace actions were designed to trace problems with
8731printing,
8732as these are the most common.
8733However,
8734you can also use the
8735<application>lpr</application>,
8736<application>lpc</application>,
8737<application>lprm</application>,
8738or
8739<application>lpq</application>
8740option to cause the <application>lpd</application> server to trace the actions during
8741the execution of an
8742<application>lpr</application>,
8743<application>lpc</application>,
8744<application>lprm</application>,
8745or
8746<application>lpq</application>
8747request.</para>
8748
8749<para>The
8750<emphasis>log</emphasis>
8751option is used to test various logging facilities and is usually
8752not used for general purpose debugging.</para>
8753
8754</sect1>
8755</chapter>
8756
8757<chapter id=lprngclients><title>&LPRng; Clients - lpr, lprm, lpq, lpc, lpstat </title>
8758
8759<para>The &LPRng; software is a true set of client/server applications.
8760The &LPRng; clients,
8761<application remap=tt>lpr</application>,
8762<application remap=tt>lpq</application>,
8763<application remap=tt>lprm</application>,
8764and <application>lpc</application> connect to a <application>lpd</application> server using a
8765TCP/IP connection.
8766This means that you must have TCP/IP networking enabled on your workstation
8767to use &LPRng;.</para>
8768
8769<para>However,
8770you do not need to have an external network connection to the Internet.
8771For most single system users,
8772the <application>lpd</application> server is running on the same workstation as the client program,
8773and the clients will simply talk to the
8774<literal remap=tt>localhost</literal>.</para>
8775
8776
8777<sect1 id="printerinfo"><title>Printer and Server Information
8778</title>
8779
8780<para>Options used:
8781<itemizedlist>
8782
8783<listitem>
8784<para>
8785<envar>PRINTER</envar>, <envar>LPDEST</envar>,
8786<envar>NPRINTER</envar> <envar>NGPRINTER</envar>
8787<emphasis>Environment variables</emphasis></para>
8788</listitem>
8789
8790<listitem>
8791<para> <literal>force_localhost</literal> FLAG <emphasis>force clients to send requests to localhost </emphasis></para>
8792</listitem>
8793
8794<listitem>
8795<para> <literal>require_explicit_q</literal> FLAG <emphasis>require queue to be specified</emphasis></para>
8796</listitem>
8797
8798</itemizedlist>
8799
8800</para>
8801
8802<para>When an &LPRng; client such as
8803<application>lpr</application>,
8804<application>lpq</application>,
8805<application>lprm</application>,
8806or
8807<application remap=tt>lpc</application>
8808needs to communicate with a print server,
8809the only information they normally need is:
8810<orderedlist>
8811
8812<listitem>
8813<para>The remote printer (<literal remap=tt>:rp</literal>) value
8814to be used in requests to the <application>lpd</application> print server.
8815This is sometimes referred to as the <emphasis>printer</emphasis>
8816or <emphasis>print queue</emphasis>
8817name.</para>
8818</listitem>
8819
8820<listitem>
8821<para>The remote server (<literal remap=tt>:rm</literal>) which is the
8822The IP address or hostname of the <emphasis>print server</emphasis>.</para>
8823</listitem>
8824
8825<listitem>
8826<para>The original queue name specified by the user
8827which may be used as part of the job information sent to the
8828print server.</para>
8829</listitem>
8830
8831</orderedlist>
8832</para>
8833
8834<para>&LPRng; has several ways to specify the <emphasis>printer queue</emphasis>
8835and <emphasis>server</emphasis>
8836information.</para>
8837</sect1>
8838
8839<sect1><title>Command Line -Pprinter@host</title>
8840
8841<para>The <literal>-P printer@host</literal> literal explicitly provides a printer
8842and server value.
8843This is equivalent to the printcap entry shown below:
8844<informalexample>
8845<screen>lpr -Plaser@10.0.0.1
8846  equivalent to printcap entry:
8847    laser:lp=laser@10.0.0.1
8848lpq -Plp@myserver
8849  equivalent to printcap entry:
8850    lp:lp=lp@myserver</screen>
8851</informalexample>
8852</para>
8853
8854</sect1>
8855
8856<sect1><title>Command Line -Pprinter</title>
8857
8858<para>Use the printcap entry with the name or alias
8859<literal remap=tt>printer</literal>
8860and use the information in that printcap entry.
8861Example:
8862<informalexample>
8863<screen>lpr -Plp
8864  look up printcap entry for 'lp'</screen>
8865</informalexample>
8866</para>
8867
8868</sect1>
8869
8870<sect1><title>PRINTER, LPDEST, NPRINTER, and NGPRINTER Environment Variables</title>
8871
8872<para>If no command line option is specified,
8873the &LPRng; clients will use the first defined
8874<acronym>PRINTER</acronym>,
8875<acronym>LPDEST</acronym>,
8876<acronym>NPRINTER</acronym>,
8877or
8878<acronym>NGPRINTER</acronym>
8879environment variable value
8880and will use the value as though specified as a
8881<literal>-P$PRINTER</literal> command line literal.
8882If the value has the form
8883<literal>-Pprinter@host</literal> the print queue will be
8884<literal remap=tt>printer</literal>
8885on server
8886<literal remap=tt>host</literal>
8887and not consult the printcap database.
8888If the value has the form
8889<literal remap=tt>printer</literal>
8890then the printcap will be searched
8891for a
8892<literal remap=tt>printer</literal>
8893printcap entry.
8894For example:
8895<informalexample>
8896<screen>export PRINTER=laser@10.0.0.1; lpr
8897  equivalent to printcap entry:
8898    laser:lp=laser@10.0.0.1
8899export PRINTER=pr; lpr
8900  look up printcap entry for 'lp'</screen>
8901</informalexample>
8902</para>
8903
8904</sect1>
8905
8906<sect1><title>Wildcard Printcap Entry</title>
8907
8908<para>If you specify a printcap name or alias as
8909<literal remap=tt>*</literal>
8910(wildcard),
8911then if the &LPRng; system cannot find a printcap with the exact
8912name then the first matching wildcard will be used.
8913For example:
8914<informalexample>
8915<screen>pr|*:rm=server
8916  lpr -Ppr2 will match, and result in a printcap entry
8917    pr|pr2:rm=server
8918
8919*|pr:rm=server
8920  lpr -Ppr2 will match, and result in a printcap entry
8921    pr2|pr:rm=server</screen>
8922</informalexample>
8923</para>
8924
8925</sect1>
8926
8927<sect1><title>First Printcap Entry</title>
8928
8929<para>If you do not specify a printer on the command line or in the
8930environment variables,
8931and the 
8932<literal/require_explicit_q/ value is not set
8933then &LPRng; will search the printcap and use the first valid printcap entry
8934as the printer.
8935It will use the first one found as the default.</para>
8936</sect1>
8937
8938<sect1 id="defaultrmrp"><title>Default Printer and Server Host
8939</title>
8940
8941<para>Options used:
8942<itemizedlist>
8943
8944<listitem>
8945<para> <literal>default_remotehost=</literal><emphasis>default rm (remote host)</emphasis></para>
8946</listitem>
8947
8948<listitem>
8949<para> <literal>default_printer=</literal><emphasis>default rp (remote printer)</emphasis></para>
8950</listitem>
8951
8952</itemizedlist>
8953</para>
8954
8955<para>
8956If the preceding steps do not yield a printer name and the
8957<literal/require_explicit_q/ flag is not set
8958then the
8959<literal>default_printer</literal>
8960and
8961<literal>default_remote_host</literal>
8962values from the <filename>lpd.conf</filename>
8963configuration file will be used.
8964If there is no configuration file,
8965then the compile time defaults will be used.
8966</para>
8967
8968<para>Using the fallback values is usually not a desirable event and may indicate
8969that you have a misconfigured host, so the
8970compile time defaults are usually
8971set to <literal>missingprinter@localhost</literal> to provide an annoying message for users.</para>
8972
8973</sect1>
8974
8975<sect1 id="forcelocalhost"><title>Force Connection to Localhost </title>
8976
8977<para>Options used:
8978<itemizedlist>
8979
8980<listitem>
8981<para> <literal>force_localhost</literal> FLAG <emphasis>force localhost to be remote host</emphasis></para>
8982</listitem>
8983
8984</itemizedlist>
8985</para>
8986
8987<para>The legacy BSD print spooler required an <application>lpd</application> print server
8988to be running on each host.
8989During the initial stages of development and deployment,
8990the default &LPRng; configuration and deployment was to always
8991allow <emphasis>lightweight</emphasis>
8992operation,
8993that is,
8994clients would always connect to the remote host specified in the
8995printcap.</para>
8996
8997<para>While this default was appropriate for experienced system administrators,
8998novice administrators or those who had already configured
8999print spooling systems and simply wanted to upgrade found themselves
9000confused by this change.
9001This problem resulted in over 700 postings to the &LPRng; mailing list
9002in a five year period.</para>
9003
9004<para>This problem was solved by providing a <literal>force_localhost</literal> option
9005in the configuration,
9006and setting the default value to
9007<literal remap=tt>1</literal>
9008or <acronym>TRUE</acronym>.
9009When this option is <acronym>TRUE</acronym>,
9010then all &LPRng; clients will connect to the server on the localhost,
9011<emphasis>unless</emphasis>
9012they use the <command>lpr -Pserver@host</command>
9013command line form.
9014If lightweight operation is wanted,
9015the administrator can either compile the
9016&LPRng;
9017software with the appropriate value or can explicitly set
9018the <literal>force_localhost@</literal> flag.
9019<informalexample>
9020<screen># default:
9021lp:lp=lp@10.0.0.1:...
9022  lpr -Plp -&gt;
9023    lp:lp=lp@localhost:...
9024  lpr -Plp@10.0.0.1 -&gt;
9025    lp:lp=lp@10.0.0.1  (no other options)
9026
9027lp:lp=lp@10.0.0.1:force_localhost@:...
9028  lpr -Plp -&gt;
9029    lp:lp=lp@10.0.0.1:...
9030
9031To disable at compile time:
9032  configure --disable-force_localhost</screen>
9033</informalexample>
9034</para>
9035
9036</sect1>
9037
9038<sect1 id="allowusersetting"><title>User Identification </title>
9039
9040<para>Options used:
9041<itemizedlist>
9042
9043<listitem>
9044<para> <literal>allow_user_setting=</literal><emphasis>privileged users</emphasis></para>
9045</listitem>
9046
9047</itemizedlist>
9048</para>
9049
9050<para>When an client program sends a command to the <application>lpd</application> server
9051it may need to provide the name of the user
9052who is originating the request for service.
9053This name is obtained by looking up the UID of the user
9054running the client
9055in the appropriate user information database;
9056if the information is not found the UID is used instead.
9057Also,
9058the client machine hostname may also be needed.
9059This is usually determined by using a DNS lookup and trying to determine
9060if there is a canonical or Fully Qualified Domain Name for the
9061host and using this.</para>
9062
9063<para>The <command>lpr -U name@host</command> (and for
9064<application>lpq</application>, <application>lprm</application>, and <application>lpc</application>)
9065option allows privileged users to
9066cause the client software to use the
9067<literal remap=tt>name</literal>
9068value as the originator
9069and
9070<literal remap=tt>host</literal>
9071as the machine name.
9072This allows privileged users to
9073<emphasis>impersonate</emphasis>
9074other users.
9075This is most useful for programs such as Samba and PCNFS,
9076which need to act as proxies for users.</para>
9077
9078<para>By default, ROOT (UID 0) is the only user that can masquerade as another
9079user.
9080The <literal>allow_user_setting=name,name...</literal> configuration option can be used
9081to specify a list of names or UIDs that can also perform masquerading.
9082For example,
9083if the Samba server was running as user
9084<literal remap=tt>samba</literal>, then
9085<literal>allow_user_setting=samba</literal> would allow it to specify the name of print
9086job originator as a remote user,
9087and the remote user would not need a login account on the system.</para>
9088
9089</sect1>
9090</chapter>
9091
9092<chapter id=lpr><title><application/lpr/ - Job Spooler Program</title>
9093
9094<para>The <application>lpr</application> client program is used to submit a job
9095to a print spooler.
9096It does this by collecting information about the job,
9097putting it in a control file,
9098and then sending the control file and files to be printed to the
9099print server.
9100The <application>lpr</application> command line options are used to control or specify
9101the values placed in the control file and how the job is to be
9102transferred to the remote host.
9103In addition,
9104there are printcap or configuration level options that provide
9105a further degree of administrative control over additional
9106facilities.
9107You can get the currently supported command line options by using
9108the following command:
9109<informalexample>
9110<screen><prompt>h4: {305} % </prompt><userinput>lpr -=</userinput>
9111lpr: Illegal option '='
9112 usage summary: lpr [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat]
9113   [-Jinfo] [-(K|#)copies] [-Q] [-Raccountname]  [-Ttitle]
9114   [-Uuser[@host]] [-V] [-Zoptions] [-b] [-m mailaddr] [-h]
9115   [-i indent] [-l] [-w num ] [-r] [-Ddebugopt ] [ filenames ...  ]
9116 -A          - use authentication specified by AUTH environment variable
9117 -B          - filter job before sending
9118 -C class    - job class
9119 -D debugopt - debugging flags
9120 -F format   - job format
9121   -b,-l        - binary or literal format
9122    c,d,f,g,l,m,p,t,v are also format options
9123 -J info     - banner and job information
9124 -K copies, -# copies   - number of copies
9125 -P printer[@host] - printer on host
9126 -Q          - put 'queuename' in control file
9127 -Raccntname - accounting information
9128 -T title    - title for 'pr' (-p) formatting
9129 -U username - override user name (restricted)
9130 -V          - Verbose information during spooling
9131 -Z options  - options to pass to filter
9132 -h          - no header or banner page
9133 -i indent   - indentation
9134 -m mailaddr - mail final status to mailaddr
9135 -r          - remove files after spooling
9136 -w width    - width to use
9137 PRINTER, NPRINTER environment variables set default printer.</screen>
9138</informalexample>
9139</para>
9140
9141<para>If you are interested in the exact details of the job transfer,
9142control file,
9143and data file formats,
9144please see
9145
9146<link linkend="rfc1179ref">RFC 1179 - Line Printer Daemon Protocol</link>
9147
9148for the exact details.</para>
9149
9150<sect1 id="defaultformat"><title>Job Format Options
9151</title>
9152
9153<para>Options used:
9154<itemizedlist>
9155
9156<listitem>
9157<para><literal>default_format=</literal><emphasis>default print job format (f)</emphasis></para>
9158</listitem>
9159
9160<listitem>
9161<para><literal>fx=</literal><emphasis>supported formats for printing</emphasis></para>
9162</listitem>
9163
9164</itemizedlist>
9165</para>
9166
9167<para>The legacy or vintage BSD print spooling system assigned each job
9168a format.
9169This format was used by the <application>lpd</application> server
9170to select an appropriate filter program that would process the job
9171and format it correctly for the printer.
9172By convention,
9173lower case letters were used to specify job formats.</para>
9174
9175<para>The &LPRng; <application>lpr</application> client supports the legacy or vintage BSD
9176formats,
9177and also provides the <literal>-Fx</literal> literal to allow addition formats to
9178be specified.
9179If a format is specified the <literal>default_format</literal>
9180value (usually
9181<literal remap=tt>f</literal>) is used.
9182The <literal>fx=...</literal> option value is a list of the
9183(lower case) characters corresponding to the
9184formats allowed for a spool queue.
9185For example, <literal>fx=flv</literal> would allow only
9186jobs with format
9187<literal remap=tt>f</literal>,
9188<literal remap=tt>l</literal>,
9189or
9190<literal remap=tt>v</literal>
9191to be spooled to a queue.
9192By default, all job formats are allowed.</para>
9193
9194<para>A couple of job formats that require special treatment:
9195the
9196<literal remap=tt>b</literal>
9197(binary) and its alias the
9198<literal remap=tt>l</literal>
9199(literal) format,
9200and the
9201<literal remap=tt>p</literal>
9202(pretty print) format.
9203The <literal>-b</literal> or <literal>-l</literal> command line literal will select job format
9204<literal remap=tt>l</literal>
9205(literal) for the job.
9206By default,
9207jobs marked with
9208<literal remap=tt>l</literal>
9209format are supposed to have a minimum
9210amount of handling and passed directly to a printer.
9211The
9212<literal remap=tt>p</literal>
9213(pretty print) format is just the opposite - these jobs
9214are supposed to be pretty printed according to the
9215various facilities available to the <application>lpd</application> print spooler.</para>
9216
9217</sect1>
9218
9219<sect1><title>Job Pretty Printing, Banners, Priority, and Accounting</title>
9220
9221<para>Options used:
9222<itemizedlist>
9223
9224<listitem>
9225<para><literal remap=tt>ab</literal> FLAG <emphasis>always print banner</emphasis></para>
9226</listitem>
9227
9228<listitem>
9229<para><literal remap=tt>sh</literal> FLAG <emphasis>suppress header (banner)</emphasis></para>
9230</listitem>
9231
9232</itemizedlist>
9233</para>
9234
9235<para>The legacy or vintage BSD pretty printing facility support
9236allowed users to specify the
9237title (<literal>-T title</literal>),
9238indentation (<literal>-i indent</literal>),
9239width (<literal>-i indent</literal>) of output for pretty printing.
9240These probably will not have any effect,
9241but their values are placed in the control file and sent
9242to the <application>lpd</application> server.</para>
9243
9244<para>The job name (<literal>-J name</literal>)
9245and no banner page (<literal>-h</literal>) literals also cause information
9246to be placed in the control file.
9247The <literal>-J</literal> value is used to specify a job name on a banner page,
9248and is placed in the control file.
9249The <literal>-h</literal> (no header) has the strange effect of <emphasis>not</emphasis>
9250putting  <emphasis>banner name</emphasis>
9251information in the control file.
9252Apparently,
9253if you do not have a name for your banner then no name will be sent.</para>
9254
9255<para>If the
9256<literal remap=tt>:sh</literal>
9257option is explicitly specified in a printcap
9258entry for the <application>lpr</application> client,
9259then it has the effect of the <literal>-h</literal> literal.
9260However,
9261the
9262<literal remap=tt>:ab</literal>
9263(Always Print Banner) option can be used on the
9264print server to always force a banner to be printed even if the
9265user does not specify a banner.</para>
9266
9267<para>Finally,
9268the <literal>-R</literal> literal allows additional accounting information to be
9269placed in the control file.</para>
9270
9271</sect1>
9272
9273<sect1 id="classpriority"><title>Job Class and Priority
9274
9275</title>
9276
9277<para>Options used:
9278<itemizedlist>
9279
9280<listitem>
9281<para><literal>break_classname_priority_link</literal> FLAG <emphasis>classname does not set priority</emphasis></para>
9282</listitem>
9283
9284<listitem>
9285<para><literal>default_priority=</literal><emphasis>default priority</emphasis></para>
9286</listitem>
9287
9288<listitem>
9289<para><literal>ignore_requested_user_priority</literal> FLAG <emphasis>ignore requested user priority</emphasis></para>
9290</listitem>
9291
9292</itemizedlist>
9293</para>
9294
9295<para>The <literal>-Cclass</literal>
9296information is used placed in the control file;
9297the default class and priority is set by the <literal>default_priority</literal>
9298option (default
9299<literal remap=tt>A</literal>).
9300The first letter of the class information is uppercased
9301and then used as the job priority.</para>
9302
9303<para>The
9304<literal>break_classname_priority_link</literal>
9305option causes <application>lpr</application> to place class information
9306in the control file but not to use it to set the job priority.
9307This is usually used in institutions where users should
9308not specify their priority.
9309Finally,
9310the
9311<literal>ignore_requested_user_priority</literal>
9312is actually used by <application>lpd</application> to ignore the priority requested by users.</para>
9313
9314</sect1>
9315<sect1 id="jobcopies"><title>Job Copies and Job Size</title>
9316
9317<para>Options used:
9318<itemizedlist>
9319
9320<listitem>
9321<para><literal>mc=</literal><emphasis>maximum number of copies</emphasis></para>
9322</listitem>
9323
9324<listitem>
9325<para><literal>mx=</literal><emphasis>maximum job size (Kbytes)</emphasis></para>
9326</listitem>
9327
9328</itemizedlist>
9329</para>
9330
9331<para>The
9332<literal remap=tt>:mc</literal>
9333(maximum number of copies) and
9334<literal remap=tt>:mx</literal>
9335(maximum job size)
9336options are used by both the <application>lpr</application> and <application>lpd</application>
9337programs.
9338The <command>lpr -Kn</command> or <command>lpr -#n</command> option sets the numbers
9339of copies wanted to
9340<literal remap=tt>n</literal>;
9341if this is larger than the
9342<literal remap=tt>:mc</literal>
9343value then the <application>lpr</application>
9344client will not print the job and the <application>lpd</application> server will discard the
9345job with an error.
9346The job size is the product of the number of copies and the
9347sum of the individual file sizes.
9348This is,
9349in effect,
9350the total number of bytes to be transferred to the printer.
9351If the job size is larger than the
9352<literal remap=tt>:mx</literal>
9353limit,
9354then the <application>lpr</application> client will not print the job and the
9355<application>lpd</application> server will discard the job with an error.</para>
9356
9357</sect1>
9358
9359<sect1 id="jobcompletion"><title>Job Completion Notification Requested
9360
9361</title>
9362
9363<para>Options used:
9364<itemizedlist>
9365
9366<listitem>
9367<para> <literal>allow_user_logging</literal> FLAG <emphasis>users can send status</emphasis></para>
9368</listitem>
9369
9370<listitem>
9371<para> <literal>lpr_bsd</literal> FLAG <emphasis>lpr -m acts as legacy BSD flag</emphasis></para>
9372</listitem>
9373
9374</itemizedlist>
9375</para>
9376
9377<para>The <command>lpr -m mailaddr</command> option will put the specified mailaddr
9378value into the control file.
9379How this is processed is left to the particular server implementation.
9380See the
9381
9382<link linkend="abnormalterm">Abnormal Termination</link>
9383
9384section for details.</para>
9385
9386<para>&LPRng; extends the <command>lpr -m mailaddr</command> to allow mail addresses of the form
9387<literal remap=tt> host[%port][/(TCP|UPD)]</literal>,
9388and when the job is being transferred or printed
9389the <application>lpd</application> server to open a connection
9390to the specified TCP/IP address and send job progress information.
9391This is a security loophole
9392and the
9393<literal>allow_user_logging</literal>
9394flag must be present to allow this operation.</para>
9395
9396<para>The <literal>lpr_bsd</literal>
9397will cause the <command>lpr -m</command>
9398option not to take an argument, as in the BSD lpr,
9399and will place the users name and host information in the control
9400file as the destination for notification.</para>
9401
9402</sect1>
9403
9404<sect1><title>Remove Files After Spooling</title>
9405
9406<para>The <command>lpr -r</command> option is extremely dangerous and has proven
9407to be fatal to a large number of system administrators,
9408so it should be used with caution.
9409Unfortunately,
9410it is used in a large number of shell scripts and by default in
9411a vast number of programs so it is present in the &LPRng; software.</para>
9412
9413<para>Its action is quite simple.
9414After sending the print job to the spooler,
9415it will try to unlink the original files.
9416It will do the unlinking operation as the original user,
9417but if the original user had permissions to remove, say,
9418<filename>/etc/password</filename>,
9419then the file will be removed.</para>
9420
9421</sect1>
9422
9423<sect1 id="append-z"><title>The -Z Passthrough to Filter Options </title>
9424
9425<para>Options used:
9426<itemizedlist>
9427
9428<listitem>
9429<para><literal>append_z=</literal><emphasis>Append values to Z options list</emphasis></para>
9430</listitem>
9431
9432<listitem>
9433<para><literal>prefix_z=</literal><emphasis>Prefix values to Z options list</emphasis></para>
9434</listitem>
9435
9436<listitem>
9437<para><literal>remove_z=</literal><emphasis>Remove values from Z options list</emphasis></para>
9438</listitem>
9439
9440<listitem>
9441<para><literal>prefix_s_to_z</literal> FLAG <emphasis>Prefix control file S to Z information</emphasis></para>
9442</listitem>
9443
9444<listitem>
9445<para><literal>prefix_s_to_z</literal> FLAG <emphasis>Prefix control file Z to S information</emphasis></para>
9446</listitem>
9447
9448</itemizedlist>
9449</para>
9450
9451<para>By convention all of the values specified with the
9452<command>lpr -Z</command>
9453option are placed in the job control file and passed to the
9454<application>lpd</application> server,
9455which turn passes them to the print filters.
9456This allows users to pass options that are not part of the
9457RFC1179 repetoire to filters.</para>
9458
9459<para>In addition to this simple method of providing options,
9460we can have the <application>lpr</application> and <application>lpd</application> systems add options to
9461the control file information.
9462The <literal>prefix_z</literal>
9463and <literal>append_z</literal>
9464options allow us to put Z options at the start or end of
9465the user provided list;
9466the <literal>remove_z</literal> removes specified options from the list.</para>
9467
9468<para>The <literal>prefix_s_to_z</literal>
9469and <literal>prefix_z_to_s</literal>
9470options are usually used by the <application>lpd</application> server,
9471and provides a simple way to have the SystemV
9472<command>lp -o option</command>
9473values put into the
9474<literal remap=tt>Z</literal>
9475options value.
9476This is very useful when existing SysV
9477<application remap=tt>lp</application>
9478print spooling systems
9479need to be interfaced to &LPRng; and the options need to be handled in a
9480meaningful manner.
9481The <literal>prefix_z_to_s</literal> is similarly used when you want to
9482forward jobs to a SysV spooling system and have the options
9483passed correctly.</para>
9484
9485<para>If present in the printer configuration,
9486the various requested actions are
9487are done by the <application>lpr</application> client,
9488the <application>lpd</application> server on job reception,
9489and the <application>lpd</application> server again on job processing.
9490This redundancy ensures that jobs which are
9491sent to this queue,
9492arrive at this queue,
9493or are processed by this queue
9494have the options set appropriately.</para>
9495
9496</sect1>
9497
9498<sect1 id="qq"><title>Record Queue Name in Control File </title>
9499
9500<para>Options used:
9501<itemizedlist>
9502
9503<listitem>
9504<para>
9505<literal remap=tt>qq</literal> FLAG <emphasis>Insert queue name into control file</emphasis></para>
9506</listitem>
9507
9508<listitem>
9509<para> <literal>force_queuename=</literal><emphasis>Queuename to be used</emphasis></para>
9510</listitem>
9511
9512</itemizedlist>
9513</para>
9514
9515<para>The
9516<literal remap=tt>:qq</literal>
9517use queuename option
9518tells &LPRng; to record the queue name that a job was originally
9519queued to in the control file
9520as the
9521<literal remap=tt>Q</literal>
9522information.
9523The
9524<literal>force_queuename=...</literal>
9525entry forces the queue name to be the specified value.
9526For example,
9527the following printcap entry and <application>lpr</application>
9528commands will result in a filter
9529being passed the arguments shown below.
9530<informalexample>
9531<screen>#printcap
9532  pr1_landscape|pr1_portrait|pr_raw
9533   :filter=/.../filter
9534   :lp=/dev/pr
9535   :qq
9536
9537lpr -Ppr1_landscape      lpr -Ppr1_portrait
9538  control file -
9539    Qpr1_landscape          Qpr1_portrait
9540
9541filter command line:
9542  ... -Qpr1_landscape     ... -Qpr1_portrait
9543</screen>
9544</informalexample>
9545</para>
9546
9547<para>The <literal>force_queuename</literal> can be used for force
9548a specific value into the control file
9549<literal remap=tt>Q</literal>
9550information.
9551<informalexample>
9552<screen>john|tom|frank
9553  :filter=/.../filter
9554  :lp=/dev/pr
9555  :force_queuename=office
9556
9557lpr -Pjohn
9558  control file -
9559   Qoffice
9560
9561filter command line:
9562  ... -Qoffice</screen>
9563</informalexample>
9564</para>
9565
9566</sect1>
9567
9568<sect1 id="checkfornonprintable"><title>Check For Nonprintable File </title>
9569
9570<para>Options used:
9571<itemizedlist>
9572
9573<listitem>
9574<para> <literal>check_for_nonprintable</literal> FLAG <emphasis><application>lpr</application> checks for non-printable file </emphasis></para>
9575</listitem>
9576
9577<listitem>
9578<para> <literal>ml=</literal><emphasis>minimum number of printable characters </emphasis></para>
9579</listitem>
9580
9581</itemizedlist>
9582</para>
9583
9584<para>By default
9585<application>lpr</application>
9586does not check files for
9587for non-printable characters (i.e., escape characters) at the start
9588of the print file.
9589You can set the <literal>check_for_nonprintable</literal> flag to cause it to do so.
9590The
9591<literal remap=tt>:ml</literal>
9592value specifies the number of characters that
9593are to be checked.
9594Clearly,  if it is 0, none will be checked.</para>
9595
9596</sect1>
9597
9598<sect1 id="lprbounce"><title>Job Filtering By LPR </title>
9599
9600<para>Options used:
9601<itemizedlist>
9602
9603<listitem>
9604<para> <literal>lpr_bounce</literal> FLAG <emphasis>lpr does filtering</emphasis></para>
9605</listitem>
9606
9607</itemizedlist>
9608</para>
9609
9610<para>Some users would like the advantages of
9611the filtering and processing capabilities of a lpd daemon
9612without running a <application>lpd</application> daemon on their system.
9613By having the <application>lpr</application> program
9614process the job by passing it through the various filters
9615and then send the output of the filters as the print job you can
9616get the desired effect.
9617<informalexample>
9618<screen># Simple example of an lpr_bounce entry
9619bounce
9620  :lpr_bounce
9621  :lp=lp@remote
9622  :filter=/usr/local/bin/lpf</screen>
9623</informalexample>
9624</para>
9625
9626<para>The
9627<literal>lpr_bounce</literal>
9628flag, if present in the printcap entry,
9629will force
9630<application remap=tt> lpr </application>
9631to process the job using the
9632specified filters and send the outputs of the filters to the remote printer
9633for further processing.</para>
9634
9635</sect1>
9636
9637<sect1 id="rg"><title>Restrict Queue Use to Group Members </title>
9638
9639<para>Options used:
9640<itemizedlist>
9641
9642<listitem>
9643<para> <literal>rg=</literal><emphasis>Restricted group list</emphasis></para>
9644</listitem>
9645
9646</itemizedlist>
9647</para>
9648
9649<para>The
9650<literal remap=tt>:rg</literal>
9651value specifies a list of groups.
9652If this value is present use of a printer or operation is restricted to only
9653users in a particular group.
9654This check is done by both the <application>lpr</application> client and the <application>lpd</application>
9655server if the option is present.</para>
9656
9657</sect1>
9658
9659<sect1 id="safechars"><title>Fixing Bad Control Files and Metacharacters </title>
9660
9661<para>Options used:
9662<itemizedlist>
9663
9664<listitem>
9665<para> <literal>safe_chars=</literal><emphasis>additional safe characters for control file </emphasis></para>
9666</listitem>
9667
9668</itemizedlist>
9669</para>
9670
9671<para>RFC1179 defines a simple protocol and standard for print jobs to be
9672interchanged between print spooling systems.
9673Unfortunately,
9674there were some major mistakes in not specifying the exact form
9675that text would take when placed in the control file.</para>
9676
9677<para>By default,
9678&LPRng; will brutally convert a non-conforming RFC1179 control file
9679into one that is acceptable to most,
9680if not all,
9681existing RFC1179 implementations.
9682In order to prevent problems with
9683&LPRng; ruthlessly purges all characters but
9684upper and lower case letters,
9685spaces, tabs, and <literal>-_.@/:()=,+-%</literal> from the control file,
9686replacing suspicious characters with underscore (<literal/_/).
9687In addition,
9688&LPRng; will ruthlessly regenerate control file entries and data file names
9689so that they are compliant with all known RFC1179 implementations.</para>
9690
9691<para>For some installations,
9692the default set of safe characters may be overly restrictive.
9693For example,
9694<emphasis>vintage</emphasis>
9695software may generate files with
9696<literal remap=tt>#</literal>
9697characters
9698in the
9699<literal remap=tt>J</literal>
9700line of the control file.
9701The replacement of this character by underscore
9702(<literal/_/) may cause other applications which use the control file
9703information to stop working.
9704The <literal>:safe_chars</literal> option allows the user to specify an additional
9705set of safe characters in the <filename>lpd.conf</filename> configuration file(s).</para>
9706
9707<para>For example, <literal>:safe_chars=#"</literal> would allow the
9708<literal remap=tt>#</literal>
9709and
9710<literal remap=tt>"</literal>
9711characters to appear in the control file.</para>
9712
9713</sect1>
9714
9715<sect1 id="minfree"><title>Minimum Spool Queue Free Space </title>
9716
9717<para>Options used:
9718<itemizedlist>
9719
9720<listitem>
9721<para> <literal>minfree=</literal><emphasis>Size in Kbytes</emphasis></para>
9722</listitem>
9723
9724</itemizedlist>
9725</para>
9726
9727<para>If this value is non-zero,
9728then the <application>lpd</application> receiving server checks to see that there is the
9729specified number of Kbytes of file space available before
9730accepting a job.
9731If there is not enough space then the job
9732is rejected.</para>
9733
9734</sect1>
9735
9736<sect1 id="forcefqdnhostname"><title>FQDN Host Information </title>
9737
9738<para>Options used:
9739<itemizedlist>
9740
9741<listitem>
9742<para><literal>force_fqdn_hostname</literal> FLAG <emphasis>Update control file with FQDN name</emphasis></para>
9743</listitem>
9744
9745<listitem>
9746<para><literal>force_ipaddr_hostname</literal> FLAG <emphasis>Update control file with IP address of remote host</emphasis></para>
9747</listitem>
9748
9749<listitem>
9750<para><literal>use_shorthost</literal> FLAG <emphasis>short control and data file names</emphasis></para>
9751</listitem>
9752
9753</itemizedlist>
9754</para>
9755
9756<para>Some <application>lpr</application> clients do not put a FQDN host name in their control file.
9757The <literal>force_fqdn_hostname</literal> flag will cause <application>lpd</application> to put a FQDN
9758host name in the control file.
9759This option will assume that the domain is where the connection originated from.</para>
9760
9761<para>Similarly, the <literal>force_ipaddr_hostname</literal>
9762flag will cause <application>lpd</application> to put a FQDN
9763host name in the control file.</para>
9764
9765<para>Some systems cannot handle FQDN hostnames in control and data file formats.
9766The <literal>use_shorthost</literal> option will send control and data files with
9767very short names to the remote print server.</para>
9768
9769</sect1>
9770</chapter>
9771
9772<chapter id=lpq><title><application/lpq/ - Status Monitoring Program </title>
9773
9774<para>The <application>lpq</application> program is the main method used to monitor queues.
9775You can obtain the available options by using:
9776<informalexample>
9777<screen><prompt>h4: {306} % </prompt><userinput>lpq -=</userinput>
9778lpq: Illegal option '='
9779usage: lpq [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime]
9780  -a           - all printers
9781  -c           - clear screen before update
9782  -l           - increase (lengthen) detailed status information
9783                 additional l flags add more detail.
9784  -L           - maximum detailed status information
9785  -n linecount - linecount lines of detailed status information
9786  -Ddebuglevel - debug level
9787  -Pprinter    - specify printer
9788  -s           - short (summary) format
9789  -tsleeptime  - sleeptime between updates
9790  -V           - print version information</screen>
9791</informalexample>
9792</para>
9793
9794<sect1><title><application>lpq</application> Queue Selection (lpq -Pprinter, lpq -a)</title>
9795<para>
9796If no queue is specified,
9797then the default queue is used,
9798with <literal>-Pprinter@host</literal> causing a direct
9799connection to the named host.
9800The <literal>-a</literal> literal selects all queues.
9801</para>
9802</sect1>
9803
9804
9805<sect1><title><application>lpq</application> Job Selection</title>
9806<para>
9807Jobs are selected by providing a job number,
9808or <literal/glob/ pattern that is matched to the user name
9809and and job identifier.
9810If multiple patterns are provided each is applied in turn
9811against the jobs in a queue until all have been tried.
9812If any one of the patterns match then the job status is displayed.
9813</para>
9814<para>
9815If no selection information
9816is provided or the <literal>all</literal> pattern is provided
9817then all jobs in the queue are displayed.
9818</para>
9819</sect1>
9820
9821<sect1><title><application>lpq</application> Short Format (lpq -s)</title>
9822
9823<para>This is one line per spool queue:
9824<informalexample>
9825<screen>% lpq -sa
9826t1@astart110  (printing disabled) 1 job
9827t2@astart110  (routed/bounce to t1@h10.private) 0 jobs
9828t3@astart110  (forwarding to t3a@h10.private)
9829t3a@astart110  (forwarding to t2@h10.private)
9830t4@astart110  (subservers t5, t6)  0 jobs
9831t5@astart110  (serving t4) 0 jobs
9832t6@astart110  (serving t4) 0 jobs</screen>
9833</informalexample>
9834</para>
9835
9836<para>Note that the name of the printer/host is first,
9837followed by optional status information, followed by
9838the number of jobs.  Only printcap entries with
9839spool queues have a jobs word in the last position.
9840The
9841<literal>-a</literal> literal forces status for all queues or the
9842queues in the
9843<literal>all</literal>
9844printcap entry to be returned.</para>
9845
9846<para>The <literal>stalled_time</literal> (default 120 seconds) printcap option can be used to set a
9847time after which active jobs will be reported as stalled.</para>
9848
9849</sect1>
9850
9851<sect1><title><application>lpq</application> Long Format (lpq, lpq -l, lpq -L)</title>
9852
9853<para>This is the default status display.
9854It is a nicely formatted, extremely verbose format
9855that is suitable for humble human interpretation. For example:
9856<informalexample>
9857<screen>% lpq -a
9858Printer: t1@astart110  'Test Printer 1' (printing disabled)
9859 Queue: 1 printable job
9860 Server: no server active
9861 Status: finished operations at 09:44:00
9862 Rank   Owner/ID            Class Job  Files         Size Time
98631       papowell@lprng110+202228663 A 10663 /tmp/hi     3 20:22:29
9864Printer: t2@astart110  'Test Printer 2' (routed/bounce to t1@h10.private)
9865 Queue: no printable jobs in queue
9866 Status: finished operations at 16:30:08
9867Printer: t3@astart110  (forwarding to t3a@h10.private)
9868Printer: t3a@astart110  (forwarding to t2@h10.private)
9869Printer: t4@astart110  (subservers t5, t6)
9870 Queue: no printable jobs in queue
9871 Status: finished operations at 09:44:06
9872Server Printer: t5@astart110  (serving t4)
9873 Queue: no printable jobs in queue
9874 Status: finished operations at 09:44:06
9875Server Printer: t6@astart110  (serving t4)
9876 Queue: no printable jobs in queue
9877 Status: finished operations at 09:10:00</screen>
9878</informalexample>
9879</para>
9880
9881<para>The <command>lpq -l</command> (longer information)
9882option causes more of the status information to be printed.
9883You can use increasing numbers of <command>lpq -l</command> options
9884(<command> lpq -ll</command> also works) to get more status.
9885Use <command> lpq -L</command> for the maximum amount of status information.</para>
9886
9887</sect1>
9888
9889<sect1><title><application>lpq</application> Verbose Format (lpq -v)</title>
9890
9891<para>This uses an extension to the RFC1179 protocol,
9892and is supported only by &LPRng;.
9893The amount of information displayed is the brutal,
9894and in effect does a total database dump
9895of the LPD.
9896This has been developed in order to provide diagnostic
9897and status information for databases that need to keep track of
9898job progress through a spool queue.
9899<informalexample>
9900<screen>% lpq -v
9901Printer: t1@astart110
9902 Comment: Test Printer 1
9903 Printing: no
9904 Spooling: yes
9905 Queue: 1 printable job
9906 Server: no server active
9907 Status: accounting at end 'papowell@lprng110+094352860' at 09:44:00
9908 Status: printing 'papowell@lprng110+094352860', \
9909            closing device at 09:44:00
9910 Status: printing 'papowell@lprng110+094352860', finished  at 09:44:00
9911 Status: subserver status 'JSUCC' for 'papowell@lprng110+094352860' \
9912            on attempt 1 at 09:44:00
9913 Status: finished operations at 09:44:00
9914 Job: papowell@lprng110+202228663 status= 1
9915 Job: papowell@lprng110+202228663 CONTROL=
9916 - Hh10.private
9917 - Ppapowell
9918 - J/tmp/hi
9919 - CA
9920 - Lpapowell
9921 - Apapowell@lprng110+202228663
9922 - Qt1
9923 - fdfA010663h10.private
9924 - N/tmp/hi
9925 - UdfA010663h10.private
9926 Job: papowell@lprng110+202228663 HOLDFILE=
9927 - active 0
9928 - done 0
9929 - hold 0
9930 - move 0
9931....</screen>
9932</informalexample>
9933</para>
9934
9935</sect1>
9936
9937<sect1 id="stalledtime"><title>Job Taking Too Long - Stalled </title>
9938
9939<para>Options used:
9940<itemizedlist>
9941
9942<listitem>
9943<para><literal>stalled_time=</literal><emphasis>seconds after which to report a stalled active job</emphasis></para>
9944</listitem>
9945
9946</itemizedlist>
9947</para>
9948
9949<para>The <literal>stalled_time</literal> option is actually used by the <application>lpd</application>
9950server to report that a job has been active more than the indicated
9951time with no change in state.
9952This is useful for spotting things such a printers that are out of paper,
9953and so forth.</para>
9954
9955</sect1>
9956
9957<sect1><title>Configuring Format and Displayed Information</title>
9958
9959<para>The following sections describe options that are used by the
9960<application>lpd</application> server to control how it will return status information
9961to a <application>lpq</application> request.</para>
9962
9963
9964<sect2 id="classinstatus"><title>Display Class Information </title>
9965
9966<para>Options used:
9967<itemizedlist>
9968
9969<listitem>
9970<para> <literal>class_in_status</literal> FLAG <emphasis>show class name in status</emphasis></para>
9971</listitem>
9972
9973</itemizedlist>
9974</para>
9975
9976<para>Setting the <literal>class_in_status</literal> option causes the class name rather
9977than priority to be displayed in the status information.</para>
9978
9979</sect2>
9980
9981<sect2 id="reverselpqformat"><title>Reverse Short and Long <application/lpq/ Formats </title>
9982
9983<para>Options used:
9984<itemizedlist>
9985
9986<listitem>
9987<para> <literal>reverse_lpq_format=</literal> FLAG <emphasis>reverse <application/lpq/ status format for specified remote systems</emphasis></para>
9988</listitem>
9989
9990</itemizedlist>
9991</para>
9992
9993<para>Various Solaris and other System V implementations support an RFC1179 interface
9994to remote printers.
9995Unfortunately,  there is a problem in that when they send a status request,
9996the status format is reversed.
9997That is,
9998when LONG status format is wanted,
9999they send SHORT,
10000and vice versa.</para>
10001
10002<para>The <literal>reverse_lpq_format=</literal> specifies a list of printers or IP addresses
10003for which the <application>lpd</application> server will return LONG status when SHORT is
10004requested,
10005and vice versa.
10006For example:
10007<informalexample>
10008<screen>reverse_lpq_format=*.eng.com,130.192.0.0/16</screen>
10009</informalexample>
10010</para>
10011
10012<para>will cause hosts whose Fully Qualified Domain Name (FQDN) ends in
10013<filename>eng.com</filename> or from subnet
10014<literal remap=tt>130.192.0.0</literal>
10015to have reversed
10016status returned.</para>
10017
10018</sect2>
10019
10020<sect2 id="shortstatus"><title>Status Line Length and Line Count
10021</title>
10022
10023<para>Options used:
10024<itemizedlist>
10025
10026<listitem>
10027<para> <literal>return_short_status=</literal><emphasis>return short <application/lpq/ status for specified remote systems</emphasis></para>
10028</listitem>
10029
10030<listitem>
10031<para>
10032<literal remap=tt>short_status_length=</literal><emphasis>short <application/lpq/ status length in lines</emphasis></para>
10033</listitem>
10034
10035</itemizedlist>
10036</para>
10037
10038<para>In order to be compatible with non-&LPRng; client programs,
10039some administrators would like <application>lpd</application> to return a short or brief
10040status to normal status queries.</para>
10041
10042<para>The <literal>return_short_status=</literal> specifies a list of printers or IP addresses
10043for which the <application>lpd</application> server will return an abbreviated
10044status when LONG status is requested.
10045For example:
10046<informalexample>
10047<screen>return_short_status=*.eng.com,130.192.0.0/16
10048short_status_length#3</screen>
10049</informalexample>
10050</para>
10051
10052<para>will cause hosts whose Fully Qualified Domain Name (FQDN) ends in
10053<filename>eng.com</filename> or from subnet
10054<literal remap=tt>130.192.0.0</literal>
10055to get only
100563 lines of detailed status returned.</para>
10057
10058</sect2>
10059
10060<sect2 id="forcelpqstatus"><title><application>lpq</application> Status Format Determined by Requesting Host Address </title>
10061
10062<para>Options used:
10063<itemizedlist>
10064
10065<listitem>
10066<para> <literal>force_lpq_status=</literal><emphasis>force <application/lpq/ status format for specified remote systems</emphasis></para>
10067</listitem>
10068
10069</itemizedlist>
10070</para>
10071
10072<para>In order to be compatible with non-&LPRng; client programs which
10073are totally unpredictable,
10074this allows the administrator to specify the format for <application/lpq/
10075status when requests arrive.</para>
10076
10077<para>The <literal>force_lpq_status=</literal> specifies a list of formats
10078and printers or IP addresses
10079for which the <application>lpd</application> server will return status
10080in the specified format.
10081The entry has the format
10082<literal>KEY=list;KEY=list...</literal> where
10083<acronym>KEY</acronym> is
10084<literal remap=tt>s</literal>
10085for short and
10086<literal remap=tt>l</literal>
10087for long format,
10088and list is a list of hosts or IP addresses.
10089For example:
10090<informalexample>
10091<screen>force_lpq_status=s=pc*.eng.com,130.192.12.0/24,l=sun*.eng.com</screen>
10092</informalexample>
10093</para>
10094
10095<para>will cause hosts whose Fully Qualified Domain Name (FQDN) matches
10096<filename>pc*eng.com</filename> or from subnet
10097<literal remap=tt>130.192.12.0</literal>
10098to get short
10099status returned and hosts which match <filename>sun*.eng.com</filename> get
10100long status.</para>
10101
10102</sect2>
10103</sect1>
10104</chapter>
10105<chapter id=lprm><title><application/lprm/ - Job Removal Program </title>
10106<para>
10107The <application/lprm/ program is used to remove jobs from
10108a print queue.
10109You can obtain the available options by using:
10110<informalexample>
10111<screen><prompt>h4: {307} % </prompt><userinput>lprm -=</userinput>
10112lprm: Illegal option '='
10113 usage: lprm [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')*
10114  -a           - all printers
10115  -A           - use authentication
10116  -Pprinter    - printer (default PRINTER environment variable)
10117  -Uuser       - impersonate this user (root or privileged user only)
10118  -Ddebuglevel - debug level
10119  -V           - show version information
10120  user           removes user jobs
10121  all            removes all jobs
10122  jobid          removes job number jobid
10123 Example:
10124    'lprm -Plp 30' removes job 30 on printer lp
10125    'lprm -a'      removes all your jobs on all printers
10126    'lprm -a all'  removes all jobs on all printers
10127  Note: lprm removes only jobs for which you have removal permission</screen>
10128</informalexample>
10129</para>
10130
10131<sect1><title><application>lprm</application> Queue Selection (lprm -Pprinter, lprm -a)</title>
10132<para>
10133If no queue is specified,
10134then the default queue is used,
10135with <literal>-Pprinter@host</literal> causing a direct
10136connection to the named host.
10137The <literal>-a</literal> literal selects all queues.
10138</para>
10139</sect1>
10140
10141
10142
10143<sect1><title><application>lprm</application> Job Selection</title>
10144<para>
10145Jobs are selected by providing a job number,
10146or <literal/glob/ pattern that is matched to the user name
10147and and job identifier.
10148If multiple patterns are provided each is applied in turn
10149against the jobs in a queue until all have been tried.
10150If any one of the patterns match then the job status is displayed.
10151</para>
10152<para>
10153If no selection information
10154is provided then the user name
10155performing the request is used as the selection pattern,
10156and only the first job that matches is removed.
10157</para>
10158<para>
10159The <literal>all</literal> pattern will match
10160all jobs in the queue.
10161</para>
10162<para>
10163The user must have permission to control the queue
10164or to remove a selected job in order for job removal to succeed.
10165</para>
10166</sect1>
10167
10168</chapter>
10169<chapter id=lpc><title><application/lpc/ - Administration Program </title>
10170
10171<para>The
10172<application>lpc</application> command is the main way that the <application>lpd</application> server
10173is controlled.
10174Here is the help information displayed by the command:
10175<informalexample>
10176<screen><prompt>h4: {308} % </prompt><userinput>lpc -=</userinput>
10177lpc: Illegal option '='
10178usage: lpc [-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command]
10179 with no command, reads from stdin
10180  -Ddebuglevel - debug level
10181  -Pprinter    - printer or printer@host
10182  -Shost       - connect to lpd server on host
10183  -Uuser       - identify command as coming from user
10184  -V           - increase information verbosity
10185 commands:
10186 active  (printer[@host])        - check for active server
10187 abort   (printer[@host] | all)  - stop server
10188 class   printer[@host] (class | off) - show/set class printing
10189 disable (printer[@host] | all)  - disable queueing
10190 debug   (printer[@host] | all) debugparms - set debug level for printer
10191 down    (printer[@host] | all)  - disable printing and queueing
10192 enable  (printer[@host] | all)  - enable queueing
10193 hold    (printer[@host] | all) (name[@host] | job | all)* - hold job
10194 holdall (printer[@host] | all)  - hold all jobs on
10195 kill    (printer[@host] | all)  - stop and restart server
10196 lpd     (printer[@host]) - get LPD PID
10197 lpq     (printer[@host] | all) (name[@host] | job | all)*   - run <application/lpq/
10198 lprm    (printer[@host] | all) (name[@host]|host|job| all)* - run <application/lprm/
10199 msg printer message text- set status message
10200 move printer (user|jobid)* target - move jobs to new queue
10201 noholdall (printer[@host] | all)- hold all jobs off
10202 printcap(printer[@host] | all)  - report printcap values
10203 quit                            - exit LPC
10204 redirect(printer[@host] | all) (printer@host | off )*     - redirect jobs
10205 redo    (printer[@host] | all) (name[@host] | job | all)* - redo jobs
10206 release (printer[@host] | all) (name[@host] | job | all)* - release jobs
10207 reread  (printer[@host])        - LPD reread database information
10208 start   (printer[@host] | all)  - start printing
10209 status  (printer[@host] | all)  - status of printers
10210 stop    (printer[@host] | all)  - stop  printing
10211 topq    (printer[@host] | all) (name[@host] | job | all)*  - reorder job
10212 up      (printer[@host] | all) - enable printing and queueing
10213   diagnostic:
10214      defaultq               - show default queue for LPD server
10215      defaults               - show default configuration values
10216      client  (printer | all) - client config and printcap information
10217      server (printer | all) - server config and printcap</screen>
10218</informalexample>
10219</para>
10220
10221<para>Most of the <application>lpc</application> command line options are common to all
10222
10223<link linkend="lprngclients">&LPRng; Clients</link>,
10224with the exception of the <literal>-S server</literal> literal.
10225This option allows the <application>lpd</application> host to be explicitly specified.</para>
10226
10227<para>The <application>lpc</application> commands can be classified as
10228<emphasis>informational</emphasis>,
10229<emphasis>queue management</emphasis>,
10230<emphasis>problem management</emphasis>,
10231<emphasis>job scheduling</emphasis>,
10232and
10233<emphasis>diagnostic</emphasis>.</para>
10234
10235
10236<sect1><title>Informational Commands - status, flush, active, reread</title>
10237
10238<para>
10239The
10240<command remap=tt>lpc status</command>
10241command
10242displays the current status of various activities of interest to the
10243system administrator.
10244This information includes the process ID of the server and other processes.
10245</para>
10246
10247<para>
10248During normal operation,
10249when requested for job status information the <application/lpd/ server will create
10250this information and then save it in a status cache.
10251When successive requests for the same information arrive,
10252the cache is checked to see if the information is already in the cache
10253and there have been no status changes.
10254If this is the case,
10255the cached status information is used.
10256The
10257<command remap=tt>lpc flush</command>
10258command will flush (delete) this cache information and cause the
10259<application/lpd/ server to regenerate it from the original
10260job files.
10261</para>
10262
10263<para>The
10264<command remap=tt>lpc active</command>
10265command connects to the print server and
10266gets the Process ID of the <application>lpd</application> process.
10267This is useful to determine if the <application>lpd</application> server is running
10268on the print server.</para>
10269
10270<para>The
10271<command remap=tt>reread</command>
10272command connects to the <application>lpd</application> print server and requests
10273that the server reread the
10274<filename>printcap</filename>,
10275<filename>lpd.conf</filename>,
10276and
10277<filename>lpd.perms</filename> database files.</para>
10278
10279</sect1>
10280
10281<sect1><title>Queue Management - enable, disable, up, down</title>
10282
10283<para>The
10284<command remap=tt>enable</command>
10285and
10286<command remap=tt>disable</command>
10287commands enable and disable <emphasis>queuing</emphasis>
10288or sending jobs to the
10289print queue.
10290The
10291<command remap=tt>up</command>
10292command combines the
10293<command remap=tt>enable</command>
10294and
10295<command remap=tt>start</command>
10296commands
10297while
10298the
10299<command remap=tt>down</command>
10300command combines the
10301<command remap=tt>disable</command>
10302and
10303<command remap=tt>stop</command>
10304commands.</para>
10305
10306</sect1>
10307
10308<sect1><title>Printing Management - start, stop, up, down</title>
10309
10310<para>These commands are used to start and stop printing.
10311The
10312<command remap=tt>up</command>
10313combines
10314<command remap=tt>start</command>
10315and
10316<command remap=tt>enable</command>,
10317while
10318<command remap=tt>down</command>
10319combines
10320<command remap=tt>stop</command>
10321and
10322<command remap=tt>disable</command>.</para>
10323
10324</sect1>
10325
10326<sect1><title>Problem Management - abort, redo, kill</title>
10327
10328<para>These commands are usually used when there is a problem
10329printing a job.
10330The
10331<command remap=tt>abort</command>
10332command is used to kill off all printing activity
10333associated with a job.
10334It also has the side effect of stopping printing on the print queue.
10335The
10336<command remap=tt>redo</command>
10337command  will redo or attempt to reprint a job.
10338The
10339<command remap=tt>kill</command>
10340command combines the abort and redo command,
10341and is useful when there are problems with the job currently being printed
10342and it should be reprinted.</para>
10343
10344</sect1>
10345
10346<sect1><title>Job Scheduling - topq, holdall, noholdall, hold, release</title>
10347
10348<para>The
10349<command remap=tt>topq</command>
10350command effectively puts the select job or jobs at the top
10351of the queue for printing.</para>
10352
10353<para>The
10354<command remap=tt>holdall</command>,
10355<command remap=tt>noholdall</command>,
10356and
10357<command remap=tt>release</command>
10358commands implement a simple holding queue for jobs.
10359By default,
10360<command remap=tt>holdall</command>
10361is disabled.
10362When the
10363<command remap=tt>holdall</command>
10364command enables it,
10365then jobs will remain in the spool queue until explicitly released
10366with the
10367<command remap=tt>release</command>
10368command.</para>
10369
10370<para>The
10371<command remap=tt>hold</command>
10372command can also be used to hold individual jobs
10373until released.</para>
10374
10375</sect1>
10376
10377<sect1 id="lpcredirect"><title>Queue Management - class, redirect, move </title>
10378
10379<para>The
10380<command remap=tt>class</command>
10381command is used to restrict printing to jobs
10382whose class value,
10383set using the <command>lpr -C class</command> option,
10384is in the class list or matches one of the classes.
10385This allows the administrator to restrict printing.
10386For more details and an example of its use,
10387see Form Support.</para>
10388
10389<para>The
10390<command remap=tt>redirect</command>
10391command allows the administrator to accepts jobs
10392at this queue and then to have them forwarded or redirected
10393to another print queue.
10394This is useful when a printer temporarily is unavailable.</para>
10395
10396<para>The
10397<command remap=tt>move</command>
10398command allows an individual job (or jobs)
10399to be forwarded or redirected to another print queue.</para>
10400
10401</sect1>
10402</chapter>
10403
10404<chapter id=checkpc><title><application/checkpc/ - Configuration Validation Utility </title>
10405
10406<para>The <application>checkpc</application> (check printcap file) is one of the most
10407useful utilities in the &LPRng; package.</para>
10408
10409<para>It will read all the configuration files, printcap files and tests
10410whether devices are set up correctly. Optionally, it will also set the
10411permissions for spool directories and device files. Additionally, it
10412will truncate the accounting and log files to a maximum size. Another
10413use for <application>checkpc</application> is to remove old entries from queue
10414directories.</para>
10415
10416<para>For a new installation, you will want to run
10417<informalexample>
10418<screen>checkpc -f -V</screen>
10419</informalexample>
10420
10421to set the permissions right. The <literal>-f</literal> flag instructs the
10422program to correct file permissions. If you don't run this as
10423<literal remap=tt>ROOT</literal>, you'll receive a warning about that fact and any
10424<function>chown(2)</function> calls will (most likely) fail.</para>
10425
10426<para>The program reports everything it changes. Since it isn't too clever
10427about some things (visit the man page), you should keep an eye on the
10428output, and run it again if needed. If it keeps failing, change the
10429permissions yourself.</para>
10430
10431
10432<sect1><title>Maintenance</title>
10433
10434<para>Later, you will want to use <application>checkpc</application> for the daily
10435maintenance of your system.
10436I have this line in user
10437<literal remap=tt>lp</literal>'s
10438crontab:
10439<informalexample>
10440<screen>32 5 * * * checkpc -t 10K -A3 -r &gt;/dev/null 2&gt;&amp;1</screen>
10441</informalexample>
10442
10443This job will:
10444<orderedlist>
10445
10446<listitem>
10447<para>truncate all log and accounting files to 10KB (<literal>-t 10K</literal>).
10448Actually, it will keep the last 10K from the file, starting on a
10449complete line.</para>
10450</listitem>
10451
10452<listitem>
10453<para>remove all stale files older than three days (<literal>-A3 -r</literal>).</para>
10454</listitem>
10455
10456</orderedlist>
10457
10458I'm redirecting output to <filename>/dev/null</filename>, because <application>checkpc</application>
10459is a little noisy to my taste. (But too noisy is better than too
10460silent :)</para>
10461
10462</sect1>
10463
10464<sect1><title>Printcap Information</title>
10465
10466<para>You can use <command>checkpc -V -P</command>
10467to examine printcaps and tell you what
10468they contain.
10469This is identical to the
10470<command remap=tt>lpc server all</command>
10471operation,
10472but with a higher level of verbosity.</para>
10473
10474</sect1>
10475</chapter>
10476
10477<chapter id=printercomm><title>Printer Communication and Protocols </title>
10478
10479<para>Common communication methods between a printer and a host system
10480are network connections,
10481parallel ports,
10482or serial ports;
10483while Fibre Channel, SCSI, USB, FireWire,
10484InfraRed,
10485and other interesting technologies have been used,
10486they are either very specialized or not directly
10487support by the &LPRng; software.
10488In this section we will discuss Network,
10489Parallel Port,
10490and Serial Printers,
10491as well as the different protocols and standards that apply to them.</para>
10492<sect1 id="networkprinter"><title>Network Printers </title>
10493
10494<para>The most flexible and highest throughput printer interface is
10495via a network (TCP/IP) connection.
10496Most high performance printers have a built in network interface,
10497or you can attach them to a
10498<emphasis>printer server</emphasis>
10499box which provides a network interface.
10500The network interface usually supports multiple network printing protocols.
10501The most common are the LPD (RFC1179), Socket API, AppSocket, SMB,
10502and Novell Netware interfaces.
10503&LPRng; directly supports the LPD (RFC1179) and Socket API interfaces,
10504and you can use the
10505<application remap=tt>smbclient</application>
10506program from the
10507
10508<link linkend="smb">Samba Software Package</link>
10509 for the SMB interface.</para>
10510
10511</sect1>
10512
10513<sect1><title>RFC1179 (LPD) Connection</title>
10514
10515<para>In this mode of operation the print server actually operates as a very
10516limited BSD print spooler.
10517These limitations include:
10518<orderedlist>
10519
10520<listitem>
10521<para>No error messages or status capability</para>
10522</listitem>
10523
10524<listitem>
10525<para>Limited or very primitive banner printing.
10526On some systems it may be <emphasis>impossible</emphasis>
10527to turn banner printing off.</para>
10528</listitem>
10529
10530<listitem>
10531<para>On most known print servers high connection activity caused
10532by multiple systems attempting to get status or spool jobs
10533may cause catastrophic failure of the printer.</para>
10534</listitem>
10535
10536</orderedlist>
10537</para>
10538
10539<para>For the above reasons,
10540using RFC1179 to transfer jobs to a printer should be regarded as the
10541least desirable option.
10542Please see
10543
10544<link linkend="rfc1179ref">The RFC1189 Protocol</link>
10545
10546for a detailed discussion of the RFC1179 protocol.</para>
10547
10548<para>In order to use the RFC1179 transfer operation you must have a printcap entry
10549for the printer that provides:
10550<itemizedlist>
10551
10552<listitem>
10553<para>The IP address or name of the printer that can be resolved to an IP address</para>
10554</listitem>
10555
10556<listitem>
10557<para>The name of the spool queue.
10558In practice,
10559this is usually used only to determine which of several printer ports
10560on the print server the job will be sent to,
10561or what type of processing the print server will do.
10562Most cards usually do not do any processing and simply pass the job
10563through to the printer.</para>
10564</listitem>
10565
10566</itemizedlist>
10567</para>
10568
10569<para>The following is an example of a simple printcap entry that
10570can be used to send a job to a remote printer using the RFC1179 protocol:
10571<informalexample>
10572<screen># &LPRng; syntax
10573# :lp value is 'where to print the job'
10574lp:
10575  :lp=raw@10.0.0.1
10576
10577# OR Vintage BSD Print Spooler Syntax
10578# (&LPRng; supports this as well)
10579# :rp = remote printer, :rm = remote machine or host
10580lp:
10581  :rp=raw:rm=10.0.0.1</screen>
10582</informalexample>
10583</para>
10584
10585<para>If you wish to transfer jobs to a print spooler without using the
10586full &LPRng; <application>lpr</application> program,
10587the Perl <literal>lpr_in_perl</literal> program
10588in the &LPRng; Distribution <acronym>UTILS</acronym> directory
10589can be used for testing and tutorial purposes.</para>
10590
10591</sect1>
10592
10593<sect1 id="socketapi"><title>Socket API </title>
10594
10595<para>The Socket API is a very flexible job transfer protocol.
10596It is widely support by most Print Server manufacturers,
10597with the
10598Hewlett Packard JetDirect setting the
10599<emphasis>de facto</emphasis>
10600standard.
10601The Socket API is extremely simple.
10602<orderedlist>
10603
10604<listitem>
10605<para>The user establishes a connection to TCP/IP
10606port on the Printer or Network Print spooler.
10607The HP JetDirect uses port 9100 by default,
10608but other ports are used as well.
10609This connection may be refused if the printer is busy
10610printing a job.</para>
10611</listitem>
10612
10613<listitem>
10614<para>When the network connection is established to a system which
10615has an <emphasis>internal printer</emphasis>
10616or for which the Network Print Spooler
10617is an integral part of the system,
10618the printer usually flushes all internal buffers and readies itself
10619to receive a new job.
10620However,
10621when you are using an external Print Server box,
10622you may need to send specific initialization sequences to the printer
10623to ensure that it is reset correctly and is ready to receive new jobs.</para>
10624</listitem>
10625
10626<listitem>
10627<para>When the connection is made,
10628all bytes sent to the connection are either transferred to
10629and external interface to directly to a
10630<emphasis>print buffer</emphasis>
10631used by the printer's Print Engine.</para>
10632</listitem>
10633
10634<listitem>
10635<para>The connection is bidirectional,
10636and information sent to the external port by an external printer
10637or error messages and status generated by the printer's Print Engine
10638will be transferred over the data link to the user.</para>
10639</listitem>
10640
10641<listitem>
10642<para>The Network Print spooler will keep the connection open
10643until it is closed by the user.
10644During this period it may continue to report status or other
10645information such as printer On Line,
10646paper outages, and so forth.</para>
10647</listitem>
10648
10649<listitem>
10650<para>If the connection to the printer is
10651<emphasis>half-closed</emphasis>,
10652that is,
10653the <function>shutdown()</function> network system call is used to indicate to the
10654remote printer that no further data will be sent,
10655then the printer may immediately terminate the network connection.
10656This means that no further network or status messages will be
10657sent to the user.</para>
10658</listitem>
10659
10660<listitem>
10661<para>If the connection is to a External Print Server,
10662then usually the connection can be immediately re-established.
10663It is the responsibility of the user to ensure that a the printer
10664has finished its work before sending a new job.</para>
10665</listitem>
10666
10667<listitem>
10668<para>If the connection is to an internal Print Server,
10669then usually the printer will not allow the connection to be made,
10670or will refuse all data transfers on the connection until
10671the printer finishes with the previous job and all internal buffers
10672have been cleared.</para>
10673</listitem>
10674
10675</orderedlist>
10676</para>
10677
10678<para>The following is a sample printcap showing how to use the Socket API:
10679<informalexample>
10680<screen>lp:
10681  # make a socket connection to port 9100
10682  :lp=10.0.0.2%9100</screen>
10683</informalexample>
10684</para>
10685
10686<para>You can use the
10687<ulink URL="http://www.l0pht.com/~weld/netcat/">netcat</ulink>
10688utility by Hobbit <email>Hobbit@avian.org</email>
10689to test that the Socket interface is available and working.
10690If <filename>ellipse.ps</filename> is a test file, then:
10691The simplest and easiest way to print a file to a network printer appears
10692<informalexample>
10693<screen>  nc printer.ip.addr 9100 &lt; file
10694Example:
10695  nc 10.0.0.25 9100 &lt; ellipse.ps</screen>
10696</informalexample>
10697</para>
10698
10699</sect1>
10700
10701<sect1 id="appsocket"><title>AppSocket TCP/IP Protocol </title>
10702
10703<para>The AppSocket interface is supported by Tektronix and some other printer
10704vendors.
10705It is similar to the Socket API,
10706with a couple of significant differences.
10707<orderedlist>
10708
10709<listitem>
10710<para>The printer has two ports for network connections:
10711a TCP port 9100 for TCP/IP stream connections and a UDP port for UDP
10712packet connections.</para>
10713</listitem>
10714
10715<listitem>
10716<para>When a 0 length UDP packet or a UDP packet containing only <filename>CR/LF</filename>
10717is sent to UDP port 9101, the printer will return a packet to the sender
10718containing print status information.
10719This information indicates the printers current status (busy, idle, printing)
10720and any error conditions.</para>
10721</listitem>
10722
10723<listitem>
10724<para>The format,
10725reliability,
10726and repeatability of the UDP format and information is totally undocumented,
10727and the UPD port facility should be regarded as,
10728at best,
10729an advisory function of the printer.</para>
10730</listitem>
10731
10732<listitem>
10733<para>To send a job to the printer,
10734a connection to TCP port is made.
10735This connection will be refused while the printer is busy or has a connection
10736to another host.</para>
10737</listitem>
10738
10739<listitem>
10740<para>When the TCP connection is established,
10741the information to be printed can be sent over the TCP connection.
10742Bytes sent on this stream will be placed in the input buffer of the
10743Print Engine and processed.</para>
10744</listitem>
10745
10746<listitem>
10747<para>An end of job (EOJ) sequence indication
10748in the data stream will cause the printer to terminate the connection.
10749This is different than the Socket API,
10750where the printer will keep the connection open.
10751This means that if the PostScript CTRL-D (end of job) character is sent in
10752a job,  then the connection will be terminated.</para>
10753</listitem>
10754
10755<listitem>
10756<para>Some models of printers modify this behavior slightly and
10757will not terminate the connection,
10758but will simply ignore any data following the EOJ indication.</para>
10759</listitem>
10760
10761<listitem>
10762<para>Some printers support bidirectional AppSocket communication,
10763and while the connection is open will return error indications or status
10764information.</para>
10765</listitem>
10766
10767<listitem>
10768<para>Once all the data has been received and the job has finished printing,
10769the connection will be terminated by the printer.</para>
10770</listitem>
10771
10772</orderedlist>
10773</para>
10774
10775<para>The
10776<application remap=tt>ifhp</application>
10777filter,
10778one of the helper programs for &LPRng;,
10779is used with &LPRng; to provide AppSocket support.
10780For details,
10781please see the <citation>IFHP-HOWTO</citation>
10782in the
10783<ulink URL="http://www.private/"><application>ifhp</application> Distribution</ulink>
10784and
10785<link linkend="P450">Tektronix P450 and Family</link>
10786 for details.
10787The following is a typical printcap entry for
10788the AppSocket protocol.
10789The actual network connection to the printer is made by the
10790<application remap=tt>ifhp</application>
10791filter:
10792<informalexample>
10793<screen>lp:
10794  # &LPRng; opens a dummy connection for consistency
10795  :lp=/dev/null
10796  # we pass the ifhp filter options indicating that the
10797  # Tektronics printer will need the appsocket protocol
10798  # and to use port 35 at 10.0.0.1 to make the connection
10799  # The ifhp filter may open and close the connection several
10800  # times during the file transfer in order to ensure that
10801  # the printer handles the job correctly.
10802  :ifhp=model=tek,appsocket,dev=10.0.0.1%35
10803  :filter=/usr/local/libexec/filters/ifhp</screen>
10804</informalexample>
10805</para>
10806
10807</sect1>
10808
10809<sect1 id="secnetwork"><title>Network Print Server Boxes </title>
10810
10811<para>A <emphasis/network print server/ is usually a box
10812(external model) or card in a printer (internal model)
10813which has a network connection to a TCP network and
10814software to implement a LPD print server.
10815If it is an external model,
10816The parallel or serial port of
10817the printer is connected to the box,
10818and the print server may support multiple printers.
10819If it is an internal model,
10820the server is usually nothing more than a Network Interface Controller
10821and a ROM containing software that the microprocessor in the printer
10822uses.</para>
10823
10824<para>The print server may support multiple printing protocols,
10825such as
10826
10827<link linkend="rfc1179">RFC1179</link>
10828
10829(TCP/IP printing using the LPD print protocol),
10830Novell Printer Protocols,
10831SMB print protocols,
10832and AppleTalk protocols.
10833One of the observed problems with Network Print servers is that while they
10834can usually support one protocol and one user at a time quite well,
10835when you try to use multiple protocols and/or multiple users try to transfer
10836print jobs to the printer,  the printer may behave in a very odd manner.
10837Usually this results in a printer failing to finish a job currently being
10838printed,
10839and unable to accept new jobs.</para>
10840
10841<para>Several of the newer models of print servers have
10842Simple Network Management Protocol (SNMP) agents built into them,
10843and can provide detailed information about their internal functions.
10844By using a SNMP manager such as SunNetmanage or HP-Openview,
10845you can monitor your network printers activities.</para>
10846
10847<para>I recommend that you use only a single protocol to send jobs to the printer.
10848If you can,  I also recommend that you use a print spooler and have only
10849a single host system send a job to the printer.</para>
10850
10851<para>My best advice on connecting to network printers is not to use the
10852the built-in LPD server,
10853but to use the direct TCP/IP connection to the print engine.
10854Usually this is done to particular TCP/IP port on the printer.
10855For the HP JetDirect and other HP products, this is usually
10856TCP port 9100.</para>
10857
10858<para>Once you have the direct connection,
10859you can now use various filters to preprocess the print job,
10860insert PJL and PCL commands,
10861or convert text to PostScript or PCL for better print quality.</para>
10862
10863</sect1>
10864
10865<sect1><title>Network Print Server Configuration Information</title>
10866
10867<para>The following is a list of print server manufacturers,
10868models,
10869and with hints on how to access these boxes with various protocols.</para>
10870
10871<table id=newps frame=all><title>Network Print Server Configuration Information</title>
10872<tgroup cols=4 align=left colsep=1 rowsep=1>
10873<thead>
10874<row><entry>Manufacturer</entry><entry>Model</entry><entry>RFC1179 Port Name (rp=XXX)</entry><entry>Send to TCP port</entry></row>
10875</thead>
10876<tbody>
10877<row><entry><ulink URL="http://www.cannon.com/">Cannon Printer</ulink></entry><entry>Cannon 460 PS, no hard drive</entry><entry>xjdirect</entry><entry>- Unknown if supported -</entry></row>
10878<row><entry></entry><entry>Cannon 460 PS hard drive</entry><entry><literal remap=tt>xjprint</literal>
10879- print immediately,<literal remap=tt>xjhold</literal>
10880- print later</entry><entry>- Unknown if supported -</entry></row>
10881<row><entry><ulink URL="http://www.digprod.com/">Digital Products Inc.</ulink></entry><entry>NETPrint Print Server</entry><entry><literal remap=tt>PORT</literal><literal>n</literal>, where <literal>n</literal>
10882is port on server</entry><entry>- Unknown if supported -</entry></row>
10883<row><entry><ulink URL="http://www.efi.com/">Electronics For Imaging Inc.</ulink></entry><entry>Fiery RIP i series</entry><entry><literal remap=tt>normalq</literal>
10884or
10885<literal remap=tt>urgentq</literal></entry><entry>- Unknown if supported -</entry></row>
10886<row><entry></entry><entry>Fiery RIP XJ series</entry><entry><literal remap=tt>xjprint</literal></entry><entry>- Unknown if supported -</entry></row>
10887<row><entry></entry><entry>Fiery RIP XJ+ and SI series</entry><entry><literal>print_</literal><literal>Model</literal>, e.g. <literal>print_DocuColor</literal></entry><entry>- Unknown if supported -</entry></row>
10888<row><entry></entry><entry>Fiery models ZX2100, ZX3300, X2, X2e</entry><entry><literal remap=tt>print</literal></entry><entry>- Unknown if supported -</entry></row>
10889<row><entry><ulink URL="http://www.emulex.com/">Emulex Corp.</ulink></entry><entry>NETJet/NETQue print server</entry><entry><acronym>PASSTHRU</acronym></entry><entry>- Unknown if supported -</entry></row>
10890<row><entry><ulink URL="http://www.extendsys.com/">Extended Systems Inc.</ulink></entry><entry>ExtendNet Print Server</entry><entry><literal remap=tt>Printer<replaceable>n</replaceable></literal>, where <literal>n</literal>
10891is port on server</entry><entry>- Unknown if supported -</entry></row>
10892<row><entry><ulink URL="http://www.hp.com/">Hewlett-Packard</ulink></entry><entry>JetDirect interface card</entry><entry><literal remap=tt>raw</literal></entry><entry>9100</entry></row>
10893<row><entry><ulink URL="http://www.hp.com/">Hewlett-Packard</ulink></entry><entry>JetDirect Multiport Server</entry><entry><literal remap=tt>port 1 - raw1, port 2 - raw2, etc.</literal></entry><entry>port 1 - 9100, port 2 - 9101, etc.</entry></row>
10894<row><entry><ulink URL="http://www.i-data.com/">I-Data</ulink></entry><entry>Easycom 10 Printserver</entry><entry><literal remap=tt>par1</literal>
10895(parallel port 1)</entry><entry>- Unknown if supported -</entry></row>
10896<row><entry></entry><entry>Easycom 100 Printserver</entry><entry><literal remap=tt>LPDPRT1</literal></entry><entry>- Unknown if supported -</entry></row>
10897<row><entry><ulink URL="http://www.printers.ibm.com/">IBM</ulink></entry><entry>Network Printer 12, 17, 24, and 24PS</entry><entry><acronym>PASS</acronym></entry><entry>- Unknown if supported -</entry></row>
10898<row><entry><ulink URL="http://www.lantronix.com/">Lantronix</ulink></entry><entry>EPS1, EPS2</entry><entry><literal remap=tt>EPS_<literal>X_S1 (serial) port 1, EPS_X</literal>_P1 (parallel) port 2</literal>, etc.</entry><entry>3001 (port 1), 3002 (port 2), etc.</entry></row>
10899<row><entry><ulink URL="http://www.qms.com/">QMS</ulink></entry><entry>Various Models</entry><entry><acronym>RAW</acronym></entry><entry>35 (AppSocket)</entry></row>
10900<row><entry><ulink URL="http://www.tek.com">Tektronix</ulink></entry><entry>Tektronix printer network cards</entry><entry><acronym>PS</acronym> (PostScript), <acronym>PCL</acronym> (PCL), or <acronym>AUTO</acronym>(Auto-selection between PS, PCL, or HPGL). Not reliable.</entry><entry>9100 (AppSocket on some models)</entry></row>
10901<row><entry><ulink URL="http://www.rosel.com">Rose Electronics</ulink></entry><entry>Microserve Print Servers</entry><entry>lp</entry><entry>9100</entry></row>
10902<row><entry><ulink URL="http://www.xerox.com/">Xerox</ulink></entry><entry>Models 4505, 4510, 4517, 4520</entry><entry><acronym>PASSTHRU</acronym></entry><entry>2501 (AppSocket on some models)</entry></row>
10903<row><entry></entry><entry>Model 4512</entry><entry><literal remap=tt>PORT1</literal></entry><entry>10001 (programmable)</entry></row>
10904<row><entry></entry><entry>Model N17</entry><entry><acronym>RAW</acronym></entry><entry>9100</entry></row>
10905<row><entry></entry><entry>Models N24 and N32</entry><entry><acronym>RAW</acronym></entry><entry>2000</entry></row>
10906<row><entry></entry><entry>Models 4900, 4915, 4925, C55</entry><entry><acronym>PS</acronym></entry><entry>2000</entry></row>
10907<row><entry></entry><entry>Document Centre DC220/230</entry><entry><literal remap=tt>lp</literal></entry><entry>- Unknown if supported -</entry></row>
10908</tbody>
10909</tgroup>
10910</table>
10911
10912<para>All company, brand, and product names are properties of their respective owners.</para>
10913
10914</sect1>
10915
10916<sect1><title>HP JetDirect Interface</title>
10917<para>
10918The HP JetDirect Interface is one of the most widely used for network printers.
10919For this reason it also has the most widely known set of problems.
10920The user is strongly urged to upgrade to the latest version of firmware
10921available for the unit.
10922Problems with older versions of firmware include system lockups that
10923require powerup level resets.
10924</para>
10925<para>
10926Newer versions of the HP JetDirect Interface have a Web Browser based
10927configuration system.
10928After you have assigned an IP address to the printer you can connect to
10929the configuration port and configure the printer using the
10930browser.
10931If you run into configuration problems then you will most likely need to
10932use the Microsoft Windows based JetDirect Configuration Software to
10933reset or reconfigure the printer.
10934</para>
10935<para>Older HPJetDirect  cards can  be configured only through through the front
10936panel  or through a set of network files.  Here is a summary
10937of  the  methods  used  from  UNIX  systems, or to use when you are
10938desperate, to configure the printer.</para>
10939
10940
10941<sect2><title>Resetting To Factory Defaults</title>
10942<para>
10943Most internal HP JetDirect print servers can be reset to factory
10944defaults
10945(or cold-reset) by turning the printer off and holding down the
10946<literal/Online/ or
10947<literal/Go/
10948button while turning the printer back on. The printer control
10949panel display should read
10950<literal/Cold Reset/,
10951<literal/Restoring Factory Settings/,
10952or something similar.
10953</para>
10954</sect2>
10955<sect2><title>Setting Up IP Networking and Address</title>
10956
10957<para>You can set the network address from the front panel.
10958Reset  the printer,
10959put it in offline mode.
10960and then use the MENU, +-, SELECT keys as follows:
10961<informalexample>
10962<screen> MENU  -&gt; MIO MENU (use MENU to display MIO MENU)
10963 ITEM  -&gt; CFG NETWORK=NO*
10964 +     -&gt; CFG NETWORK=YES
10965 ENTER -&gt; CFG NETWORK=YES*
10966 ITEM  -&gt; TCP/IP=OFF* (use ITEM to display TCP/IP)
10967 +     -&gt; TCP/IP=ON
10968 ENTER -&gt; TCP/IP=ON*
10969 ITEM  -&gt; CFG TCP/IP=NO* (use ITEM to display TCP/IP)
10970 +     -&gt; CFG TCP/IP=YES
10971 ENTER -&gt; CFG TCP/IP=YES*
10972 ITEM  -&gt; BOOTP=NO*
10973     (Enable BOOTP if you want to - see below)
10974 ITEM  -&gt; IP BYTE 1=0*
10975     This is IP address MSB byte.
10976     Use +- keys to change value, and then ENTER to change
10977     Use ITEM keys to get IP BYTE=2,3,4
10978 ITEM  -&gt; SM BYTE 1=255*
10979      This is the subnet mask value
10980     Use +- keys to change value, and then ENTER to change
10981     Use ITEM keys to get IP BYTE=2,3,4
10982 ITEM  -&gt; LG BYTE 1=255*
10983     This is the Syslog server (LoGger) IP address
10984     Use +- keys to change value, and then ENTER to change
10985     Use ITEM keys to get IP BYTE=2,3,4
10986 ITEM  -&gt; GW BYTE 1=255*
10987     This is the subnet gateway (router) IP address
10988     Use +- keys to change value, and then ENTER to change
10989     Use ITEM keys to get IP BYTE=2,3,4
10990 ITEM  -&gt; TIMEOUT=90
10991      This is the connection timeout value.  It puts a limit
10992     on time between connections.  A value of 10 is reasonable.</screen>
10993</informalexample>
10994</para>
10995
10996</sect2>
10997
10998<sect2><title>BOOTP Information</title>
10999
11000<para>If  you have a bootp server, you can put this information
11001in  the  bootptab  file.   To  use this, you must enable the
11002bootp  option  on  the printer.  The T144 option specifies a
11003file to be read from the bootp server.  This file is read by
11004using  the  TFTP  protocol, and you must have a TFTPD server
11005enabled.  Here is a sample bootptab entry.
11006<informalexample>
11007<screen># Example /etc/bootptab: database for bootp server (/etc/bootpd).
11008# Blank lines and lines beginning with '#' are ignored.
11009#
11010# Legend:
11011#
11012#       first field -- hostname
11013#                       (may be full domain name)
11014#
11015#       hd -- home directory
11016#       bf -- bootfile
11017#       cs -- cookie servers
11018#       ds -- domain name servers
11019#       gw -- gateways
11020#       ha -- hardware address
11021#       ht -- hardware type
11022#       im -- impress servers
11023#       ip -- host IP address
11024#       lg -- log servers
11025#       lp -- LPR servers
11026#       ns -- IEN-116 name servers
11027#       rl -- resource location protocol servers
11028#       sm -- subnet mask
11029#       tc -- template host (points to similar host entry)
11030#       to -- time offset (seconds)
11031#       ts -- time servers
11032#
11033# Be careful about including backslashes where they're needed.
11034# Weird (bad) things can happen when a backslash is omitted
11035# where one is intended.
11036#
11037peripheral1:
11038:hn:ht=ether:vm=rfc1048:
11039:ha=08000903212F:
11040:ip=190.40.101.22:
11041:sm=255.255.255.0:
11042:gw=190.40.101.1:
11043:lg=190.40.101.3:
11044:T144="hpnp/peripheral1.cfg":</screen>
11045</informalexample>
11046</para>
11047
11048<para>If  you  are  using the T144 option, you will need to create
11049the  configuration file.  The sample configuration file from
11050the HP Direct distribution is included below.
11051<informalexample>
11052<screen>#
11053# Example HP Network Peripheral Interface configuration file
11054#
11055# Comments begin with '#' and end at the end of the line.
11056# Blank lines are ignored.  Entries cannot span lines.
11057
11058# Name is the peripheral (or node) name.  It is displayed on the
11059# peripheral's self-test page or configuration plot, and when sysName
11060# is obtained through SNMP.  This name can be provided in the BOOTP
11061# response or can be specified in the NPI configuration file to
11062# prevent the BOOTP response from overflowing the packet.  The domain
11063# portion of the name is not necessary because the peripheral does
11064# not perform Domain Name System (DNS) searches.  Name is limited to
11065# 64 characters.
11066
11067name: picasso
11068
11069# Location describes the physical location of the peripheral.  This
11070# is the value used by the interface for the MIB-II sysLocation
11071# object.  The default location is undefined.  Only printable ASCII
11072# characters are allowed.  Maximum length is 64 characters.
11073
11074location: 1st floor, south wall
11075
11076# Contact is the name of the person who administers or services the
11077# peripheral and may include how to contact this person.  It is
11078# limited to 64 characters.  This is the value used by the interface
11079# for the MIB-II sysContact object.  The default contact is undefined.
11080# Only printable ASCII characters are allowed.  Maximum length is 64
11081# characters.
11082
11083contact: Phil, ext 1234
11084
11085# The host access list contains the list of hosts or networks of
11086# hosts that are allowed to connect to the peripheral.  The format
11087# is "allow: netnum [mask]", where netnum is a network number or a
11088# host IP address.  Mask is an address mask of bits to apply to the
11089# network number and connecting host's IP address to verify access
11090# to the peripheral.  The mask usually matches the network or subnet
11091# mask, but this is not required.  If netnum is a host IP address,
11092# the mask 255.255.255.255 can be omitted.  Up to ten access list
11093# entries are permitted.
11094
11095# to allow all of network 10 to access the peripheral:
11096allow: 10.0.0.0  255.0.0.0
11097
11098# to allow a single host without specifying the mask:
11099allow: 15.1.2.3
11100
11101# Idle timeout is the time (in seconds) after which an idle
11102# print data connection is closed.  A value of zero disables
11103# the timeout mechanism.  The default timeout is 90 seconds.
11104
11105idle-timeout: 120
11106
11107# A community name is a password that allows SNMP access to MIB
11108# values on the network peripheral.
11109# Community names are not highly secure;
11110# they are not encrypted across the network.  The get community name
11111# determines which SNMP GetRequests are responded to.  By default,
11112# the network peripheral responds to all GetRequests.  The get
11113# community name is limited to 32 characters.
11114
11115#
11116# For hpnpstat and hpnpadmin, the community name can be stored in
11117# /usr/lib/hpnp/hpnpsnmp.
11118
11119get-community-name: blue
11120
11121# The set community name is similar to the get community name.  The
11122# set community name determines which SNMP SetRequests are responded
11123# to.  In addition, SetRequests are only honored if the sending host
11124# is on the host access list.  By default, the network peripheral
11125# does not respond to any SetRequests.  The set community name is
11126# limited to 32 characters.
11127#
11128# The set community name can come from /usr/lib/hpnp/hpnpsnmp if it
11129# is the same as the get community name.  We recommend that the set
11130# community name be different from the get community name though.
11131
11132set-community-name: yellow
11133
11134# SNMP traps are asynchronous notifications of some event
11135# that has occurred.
11136# SNMP traps are useful only with network management software.
11137# Traps are sent to specific hosts and include a trap community
11138# name.  Up to four hosts can be sent SNMP traps.
11139# The trap community name is limited to
11140# 32 characters.  The default name is public.
11141
11142trap-community-name: red
11143
11144# The SNMP trap destination list specifies systems to which SNMP
11145# traps are sent.  Up to four IP addresses are allowed.  If no
11146# trap destinations are listed, traps are not sent.
11147
11148trap-dest: 15.1.2.3
11149trap-dest: 15.2.3.4
11150
11151# The SNMP authentication trap parameter enables or disables the
11152# sending of SNMP authentication traps.  Authentication traps indicate
11153# that an SNMP request was received and the community name check
11154# failed.  By default, the parameter is off.
11155
11156authentication-trap: on
11157
11158# The syslog-facility parameter sets the source facility identifier
11159# that the card uses when issuing syslog messages.  Other facilities,
11160# for example, include the kernel (LOG_KERN), the mail system
11161# (LOG_MAIL), and the spooling system (LOG_LPR).  The card only allows
11162# its syslog facility to be configured to one of the local user values
11163# (LOG_LOCAL0 through LOG_LOCAL7).  The selectible option strings,
11164# local0 through local7 (configured to LOG_LOCAL0 through LOG_LOCAL7,
11165# respectively) are case insensitive.  The default syslog-facility
11166# for the card is LOG_LPR.
11167
11168syslog-facility: local2
11169
11170# This parameter allows the card to treat hosts on other subnets as
11171# if the hosts were on the card's subnet.  This parameter determines
11172# the TCP Maximum Segment Size (MSS) advertised by the card to hosts
11173# on other subnets and affects the card's initial receive-window
11174# size.  The card will use a TCP MSS of 1460 bytes for local hosts,
11175# and 536 bytes for a non-local host.  The default is off, that is,
11176# the card will use the maximum packet sizes only on the card's
11177# configured subnet.
11178#
11179# The configuration utility does not allow access to this parameter.
11180# If you want to configure it, you must manually edit the NPI
11181# configuration file and add it to the bottom of the entry for the
11182# network peripheral.
11183
11184subnets-local: on
11185
11186# This parameter affects how the card handles TCP connection requests
11187# from the host.  By default, the JetDirect MPS card will accept a
11188# TCP connection even if the peripheral is off-line.  If this parameter
11189# is set to "on", then the card will only accept a TCP connection
11190# when the peripheral is on-line.
11191
11192old-idle-mode: off</screen>
11193</informalexample>
11194</para>
11195
11196</sect2>
11197<sect2><title>Telnet Configuration</title>
11198<para>
11199You can telnet to the JetDirect interface and use the command line
11200mode.
11201There is a very simple help facility available that you can invoke
11202by entering <literal/?/ at the prompt.
11203</para>
11204<para>
11205Different versions of HP JetDirect cards have different commands.
11206You will have to experiment to find out which ones are supported.
11207</para>
11208</sect2>
11209<sect2><title>Disabling Banner Page Generation</title>
11210<para>
11211You can do this by making a telnet connection
11212to the JetDirect interface and use the command line
11213mode.
11214There is a very simple help facility available that you can invoke
11215by entering <literal/?/ at the prompt.
11216</para>
11217<para>
11218The configuration command <literal/banner: 0/ will disable banners.
11219You may need to save the configuration after you have changed it
11220and then do a power up reset of the printer to have it take effect.
11221</para>
11222</sect2>
11223</sect1>
11224
11225<sect1><title>Problems With Network Print Servers</title>
11226<para>
11227Most of the Network Print Servers are implemented using extremely
11228simply software.  The following is a list of some problems
11229and what options the &LPRng; software uses to handle them.
11230</para>
11231
11232
11233<sect2><title>Network Print Server Not Responding</title>
11234<para>
11235Only a single TCP/IP connection is accepted at a time.
11236This means that when one user is sending a job then the
11237unit will not accept other connections.
11238There is another side effect of this problem,
11239which is that some implementations will accept a network
11240connection but not read any data from the connection until
11241the previous connection is finished.
11242</para>
11243<para>
11244The deal with these problems the <literal/connect_timeout/,
11245<literal/send_job_rw_timeout/,
11246and
11247<literal/send_query_rw_timeout/
11248are used to control job transfer and lpq status gathering.
11249See
11250<link linkend="printingjob">Printing Job Files</link>
11251and
11252<link linkend="opendevice">Opening the Output Device</link>
11253for details.
11254</para>
11255</sect2>
11256
11257<sect2><title>Network Print Server Does Not Handle LPQ, LPRM</title>
11258<para>
11259Some Network Print Servers do not respond to <literal/lpq/ or
11260<literal/lprm/ queries correctly.
11261The <literal/remote_support/ option can be used to solve this
11262problem by specifying what operations the remote print server
11263can handle:
11264<informalexample>
11265<screen>:remote_support=RMQVC
11266  R = lpr, M = lprmg, Q = lpq, V = lpq -v, C = lpc
11267  :remote_support=R  # printer only handles LPR
11268</screen>
11269</informalexample>
11270</para>
11271</sect2>
11272
11273<sect2><title>Incomplete Job Transfers</title>
11274
11275<para>
11276This is the result of a defective or buggy TCP/IP stacks.
11277A common problem is the habit that some
11278Network Print Servers occaisionally discard data at the end of a print job
11279when a network connection is <emphasis/half-closed/.
11280A <emphasis/half-closed/ connection is one where one end of the sending
11281connection indicates that no further data will be sent.
11282Unfortunately,  the Network Print Server will then try to close the
11283connection in the other direction.  When this does not immediately succeed,
11284it will terminate the network connection, discarding any unprinted data.
11285</para>
11286
11287<para>
11288The <literal/half_close/ flag can be used to solve this problem.
11289See
11290<link linkend="normalterm">Normal Termination </link>
11291for more details.
11292<informalexample>
11293<screen>lp:lp=lp@remote        # shutdown(fd,WRITE) connection, wait for end
11294lp:lp=lp@remote:half_close@    # close() connection and do not wait
11295</screen>
11296</informalexample>
11297</para>
11298</sect2>
11299</sect1>
11300
11301<sect1><title>Printing to a SMB (MicroSoft) Printer</title>
11302
11303<para>Microsoft use the SMB (Simple Message Block) protocol to transfer files
11304and print jobs to hosts and printers.
11305SMB can be used over TCP/IP, NetBEUI, IPX,
11306and other lower level network protocols.</para>
11307
11308<para>Unfortunately,
11309most printers do not provide detailed status or error reports
11310when using the SMB protocol.
11311There are a very large number of printers that have deficient SMB
11312support that causes problems when used in a high traffic or
11313high throughput environment.</para>
11314
11315<para>It is highly recommended that this protocol not be used unless there
11316is no alternative.</para>
11317
11318<para>If you have a printer or a remote print spooler that supports
11319SMB You can use the
11320
11321<link linkend="smb">SAMBA</link>
11322
11323<application remap=tt>smbclient</application>
11324program to send a print job to an SMB client.
11325The following is a sample
11326Shell Script script which you can use:
11327<informalexample>
11328<screen>#!/bin/sh -x
11329# This script is an input filter for printing on a unix machine. It
11330# uses the smbclient program to print the file to the specified smb-based
11331# server and service.
11332# The 'smb' printcap entry below shows how to configure LPRng
11333# for printing
11334#
11335# smb:
11336#  :lp=|/usr/local/samba/smbprint
11337#  :sd=/var/spool/smb:
11338#  :filter= ... filter ...
11339#
11340# The /var/spool/smb/.config file should contain:
11341#   server="PC_SERVER"
11342#   service="PR_SHARENAME"
11343#   password="PASSWORD"
11344#
11345# Set PC_SERVER to the server, PR_SHARENAME to the printer,
11346# and PASSWORD to the password for this service.
11347#
11348# E.g.
11349#   server=PAULS_PC
11350#   service=CJET_371
11351#   password=""
11352#
11353#
11354config_file=.config
11355if [ -f $config_file ] ; then
11356    eval `/bin/cat $config_file`
11357fi
11358#
11359# NOTE You may wish to add the line `echo translate'
11360# if you want automatic
11361# CR/LF translation when printing.
11362(
11363#   echo translate
11364    echo "print -"
11365    /bin/cat
11366) | /usr/local/bin/smbclient "\\\\$server\\$service" \
11367   "$password" -U "$server" -N -P 1&gt;&amp;2</screen>
11368</informalexample>
11369</para>
11370
11371<para>If the above script was in <filename>/usr/local/libexec/filters/smbprint</filename>,
11372the printcap entry for this printer would be:
11373<informalexample>
11374<screen>pauls_pc:
11375  :sd=/var/spool/lpd/%P
11376  # we filter the output
11377  :lp=|/usr/local/libexec/filters/smbprint
11378  # you can add filters if you want to do specific actions
11379  :ifhp=model=hp4
11380  :filter=/usr/local/libexec/filters/ifhp</screen>
11381</informalexample>
11382</para>
11383
11384</sect1>
11385
11386<sect1><title>Printing to AppleTalk Printers</title>
11387
11388<para>The
11389<link linkend="appletalk">netatalk</link>
11390
11391package comes with the
11392<application remap=tt>pap</application>
11393program that can be used to transfer jobs using the AppleTalk
11394protocol.
11395A printcap entry for a network printer looks like the following:
11396<informalexample>
11397<screen>atalk:
11398  :lp=| -$ /usr/local/atalk/bin/pap -e -p "npbname"
11399  :sd=/var/spool/lpd/atalk
11400  :ifhp=model=ps,status@
11401  :filter=/usr/local/libexec/filters/ifhp</screen>
11402</informalexample>
11403</para>
11404
11405<para>
11406The <literal/-$/ suppress the addition of extra parameters to the
11407<application/pap/ command line.
11408The
11409<application remap=tt>pap</application>
11410program must be
11411SETUID root and executable only by root or group <literal>daemon</literal>.
11412This can be done by using the following script:
11413<informalexample>
11414<screen><prompt>h4: {309} </prompt><userinput>cd /usr/local/atalk/bin</userinput>
11415<prompt>h4: {310} </prompt><userinput>chown root pap</userinput>
11416<prompt>h4: {311} </prompt><userinput>chgrp daemon pap</userinput>
11417<prompt>h4: {312} </prompt><userinput>chmod 550 pap</userinput>
11418<prompt>h4: {313} </prompt><userinput>chmod s+u pap</userinput></screen>
11419</informalexample>
11420</para>
11421
11422</sect1>
11423
11424<sect1><title>Parallel Port Printers</title>
11425
11426<para>When installing a parallel port printer,
11427there are three elements of concern:
11428the physical hardware connection (cable and connectors),
11429the IO device and Operating System support,
11430and finally the print spooler support for the device.</para>
11431
11432<para>Originally most parallel port devices were strictly
11433<emphasis>write only</emphasis>
11434with a minimum amount of error information -
11435only hardware signals for
11436<emphasis>online</emphasis>,
11437<emphasis>out of paper</emphasis>
11438and
11439<emphasis>fault</emphasis>
11440were present.
11441Due to the lack of any other way to interface devices to the
11442Intel based PC platform,
11443desperate hardware designers in search of a cheap (free?)
11444way to interface their IO devices developed ways to manipulate the
11445signals and do <emphasis>bidirectional</emphasis>
11446communication.
11447Needless to say,
11448no two companies developed the same methods,
11449and no two companies were compatible with any other companies method.</para>
11450
11451<para>In 1994, the IEEE 1284 standard was first developed,.
11452The following information is courtesy of Warp Nine Engineering,
11453of San Diego, CA, from the
11454<ulink URL="http://www.fapo.com/1284int.htm">http://www.fapo.com/1284int.htm</ulink>
11455web page.</para>
11456
11457<para>When IBM introduced the PC, in 1981, the parallel printer port was
11458included as an alternative to the slower serial port as a means
11459for driving the latest high performance dot matrix printers. The
11460parallel port had the capability to transfer 8 bits of data at time
11461whereas the serial port transmitted one bit at a time. When the PC
11462was introduced, dot matrix printers were the main peripheral that
11463used the parallel port. As technology progressed and the need for
11464greater external connectivity increased, the parallel port became
11465the means by which you could connect higher performance peripherals.
11466These peripherals now range from printer sharing devices, portable
11467disk drives and tape backup to local area network adapters and CD
11468ROM players.</para>
11469
11470<para>The problems faced by developers and customers of these peripherals
11471fall into three categories. First, although the performance of the
11472PC has increased dramatically, there has been virtually no change
11473in the parallel port performance or architecture. The maximum data
11474transfer rate achievable with this architecture is around 150
11475kilobytes per second and is extremely software intensive. Second,
11476there is no standard for the electrical interface. This causes many
11477problems when attempting to guarantee operation across various
11478platforms. Finally, the lack of design standards forced a distance
11479limitation of only 6 feet for external cables.</para>
11480
11481<para>In 1991 there was a meeting of printer manufacturers to start
11482discussions on developing a new standard for the intelligent control
11483of printers over a network. These manufacturers, which included
11484Lexmark, IBM, Texas Instruments and others, formed the Network
11485Printing Alliance. The NPA defined a set of parameters that, when
11486implemented in the printer and host, will allow for the complete
11487control of printer applications and jobs.
11488While this work was in progress it became apparent that to fully
11489implement this standard would require a high performance bi-directional
11490connection to the PC. The usual means of connection, the ordinary
11491PC parallel port, did not have the capabilities required to meet
11492the full requirements or abilities of this standard.</para>
11493
11494<para>The NPA submitted a proposal to the IEEE for the creation of a
11495committee to develop a new standard for a high speed bi-directional
11496parallel port for the PC. It was a requirement that this new standard
11497would remain fully compatible with the original parallel port
11498software and peripherals, but would increase the data rate capability
11499to greater than 1M bytes per second, both in and out of the computer.
11500This committee became the IEEE 1284 committee.
11501The IEEE 1284 standard, "Standard Signaling Method for a Bi-directional
11502Parallel Peripheral Interface for Personal Computers", was approved
11503for final release in March of 1994.</para>
11504
11505<para>Even if your hardware has support for the
11506IEEE 1284 high speed bidirectional data transfers,
11507your Operating System drivers must support it.
11508Unfortunately,
11509there is no universal agreement on the capabilities that should
11510be provided by the low level printer port device drivers,
11511and the method for supporting them.
11512A good example of the problem of OS support and drivers
11513is given by the Linux Parallel Port group,
11514currently headed by Tim Waugh,
11515and which is documented in the
11516<ulink URL="http://people.redhat.com/twaugh/parport/">http://people.redhat.com/twaugh/parport/</ulink>
11517and
11518<ulink URL="http://people.redhat.com/twaugh/parport/html/parportguide.html">http://people.redhat.com/twaugh/parport/html/parportguide.html</ulink>
11519web pages.</para>
11520
11521<para>Given this state of affairs,
11522it should be no surprise that there is no support
11523for bidirectional parallel port printers in &LPRng;.
11524In fact,
11525it turns out that there are severe problems with many Unix implementations
11526that cause extreme headaches.
11527These include:
11528<itemizedlist>
11529
11530<listitem>
11531<para>While a parallel port may be opened Read/Write,
11532a <function>read()</function> will either block indefinitely or cause a major system
11533failure (crash).</para>
11534</listitem>
11535
11536<listitem>
11537<para>There is no buffering of data in the low level driver;
11538that is,
11539once a <function>write()</function> starts,
11540then the process will block until the data is written out.
11541If the <function>write()</function> call is interrupted by a
11542<emphasis>signal</emphasis>
11543and not immediately restarted,
11544then the status returned by the <function>write()</function>
11545may be an error indication (<literal>-1</literal>)
11546or the numbers of bytes that were actually written.
11547If an error is returned,
11548then an unknown number were written and the print job
11549must be aborted.</para>
11550</listitem>
11551
11552<listitem>
11553<para>Many Operating systems do not implement a <function>select()</function>
11554functionality for the parallel port,
11555which means that it is difficult to do a multi-threaded implementation.
11556Instead,
11557a polling method must be used.</para>
11558</listitem>
11559
11560</itemizedlist>
11561</para>
11562
11563<para>The good news is that on all known systems,
11564if the parallel port device is opened exclusively for writing,
11565and a blocking <function>write()</function> is used,
11566and the <function>write()</function> is not interrupted,
11567and there are no device errors,
11568then data is delivered correctly to the device.</para>
11569
11570<para>In most UNIX systems the printer port has the name
11571<filename>/dev/lpt</filename>,
11572<filename>/dev/prn</filename>,
11573or something similar.
11574On most systems the
11575<application remap=tt>dmesg</application>
11576utility will print a list of IO devices found
11577during system configuration.
11578Use the following commands to get the information and scan
11579for the device.
11580You should also make sure that the printer device is
11581available.
11582<informalexample>
11583<screen>dmesg &gt;/tmp/a
11584grep lp /tmp/a
11585ls /dev/lp*</screen>
11586</informalexample>
11587</para>
11588
11589<para>Gordon Haverland
11590<email>haverlan@agric.gov.ab.ca</email> supplied this little script,
11591that will assist with this:
11592<informalexample>
11593<screen>#!/bin/sh
11594#set -v -x              # uncomment for debugging
11595PATH=/bin:/usr/bin
11596printer=
11597for printer in /dev/lp* ;
11598do
11599    echo PRINTER TEST to $printer 1&gt;&amp;2
11600    for i in 1 2 3 4 5 6 7 8 9;
11601    do
11602        echo PRINTER $printer $i &gt; $printer;
11603    done
11604    echo -e \\r\\f &gt; $printer
11605done
11606exit 0;</screen>
11607</informalexample>
11608</para>
11609
11610<para>If your printer is connected to the device name you provided,
11611then you should get a page of something out.  If the output
11612suffers from the <emphasis/staircase/ effect, you will see the numbers
11613marching across the page, otherwise the numbers will all be in
11614a single column.</para>
11615
11616</sect1>
11617
11618<sect1 id="secserial"><title>Serial Printers </title>
11619
11620<para>If your printer is attached by a serial line,
11621then you may need to set the serial line characteristics before sending
11622the job to the printer.
11623Here are a set of guidelines to following when attaching a serial port printer
11624to a serial line.</para>
11625
11626<para>1. Check to make sure that the line is not enabled for login.
11627Logins are usually managed by the
11628<application remap=tt>getty</application>
11629(BSD)
11630or
11631<application remap=tt>ttymon</application>
11632(Solaris, SystemV).
11633Check your system documentation and make sure that these daemons are not
11634managing the serial line.</para>
11635
11636<para>2. Check the permissions and ownership of the serial line.
11637For the most easy testing,
11638set the permissions to 0666 (everybody can open for reading and writing).
11639After you have made sure that you can send jobs to the printer,
11640you might want to change the ownership of the serial line to the <application/lpd/ server
11641and change the permissions to 0600.</para>
11642
11643<para>3. Make sure that you can print a test file on the printer via the
11644serial port.
11645This may require setting the line characteristics and then sending
11646a file to the printer.
11647You should try to use 8 bit, no parity, with hardware flow control
11648and no special character interpretation,
11649and definitely no LF to CR/LF translation.
11650The problem is that different versions of UNIX systems have different
11651sets of stty(1) commands to do this.
11652The following simple test script can help in this.
11653<informalexample>
11654<screen>#!/bin/sh
11655# 9600, no echo, no CR
11656FLAGS= 9600 -raw -parenb cs8 crtscts
11657DEV= /dev/tty01
11658(stty $FLAGS; stty 1&gt;&amp;2; cat $1 ) &lt;$DEV &gt;$DEV</screen>
11659</informalexample>
11660</para>
11661
11662<para>This shows using stty to set the flags,
11663then to print the current settings, and then using
11664cat a file to the output.
11665If you attach a dumb terminal to the serial port,
11666you can even use this script to ensure that input from the device
11667is echoed to the output with the correct speed, parity,
11668etc.</para>
11669
11670<para>Experience has shown that serially connected printers are the least
11671reliable and lowest speed.
11672Where possible,
11673it is strongly recommended that they be attached to a <emphasis>network print box</emphasis>
11674which will provide a
11675Socket API interface and handle the low level network to serial port protocol
11676conversions.</para>
11677
11678</sect1>
11679</chapter>
11680
11681<chapter id=printcapref><title>Printcap Database </title>
11682
11683<para>As described in the
11684
11685<link linkend="overview">Print Spooling Overview</link>,
11686the heart of the &LPRng; system is information in the <filename>printcap</filename>
11687file.
11688The printcap information specifies:
11689<orderedlist>
11690
11691<listitem>
11692<para>The print queues available to users.</para>
11693</listitem>
11694
11695<listitem>
11696<para>How client programs communicate with the <application>lpc</application> print server.</para>
11697</listitem>
11698
11699<listitem>
11700<para>The configuration,
11701location,
11702and other information for each print queue on the print server.</para>
11703</listitem>
11704
11705<listitem>
11706<para>How the <application>lpd</application> server processes jobs in each print queue.</para>
11707</listitem>
11708
11709</orderedlist>
11710</para>
11711
11712<para>In order to explain a complex subject,
11713we will start with a set of simple printer configurations,
11714and explain the purpose and effect of each entry in the printcap.</para>
11715
11716<para>For details about individual printcap
11717options, see the
11718<citerefentry/<refentrytitle/printcap/<manvolnum/5//
11719man page from the &LPRng; distribution,
11720or use the
11721<link linkend="optionindex">Index To All The Configuration and Printcap Options</link>
11722 to find a specific
11723printcap option and its effects.</para>
11724
11725
11726<sect1 id="printcapparse"><title>The Printcap Parsing Rules </title>
11727<para>Options used:
11728<itemizedlist>
11729
11730<listitem>
11731<para>
11732<literal>client</literal> FLAG <emphasis> printcap entry valid only for client programs </emphasis></para>
11733</listitem>
11734
11735<listitem>
11736<para>
11737<literal>oh=</literal><emphasis> hosts where printcap entry valid</emphasis></para>
11738</listitem>
11739
11740<listitem>
11741<para>
11742<literal>server</literal><emphasis> printcap entry valid only for lpd server </emphasis></para>
11743</listitem>
11744
11745<listitem>
11746<para>
11747<literal>tc</literal><emphasis> add named printcap entry contents </emphasis></para>
11748</listitem>
11749
11750</itemizedlist>
11751</para>
11752
11753<para>In this section,
11754we will discuss the remaining tricky parts of the &LPRng; printcap
11755database:
11756combined client and server printcaps,
11757host specific printcap entries,
11758and the
11759<literal>tc</literal>
11760<emphasis>include</emphasis>
11761facility.</para>
11762
11763<para>The following is a complete description of how a printcap file is processed:
11764<orderedlist>
11765
11766<listitem>
11767<para>When processing a printcap file,
11768the &LPRng; software reads and parses each entry individually.
11769Leading whitespace is removed.
11770Lines starting with
11771<literal remap=tt>#</literal>
11772and blank lines are ignored.</para>
11773</listitem>
11774
11775<listitem>
11776<para>Lines ending with
11777<literal remap=tt>\</literal>
11778will have the
11779<literal remap=tt>\</literal>
11780discarded,
11781and all lines of a printcap entry are joined by removing the line separators (<literal>\n</literal>)
11782and replacing them with a space.</para>
11783</listitem>
11784
11785<listitem>
11786<para>The printcap entry is parsed,
11787and the printcap name, aliases, and options are determined.
11788Colons
11789<literal remap=tt>:</literal>
11790act as option separators,
11791and leading and trailing whitespaces are removed.
11792</para>
11793</listitem>
11794
11795<listitem>
11796<para>Options are sorted and except for the
11797<literal>tc=...</literal> option only the last option setting is retained.</para>
11798</listitem>
11799
11800<listitem>
11801<para>If an option value requires a colon, then the
11802<literal/\:/ or
11803<literal/\072/,
11804the same escaped character value as used in the C, Perl, tcl, and other programming
11805languages,
11806can be used.
11807</para>
11808</listitem>
11809
11810<listitem>
11811<para>Client programs will discard a printcap entry with a
11812<literal>server</literal>
11813option
11814and
11815server programs will discard a printcap entry with a
11816<literal>client</literal>
11817options.</para>
11818</listitem>
11819
11820<listitem>
11821<para>The
11822<literal>oh</literal>
11823(<emphasis remap=bf>o</emphasis>n this
11824<emphasis remap=bf>h</emphasis>ost) option specifies a list of
11825IP addresses and mask pairs or glob strings which are used to determine
11826if this printcap entry is valid for this host
11827(see discussion below).</para>
11828</listitem>
11829
11830<listitem>
11831<para>After the above processing,
11832if there is an existing termcap entry with the same name,
11833the two sets of options are combined,
11834with the last option setting retained except for the
11835<literal>tc</literal>
11836entries
11837which are combined.</para>
11838</listitem>
11839
11840<listitem>
11841<para>When a printcap entry is actually used,
11842the printcap entries listed by the
11843<literal>tc</literal>
11844include option
11845are extracted and combined in order.
11846This allows include entries to appear after the referring printcap entry.
11847Then printcap options will be combined with the included ones.
11848This has the effect that the options specified in the printcap entry
11849will override the ones from the
11850<literal>tc</literal>
11851included entries.</para>
11852</listitem>
11853
11854<listitem>
11855<para>Finally,
11856each string printcap option with a <emphasis>%X</emphasis>
11857value
11858has <emphasis>%X</emphasis>
11859replaced by the following values.
11860Unspecified values will not be modified.
11861<informaltable frame=all>
11862<tgroup cols=3 align=left rowsep=1 colsep=1>
11863<thead>
11864<row><entry>Key</entry><entry>Value</entry><entry>Purpose</entry></row>
11865</thead>
11866<tbody>
11867<row><entry><literal>%P</literal></entry><entry>printcap entry primary name</entry></row>
11868<row><entry><literal>%Q</literal></entry><entry>queue requested</entry></row>
11869<row><entry><literal>%h</literal></entry><entry>short host name  (host)</entry></row>
11870<row><entry><literal>%H</literal></entry><entry>fully qualified host name  (host.dns.whatever)</entry></row>
11871<row><entry><literal>%R</literal></entry><entry>remote printer (rp value)</entry></row>
11872<row><entry><literal>%M</literal></entry><entry>remote host (rm value)</entry></row>
11873<row><entry><literal>%D</literal></entry><entry>date in YYYY-MM-DD format</entry></row>
11874</tbody>
11875</tgroup>
11876</informaltable>
11877</para>
11878</listitem>
11879
11880<listitem>
11881<para>When parsing multiple printcap files,
11882these are processed in order,
11883and all of their printcap entries are combined according to the
11884above procedures.
11885The
11886<literal>tc</literal>
11887resolution and <emphasis>%X</emphasis>
11888expansion is done after all the files
11889have been processed.</para>
11890</listitem>
11891
11892</orderedlist>
11893</para>
11894
11895<para>The following examples show how to use the above rules
11896to your advantage.
11897You can combine both client and server printcap information in
11898a single file
11899as well as dividing a printcap entry into several parts.
11900Here is an example:
11901<informalexample>
11902<screen># seen by both client and server
11903lp1:lp=lp@pr1:mx=100
11904lp1:sd=/usr/local/spool/lp1:mx=0
11905# seen only by client
11906lp2:lp=lp@pr2:client
11907# seen only by server
11908lp2:lp=/dev/lp:server</screen>
11909</informalexample>
11910
11911<orderedlist>
11912
11913<listitem>
11914<para>Printcap entries with the same name are combined.
11915The first printcap entry,
11916<literal>lp1</literal>,
11917the information is seen by both client and server.
11918The next printcap entry,  with the same name
11919<literal>lp1</literal>,
11920will be combined with the first one.
11921The order of options is important - the entries are scanned in order
11922and an option will have the last value set.
11923Thus,
11924after having read both the
11925<literal>lp1</literal>
11926printcap entries,
11927both client and server will have:
11928<informalexample>
11929<screen>lp1:lp=lp@pr1
11930  :mx=0
11931  :sd=/usr/local/spool/lp1</screen>
11932</informalexample>
11933</para>
11934</listitem>
11935
11936<listitem>
11937<para>The
11938<literal>lp2</literal>
11939has a client and server version.
11940This is recommended when complex printcaps on multiple hosts and servers
11941are used.
11942Thus, the &LPRng; clients will see:
11943<informalexample>
11944<screen>lp1
11945  :lp=lp@pr1
11946  :mx=0
11947  :sd=/usr/local/spool/lp1
11948lp2
11949  :client
11950  :lp=lp@pr2</screen>
11951</informalexample>
11952
11953and the server will see:
11954<informalexample>
11955<screen>lp1
11956  :lp=lp@pr1
11957  :mx=0
11958  :sd=/usr/local/spool/lp1
11959lp2
11960  :lp=/dev/lp
11961  :server</screen>
11962</informalexample>
11963</para>
11964</listitem>
11965
11966</orderedlist>
11967</para>
11968
11969<para>If you have multiple printers of the same type whose configuration is almost
11970identical,
11971then you can define a set of <emphasis>tc</emphasis>
11972only printcap entries containing common
11973information
11974and use the
11975<literal>tc</literal>
11976include facility.</para>
11977
11978<para>Printcap entry names
11979may start with
11980period (<literal remap=tt>.</literal>),
11981question mark (<literal remap=tt>?</literal>),
11982or
11983exclamation mark (<literal remap=tt>!</literal>),
11984followed by one or more
11985alphanumeric , underscore (<literal>_</literal>) or hyphen (<literal>-</literal>) characters.
11986Queue or printer names start with an alphanumeric character.
11987Printcap entries whose names do not start with
11988an alphanumeric character
11989can only be used as targets of the
11990<literal>tc</literal>
11991include facility.
11992For example:
11993<informalexample>
11994<screen>.hp:
11995  :sd=/usr/local/spool/%P
11996  :mx=0
11997hp1:tc=.hp,.filter
11998  :lp=lp@10.0.0.1
11999hp2:tc=.hp,.filter
12000  :lp=lp@10.0.0.2
12001.filter
12002  :filter=/usr/local/libexec/filters/ifhp</screen>
12003</informalexample>
12004
12005<orderedlist>
12006
12007<listitem>
12008<para>The <filename>.hp</filename> and <filename>.filter</filename> printcap entities are
12009not spool queue definitions.
12010After
12011<literal>tc</literal>
12012include processing is completed,
12013the printcap information would resemble:
12014<informalexample>
12015<screen>hp1
12016  :lp=lp@10.0.0.1
12017  :filter=/usr/local/libexec/filters/ifhp
12018  :mx=0
12019  :sd=/usr/local/spool/%P
12020hp2
12021  :lp=lp@10.0.0.2
12022  :filter=/usr/local/libexec/filters/ifhp
12023  :mx=0
12024  :sd=/usr/local/spool/%P</screen>
12025</informalexample>
12026</para>
12027</listitem>
12028
12029<listitem>
12030<para>The <literal>%X</literal>
12031processing will replace
12032<literal remap=tt>%P</literal>
12033with the
12034printcap name,
12035so we would have:
12036<informalexample>
12037<screen>hp1
12038  :lp=lp@10.0.0.1
12039  :filter=/usr/local/libexec/filters/ifhp
12040  :mx=0
12041  :sd=/usr/local/spool/hp1
12042hp2
12043  :lp=lp@10.0.0.2
12044  :filter=/usr/local/libexec/filters/ifhp
12045  :mx=0
12046  :sd=/usr/local/spool/hp2</screen>
12047</informalexample>
12048</para>
12049</listitem>
12050
12051</orderedlist>
12052</para>
12053
12054</sect1>
12055
12056<sect1 id="simple"><title>Simple Client Printcap Entry
12057
12058</title>
12059
12060<para>Options used:
12061<itemizedlist>
12062
12063<listitem>
12064<para>
12065<literal>client</literal> FLAG <emphasis> client printcap entry </emphasis></para>
12066</listitem>
12067
12068<listitem>
12069<para> <literal>lp=</literal><emphasis>destination printer information</emphasis></para>
12070</listitem>
12071
12072<listitem>
12073<para> <literal>rm=</literal><emphasis>remote host (machine)</emphasis></para>
12074</listitem>
12075
12076<listitem>
12077<para> <literal>rp=</literal><emphasis>remote printer</emphasis></para>
12078</listitem>
12079
12080</itemizedlist>
12081</para>
12082
12083<para>I'll use this simple example to explain the basics of the &LPRng;
12084printcap format
12085and introduce some of the &LPRng; network configuration options.
12086Here is a simple printcap file used to provide client programs
12087(<literal>lpr, lprm,</literal>
12088etc)
12089with <emphasis>remote printer</emphasis>
12090and <emphasis>server</emphasis>
12091information.
12092<informalexample>
12093<screen># printer lp1
12094lp1|printer1
12095  :rm=localhost
12096# printer lp2 with continuation
12097lp2:\
12098  :lp=pr@10.0.0.1:client
12099# printcap lp3, to printer pr, with overrides
12100lp3:rp=pr:rm=hp.private
12101  :force_localhost@
12102# Simplest possible printcap entry - defaults for everything
12103lp4</screen>
12104</informalexample>
12105
12106<orderedlist>
12107
12108<listitem>
12109<para>Lines starting with a
12110<literal remap=tt>#</literal>
12111sign are comments, and all
12112leading and trailing <emphasis>whitespace</emphasis>,
12113i.e. - spaces, tabs, etc, are ignored.
12114Empty lines are ignored as well.</para>
12115</listitem>
12116
12117<listitem>
12118<para>A printcap entry starts with the printcap entry <emphasis remap=bf>name</emphasis>,
12119followed by one or more <emphasis>aliases</emphasis>,
12120followed by one or more options.
12121In the above example we have three printcap entries:
12122<literal>lp1</literal>
12123with an alias
12124<literal>printer1</literal>
12125and
12126<literal>lp2</literal>,
12127<literal>lp3</literal>, and
12128<literal>lp4</literal>
12129with no aliases.</para>
12130</listitem>
12131
12132<listitem>
12133<para>Aliases start with the
12134<literal remap=tt>|</literal>
12135character and options with the
12136<literal remap=tt>:</literal>
12137character;
12138tabs and spaces before and after the
12139<literal remap=tt>|</literal>
12140or
12141<literal remap=tt>:</literal>
12142characters
12143and at the start and end of lines are ignored.
12144You can use backslash (<literal remap=tt>\</literal>) at the end of a line to create a multi-line
12145value for an option.
12146The backslash will cause the next line to be appended to the
12147current line;
12148watch out for comments and ends of printcap entries if you use this facility.
12149As you can see from the example,
12150there is no
12151<literal>Name</literal>
12152printcap entry - this is part of the
12153<literal>cm</literal>
12154option on the previous line.</para>
12155</listitem>
12156
12157<listitem>
12158<para>Options take the form of a
12159keyword/value pair, i.e.-
12160<literallayout>:option=value
12161:option#value   (legacy, not advised for new systems)
12162:option
12163:option@</literallayout>
12164</para>
12165</listitem>
12166
12167<listitem>
12168<para>Option names are case insensitive, but option values are not.
12169While
12170<literal>Ts</literal>
12171and
12172<literal>ts</literal>
12173are the same option name,
12174<literal>ts=Testing</literal> and <literal>ts=testing</literal> have their case preserved.
12175A string or integer value is specified by <literal>option=value</literal>
12176or
12177<literal>option#value</literal>.</para>
12178</listitem>
12179
12180<listitem>
12181<para>The use of the legacy
12182<literal>option#value</literal>
12183form is <acronym>NOT</acronym> recommended as some preprocessors
12184and database systems will treat <emphasis remap=bf>#</emphasis>
12185as the start of a comment
12186and delete the remainder of the line.
12187This has caused great consternation for sysadmins who wonder why their
12188NIS distributed printcap entries have been mysteriously truncated.</para>
12189</listitem>
12190
12191<listitem>
12192<para>If you want to set a string option to <emphasis>empty</emphasis>
12193value,
12194use <literal>option=</literal>. The
12195<literal>option</literal>
12196will set it to
12197<literal remap=tt>1</literal>.
12198If an option value contains a colon, then use the C (or Perl or Tck/Tk)
12199string escape
12200<literal>\072</literal>
12201to represent the value.</para>
12202</listitem>
12203
12204<listitem>
12205<para>Boolean options are set TRUE (1) if no value follows the keyword and FALSE (0) by
12206appending a <literal>@</literal>.
12207For example
12208<literal>sh</literal>
12209will set
12210<literal>sh</literal>
12211to TRUE and
12212<literal>sh@</literal> to FALSE.</para>
12213</listitem>
12214
12215</orderedlist>
12216</para>
12217
12218<para>There may be multiple options on the same line, separated
12219by colons.</para>
12220
12221<para>Now let's examine the first printcap entry in detail.
12222It is reproduced here for convenience:
12223<informalexample>
12224<screen># printer lp1
12225lp1|printer1
12226  :rm=localhost</screen>
12227</informalexample>
12228
12229<orderedlist>
12230
12231<listitem>
12232<para>We start with a comment, followed by the printcap entry name and and alias.
12233Aliases are useful when you want to refer to a single printer or print queue
12234by different names.
12235This can be useful in advanced printcap and print queue setups.
12236By default,
12237the remote printer name is the printcap entry name.</para>
12238</listitem>
12239
12240<listitem>
12241<para>The
12242<literal>rm</literal>
12243(remote machine or host) option specifies the name or IP address
12244of the <application>lpd</application> host running <application>lpd</application>.
12245In this example the remote host is
12246<literal>localhost</literal>
12247or the machine that the client is running on
12248and we assume that the <application>lpd</application> server is running on the localhost.
12249Thus,
12250we would communicate with printer
12251<literal>lp1@localhost</literal>.</para>
12252</listitem>
12253
12254</orderedlist>
12255</para>
12256
12257<para>Let's look at the next printcap entry:
12258<informalexample>
12259<screen># printer lp2 with continuation
12260lp2:\
12261  :lp=pr@10.0.0.1:client</screen>
12262</informalexample>
12263
12264<orderedlist>
12265
12266<listitem>
12267<para>The
12268<literal>lp2</literal>
12269printcap entry illustrates the use (and abuse)
12270of the
12271<literal remap=tt>\</literal>
12272continuation.
12273If you think about this,
12274we have really defined a printcap entry of the form:
12275<informalexample>
12276<screen>lp2: :lp=pr@10.0.0.1:client</screen>
12277</informalexample>
12278
12279</para>
12280
12281<para>Luckily, &LPRng; ignores empty options like
12282<literal remap=tt>::</literal>.
12283While it is strongly recommended that
12284<literal remap=tt>\</literal>
12285be avoided it may be necessary for compatibility with other system utilities.</para>
12286</listitem>
12287
12288<listitem>
12289<para>The <literal>lp=pr@10.0.0.1</literal> literal is an alternate way to
12290specify a remote queue and server.
12291If the <literal>force_localhost</literal> default is being used,
12292then the &LPRng; clients will ignore the
12293<literal>10.0.0.1</literal>
12294address
12295and still connect to <literal>pr@localhost</literal>.
12296There is further discussion about this in the next section.</para>
12297</listitem>
12298
12299<listitem>
12300<para>The
12301<literal>client</literal>
12302option explicitly labels client only printcap information.
12303The <application>lpd</application> server will ignore any printcap with the
12304<literal>client</literal>
12305option.
12306When constructing complex printcaps,
12307this option is used to keep ensure that you have consistent printcap information.</para>
12308</listitem>
12309
12310</orderedlist>
12311
12312The following printcap entry shows how to override the
12313<literal>force_localhost</literal> default,
12314and force the &LPRng; clients to connect directly to a remote server:
12315<informalexample>
12316<screen>lp3:rp=pr:rm=hp.private
12317  :force_localhost@</screen>
12318</informalexample>
12319
12320<orderedlist>
12321
12322<listitem>
12323<para>The <literal>rp=</literal>  (remote printer)
12324remote print queue name to used when sending commands to the <application>lpd</application> print server.</para>
12325</listitem>
12326
12327<listitem>
12328<para>The <literal>force_localhost@</literal> literal is an example of a <emphasis>flag</emphasis>
12329option.
12330The <literal>@</literal> sets the literal value to 0 (false).
12331We set <literal>force_localhost</literal> to false,
12332which now allows the &LPRng; clients to connect directly to the
12333specified remote printer.
12334In this example,
12335the <filename>hp.private</filename> could be a HP LaserJet Printer with a
12336JetDirect interface,
12337which supports the RFC1179 protocol.</para>
12338</listitem>
12339
12340<listitem>
12341<para>One disadvantages of sending a job directly to a printer using the above
12342method is that <application>lpr</application> program will not
12343terminate or exit until all of the files have been transferred to the printer,
12344and this may take a long time
12345as the printer processes the files as they are received.</para>
12346</listitem>
12347
12348</orderedlist>
12349</para>
12350
12351<para>Now let's look at the last printcap entry:
12352<informalexample>
12353<screen># Simplest possible printcap entry - defaults for everything
12354lp4</screen>
12355</informalexample>
12356</para>
12357
12358<para>The last example is the simplest possible printcap entry.
12359This will cause &LPRng; clients to use the default values for everything.
12360The printer will be
12361<literal>lp4</literal>,
12362i.e. - the name of the printcap,
12363and the server will be
12364<literal>localhost</literal>
12365if <literal>force_localhost</literal> is set,
12366or the value of the <literal>default_remote_host</literal> configuration option
12367if it is not.</para>
12368
12369</sect1>
12370
12371<sect1 id="cm"><title>Simple Server Printcap Example
12372</title>
12373
12374<para>Options used:
12375<itemizedlist>
12376
12377<listitem>
12378<para> <literal>cm=</literal><emphasis>comment for status</emphasis></para>
12379</listitem>
12380
12381<listitem>
12382<para> <literal>filter=</literal><emphasis>job filter</emphasis></para>
12383</listitem>
12384
12385<listitem>
12386<para> <literal>lf=</literal><emphasis>log file </emphasis></para>
12387</listitem>
12388
12389<listitem>
12390<para> <literal>af=</literal><emphasis>accounting file </emphasis></para>
12391</listitem>
12392
12393<listitem>
12394<para> <literal>lp=</literal><emphasis>output device</emphasis></para>
12395</listitem>
12396
12397<listitem>
12398<para> <literal>mx=</literal><emphasis>maximum job size</emphasis></para>
12399</listitem>
12400
12401<listitem>
12402<para> <literal>sd=</literal><emphasis>spool directory file </emphasis></para>
12403</listitem>
12404
12405</itemizedlist>
12406</para>
12407
12408<para>The previous section discussed printcap entries for use by the client programs.
12409Now we will discuss printcap entries for use by the <application>lpd</application> server.
12410In simple configurations or when we have the <literal>force_localhost</literal>
12411option enabled
12412we can use the same printcap for both &LPRng; clients and the <application>lpd</application>
12413server.</para>
12414
12415<para>
12416<informalexample>
12417<screen># Local ASCII printer
12418lp1|printer
12419  :server
12420  :cm=Dumb printer
12421  :lp=/dev/lp1
12422  :sd=/var/spool/lpd/lp1
12423  :lf=log:af=acct
12424  :filter=/usr/local/libexec/filters/ifhp
12425  :mx=0</screen>
12426</informalexample>
12427</para>
12428
12429<para>
12430<orderedlist>
12431
12432<listitem>
12433<para>The printcap entry name is
12434<literal>lp1</literal>.
12435This information will be displayed when requesting status information using
12436the <application>lpq</application> program.</para>
12437</listitem>
12438
12439<listitem>
12440<para>The
12441<literal>printer</literal>
12442alias.
12443This allows a single spool queue to have multiple names.</para>
12444</listitem>
12445
12446<listitem>
12447<para>The
12448<literal>:server</literal>
12449option specifies
12450this printcap entry is only used by <application>lpd</application>
12451server.</para>
12452</listitem>
12453
12454<listitem>
12455<para>The
12456<literal>:cm</literal>
12457field supplies a information field
12458for <application>lpq</application> (printer status) output.</para>
12459</listitem>
12460
12461<listitem>
12462<para> The
12463<literal>:lp</literal>
12464value
12465specifies the destination file, device or remote spool queue to which data is sent.
12466In this example it is the device <filename>/dev/lp1</filename>.
12467By default,
12468IO devices are opened for <emphasis>write-only</emphasis>
12469operation.</para>
12470</listitem>
12471
12472<listitem>
12473<para>The
12474<literal>:sd=/path</literal>
12475specifies the <emphasis>spool directory</emphasis>
12476where print job files
12477are stored until they are printed.</para>
12478</listitem>
12479
12480<listitem>
12481<para> The
12482<literal>:lf</literal>
12483and
12484<literal>:af</literal>
12485options specify the names
12486of the log and accounting files, respectively.
12487These have the default values
12488<literal>log</literal>
12489and
12490<literal>acct</literal>
12491respectively.
12492If not an absolute path, the file is relative to the spool queue directory.
12493If these files don't exist, they will not be created,
12494and no logging or accounting will be done. You will
12495need to create them manually (e.g., by using
12496<literal>touch</literal>)
12497or by using the
12498<emphasis remap=tt>
12499<link linkend="checkpc">checkpc</link>
12500</emphasis>
12501program.
12502If you do not want a log or accounting file,
12503then use <literal/:lf=/, i.e. - no value.
12504</para>
12505</listitem>
12506
12507<listitem>
12508<para>The
12509<literal remap=tt>:filter=/path</literal>
12510option specifies a filter program to be used
12511to process job files.
12512Filters and print formats are discussed in
12513<link linkend="filters">Filters</link>.
12514</para>
12515</listitem>
12516
12517<listitem>
12518<para><literal>mx</literal>
12519indicates the maximum file size for a print job.
12520Specifying 0 means that there is no limit.</para>
12521</listitem>
12522
12523</orderedlist>
12524</para>
12525
12526</sect1>
12527
12528<sect1><title>Using :oh To Select Printcap Information</title>
12529
12530<para>When administering a large number of printers over a large area,
12531it is sometimes desirable to have a <emphasis>default</emphasis>
12532printer for
12533each host.
12534This default printer may be different for each host,
12535and can be selected by using the
12536<literal>oh</literal>
12537entry.
12538The
12539<literal>oh</literal>
12540value is a list of the following entries
12541<informalexample>
12542<screen>[!] IP/n     - address + mask length    10.0.0.0/8
12543[!] IP/IP    - address + mask           10.0.0.0/255.0.0.0
12544[!] vvv      - glob for hostname        pc*.org.com</screen>
12545</informalexample>
12546</para>
12547
12548<para>The &LPRng; software will determine the hostnames and IP addresses assigned to the
12549host and then check to see if there is a match in the listed hostnames
12550or IP addresses.
12551The optional test inversion (<literal remap=tt>!</literal>) causes the sense of the match
12552to be inverted.
12553The list of addresses or entries are tested in sequence until
12554a match is found.
12555If no match is found the printcap entry will not be used.
12556For example:
12557<informalexample>
12558<screen>lp:oh=*.admin.org.com,10.0.0.5,10.2.0.0/16:lp=pr1@server1
12559lp:oh=*.eng.org.com:lp=hp@server2
12560color:oh=*.eng.org.com:lp=color@server3
12561color:oh=!*.eng.org.com:lp=color@server4</screen>
12562</informalexample>
12563</para>
12564
12565<para>In the above example,
12566if our host name is
12567<filename>booster.admin.org.com</filename>,
12568then we would use <literal>lp=pr1@server1</literal>,
12569as the <filename>*.admin.org.com</filename> glob pattern would match our host name.</para>
12570
12571<para>if our host name is
12572<filename>booster.dev.org.com</filename> and our IP address is 10.2.0.1,
12573then we would use <literal>lp=pr1@server1</literal>,
12574as the <filename>10.2.0.0/16</filename> ip address would be in the specified address range.</para>
12575
12576<para>Finally we have an example of the use of the match inversion
12577operator (<literal/!/).
12578All hosts whose name matches <filename>*.eng.org.com</filename> will use
12579<literal>color@server3</literal> and the others will use
12580<literal>color@server4</literal>.</para>
12581
12582</sect1>
12583
12584<sect1><title>Using the Wildcard Printcap Entry</title>
12585
12586<para>The wildcard printcap name
12587<literal remap=tt>*</literal>
12588is used to select a default
12589or printcap entry when a match is not found in the printcap
12590database.
12591<informalexample>
12592<screen># %P and %Q set to printer name
12593*:lp=%P@server
12594
12595# %P set to 'printer', %Q set to printer name
12596printer|*:lp=%P@server</screen>
12597</informalexample>
12598</para>
12599
12600<para>When searching for printcap information,
12601the &LPRng; software will first search for an exact match
12602for a printcap entry against the printcap names and aliases.
12603If non is found,
12604it then searches for a wildcard entry and uses the first one
12605found with a wildcard name or alias.</para>
12606
12607<para>If the wildcard
12608<literal remap=tt>*</literal>
12609is the printcap name,
12610then the printer name
12611(<literal>%P</literal>
12612value)
12613and queue
12614(<literal>%Q</literal>
12615value)
12616are set to the name being searched for.
12617If the wildcard is an alias,
12618then then printer name is set to the printcap main entry name
12619and the queue to the name being searched for.</para>
12620
12621</sect1>
12622
12623<sect1><title>Enterprise Strength Printcap Example</title>
12624
12625<para>Most system administrators want to have a single printcap
12626file that can be distributed or referenced from
12627all the hosts under their administrative control.
12628The following show how several large institutions have
12629organized their printcap information.
12630It uses the following principles:
12631<itemizedlist>
12632
12633<listitem>
12634<para>Many times it is necessary to partition groups of users
12635into areas that have particular printing setups,
12636but use the same queue name for different printers.
12637This is done by using the
12638<literal remap=tt>:oh</literal>
12639(on this host)
12640option to select the printcap to be used.</para>
12641</listitem>
12642
12643<listitem>
12644<para>Provide as little information as possible to the
12645systems that do not have print spoolers.
12646This is because they will simply forward their requests to
12647a print spooler and it is not necessary to have the information
12648for a printer.
12649As we will see in an example below,
12650this can be very simple to do.</para>
12651</listitem>
12652
12653<listitem>
12654<para>Provide a default printer so that when the user does
12655not have a printer explicitly selected then he will
12656get well behaved results.</para>
12657</listitem>
12658
12659<listitem>
12660<para>For each family of printers,
12661develop a standard method of interfacing to them.
12662This means that the filter,
12663options,
12664and other things should be identical.</para>
12665</listitem>
12666
12667<listitem>
12668<para>For each server,
12669provide a uniform set of standards for the spool queues
12670for a printer.
12671If the spool queue is simply used to store and forward
12672jobs,
12673then provide a standard default operation for this queue.
12674If the spool queue directly feeds a printer,
12675use the default options for the printer,
12676and then refine them with printer specific information.</para>
12677</listitem>
12678
12679</itemizedlist>
12680
12681<informalexample>
12682<screen># client setups; note brutality of this method that
12683#  assigns servers to clients based on their names
12684#  you could do this for IP addresses as well
12685# lp1 is default printer for Engineering
12686#   Default client information
12687.client=force_localhost@
12688#
12689lp1:oh=*.eng.com:lp=%P@server1.eng.com:tc=.client
12690*:oh=*.eng.com:lp=%P@server1.eng.com:tc=.client
12691color:oh-*.admin.com:lp=%P@server2.admin.com:tc=.client
12692*:oh=*.admin.com:lp=%P@server2.admin.com:tc=.client
12693lowres:lp=%P@general.services.com:tc=.client
12694*:lp=%P@general.services.com:tc=.client
12695
12696# Standard Printer Configurations
12697# this is for the HP4simx, we use a standard filter setup
12698.cf_hp4simx
12699 :ifhp=model=hp4simx
12700 :filter=/usr/local/libexec/filters/ifhp
12701.cf_hplj5000
12702 :ifhp=model=hp5000
12703 :filter=/usr/local/libexec/filters/ifhp
12704# now we define the printers that use them
12705.pr_eng1:cm=Engineering's Printer 1
12706 :tc=.cf_hplj5000:lp=10.0.0.2%9100
12707.pr_eng2:cm=Engineering's Printer 2
12708 :tc=.cf_hplj5000:lp=10.0.0.23%9100
12709
12710# now we define the server entries
12711# We set up server entries and then forward
12712#  to a single server that sends the the printer
12713
12714.server
12715 :sd=/var/spool/lpd/%P
12716 :mx=0
12717pr1:oh=!10.0.0.5:lp=%P@10.0.0.5:server:tc=.server
12718pr1:oh=10.0.0.5:tc=.server
12719 :tc=.pr_eng1</screen>
12720</informalexample>
12721</para>
12722
12723</sect1>
12724
12725<sect1><title>Remote Printer Using RFC1179</title>
12726
12727<para>Options used:
12728<itemizedlist>
12729
12730<listitem>
12731<para> <literal>lp=</literal><emphasis>destination</emphasis></para>
12732</listitem>
12733
12734<listitem>
12735<para> <literal>rm=</literal><emphasis>remote host (machine)</emphasis></para>
12736</listitem>
12737
12738<listitem>
12739<para> <literal>rp=</literal><emphasis>remote printer (machine)</emphasis></para>
12740</listitem>
12741
12742</itemizedlist>
12743</para>
12744
12745<para>You can have the <application>lpd</application> server forward jobs to another server
12746or print which supports the RFC1179 protocol by using the
12747following printcap:
12748<informalexample>
12749<screen># Simplest
12750remote|Remote Printer
12751   :lp=raw@server
12752# historical
12753remote:
12754  rp=raw:rm=server
12755# Sometimes you have to connect to a non-standard port
12756special:lp=lp@server%2000</screen>
12757</informalexample>
12758
12759<orderedlist>
12760
12761<listitem>
12762<para>If the
12763<literal>lp</literal>
12764printer entry is present, it will override the
12765<literal>rm</literal>
12766and
12767<literal>rp</literal>
12768printer entries.</para>
12769</listitem>
12770
12771<listitem>
12772<para>The <literal>lp=pr@host</literal> format specifies that the output device is actually
12773a remote spool queue,
12774and jobs should be transferred using RFC1179 protocol.</para>
12775</listitem>
12776
12777<listitem>
12778<para>By default,
12779&LPRng; will attempt to
12780<emphasis remap=bf>sanitize</emphasis>
12781all jobs that it originates or forwards.
12782This sanitization will result in an RFC1179 compliant
12783<literal>control file</literal>,
12784and will not modify any of the job information.</para>
12785</listitem>
12786
12787</orderedlist>
12788</para>
12789
12790</sect1>
12791
12792<sect1><title>Remote Printer Using Socket API</title>
12793
12794<para>If the spool queue destination is a remote printer supporting the
12795Socket API,
12796then you can have &LPRng; open a connection directly to the printer.
12797These include the older Apple printers with TCP/IP support and the
12798HP JetDirect supported printers.
12799<informalexample>
12800<screen># Simplest
12801remote
12802   :lp=10.24.2.3%9100</screen>
12803</informalexample>
12804
12805<orderedlist>
12806
12807<listitem>
12808<para>The <literal>lp=server%port</literal> or <literal>lp=IPaddr%port</literal> format
12809specifies that <application>lpd</application> should open a TCP/IP connection to the remote
12810host and simply transfer verbatum the files to be printed.</para>
12811</listitem>
12812
12813<listitem>
12814<para>The
12815<literal>sh</literal>
12816and
12817<literal>sf</literal>
12818will prevent <application>lpd</application> from trying to generate
12819banner pages or put form feeds between jobs.</para>
12820</listitem>
12821
12822</orderedlist>
12823</para>
12824
12825<para>While this is the simplest printcap,
12826it is also the most dangerous as there is nothing to prevent
12827a malformed job from being sent to the printer.
12828The next printcap example is much more robust:
12829<informalexample>
12830<screen># Simplest
12831remote
12832   :lp=10.24.2.3%9100
12833   :of=/usr/local/libexec/filters/ifhp
12834   :filter=/usr/local/libexec/filters/ifhp</screen>
12835</informalexample>
12836
12837<orderedlist>
12838
12839<listitem>
12840<para>This version will use the
12841<application remap=tt>ifhp</application>
12842filter to precondition the printer
12843and to process jobs.
12844See
12845<link linkend="ifhp"><application>ifhp</application> Filter</link>
12846 for details.
12847The
12848<application remap=tt>ifhp</application>
12849filter will perform the appropriate printer resets,
12850translate job information,
12851and ensure correct printer operation in the presence of errors.
12852It will also produce voluminous error messages and status information.</para>
12853</listitem>
12854
12855</orderedlist>
12856</para>
12857
12858</sect1>
12859
12860<sect1><title>Parallel Printer</title>
12861
12862<para>The parallel printer printcap is very simple.
12863<informalexample>
12864<screen># parallel printer
12865lp:
12866   :lp=/dev/lpr</screen>
12867</informalexample>
12868
12869<orderedlist>
12870
12871<listitem>
12872<para>The <literal>lp=/dev/lpr</literal>
12873specifies that <application>lpd</application> should open the device for APPEND and simply transfer
12874job files to it.</para>
12875</listitem>
12876
12877<listitem>
12878<para>The
12879<literal>sh</literal>
12880and
12881<literal>sf</literal>
12882will prevent <application>lpd</application> from trying to generate
12883banner pages or put form feeds between jobs.</para>
12884</listitem>
12885
12886</orderedlist>
12887</para>
12888
12889<para>If you discover that UNIX print jobs result in a <emphasis>staircase</emphasis>
12890appearance,
12891then you need to force your printer to do <acronym>LF</acronym> (linefeed) to <filename>CR/LF</filename>
12892(carriage return/line feed) translation,
12893or do the translation yourself.
12894<informalexample>
12895<screen># Simple parallel printer
12896lp:
12897   :lp=/dev/lpr
12898   :filter=/usr/local/bin/lpf</screen>
12899</informalexample>
12900</para>
12901
12902<para>By using the <literal>if=...lpf</literal> filter,
12903the job will be passed through the
12904<application>lpf</application>
12905filter,
12906which will do the <acronym>LF</acronym> to <filename>CR/LF</filename> translation.</para>
12907
12908<para>If you have a more complex printer that handles PostScript, PCL, and PJL,
12909then you will need to use the more powerful
12910<application remap=tt>ifhp</application>
12911filter:
12912<informalexample>
12913<screen># Simple parallel printer
12914lp:
12915   :lp=/dev/lpr
12916   :ifhp=model=hp4,status@
12917   :of=/usr/local/libexec/filters/ifhp
12918   :filter=/usr/local/libexec/filters/ifhp</screen>
12919</informalexample>
12920</para>
12921
12922<para>See
12923<link linkend="ifhp"><application>ifhp</application> Filter</link>
12924 for details.
12925This entry will specify that the printer is an HP4,
12926and that no status information is available.
12927This is usually the case with a parallel port.</para>
12928
12929</sect1>
12930
12931<sect1 id="serial"><title>Serial Printer
12932</title>
12933
12934<para>Options used:
12935<itemizedlist>
12936
12937<listitem>
12938<para>
12939<literal>br=</literal><emphasis>serial port bit rate</emphasis></para>
12940</listitem>
12941
12942<listitem>
12943<para>
12944<literal>rw</literal> FLAG <emphasis>device opened RW</emphasis></para>
12945</listitem>
12946
12947
12948<listitem>
12949<para> <literal>stty=</literal><emphasis>stty options for serial port configuration</emphasis></para>
12950</listitem>
12951
12952</itemizedlist>
12953</para>
12954
12955<para>The following is a typical printcap for a serial printer:
12956<informalexample>
12957<screen># Local Serial ASCII printer
12958lp2
12959  :lp=/dev/ttya
12960  :rw
12961  :cm=Serial printer
12962  :sd=/var/spool/lpd/lp2
12963  :stty=9600 -echo -crmod -raw -oddp -evenp pass8 cbreak ixon
12964  :filter=/usr/local/sbin/lpf
12965  :mx=0</screen>
12966</informalexample>
12967</para>
12968
12969<para>Let's examine the new options:
12970<orderedlist>
12971
12972<listitem>
12973<para>A serial port is usually <emphasis>bidirectional</emphasis>,
12974and printers will report errors back to the host computer.
12975The
12976<literal>rw</literal>
12977flag will cause the printer port to be opened
12978<literal>read-write</literal>,
12979and the <application>lpd</application> server will report status information.</para>
12980</listitem>
12981
12982<listitem>
12983<para>The
12984<literal>stty</literal>
12985option specifies the <command>stty(1)</command>
12986flags and line speed needed to configure the serial line
12987(See
12988
12989<link linkend="secserial">Serial Printers</link>
12990
12991for details).</para>
12992</listitem>
12993
12994<listitem>
12995<para>The legacy
12996<literal>br</literal>
12997(bit rate) option
12998can be used to specify the line speed as well.</para>
12999</listitem>
13000
13001</orderedlist>
13002</para>
13003
13004</sect1>
13005
13006<sect1 id="lpdbounce"><title>Bounce Queue
13007
13008</title>
13009
13010<para>Options used:
13011<itemizedlist>
13012
13013<listitem>
13014<para> <literal>lpd_bounce</literal> FLAG <emphasis>produces a single file for forwarding</emphasis></para>
13015</listitem>
13016
13017<listitem>
13018<para> <literal>bq_format=</literal><emphasis>format of filtered files</emphasis></para>
13019</listitem>
13020
13021</itemizedlist>
13022</para>
13023
13024<para>When the destination of a spool queue is another spool queue
13025the job is simply forwarded without any modifications.
13026However,
13027sometimes it is essential that the job be modified before
13028forwarding,
13029as when the remote spool queue is actually a printer,
13030and
13031jobs need to be converted to the format acceptable by
13032the remote printer or banner pages added.</para>
13033
13034<para>The <literal>lpd_bounce</literal> flag marks a spool queue as a bounce queue.
13035<literal>Lpd</literal>
13036will perform all of the usually job processing steps,
13037such as banner generation,
13038filtering files,
13039etc,
13040but
13041saves the output to a file.
13042This file is then sent to the destination print queue for further
13043processing.</para>
13044
13045<para>
13046<informalexample>
13047<screen># Simple example of a bounce queue
13048bounce:lp=bounce@bouncehost
13049bounce:server
13050    :lp=lp@remote
13051    :lpd_bounce
13052    :sd=/var/spool/lpd/%P
13053    :filter=/usr/local/bin/lpf
13054    # uncomment ab if you want banner
13055    #:ab</screen>
13056</informalexample>
13057</para>
13058
13059<para>Some comments:</para>
13060
13061<para>
13062<orderedlist>
13063
13064<listitem>
13065<para>The
13066<literal>lpd_bounce</literal>
13067option marks the job as a bounce queue,
13068and the <application>lpd</application> server will process the job through the appropriate
13069filter programs.</para>
13070</listitem>
13071
13072<listitem>
13073<para>The printcap has filter specifications for different job formats.
13074These are the programs that will be used by &LPRng; to process the job.</para>
13075</listitem>
13076
13077<listitem>
13078<para>The
13079<literal>bq_format</literal>
13080specifies the job format for the output file sent to the remote spool queue.
13081If not specified, it defaults to
13082<literal remap=tt>l</literal>
13083(literal or binary).</para>
13084</listitem>
13085
13086<listitem>
13087<para>The
13088<literal>ab</literal>
13089(always print a banner) flag will force a banner to be
13090added to the job.
13091The banner generation is done as discussed in
13092
13093<link linkend="bannerprinting">Banner Printing</link>.</para>
13094</listitem>
13095
13096</orderedlist>
13097</para>
13098
13099</sect1>
13100
13101<sect1 id="translateformat"><title>Job Format Translation </title>
13102
13103<para>Options used:
13104<itemizedlist>
13105
13106<listitem>
13107<para> <literal>translate_format=</literal><emphasis>change outgoing job file formats</emphasis></para>
13108</listitem>
13109
13110<listitem>
13111<para> <literal>translate_incoming_format=</literal><emphasis>change incoming job file formats</emphasis></para>
13112</listitem>
13113
13114</itemizedlist>
13115</para>
13116
13117<para>A rarely encountered problem is when a job is printed with
13118one format but for compatibility needs to be processed with another.
13119The simple
13120<literal>translate_format=vlxf</literal>
13121option will rename format
13122<literal remap=tt>x</literal>
13123files to
13124<literal remap=tt>f</literal>
13125format.</para>
13126
13127<para>This can be used to resolve problems with PC based software,
13128which spools jobs using the
13129<literal remap=tt>v</literal>
13130format.
13131Unfortunately,
13132many RCF1179 print spoolers do not understand the
13133<literal remap=tt>v</literal>
13134format and mishandle the job.
13135A simple forwarding queue with the following entries will rename
13136<literal remap=tt>v</literal>
13137format to
13138<literal remap=tt>l</literal>
13139(binary) format.
13140<informalexample>
13141<screen>lp
13142  :sd=/var/spool/lpd/%P
13143  :translate_format=vl
13144  :lp=lp@printerserver</screen>
13145</informalexample>
13146</para>
13147
13148<para>The <literal>translate_incoming_format</literal> will do the same thing,
13149but this time on incoming jobs.</para>
13150
13151</sect1>
13152
13153<sect1 id="destinations"><title>Dynamic Routing
13154
13155</title>
13156
13157<para>Options used:
13158<itemizedlist>
13159
13160<listitem>
13161<para> <literal>destinations=</literal><emphasis>destinations for jobs</emphasis></para>
13162</listitem>
13163
13164<listitem>
13165<para> <literal>router=</literal><emphasis>router program</emphasis></para>
13166</listitem>
13167
13168</itemizedlist>
13169</para>
13170
13171<para>&LPRng; has the ability to route a job to one or
13172more destinations in a dynamic manner.
13173This is not the same as
13174<emphasis>load balancing</emphasis>,
13175as the destinations are hard coded and not able to be changed.
13176This is accomplished by having
13177a
13178<literal>router</literal>
13179filter generate a set of destinations.
13180Here is a sample printcap entry:
13181<informalexample>
13182<screen>t2|Test Printer 2
13183    :sd=/var/spool/LPD/t2
13184    :lf=log
13185    :destinations=t1@server1,t1@server2,t1@localhost
13186    :router=/usr/local/LPD/router</screen>
13187</informalexample>
13188</para>
13189
13190<para>When a job arrives at the <application>lpd</application> server,
13191the 'router' filter
13192is invoked with the standard filter options which include
13193the user, host, and other information obtained from the control file.
13194<acronym/STDIN/ is connected to a temporary copy of the control file,
13195and the CONTROL environment variable is set to the value of the
13196actual control file itself.</para>
13197
13198<para>The routing filter exit status is used as follows:
13199<itemizedlist>
13200
13201<listitem>
13202<para>0  (JSUCC) - normal processing</para>
13203</listitem>
13204
13205<listitem>
13206<para>37 (JHOLD) - job is held</para>
13207</listitem>
13208
13209<listitem>
13210<para>any other value - job is deleted from queue</para>
13211</listitem>
13212
13213</itemizedlist>
13214</para>
13215
13216<para>The router filter writes to <acronym/STDOUT/ a file specifying the destinations
13217for the job.
13218The destinations entries in this file file have the following format.
13219Entry order is not important,
13220but each destination must end with the 'end' tag.
13221<informalexample>
13222<screen>dest (destination queue)
13223copies (number of copies to be made)
13224priority (priority letter)
13225X(controlfile modifications)
13226end</screen>
13227</informalexample>
13228</para>
13229
13230<para>Example of router output:
13231<informalexample>
13232<screen>dest t1@localhost
13233copies 2
13234CA
13235priority B
13236end
13237dest t2@localhost
13238CZ
13239priority Z
13240end</screen>
13241</informalexample>
13242</para>
13243
13244<para>In this example,
13245two copies of the job will be sent to the t1 and t2 spool queue servers.
13246The Class (C letter value) and job priority information will be rewritten
13247with the indicated values.</para>
13248
13249<para>If routing information
13250is specified by the router filter the job will be sent to the default
13251destination.</para>
13252
13253<para><application>lpq</application> will display job information in a slightly different format
13254for multiple destination jobs.  For example:
13255<literallayout>Printer: t2@h4 'Test Printer 2' (routed/bounce queue to 't1@h2.private')
13256  Queue: 1 printable jobs in queue
13257 Rank  Owner/ID        Class Job Files                         Size Time
13258active  papowell@h4+707 A 707  /tmp/hi                         3 10:04:49
13259 - actv papowell@h4+707.1 A 707 -&gt;t1@localhost &lt;cpy 1/2&gt;       3 10:04:49
13260 -      papowell@lprng2+707.2 A 707 -&gt;t2@localhost                 3 10:04:49</literallayout>
13261</para>
13262
13263<para>The routing information is displayed below the main job information.
13264Each destination will have its transfer status displayed as it is
13265transferred.  By convention,  the job identifier of the routed jobs
13266will have a suffix of the form .N added;  copies will have CN added
13267as well.  For example, papowell@lprng2+707.1C2 will be the job
13268sent to the first destination, copy two.</para>
13269
13270<para>Routed jobs can be held, removed, etc., just as normal jobs.  In addition,
13271the individual destination jobs can be manipulated as well.  The LPC
13272functionality has been extended to recognize destination jobids as well
13273as the main job id for control and/or selection operations.</para>
13274
13275<para>The optional
13276<literal>destinations</literal>
13277entry specifies the possible set of
13278destinations that the job can be sent to,
13279and is for informational purposes only.
13280In order for
13281<application/lpq/
13282and
13283<application/lprm/
13284to find the job once it has been sent to <application/lpd/,
13285<application/lpq/
13286and
13287<application/lprm/
13288uses the list of printers in the
13289<literal>destinations</literal>,
13290and iterates over list looking for the job that you are interested in.</para>
13291
13292</sect1>
13293
13294<sect1 id="loadbalance"><title>Printer Load Balancing
13295</title>
13296
13297<para>Options used:
13298<itemizedlist>
13299
13300<listitem>
13301<para> <literal>ss=</literal><emphasis>queue served by printer </emphasis></para>
13302</listitem>
13303
13304<listitem>
13305<para> <literal>sv=</literal><emphasis>printers where jobs are sent (servers)</emphasis></para>
13306</listitem>
13307
13308</itemizedlist>
13309</para>
13310
13311<para>In a large site, you could have several equivalent printers, which
13312will be used by many people. The reason for this is, of course, to
13313increase the printer output by enabling several jobs to be printed at
13314once.
13315A load balance print queue is one that feeds jobs to other queues
13316and has a
13317<literal>sv=q1,q2,...</literal> printcap entry
13318that specifies the destination or server queues.
13319These must be print queue entries and have spool directories
13320on the server.</para>
13321
13322<para>The service queues have a
13323<literal>ss=</literal><emphasis>mainqueue</emphasis>
13324printcap entry
13325This informs the <application>lpd</application> server that the queue operates under the
13326control of the <emphasis>mainqueue</emphasis>
13327print queue,
13328and is fed jobs from it.</para>
13329
13330<para>During normal operation,
13331when the <application>lpd</application> server has a job to print in the <emphasis>mainqueue</emphasis>,
13332it will check to see if there is an idle <emphasis>service</emphasis>
13333 queue.
13334If there is,
13335it will transfer the job to the service queue spooling directory
13336and start the service queue printing activities.</para>
13337
13338<para>Even though the queues are not meant for
13339direct use,
13340people can print directly to individual queues.
13341This allows a specific load sharing printer to be used.
13342If you wanted to
13343<emphasis>hide</emphasis>
13344the load sharing printers,
13345i.e. - not allow direct spooling to them,
13346then you would simply remove the non-server entries from the printcap.</para>
13347
13348</sect1>
13349
13350<sect1 id="printcappath"><title>Locations of Printcap Files
13351
13352</title>
13353
13354<para>Options used:
13355<itemizedlist>
13356
13357<listitem>
13358<para> <literal>printcap_path=</literal><emphasis>printcap file locations</emphasis></para>
13359</listitem>
13360
13361<listitem>
13362<para> <literal>lpd_printcap_path=</literal><emphasis>lpd server printcap information</emphasis></para>
13363</listitem>
13364
13365</itemizedlist>
13366</para>
13367
13368<para>The
13369<literal>printcap_path </literal>
13370and
13371<literal> lpd_printcap_path </literal>
13372configuration options (see
13373<link linkend="configfile">lpd.conf(5)</link>
13374) specify a set of paths for the
13375printcap information.
13376If the
13377<literal>lpd_printcap_path</literal> is nonblank then
13378the 
13379<application>lpd</application>
13380server uses it,
13381otherwise it uses the
13382<literal>printcap_path</literal> information.
13383Client programs use only <literal>printcap_path</literal>.
13384The path names can be separated with whitespace,
13385commas, semicolons, or colons.
13386The default values are:
13387<informalexample>
13388<screen>printcap_path      ${sysconfdir}/printcap
13389lpd_printcap_path  (blank or empty)</screen>
13390</informalexample>
13391</para>
13392
13393
13394<sect2><title>Separate Server and Client Printcap Files</title>
13395
13396<para>Since only the <application/lpd/ server uses the
13397printcap file specified by the
13398<literal>lpd_printcap_path</literal>,
13399you can place server specific information there.
13400If this file is used it must also contain any required information
13401in the <literal/printcap_path/ file.</para>
13402
13403</sect2>
13404
13405<sect2 id="allpc"><title><literal/all/ Printcap Entry </title>
13406
13407<para>The
13408<literal>all</literal>
13409printcap name and
13410<literal>all</literal>
13411option
13412is reserved to provide a list of printers
13413available for use by the spooling software.
13414This is a desperation,
13415last ditch,
13416back to the wall option for
13417administrators
13418with systems that do not have ways to provide a list of printcap entries.
13419The 'all' printcap entry has the form:
13420<informalexample>
13421<screen>all:all=pr1,pr2,...</screen>
13422</informalexample>
13423</para>
13424
13425<para>The value of the
13426<literal>all</literal>
13427option should be a list of printcap names
13428whose values will then be extracted.</para>
13429
13430</sect2>
13431</sect1>
13432
13433<sect1 id="secoh"><title>Single Printcap File for Large Installation </title>
13434
13435<para>One of the major problems faced by administrators of large sites is how
13436to distribute printcap information.
13437They would like to have a single printcap file either distributed by
13438a file server (NFS) or by some other method such as
13439<literal>rdist</literal>.
13440By using the
13441<literal>server</literal>
13442and
13443<literal>oh</literal>
13444tags,
13445information for the specific sites can be separated out.
13446For example:
13447<informalexample>
13448<screen># printcap
13449pr1:lp=pr1@serverhost1:oh=*.eng.site.com,130.191.12.0/24
13450pr2:lp=pr1@serverhost1:oh=*.eng.site.com,130.191.12.0/24
13451pr1:lp=pr2@serverhost2:oh=*.admin.site.com
13452pr2:lp=pr2@serverhost2:oh=*.admin.site.com
13453pr1:server:oh=serverhost1.eng.com:lp=/dev/lp:tc=.common
13454pr2:server:oh=serverhost2.admin.com:lp=/dev/lp:tc=.common
13455.common:sd=/usr/local/lpd/%P</screen>
13456</informalexample>
13457</para>
13458
13459<para>The above example has some interesting effects.
13460The
13461<literal>pattern</literal>
13462is used as a <emphasis>glob</emphasis>
13463pattern
13464and is applied to the fully qualified domain name (FQDN) of the
13465host reading the printcap file.
13466For example,
13467<filename>*.eng.site.com</filename> would match host
13468<filename>h1.eng.site.com</filename>
13469but would not match
13470<filename>h1.admin.site.com</filename>.
13471Thus, the effects of the first couple of entries would be to
13472specify that the
13473<literal>pr1</literal>
13474and
13475<literal>pr2</literal>
13476printers on the
13477<literal>eng</literal>
13478hosts would be <literal>pr1@serverhost1</literal>,
13479and on the
13480<literal>admin</literal>
13481hosts would be <literal>pr2@serverhost2</literal>,</para>
13482
13483<para>Also,
13484the lpd daemons on
13485<literal>serverhost1</literal>
13486and
13487<literal>serverhost2</literal>
13488would extract the additional
13489information for
13490<literal>pr1</literal>
13491and
13492<literal>pr2</literal>
13493respectively,
13494overriding the common
13495<literal>lp</literal>
13496entries.</para>
13497
13498</sect1>
13499
13500<sect1><title>Management Strategies for Large Installations</title>
13501
13502<para>One very effective way to organize print spooling is to have a small
13503number of print servers running a
13504<application>lpd</application> daemon,
13505and to have all the other systems send their jobs directly to them.
13506By using the above methods of specifying the printer and server host
13507you eliminate the need for more complex management strategies.</para>
13508
13509<para>However,
13510you still need to inform users of the names and existence of these printers,
13511and how to contact them.
13512One method is to use a common
13513<filename>printcap</filename>
13514file which is periodically updated and transfered to all sites.
13515Another method is to distribute the information using the
13516NIS or some other database.
13517&LPRng; has provided a very flexible method of obtaining and distributing
13518database information:  see
13519
13520<link linkend="secnis">Using Programs To Get Printcap Information</link>
13521
13522for details.</para>
13523
13524</sect1>
13525
13526<sect1 id="secnis"><title>Using Programs To Get Printcap Information </title>
13527
13528<para>In the
13529<filename>lpd.conf</filename>
13530file you can specify:
13531<informalexample>
13532<screen>printcap_path=|program</screen>
13533</informalexample>
13534
13535This will cause the &LPRng; software to execute the specified program,
13536which should then provide the printcap information.
13537The program is invoked with the standard filter options,
13538and has the name of the printcap entry provided on
13539<acronym/STDIN/.
13540The filter
13541should supply the printcap information on
13542<literal>stdout</literal>
13543and exit with a 0
13544(success) error code.  By convention,  the printcap name 'all'
13545requests a printcap entry that lists all printers.</para>
13546
13547<para>This technique has been used to interface to the Sun Microsystem NIS
13548and NIS+ databases with great success.
13549By having the invoked program a simple shell script or front end to the
13550<literal>nismatch</literal>
13551or
13552<literal>ypmatch</literal>
13553programs,
13554the complexity of incorporating vendor specific code is avoided.</para>
13555
13556
13557<sect2><title>How to use NIS and &LPRng;</title>
13558
13559<para>This note is based on material sent to the
13560<link linkend="maillist">lprng@lprng.com</link>
13561mailing list by
13562Paul Haldane
13563<email>paul@ucs.ed.ac.uk</email>.</para>
13564
13565<para>We generally don't use NIS for printcap files (we've
13566moved to hesiod) but I can show you what we've done in the past.</para>
13567
13568<para>The input to NIS is a normal printcap file:
13569<informalexample>
13570<screen># Classical printcap entry
13571lp23a|lp23|lp|main printhost printer - KB, EUCS front Door:\
13572        :lp=lp23a@printhost:\
13573        :sd=/var/spool/lpr/lp23a:
13574
13575#lprng printcap entry
13576lplabel|lpl|TEST - Labels printer:
13577        :lp=:rm=printhost:rp=lplabel:
13578        :sd=/var/spool/lpr/lplabel:
13579        :rg=lpadm:mx=1:</screen>
13580</informalexample>
13581</para>
13582
13583<para>To build the NIS printcap.byname map we add the following to
13584the NIS makefile (along the other bits and pieces that the makefile
13585needs to know about a new map).
13586<informalexample>
13587<screen>PRINTCAP=${sysconfdir}/printcap
13588# warning : [  ] is actually [&lt;space&gt;&lt;tab&gt;] in the script
13589printcap.time: $(PRINTCAP) Makefile
13590  if [ -f $(PRINTCAP) ]; then \
13591    sed &lt; $(PRINTCAP) \
13592      -e 's/[   ][  ]*$$//' -e '/\\$$/s/\\$$/ /' \
13593    | awk '$$1 ~ /^#/{next;} $$1 ~ /^[:|]/ {printf "%s", $$0; next;} \
13594        {printf "\n%s", $$0 }' \
13595    | sed -e 's/[   ]*:[  ]*:/:/g' -e 's/[  ]*|[  ]*/|/g' \
13596      -e '/^[   ]*$$/d' &gt; .printcap.$$$$; \
13597    cat .printcap.$$$$; \
13598    if [ $$? = 0 -a -s .printcap.$$$$ ]; then \
13599      awk &lt;.printcap.$$$$ '{ FS=":"; OFS="\t"; } { \
13600          n = split($$1, names, "|"); \
13601          for (i=1; i&lt;=n; i++) \
13602              if (length(names[i]) &gt; 0 \
13603              &amp;&amp; names[i] !~ /[ \t]/) \
13604                  print names[i], $$0; \
13605      }' | $(MAKEDBM) - $(YPDBDIR)/$(DOM)/printcap.byname; \
13606      awk &lt;.printcap.$$$$ '{ FS=":"; OFS="\t"; } { \
13607          n = split($$1, names, "|"); \
13608          if (n &amp;&amp; length(names[1]) &gt; 0 &amp;&amp; names[1] !~ /[ \t]/) \
13609              print names[1], $$0; \
13610      }' | $(MAKEDBM) - $(YPDBDIR)/$(DOM)/printcap.bykey; \
13611      rm -f .printcap.$$$$; \
13612      touch printcap.time; echo "updated printcap"; \
13613    fi \
13614  fi
13615  @if [ ! $(NOPUSH) -a -f $(PRINTCAP) ]; then \
13616      $(YPPUSH) printcap.byname; \
13617      $(YPPUSH) printcap.bykey; \
13618      touch printcap.time; echo "pushed printcap"; \
13619  fi</screen>
13620</informalexample>
13621</para>
13622
13623<para>To specify that you want YP database rather than file access,
13624use the following entry in your <filename>/etc/lpd.conf</filename> file:
13625<informalexample>
13626<screen>printcap_path |/usr/local/libexec/pcfilter</screen>
13627</informalexample>
13628</para>
13629
13630<para>Put the following shell script in /usr/local/libexec/pcfilter
13631<informalexample>
13632<screen>#!/bin/sh
13633#/usr/local/libexec/filters/pcfilter
13634read key
13635# specify the full pathname to the ypmatch program
13636# the location depends on the version of Solaris or your
13637# system install
13638/full/pathname/to/ypmatch "$key" printcap.byname</screen>
13639</informalexample>
13640</para>
13641
13642<para>
13643You can test this by using:
13644<informalexample>
13645<screen><prompt>h4: {314} # </prompt><userinput>lpc client pr</userinput>
13646pr
13647 :lp=pr@server
13648<prompt>h4: {315} # </prompt><userinput>lpc server pr</userinput>
13649pr
13650 :lp=pr@server</screen>
13651</informalexample>
13652</para>
13653
13654</sect2>
13655
13656<sect2><title>How to use NIS and &LPRng; - Sven Rudolph</title>
13657
13658<para>
13659<informalexample>
13660<screen> Date: Wed, 11 Sep 1996 00:11:02 +0200
13661From: Sven Rudolph &lt;sr1@os.inf.tu-dresden.de&gt;
13662To: lprng@lprng.com
13663Subject: Using :oh=server: with NIS</screen>
13664</informalexample>
13665</para>
13666
13667<para>When I use a cluster-wide printcap,
13668I want the entries for each printer to appear, e.g.:
13669<informalexample>
13670<screen>---------- start of printcap snippet
13671lp1
13672 :lp=lp1@server
13673lp2
13674 :lp=lp2@server
13675lp1
13676 :server:oh=servername
13677 :sd=/var/spool/lpd/lp1
13678 :lp=/dev/lp1
13679 :mx=0
13680---------- end of printcap snippet</screen>
13681</informalexample>
13682</para>
13683
13684<para>When I create a NIS map out of this
13685the printer name is used as a key
13686and must be unique. The NIS makedbm will drop all but the last
13687entry for each printer.
13688This makes the printer on the clients unavailable.
13689I solved this by a hack where the second entry is called lp1.server
13690and the NIS client script has to request the right entry.
13691<orderedlist>
13692
13693<listitem>
13694<para>Assumptions
13695</para>
13696
13697<para>Perl is available at the YP server in <command>/usr/bin/perl</command>.
13698A Bourne Shell is available at all clients in <command>/bin/sh</command>
13699The printcap that is to be exported is in <filename>/etc/printcap</filename>.
13700The printcap is written in the new format. 
13701In the examples the printer is called lp1.</para>
13702</listitem>
13703
13704<listitem>
13705<para>Add the following to your YP <filename>Makefile</filename>
13706(<filename>/var/yp/Makefile</filename>) on the YP server
13707(these lines are for Debian GNU/Linux, other systems might require
13708other modifications):
13709<informalexample>
13710<screen>---------- start of /var/yp/Makefile snippet
13711PRINTCAP  = /etc/printcap
13712printcap: $(PRINTCAP)
13713    @echo "Updating $@..."
13714    $(CAT) $(PRINTCAP) | \
13715        /usr/lib/yp/normalize_printcap | $(DBLOAD) -i $(PRINTCAP) \
13716        -o $(YPMAPDIR)/$@ - $@
13717    @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
13718    @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
13719---------- end of /var/yp/Makefile snippet</screen>
13720</informalexample>
13721</para>
13722</listitem>
13723
13724<listitem>
13725<para>Install the programs <application>match_printcap</application>
13726and <application>normalize_printcap</application> in the
13727<filename>/usr/lib/yp</filename> directory;
13728<application>normalize_printcap</application>
13729is only required on the YP server.
13730The <application>normalize_printcap</application> processes only the &LPRng; printcap format.
13731<informalexample>
13732<screen>---------- start of /usr/lib/yp/normalize_printcap
13733#! /usr/bin/perl
13734$debug = 0;
13735$line = "";
13736$new = "";
13737while (&lt;&gt;) {
13738    chomp;
13739    next if ( /^\s*\#.*/ );
13740    s/^\s*$//;
13741    next if ( $_ eq '' );
13742    print "new: " . $_ . "\n" if $debug;;
13743    if (/^\s/) { # continuation line
13744        $line = $line.$_;
13745        print "continued: $line\n" if $debug;
13746        next;
13747    } else {
13748        $line =~ s/\s+\:/:/g;
13749        $line =~ s/\:\s+/:/g;
13750        $line =~ s/\:\s*\:/:/g;
13751        print "line: $line\n" if $debug;
13752        push(@lines, $line) if $line;
13753        $line = $_;
13754    }
13755}
13756$line =~ s/\s+\:/:/g;
13757$line =~ s/\:\s+/:/g;
13758$line =~ s/\:\s*\:/:/g;
13759push(@lines,$line) if $line;
13760@lines = sort(@lines);
13761foreach $line (@lines) {
13762    ($printers) = split(/\:/,$line);
13763    @printers = split(/\|/,$printers);
13764    foreach $printer (@printers) {
13765      $num{$printer}++;
13766      push(@allprinters,$printer);
13767      print "allprinters: @allprinters\n" if $debug;
13768      print $printer."_".$num{$printer}."\t$line\n";
13769    }
13770}
13771@pr = keys %num;
13772print "printers @pr\n" if $debug;
13773if ($#allprinters &gt;=0) {
13774    print "all_1\tall:all=".join(",",@pr)."\n";
13775}
13776---------- end of /usr/lib/yp/normalize_printcap</screen>
13777</informalexample>
13778
13779</para>
13780
13781<para>The result of processing the sample printcap file is:
13782<informalexample>
13783<screen>lp1_1 lp1:lp=lp1@server
13784lp1_2 lp1:server:oh=servername:sd=/var/spool/lpd/lp1:lp=/dev/lp1:mx=0
13785lp2_1 lp2:lp=lp2@server
13786all_1 all:all=lp1,lp2</screen>
13787</informalexample>
13788</para>
13789
13790<para>Observe that each of the real printer entries has a key consisting of the
13791printer name with a numerical suffix.
13792This leads to the following method of extracting the printcap information
13793using
13794<literal>ypmatch</literal>:
13795<informalexample>
13796<screen>---------- start of /usr/lib/yp/match_printcap
13797#!/bin/sh
13798read p
13799n=1
13800# specify the full pathname to ypmatch - this depends on your
13801# OS version and installation
13802while /full/pathname/to/ypmatch "${p}_${n}" printcap 2&gt;/dev/null; do
13803    n=`expr $n + 1`
13804done
13805---------- end of /usr/lib/yp/match_printcap</screen>
13806</informalexample>
13807</para>
13808</listitem>
13809
13810<listitem>
13811<para>Now test the YP arrangement:
13812<informalexample>
13813<screen><prompt>h4: {316} # </prompt> cd /var/yp; make
13814    # this should create the printcap map
13815<prompt>h4: {317} # </prompt> ypcat printcap
13816    # should provide the whole normalized printcap
13817<prompt>h4: {318} # </prompt> echo lp1 |/usr/lib/yp/match_printcap
13818    # yields lp1 printcap</screen>
13819</informalexample>
13820</para>
13821</listitem>
13822
13823<listitem>
13824<para>Modify the <literal>printcap_path</literal> entry in the
13825<filename>lpd.conf</filename> file:
13826<informalexample>
13827<screen>printcap_path=|/usr/lib/yp/match_printcap</screen>
13828</informalexample>
13829</para>
13830</listitem>
13831
13832<listitem>
13833<para>Test the use of the printcap path entry:
13834<informalexample>
13835<screen><prompt>h4: {319} # </prompt> lpc client lp1 # shows the printcap for lp1
13836<prompt>h4: {320} # </prompt> lpc server lp1 # shows the printcap for lp1
13837</screen>
13838</informalexample>
13839</para>
13840</listitem>
13841
13842<listitem>
13843<para>Restart the lpd server and check to see that it accesses
13844the right printcap information.
13845Use the same <application>lpq</application> command,
13846and then try
13847<command remap=tt>lpc printcap lp1</command>.</para>
13848</listitem>
13849
13850</orderedlist>
13851</para>
13852
13853</sect2>
13854</sect1>
13855
13856<sect1><title>Lexmark Printers</title>
13857
13858<para>Some Lexmark printers do not send
13859<emphasis>end of job</emphasis>
13860status back unless configured
13861to do so.
13862Here is what is needed to force this.
13863(This capability has been incorporated into the
13864<application remap=tt>ifhp</application>
13865filter.)
13866<informalexample>
13867<screen>From: Matt White &lt;whitem@bofh.usask.ca&gt;
13868To: lprng@lprng.com
13869Date: Wed, 21 Jan 1998 18:25:50 -0600 (CST)
13870Subject: Re: [LPRng] ifhp with Lexmark Optra N printer
13871
13872On Wed, 21 Jan 1998, Simon Greaves wrote:
13873
13874&gt; Apologies in advance if this is way off mark, but we've been
13875&gt; evaluating a commercial print charging package (Geomica) which
13876&gt; works by talking to the printer in what I think is a similar way
13877&gt; to the ifhp filters. Lexmarks are currently a big headache because
13878&gt; they seem to fail to return the message that they have finished
13879&gt; printing which screws things up somewhat. In our case, it is believed
13880&gt; to be a problem with the Lexmark firmware which they are looking
13881&gt; into.
13882
13883There is a fix for that...it is originally from the Lexmark 4039
13884series, but it still works on the Optra S 1650 machines that we
13885have (and should work on the rest of the optra line).  Just send
13886this little chunk of postscript to the printer once:
13887
13888-----------snip----------
13889%! Postscript to set the 4039 printer into synchronous mode
13890serverdict begin 0 exitserver
13891statusdict begin true setenginesync end
13892-----------snip----------
13893
13894Basically, it causes the printer to wait until it is finished
13895printing before actually reporting that it is done.  I've got 3
13896Optra S printers running with ifhp right now with no extra options
13897(just defaults).
13898
13899-----------------------------------------------------------
13900- Matt White                  whitem@arts.usask.ca
13901- Network Technical Support   http://arts.usask.ca/~whitem
13902- College of Arts &amp; Science  University of Saskatchewan
13903-----------------------------------------------------------</screen>
13904</informalexample>
13905</para>
13906
13907</sect1>
13908
13909<sect1 id="P450"><title>Tektronix Phaser Printers </title>
13910
13911<para>The
13912<application remap=tt>ifhp</application>
13913filter supports the
13914
13915<link linkend="appsocket">AppSocket</link>
13916 protocol used by Tektronix.
13917You will need a printcap similar to the following:
13918<informalexample>
13919<screen>phaser:
13920 :sd=/var/spool/lpd/%P
13921 # need a dummy device for output
13922 :lp=/dev/null
13923 # You need to specify the IP address of the printer's network interface
13924 #  In this example it is 10.0.0.1 - replace with the correct value
13925 # The filter will actually open the connection.
13926 :filter=/usr/local/libexec/filters/ifhp
13927 :ifhp=dev=10.0.0.1%9100,model=tek</screen>
13928</informalexample>
13929</para>
13930
13931</sect1>
13932
13933<sect1><title>Duplex Printing</title>
13934
13935<para>Duplex printing is when you print on both sides of a page.
13936Some printers which do duplex printing require that you
13937send them special commands to force this mode.  This is
13938usually done by the FILTERS.  The <application>ifhp</application> filter makes a stab at sending
13939the PJL or PostScript commands to the printer.  Many people have
13940reported problems doing duplex printing,  so  here is a check
13941list.
13942<orderedlist>
13943
13944<listitem>
13945<para>Make sure you have enough memory for the worst case
13946print job.  Usually the printer has to rasterize both
13947pages before it can produce an impression.  It may require
13948much more memory than you expect.</para>
13949</listitem>
13950
13951<listitem>
13952<para>Check your printer manual to discover the EXACT form of the
13953<literal>enter duplex mode</literal>
13954command and make sure that either the command
13955is part of the job (PJL language at the start of the job,
13956postscript header, etc), or that the filter generates the
13957correct form.
13958</para>
13959
13960<para>Note there is a PostScript Printer Description file (PPD) for
13961most printers that support PostScript,  and they even have the
13962PJL and PostScript code for this in the PPD file.</para>
13963</listitem>
13964
13965<listitem>
13966<para>It has been observed that even with what would apparently be
13967sufficient memory,  that many duplex jobs print 'oddly',
13968that they are not aligned on the same side in the same way,
13969etc etc.  This may not be the fault of the software,  but of the
13970support for duplex operation.</para>
13971</listitem>
13972
13973<listitem>
13974<para>Read the <application>ifhp</application> documentation,
13975and create a configuration section in the <filename>ifhp.conf</filename> file
13976for your printer.</para>
13977</listitem>
13978
13979</orderedlist>
13980</para>
13981
13982<para>I know this is painful,  but until there is a uniform way to get the
13983correct commands extracted from either PPD or some other database then
13984this appears to be the only way to do it.
13985<blockquote>
13986<para><emphasis>Patrick Powell</emphasis></para>
13987</blockquote>
13988</para>
13989
13990</sect1>
13991
13992<sect1><title>Solaris, Newsprint and FrameMaker</title>
13993
13994<para>The following is a guide to using &LPRng; and
13995Sun Microsystems Newsprint by
13996Christopher Hylands, Ptolemy Project Manager
13997of the University of California.</para>
13998
13999<para>The Sun Newsprint printer is actually
14000an OEM version of the  Tektronix PhaserII;
14001Sun Microsystems appears to have dropped support for Newsprint,
14002and the recommended migration path is to buy a PostScript printer.
14003If you want more information on using the Newsprint system,
14004notes are available via
14005<filename>http://ptolemy.eecs.berkeley.edu/~cxh/lprng.html</filename>.</para>
14006
14007<para>Looking through the mailing list logs, it looks like everyone was
14008having a hard time getting lprng to work with Sun's brain-dead
14009newsprinters.  I tried using GhostScript, but the fonts were, IMHO,
14010ugly, so I spent a little time getting the newsprint fonts to work.</para>
14011
14012<para>The key thing was to grab the file
14013<filename>/usr/newsprint/lpd/if</filename>
14014from a SunOS4.1.3 newsprint installation.
14015If you cannot get this code,
14016then the installation will be extremely difficult.</para>
14017
14018<para>To install lprng on a Solaris2.x machine,
14019you need to first stop the existing print services and install the
14020startup scripts for &LPRng;.
14021Note that if there is a local printer, you may have
14022to also fix the permissions of the device. Typical commands are:
14023<informalexample>
14024<screen>chown daemon /devices/sbus@1,f8000000/SUNW,lpvi@1,300000:lpvi0</screen>
14025</informalexample>
14026</para>
14027
14028<para>We use the following simple
14029<literal>:if</literal>
14030script.
14031<informalexample>
14032<screen>#/bin/sh
14033# extremely simple filter script
14034/bin/cat</screen>
14035</informalexample>
14036</para>
14037
14038<para>The Sparcprinters use licensed fonts from NeWSprint. To use the
14039licensed fonts, you must have the lprng spool directory for the
14040sparcprinter in the same location as spool directory of the brain
14041dead Solaris lp system.  If your printer is named xsp524, then this
14042directory would be <command> /etc/lp/printers/xsp524</command>.</para>
14043
14044<para>The printcap entry looks like:
14045<informalexample>
14046<screen>sp524|524:
14047    :mx=0
14048    :lp=:rm=doppler:rp=xsp524:
14049    :sd=/var/spool/lpd/sp524d:
14050    :lf=/var/spool/lpd/sp524d/log:
14051xsp524|Sun SPARCprinter NeWSprint printer:
14052    :mx=0:rs:
14053    :lp=/dev/lpvi0:
14054    :sd=/etc/lp/printers/xsp524:
14055    :lf=/etc/lp/printers/xsp524/log:
14056    :af=/var/spool/lpd/xsp524/acct:
14057    :filter=/usr/local/libexec/newsprint/if:</screen>
14058</informalexample>
14059</para>
14060
14061<para>The
14062<filename>/usr/local/libexec/newsprint/if</filename>
14063was copied from
14064<filename>/usr/newsprint/lpd/if</filename>
14065in a SunOS4.x installation of the newsprint
14066software.
14067Unfortunately, the newsprint engine is so brain dead that it
14068needs many environment variables set, so it is fairly difficult to
14069come up with a clean script to start the engine. I made the following
14070changes to the file.
14071<orderedlist>
14072
14073<listitem>
14074<para>First, set the path in the script.
14075You may also need to change defaults to suit your preferences:
14076<informalexample>
14077<screen>PATH=/usr/ucb:/usr/bin:/etc:/usr/etc:\
14078  /opt/NeWSprint/bin:/opt/NeWSprint/np/bin:
14079PATH=$PATH:$NPHOME/pl.$ARCH/bin:$NPHOME/np/bin; export PATH</screen>
14080</informalexample>
14081</para>
14082</listitem>
14083
14084<listitem>
14085<para>You will also need a
14086<filename>/etc/lp/printers/printername/.params</filename>
14087file. If you
14088are using the same spooler directory as the directory that the Solaris
14089lp system uses, then the .param file should appear there. If you are
14090using a different spooler directory, then you will need to copy
14091the .param file from elsewhere and edit it accordingly.</para>
14092</listitem>
14093
14094<listitem>
14095<para>If you are going to move a license to a new printer, you should
14096probably save the .param file in the old printer spooler directory.
14097Run /opt/NeWSprint/bin/fp_install and remove the license from the
14098old printer and assign it to the new printer.
14099You could run /opt/NeWSprint/bin/rm_np_printer and remove the printer,
14100but that will get rid of the .param file</para>
14101</listitem>
14102
14103<listitem>
14104<para>FrameMaker under Solaris2.x uses the lp command. The fix is to edit
14105$FMHOME/fminit/FMlpr and comment out the lp line and add an lpr line
14106<informalexample>
14107<screen>sunxm.s5.sparc)
14108    lpr -P"$PRINTER" "$FILE"
14109    #lp -c -d"$PRINTER" "$FILE"</screen>
14110</informalexample>
14111</para>
14112</listitem>
14113
14114</orderedlist>
14115
14116<informalexample>
14117<screen>Christopher Hylands, Ptolemy Project Manager  University of California
14118cxh@eecs.berkeley.edu                 US Mail: 558 Cory Hall #1770
14119ph: (510)643-9841 fax:(510)642-2739       Berkeley, CA 94720-1770
14120home: (510)526-4010 (if busy -4068)       (Office: 493 Cory)</screen>
14121</informalexample>
14122</para>
14123
14124</sect1>
14125</chapter>
14126
14127<chapter id=spoolqueue><title>Spool Queues and Files
14128</title>
14129
14130<para>When files are accepted by the <application>lpd</application> server for printing,
14131they are stored in a spool queue directory,
14132together with other files controlling the print operation.
14133This section describes these files and how the &LPRng; software uses them.</para>
14134
14135<para>For descriptive purposes,
14136we will use the following printcap entry as a guide:</para>
14137
14138<para>
14139<informalexample>
14140<screen>pr|alias
14141  :sd=/var/lpd/pr_public
14142  :cd=/var/lpd/pr</screen>
14143</informalexample>
14144</para>
14145
14146
14147<sect1><title>Spool Queue</title>
14148
14149<para>
14150<itemizedlist>
14151
14152<listitem>
14153<para> <literal>sd=</literal><emphasis>Spool queue directory name</emphasis></para>
14154</listitem>
14155
14156</itemizedlist>
14157</para>
14158
14159<para>The
14160<option>:sd</option>
14161option in the printcap entry specifies the spool queue
14162directory.
14163If there is no
14164<option>:sd</option>
14165entry or value,
14166then the printer can only be used by the clients such as <application>lpq</application>
14167to locate the destination for a print job.
14168All information,
14169files,
14170etc.,
14171for a print queue is stored in the spool directory.</para>
14172
14173</sect1>
14174
14175<sect1 id="queuelockfile"><title>Queue Lock File </title>
14176
14177<para>
14178<itemizedlist>
14179
14180<listitem>
14181<para> <literal>spool_lock_file</literal><emphasis>spool queue lock file - default %P</emphasis></para>
14182</listitem>
14183
14184</itemizedlist>
14185</para>
14186
14187<para>When the <application>lpd</application> server starts printing,
14188it will fork individual worker processes to service each queue.
14189To prevent multiple processes from working on the same queue,
14190a printer lock file specified by the
14191<literal>queue_lock_file</literal> option
14192(default
14193<literal>%P</literal>
14194- the %P is expanded to the print queue name)
14195is used.
14196In our example,
14197the lock file would be:
14198<filename>/var/lpd/pr/pr</filename>.</para>
14199
14200<para>The process ID of the currently active printer is stored in the lock file.
14201By reading the lock file and testing to see if the process is still active,
14202programs such as <application>lpq</application> can determine queue activity.</para>
14203
14204<para>Similarly,
14205the worker process may need to create other processes to assist it.
14206These in turn will create lock or temporary files in the spool directory
14207as well.</para>
14208
14209</sect1>
14210
14211<sect1 id="queuecontrolfile"><title>Spool Control File </title>
14212
14213<para>
14214<itemizedlist>
14215
14216<listitem>
14217<para> <literal>spool_control_file</literal><emphasis>spool queue control file - default control.%P</emphasis></para>
14218</listitem>
14219
14220</itemizedlist>
14221</para>
14222
14223<para>The spool control file is used to control the operations of the
14224spooler,
14225and is in the spool or control directory.
14226The file name specified by the
14227<literal>queue_control_file</literal> option
14228(default
14229<literal>control.%P</literal>
14230- the %P is expanded to the print queue name);
14231in our example,
14232the control file would be:
14233<filename>/var/lpd/pr/control.pr</filename>.</para>
14234
14235<para>The <application>lpc</application> program sends spool control requests to the
14236<application>lpd</application> daemon,
14237which updates the control file and then signals the appropriate
14238spool server processes that an update has been performed.
14239The control file contents have the form:
14240<informalexample>
14241<screen>key value</screen>
14242</informalexample>
14243</para>
14244
14245<para>The following keys and their values are currently supported.</para>
14246
14247<informaltable frame=all>
14248<tgroup cols=3 align=left rowsep=1 colsep=1>
14249<thead>
14250<row><entry>Key</entry><entry>Value</entry><entry>Purpose</entry></row>
14251</thead>
14252<tbody>
14253<row><entry> <literal remap=tt>printing_disabled</literal>
14254</entry><entry> 0 or 1
14255</entry><entry> disable printing of jobs in queue <!-- <br> -->
14256</entry></row>
14257<row><entry> <literal remap=tt>spooling_disabled</literal>
14258</entry><entry> 0 or 1
14259</entry><entry> disable placing jobs in queue <!-- <br> -->
14260</entry></row>
14261<row><entry> <literal remap=tt>holdall</literal>
14262</entry><entry> 0 or 1
14263</entry><entry> hold jobs until released <!-- <br> -->
14264</entry></row>
14265<row><entry> <literal remap=tt>redirect</literal>
14266</entry><entry> <literal remap=tt>printer</literal>
14267</entry><entry> transfer jobs to indicated printer <!-- <br> -->
14268</entry></row>
14269<row><entry> <literal remap=tt>class</literal>
14270</entry><entry> <literal remap=tt>glob expression</literal>
14271</entry><entry> print only jobs whose class matches glob expression <!-- <br> -->
14272</entry></row>
14273<row><entry> <literal remap=tt>server_order</literal>
14274</entry><entry> <literal remap=tt>printer name list</literal>
14275</entry><entry> preferred order of printer use <!-- <br> -->
14276</entry></row>
14277<row><entry> <literal remap=tt>debug</literal>
14278</entry><entry> <literal remap=tt>debugging options</literal>
14279</entry><entry> debugging and tracing <!-- <br> -->
14280</entry></row>
14281</tbody>
14282</tgroup>
14283</informaltable>
14284
14285<para>The <literal>printing_disabled</literal> and <literal>spooling_disabled</literal>
14286are managed using the
14287<command remap=tt>lpc start</command>,
14288<command remap=tt>lpc stop</command>,
14289
14290<command remap=tt>lpc enable</command>
14291and
14292<command remap=tt>lpc disable</command>
14293commands.
14294Similarly,
14295<literal>holdall</literal>
14296is enabled and disabled by
14297<literal>holdall</literal>
14298and
14299<literal>noholdall</literal>
14300commands respectively.
14301When holdall is enabled,
14302jobs placed in the print queue will be held until they are explicitly
14303released for printing by an
14304<command remap=tt>lpc release</command>
14305command.</para>
14306
14307<para>The
14308<literal>redirect</literal>
14309entry is used to redirect or transfer jobs
14310which are spooled to this queue to another queue,
14311and is managed by the redirect command.
14312The
14313<command remap=tt>lpc redirect off</command>
14314removes the redirect entry from the
14315control file.</para>
14316
14317<para>The
14318<literal>class</literal>
14319entry is similar in operation to the
14320<literal>holdall</literal>,
14321but allows jobs whose class identification matches the glob
14322expression to be printed.
14323This can be useful when you have special forms or paper required for a
14324print job,
14325and want to run only these jobs when the paper is in the printer.</para>
14326
14327<para>The <literal>server_order</literal>
14328entry is created and updated for a multiple printer queue.
14329It records the order in which printers should next be used
14330for normal print operations.
14331This allows <emphasis>round robin</emphasis>
14332use of printers,
14333rather than having all jobs printed to the first printer in the
14334list of printers.</para>
14335
14336<para>The
14337<literal>debug</literal>
14338entry is set by the
14339<command remap=tt>lpc debug</command>
14340command,
14341and is used to enable or disable debugging and tracing information
14342for a spool queue.
14343This facility is for diagnostic purposes only.</para>
14344
14345</sect1>
14346
14347<sect1 id="logfiles"><title>Log and Status Files </title>
14348
14349<para>
14350<itemizedlist>
14351
14352<listitem>
14353<para> <literal>create_files</literal><emphasis>create log, accounting and status files</emphasis></para>
14354</listitem>
14355
14356<listitem>
14357<para> <literal>lf=</literal><emphasis>log file name (default: log)</emphasis></para>
14358</listitem>
14359
14360<listitem>
14361<para>
14362<literal>max_log_file_size#</literal><emphasis>maximum log file size (Kbytes)</emphasis></para>
14363</listitem>
14364
14365<listitem>
14366<para>
14367<literal>min_log_file_size#</literal><emphasis>minimum log file size (Kbytes)</emphasis></para>
14368</listitem>
14369
14370<listitem>
14371<para>
14372<literal>max_status_line#</literal><emphasis>maximum status line length (characters) </emphasis></para>
14373</listitem>
14374
14375<listitem>
14376<para>
14377<literal>max_status_size#</literal><emphasis>maximum status file size (Kbytes)</emphasis></para>
14378</listitem>
14379
14380<listitem>
14381<para>
14382<literal>min_status_size#</literal><emphasis>minimum status file size (Kbytes)</emphasis></para>
14383</listitem>
14384
14385<listitem>
14386<para> <literal>ps=</literal><emphasis>filter status file name (default: status)</emphasis></para>
14387</listitem>
14388
14389<listitem>
14390<para> <literal>queue_status_file=</literal><emphasis>queue status file (default: status.%P)</emphasis></para>
14391</listitem>
14392
14393<listitem>
14394<para> <literal>short_status_date=</literal><emphasis>display short (hh:mm) timestamp (default: true)</emphasis></para>
14395</listitem>
14396
14397</itemizedlist>
14398</para>
14399
14400<para>During operation,
14401the <application>lpd</application> server records the current printing operations
14402in the spool queue status file specified by the <literal>spool_status_file</literal> option
14403(default
14404<literal>status.%P</literal>
14405- the %P is expanded to the print queue name);
14406for our example, this would be
14407<filename>/var/lpd/pr/status.pr</filename>.
14408In order to prevent this file from growing too large,
14409the server will periodically truncate the file.
14410You can force creation of these files by setting the
14411<literal>create_files</literal> option.
14412The
14413<literal>max_status_size</literal> configuration or printcap option
14414sets the maximum size (in Kbytes) of the status file;
14415if the file exceeds this,  only the last
14416<literal>min_status_size</literal> bytes
14417or 25% of the maximum size (default if not specified)
14418will be preserved.</para>
14419
14420<para>Similarly,
14421the server logs its operations in the log file specified by the
14422<literal>lf</literal>
14423(log file) option (default is <literal>lf=log</literal>).
14424The <literal>max_log_file_size</literal>
14425value
14426(default 0)
14427specifies the maximum length
14428of the log file in Kbytes.
14429If this value is non-zero,
14430then the log file is truncated to
14431<literal>min_log_file_size</literal> bytes
14432or 25% of the maximum file size.
14433Again, the last portion of the log file is preserved.
14434If the <literal>max_log_file_size</literal> value is 0,
14435then the log file grows without limit.</para>
14436
14437<para>Some filters require an additional filter status file
14438that they use for recording additional filter status or
14439other operational information.
14440The
14441<literal>ps</literal>
14442names this file,
14443and it is passed to a print filter using the
14444<literal>$s</literal>
14445option
14446(see
14447
14448<link linkend="filteroptions">Filter Command Line Options and Environment Variables</link>
14449).</para>
14450
14451<para>The <acronym/STDERR/ output for filters is put into the printer
14452status file.
14453This allows the filter to produce informative messages that can be displayed
14454as part of the user status.
14455In addition,
14456a separate status file specified by the
14457<literal>ps</literal>
14458(Printer Status) can be used as well.
14459This file is
14460<emphasis>not</emphasis>
14461truncated by the &LPRng; system.</para>
14462
14463<para>When reporting status information,
14464the length of line returned can be a problem.
14465The
14466<literal>max_status_line#79</literal>
14467option restricts the status line
14468to a maximum of 79 characters.</para>
14469
14470<para>The <literal>short_status_date</literal> (default is true)
14471option causes short (hour:minute) timestamps to be displayed
14472on status queries.</para>
14473
14474</sect1>
14475
14476<sect1 id="jobfiles"><title>Job Files
14477</title>
14478
14479<para>
14480<itemizedlist>
14481
14482<listitem>
14483<para>
14484<literal>longnumber</literal><emphasis>long job number</emphasis></para>
14485</listitem>
14486
14487<listitem>
14488<para> <literal>default_priority=</literal><emphasis>default job priority</emphasis></para>
14489</listitem>
14490
14491<listitem>
14492<para> <literal>nline_after_file</literal><emphasis>N line after data file</emphasis></para>
14493</listitem>
14494
14495</itemizedlist>
14496</para>
14497
14498<para>A print job consists of a control file and one or more data files.
14499
14500<link linkend="rfc1179">RFC1179</link>
14501
14502specifies the general format of these files and how they are to be
14503transfered between servers.
14504&LPRng; has extended the contents of the control files and the transfer protocol
14505to provide a more powerful set of features,
14506but has extensive provisions for backwards compatibility with
14507non-&LPRng; software.
14508A sample control file is shown below:
14509<informalexample>
14510<screen>Hh4.private
14511J/tmp/file1 /tmp/file2
14512CA
14513Lpapowell
14514Ppapowell
14515fdfA002230h4.private
14516N/tmp/file1
14517UdfA002230h4.private
14518fdfB002230h4.private
14519N/tmp/file2
14520UdfB002230h4.private</screen>
14521</informalexample>
14522</para>
14523
14524<para>The first part of the control file contains general information generated
14525by the <application>lpr</application> or other spooling program.
14526The information lines start with an uppercase letter or digit.
14527Some other spooling systems also start information lines with
14528various punctuation marks such as underscores (_) or periods (.).</para>
14529
14530<para>Following this are a set of entries about each of the various files to
14531be printed.
14532These lines start with a lower case letter,
14533followed by the print file name.
14534The lower case letter is the
14535<emphasis>format</emphasis>
14536to be used to process the file.
14537See
14538
14539<link linkend="printingjob">print file formats</link>
14540
14541for more information about its use.</para>
14542
14543<table id=cfline frame=all><title>Control File Lines</title>
14544<tgroup cols=3 align=left colsep=1 rowsep=1>
14545<thead>
14546<row><entry>Key</entry><entry>Meaning</entry><entry>Generated By</entry></row>
14547</thead>
14548<tbody>
14549<row><entry>Key</entry><entry>Meaning</entry><entry>Generated By</entry></row>
14550<row><entry>A</entry><entry>identifier *</entry><entry>&LPRng; internal</entry></row>
14551<row><entry>C</entry><entry>class</entry><entry>lpr -C class</entry></row>
14552<row><entry>D</entry><entry>date</entry><entry>lpr</entry></row>
14553<row><entry>H</entry><entry>originating host</entry><entry>lpr</entry></row>
14554<row><entry>I</entry><entry>indent</entry><entry>lpr -i indent</entry></row>
14555<row><entry>J</entry><entry>jobname</entry><entry>lpr -J jobname (default: list of files)</entry></row>
14556<row><entry>L</entry><entry>bnrname</entry><entry>lpr -U username</entry></row>
14557<row><entry>N</entry><entry>filename</entry><entry>(see text)</entry></row>
14558<row><entry>M</entry><entry>mailname</entry><entry>lpr -m mailname</entry></row>
14559<row><entry>P</entry><entry>logname</entry><entry>lpr</entry></row>
14560<row><entry>Q</entry><entry>queuename</entry><entry>lpr -Q</entry></row>
14561<row><entry>R</entry><entry>accntname</entry><entry>lpr -R accntname</entry></row>
14562<row><entry>S</entry><entry>slinkdata *</entry><entry>lpr</entry></row>
14563<row><entry>T</entry><entry>prtitle</entry><entry>lpr -T prtitle</entry></row>
14564<row><entry>U</entry><entry>unlnkfile</entry><entry>(see text)</entry></row>
14565<row><entry>W</entry><entry>width</entry><entry>lpr -w width</entry></row>
14566<row><entry>Z</entry><entry>zopts *</entry><entry>lpr -Z zopts</entry></row>
14567<row><entry>1</entry><entry>font1</entry><entry>lpr -1 font1</entry></row>
14568<row><entry>2</entry><entry>font2</entry><entry>lpr -2 font2</entry></row>
14569<row><entry>3</entry><entry>font3</entry><entry>lpr -3 font3</entry></row>
14570<row><entry>4</entry><entry>font4</entry><entry>lpr -4 font4</entry></row>
14571</tbody>
14572</tgroup>
14573</table>
14574
14575<para>The entries marked with * are used only by &LPRng;.
14576<literal remap=tt>N</literal>
14577and
14578<literal remap=tt>U</literal>
14579lines
14580are associated with a print file.
14581The
14582<literal remap=tt>N</literal>
14583line is the original name of the print
14584file.
14585By default,
14586&LPRng; places this line <emphasis>before</emphasis>
14587the corresponding data file.
14588You can use the
14589<literal>nline_after_file</literal>
14590option to have &LPRng; place the N line after the data file line.
14591The
14592<literal remap=tt>U</literal>
14593line originally was used to indicate that the
14594named file was to be unlinked after printing.
14595This information is now ignored by &LPRng;.
14596These lines are always grouped with a print file entry.</para>
14597
14598<para>The names of control and data files follow a very strict pattern.
14599Control files have the format
14600<literal>cfX</literal><replaceable>number</replaceable><emphasis>host</emphasis>,
14601where X is an upper case letter,
14602<emphasis>number</emphasis>
14603is (usually) a 3 digit number,
14604and <emphasis remap=bf>host</emphasis>
14605is the host name.
14606
14607<link linkend="rfc1179">RFC1179</link>
14608
14609restricted the total length of the control file name to 32 characters;
14610&LPRng; has a much looser limit.</para>
14611
14612<para>Data file names must follow the same pattern as the control file name,
14613and have the format
14614<literal>dfX</literal><replaceable>number</replaceable><emphasis>host</emphasis>.
14615The X can be in the range A-Za-z,
14616allowing at most 52 data files for a job.
14617The <emphasis>number</emphasis>
14618and <emphasis remap=bf>host</emphasis>
14619must be identical to the corresponding
14620control file.</para>
14621
14622<para>By convention,
14623&LPRng; uses the X of the control file name to set a priority for the
14624job.
14625A job with control file name
14626<literal>cfA...</literal>
14627will have <emphasis>lower</emphasis>
14628format
14629than a job with format
14630<literal>cfB...</literal>,
14631and so forth.
14632The <application>lpr</application>
14633program uses the first letter of the class name
14634or an explicit priority value to set the letter value.
14635If none of these are specified, then the
14636<literal>default_priority</literal> value from the configuration or printcap
14637entry is used.</para>
14638
14639<para>The job number is usually a 3 digit value.
14640However,
14641in systems where a large number of jobs are spooled and need to be
14642kept for printing at scheduled times,
14643this can lead to problems.
14644The
14645<literal>longnumber</literal>
14646option will use 6 digit job numbers.
14647This must be used with care when operating with non-&LPRng; software.</para>
14648
14649</sect1>
14650
14651<sect1><title>Job Hold File</title>
14652
14653<para>Associated with each control file is a
14654hold file that has additional information controlling the printing operations.
14655The entries in this file have the form:
14656<informalexample>
14657<screen>key [value]</screen>
14658</informalexample>
14659</para>
14660
14661<para>The following is an example of a hold file:
14662<informalexample>
14663<screen>server 0
14664subserver 0
14665attempt 3
14666error cannot open printer
14667hold 0
14668priority 0
14669remove 0
14670routed 0</screen>
14671</informalexample>
14672</para>
14673
14674<para>The
14675<literal>server</literal>
14676and
14677<literal>subserver</literal>
14678entry records the process ID of the server process
14679and the subserver process that is printing the job.
14680The
14681<literal>attempt</literal>
14682field records the total number of attempts to print the job.
14683The
14684<literal>error</literal>
14685field records any error that would prevent the job from being printed.
14686This information is reported by the <application>lpq</application> program.</para>
14687
14688<para>The
14689<literal>hold</literal>
14690field is non-zero when the
14691
14692<command remap=tt>lpc hold</command>
14693command is used to
14694explicitly prevent the job from being printed;
14695
14696<command remap=tt>lpc release</command>
14697will clear the field and allow the job to be printed.</para>
14698
14699<para>The
14700<literal>priority</literal>
14701field is modified by the
14702
14703<command remap=tt>lpc topq</command>
14704command and is used to provide an overriding priority to printing the file.</para>
14705
14706<para>The
14707<literal>remove</literal>
14708field is non-zero when the file has been printed and should be removed.</para>
14709
14710<para>The
14711<literal>routed</literal>
14712field is used to indicate that there is routing information present in
14713the hold file,
14714and that special handling is needed.
14715The routing information is provided by a
14716
14717<link linkend="destinations">routing filter</link>.
14718The information is recorded by information in the hold file.
14719The following is an example of routing information.
14720Normally this information is stored in a URL escaped format,
14721with one line per destination,
14722but for clarity this has been broken out into plain text form:</para>
14723
14724<para>
14725<informalexample>
14726<screen>active 0
14727attempt 0
14728done 0
14729hold 0
14730priority 0
14731remove 0
14732routed 880892602
14733route 1
14734  dest t1
14735  ident papowell@h4+705.1
14736  error
14737  copies 1
14738  copy_done 0
14739  status 0
14740  active 0
14741  attempt 0
14742  done 0
14743  hold 0
14744  sequence 0
14745  priority B
14746  CB
14747  end
14748route 2
14749  dest t1
14750  ident papowell@h4+705.2
14751  error
14752  copies 0
14753  copy_done 0
14754  status 0
14755  active 0
14756  attempt 0
14757  done 0
14758  hold 0
14759  sequence 1
14760  end</screen>
14761</informalexample>
14762</para>
14763
14764<para>Routing information lines start with
14765<literal>route</literal>
14766followed by individual routing entry information.
14767The
14768<literal>route</literal>
14769<literal>dest</literal>,
14770<literal>copies</literal>,
14771<literal>priority</literal>,
14772and
14773<literal>Xnnnn</literal>
14774entries are
14775derived from the output of the router program;
14776other fields are used during the printing process.
14777The <literal>copy_done</literal> records the numbers of copies done,
14778while the
14779<literal>done</literal>
14780records that the entry has been completed.
14781The
14782<literal>status</literal>
14783is the process ID of the server process
14784doing the printing.</para>
14785
14786<para>The output from  route filter  that generated the above file was:
14787<informalexample>
14788<screen>dest t1
14789copies 1
14790priority B
14791CB
14792end
14793dest t1
14794end</screen>
14795</informalexample>
14796</para>
14797
14798</sect1>
14799
14800<sect1 id="ah"><title>Job State </title>
14801
14802<para>Options used:
14803<itemizedlist>
14804
14805<listitem>
14806<para>
14807<literal>ah</literal> FLAG <emphasis>Automatically hold jobs</emphasis></para>
14808</listitem>
14809
14810</itemizedlist>
14811</para>
14812
14813<para>A job can be in the following state:
14814<orderedlist>
14815
14816<listitem>
14817<para>Initial.
14818This is the state during job submission.
14819Jobs in the initial state do not have any status displayed for them.</para>
14820</listitem>
14821
14822<listitem>
14823<para>Held.
14824Once a job is submitted,
14825it can either be printed or <emphasis>held</emphasis>.
14826The
14827<literal>ah</literal>
14828printcap option specifies that all jobs are
14829automatically held on submission.
14830The
14831
14832<command remap=tt>lpc release</command>
14833and
14834
14835<command remap=tt>lpc redo</command>
14836command will cause these jobs to be printed and
14837the <application>lprm</application> command can remove these jobs.</para>
14838</listitem>
14839
14840<listitem>
14841<para>Active.
14842The job is being processed for printing or transfer to another queue.</para>
14843</listitem>
14844
14845<listitem>
14846<para>Pending.
14847Jobs which can be printed but are not active.
14848This can be due to the printer being busy or
14849the job <emphasis remap=bf>class</emphasis>
14850not being printed.</para>
14851</listitem>
14852
14853<listitem>
14854<para>Error.
14855Jobs which have encountered an error during printing.
14856The
14857
14858<command remap=tt>lpc release</command>
14859and
14860
14861<command remap=tt>lpc redo</command>
14862command will cause these jobs to be printed and
14863the <application>lprm</application> command can remove these jobs.</para>
14864</listitem>
14865
14866<listitem>
14867<para>Done.
14868Jobs which have completed printing,
14869but which are not yet removed from the print queue.
14870See the
14871<emphasis remap=tt>
14872<link linkend="normalterm">save_when_done</link>
14873</emphasis>
14874flag for more information.
14875The <application>lprm</application> command can remove these jobs.</para>
14876</listitem>
14877
14878</orderedlist>
14879</para>
14880
14881<para>Normally the job sequences is initial, pending, active, and done.
14882However, a job may be put in the error state by problems processing the job
14883or by actions of the <application>lpc</application> command.</para>
14884
14885</sect1>
14886
14887<sect1 id="useidentifier"><title>Job Identifier </title>
14888
14889<para>For each job in a spool queue,
14890the &LPRng; software creates a unique identifier.
14891This identifier is recorded in the control file
14892<literal remap=tt>A</literal>
14893line.
14894It can be used by the various client programs for identifying jobs,
14895and is displayed by the <application>lpq</application> program as status information.</para>
14896
14897</sect1>
14898</chapter>
14899
14900<chapter id=configfile><title>Configuration File, Defaults and Overrides </title>
14901<para>Options used:
14902<itemizedlist>
14903
14904<listitem>
14905<para> <literal>allow_getenv</literal> FLAG <emphasis>use GETENV environment variable</emphasis></para>
14906</listitem>
14907
14908</itemizedlist>
14909</para>
14910
14911<para>The &LPRng; options are obtained as follows:
14912<itemizedlist>
14913
14914<listitem>
14915<para>The compile time defaults.
14916These are in the <filename>LPRng/src/common/vars.c</filename>
14917file.</para>
14918</listitem>
14919
14920<listitem>
14921<para>If the &LPRng; software has been compiled with the regression testing
14922<acronym>GETENV</acronym> option enabled,
14923the configuration information in the file specified by the
14924<literal>LPD_CONF</literal> environment variable will be used.
14925This can only be used if you are not setuid ROOT or as ROOT
14926as it opens severe security loopholes.</para>
14927</listitem>
14928
14929<listitem>
14930<para>The file specified by the <literal>config_file</literal> compile time
14931option, usually <filename>/etc/lpd.conf</filename> or <filename>/usr/local/etc/lpd.conf</filename>,
14932and referred to a the <filename>lpd.conf</filename> file.
14933If the <literal>config_file</literal> option value has
14934the form <filename>|/pathname</filename>,
14935then <filename>/pathname</filename> must be an executable program
14936and will be run with the standard set of filter
14937options.
14938It must write configuration option values to its <acronym/STDOUT/
14939and exit with a 0 status.</para>
14940</listitem>
14941
14942<listitem>
14943<para>In order to protect system security,
14944the
14945<filename>lpd.conf</filename>
14946(and the <filename>printcap</filename>)
14947file should be read only.</para>
14948</listitem>
14949
14950<listitem>
14951<para>If the <literal>require_configfiles</literal> option is set in the compile time
14952options,
14953then the preceeding step must be successful,
14954i.e. - there must be a configuration file or the program
14955must execute and exit with a 0 status.</para>
14956</listitem>
14957
14958<listitem>
14959<para>If a printer or spooling operation is done,
14960then the values in the <filename>printcap</filename>
14961entry for the spooler are used to override
14962the default and <filename>ifhp.conf</filename> file values.</para>
14963</listitem>
14964
14965</itemizedlist>
14966</para>
14967
14968
14969<sect1><title>Configuration File Format</title>
14970
14971<para>The configuration file format is similar to
14972a the fields of a printcap entry
14973with the difference that the leading colon is optional
14974and there can only be one option per line:
14975<informalexample>
14976<screen># comment
14977# set option value to 1 or ON
14978ab
14979:ab
14980# set option value to 0 or OFF
14981ab@
14982:ab
14983# set option value to string
14984str=name</screen>
14985</informalexample>
14986</para>
14987
14988<para>During system installation the &LPRng; software processes the
14989default values in the <filename>LPRng/src/common/vars.c</filename>
14990file and generates a sample <filename>lpd.conf</filename> file that has the
14991format:
14992<informalexample>
14993<screen># Purpose: always print banner, ignore lpr -h option
14994#   default ab@ (FLAG off)
14995# Purpose: query accounting server when connected
14996#   default achk@ (FLAG off)
14997# Purpose: accounting at end (see also af, la, ar, as)
14998#   default ae=jobend $H $n $P $k $b $t  (STRING)
14999# Purpose: name of accounting file (see also la, ar)
15000#   default af=acct  (STRING)
15001
15002# change:
15003# --- we change the af value to none, i.e. - no accounting
15004# --- file by default
15005af=</screen>
15006</informalexample>
15007</para>
15008
15009<para>You can change option values by editing the file
15010as shown above then then
15011to force the <application>lpd</application> server to use the new options,
15012use the
15013<command remap=tt>lpc reread</command>
15014command.</para>
15015
15016</sect1>
15017
15018<sect1><title>Legacy Compatibility</title>
15019
15020<para>The following arguments have been provided for compatibility with
15021legacy systems.</para>
15022
15023</sect1>
15024</chapter>
15025
15026<chapter id=jobsteps><title>Job Processing</title>
15027
15028<para>Much of the flexibility of the &LPRng; software is obtained
15029from the ability to control the details of each step of job processing.
15030The following section details each step in the processing of a job,
15031and explains the printcap options used to control each operation.</para>
15032
15033<para>Assume the
15034<literal>pr</literal>
15035printcap entry has the form:
15036<informalexample>
15037<screen>pr
15038    :lp=/dev/lp  OR  :lp=rp@rm
15039    :sd=/var/spool/lpd/pr
15040    :lf=log
15041    :filter=/usr/local/bin/lpf</screen>
15042</informalexample>
15043</para>
15044
15045<para>Assume that we have used the following command to print
15046a set of files.
15047<informalexample>
15048<screen>lpr -Ppr file1 file2</screen>
15049</informalexample>
15050</para>
15051
15052<para>This will create a control file
15053in the
15054<filename>/var/spool/lpd/pr</filename>
15055directory with the following contents (this is an example -
15056in practice there may be minor differences between the example
15057and an actual control file):
15058<informalexample>
15059<screen>Hh4.private
15060J/tmp/file1 /tmp/file2
15061CA
15062Lpapowell
15063Ppapowell
15064fdfA002230h4.private
15065N/tmp/file1
15066UdfA002230h4.private
15067fdfB002230h4.private
15068N/tmp/file2
15069UdfB002230h4.private</screen>
15070</informalexample>
15071</para>
15072
15073<para>
15074We will refer to this example throughout the following sections.
15075</para>
15076
15077
15078<sect1 id="configsetup"><title>Configuration and Setup Options
15079</title>
15080
15081<para>Options used:
15082<itemizedlist>
15083
15084<listitem>
15085<para>
15086<literal>ipv6</literal> FLAG <emphasis>use IPV6 Network facilities </emphasis></para>
15087</listitem>
15088
15089<listitem>
15090<para> <literal>default_tmp_dir=</literal><emphasis>temporary directory</emphasis></para>
15091</listitem>
15092
15093<listitem>
15094<para> <literal>lockfile=</literal><emphasis>lpd server lock file</emphasis></para>
15095</listitem>
15096
15097<listitem>
15098<para> <literal>report_server_as=</literal><emphasis>server name for status reports</emphasis></para>
15099</listitem>
15100
15101<listitem>
15102<para>
15103<literal>spool_dir_perms=</literal><emphasis>spool directory permissions </emphasis></para>
15104</listitem>
15105
15106<listitem>
15107<para>
15108<literal>spool_file_perms=</literal><emphasis>spool file permissions </emphasis></para>
15109</listitem>
15110
15111</itemizedlist>
15112</para>
15113
15114<para>The
15115<literal>ipv6</literal>
15116specifies that the IPV6 protocol,
15117rather than IPV4 will be used.</para>
15118
15119<para>The
15120<literal>lockfile</literal>
15121specifies the location of the
15122lock file used by the <application>lpd</application> server.
15123This file has the port number in the <literal>lpd_port</literal> value appended to form a unique
15124lock file name.</para>
15125
15126<para>The <literal>spool_dir_perms</literal> and <literal>spool_file_perms</literal>
15127(default 0700 and 0600 respectively)
15128values are the (numeric) permissions for the spool directory and
15129spool files.</para>
15130
15131<para>The <literal>report_server_as</literal> option allows an administrator to
15132masquerade a server with another name.
15133This could be useful if various load sharing activities are
15134being carried out,  or if there are problems reconfiguring DNS
15135to cause the correct server name to be reported.</para>
15136
15137<para>The <literal>default_tmp_dir</literal> option specifies a temporary
15138directory to be used to hold files or information temporarily
15139if there is no spool directory available.</para>
15140
15141</sect1>
15142<sect1 id="submitting"><title>Submitting Jobs and Service Requests</title>
15143
15144
15145<para>Options used:
15146<itemizedlist>
15147
15148<listitem>
15149<para> <literal>lpd_port=</literal><emphasis>Listening Port for <application/lpd/</emphasis></para>
15150</listitem>
15151
15152<listitem>
15153<para> <literal>unix_socket_path=</literal><emphasis>Unix socket for <application/lpd/ connections</emphasis></para>
15154</listitem>
15155
15156</itemizedlist>
15157</para>
15158<para>
15159After the <application/lpd/ server has done its initialization,
15160it will attempt to bind to the <application/lpd/ listening port specified by the
15161<literal/lpd_port/ value.
15162This value has the format <literal>[ipaddr%]port</literal>.
15163If the <literal>ipaddr</literal> is specified then the lpd server binds to the
15164interface with the specified address otherwise it binds to all interfaces.
15165The port value can be a number or name the name of a service;
15166The port corresponding to the service name is used.
15167The <literal/printer/ services port is 515.
15168If the port binding operation is successful
15169and the server has not been request to run in <emphasis/foreground/ mode
15170by the <literal/-F/ command line option,
15171then a child process is forked and the parent process will exit.
15172The child process then takes steps to disconnect itself from the control terminal
15173of the process that started it.
15174</para>
15175<para>
15176The <literal/unix_socket_path/ option specifies the pathname of a <emphasis/fifo/
15177socket that local processes can use instead of the TCP/IP port.
15178</para>
15179<para>
15180The main <application/lpd/ process will then start a
15181<emphasis/queue checking/ process that will check all of the spool queues
15182used by the server for queues that have pending jobs.
15183This process sends a message to the main <application/lpd/ process requesting
15184that it start a service process for this queue.
15185</para>
15186<para>
15187The <application/lpd/ process will then sit in a loop waiting for
15188one of the following events:
15189</para>
15190<orderedlist>
15191<listitem><para>
15192An incoming connection request.
15193If the maximum number of children has not been exceeded,
15194then a new process will be forked to handle this connection.
15195</para></listitem>
15196<listitem><para>
15197A child process exiting.
15198The server will check to see if there is a pending request to start
15199a server for a queue that could not be accommodated due to too many
15200processes running.
15201</para></listitem>
15202<listitem><para>
15203A request to start a service process for a queue.
15204If the number of active processes is less than the maximum
15205allowed
15206a service process will be started,
15207otherwise the request will be placed on a list for service when the
15208number of processes active decreases.
15209</para></listitem>
15210<listitem><para>
15211A timeout alarm for the queue rescanning operation.
15212This is discussed in the next section in detail.
15213</para></listitem>
15214</orderedlist>
15215<para>
15216When connection is accepted by the <application/lpd/ spooler,
15217the following steps are taken to processes the job.
15218</para>
15219<orderedlist>
15220<listitem><para>
15221First,
15222a timeout is established for the transfer of the information from client
15223to the <application/lpd/ server.
15224This is done to prevent a denial of service attack by processes that do
15225not close connections in a timely manner.
15226</para></listitem>
15227<listitem><para>
15228A single line is read into an internal buffer.
15229This line must be terminated with a <literal/NEWLINE/ character.
15230</para></listitem>
15231<listitem><para>
15232The input line is parsed and the actions required are determined.
15233</para></listitem>
15234<listitem><para>
15235If the activity requires access to the spool queue information,
15236then the current directory of the process is changed to the spool
15237directory.
15238This allows all file accesses to then be relative to this directory.
15239</para></listitem>
15240<listitem><para>
15241If the processing requires starting a spool queue server process,
15242a message is sent to the main <application/lpd/ server process
15243to start a spool queue server process.
15244By having all the processes serving spool queues children of the main
15245server process it is possible to monitor
15246and limit the total number of active processes.
15247This is important on systems with a very large number of queues.
15248</para></listitem>
15249<listitem><para>
15250After the processing of the original request has been completed,
15251the process with then check to see if the Spool Queue for the printer
15252should be processed.
15253</para></listitem>
15254</orderedlist>
15255
15256</sect1>
15257
15258<sect1 id="reception"><title>Job Reception </title>
15259<itemizedlist>
15260
15261<listitem>
15262<para>
15263<literal>longnumber</literal> FLAG <emphasis>Long job number (6 digits)</emphasis></para>
15264</listitem>
15265
15266<listitem>
15267<para>
15268<literal>fifo</literal> FLAG <emphasis>enforce FIFO order for reception</emphasis></para>
15269</listitem>
15270
15271<listitem>
15272<para> <literal>lpd_listen_port=</literal><emphasis><application/lpd/ will listen on this port </emphasis></para>
15273</listitem>
15274
15275<listitem>
15276<para> <literal>incoming_control_filter=</literal><emphasis>filter to modify incoming job control file </emphasis></para>
15277</listitem>
15278
15279<listitem>
15280<para> <literal>translate_incoming_format=</literal><emphasis>change data file formats</emphasis></para>
15281</listitem>
15282
15283<listitem>
15284<para> <literal>accounting_fixupname=</literal><emphasis>change accounting name infomration</emphasis></para>
15285</listitem>
15286
15287</itemizedlist>
15288
15289<para>
15290When a print job is received,
15291the <application/lpd/ server will assign a job number to the
15292new job.  Historically these have been in the range of 0 to 999,
15293but the
15294<literal/longnumber/
15295option allows numbers from 0 to 999,999 to be assigned.
15296The server then checks to see that all of the data files for a job have been
15297transferred correctly.
15298</para>
15299
15300<para>
15301The <literal/fifo/ flag forces all jobs receieved from a particular
15302host to be processed in First In, First Out (fifo) order.
15303No new jobs will be processed until the incoming job has been released
15304into the spool queue.
15305</para>
15306
15307<para>
15308If an incoming control file filter is specified,
15309then the incoming job's control file will be passed through the
15310<literal/incoming_control_filter/
15311filter if it is specified.
15312This allows the modification of the control file.
15313</para>
15314<para>
15315The majority of control file modifications are simple job file format
15316changes.
15317The
15318<literal/translate_incoming_format/ option provides a simple
15319way to do this.
15320See the
15321<emphasis remap=tt>
15322<link linkend="translateformat">translate_format</link>
15323</emphasis>
15324for details.
15325</para>
15326
15327<para>
15328The <literal/accounting_namefixup/ option was introduced to allow
15329a simple mapping of host and user names to names to be used for
15330accounting purposes.
15331By convention,
15332the <literal/R/ field in the job control file specifies the name
15333to be used for accounting purposes.
15334<informalexample>
15335<screen>
15336accounting_namefixup=list[,list]*
15337   where list is:   host(,host*)[=user(,user*)]
15338</screen>
15339</informalexample>
15340The incoming job is checked to see if the originating host
15341is in the list of hosts;  the first matching one found is used.
15342</para>
15343<para>
15344Each host list has the format: host,host... where host has the
15345same format used for the <literal/oh/ and other host name matching
15346options.  You can  use '!host' to invert matching.  For example:
15347<literal/host1,127.*,!somehost/.
15348</para>
15349<para>
15350When a host match is found,  the name to be used for the user
15351is determined from the user list; if none is specified then no
15352changes are made.  Each entry in the user list has the format
15353<literal/${option}/
15354or
15355<literal/name/; the
15356<literal/${option}/
15357values are extracted from
15358the control file (capital letters) or printcap/configuration
15359information (lower case letters/names).  The first non-empty
15360value list value used.
15361For example, the
15362<literal/${R},${L},${accounting_name},anon/
15363will select the control file 'R' option value,
15364then the 'L' option value,
15365then the printcap/config option 'accounting_name' value,
15366and then finally the 'anon' value.
15367</para>
15368<para>
15369The control file is then passed through the
15370<literal/router/ routing filter.
15371This allows the incoming job to be redirected to one or more
15372print queues.
15373For details about all of the capabilities of the routing filter,
15374see
15375<link linkend="destinations">Dynamic Routing</link>.
15376</para>
15377
15378<para>
15379Finally,
15380the <application/lpd/ server is requested to start a spooling process
15381that will print the newly arrived job.
15382</para>
15383
15384</sect1>
15385
15386<sect1 id="spoolq"><title>Spool Queue Processing </title>
15387
15388<para>Options used:
15389<itemizedlist>
15390
15391<listitem>
15392<para> <literal>lpd_force_poll=</literal><emphasis>Force <application/lpd/ to periodically poll print queues </emphasis></para>
15393</listitem>
15394
15395<listitem>
15396<para>
15397<literal>lpd_poll_time=</literal><emphasis>Time between polls</emphasis></para>
15398</listitem>
15399
15400<listitem>
15401<para>
15402<literal>max_servers_active=</literal><emphasis>Maximum number of active servers</emphasis></para>
15403</listitem>
15404
15405</itemizedlist>
15406</para>
15407
15408<para>When the <application>lpd</application> server starts,
15409it will fork a set of subserver processes,
15410each which will handle an individual queue.</para>
15411
15412<para>If a system has a large number of queues,
15413then this forking operation may result in the <application>lpd</application> server
15414exhausting the process resources.
15415To control this,  the
15416<literal>max_servers_active</literal> value restricts the number of active
15417children to the specified value.
15418If this value is 0,
15419then 50% of the maximum system processes value will be used.</para>
15420
15421<para>Due to the limits on the number of processes,
15422there may be times when a job is placed in a queue,
15423but the <application>lpd</application> server is unable to start handling the job.
15424When all of the children of the main <application>lpd</application> server have
15425exited,
15426the server starts a timer.
15427After <literal>lpd_poll_time</literal> seconds,  it will scan the queues,
15428looking for jobs to process,
15429and starts a process to service them.
15430If it does not find any jobs it remains idle.</para>
15431
15432<para>The <literal>lpd_force_poll</literal> flag causes the server to periodically
15433poll the queues.
15434This is useful when there is a high possibility that jobs could fail to be
15435printed due to high loads on the server.</para>
15436
15437</sect1>
15438
15439<sect1 id="opendevice"><title>Opening the Output Device
15440
15441</title>
15442
15443<para>Options used:
15444<itemizedlist>
15445
15446<listitem>
15447<para>
15448<literal>achk</literal> FLAG <emphasis>Accounting check at start</emphasis></para>
15449</listitem>
15450
15451<listitem>
15452<para> <literal>af=</literal><emphasis>Accounting File</emphasis></para>
15453</listitem>
15454
15455<listitem>
15456<para>
15457<literal>ar</literal> FLAG <emphasis>Remote printer accounting enabled</emphasis></para>
15458</listitem>
15459
15460<listitem>
15461<para> <literal>as=</literal><emphasis>Accounting at start</emphasis></para>
15462</listitem>
15463
15464<listitem>
15465<para>
15466<literal>connect_grace=</literal><emphasis>Time between jobs</emphasis></para>
15467</listitem>
15468
15469<listitem>
15470<para>
15471<literal>connect_interval=</literal><emphasis>Connection interval</emphasis></para>
15472</listitem>
15473
15474<listitem>
15475<para>
15476<literal>connect_timeout=</literal><emphasis>Connection timeout</emphasis></para>
15477</listitem>
15478
15479<listitem>
15480<para> <literal>control_filter=</literal><emphasis>Control file filter</emphasis></para>
15481</listitem>
15482
15483<listitem>
15484<para>
15485<literal>ff=</literal><emphasis>form feed</emphasis></para>
15486</listitem>
15487
15488<listitem>
15489<para>
15490<literal>fo</literal> FLAG <emphasis>form feed on open</emphasis></para>
15491</listitem>
15492
15493<listitem>
15494<para>
15495<literal>la</literal> FLAG <emphasis>Local printer accounting enabled</emphasis></para>
15496</listitem>
15497
15498<listitem>
15499<para> <literal>ld=</literal><emphasis>leader on open (initialization string)</emphasis></para>
15500</listitem>
15501
15502<listitem>
15503<para>
15504<literal>lk</literal> FLAG <emphasis>Lock IO device</emphasis></para>
15505</listitem>
15506
15507<listitem>
15508<para> <literal>lp=</literal><emphasis>IO device pathname</emphasis></para>
15509</listitem>
15510
15511<listitem>
15512<para>
15513<literal>nb</literal> FLAG <emphasis>Nonblocking device open</emphasis></para>
15514</listitem>
15515
15516<listitem>
15517<para>
15518<literal>network_connect_grace=</literal><emphasis>Interval in secs between jobs</emphasis></para>
15519</listitem>
15520
15521<listitem>
15522<para> <literal>of=</literal><emphasis>of filter</emphasis></para>
15523</listitem>
15524
15525<listitem>
15526<para>
15527<literal>retry_econnrefused</literal> FLAG <emphasis>Retry if open failed</emphasis></para>
15528</listitem>
15529
15530<listitem>
15531<para>
15532<literal>retry_nolink</literal> FLAG <emphasis>Retry if open failed</emphasis></para>
15533</listitem>
15534
15535<listitem>
15536<para>
15537<literal>rm=</literal><emphasis>the remote machine to send the job to</emphasis></para>
15538</listitem>
15539
15540<listitem>
15541<para>
15542<literal>rp=</literal><emphasis>the remote print queue to send the job to</emphasis></para>
15543</listitem>
15544
15545<listitem>
15546<para>
15547<literal>rw</literal> FLAG <emphasis>device opened RW flag</emphasis></para>
15548</listitem>
15549
15550<listitem>
15551<para> <literal>server_tmp_dir=</literal><emphasis>temporary directory</emphasis></para>
15552</listitem>
15553
15554</itemizedlist>
15555
15556Sequence of Operations:
15557<orderedlist>
15558
15559<listitem>
15560<para>During the server operations,
15561it will try to create temporary files in the print queue spool directory.
15562If this is not desirable,
15563it will create them in the <literal>server_tmp_dir</literal> directory.</para>
15564</listitem>
15565
15566<listitem>
15567<para>If the accounting file specified by
15568<literal>af</literal>
15569exists,
15570it is opened (af_fd) and the af_fd is passed as file descriptor
155713 to all filters.
15572If the
15573<literal>af</literal>
15574value has the form <literal>af=|/program</literal>
15575then the program is started and the program <acronym/STDIN/ is used as af_fd.
15576If the
15577<literal>af</literal>
15578value has the form <literal>af=host%port</literal>,
15579then a TCP/IP connection to the corresponding port on the remote host
15580is made and the port used as af_fd.
15581In the latter two cases,  the filter <acronym/STDIN/ (file descriptor 0)
15582is actually opened read/write, and is used when information is needed
15583from the accounting filter or remote server.
15584See
15585
15586<link linkend="accountingserver">Accounting Printcap Options</link>
15587
15588for more information on the &LPRng; accounting support.</para>
15589</listitem>
15590
15591<listitem>
15592<para>
15593<anchor id="accountstart">
15594If
15595<literal>la</literal>
15596(local accounting) is true and we are printing a job
15597or
15598<literal>ar</literal>
15599(remote accounting) is true and we are transferring a job,
15600the
15601<literal>as</literal>
15602value is examined.
15603If it is a filter (program) specification,
15604then the program is started with its <acronym/STDIN/ attached to
15605<filename>/dev/null</filename>, <acronym/STDOUT/ will be read by the print spooler,
15606<acronym/STDERR/ output will be written to the error log.
15607The lpd program will wait until the accounting filter program terminates,
15608and examine the error code for action, as for the other filters
15609(see
15610
15611<link linkend="errorcodes">errorcodes</link>
15612 below).
15613If the exit status is 0,
15614(JSUCC) then the printing process will continue,
15615if JHOLD the job will be held,
15616if JREMOVE the job will be removed,
15617if JFAIL the job processing will terminate with a JFAIL indication,
15618otherwise
15619the job processing will terminate with a JABORT indication.</para>
15620</listitem>
15621
15622<listitem>
15623<para>If the accounting filter exited with a JSUCC (no error code)
15624and the
15625<literal>achk</literal>
15626(accounting check) flag is set,
15627the line read from the accounting filter <acronym/STDOUT/ will be examined.
15628This line should be
15629<literal>accept</literal>,
15630<literal>hold</literal>,
15631<literal>fail</literal>,
15632<literal>remove</literal>,
15633otherwise the job processing terminates with a JABORT indication.
15634An
15635<literal>accept</literal>
15636will allow the job to be printed,
15637<literal>hold</literal>
15638will hold the job,
15639<literal>fail</literal>
15640will cause the job to fail,
15641<literal>remove</literal>
15642will cause the job to be removed.</para>
15643</listitem>
15644
15645<listitem>
15646<para>If the
15647<literal>connect_grace</literal>
15648value is non-zero and the server is opening a device or
15649<literal>network_connect_grace</literal> is non-zero and a network connection
15650is being made,
15651the server will pause the specified time.
15652This is to accommodate devices which need a recovery time between jobs.</para>
15653</listitem>
15654
15655<listitem>
15656<para>The
15657<literal>lp</literal>
15658option is checked to determine the type of IO device.
15659<informaltable frame=all>
15660<tgroup cols=2 align=left rowsep=1 colsep=1>
15661<thead>
15662<row><entry>Format</entry><entry>Meaning</entry></row>
15663</thead>
15664<tbody>
15665<row><entry><filename>/pathname</filename></entry><entry>Absolute pathname of IO device</entry></row>
15666<row><entry><literal>pr@host</literal></entry><entry>transfer to
15667<literal>pr</literal>
15668on remote
15669<literal>host</literal></entry></row>
15670<row><entry><literal>host%port</literal></entry><entry>open a TCP/IP connection to port on host. host can be name or IP address</entry></row>
15671<row><entry><literal>|filter</literal></entry><entry>run the filter program; it <acronym/STDIN/ will be used as device</entry></row>
15672</tbody>
15673</tgroup>
15674</informaltable>
15675</para>
15676</listitem>
15677
15678<listitem>
15679<para>The IO device specified by
15680<literal>lp</literal>
15681is opened write-only or read-write if the
15682<literal>rw</literal>
15683flag is true, and the resulting file descriptor is io_fd.
15684If the
15685<literal>nb</literal>
15686flag is set,
15687a non-blocking open will be done as well.
15688If the
15689<literal>lk</literal>
15690(lock device) flag is true,
15691the device will be locked against use by other <application/lpd/ servers.</para>
15692</listitem>
15693
15694<listitem>
15695<para>If a
15696<literal>host%port</literal>
15697combination,
15698a TCP/IP connection will be opened to the remote port and the connection will
15699be used as io_fd.</para>
15700</listitem>
15701
15702<listitem>
15703<para>If a filter program is specified,
15704the filter program will be run and the <acronym/STDIN/ of the filter will be
15705used as the device file descriptor.</para>
15706</listitem>
15707
15708<listitem>
15709<para>If a <literal>rp@rm</literal> combination,
15710or none of the above combinations are true and the
15711<literal>rm</literal>
15712and
15713<literal>rp</literal>
15714values are non-zero,
15715then the job will be transferred to a remote printer.
15716The type of operation will be a job transfer,
15717rather than printing operation.</para>
15718</listitem>
15719
15720<listitem>
15721<para>If the <literal>connect_timeout</literal> value is non-zero,
15722a timeout is setup for the device or socket open.
15723If the device or connection open does not succeed within the timeout,
15724then the open operation fails.</para>
15725</listitem>
15726
15727<listitem>
15728<para>If a connection is to a network address
15729(i.e. - <function>connect()</function> system call)
15730and the connection attempt fails with an <acronym>ECONNREFUSED</acronym>
15731error,
15732if the <literal>retry_econnrefused</literal>
15733flag is set then the connection attempt is retried,
15734but this time using an alternative port number.
15735See
15736
15737<link linkend="rfc1179ref">RFC1179</link>
15738 for details.
15739This is repeated until all of the possible originating port numbers
15740are exhausted.</para>
15741</listitem>
15742
15743<listitem>
15744<para>If the open or connect operation fails,
15745and the <literal>retry_nolink</literal> flag is set,
15746then the server will pause for a minimum of
15747<literal>connect_grace</literal> plus a multiple of
15748<literal>connect_interval</literal> seconds
15749based on the number of attempts
15750before retrying the open operation.
15751Note that the interval may increase as the number of attempts
15752increases.</para>
15753</listitem>
15754
15755<listitem>
15756<para>If printing a job and the
15757<literal remap=tt>:of</literal>
15758filter is specified,
15759it is created with its <acronym/STDOUT/ (fd 1) attached to the io_fd.
15760Its stdin (of_fd) will be used in the steps listed below.
15761If there is no
15762<literal remap=tt>:of</literal>
15763filter,
15764then the of_fd value will be the io_fd descriptor.</para>
15765</listitem>
15766
15767<listitem>
15768<para>If transferring a job and the <literal>control_filter</literal> option is specified,
15769then the program specified by the <literal>control_filter</literal>
15770value will be run. It will have its <acronym/STDIN/ set to the control file,
15771and its <acronym/STDOUT/ output will be used as the new value of the control file
15772to transfer to the remote host.
15773See
15774
15775<link linkend="filteroptions">Filter Command Line Options and Environment Variables</link>
15776
15777for details of options passed to the control filter,
15778and
15779
15780<link linkend="errorcodes">errorcodes</link>
15781 for the exit codes of the filter.</para>
15782</listitem>
15783
15784<listitem>
15785<para>If the operation is a job transfer, the operation proceeds as outlined in
15786
15787<link linkend="rfc1179ref">RFC1179</link>,
15788and then the
15789
15790<link linkend="normalterm">Normal Termination</link>
15791 operations are
15792carried out.</para>
15793</listitem>
15794
15795<listitem>
15796<para>If the operation is a print operation
15797and the
15798<literal>ld</literal>
15799(leader on open) value is provided,
15800the string
15801is translated (escapes removed)
15802and written to the of_fd file descriptor.</para>
15803</listitem>
15804
15805<listitem>
15806<para>If the
15807<literal>fo</literal>
15808(form feed on open) flag is true, then the
15809<literal>ff</literal>
15810(form feed) string
15811is translated (escapes removed)
15812and written to the of_fd file descriptor.</para>
15813</listitem>
15814
15815</orderedlist>
15816</para>
15817
15818</sect1>
15819
15820<sect1 id="bannerprinting"><title>Printing Banners </title>
15821
15822<para>Options used:
15823<itemizedlist>
15824
15825<listitem>
15826<para>
15827<literal>ab</literal> FLAG <emphasis>Always print banner (default FALSE)</emphasis></para>
15828</listitem>
15829
15830<listitem>
15831<para> <literal>be=</literal><emphasis>End banner generator program</emphasis></para>
15832</listitem>
15833
15834<listitem>
15835<para> <literal>bl=</literal><emphasis>Short banner line format</emphasis></para>
15836</listitem>
15837
15838<listitem>
15839<para> <literal>bp=</literal><emphasis>Banner generator program</emphasis></para>
15840</listitem>
15841
15842<listitem>
15843<para> <literal>bs=</literal><emphasis>Start banner generator</emphasis></para>
15844</listitem>
15845
15846<listitem>
15847<para> <literal>generate_banner</literal> FLAG <emphasis>Generate banner for forwarded jobs</emphasis></para>
15848</listitem>
15849
15850<listitem>
15851<para>
15852<literal>hl</literal> FLAG <emphasis>Banner (header) Last</emphasis></para>
15853</listitem>
15854
15855<listitem>
15856<para> <literal>of=</literal><emphasis>Banner and File Separator Filter</emphasis></para>
15857</listitem>
15858
15859<listitem>
15860<para>
15861<literal>sb</literal> FLAG <emphasis>Short banner (default FALSE)</emphasis></para>
15862</listitem>
15863
15864<listitem>
15865<para>
15866<literal>sh</literal> FLAG <emphasis>Suppress header (banners) (default FALSE)</emphasis></para>
15867</listitem>
15868
15869</itemizedlist>
15870</para>
15871
15872<para>Banner printing is one of the more complicated configuration options
15873of &LPRng;.
15874This is due mainly to historical evolution of the software,
15875as well as a lack of a well defined standard for
15876filter responsibilities.
15877In the original BSD print spoolers,
15878the philosophy was that banner printing should be delegated to the
15879filters,
15880as they were the most aware of the capabilities of the printers.
15881This required an
15882<emphasis>out of band</emphasis>
15883method to convey banner printing information to the filter,
15884and resulted in a complicated interface.
15885The original interface was:
15886<orderedlist>
15887
15888<listitem>
15889<para>The filter doing banner printing was invoked as a special
15890<literal remap=tt>:of</literal>
15891filter,
15892or passed a special flag.</para>
15893</listitem>
15894
15895<listitem>
15896<para>The print spooling software would send a special
15897<emphasis remap=bf>single line</emphasis>
15898of information telling it what the banner information should be.
15899Note that this line was never documented except for the source code,
15900and was inconsistent from version to version.
15901Also,
15902there was no indication of what to do with additional lines,
15903if any.</para>
15904</listitem>
15905
15906<listitem>
15907<para>The filter would generate the banner,
15908discard the line,
15909and then pass other lines to the output device.</para>
15910</listitem>
15911
15912</orderedlist>
15913</para>
15914
15915<para>Adding to the confusion,
15916the original print spoolers had a
15917<literal remap=tt>:sh</literal>
15918(suppress header or banner)
15919flag,
15920which was supposed to suppress banner printing.
15921It did this by having the print spooler not generate the magic banner
15922information line.</para>
15923
15924<para>A more sophisticated banner printing system would allow the
15925print spooler software to generate the banner,
15926and would then have the
15927<literal remap=tt>:of</literal>
15928filter act as a pass through.
15929Thus, we need configure the
15930<literal remap=tt>:of</literal>
15931filter NOT to use the first
15932line as banner printing information,
15933and to pass through all information to the device.</para>
15934
15935<para>Complicating this whole mess is the
15936<literal>ld</literal>
15937 (leader option)
15938and
15939<literal>tr</literal>
15940 (trailer option)
15941which is a string sent to the output device (<literal remap=tt>:of</literal>
15942filter)
15943when the device (filter) is initialized or terminated.
15944This can sometimes be interpreted as the banner line,
15945leading to unexpected results.</para>
15946
15947<para>Sequence of Operations:
15948<orderedlist>
15949
15950<listitem>
15951<para>If the
15952<literal>sh</literal>
15953(suppress header) flag is true, no banner is
15954printed,
15955and the actions in this section are skipped.
15956No <emphasis>banner information line</emphasis>
15957is generated for the
15958<literal remap=tt>:of</literal>
15959filter,
15960and no banner printing program is invoked.
15961If there is an
15962<literal remap=tt>:of</literal>
15963filter and it is expecting such a line
15964and you have
15965<literal>ld</literal>
15966or
15967<literal>tr</literal>
15968information then
15969you may get unexpected results
15970(actually, catastrophic failure is a better term, but I digress).</para>
15971</listitem>
15972
15973<listitem>
15974<para>If the
15975<literal>hl</literal>
15976(header last) flag is true the banner is printed at the end
15977of the job
15978and the actions in this section are done at the end of the job.</para>
15979</listitem>
15980
15981<listitem>
15982<para>If the user does not want banner pages she can use the
15983<command>lpr -h </command> option.
15984This will cause the <application>lpr</application> program
15985to delete the
15986<literal remap=tt>L</literal>
15987(banner name) line in the control file.
15988If there is no
15989<literal remap=tt>L</literal>
15990line in the control file
15991and
15992<literal>ab</literal>
15993(always print a banner) is false
15994(the default),
15995then no banner is printed
15996and the other actions in this section are skipped.
15997If
15998<literal>ab</literal>
15999is true
16000and the
16001<literal remap=tt>L</literal>
16002line is missing then the
16003<literal remap=tt>N</literal>
16004(user login name) is used;
16005if it is missing as well,
16006then ANONYMOUS is used for the user name.</para>
16007</listitem>
16008
16009<listitem>
16010<para>If a banner printing program is specified by
16011<literal>bp</literal>,
16012<literal>bs</literal>,
16013or
16014<literal>be</literal>
16015options,
16016then &LPRng; will invoke the
16017program to generate a banner and then send the generated
16018banner to the printer
16019via the
16020<literal remap=tt>:of</literal>
16021filter.
16022The banner printing program will be invoked using
16023the standard filter command line flags
16024(see
16025
16026<link linkend="filteroptions">Filter Command Line Options and Environment Variables</link>
16027
16028for details),
16029with is <acronym/STDIN/ attached to /dev/null
16030and <acronym/STDOUT/ attached to a file to hold the output banner.</para>
16031</listitem>
16032
16033<listitem>
16034<para>If no banner printing program is specified
16035and the
16036<literal>sb</literal>
16037(short banner) option is TRUE (default is true),
16038then the <literal>bl=...</literal> (banner line) option value
16039is expanded and sent to the <literal>of_fd</literal>  (<literal remap=tt>:of</literal>
16040filter or
16041device.
16042The default
16043<literal>bl</literal>
16044value is:
16045<literal>bl=$-'C:$-'n Job: $-'J Date: $-'t</literal>.
16046Using our example, this will get translated to:
16047<informalexample>
16048<screen>papowell:A Job: file1 file2 Date: Thu Nov 27 23:02:04 PST 1997</screen>
16049</informalexample>
16050</para>
16051</listitem>
16052
16053<listitem>
16054<para>If no banner printing program is specified and we have <literal>sb@</literal>
16055(no short banner)
16056then we skip banner generation,
16057i.e. - we do <emphasis>not</emphasis>
16058send a banner generation line
16059to the output (<literal remap=tt>:of</literal>
16060filter).</para>
16061</listitem>
16062
16063<listitem>
16064<para>If the queue is a normal forwarding queue,
16065then the
16066<literal>generate_banner</literal>
16067option will invoke the
16068<literal>bp</literal>,
16069<literal>bs</literal>
16070or
16071<literal>be</literal>
16072program as appropriate to create a banner page file which is then made the
16073first (default) or last (<literal>hl</literal>
16074flag or <literal>be=...</literal> present)
16075file in a job.
16076This option has no effect in other types of queues.
16077See the
16078<emphasis remap=tt>
16079<link linkend="translateformat">translate_format</link>
16080</emphasis>
16081option as well.</para>
16082</listitem>
16083
16084</orderedlist>
16085</para>
16086
16087</sect1>
16088
16089<sect1 id="printingjob"><title>Printing Job Files
16090
16091
16092</title>
16093
16094<para>Options used:
16095<itemizedlist>
16096
16097<listitem>
16098<para> <literal>Xf=</literal><emphasis>Format Filter</emphasis></para>
16099</listitem>
16100
16101<listitem>
16102<para>
16103<literal>sf</literal> FLAG <emphasis> Suppress Form Feed Separators</emphasis></para>
16104</listitem>
16105
16106<listitem>
16107<para> <literal>if=</literal><emphasis>Default F Format Filter</emphasis></para>
16108</listitem>
16109
16110<listitem>
16111<para> <literal>pr=</literal><emphasis>pr formatting program</emphasis></para>
16112</listitem>
16113
16114<listitem>
16115<para> <literal>send_job_rw_timeout=</literal><emphasis> print job read/write timeout </emphasis></para>
16116</listitem>
16117
16118<listitem>
16119<para> <literal>send_query_rw_timeout=</literal><emphasis> status query operation read/write timeout </emphasis></para>
16120</listitem>
16121
16122<listitem>
16123<para>
16124<literal>sf</literal> FLAG <emphasis>Suppress form feed between job files</emphasis></para>
16125</listitem>
16126
16127</itemizedlist>
16128</para>
16129
16130<para>Sequence of Operations:
16131for each job in listed in the control file,
16132the following operations are done in turn.
16133<orderedlist>
16134
16135<listitem>
16136<para>If there is an
16137<literal remap=tt>:of</literal>
16138filter present,
16139the suspend string
16140<literal>\031\001</literal>
16141is written to of_fd
16142and the no further action is taken until the of filter is suspended.</para>
16143</listitem>
16144
16145<listitem>
16146<para>The control file line for the job is examined,
16147and the first letter of the data file specification is used as the format.</para>
16148</listitem>
16149
16150<listitem>
16151<para>If the format is
16152<literal remap=tt>p</literal>,
16153the job is first processed by the program specified by the
16154<literal>pr</literal>
16155program,
16156and the program output used as the print file.</para>
16157</listitem>
16158
16159<listitem>
16160<para>If the format is
16161<literal remap=tt>f</literal>,
16162<literal remap=tt>l</literal>,
16163or
16164<literal remap=tt>p</literal>
16165then the
16166<literal>:if</literal>
16167filter is used,
16168otherwise the keyword
16169<literal>Xf</literal>
16170is used.
16171Note that certain formats such as
16172<literal>p, a, l</literal>, may not be used as formats.</para>
16173</listitem>
16174
16175<listitem>
16176<para>The filter program is started with an appropriate set of command line options
16177(see
16178
16179<link linkend="filteroptions">Filter Command Line Options and Environment Variables</link>
16180),
16181and with its <acronym/STDOUT/ attached to the printing device (io_fd),
16182<acronym/STDERR/ to a pipe which results in the output being written
16183to the status file.
16184If debugging is enabled,
16185then the <acronym/STDERR/ output is also written to the error log file (lf).</para>
16186</listitem>
16187
16188<listitem>
16189<para>When doing a read/write operation to a device or remote system,
16190a timeout can be specified.
16191When doing a print or job transfer operation,
16192the <literal>send_job_rw_timeout</literal> value is used.
16193When doing a status or query operation,
16194the <literal>send_query_rw_timeout</literal> value is used.
16195If a write or write operation does not complete within
16196the specified timeout seconds, then we have an error
16197condition and job processing or the query operation
16198is terminated with JFAIL status.
16199If the timeout value is 0, then no timeout is done.</para>
16200</listitem>
16201
16202<listitem>
16203<para><anchor id="errorcodes">
16204<application>lpd</application> will then wait for the filter to exit.
16205The following exit codes are used by <application>lpd</application>:
16206<informalexample>
16207<screen>Key      Value   Meaning
16208JSUCC    0       Successful
16209JFAIL    1, 32   Failed - retry later
16210JABORT   2, 33   Abort - terminate queue processing
16211JREMOVE  3, 34   Failed - remove job
16212(Unused) 4, 35
16213(Unused) 5, 36
16214JHOLD    6, 37   Hold this job - reprint later
16215JNOSPOOL 7, 38   No spooling to this queue
16216JNOPRINT 8, 39   No printing from this queue
16217JSIGNAL  9,  40   Killed by unrecognized signal
16218JFAILNORETRY 10, 41 Failed, no retry
16219Other            Abort - terminate queue processing</screen>
16220</informalexample>
16221</para>
16222</listitem>
16223
16224<listitem>
16225<para>If the filter exit status was JSUCC (0), or no error indicated,
16226then processing will continue otherwise the job termination takes
16227(see
16228
16229<link linkend="abnormalterm">Abnormal Termination</link>
16230).</para>
16231</listitem>
16232
16233<listitem>
16234<para>If the
16235<literal remap=tt>:of</literal>
16236filter is present,
16237then it is reactivated with a <command>kill -CONT</command> signal.</para>
16238</listitem>
16239
16240<listitem>
16241<para>The the
16242<literal>sf</literal>
16243(suppress FF print file separators )
16244is turned off a form feed is sent between each file of a job.</para>
16245</listitem>
16246
16247</orderedlist>
16248</para>
16249
16250</sect1>
16251
16252<sect1><title>Printing Banner At End of Job </title>
16253
16254<para>Options used:
16255<itemizedlist>
16256
16257<listitem>
16258<para>
16259<literal>hl</literal> FLAG <emphasis>Header (Banner) Last</emphasis></para>
16260</listitem>
16261
16262</itemizedlist>
16263</para>
16264
16265<para>The actions taken in this step are identical to those for the
16266
16267<link linkend="bannerprinting">Printing Banner</link>,
16268with the exception that the
16269<literal>be</literal>
16270(end banner program) is used to select the banner generation program
16271rather than the
16272<literal>bs</literal>
16273(start banner program).</para>
16274
16275<para>If we have
16276<literal>hl</literal>
16277true,
16278then we print a banner at the end of the job,
16279rather than start.</para>
16280
16281</sect1>
16282
16283<sect1 id="normalterm"><title>Normal Termination
16284</title>
16285
16286<para>Options used:
16287<itemizedlist>
16288
16289<listitem>
16290<para>
16291<literal>fq</literal> FLAG <emphasis>Form Feed on Close</emphasis></para>
16292</listitem>
16293
16294<listitem>
16295<para>
16296<literal>la</literal> FLAG <emphasis>Local Printer Accounting</emphasis></para>
16297</listitem>
16298
16299<listitem>
16300<para> <literal>tr=</literal><emphasis>Trailer on Close</emphasis></para>
16301</listitem>
16302
16303<listitem>
16304<para> <literal>ae=</literal><emphasis>Accounting at end</emphasis></para>
16305</listitem>
16306
16307<listitem>
16308<para> <literal>save_when_done</literal> FLAG <emphasis>Save when done</emphasis></para>
16309</listitem>
16310
16311<listitem>
16312<para> <literal>save_on_error</literal> FLAG <emphasis>Do not delete on error</emphasis></para>
16313</listitem>
16314
16315<listitem>
16316<para> <literal>done_jobs=N</literal><emphasis>Save status of last N jobs</emphasis></para>
16317</listitem>
16318
16319<listitem>
16320<para> <literal>wait_for_eof</literal> FLAG <emphasis>Wait for EOF before closing device</emphasis></para>
16321</listitem>
16322
16323<listitem>
16324<para> <literal>socket_linger</literal><emphasis>socket linger timeout</emphasis></para>
16325</listitem>
16326
16327<listitem>
16328<para> <literal>half_close</literal> FLAG <emphasis>use shutdown() and not close()</emphasis></para>
16329</listitem>
16330
16331</itemizedlist>
16332</para>
16333
16334<para>Sequence of Operations:
16335<orderedlist>
16336
16337<listitem>
16338<para>If we are printing and the
16339<literal>fq</literal>
16340flag is set and the
16341<literal>sf</literal>
16342(suppress interfile FF) flag is set,
16343then the
16344<literal>ff</literal>
16345(form feed) string
16346will be interpreted and sent to the of_fd.</para>
16347</listitem>
16348
16349<listitem>
16350<para>If we are printing, the
16351<literal>tr</literal>
16352(trailer) string
16353will be interpreted and sent to the of_fd.</para>
16354</listitem>
16355
16356<listitem>
16357<para>If printing and the
16358<literal>la</literal>
16359(local printer accounting) flag is set
16360or transferring a job and the
16361<literal>ar</literal>
16362(remote accounting) flag is set,
16363the
16364<literal>ae</literal>
16365is examined and accounting is done as described
16366for the
16367<emphasis remap=tt>
16368<link linkend="accountstart">as</link>
16369 field.</emphasis></para>
16370</listitem>
16371
16372<listitem>
16373<para>If the
16374<literal remap=tt>:of</literal>
16375filter is present,
16376its <acronym/STDIN/ is closed,
16377and the <application>lpd</application> server waits for it to exit.
16378The exit status is used as described above.</para>
16379</listitem>
16380
16381<listitem>
16382<para>If the device is a socket or network connection,
16383the socket linger time is set to
16384<literal>socket_linger</literal> value if nonzero.
16385</para></listitem>
16386
16387<listitem><para>
16388If the <literal/half_shut/ flag is set,
16389then a <literal/shutdown(fd,WR_DONE)/ will be done on the connection.
16390This tells the TCP/IP stack that all data transmission has been
16391completed.  Errors or other information can still be read from the
16392connection.
16393If the <literal/half_shut/ flag is clear,
16394then a <literal/close(fd)/ will be done and
16395no errors or other information will be read.
16396</para></listitem>
16397
16398<listitem><para>
16399If the <literal>wait_for_eof</literal> option is true (default)
16400then a read is done on the connection until an EOF is found.
16401The device (io_fd) is then closed.</para>
16402</listitem>
16403
16404<listitem>
16405<para>The job is marked as completed in the spool queue.</para>
16406</listitem>
16407
16408<listitem>
16409<para>
16410If the <literal>save_when_done</literal> flag is clear
16411and the <literal>done_jobs</literal> and
16412<literal>done_jobs_max_age</literal> values are zero (0), 
16413the job is removed.</para>
16414</listitem>
16415
16416<listitem>
16417<para>
16418If the <literal>done_jobs</literal> or
16419<literal>done_jobs_max_age</literal> values are nonzero,
16420the spool queue is periodically checked and for an excess number
16421of jobs or jobs with old status.
16422This action is suppressed if either the <literal/save_when_done/ or <literal/save_on_error/
16423flag is set.
16424</para>
16425</listitem>
16426
16427
16428</orderedlist>
16429</para>
16430
16431</sect1>
16432
16433<sect1 id="abnormalterm"><title>Abnormal Termination </title>
16434
16435<para>Options used:
16436<itemizedlist>
16437
16438<listitem>
16439<para> <literal>mail_from=</literal><emphasis>Mail from user name</emphasis></para>
16440</listitem>
16441
16442<listitem>
16443<para> <literal>mail_operator_on_error=</literal><emphasis>Mail to operator on error</emphasis></para>
16444</listitem>
16445
16446<listitem>
16447<para>
16448<literal>send_try=</literal><emphasis>Maximum printing or transfer attempts</emphasis></para>
16449</listitem>
16450
16451<listitem>
16452<para> <literal>save_on_error</literal> FLAG <emphasis>Do not delete on error</emphasis></para>
16453</listitem>
16454
16455<listitem>
16456<para> <literal>done_jobs=N</literal><emphasis>Save status of last N jobs</emphasis></para>
16457</listitem>
16458
16459<listitem>
16460<para> <literal>done_jobs_max_age=N</literal><emphasis>Remove status when older than N seconds</emphasis></para>
16461</listitem>
16462
16463<listitem>
16464<para> <literal>send_failure_action=</literal><emphasis>Action on Failure</emphasis></para>
16465</listitem>
16466
16467<listitem>
16468<para> <literal>sendmail=</literal><emphasis>sendmail path name and options</emphasis></para>
16469</listitem>
16470
16471<listitem>
16472<para> <literal>stop_on_abort</literal> FLAG <emphasis>Stop processing queue on filter abort</emphasis></para>
16473</listitem>
16474
16475</itemizedlist>
16476</para>
16477
16478<para>If the job processing terminates abnormally,
16479the following sequence of events occurs:
16480<orderedlist>
16481
16482<listitem>
16483<para>The job is marked as having an error during processing.</para>
16484</listitem>
16485
16486<listitem>
16487<para>The <application/lpd/ server will attempt to kill all filters and other associated processes
16488by sending a SIGINT and SIGCONT (<command>kill -INT</command> and <command>kill -CONT</command>)
16489to them.</para>
16490</listitem>
16491
16492<listitem>
16493<para>If there is a <literal>mail_operator_on_error</literal> value,
16494the specified operator will be mailed an error indication.
16495The
16496<literal>sendmail</literal>
16497option specifies the pathname of the
16498<emphasis>sendmail</emphasis>
16499program and the options needed to have it read
16500mail addresses from its standard input.
16501For example, <literal>sendmail=/usr/sbin/sendmail -oi -t</literal>
16502is a commonly used set of options.</para>
16503</listitem>
16504
16505<listitem>
16506<para>The <literal>mail_from</literal> value specifies the user name used for
16507mail origination.  If not specified, the default is to use the print spool
16508queue or printer name.</para>
16509</listitem>
16510
16511<listitem>
16512<para>If there is a <literal>send_failure_action</literal> specified,
16513then it is decoded and the corresponding action taken.
16514If the value is
16515<literal>remove</literal>,
16516<literal>hold</literal>,
16517<literal>abort</literal>,
16518or
16519<literal>retry</literal>,
16520then the job is removed, held, aborted, or retried.
16521If the value is <filename>|/program</filename>,
16522the program is executed and
16523the number of attempts are written to the filter <acronym/STDIN/.
16524The exit status of the filter will be used to determine the consequent actions.
16525That is, JSUCC (0) will be success, and the standard success action will
16526be taken;
16527JFAIL will cause retry,
16528JREMOVE will cause the job to be removed,
16529JHOLD will cause the job to be held,
16530JABORT or other status will abort processing.</para>
16531</listitem>
16532
16533<listitem>
16534<para>If the status is ABORT and the
16535<literal>stop_on_abort</literal>
16536flag is set,
16537then further processing of jobs is terminated.
16538The job is not removed from the queue.</para>
16539</listitem>
16540
16541<listitem>
16542<para>If the error status indicates removal,
16543the <literal>save_on_error</literal> flag is clear,
16544and the <literal>done_jobs</literal> and
16545<literal>done_jobs_max_age</literal> values are zero (0), 
16546then the job is removed from the spool queue.</para>
16547</listitem>
16548
16549<listitem>
16550<para>If the error status indicates that no further operations should
16551be performed on the queue,
16552then the <application>lpd</application> server will stop processing jobs.</para>
16553</listitem>
16554
16555<listitem>
16556<para>If the error code indicated that the job should be retried,
16557and the
16558<literal>send_try</literal> value is 0 or the number of attempts is less than
16559the <literal>send_try</literal> value,
16560then the job is retried.
16561Between each attempt to transfer a job to a remote site.
16562This pause will double after each attempt,
16563reaching a maximum of <literal>max_connect_interval</literal> seconds.
16564If <literal>max_connect_interval</literal> is 0, there is no limit on the interval value.</para>
16565</listitem>
16566
16567</orderedlist>
16568</para>
16569
16570</sect1>
16571
16572<sect1 id="bk"><title>Forwarding Jobs
16573</title>
16574
16575<para>Options:
16576<itemizedlist>
16577
16578<listitem>
16579<para>
16580<literal>bk</literal><emphasis>Berkeley compatible control file</emphasis></para>
16581</listitem>
16582
16583<listitem>
16584<para> <literal>bq_format=</literal><emphasis>format of filtered output</emphasis></para>
16585</listitem>
16586
16587<listitem>
16588<para> <literal>lpd_bounce</literal><emphasis>filter job and transfer output </emphasis></para>
16589</listitem>
16590
16591<listitem>
16592<para> <literal>control_filter=</literal><emphasis>Control file filter</emphasis></para>
16593</listitem>
16594
16595<listitem>
16596<para> <literal>control_file_line_order=</literal><emphasis>Control file line order</emphasis></para>
16597</listitem>
16598
16599<listitem>
16600<para> <literal>nline_after_file</literal><emphasis>N line after data file</emphasis></para>
16601</listitem>
16602
16603<listitem>
16604<para> <literal>send_data_first</literal><emphasis>send data files first</emphasis></para>
16605</listitem>
16606
16607</itemizedlist>
16608</para>
16609
16610<para>If a spool queue is doing store and forward operations,
16611then rather than printing a job the control files and data files
16612are sent to the remote printer.
16613In order to do this,
16614the following items must be arranged.
16615<itemizedlist>
16616
16617<listitem>
16618<para>If necessary,
16619the job must be processed by filters on the local host.</para>
16620</listitem>
16621
16622<listitem>
16623<para>The control file must be prepared and updated according to the
16624requirements of the remote site.</para>
16625</listitem>
16626
16627<listitem>
16628<para>A connection must be established to the remote site.</para>
16629</listitem>
16630
16631<listitem>
16632<para>The data files and control files must be transferred to the remote
16633site.</para>
16634</listitem>
16635
16636</itemizedlist>
16637</para>
16638
16639<para>One of the more serious problems is when a print spooler (LPR) program
16640does not generate print jobs in a manner compatible with a remote system.
16641While &LPRng; performs checks for improper implementations of RFC1179,
16642it will try to accept a job
16643even under the most severe abuse of the protocol.
16644However,
16645other spoolers are not so forgiving.
16646Some spoolers require that the contents of the control file
16647be in <emphasis remap=bf>exactly</emphasis>
16648the order that the original 1988 BSD <application/lpr/ software
16649generated them.
16650While some entries can be missing,
16651all the entries present in the file must be in an explicit order.</para>
16652
16653<para>The
16654<literal>bk</literal>
16655(Berkeley <application/lpd/ compatible control file) option
16656causes <application/lpr/ and <application/lpd/ to reformat the control file,
16657removing objectionable entries.
16658The control file of a job being sent to
16659a remote printer will have its control file entries restricted to
16660letters in (and the same order) as HPJCLIMWT1234.
16661You can use the <literal>control_file_line_order</literal> option to specify
16662an even more restricted set,
16663and use the <literal>nline_after_file</literal> option to have the file information
16664line (<literal remap=tt>N</literal>
16665value) come after the data file entry.</para>
16666
16667<para>However,
16668there are some very odd commercial implementations that require
16669<emphasis>more</emphasis>
16670information than is present.
16671To assist with this,
16672the <literal>control_filter</literal> option can be used.
16673This specifies a program that will process the control file
16674before it is sent to a remote destination.
16675The <literal>control_filter</literal> program is run with the standard set of
16676filter options.
16677<acronym/STDIN/ is attached to the control file and
16678the <acronym/STDOUT/ will be used as the control file value
16679sent to the remote host.</para>
16680
16681<para>The exit code of the
16682<literal>control_filter</literal>
16683is used to determine whether to proceed in processing.
16684See
16685
16686<link linkend="errorcodes">Errorcodes</link>
16687 for details.</para>
16688
16689<para>Sequence of Operations:
16690<orderedlist>
16691
16692<listitem>
16693<para>A copy of the control file information is made and
16694the copy will be modified during processing,
16695rather than the original.</para>
16696</listitem>
16697
16698<listitem>
16699<para>If the <literal>lpd_bounce</literal> option is specified
16700then a temporary file is created and the job is printed
16701using the procedures for printing to a device,
16702but to the file.
16703This includes all of the filter operations,
16704banners, and so forth.
16705The working copy of the control file is set to have the temporary
16706file as the data file to be sent to the remote destination,
16707and the data file format is set to the <literal>bq_format</literal> value.</para>
16708</listitem>
16709
16710<listitem>
16711<para>The control file is rewritten according to the requirements
16712of the routing information, if any.
16713For each destination in the routing information and each copy,
16714a new job identifier value will be generated.</para>
16715</listitem>
16716
16717<listitem>
16718<para>The control file is rewritten according to the
16719<literal>bk</literal>
16720and <literal>control_file_line_order</literal> options.
16721If a control filter is specified,
16722the control filter program is run
16723and the output of the program is used as the new control file.</para>
16724</listitem>
16725
16726<listitem>
16727<para>A connection is made to the remote host,
16728and the data and control files are transferred to the remote host
16729using the RFC1179 protocol.
16730If the <literal>send_data_first</literal> option is specified the data files
16731are sent first.</para>
16732</listitem>
16733
16734<listitem>
16735<para>If the job was sent successfully,
16736the job status is updated in the same manner as for a printed job.</para>
16737</listitem>
16738
16739</orderedlist>
16740</para>
16741
16742</sect1>
16743
16744<sect1 id="debugging"><title>Debugging </title>
16745
16746<para>Options used:
16747<itemizedlist>
16748
16749<listitem>
16750<para> <literal>debugging=</literal><emphasis>debugging options</emphasis></para>
16751</listitem>
16752
16753<listitem>
16754<para> <literal>full_time</literal> FLAG <emphasis>full or extended time format</emphasis></para>
16755</listitem>
16756
16757<listitem>
16758<para> <literal>ms_time_resolution</literal> FLAG <emphasis>millisecond time resolution</emphasis></para>
16759</listitem>
16760
16761<listitem>
16762<para> <literal>syslog_device=</literal><emphasis>syslog alternative device</emphasis></para>
16763</listitem>
16764
16765<listitem>
16766<para> <literal>use_info_cache</literal> FLAG <emphasis>cache printcap and other information</emphasis></para>
16767</listitem>
16768
16769</itemizedlist>
16770</para>
16771
16772<para>The &LPRng; software has a very powerful debugging capability.
16773Since most printing problems occur on remote systems where it is impossible
16774to run debuggers,  and since most systems do not do core dumps of SETUID ROOT
16775programs,
16776the &LPRng; software provides a very verbose set of log file trace messages.</para>
16777
16778<para>First,
16779serious errors or other information are logged using the
16780<function>syslog()</function> facilities.
16781If these are not present on a system,
16782then the messages are logged to the device specified by
16783<literal>syslog_device</literal>.</para>
16784
16785<para>For client programs, the debugging options are specified on the command
16786line and output is directed to <acronym/STDERR/.
16787For the <application>lpd</application> server,
16788debugging commands can be specified on the command line OR as the
16789<literal>db=options</literal> printcap value.
16790Output is directed to the log file (<literal>lf</literal>
16791option value, default log).</para>
16792
16793<para>A typical debug entry has the format
16794<literal>2,network+1,database</literal>.
16795This sets the general
16796debugging level to 2, network debugging to 1 and the database debugging level
16797to the default.  The following debugging options and levels are supported.
16798<itemizedlist>
16799
16800<listitem>
16801<para>nnn - general purpose debugging level</para>
16802</listitem>
16803
16804<listitem>
16805<para>network - network debugging</para>
16806</listitem>
16807
16808<listitem>
16809<para>database - database debugging</para>
16810</listitem>
16811
16812<listitem>
16813<para>receive - job or command reception debugging</para>
16814</listitem>
16815
16816<listitem>
16817<para>print - detailed job printing debugging</para>
16818</listitem>
16819
16820</itemizedlist>
16821</para>
16822
16823<para>The <literal>full_time</literal> flag forces the logging and other information
16824which has timestamps to have a full (year, month, day, etc.) timestamp.
16825The
16826<literal>ms_time_resolution</literal> flag forces millisecond time resolution
16827in the time stamp.
16828</para>
16829
16830<para>The <literal>use_info_cache</literal> (default ON) causes <application>lpd</application>
16831to cache printcap and configuration information.
16832This is desirable except when trying to change values in printcap files and
16833test the results.
16834By using <literal>use_info_cache@</literal> in the configuration information,
16835you can get immediate responses.
16836Also, see
16837
16838<link linkend="lpcreread">lpc reread</link>
16839
16840for another method.</para>
16841
16842</sect1>
16843</chapter>
16844
16845<chapter id=filters><title>Filters </title>
16846
16847<para>This section gives an overview of how &LPRng; uses filter programs,
16848and gives a detailed discussion of how the printcap options and
16849filters interact.</para>
16850
16851
16852<sect1><title>Filter Functions</title>
16853
16854<para>Print filters are one of the most powerful tools in BSD-style printer
16855systems.</para>
16856
16857<para>In general UNIX terms, a <emphasis>filter</emphasis>
16858is a program that takes its input
16859file(s), does something with it, and sends the result to its standard
16860output. Most UNIX utilities are designed as filters.
16861(But since you are a system manager, you should already know that :))</para>
16862
16863<para>In the context of a BSD-style print spooler (and also &LPRng;), the term
16864<emphasis>filter</emphasis>
16865refers to a program that processes file while it is
16866being transferred to a printer.</para>
16867
16868<para>The filter is executed with <acronym/STDIN/ reading from the file to be
16869printed
16870<acronym/STDOUT/ to the printer device or a temporary file.
16871<acronym/STDERR/ (file handle 2) is redirected to the status file,
16872and file handle3 to an accounting file or program.</para>
16873
16874<para>A filter can be as simple as a <acronym>LF</acronym> to <filename>CR/LF</filename>
16875translator,
16876or it can incorporate a complete
16877accounting system, automatic file type translations,
16878or even redirect the job to another printing system.</para>
16879
16880<para>The
16881<application>lpf</application>
16882filter supplied as part of the &LPRng; distribution is a
16883a very simple CR to CR/LF conversion filter.
16884The
16885<application remap=tt>ifhp</application>
16886filter provides support for more complex PostScript,
16887PCL,
16888and text printers.</para>
16889
16890</sect1>
16891
16892<sect1 id="exitcodes"><title>Filter Exit Codes </title>
16893
16894<para>When a filter exits,
16895the exit code value is used by the parent process to determine
16896what actions to take.
16897Since filters are used in several places in the printing process,
16898not just to do format conversion,
16899there is a large number of recognized exit values.
16900<informalexample>
16901<screen>Key      Value   Meaning
16902JSUCC    0       Successful
16903JFAIL    1, 32   Failed - retry later
16904JABORT   2, 33   Abort - terminate queue processing
16905JREMOVE  3, 34   Failed - remove job
16906(Unused) 4, 35   (Unused)
16907(Unused) 5, 36   (Unused)
16908JHOLD    6, 37   Hold this job - reprint later
16909JNOSPOOL 7, 38   No spooling to this queue
16910JNOPRINT 8, 39   No printing from this queue
16911JSIGNAL  9,  40   Killed by unrecognized signal
16912JFAILNORETRY 10, 41 Failed, no retry
16913Other            Abort - terminate queue processing</screen>
16914</informalexample>
16915</para>
16916
16917
16918<sect2 id="jsucc"><title>JSUCC </title>
16919
16920<para>A zero or <acronym>JSUCC</acronym>
16921exit value always indicates success;
16922a non-zero exit value indicates failure or a problem condition
16923and requires special handling by the parent process.</para>
16924
16925</sect2>
16926
16927<sect2 id="jfail"><title>JFAIL </title>
16928
16929<para>When printing or performing some action that can be repeated,
16930such as connecting to a remote printer,
16931a 1 or <acronym>JFAIL</acronym>
16932status indicates a transient failure condition.
16933Depending on various configuration options,
16934the printing or other operation can be retried.</para>
16935
16936</sect2>
16937
16938<sect2 id="jabort"><title>JABORT </title>
16939
16940<para>The 2 or <acronym>JABORT</acronym>
16941is a more serious error,
16942and indicates that there is no expectation that the
16943operation would succeed if retried.
16944It may also indicate that no other similar operation should
16945be performed.
16946Jobs whose print filters exit with <acronym>JABORT</acronym> are usually unprintable,
16947and by default are removed from the print queue.</para>
16948
16949</sect2>
16950
16951<sect2 id="jremove"><title>JREMOVE </title>
16952
16953<para>The <acronym>JREMOVE</acronym>
16954status indicates that the job should be removed from the print queue.
16955This is a refinement of the <acronym>JFAIL</acronym> and <acronym>JABORT</acronym>
16956status.
16957The job is usually unconditionally removed from the print queue,
16958even if it is normally kept in the queue for reprinting.
16959This status is usually returned by filters which are responsible for
16960permission checking and is returned when the user has no permission to
16961print.</para>
16962
16963</sect2>
16964
16965<sect2 id="jhold"><title>JHOLD </title>
16966
16967<para>The <acronym>JREMOVE</acronym>
16968status indicates that the job should be held and reprinted at
16969a later time.
16970This status is returned by various filters during the processing
16971of a job,
16972and usually indicates that the resources needed for a job
16973are not available.
16974Held jobs need to be explicitly released by the administrator.</para>
16975
16976</sect2>
16977
16978<sect2 id="jnospool"><title>JNOSPOOL and JNOPRINT
16979</title>
16980
16981<para>The <acronym>JNOSPOOL</acronym> and <acronym>JNOPRINT</acronym>
16982are used as part of the management of load balancing queues
16983and the <emphasis>check idle</emphasis>
16984filter.
16985&LPRng; has the ability to run a program to check to see if a spool
16986queue is available for printing on a dynamic basis.
16987If the filter that does this checking exits with
16988<acronym>JNOSPOOL</acronym> or <acronym>JNOPRINT</acronym>
16989then jobs should not be sent to the spool queue.</para>
16990
16991</sect2>
16992
16993<sect2 id="jsignal"><title>JSIGNAL </title>
16994
16995<para>This status is usually returned when the exiting process
16996is terminated by a signal or abort,
16997and does not exit using the
16998<literal>exit</literal>
16999facility.
17000It is usually handled like a <acronym>JABORT</acronym> exit status,
17001and is the indication of a severe and possibly non-restartable
17002system failure.</para>
17003
17004</sect2>
17005
17006<sect2 id="jnoretry"><title>JFAILNORETRY </title>
17007
17008<para>This code is used under an extremely odd set of circumstances
17009and was used to support a sophisticated print retry system.</para>
17010
17011<para>Normally when a print filter or other filter returns this code,
17012it is treated as <acronym>JFAIL</acronym>.
17013The job is marked as having an error condition
17014and is not
17015<literal>immediately</literal>
17016retried.
17017Other jobs can then be tried for printing in the queue.
17018It is not removed from the print queue,
17019but marked as
17020<literal>unprintable</literal>.</para>
17021
17022<para>When a <emphasis>round-robin retry</emphasis>
17023print scheduling
17024algorithm is used,
17025if there are no other jobs available for printing then the
17026jobs that failed with <acronym>JFAILNORETRY</acronym> are retried.
17027Thus,
17028jobs that are submitted go to the head of the queue for printing,
17029and jobs that are pending for repeat are printed after them.
17030This algorithm is deprecated,
17031and that the details of this algorithm are undocumented.</para>
17032
17033</sect2>
17034
17035<sect2 id="jother"><title>Other Values </title>
17036
17037<para>If a filter exits with other than the indicated value,
17038or a value inappropriate for its purpose,
17039then the result is treated like <acronym>JABORT</acronym>.</para>
17040
17041</sect2>
17042</sect1>
17043
17044<sect1 id="printjobformats"><title>Print Job Formats </title>
17045<para>Options used:
17046<itemizedlist>
17047
17048<listitem>
17049<para><literal>:if</literal>,
17050<literal>cf</literal>,
17051<literal>df</literal>,
17052<literal>gf</literal>,
17053<literal>nf</literal>,
17054<literal remap=tt>:of</literal>,
17055<literal>rf</literal>,
17056<literal>tf</literal>,
17057<literal>vf</literal>,
17058<literal>X</literal><literal remap=tt>f</literal>,
17059<emphasis>Filter programs </emphasis></para>
17060</listitem>
17061
17062</itemizedlist>
17063</para>
17064
17065<para>&LPRng; has inherited a set of so-called `<emphasis remap=bf>print formats</emphasis>' from its
17066BSD ancestor.
17067The format was used to specify the type of file that was being printed.
17068The <application>lpd</application> server
17069used the print format to select the filter for processing the file.
17070The de<emphasis remap=bf>f</emphasis>ault format is
17071<literal remap=tt>f</literal>.</para>
17072
17073<para>The user can specify the format (i.e., the file type) by giving
17074the appropriate option to <application>lpr</application>:</para>
17075
17076<para>
17077<itemizedlist>
17078
17079<listitem>
17080<para><literal>-b</literal> or <literal>-l</literal>: Binary (literal) file. No processing should
17081be done.
17082The
17083<literal remap=tt>l</literal>
17084format is recorded as the file format.</para>
17085</listitem>
17086
17087<listitem>
17088<para><literal>-c</literal>: cifplot(1) output.</para>
17089</listitem>
17090
17091<listitem>
17092<para><literal>-d</literal>: TeX DVI file.</para>
17093</listitem>
17094
17095<listitem>
17096<para><literal>-g</literal>: Output from the plot(3X) routines.</para>
17097</listitem>
17098
17099<listitem>
17100<para><literal>-n</literal> or <literal>-t</literal>: (di)troff output.</para>
17101</listitem>
17102
17103<listitem>
17104<para><literal>-p</literal>: Text file that should be pre-processed by the
17105<literal>pr</literal>
17106command, and then by the standard text filter.</para>
17107</listitem>
17108
17109<listitem>
17110<para><literal>-v</literal>: Benson Varian raster image.</para>
17111</listitem>
17112
17113</itemizedlist>
17114</para>
17115
17116<para>Alternatively, one can also use
17117<literal>-Fx</literal>, where
17118<literal remap=tt>x</literal>
17119is the format specifier.
17120(E.g., <literal>-Fc</literal>
17121instead of <literal>-c</literal>.)
17122This last form also allows you to use other
17123(non-standard) format specifiers.</para>
17124
17125<para>The filter for format
17126<literal remap=tt>X</literal>
17127is the value for the
17128<literal>Xf</literal>
17129printcap
17130option,
17131with some minor exceptions.
17132The following
17133<literal>Xf</literal>
17134options have a pre-defined meaning.</para>
17135
17136<para>
17137<itemizedlist>
17138
17139<listitem>
17140<para><literal>:if</literal>
17141The
17142<literal remap=tt>f</literal>
17143format filter,
17144i.e. - for the default
17145<literal remap=tt>f</literal>
17146format.
17147All print jobs are passed
17148through this one, unless another format is selected.</para>
17149</listitem>
17150
17151<listitem>
17152<para><anchor id="cf">
17153<literal>cf</literal>
17154Cifplot data filter (for <literal>-c</literal> format).</para>
17155</listitem>
17156
17157<listitem>
17158<para><anchor id="df">
17159<literal>df</literal>
17160Filter for DVI files (<literal>-d</literal>).</para>
17161</listitem>
17162
17163<listitem>
17164<para><anchor id="gf">
17165<literal>gf</literal>
17166Graph data filter (<literal>-g</literal>).</para>
17167</listitem>
17168
17169<listitem>
17170<para><anchor id="nf">
17171<literal>nf</literal>
17172Ditroff data filter (<literal>-n</literal>).</para>
17173</listitem>
17174
17175<listitem>
17176<para><literal remap=tt>:of</literal>
17177This filter is used for processing the (optional)
17178banner at the start and/or end of the print job,
17179and also for the interjob separators.
17180See
17181
17182<link linkend="ofdetails">OF Filter</link>
17183for details.</para>
17184</listitem>
17185
17186<listitem>
17187<para><anchor id="rf">
17188<literal>rf</literal>
17189Filter for Fortran style files (<literal>-r</literal>).</para>
17190</listitem>
17191
17192<listitem>
17193<para><anchor id="tf">
17194<literal>tf</literal>
17195Troff filter (<literal>-t</literal>).</para>
17196</listitem>
17197
17198<listitem>
17199<para><anchor id="vf">
17200<literal>vf</literal>
17201(Versatek) raster image filter (<literal>-v</literal>).</para>
17202</listitem>
17203
17204</itemizedlist>
17205
17206</para>
17207</sect1>
17208
17209<sect1 id="ofdetails"><title>OF Filter</title>
17210
17211<para>The
17212<literal remap=tt>:of</literal>
17213filter is used to process banners and job separators.
17214The
17215<literal remap=tt>:of</literal>
17216filter is responsible for performing appropriate
17217processing of this information and sending to the printer
17218for action.</para>
17219
17220<para>While the various file filters are invoked on a once per print file basis,
17221the
17222<literal remap=tt>:of</literal>
17223filter is invoked on a once per print job basis.</para>
17224
17225<para>This filter is the first one to be started,
17226and should perform whatever specialized device initialization
17227is needed.
17228It should also do whatever accounting procedure is desired
17229for start of job accounting.</para>
17230
17231<para>The
17232<literal remap=tt>:of</literal>
17233filter will be given any banner printing or job separation
17234information for a job.
17235As part of its operation,
17236it can detect a specific string,
17237corresponding to a banner print request,
17238and generate a banner.
17239(See the
17240
17241<link linkend="jobsteps">Job Processing Steps and Printcap Options</link>
17242
17243for details.)</para>
17244
17245<para>During operation,
17246the
17247<application>lpd</application> server will send the special
17248<emphasis remap=bf>stop</emphasis>
17249sequence of
17250<literal>\031\001</literal>
17251to the
17252<literal remap=tt>:of</literal>
17253filter.
17254The filter must then suspend itself using a
17255<command>kill -STOP</command> operation.
17256The <application>lpd</application> server will detect that the
17257<literal remap=tt>:of</literal>
17258filter has suspended itself and then
17259will perform other printing operations.</para>
17260
17261<para>After the other printing operations have been completed,
17262the
17263<literal remap=tt>:of</literal>
17264will then be sent a
17265<command>kill -CONT</command> signal.</para>
17266
17267<para>This sequence will continue until all information has been printed,
17268and then the
17269<literal remap=tt>:of</literal>
17270filter's <acronym/STDIN/ will be closed.
17271The filter will then perform whatever cleanup operations are needed,
17272update accounting or other information,
17273and exit.</para>
17274
17275</sect1>
17276
17277<sect1 id="pr"><title><application>lpr</application> -p format </title>
17278
17279<para>Options used:
17280<itemizedlist>
17281
17282<listitem>
17283<para><literal>pr=</literal><emphasis>pr program for p format</emphasis></para>
17284</listitem>
17285
17286</itemizedlist>
17287</para>
17288
17289<para>The <literal>-p</literal> format is requires filtering the
17290the input files by the
17291<literal>pr</literal>
17292utility
17293and then passing the result through the
17294<literal>:if</literal>
17295filter.</para>
17296
17297<para>This is widely regarded as a kludge and may not be supported
17298on your print spooler.</para>
17299
17300</sect1>
17301
17302<sect1><title><application>lpr</application> binary (-l) format</title>
17303
17304<para>The binary (or literal) format is <literal>-l</literal>.
17305The
17306<literal>:if</literal>
17307filter
17308is used to process the file,
17309and is invoked with the
17310<literal>-c</literal>
17311(<literal remap=tt>c</literal>ancel processing?) flag.</para>
17312
17313<para>The filter will not modify the file when sending it to the printer,
17314but may apply various setups to the printer.</para>
17315
17316</sect1>
17317
17318<sect1 id="chainingfilters"><title>Chaining Filters </title>
17319
17320<para>If a filter command has a pipe (<literal remap=tt>|</literal>) or IO redirection indicator (<literal remap=tt>&lt;</literal>
17321or
17322<literal>&gt;</literal>) in it,
17323or starts with an open parenthesis (<literal/(/),
17324the filter is run by passing the entire command to the shell
17325specified by the
17326<literal>shell</literal>
17327configuration option.
17328This allows a wide variety of options and operations to be carried out.
17329The
17330<literal>$*</literal>
17331value should be used to have the filter options passed
17332to the correct entry in the filter chain.</para>
17333
17334<para>For example,
17335<informalexample>
17336<screen>lp:
17337  :filter=( echo "starting `date`" &gt;/var/log/status; /usr/local/ifhp $* )
17338</screen>
17339</informalexample>
17340</para>
17341
17342</sect1>
17343
17344<sect1 id="filteroptions"><title>Filter Command Line Options and Environment Variables </title>
17345
17346<para>Options used:
17347<itemizedlist>
17348
17349<listitem>
17350<para> <literal>bk_filter_options=</literal><emphasis>Backwards Compatible Filter options</emphasis></para>
17351</listitem>
17352
17353<listitem>
17354<para> <literal>bk_of_filter_options=</literal><emphasis>Backwards Compatible OF Filter options</emphasis></para>
17355</listitem>
17356
17357<listitem>
17358<para>
17359<literal>bkf</literal> FLAG <emphasis>Backwards Compatible Filters</emphasis></para>
17360</listitem>
17361
17362<listitem>
17363<para> <literal>filter_ld_path=</literal><emphasis>Filter LD_LIBRARY_PATH environment</emphasis></para>
17364</listitem>
17365
17366<listitem>
17367<para> <literal>filter_options=</literal><emphasis>Filter options</emphasis></para>
17368</listitem>
17369
17370<listitem>
17371<para> <literal>filter_path=</literal><emphasis>Filter PATH environment</emphasis></para>
17372</listitem>
17373
17374<listitem>
17375<para> <literal>of_filter_options=</literal><emphasis>OF Filter options</emphasis></para>
17376</listitem>
17377
17378<listitem>
17379<para> <literal>pass_env=</literal><emphasis>Environment variables to copy to Filter environment</emphasis></para>
17380</listitem>
17381
17382<listitem>
17383<para>
17384<literal>pl=</literal><emphasis>line count for page</emphasis></para>
17385</listitem>
17386
17387<listitem>
17388<para>
17389<literal>pw=</literal><emphasis>column count for page</emphasis></para>
17390</listitem>
17391
17392<listitem>
17393<para>
17394<literal>px=</literal><emphasis>pixel width for page</emphasis></para>
17395</listitem>
17396
17397<listitem>
17398<para>
17399<literal>py=</literal><emphasis>pixel length for page</emphasis></para>
17400</listitem>
17401
17402</itemizedlist>
17403</para>
17404
17405<para>A filter (or program) specification in the &LPRng; printcap database
17406has the form:
17407<informalexample>
17408<screen>:option=| [flags] /path [argument | "argument" | 'argument' ]*
17409:option=[flags]   /path [argument | "argument" | 'argument' ]*</screen>
17410</informalexample>
17411</para>
17412
17413<para>The first case is used where the option value can be a string or filter,
17414and the second where a program is always expected.
17415The following procedure is used to run a filter program.
17416Arguments in single or double quotes are passed as a single value,
17417as for a shell.</para>
17418
17419<para>The sequence of operations to run a filter is as follows:
17420<orderedlist>
17421
17422<listitem>
17423<para>The program must be specified with an absolute path name.</para>
17424</listitem>
17425
17426<listitem>
17427<para>By default, the program is run as the user if invoked from a client
17428program such as <application>lpr</application>, <application>lpc</application>, etc.
17429If invoked from <application>lpd</application>,  it is run as the
17430user ID specified by the
17431<literal>:user</literal>
17432(default <literal>daemon</literal>) configuration entry.</para>
17433</listitem>
17434
17435
17436<listitem>
17437<para>The
17438<literal/filter_path/ (default <literal>/bin:/usr/bin:/usr/local/bin</literal>,
17439and
17440<literal/filter_ld_path/ (default <literal>/lib:/usr/lib:/usr/local/lib</literal>,
17441configuration options specifies the value of the
17442<literal/PATH/
17443and
17444<literal/LD_LIBRARY_PATH/
17445environment variables.</para>
17446</listitem>
17447
17448<listitem>
17449<para>The
17450<literal/filter_path/ (default <literal>/bin:/usr/bin:/usr/local/bin</literal>,
17451and
17452<literal/filter_ld_path/ (default <literal>/lib:/usr/lib:/usr/local/lib</literal>,
17453configuration option specifies the value of the
17454<literal/PATH/
17455and
17456<literal/LD_LIBRARY_PATH/
17457environment variables.
17458The other enviroment variables are described in 
17459<link linkend="filterenv">
17460&LPRng; ftp mirror sites
17461Filter Environment Variables
17462</link>
17463</listitem>
17464
17465<listitem>
17466<para><acronym>ROOT</acronym> Flag.
17467If the ROOT flag is specified the
17468filter is executed with Userid and Effective Userid ROOT (User ID 0).
17469By default it is executed with the
17470<literal>user</literal>
17471and
17472<literal>group</literal>
17473configuration option user and group ids.
17474Running a filter as ROOT is extremely dangerous,
17475and should only be used for programs that require
17476root permissions to open files or make network connections
17477from privileged ports.</para>
17478</listitem>
17479
17480<listitem>
17481<para>
17482<literal/$-/
17483or
17484<literal/-$/ Flag.
17485This flag suppresses appending options to the filter command line.
17486If the
17487<emphasis remap=bf>$-</emphasis> or <literal>-$</literal> flag
17488is not present,
17489the
17490<literal>:filter_options</literal>
17491or <literal>:of_filter_options</literal> for the <option>:of</option> filter
17492values are appended to the filter command line.
17493If the
17494<literal>:bkf</literal>
17495(Berkeley <application/lpd/ filter compatible flag) is <literal/TRUE/
17496then the
17497<literal>:bk_filter_options</literal> and <literal>:bk_of_filter_options</literal>
17498values are used instead of the <literal>:filter_options</literal> and
17499<literal>:of_filter_options</literal> values.
17500</para>
17501<table id=printfiltercommand><title>Print Filter Command Line Options</title>
17502<tgroup cols=2 align=left>
17503<thead>
17504<row><entry>Option</entry><entry>DefaultValue</entry></row>
17505</thead>
17506<tbody>
17507<row><entry>Option</entry><entry>DefaultValue</entry></row>
17508<row><entry><literal>filter_options</literal></entry><entry>$C $F $H $J $L $P $Q $R $Z $a $c $d $e $f $h $i $j $k $l $n $p$r $s $w $x $y $-a</entry></row>
17509<row><entry><literal>of_filter_options</literal></entry><entry>(same as <literal>filter_options</literal>)</entry></row>
17510<row><entry><literal>bk_filter_options</literal></entry><entry>$P $w $l $x $y $F $c $L $i $J $C $0n $0h $-a</entry></row>
17511<row><entry><literal>bk_of_filter_options</literal></entry><entry>$w $l $x $y</entry></row>
17512</tbody>
17513</tgroup>
17514</table>
17515
17516</listitem>
17517
17518<listitem>
17519<para>By default,
17520for programs that are not being invoked as print job file filters,
17521the
17522<literal>filter_options</literal>
17523arguments are added.
17524For print job filters, if the
17525<literal>:bkf</literal>
17526flag is set,
17527then the
17528<literal>bk_filter_options</literal>
17529and
17530<literal>bk_of_filter_options</literal>
17531entries are used.
17532The default
17533<literal>bk</literal>
17534filter options are the same as originally used
17535with the BSD <application/lpr/ filters.
17536For the
17537<literal remap=tt>:of</literal>
17538filter,
17539either the <literal>of_filter_options</literal>
17540or <literal>bk_of_filter_options</literal> arguments will be added.</para>
17541</listitem>
17542
17543<listitem>
17544<para>The program arguments will then be scanned and interpreted.
17545Arguments of the form
17546<literal remap=tt>$</literal><literal>letter</literal>
17547will be
17548translated into values from the
17549print job control file and/or printcap entry.
17550The letters have the following meaning:
17551<table id=filteroptionflags><title>Filter Command Line Options and Values</title>
17552<tgroup cols=2>
17553<thead>
17554<row><entry>Option</entry><entry>Purpose or Value</entry></row>
17555</thead>
17556<tbody>
17557<row><entry><literal>a </literal></entry><entry>printcap
17558<literal>af</literal>
17559(accounting file name)</entry></row>
17560<row><entry><literal>b </literal></entry><entry>job size (in K bytes)</entry></row>
17561<row><entry><literal remap=tt>c </literal></entry><entry>binary file (<literal remap=tt>l</literal>
17562format for print file)</entry></row>
17563<row><entry><literal>d </literal></entry><entry>printcap
17564<literal>cd</literal>
17565or
17566<literal>sd</literal>
17567entry</entry></row>
17568<row><entry><literal>e </literal></entry><entry>print job data file name (currently being processed)</entry></row>
17569<row><entry><literal>f </literal></entry><entry>print job original name when spooled for printing (N info from control file)</entry></row>
17570<row><entry><literal>h </literal></entry><entry>print job originating host (H info from control file)</entry></row>
17571<row><entry><literal>i </literal></entry><entry>indent request (I info from control file)</entry></row>
17572<row><entry><literal>j </literal></entry><entry>job number in spool queue</entry></row>
17573<row><entry><literal>k </literal></entry><entry>print job control file name</entry></row>
17574<row><entry><literal>l </literal></entry><entry>printcap
17575<literal>pl</literal>
17576(page length)</entry></row>
17577<row><entry><literal>m </literal></entry><entry>printcap
17578<literal>co</literal></entry></row>
17579<row><entry><literal>n </literal></entry><entry>user name (L info from control file)</entry></row>
17580<row><entry><literal>p </literal></entry><entry>remote printer (when processing for bounce queue)</entry></row>
17581<row><entry><literal>r </literal></entry><entry>remote host (when processing for bounce queue)</entry></row>
17582<row><entry><literal>s </literal></entry><entry>printcap
17583<literal>sf</literal>
17584(status file)</entry></row>
17585<row><entry><literal>t </literal></entry><entry>time in common UNIX format</entry></row>
17586<row><entry><literal>w </literal></entry><entry>printcap
17587<literal>pw</literal>
17588(page width)</entry></row>
17589<row><entry><literal>x </literal></entry><entry>printcap
17590<literal>px</literal>
17591(page x dimension)</entry></row>
17592<row><entry><literal>y </literal></entry><entry>printcap
17593<literal>py</literal>
17594(page y dimension)</entry></row>
17595<row><entry><literal>F </literal></entry><entry>print file format</entry></row>
17596<row><entry><literal>P </literal></entry><entry>printer name</entry></row>
17597<row><entry><literal>S </literal></entry><entry>printcap
17598<literal>cm</literal>
17599(comment field)</entry></row>
17600<row><entry>Capital letter</entry><entry>Corresponding line from control file</entry></row>
17601<row><entry>{key}</entry><entry>printcap value for
17602<literal>key</literal></entry></row>
17603</tbody>
17604</tgroup>
17605</table>
17606</para>
17607</listitem>
17608
17609<listitem>
17610<para>If there is no value for the specified argument,
17611then the argument is removed from the list.
17612If there is a value, the actual form of the substitution is
17613controlled by additional flags as follows.
17614<table frame=all><title>Filter Command Line Option Format</title>
17615<tgroup cols=2 rowsep=1 colsep=1 align=left>
17616<thead>
17617<row><entry>Form</entry><entry>TranslatedValue</entry></row>
17618</thead>
17619<tbody>
17620<row><entry><literal> $x </literal></entry> <entry><literal/'-x/<replaceable/value/<literal/'/</entry></row>
17621<row><entry><literal> $-x </literal></entry><entry><literal/   '/<replaceable/value/<literal/'/</entry></row>
17622<row><entry><literal> $0x </literal></entry><entry><literal/-x '/<replaceable/value/<literal/'/</entry></row>
17623<row><entry><literal> $'x </literal></entry><entry><literal/-x  /<replaceable/value/<literal//</entry></row>
17624</tbody>
17625</tgroup>
17626</table>
17627</para>
17628
17629<para>Each entry in quotes is treated as a single value,
17630as in /bin/sh.
17631The
17632<literal>$'x</literal>
17633does not quote the value.
17634Combinations of the various flags are allowed.  For example,
17635<literal>$-x</literal>
17636would simply substitute the value for
17637<literal remap=tt>x</literal>,
17638and then pass the whitespace separated components as individual arguments.
17639This last form is useful for adding in additional flags on the command line.</para>
17640</listitem>
17641
17642<listitem>
17643<para>The command line is parsed,
17644metacharacters are ruthlessly stripped from all arguments and pathnames
17645and replaced by <literal>_</literal> (underscores),
17646and an argument list suitable for the
17647<literal>execve</literal>
17648system call
17649is formed.</para>
17650</listitem>
17651
17652<listitem>
17653<para>A sanitized environment is set up for the program execution,
17654with the following environment variables.
17655
17656<table frame=all id=filterenv><title>Filter Environment Variables</title>
17657<tgroup cols=2 align=left colsep=1 rowsep=1>
17658<thead>
17659<row><entry>Variable Name</entry><entry>Meaning</entry></row>
17660</thead>
17661<tbody>
17662<row><entry><literal> CONTROL </literal></entry><entry>control file name</entry></row>
17663<row><entry><literal> DATAFILES </literal></entry><entry>list of data file names</entry></row>
17664<row><entry><literal> HOME </literal></entry><entry>Home directory (client only)</entry></row>
17665<row><entry><literal> IFS </literal></entry> <entry><literal>" \t"</literal></entry></row>
17666<row><entry><literal> LD_LIBRARY_PATH </literal></entry> <entry><literal>:filter_ld_path </literal> configuration information</entry></row>
17667<row><entry><literal> LOGDIR </literal></entry><entry>Home directory (client only)</entry></row>
17668<row><entry><literal> LOGNAME </literal></entry><entry><literal/L/ control file line</entry></row>
17669<row><entry><literal> PATH </literal></entry><entry><literal>filter_path</literal> configuration information</entry></row>
17670<row><entry><literal> PRINTCAP_ENTRY </literal></entry><entry>printcap information</entry></row>
17671<row><entry><literal> SHELL </literal></entry><entry><option/:sh/ configuration information (default <filename>/bin/sh</filename>)</entry></row>
17672<row><entry><literal> SPOOL_DIR </literal></entry> <entry><literal>:sd</literal> printcap information</entry></row>
17673<row><entry><literal> TZ </literal></entry><entry>Time zone</entry></row>
17674<row><entry><literal> USER </literal></entry><entry>User name (client only)</entry></row>
17675</tbody>
17676</tgroup>
17677</table>
17678</para>
17679</listitem>
17680
17681<listitem>
17682<para>If the filter is to be run by a client program such as <application>lpr</application>,
17683then the environment variables specified by the
17684<literal>pass_env</literal> configuration or printcap option will be
17685extracted from the environment,
17686have any metacharacters removed,
17687and then placed in the environment variable list.
17688Commonly, the
17689<acronym>PGPPASS</acronym>,
17690<acronym>PGPPASSFD</acronym>,
17691and <acronym>PGPPATH</acronym> are specified.</para>
17692</listitem>
17693
17694<listitem>
17695<para>The program is started,
17696with <acronym/STDIN/, <acronym/STDOUT/, and <acronym/STDERR/ attached to the appropriate files or
17697file descriptors.
17698If none is specified, then they are attached to
17699<filename>/dev/null</filename>.</para>
17700</listitem>
17701
17702</orderedlist>
17703</para>
17704
17705</sect1>
17706
17707<sect1><title>&LPRng; Supported Filters</title>
17708
17709<para>There already exists a large library of ready-to-use filters. Some of
17710them have &LPRng;-specific versions, which can be found at the
17711
17712<link linkend="secftp">&LPRng; ftp mirror sites</link>.</para>
17713
17714
17715<sect2><title>Filter Support Conventions</title>
17716
17717<para>By convention,
17718most filters are either totally standalone (very rare)
17719or require a set of support files or configuration files.
17720There are two types of configuration files:
17721per print queue configuration information
17722and global configuration information.</para>
17723
17724<para>Since a print filter executes
17725with the spool queue directory as the current directory,
17726most filters put per print queue configuration information
17727in a file in the spool directory.
17728Some <emphasis>vintage</emphasis>
17729filters insist on having these files <emphasis>hidden</emphasis>
17730with names such as <emphasis remap=bf><filename>.setup</filename></emphasis>.
17731This can make it difficult for administrators to determine where the
17732configuration files are.</para>
17733
17734<para>Global configuration files are usually
17735placed in commonly accessible directories such as
17736<emphasis remap=tt><filename>/usr/local/libexec/filters</filename></emphasis>
17737and its subdirectories.
17738This allows the &LPRng; administrator to set the privileges on these
17739directories such that only the <application>lpd</application> process can
17740access them.</para>
17741
17742<para>When a filter is invoked,
17743it is passed a large number of options,
17744many of which are totally ignored in filter operation.
17745However,
17746for many purposes it is necessary to provide options to the
17747filters to tailor their operation to the particular spool queue needs.</para>
17748
17749<para>
17750An alternative to using information in a file is to place options in the
17751printcap entry and have the filter extract them from the
17752<envar/PRINTCAP_ENTRY/ environment variable value.
17753This is much easier to implement,
17754but is specific to &LPRng;.
17755</para>
17756
17757</sect2>
17758</sect1>
17759
17760<sect1 id="lpf"><title>lpf </title>
17761
17762<para>Source code:
17763
17764<link linkend="secftp">&LPRng; Distribution</link>
17765</para>
17766
17767<para>This filter is distributed as part of the &LPRng; source code,
17768and has a very limited functionality.
17769By default,
17770it only translates
17771<literal>\n</literal>
17772to
17773<literal>\r\n</literal>
17774sequences,
17775and detects the OF Filter Stop sequence when invoked as an OF filter.
17776<itemizedlist>
17777
17778<listitem>
17779<para>Options:<!-- <br> -->
17780<literal>-Tcrlf</literal> - suppress
17781<literal>\n</literal>
17782to
17783<literal>\r\n</literal>
17784translation</para>
17785</listitem>
17786
17787</itemizedlist>
17788</para>
17789
17790</sect1>
17791
17792<sect1 id="ifhp"><title><application>ifhp</application> Filter </title>
17793
17794<para>Source code:
17795
17796<link linkend="secftp">&LPRng; Distribution, ifhp-&lt;em&gt;version&lt;/em&gt;.tgz</link>
17797</para>
17798
17799<para>The <application>ifhp</application> filter supports a wide variety of <emphasis>smart</emphasis>
17800printers,
17801or to be more specific,
17802printers which support PostScript, PCL or PJL languages.
17803For details on using the
17804<application remap=tt>ifhp</application> filter
17805see the
17806<application remap=tt>ifhp</application> filter
17807documentation for details.
17808The following is a quick set of examples of printcap entries:
17809<informalexample>
17810<screen># network connection to jet direct box,
17811#   no banners, HP compatible
17812lp
17813  :lp=ipaddr%9100
17814  :filter=/usr/local/libexec/filters/ifhp
17815#
17816# banner added,  model information added
17817#
17818lp
17819  :lp=ipaddr%9100
17820  :ifhp=model=hp4
17821  :bp=/usr/local/libexec/filters/pclbanner
17822  :of=/usr/local/libexec/filters/ifhp
17823  :filter=/usr/local/libexec/filters/ifhp
17824#
17825# for a parallel port printer or when you want VERY fast
17826#  throughput, no pagecounts, error messages, etc.  The
17827#
17828lp
17829  :lp=/dev/lp0
17830  :ifhp=model=hp4,status@
17831  :filter=/usr/local/libexec/filters/ifhp</screen>
17832</informalexample>
17833</para>
17834</sect1>
17835</chapter>
17836
17837<chapter id=permsref><title>Permissions and Authentication </title>
17838
17839<para>The contents of the <filename>/etc/lpd.perms</filename> file
17840are used to control access to the <application>lpd</application> server facilities.
17841The model used for permission granting is similar to packet filters.
17842An incoming request is tested against a list of rules,
17843and the first match found determines the action to be taken.
17844The action is either <acronym>ACCEPT</acronym> or the request is granted,
17845or <acronym>REJECT</acronym> and the request is denied.
17846You can also establish a default action.</para>
17847
17848<para>The following is a sample <filename>lpd.perms</filename> file.</para>
17849
17850<para>
17851<informalexample>
17852<screen># allow root on server to control jobs
17853ACCEPT SERVICE=C SERVER REMOTEUSER=root
17854REJECT SERVICE=C
17855#
17856# allow same user on originating host to remove a job
17857ACCEPT SERVICE=M SAMEHOST SAMEUSER
17858# allow root on server to remove a job
17859ACCEPT SERVICE=M SERVER REMOTEUSER=root
17860REJECT SERVICE=M
17861# all other operations allowed
17862DEFAULT ACCEPT</screen>
17863</informalexample>
17864</para>
17865
17866<para>Each line of the permissions file is a rule.
17867A rule will ACCEPT or REJECT a request
17868if all of the patterns specified in the rule match.
17869If there is a match failure,
17870the next rule in sequence will be applied.
17871If all of the rules are exhausted,
17872then the last specified default authorization will be used.</para>
17873
17874<para>The sense of a pattern match can be inverted using the NOT keyword.
17875For example,
17876the rules with
17877<literal>ACCEPT NOT REMOTEUSER=john,bill</literal>
17878succeeds only if the REMOTEUSER value is defined and
17879is not
17880<literal>john</literal>
17881or
17882<literal>bill</literal>.</para>
17883
17884<para>Each entry in a rule is a keyword which has is assigned a value or
17885list of values followed by an optional set of patterns that are matched
17886against these values.
17887The following table is a summary of the available keywords.</para>
17888
17889<table frame=all id=permskeywords><title>Permission Keywords and Purpose</title>
17890<tgroup cols=2 align=left rowsep=1 colsep=1>
17891<thead>
17892<row><entry>Keyword</entry><entry>Match</entry></row>
17893</thead>
17894<tbody>
17895<row><entry><acronym>DEFAULT</acronym></entry><entry>default result</entry></row>
17896<row><entry><acronym>SERVICE</acronym></entry><entry>Checking lpC, lpR, lprM, lpQ, and Printing</entry></row>
17897<row><entry><acronym>USER</acronym></entry><entry>P (logname) field name in print job control file.</entry></row>
17898<row><entry><acronym>REMOTEUSER</acronym></entry><entry>user name in request from remote host.</entry></row>
17899<row><entry><acronym>HOST</acronym></entry><entry>DNS and IP address information for the H (host) field name in print job control file</entry></row>
17900<row><entry><acronym>REMOTEHOST</acronym></entry><entry>DNS and IP address information for the connection from the remote host making the request</entry></row>
17901<row><entry><acronym>IP</acronym></entry><entry>Alias for HOST</entry></row>
17902<row><entry><acronym>REMOTEIP</acronym></entry><entry>Alias for REMOTEHOST</entry></row>
17903<row><entry><acronym>REMOTEPORT</acronym></entry><entry>Originating TCP/IP port for the connection from the remote host making the request</entry></row>
17904<row><entry><acronym>PORT</acronym></entry><entry>Alias for PORT</entry></row>
17905<row><entry><acronym>UNIXSOCKET</acronym></entry><entry>Connection is on a UNIX socket, i.e. from localhost</entry></row>
17906<row><entry><acronym>SAMEUSER</acronym></entry><entry>USER and REMOTEUSER matches</entry></row>
17907<row><entry><acronym>SERVER</acronym></entry><entry>request originates on lpd server</entry></row>
17908<row><entry><acronym>FORWARD</acronym></entry><entry>destination of job is not host</entry></row>
17909<row><entry><acronym>REMOTEGROUP</acronym></entry><entry>REMOTEUSER is in the specified group or netgroup in the <application>lpd</application> server group database.</entry></row>
17910<row><entry><acronym>GROUP</acronym></entry><entry>USER is in the specified group or netgroup in the <application>lpd</application> server group database.</entry></row>
17911<row><entry><acronym>LPC</acronym></entry><entry>LPC command in the LPC request.</entry></row>
17912<row><entry><acronym>CONTROLLINE</acronym></entry><entry>match a line in control file</entry></row>
17913<row><entry><acronym>AUTH</acronym></entry><entry>authentication type</entry></row>
17914<row><entry><acronym>AUTHUSER</acronym></entry><entry>authenticated user</entry></row>
17915<row><entry><acronym>AUTHSAMEUSER</acronym></entry><entry>same authenticated user</entry></row>
17916<row><entry><acronym>AUTHFROM</acronym></entry><entry>authenticated forwarder</entry></row>
17917<row><entry><acronym>AUTHJOB</acronym></entry><entry>authenticated job in queue</entry></row>
17918<row><entry><acronym>AUTHCA</acronym></entry><entry>SSL signing certificates for job</entry></row>
17919</tbody>
17920</tgroup>
17921</table>
17922
17923<sect1 id="defaultpermission"><title>Permission Checking Algorithm </title>
17924
17925<para>Options used:
17926<itemizedlist>
17927
17928<listitem>
17929<para> <literal>default_permission=</literal><emphasis>Default Permission (accept)</emphasis></para>
17930</listitem>
17931
17932</itemizedlist>
17933</para>
17934
17935<para>The <application>lpd</application> server uses the following algorithm to do
17936permission checks.
17937<orderedlist>
17938
17939<listitem>
17940<para>The configuration information initially establishes
17941a default permission using the <literal>default_permission</literal>
17942configuration value.
17943This is used if an explicit permission is not determined
17944by the other steps in this algorithm.</para>
17945</listitem>
17946
17947<listitem>
17948<para>Each line of the permissions file is a lists of tests (patterns)
17949and a permission value that is used if all of the tests (patterns)
17950on the line are successful.
17951A DEFAULT line sets the default result if all lines fail.</para>
17952</listitem>
17953
17954<listitem>
17955<para>Each line is executed in sequence until a match is found.
17956The first matching line terminates the permission checking
17957and the corresponding permission value is used.</para>
17958</listitem>
17959
17960<listitem>
17961<para>Each keyword has a value (or set of values) that are matched against
17962a set of patterns.
17963If the keyword does not have a value (or the <emphasis>null</emphasis>
17964value)
17965then the match will fail.
17966Initially,
17967all the keywords have a
17968<literal>null</literal>
17969value.</para>
17970</listitem>
17971
17972<listitem>
17973<para>When a connection is received by the <application>lpd</application> server,
17974REMOTEHOST
17975and
17976REMOTEPORT
17977are set to the the IP addresses and hostnames, and the TCP/IP port
17978of the host originating the IP address respectively.
17979REMOTEIP and IFHP are aliases for REMOTEPORT
17980and PORT is an alias for REMOTEPORT
17981and are provided for backwards compatibility with older versions of &LPRng;.
17982If the connection was on a UNIX socket, then the
17983UNIXSOCKET flag is set.
17984For example,
17985a request originating from
17986<literal>10.0.0.2</literal>, port 1011 would set
17987REMOTEIP to 10.0.0.2 and PORT to 1011.</para>
17988</listitem>
17989
17990<listitem>
17991<para>The REMOTEHOST value is set to the result of doing a reverse DNS lookup
17992on the REMOTEIP address.
17993This value is the list of names <emphasis>and</emphasis>
17994ip addresses in standard
17995IP notation (nnn.nnn.nnn.nnn) that are returned by the
17996lookup.
17997If the DNS lookup fails
17998then the REMOTEHOST value is set to the REMOTEIP value.
17999For example,
18000lookup of 10.0.0.2 would result in the names
18001<filename>h2.private</filename> and <filename>patrick.private</filename>,
18002and the only IP address assigned to it was
18003<literal>10.0.0.2</literal>.
18004The REMOTEHOST value would then be the list
18005<literal>h2.private,patrick.private,10.0.0.2</literal>.</para>
18006</listitem>
18007
18008<listitem>
18009<para>The SERVICE value is set to
18010<literal remap=tt>X</literal>
18011and then the permissions database is scanned for a matching entry.
18012The result is the permission value of the first matching line or the default
18013permission.
18014If the result is REJECT then the connection is closed.</para>
18015</listitem>
18016
18017<listitem>
18018<para>Next, a single line is read from the connection.
18019This line contains the request type,
18020the print queue name,
18021and depending on the request type an optional user name and options.
18022The SERVICE value is set to
18023<literal>R,</literal>
18024<literal>Q,</literal>
18025<literal>M,</literal>
18026and
18027<literal>C,</literal>
18028for a
18029<literal>lpR</literal>,
18030<literal>lpQ</literal>,
18031<literal>lprM</literal>,
18032and
18033<application>lpc</application>
18034request respectively and PRINTER to the print queue name.</para>
18035</listitem>
18036
18037<listitem>
18038<para>If the request is for an <application>lpc</application> operation,
18039the LPC value is set to the name of the operation.
18040For example,
18041and
18042
18043<command remap=tt>lpc lpd</command>
18044operation</para>
18045</listitem>
18046
18047<listitem>
18048<para>If the request contains a user name then REMOTEUSER is assigned the user name.</para>
18049</listitem>
18050
18051<listitem>
18052<para>If the request originates from the <application>lpd</application> server as determined by
18053the connection arriving from the
18054<literal>localhost</literal>
18055address or an
18056address assigned to one of the network interfaces for this host
18057then the SERVER value is set to true (or matches).</para>
18058</listitem>
18059
18060<listitem>
18061<para>If the request is for an authenticated transfer,
18062(see
18063
18064<link linkend="authref">Authentication and Encryption</link>
18065),
18066then the authentication procedures are carried out.
18067After they have been performed,
18068the AUTH value is set to true,
18069AUTHTYPE is set to the name of the authentication method,
18070AUTHUSER to the authenticated identifier of the originator of the request,
18071and AUTHFROM to the authenticated identifier of the originator of the connection.</para>
18072</listitem>
18073
18074<listitem>
18075<para>Other matching keywords such as REMOTEGROUP use values set at this time.
18076These are discussed in the next section.</para>
18077</listitem>
18078
18079<listitem>
18080<para>The permission database is rescanned,
18081this time to see if there is permission to operate on the
18082specified spool queue.
18083The permission database is first checked to see
18084if the requesting user has control (SERVICE=C) permission.
18085If they do,
18086then they can perform any operation on the spool queue.
18087The scan is then repeated for the actual request.</para>
18088</listitem>
18089
18090<listitem>
18091<para>If there is no permission to perform the operation
18092then an error code and messages is returned on the
18093requesting connection.</para>
18094</listitem>
18095
18096<listitem>
18097<para>If the operation is for a spool queue or server,
18098no other permissions checking is done.
18099This includes the <application>lpq</application> command,
18100and most of the <application>lpc</application> commands control queue operations.</para>
18101</listitem>
18102
18103<listitem>
18104<para>If the operation is for for individual jobs in a spool queue,
18105then the queue is scanned and job information is extracted
18106for each job in the queue.
18107The USER value is set to the job control file
18108<literal remap=tt>P</literal>
18109line.
18110The value of the
18111<literal remap=tt>H</literal>
18112line in the control file is used to perform a
18113DNS lookup,
18114and the HOST value is set to the results of this lookup.
18115IP is an alias for HOST,
18116and is retained for backwards compatibility.</para>
18117</listitem>
18118
18119<listitem>
18120<para>The SAMEUSER value is set to true (or match) if the REMOTEUSER
18121value is identical to the USER value.
18122Similarly,
18123SAMEHOST is set to true if the REMOTEHOST value matches the HOST value.
18124See the following sections for other keywords such as GROUP.</para>
18125</listitem>
18126
18127<listitem>
18128<para>The permission checking is done for each individual job in a
18129spool queue,
18130and if it succeeds the action is carried out on the job.</para>
18131</listitem>
18132
18133</orderedlist>
18134</para>
18135
18136<para>These checks are applied on the arrival of a job from an external
18137connection.
18138Unfortunately,
18139there are a set of print spooler implementations that do not
18140handle job rejection due to lack of permissions.
18141These printers will continually and repeatedly attempt to send a job
18142for which there is no printing permission until the job is removed
18143by administrative action.
18144To accommodate these printers,
18145we must accept jobs for printing and then dispose of them.
18146This is done by using the SERVICE=P (printing) checks.
18147These checks are performed
18148<emphasis/after/
18149the job has been accepted.
18150</para>
18151
18152<para>
18153<orderedlist>
18154
18155<listitem>
18156<para>When a print spool is active and is printing or forwarding jobs,
18157before it processes a job it will read the job control file
18158and set the <acronym>USER</acronym>  and <acronym>HOST</acronym>
18159values as discussed in the previous sections.
18160It will also set the <acronym>AUTH</acronym>,
18161<acronym>AUTHUSER</acronym>,
18162and <acronym>AUTHJOB</acronym>
18163values as well,
18164if the job was spooled by using an authenticated method.</para>
18165</listitem>
18166
18167<listitem>
18168<para>The permissions database will be scanned
18169and the resulting permission determined.
18170Note that the values of the REMOTE keys are undefined,
18171and tests using them will have unpredictable effects.</para>
18172</listitem>
18173
18174<listitem>
18175<para>If the job does not have permission to be printed,
18176it will normally be removed from the spool queue.</para>
18177</listitem>
18178
18179</orderedlist>
18180</para>
18181
18182<para>While this model is very simple
18183it can handle a wide range of situations.
18184However,
18185it is really based on the simple <emphasis remap=bf>trust</emphasis>
18186that
18187users will not <emphasis>impersonate</emphasis>
18188other users or hosts.
18189If this is not the case,
18190then more elaborate procedures based on encryption and
18191authentication are called for.</para>
18192
18193<para>There is a problem with permissions checking for <application>lpq</application> (SERVICE=Q)
18194requests.
18195Since the user name is not passed as part of the request,
18196it is impossible to use the REMOTEUSER clause to restrict <application>lpq</application>
18197operations.</para>
18198
18199<para>The <literal>SERVICE=R</literal> and <literal>SERVICE=P</literal>
18200facilities are provided to handle problems with print spoolers that
18201do not recognize a <emphasis>lack of permission</emphasis>
18202error code,
18203and will indefinitely retry sending a job to the <application>lpd</application> server.
18204If this is the case,
18205then the <literal>SERVICE=R</literal> clause can be used to accept jobs,
18206and then the <literal>SERVICE=P</literal> clause will cause the <application>lpd</application>
18207server to remove of the job when it is scheduled for printing.</para>
18208
18209</sect1>
18210
18211<sect1><title>Rule Matching Procedures</title>
18212
18213<para>
18214<informalexample>
18215<screen>[not] key                                 assigned value
18216[not] key=pattern                         substring match
18217[not] key=pattern1,pattern2,pattern3,...  glob and exact
18218[not] key=IP1/mask1,IP2/mask2,...         IP address</screen>
18219</informalexample>
18220</para>
18221
18222<para>Each of the indicated values is matched against a list of patterns.
18223The following types of matches are used:
18224<orderedlist>
18225
18226<listitem>
18227<para>assigned value.
18228The keyword has an assigned value which is true (match) or false (no match).
18229Examples are SAMEHOST and SERVER.</para>
18230</listitem>
18231
18232<listitem>
18233<para>substring match.
18234The indicated entry is present as a substring in the pattern.</para>
18235</listitem>
18236
18237<listitem>
18238<para>GLOB matches.
18239The pattern is interpreted as a GLOB style pattern,
18240where * matches 0 or more characters,
18241and ? matches a single character,
18242and
18243<literal>[L-H]</literal>
18244specifies a range of characters from
18245<literal remap=tt>L</literal>
18246to
18247<literal remap=tt>H</literal>,
18248in ASCII order.</para>
18249</listitem>
18250
18251<listitem>
18252<para>IP address match.  The address must be specified in the
18253standard <filename>nn.nn.nn.nn</filename> format.
18254The mask must be either an integer number
18255corresponding to the number of significant bits,
18256or in the standard <filename>nn.nn.nn.nn</filename> format.
18257Addresses are compared by doing
18258<informalexample>
18259<screen>( IPaddr XOR IP ) AND mask</screen>
18260</informalexample>
18261
18262</para>
18263
18264<para>If the result is 0, then a match results.
18265Note that there may be one or more addresses being checked for;
18266this can occur when a host may have multiple IP addresses assigned to it.</para>
18267</listitem>
18268
18269<listitem>
18270<para>integer range match.
18271The pattern has the form
18272<literal>low-high</literal>,
18273where low and high are integer numbers.
18274The match succeeds if the value is in the specified range.</para>
18275</listitem>
18276
18277<listitem>
18278<para>Same IP Address Match.
18279This compares two lists of IP addresses;
18280a match is found when there is one or more common addresses.</para>
18281</listitem>
18282
18283</orderedlist>
18284</para>
18285
18286
18287<sect2><title>DEFAULT</title>
18288
18289<para>
18290<informalexample>
18291<screen>DEFAULT ACCEPT
18292DEFAULT REJECT</screen>
18293</informalexample>
18294</para>
18295
18296<para>The DEFAULT rule specifies the default if no rule matches.
18297Normally,
18298there is one DEFAULT entry in a permissions file.
18299<informalexample>
18300<screen>Example:
18301
18302DEFAULT ACCEPT</screen>
18303</informalexample>
18304</para>
18305
18306</sect2>
18307
18308<sect2><title>SERVICE</title>
18309
18310<para>Match type: substring</para>
18311
18312<para>The SERVICE key is based on the type of request.
18313<informaltable frame=all>
18314<tgroup cols=2 align=left rowsep=1 colsep=1>
18315<thead>
18316<row><entry>Key</entry><entry>Request</entry></row>
18317</thead>
18318<tbody>
18319<row><entry>Key</entry><entry>Request</entry></row>
18320<row><entry><literal remap=tt>C</literal></entry><entry>LPC Control Request</entry></row>
18321<row><entry><literal remap=tt>M</literal></entry><entry><application>lprm</application> Removal Request</entry></row>
18322<row><entry><literal remap=tt>P</literal></entry><entry>Printing</entry></row>
18323<row><entry><literal remap=tt>Q</literal></entry><entry><application>lpq</application> Status Request</entry></row>
18324<row><entry><literal remap=tt>R</literal></entry><entry><application>lpr</application> Job Transfer</entry></row>
18325<row><entry><literal remap=tt>X</literal></entry><entry>Connection Request</entry></row>
18326</tbody>
18327</tgroup>
18328</informaltable>
18329</para>
18330
18331<para>Each of the above codes corresponds either directly to the user command,
18332or a set of subcommands.</para>
18333
18334<para>If you have an LPC request,
18335you can add an <literal>LPC=xxx</literal> clause to refine the
18336permissions checking to allow or disallow
18337<application>lpc</application> commands such as
18338<command remap=tt>lpc status, printcap, active, </command>.
18339<informalexample>
18340<screen>Example:
18341
18342# control only from root on server
18343ACCEPT SERVICE=C SERVER USER=root
18344REJECT SERVICE=C
18345# accept all others
18346ACCEPT SERVICE=*</screen>
18347</informalexample>
18348</para>
18349
18350</sect2>
18351
18352<sect2><title>USER</title>
18353
18354<para>Match type: GLOB</para>
18355
18356<para>The USER information is taken from the
18357<literal remap=tt>P</literal>
18358(person or logname)
18359information in the print job control file.
18360<informalexample>
18361<screen>Example:
18362
18363# we allow jobs to be spooled
18364ACCEPT SERVICE=R
18365# now we do the checking at print time
18366ACCEPT SERVICE=P USER=root
18367REJECT SERVICE=P</screen>
18368</informalexample>
18369</para>
18370
18371</sect2>
18372
18373<sect2><title>REMOTEUSER</title>
18374
18375<para>Match type: GLOB</para>
18376
18377<para>The REMOTEUSER information is taken from the user information sent
18378with a service request.</para>
18379
18380<para>Note that one of the flaws of
18381
18382<link linkend="rfc1179">RFC1179</link>
18383
18384is that an <application/lpq/ (print status)
18385request does not provide a REMOTEUSER name.
18386<informalexample>
18387<screen>Example:
18388
18389ACCEPT SERVICE=C REMOTEUSER=root,papowell,admin SERVER
18390ACCEPT SERVICE=C LPC=status,lpd REMOTEUSER=admin
18391REJECT SERVICE=C</screen>
18392</informalexample>
18393</para>
18394
18395</sect2>
18396
18397<sect2><title>HOST</title>
18398
18399<para>Match type: GLOB</para>
18400
18401<para>The
18402<literal remap=tt>H</literal>
18403(host) information in the print job control file
18404is used to do a DNS lookup,
18405and the resulting list of names and addresses is used for matching purposes.
18406<informalexample>
18407<screen>Example:
18408
18409# we allow jobs to be spooled
18410ACCEPT SERVICE=R
18411# now we do the checking at print time
18412# allow from our private subnet
18413ACCEPT SERVICE=P HOST=10.0.0.0/8,*.othernet.com
18414REJECT SERVICE=P</screen>
18415</informalexample>
18416</para>
18417
18418</sect2>
18419
18420<sect2><title>REMOTEHOST</title>
18421
18422<para>Match type: GLOB</para>
18423
18424<para>The REMOTEHOST information is obtained by doing a reverse IP name lookup
18425on the remote host IP address
18426and the resulting list of names and addresses is used for matching purposes.
18427If there is no FQDN available,
18428then the IP address in text form will be used.
18429<informalexample>
18430<screen>Example:
18431
18432# allow from our private subnet
18433ACCEPT SERVICE=R REMOTEHOST=10.0.0.0/8,*.othernet.com
18434REJECT SERVICE=R</screen>
18435</informalexample>
18436</para>
18437
18438</sect2>
18439
18440<sect2><title>REMOTEPORT</title>
18441
18442<para>Match type: integer range</para>
18443
18444<para>The REMOTEPORT value is the originating port of the TCP/IP connection.
18445The match succeeds if it is in the specified range.
18446<informalexample>
18447<screen>Example:
18448
18449# require connections to originate from privileged port
18450ACCEPT SERVICE=X REMOTEPORT=1-1023
18451REJECT SERVICE=X</screen>
18452</informalexample>
18453</para>
18454
18455</sect2>
18456
18457<sect2><title>PORT</title>
18458
18459<para>Alias for REMOTEPORT.</para>
18460
18461</sect2>
18462
18463<sect2><title>IP</title>
18464
18465<para>Alias for HOST.</para>
18466
18467</sect2>
18468
18469<sect2><title>REMOTEIP</title>
18470
18471<para>Alias for REMOTEHOST.</para>
18472
18473</sect2>
18474
18475<sect2><title>LPC</title>
18476
18477<para>Match type: GLOB</para>
18478
18479<para>The requested <application>lpc</application> command.
18480This allows the following permissions line to be used:
18481<informalexample>
18482<screen>Example:
18483
18484#allow remoteuser admin on server to use LPC topq and hold
18485ACCEPT SERVICE=C SERVER REMOTEUSER=root
18486ACCEPT LPC=topq,hold SERVER REMOTEUSER=papowell
18487REJECT SERVICE=C</screen>
18488</informalexample>
18489</para>
18490
18491</sect2>
18492
18493<sect2><title>SAMEUSER</title>
18494
18495<para>Match type: exact string match</para>
18496
18497<para>Both the REMOTEUSER and USER information must be present and identical.
18498<informalexample>
18499<screen>Example:
18500
18501# LPC users can do anything
18502ACCEPT SERVICE=C SERVER REMOTEUSER=root
18503REJECT SERVICE=C
18504# allow users who sent jobs from the same host to remove them
18505ACCEPT SERVICE=M SAMEUSER SAMEHOST
18506REJECT SERVICE=M</screen>
18507</informalexample>
18508</para>
18509
18510</sect2>
18511
18512<sect2><title>SAMEHOST</title>
18513
18514<para>Match type: Same IP Address</para>
18515
18516<para>The REMOTEHOST and HOST address lists are checked;
18517if there is a common value the match succeeds.
18518<informalexample>
18519<screen>Example:
18520
18521# allow root on the same host as user
18522# to remove files
18523ACCEPT SERVICE=M SAMEHOST REMOTEUSER=root
18524REJECT SERVICE=M</screen>
18525</informalexample>
18526</para>
18527
18528</sect2>
18529
18530<sect2><title>SERVER</title>
18531
18532<para>Match type: Matching IP Address</para>
18533
18534<para>One of the REMOTEHOST addresses
18535must be the same as one of the addresses of the <application>lpd</application> server host,
18536or must be one of the addresses found by looking up the
18537<literal>localhost</literal>
18538name using <function>gethostbyname()</function>.
18539<informalexample>
18540<screen>Example:
18541
18542# allow root on the server full LPC permissions
18543ACCEPT SERVICE=C SERVER REMOTEUSER=root
18544REJECT SERVICE=C</screen>
18545</informalexample>
18546</para>
18547
18548</sect2>
18549
18550<sect2><title>FORWARD</title>
18551
18552<para>Match type: Address Match</para>
18553
18554<para>The list of REMOTEHOST and HOST addresses must not have a common entry.
18555This is usually the case when a remote <application>lpd</application> server is forwarding
18556jobs to the <application>lpd</application> server.
18557<informalexample>
18558<screen>Example:
18559
18560# do not accept forwarded jobs or requests
18561REJECT SERVICE=* FORWARD</screen>
18562</informalexample>
18563</para>
18564
18565</sect2>
18566
18567<sect2><title>GROUP</title>
18568
18569<para>Match type: modified GLOB</para>
18570
18571<para>The USER must be present in
18572one of the groups in <filename>/etc/group</filename> or whatever permissions mechanism is used
18573to determine group ownership
18574which matches the GLOB pattern.
18575If the pattern has the form <literal>@name</literal>,
18576then a check to see if the user is in the named netgroup is done.
18577<informalexample>
18578<screen>Example:
18579
18580ACCEPT SERVICE=P GROUP=admin,@netgroup
18581REJECT SERVICE=P</screen>
18582</informalexample>
18583</para>
18584
18585</sect2>
18586
18587<sect2><title>REMOTEGROUP</title>
18588
18589<para>The same rules as for GROUP,
18590but using the REMOTEUSER value.
18591<informalexample>
18592<screen>Example:
18593
18594ACCEPT SERVICE=R REMOTEGROUP=admin,@netgroup
18595REJECT SERVICE=R</screen>
18596</informalexample>
18597</para>
18598
18599</sect2>
18600
18601<sect2><title>CONTROLLINE</title>
18602
18603<para>Match type: GLOB</para>
18604
18605<para>A <acronym>CONTROLLINE</acronym> pattern has the form
18606<informalexample>
18607<screen>X=pattern1,pattern2,...</screen>
18608</informalexample>
18609</para>
18610
18611<para>X is a single upper case letter.
18612The corresponding line must be present in a control file,
18613and the pattern is applied to the line contents.</para>
18614
18615<para>This pattern can be used to select only files with specific control
18616file information for printing.</para>
18617
18618</sect2>
18619
18620<sect2><title>AUTH</title>
18621
18622<para>Match type: value</para>
18623
18624<para>If the current transfer or the transfer used to send a job
18625was authenticated,
18626then AUTH is true or matches.
18627<informalexample>
18628<screen>Example:
18629
18630# reject all non-authenticated transfers
18631REJECT NOT AUTH</screen>
18632</informalexample>
18633</para>
18634
18635</sect2>
18636
18637<sect2><title>AUTHTYPE</title>
18638
18639<para>Match type: glob</para>
18640
18641<para>If the current transfer or the transfer used to send a job
18642was authenticated,
18643then AUTHTYPE is set to the name of the authentication method.
18644<informalexample>
18645<screen>Example:
18646
18647# require kerberos, pgp, or md5 authentication
18648REJECT NOT AUTHTYPE=kerberos*,pgp,md5</screen>
18649</informalexample>
18650</para>
18651
18652</sect2>
18653
18654<sect2><title>AUTHUSER</title>
18655
18656<para>Match type: GLOB</para>
18657
18658<para>The AUTHUSER rule will check to see if the authenticated user identification
18659matches the pattern.
18660<informalexample>
18661<screen>Example:
18662
18663ACCEPT SERVICE=C AUTHTYPE=kerberos* AUTHUSER=admin@ASTART.COM</screen>
18664</informalexample>
18665</para>
18666
18667</sect2>
18668
18669<sect2><title>IFIP</title>
18670
18671<para>Match type: IPmatch, but for IPV6 as well as IPV4</para>
18672
18673<para>There is a subtle problem with names and IP addresses which are
18674obtained for 'multi-homed hosts', i.e. - those with multiple
18675ethernet interfaces,  and for IPV6 (IP Version 6),  in which a host
18676can have multiple addresses,  and for the normal host which can have
18677both a short name and a fully qualified domain name.</para>
18678
18679<para>The IFIP (interface IP) field can be used to check the IP address
18680of the interface
18681that accepted the network connection,
18682as reported by the information
18683returned by the accept() system call.  Note that this information may
18684be IPV4 or IPV6 information,  depending on the origination of the
18685system.  This information is used by gethostbyaddr() to obtain the
18686originating host fully qualified domain name (FQDN) and set of IP addresses.
18687Note that this FQDN will be for the originating interface,  and may
18688not be the canonical host name.  Some systems which use the Domain Name Server
18689(DNS) system may add the canonical system name as an alias.</para>
18690
18691<para>This entry is deprecated and may not be supported in future releases.</para>
18692
18693</sect2>
18694</sect1>
18695
18696<sect1 id="permspath"><title>Permission File Location </title>
18697
18698<para>Options used:
18699<itemizedlist>
18700
18701<listitem>
18702<para> <literal>perms_path=</literal><emphasis> path </emphasis></para>
18703</listitem>
18704
18705</itemizedlist>
18706</para>
18707
18708<para>The <literal>perms_path=</literal> configuration variable specifies the
18709location of the default permissions file.
18710The default value is:
18711<informalexample>
18712<screen>perms_path=${sysconfdir}/lpd.perms</screen>
18713</informalexample>
18714</para>
18715
18716<para>The <filename>lpd.perms</filename> file can be obtained by running a program,
18717in a similar manner to the <filename>printcap</filename> file.
18718See
18719<link linkend="filters">Filters</link>
18720for details on how
18721the program would be invoked.
18722For example, assume the configuration information specified:
18723<informalexample>
18724<screen>perms_path=|/usr/local/libexec/get_perms</screen>
18725</informalexample>
18726</para>
18727
18728<para>The <application>lpd</application> server will write either a blank line
18729for connection (<literal>SERVICE=X</literal>) and global <application>lpc</application> permissions
18730(<literal>SERVICE=C</literal> and <literal>LPC=reread,lpd,default</literal>)
18731or the name of the spool queue to the <literal>get_perms</literal>
18732<acronym/STDIN/,
18733and expects to read permission information from its <acronym/STDOUT/.
18734If the filter method is used,
18735it should always return the complete set of connection (<literal remap=tt>X</literal>)
18736and control (<literal remap=tt>C</literal>
18737service values.</para>
18738
18739</sect1>
18740
18741<sect1><title>Example Permission File</title>
18742
18743<para>
18744<informalexample>
18745<screen># allow root on server to control jobs
18746ACCEPT SERVICE=C SERVER REMOTEUSER=root
18747ACCEPT SERVICE=C LPC=lpd
18748REJECT SERVICE=C
18749#
18750# allow same user on originating host to remove a job
18751ACCEPT SERVICE=M SAMEHOST SAMEUSER
18752# allow root on server to remove a job
18753ACCEPT SERVICE=M SERVER REMOTEUSER=root
18754REJECT SERVICE=M
18755# all other operations allowed
18756DEFAULT ACCEPT</screen>
18757</informalexample>
18758</para>
18759
18760<para>In the above sample, we first specify that
18761lp<literal remap=tt>C</literal>
18762commands from user
18763<literal>root</literal>
18764on the lpd server will be accepted.
18765This is traditionally the way that most lpc commands operate.
18766We also allow anybody to use the
18767<command remap=tt>lpc lpd</command>
18768command.
18769We reject any other <application>lpc</application> requests.</para>
18770
18771<para>We accept
18772lpr<literal remap=tt>M</literal>
18773requests from the host and user that submitted the job,
18774as well as from root on the server,
18775and reject any others.</para>
18776
18777<para>Finally,
18778all other types of commands (lpq, lpr) are allowed by default.</para>
18779
18780</sect1>
18781
18782<sect1><title>Complex Permission Checking</title>
18783
18784<para>One of the more useful types of permission checking is to
18785restrict access to your printers from users outside your
18786networks.
18787The IP pattern can specify a list of IP addresses and netmasks
18788to apply to them.</para>
18789
18790<para>For example
18791<literal>IP=10.3.4.0/24</literal> would match all hosts with the IP
18792addresses
18793<literal>IP=10.3.4.0</literal> to
18794<literal>IP=10.3.4.255</literal>.</para>
18795
18796<para>Similarly, the HOST pattern can specify a set of hostnames
18797or patterns to match against based on the GLOB notation.</para>
18798
18799<para>For example
18800<literal>REMOTEHOST=*.private</literal>
18801would match all hosts with a DNS entry which ended with
18802<filename>private</filename>.</para>
18803
18804<para>The NOT keyword reverses the match sense.  For example
18805<literal>REJECT NOT REMOTEHOST=*.private,*.murphy.com</literal>
18806would reject all requests from hosts which did not have a DNS entry
18807ending in
18808<filename>private</filename>
18809or
18810<filename>murphy.com</filename>.</para>
18811
18812</sect1>
18813
18814<sect1><title>More Examples</title>
18815
18816<para>The following is a more complex lpd.perms file.
18817<informalexample>
18818<screen># All operations allowed except those specifically forbidden
18819DEFAULT ACCEPT
18820#Reject connections which do not originate from hosts with an
18821# address on 130.191.0.0 or from localhost,
18822# or name is not assigned to Engineering pc's
18823REJECT SERVICE=X NOT IFIP=130.191.0.0/16,127.0.0.1/32
18824REJECT SERVICE=X NOT REMOTEHOST=engpc*
18825#Do not allow anybody but root or papowell on
18826#astart1.private or the server to use control
18827#facilities.
18828ACCEPT SERVICE=C SERVER REMOTEUSER=root
18829ACCEPT SERVICE=C REMOTEHOST=astart1.private REMOTEUSER=papowell
18830#Allow root on talker.private to control printer hpjet
18831ACCEPT SERVICE=C HOST=talker.private PRINTER=hpjet REMOTEUSER=root
18832#Reject all others
18833REJECT SERVICE=C
18834#Do not allow forwarded jobs or requests
18835REJECT SERVICE=R,C,M FORWARD
18836# allow same user on originating host to remove a job
18837ACCEPT SERVICE=M SAMEHOST SAMEUSER
18838# allow root on server to remove a job
18839ACCEPT SERVICE=M SERVER REMOTEUSER=root</screen>
18840</informalexample>
18841</para>
18842
18843</sect1>
18844
18845<sect1 id="authref"><title>Authentication </title>
18846
18847<para>One of the major problems in a print spooler system is providing
18848privacy and authentication services for users.  One method is to
18849construct a specific set of protocols which will be used for
18850providing the privacy or authentication;  another is to provide a
18851simple interface to a set of tools that will do the authentication
18852and/or encryption.</para>
18853
18854<para>&LPRng; provides native support for the MIT Kerberos 4 extensions and
18855Kerberos 5 authentication.</para>
18856
18857<para>&LPRng; uses the OpenSSL libraries to support SSL 
18858authentication and encrypted data transfers.</para>
18859
18860<para>&LPRng; has native support for the PGP (Pretty Good Privacy) program
18861and can sign and optionally encrypt command and responses between servers
18862and clients.
18863Due to legal restrictions,
18864an external PGP program must be used for this purpose.</para>
18865
18866<para>A simple MD5 hash based authentication scheme is also provided as an
18867example to illustrate how new or different authentication methods
18868can be adddd.</para>
18869
18870<para>Finally,
18871&LPRng; provide a general purpose interface allowing users to insert their
18872own authentication methods,
18873either at the program level or at the code level.</para>
18874
18875<para>A careful study of the authentication problem shows that it should be done
18876during reception of commands and/or jobs from a remote user and/or
18877spooler.  At this time the following must be done:
18878<orderedlist>
18879
18880<listitem>
18881<para>The received command must be checked for consistency,  and the
18882remote user and host must be determined.</para>
18883</listitem>
18884
18885<listitem>
18886<para>The remote user and host must be authenticated.</para>
18887</listitem>
18888
18889<listitem>
18890<para>The command and/or spooling operation must be carried out.</para>
18891</listitem>
18892
18893<listitem>
18894<para>The results must be returned to the remote system.</para>
18895</listitem>
18896
18897</orderedlist>
18898</para>
18899
18900</sect1>
18901
18902<sect1><title>User Identification</title>
18903
18904<para>When a user logs into a system,  they are assigned a user name
18905and a corresponding UserID.  This user name is used by the &LPRng;
18906software when transferring jobs to identify the user.</para>
18907
18908<para>When we look into the problem of authentication,  we will possibly
18909have a more global user identification to deal with, the
18910authentication identifier (AuthID).  One way to deal with this problem is to
18911give &LPRng; intimate knowledge of the UserID and AuthID relationship.
18912While this is possible it is difficult to deal with in a
18913simple and extensible manner.  An alternate solution is to provide
18914a mapping service,  where the authentication procedure provides
18915a map between the UserID and AuthID.</para>
18916
18917</sect1>
18918
18919<sect1><title>RFC1179 Protocol Extensions</title>
18920
18921<para>The RFC1179 protocol specifies that a <application/lpd/ server command sent on
18922a connection has the form:
18923<informalexample>
18924<screen>\nnn[additional fields]\n</screen>
18925</informalexample>
18926</para>
18927
18928<para><literal>\nnn</literal>
18929is a one octet (byte) value with the following meaning:</para>
18930
18931<para>
18932<informalexample>
18933<screen>REQ_START   1    start printer
18934REQ_RECV    2    transfer a printer job
18935REQ_DSHORT  3    print short form of queue status
18936REQ_DLONG   4    print long form of queue status
18937REQ_REMOVE  5    remove jobs</screen>
18938</informalexample>
18939</para>
18940
18941<para>The &LPRng; system extends the protocol with the following additional
18942types:
18943<informalexample>
18944<screen>REQ_CONTROL 6    do control operation
18945REQ_BLOCK   7    transfer a block format print job
18946REQ_SECURE  8    do operation with authentication</screen>
18947</informalexample>
18948</para>
18949
18950<para>The REQ_CONTROL allows a remote user to send LPC commands to the
18951server.  The REQ_BLOCK provides an alternate method to transfer a
18952job.  Rather than transferring the control and data files individually,
18953this format transfers one file.  The REQ_AUTH provides a mechanism
18954for providing an authentication mechanism and is described in this
18955document.</para>
18956
18957</sect1>
18958
18959<sect1 id="auth"><title>Authentication Operations
18960</title>
18961
18962<para>Options used:
18963<itemizedlist>
18964
18965<listitem>
18966<para> <literal>auth=</literal><emphasis>client to server authentication type</emphasis></para>
18967</listitem>
18968
18969<listitem>
18970<para> <literal>auth_forward=</literal><emphasis>server to server authentication type</emphasis></para>
18971</listitem>
18972
18973<listitem>
18974<para> <literal>XX_id=</literal><emphasis>server identification</emphasis></para>
18975</listitem>
18976
18977<listitem>
18978<para> <literal>XX_forward_id=</literal><emphasis>Server identification</emphasis></para>
18979</listitem>
18980
18981</itemizedlist>
18982</para>
18983
18984<para>A &LPRng; client
18985<application/lpr/,
18986<application/lpq/,
18987<application/lprm/,
18988or
18989<application/lpc/
18990to <application>lpd</application> server authenticated transfer
18991proceeds as follows.
18992If an authenticated transfer is specified by the
18993<literal>auth=protocol</literal> entry in the printcap or configuration information,
18994the client sends a request for an authenticated transfer
18995to the server.</para>
18996
18997<para>Part of the authentication request is the authentication type.
18998If authentication type <acronym>XX</acronym> is requested
18999the server will examine the information in the printcap and configuration
19000entries for an <literal>XX_id</literal> value.
19001If this value is present then the server supports authentication of this type.
19002Further permission checks are carried out and finally the
19003server will accept or reject the authentication request.
19004If the request is accepted the server returns a positive
19005acknowledgment (single 0 byte) to the requester,
19006otherwise it returns a nonzero value and an error message.</para>
19007
19008<para>If the request is accepted
19009then an authentication specific protocol exchange is carried out between
19010client and server.
19011The commands and/or data files
19012are encrypted and/or signed and transferred to the server.
19013The protocol specific software on the server will then decrypt and/or check
19014signatures,
19015perform the requested actions,
19016and in turn generate a status information.
19017The status information is encrypted and/or signed by the server
19018and sent to the client,
19019where the client decrypts and/or checked for correct signature.</para>
19020
19021<para>A <application>lpd</application> server to <application>lpd</application> server authenticated transfer
19022proceeds as follows.
19023If an authenticated transfer is specified by the
19024<literal>auth_forward=protocol</literal> entry in the printcap or configuration information,
19025the originating server sends a request for an authenticated transfer
19026to the destination server.
19027The originating server plays the part of the client
19028and performs the same set of actions.</para>
19029
19030<para>The following printcap or user level information needs to be provided
19031for an authenticated exchange.
19032<orderedlist>
19033
19034<listitem>
19035<para>The
19036<literal>auth</literal>
19037option specifies the authentication type to be used
19038for client to server transfers.
19039For example,
19040<literal>auth=kerberos</literal> or
19041<literal>auth=kerberos5</literal> or
19042would specify Kerberos 5 authentication,
19043<literal>auth=kerberos4</literal> would specify Kerberos 4 authentication,
19044<literal>auth=pgp</literal> would specify PGP authentication,
19045<literal>auth=md5</literal> would specify MD5 authentication,
19046etc.
19047The special form <literal>auth@</literal> specifies no authentication.</para>
19048</listitem>
19049
19050<listitem>
19051<para>The <literal>auth_forward</literal> option specifies the authentication type to be used
19052for server to server transfers.
19053For example,
19054<literal>auth_forward=kerberos5</literal> would specify Kerberos 5 authentication,
19055etc.
19056The special form <literal>auth@</literal> specifies no authentication.</para>
19057</listitem>
19058
19059<listitem>
19060<para>The authenticated transfer request sent to a server has one of the
19061following forms, depending on the originator:
19062<informalexample>
19063<screen>\008printer C user_id authtype \n  - for commands (lpq, lpc, etc.)
19064\008printer C user_id authtype size\n - for print jobs (lpr)
19065\008printer F server_id authtype \n - forwarded commands (lpq, lpc, etc.)
19066\008printer F server_id authtype size\n - forwarded print jobs (lpr)</screen>
19067</informalexample>
19068
19069</para>
19070
19071<para>The single character with the
19072<literal>\008</literal>
19073value signals that this
19074is an authentication request
19075the
19076<literal>printer</literal>
19077is the name of a print queue,
19078and the
19079<literal remap=tt>C</literal>
19080(client) or
19081<literal remap=tt>F</literal>
19082indicates that the request is from
19083a client program or is a forwarded request from a server.
19084The <literal>user_id</literal> or <literal>server_id</literal> field is an identifier supplied by
19085the originator and is discussed below.
19086If the
19087<literal>size</literal>
19088value is present then the request
19089is for a job transfer and this value represents the job size.
19090It is used to determine if there is sufficient space in the spool queue
19091for the job.</para>
19092</listitem>
19093
19094<listitem>
19095<para>The <literal>user_id</literal> or <literal>server_id</literal> fields in the authentication
19096request are obtained as follows.
19097If the request originates from a client,
19098then the <literal>user_id</literal> is the user name of the originator obtained from
19099password information.
19100If the request originates from a server,
19101then the  <literal>server_id</literal> is the printcap or configuration
19102<literal>xx_id=server_id</literal> value,
19103where
19104<literal>xx</literal>
19105is the value of the <literal>auth_forward=xx</literal> entry.</para>
19106</listitem>
19107
19108<listitem>
19109<para>When the authenticated transfer request is received,
19110the destination will either return a single zero byte,
19111or a non-zero byte value followed by additional refusal information.
19112A refusal terminates the protocol exchange.</para>
19113</listitem>
19114
19115<listitem>
19116<para>Further exchanges are then determined by the authentication
19117protocol specific requirements.</para>
19118</listitem>
19119
19120<listitem>
19121<para>Once the initial exchanges have been completed
19122a user file and/or command will be transferred to the destination server.</para>
19123</listitem>
19124
19125<listitem>
19126<para>An authentication protocol specific <acronym>AUTHFROM</acronym> and <acronym>AUTHUSER</acronym>
19127strings will be supplied
19128to the lpd server for purposes of permission checking.</para>
19129</listitem>
19130
19131<listitem>
19132<para>The lpd server then carries out the requested operation,
19133and will write error and status information into a file.</para>
19134</listitem>
19135
19136<listitem>
19137<para>After the requested activity has finished,
19138protocol specific module transfer the status information in the
19139file to the requesting system
19140and terminate the protocol exchange.</para>
19141</listitem>
19142
19143</orderedlist>
19144</para>
19145
19146</sect1>
19147
19148<sect1><title>Permission Checking</title>
19149
19150<para>When an authenticated transfer has been performed,
19151the following permission information will be provided.
19152<itemizedlist>
19153
19154<listitem>
19155<para>AUTH<!-- <br> -->
19156This value is
19157<literal>true</literal>
19158or
19159<literal>match</literal>
19160if an authenticated request
19161was received.</para>
19162</listitem>
19163
19164<listitem>
19165<para>AUTHTYPE=authtype<!-- <br> -->
19166This has the value of the
19167<literal>authtype</literal>
19168field in the authentication
19169request.</para>
19170</listitem>
19171
19172<listitem>
19173<para>AUTHUSER=userinfo<!-- <br> -->
19174This is the <acronym>AUTHUSER</acronym> information provided by the authentication
19175protocol,
19176and is usually the originating user's identification.</para>
19177</listitem>
19178
19179<listitem>
19180<para>AUTHFROM=frominfo<!-- <br> -->
19181This is the <acronym>AUTHUSER</acronym> information provided by the authentication
19182protocol,
19183and is usually the originating system (user or lpd server) identification.</para>
19184</listitem>
19185
19186<listitem>
19187<para>AUTHSAMEUSER<!-- <br> -->
19188This item has effect only when checking jobs in a spool queue.
19189The <acronym>AUTHUSER</acronym> information from the request is compared to the
19190<acronym>AUTHUSER</acronym> information from the request that created a job.
19191If they are identical,  the match succeeds.</para>
19192</listitem>
19193
19194<listitem>
19195<para>AUTHJOB
19196This item has effect only when checking jobs in a spool queue.
19197If the job was transfered using an authentication protocol the match succeeds.<!-- <br> --></para>
19198</listitem>
19199
19200</itemizedlist>
19201</para>
19202
19203<para>For example,  to reject non-authenticated operations, the following
19204line could be put in the permissions file.
19205<informalexample>
19206<screen>REJECT NOT AUTH</screen>
19207</informalexample>
19208</para>
19209
19210<para>If a remote server has id information FFEDBEEFDEAF,  then the
19211following will accept only forwarded jobs from this server.
19212<informalexample>
19213<screen>ACCEPT AUTH AUTHFROM=FFEDBEEFDEAF
19214REJECT AUTH
19215REJECT NOT AUTH</screen>
19216</informalexample>
19217</para>
19218
19219<para>To allow only authenticated users to remove jobs you can use:
19220<informalexample>
19221<screen>ACCEPT AUTH SERVICE=R,M,L,P AUTHSAMEUSER
19222REJECT AUTH
19223REJECT NOT AUTH</screen>
19224</informalexample>
19225</para>
19226
19227</sect1>
19228
19229<sect1><title>PGP Authentication Support</title>
19230
19231<para>PGP is a well known encryption and authentication program.
19232For more details see the web site
19233<ulink URL="http://www.pgp.net">http://www.pgp.net</ulink>
19234or the ftp site
19235<ulink URL="ftp://ftp.pgp.net">ftp://ftp.pgp.net</ulink>.</para>
19236
19237<para>&LPRng; has greatly simplified the use of PGP for authentication
19238by building in support as follows.
19239<itemizedlist>
19240
19241<listitem>
19242<para>The
19243<literal>user</literal>
19244and
19245<literal>group</literal>
19246configuration entry (defaults
19247<literal>daemon</literal> and <literal>daemon</literal> respectively) specify the user and group id
19248used by the <application>lpd</application> server for file and program execution.
19249PGP uses the current user id of the PGP process to determine the locations
19250of various configuration files and information.
19251In this discussion we will assume that <application>lpd</application> runs as uid <literal>daemon</literal>.</para>
19252</listitem>
19253
19254<listitem>
19255<para>By default,
19256the PGP program expects the public and secret key rings to be in the
19257<filename>$HOME/.pgp/</filename> directory
19258to be readable only by the user.
19259In order to set up PGP authentication,
19260make sure that the <literal>daemon</literal> account has a home directory.
19261Then use the
19262<literal>su daemon</literal>
19263command to change effective UID to daemon
19264and run the
19265<command>pgp -kg</command>
19266(generate key)
19267command as daemon.
19268The <literal>daemon</literal> user should not have a password.</para>
19269</listitem>
19270
19271<listitem>
19272<para>Each PGP key has an associated identifier.
19273It is recommended that the <application>lpd</application> key be <literal>lpr@hostname</literal>,
19274where hostname is the fully qualified domain name of the server.
19275A public and a private key file will be created.</para>
19276</listitem>
19277
19278<listitem>
19279<para>Next,
19280place the passphrase for the <literal>daemon</literal>
19281user in
19282<filename>~daemon/.pgp/serverkey</filename>,
19283and make sure it has owner <literal>daemon</literal>
19284and
19285<literal>600</literal>
19286permissions (read/write only by <literal>daemon</literal>).
19287This is extremely important.
19288If other users can read this file then security will be severely compromised.</para>
19289</listitem>
19290
19291<listitem>
19292<para>Next, distribute the <literal>lpr@hostname</literal> public key to all users of the
19293&LPRng; server.
19294This is usually done by placing the public key in a well known file location
19295or making it available to users by some form of Public Key Distribution system
19296(PKD).
19297The key can be extracted and put into a text file using the following commands:
19298<informalexample>
19299<screen>pgp -kxa userid destfile keyfile
19300
19301Example:
19302&gt; pgp -kxa lpr@astart /tmp/lprkey ~daemon/.pgp/pubring.pgp
19303Key for user ID: lpr@astart
19304512-bit key, key ID BB261B89, created 1999/01/01
19305
19306Transport armor file: /tmp/lprkey.asc
19307Key extracted to file '/tmp/lprkey.asc'.</screen>
19308</informalexample>
19309</para>
19310</listitem>
19311
19312<listitem>
19313<para>To allow a user to send files to the server,
19314their public key must be put into the <literal>daemon</literal> public key ring.
19315This can be done using:
19316<informalexample>
19317<screen>pgp -ka /tmp/lprkey.asc</screen>
19318</informalexample>
19319</para>
19320</listitem>
19321
19322<listitem>
19323<para>Finally,  the administrator will need to add users public keys to the
19324<literal>daemon</literal> users public key ring.  This can most easily be done by
19325copying all the keys (in ASCII text form) to a single file
19326(<filename>/tmp/keyfile</filename>)and using:
19327<informalexample>
19328<screen>su daemon
19329pgp -ka /tmp/keyfile ~daemon/.pgp/pubring.pgp</screen>
19330</informalexample>
19331</para>
19332</listitem>
19333
19334<listitem>
19335<para>If the <application>lpd</application> server is using PGP to forward jobs or requests,
19336the destination server's public key must be put in the originating
19337servers public keyring.  For example:
19338<informalexample>
19339<screen>su daemon
19340pgp -ka /tmp/lpd.keyfile ~daemon/.pgp/pubring.pgp</screen>
19341</informalexample>
19342</para>
19343</listitem>
19344
19345</itemizedlist>
19346</para>
19347
19348
19349<sect2 id="pgppath"><title>Printcap Configuration
19350
19351</title>
19352
19353<para>Options used:
19354<itemizedlist>
19355
19356<listitem>
19357<para><literal>pgp_path=</literal><emphasis>path to PGP program</emphasis></para>
19358</listitem>
19359
19360<listitem>
19361<para><literal>pgp_id=</literal><emphasis>destination server key used by clients</emphasis></para>
19362</listitem>
19363
19364<listitem>
19365<para><literal>pgp_forward_id=</literal><emphasis>destination server used by server</emphasis></para>
19366</listitem>
19367
19368<listitem>
19369<para><literal>pgp_server_key=</literal><emphasis>path to server passphrase file</emphasis></para>
19370</listitem>
19371
19372</itemizedlist>
19373</para>
19374
19375<para>Example printcap entry:
19376<informalexample>
19377<screen>pr:
19378    :lp=pr@wayoff
19379    :auth=pgp
19380    :pgp_id=lpr@wayoff.com
19381    :pgp_path=/usr/local/bin/pgp
19382pr:server
19383    :lp=pr@faroff
19384    :auth_forward=pgp
19385    :pgp_id=lpr@wayoff.com
19386    :pgp_path=/usr/bin/pgp
19387    :pgp_forward_id=lpr@faroff.com</screen>
19388</informalexample>
19389</para>
19390
19391<para>The <literal>pgp_path</literal> value is the path to the PGP program.
19392The program must be executable by all users.</para>
19393
19394<para>The <literal>pgp_id</literal> value is the id used by PGP to look extract keys from
19395key rings.
19396When doing a client to server transfer this will be supplied as the id
19397to be used for the destination,
19398and the user's public keyring will be checked for a key corresponding to
19399this id.
19400When a request arrives at the server,
19401the server will use this value as the id of a key in its private key ring.
19402Finally,
19403when a server is forwarding a request to a remote server,
19404it will use this value
19405as the id of the key in its private key ring to be used to sign
19406or encode the destination information.</para>
19407
19408<para>The <literal>pgp_forward_id</literal> value is used by the <application>lpd</application> server as the id
19409to use to find a key for the destination.</para>
19410
19411<para>The <literal>pgp_server_key</literal> is the path to the file containing the server passphrase.
19412This file will be read by <application>lpd</application> to get the passphrase to unlock the server's
19413keyring.</para>
19414
19415</sect2>
19416
19417<sect2><title>User Files and Environment Variables</title>
19418
19419<para>Options used:
19420<itemizedlist>
19421
19422<listitem>
19423<para><literal>PGPPASSFILE=</literal><emphasis>File to read PGP passphrase from</emphasis></para>
19424</listitem>
19425
19426<listitem>
19427<para><literal>PGPPASSFD=</literal><emphasis>File descriptor to read PGP passphrase from</emphasis></para>
19428</listitem>
19429
19430<listitem>
19431<para><literal>PGPPASS=</literal><emphasis>PGP passphrase</emphasis></para>
19432</listitem>
19433
19434</itemizedlist>
19435</para>
19436
19437<para>One problem with using PGP is the need to have users input their
19438passphrases.
19439The following methods can be used.
19440<itemizedlist>
19441
19442<listitem>
19443<para>Put the passphrase in a file,
19444say <filename>$(HOME)/.pgp/.hidden</filename>,
19445and set the <acronym>PGPPASSFILE</acronym> environment variable to the file name.
19446This file will be opened and read by PGP to get the passphrase.
19447This file should be owned by the user and have
19448<literal>0600</literal>
19449or read/write
19450only by user permissions.</para>
19451</listitem>
19452
19453<listitem>
19454<para>A more subtle solution is to use the <acronym>PGPPASSFD</acronym> environment variable
19455facility.
19456This causes PGP to read the passphrase from a file descriptor.
19457If the user puts his passphrase in a file,  say
19458<filename>$(HOME)/.pgp/.hidden</filename>,
19459then the following shell script can be used:
19460<informalexample>
19461<screen>#!/bin/sh
19462#  /usr/local/bin/pgplpr script - passphrase in $(HOME)/.pgp/.hidden
19463#
19464PGPASSFD=3 3&lt;$(HOME)/.pgp/.hidden lpr "$@"</screen>
19465</informalexample>
19466</para>
19467</listitem>
19468
19469<listitem>
19470<para>The least desirable method is to put the passphrase in the
19471<acronym>PGPPASS</acronym> environment variable.
19472Since the
19473<literal>ps</literal>
19474command can be used to list the environment variables
19475of processes,
19476this is highly undesirable and should not be used under any circumstances.</para>
19477</listitem>
19478
19479</itemizedlist>
19480</para>
19481
19482</sect2>
19483</sect1>
19484
19485<sect1 id=kerberos><title>Using Kerberos 5 for Authentication</title>
19486
19487<para>&LPRng; Kerberos 5 authentication is
19488based on the
19489Kerberos5-1.2.5 release as of 3 June 2002.
19490The distribution was obtained
19491from MIT from the
19492<emphasis remap=tt><ulink URL="http://web.mit.edu/kerberos/www/">http://web.mit.edu/kerberos/www/</ulink></emphasis>
19493Website.</para>
19494
19495<para>The following sections briefly describes
19496how to set up and test the Kerberos software
19497and then how to configure &LPRng; to use Kerberos.</para>
19498
19499
19500<sect2><title>&LPRng; Configuration</title>
19501
19502<para>The following <literal/configure/ options are used to enable
19503Kerberos support:
19504<informalexample>
19505<screen>
19506--enable-kerberos         enable Kerberos V support
19507--enable-mit_kerberos4    enable MIT Kerberos 4 support
19508--disable-kerberos_checks disable Kerberos sanity checks
19509</screen>
19510</informalexample>
19511</para>
19512
19513<para>
19514The <literal/--enable-kerberos/ option will 
19515cause <literal/configure/ to search for the
19516include files such as
19517<filename>krb5.h</filename>
19518and the
19519<literal>krb5</literal>
19520support libraries.
19521libraries.
19522If it finds these,
19523then Kerberos authentication will be included.
19524The <literal/--enable-mit_kerberos/ enable searching for 
19525the Kerberos 4 include files and support libraries.
19526If these are found then
19527MIT Kerberos 4 compatibility will
19528be enabled.
19529The <literal/--disable-kerberos_checks/ will disable checking for libraries
19530and simply enable the various options.
19531</para>
19532
19533</sect2>
19534
19535<sect2><title>Kerberos Installation Procedure </title>
19536
19537<para>
19538<orderedlist>
19539
19540<listitem>
19541<para> Get the Kerberos 5 distribution.</para>
19542</listitem>
19543
19544<listitem>
19545<para> Compile and install the distribution.</para>
19546</listitem>
19547
19548<listitem>
19549<para> Create the
19550<filename>/etc/krb5.conf</filename> and
19551<filename>/usr/local/var/krb5kdc/kdc.conf</filename>,
19552files using templates from the files in the
19553Kerberos distribution's
19554<filename>src/config-files</filename> directory.
19555See the Kerberos Installation Guide and the Kerberos System Administrators Guide for
19556details.</para>
19557</listitem>
19558
19559<listitem>
19560<para> Start up the KDC and KADMIN servers - you might want to put
19561the following in your
19562<filename>rc.local</filename>
19563or equivalent system startup files:
19564<informalexample>
19565<screen>if [ -f /etc/krb5.conf -a -f /usr/local/var/krb5kdc/kdc.conf  ]; then
19566    echo -n ' krb5kdc ';    /usr/local/sbin/krb5kdc;
19567    echo -n ' kadmind ';    /usr/local/sbin/kadmind;
19568fi</screen>
19569</informalexample>
19570</para>
19571</listitem>
19572
19573<listitem>
19574<para> Use kadmin (or kadmin.local) to create principals for your users.</para>
19575</listitem>
19576
19577<listitem>
19578<para> Use kadmin (or kadmin.local) to create principals for the
19579<application>lpd</application> servers.  The recommended method is to use
19580<filename>lpr/hostname@REALM</filename>
19581as a template for the principal name,
19582i.e. -
19583<literal>lpr/astart1.private@ASTART.COM</literal>
19584for an example.
19585You should use fully qualified domain names for the principals.
19586Do not assign the principal a password.
19587<informalexample>
19588<screen>Example:
19589
19590#&gt; kadmin   OR #> kadmin.local 
19591kadmin: addprinc -randkey lpr/wayoff.private@ASTART.COM
19592quit</screen>
19593</informalexample>
19594</para>
19595</listitem>
19596
19597<listitem>
19598<para> Extract the keytab for each server:
19599<informalexample>
19600<screen>
19601Example:
19602#> kadmin   OR #> kadmin.local 
19603ktadd -k /etc/lpr.wayoff.private  lpr/wayoff.private@ASTART.COM
19604quit</screen>
19605</informalexample>
19606</para>
19607</listitem>
19608
19609<listitem>
19610<para>The
19611<literal>/etc/lpr.wayoff.private</literal>
19612file contains the keytab information which is the
19613equivalent of a password for a server program.
19614You should create these files and then
19615copy the appropriate
19616<literal>keytab</literal>
19617file  to <filename>/etc/lpd.keytab</filename> file on each server.
19618See the warnings about of keytab files in the
19619Kerberos Installation and  Kerberos  Administration manuals.
19620You should copy the file using an encrypted connection,
19621set the permissions to read only by the owner (<literal>400</literal>),
19622and set the owner to
19623<literal>daemon</literal> or the user that <application>lpd</application> will run as.
19624<informalexample>
19625<screen>#&gt; chmod 400 lpr.wayoff.com
19626#&gt; scp lpr.wayoff.com root@wayoff.com:/etc/lpd.keytab
19627#&gt; ssh -l root wayoff.com
19628# wayoff &gt; chmod 400 /etc/lpd.keytab  
19629# wayoff &gt; chown daemon /etc/lpd.keytab  
19630# wayoff &gt; ls -l /etc/lpd.keytab  
19631-rw-------  1 daemon  wheel  128 Jan 16 11:06 /etc/lpd.keytab</screen>
19632</informalexample>
19633</para>
19634</listitem>
19635
19636<listitem>
19637<para>If you want to have MIT Kerberos4 printing compatibility
19638then you will need to set up Kerberos 4
19639<literal>servertabs</literal>
19640instead of Kerberos 5 keytabs.
19641Assuming that you have put the Kerberos 5 keytab in <filename>/etc/lpd.keytab</filename>,
19642then you extract the Kerberos 4 srvtab version of the Kerberos 5 keytab using
19643the following commands.
19644You must put the key in the <filename>/etc/srvtab</filename> file
19645in order to be compatible with the Kerberos 4 support.
19646<informalexample>
19647<screen><prompt>h4: {321} # </prompt><userinput>ktuil</userinput>
19648<userinput>rkt /etc/lpd.keytab</userinput>
19649<userinput>wst /etc/srvtab</userinput></screen>
19650</informalexample>
19651</para>
19652</listitem>
19653
19654</orderedlist>
19655</para>
19656
19657</sect2>
19658
19659<sect2><title>&LPRng; Configuration</title>
19660
19661<para>The &LPRng;  software needs to be configured so that it can find the
19662Kerberos libraries and include files.
19663By default,
19664the include files are installed in
19665<filename>/usr/local/include</filename>
19666and the libraries in
19667<filename>/usr/local/lib</filename>.
19668Use the following steps to configure &LPRng; so that it uses these
19669directories during configuration and installation:
19670<informalexample>
19671<screen>cd .../LPRng
19672rm -f config.cache
19673CPPFLAGS="-I/usr/local/include -I/usr/include/kerberosIV" \
19674  LDFLAGS="-L/usr/local/lib -L/usr/lib/kerberosIV" \
19675  ./configure
19676make clean all
19677su
19678make install</screen>
19679</informalexample>
19680</para>
19681
19682</sect2>
19683
19684<sect2><title>Printcap Entries</title>
19685
19686<para>Options used:
19687<itemizedlist>
19688
19689<listitem>
19690<para><literal>auth=kerberos5</literal><emphasis>use Kerberos5 authentication</emphasis></para>
19691</listitem>
19692
19693<listitem>
19694<para><literal>kerberos_id=</literal><emphasis>server prinicpal name (for client use)</emphasis></para>
19695</listitem>
19696
19697<listitem>
19698<para><literal>kerberos_server_principal=</literal><emphasis>alias for kerberos_id</emphasis></para>
19699</listitem>
19700
19701<listitem>
19702<para><literal>kerberos_forward_id=</literal><emphasis>destination server used by server</emphasis></para>
19703</listitem>
19704
19705<listitem>
19706<para><literal>kerberos_forward_principal=</literal><emphasis>alias for kerberos_forward_id</emphasis></para>
19707</listitem>
19708
19709<listitem>
19710<para><literal>kerberos_keytab=</literal><emphasis>location of the lpd server keytab file</emphasis></para>
19711</listitem>
19712
19713<listitem>
19714<para><literal>kerberos_service=</literal><emphasis>service to be used</emphasis></para>
19715</listitem>
19716
19717<listitem>
19718<para><literal>kerberos_life=</literal><emphasis>lpd server ticket lifetime</emphasis></para>
19719</listitem>
19720
19721<listitem>
19722<para><literal>kerberos_renew=</literal><emphasis>lpd server ticket renew</emphasis></para>
19723</listitem>
19724
19725</itemizedlist>
19726</para>
19727
19728<para>Example printcap entry:
19729<informalexample>
19730<screen>pr:client
19731    :lp=pr@wayoff
19732    :auth=kerberos5
19733    :kerberos_id=lpr/wayoff.private@ASTART.COM
19734pr:server
19735    :lp=pr@faroff.private
19736    :auth_forward=kerberos5
19737    :kerberos_id=lpr/wayoff.private@ASTART.COM
19738    :kerberos_forward_id=lpr/faroff.private@ASTART.COM
19739    :kerberos_keytab=/etc/lpd.keytab
19740
19741OR If you want to use Kerberos 4 authentication to the server
19742pr:client
19743    :lp=pr@wayoff
19744    :auth=kerberos4
19745    :kerberos_id=lpr/wayoff.private@ASTART.COM
19746# support both Kerberos 4 and 5 on server
19747pr:server
19748    :lp=pr@faroff.private
19749    :auth_forward=kerberos5
19750    :kerberos_id=lpr/wayoff.private@ASTART.COM
19751    :kerberos_forward_id=lpr/faroff.private@ASTART.COM
19752    :kerberos_keytab=/etc/lpd.keytab
19753</screen>
19754</informalexample>
19755</para>
19756
19757<para>The printcap configuration for Kerberos authentication is very simple.</para>
19758
19759<para>The <literal>kerberos_id</literal> is the principal name of the lpd server
19760that clients will connect to.
19761For backwards compatibility,
19762<literal>kerberos_server_principal</literal> can also be used.
19763This values is used to obtain a ticket for the <application>lpd</application> server,
19764and is the only entry required for client to server authentication.</para>
19765
19766<para>The other entries are used by the <application>lpd</application> server.
19767<literal>kerberos_keytab</literal>
19768entry is the location of the keytab file to be used by the server.
19769This contains the passphrase used by the server to authenticate itself
19770and get a ticket from the ticket server.</para>
19771
19772<para>The <literal>kerberos_id</literal> value is also used by the server during the
19773authentication process to make sure that the correct principal name
19774was used by the request originator.
19775This check has saved many hours of pain in trying to determine why
19776authentication is failing.</para>
19777
19778<para>The
19779<literal>kerberos_life</literal> and <literal>kerberos_renew</literal>
19780set the lifetime and renewability
19781of the lpd server Kerberos tickets.
19782These values should not be modified unless you are familiar with the
19783Kerberos system.
19784There are extensive notes in the &LPRng; source code concerning these values.
19785The <literal>kerberos_service</literal> value supplies the name of the service
19786to be used when generating a ticket.
19787It is stronly recommended that the <literal>kerberos_id</literal> entry
19788be used instead.</para>
19789
19790</sect2>
19791
19792<sect2><title>User Environment Variables and Files</title>
19793
19794<para>In order to use kerberos authentication,
19795the user will need to obtain a ticket from the Kerberos ticket server.
19796This is done using
19797<literal>kinit</literal>.</para>
19798
19799<para>No other actions are required by the user.</para>
19800
19801</sect2>
19802</sect1>
19803
19804<sect1><title>Using Kerberos 4 for Authentication</title>
19805
19806<para>&LPRng; has built-in support for the Project Athena extensions to the
19807RFC1179 protocol.
19808These provide an extremely simple authentication protocol
19809using an initial credential exchange.
19810After the initial exchange the usual RFC1179 protocol is used.</para>
19811
19812<para>During configuration,
19813if the <filename>krb.h</filename> (Kerberos 4) include file is found,
19814then this is enabled by default.</para>
19815
19816
19817<sect2><title>Printcap Entries</title>
19818
19819<para>Options used:
19820<itemizedlist>
19821
19822<listitem>
19823<para><literal>auth=kerberos4</literal><emphasis>use Kerberos4 authentication</emphasis></para>
19824</listitem>
19825
19826<listitem>
19827<para><literal>kerberos_id=</literal><emphasis>destination server key used by clients</emphasis></para>
19828</listitem>
19829
19830<listitem>
19831<para><literal>kerberos_server_principal=</literal><emphasis>alias for kerberos_id</emphasis></para>
19832</listitem>
19833
19834</itemizedlist>
19835</para>
19836
19837<para>Example printcap entry:
19838<informalexample>
19839<screen>pr:
19840    :lp=pr@wayoff
19841    :auth=kerberos4
19842    :kerberos_id=lpr/wayoff.private@ASTART.COM</screen>
19843</informalexample>
19844</para>
19845
19846<para>The configuration information for Kerberos4 and Kerberos5 is identical
19847and differ only in the authentication type.
19848Note that only client to server authentication is supported.</para>
19849
19850</sect2>
19851</sect1>
19852
19853<sect1><title>Using SSL for Authentication</title>
19854<para>&LPRng; has built-in support for using SSL as an
19855authentication method.
19856The implementation is based on OpenSSL 0.9.6c
19857and the associated libraries as of
19858of 3 June 2002.
19859The distribution was obtained
19860from the OpenSSL group from the
19861<emphasis remap=tt><ulink URL="http://www.openssl.org">http://www.openssl.org</ulink></emphasis>
19862Website.
19863</para>
19864
19865<para>
19866SSL authentication is based a private key/secret key technology,
19867where the various keys are placed in files (or data structures) called
19868<emphasis/certificates/ or <literal/certs/,
19869and the certificates are
19870<emphasis/signed/ by calculating a checksum over the certificate,
19871encypting the checksum and other information using the private key
19872of a
19873<emphasis/signing/ certificate. 
19874The top level or <emphasis/root/ certificate is signed by its own key;
19875lower level signing certificates can be created which are signed by the
19876top level or root certificate,
19877and in turn can sign other signing certificates.
19878User certificates can be created and signed by a signing certificate
19879which can be used in the SSL protocol for authentication purposes.
19880The following objects are needed to use SSL encryption.
19881</para>
19882
19883<para>
19884<orderedlist>
19885
19886<listitem>
19887<para>
19888A top level or root certificates and a set of signing certificates.
19889By convention,
19890these are stored in the
19891<filename>/etc/lpd/ssl.ca</filename>
19892directory;
19893the root certificate is usually the
19894<filename>ca.crt</filename>
19895file.
19896</para>
19897</listitem>
19898
19899<listitem>
19900<para>
19901Each server has a certificate and private key  file which are used to identify the
19902server and sign the SSL messages.
19903The private key file is usually stored in an encrypted form and a password
19904is required unlock the file.
19905By convention,
19906the server files are stored in the
19907<filename>/etc/lpd/ssl.server</filename>
19908directory;
19909the 
19910<filename>server.crt</filename>
19911file contains the server certificate and (encrypted) private key;
19912the
19913<filename>server.pwd</filename>
19914file contains the password to decrypt the private key.
19915</para>
19916</listitem>
19917
19918<listitem>
19919<para>
19920Each user has a certificate and private key  file which are used to identify the
19921user and sign the SSL messages.
19922The private key file is usually stored in an encrypted form and a password
19923is required unlock the file.
19924By convention,
19925the user files are stored in the
19926<filename>${HOME}/.lpr</filename>
19927directory;
19928the 
19929<filename>client.crt</filename>
19930file contains the client certificate and (encrypted) private key;
19931the
19932<filename>client.pwd</filename>
19933file contains the password to decrypt the private key.
19934</para>
19935</listitem>
19936
19937<listitem>
19938<para>
19939A utility to create and manage the SSL certificate files.
19940</para>
19941</listitem>
19942
19943</orderedlist>
19944
19945</para>
19946
19947<para>
19948The locations of the SSL files can be specified by various options
19949to <application/configure/ facility
19950and by values in the the <literal/lpd.conf/ file.
19951</para>
19952
19953<sect2><title>Certificate Management</title>
19954<para>
19955The <application/lprng_cert/ utility is used to set up the various
19956directories and files required for SSL authentication.
19957This code was derived from similar facilities developed for
19958the <literal/mod_ssl/ extensions to the <application/Apache/
19959web server.
19960This interactive utility is very verbose and has extensive comments and
19961assistance. 
19962<informalexample>
19963<screen>h110: {111} % lprng_certs
19964lprng_certs -- LPRng SSL Certificate Management
19965Copyright (c) 2002 Patrick Powell
19966Based on CCA by Ralf S. Engelschall
19967(Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.)
19968
19969usage: lprng_certs option
19970  init              - make directory structure
19971  newca             - make new root CA and default values for certs
19972  defaults          - set new default values for certs
19973  gen               - generate user, server, or signing cert
19974  verify [cert]     - verify cert file
19975  index [dir]       - make certificate index files in directory dir
19976  encrypt keyfile   - set or change password on private key file
19977</screen>
19978</informalexample>
19979</para>
19980
19981<para>
19982The <literal/lprng_certs init/ option will create the
19983necessary directories for the &LPRng; software on a system.
19984The <literal/lprng_certs newca/ option will create the root level
19985certificate and set up a set of defaults for the creation of other
19986certificates.
19987The <literal/lprng_certs defaults/ option allows viewing and editting of the various
19988default values.
19989The <literal/lprng_certs gen/ option is used to create and sign new certificate files.
19990The OpenSSL software assumes that the file names of the signing certificate files have a special
19991format; the <literal/lprng_certs index/ creates links of the required format to the
19992certificate files.
19993Finally,
19994the <literal/lprng_certs verify/ and
19995the <literal/lprng_certs encrypt/ facilities can be used to
19996verify that the certificate files have the proper format and to
19997change the private key password respectively.
19998</para>
19999
20000</sect2>
20001
20002<sect2><title>Creating Root Certificate</title>
20003<para>
20004The <literal/lprng_certs newca/
20005option is used to create a new root signing certificate and to establish defaults.
20006<informalexample>
20007<screen>h110: {112} #> lprng_certs newca
20008lprng_certs -- LPRng SSL Certificate Management
20009Copyright (c) 2002 Patrick Powell
20010Based on CCA by Ralf S. Engelschall
20011(Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.)
20012
20013INITIALIZATION - SET DEFAULTS
20014...  
20015______________________________________________________________________
20016
20017STEP 1: Generating RSA private key for CA (1024 bit)
20018______________________________________________________________________
20019
20020STEP 2: Generating X.509 certificate signing request for CA
20021______________________________________________________________________
20022
20023STEP 3: Generating X.509 certificate for CA signed by itself
20024______________________________________________________________________
20025
20026RESULT:
20027/etc/lpd/ssl.ca/ca.crt:
20028/C=US/ST=California/L=San Diego/O=Astart/OU=Certificate Authority/\
20029 CN=Astart CA/Email=id@astart.com
20030error 18 at 0 depth lookup:self signed certificate
20031OK
20032______________________________________________________________________
20033
20034STEP 4. Encrypting RSA private key with a pass phrase for security
20035The contents of the certificate key file (the generated private
20036key) should be echo kept secret, especially so if it is used to
20037sign Certificates or for User authentication.  SSL experts strongly
20038recommend you to encrypt the key file with a Triple-DES cipher and
20039a Pass Phrase.  When using LPRng, you provide the password via a
20040file specified by the LPR_SSL_PASSWORD environent variable, or in
20041the ${HOME}/.lpr/client.pwd file.  The LPD server uses the
20042ssl_server_password_file option to specify the location of a file
20043containing the password.  See the LPRng Reference Manual for details, or the
20044printcap(5) man page.
20045
20046key file is /etc/lpd/ssl.ca/ca.key
20047Encrypt the private key now? [Y/n]: y
20048Fine, you're using an encrypted private key to sign CERTS.
20049</screen>
20050</informalexample>
20051</para>
20052</sect2>
20053
20054<sect2><title>Creating Client and Server Certificates</title>
20055<para>
20056The <literal/lprng_certs gen/
20057option allows the creation of client and server identification
20058certificates.
20059By convention,
20060these are created in a default directory and the
20061system administrator then copies them to the appropriate client
20062or server directory.
20063
20064<informalexample>
20065<screen>h110: {112} #> lprng_certs gen
20066lprng_certs -- LPRng SSL Certificate Management
20067Copyright (c) 2002 Patrick Powell
20068Based on CCA by Ralf S. Engelschall
20069(Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.)
20070
20071CERTIFICATE GENERATION
20072What type of certificate? User/Server/Signing Authority/Help? [u/s/a/H]
20073Create in '/etc/lpd/ssl.certs' [return for yes, or specify directory]
20074CERT name 'user-10'? [return for yes, or specify name] papowell
20075CERT name 'papowell'? [return for yes, or specify name] 
20076Creating papowell in /etc/lpd/ssl.certs
20077Sign with Certificate '/etc/lpd/ssl.ca/ca.crt' \
20078   [return for yes, ? for list, or specify cert file] ?
20079Possible CERTS in directory '/etc/lpd/ssl.ca' are:
20080/etc/lpd/ssl.ca/ca.crt
20081/etc/lpd/ssl.ca/signer1.crt
20082/etc/lpd/ssl.ca/tsign.crt
20083Sign with Certificate '/etc/lpd/ssl.ca/ca.crt'  \
20084  [return for yes, ? for list, or specify cert file] signer1
20085Match Found /etc/lpd/ssl.ca/signer1.crt
20086Sign with Certificate '/etc/lpd/ssl.ca/signer1.crt'  \
20087  [return for yes, ? for list, or specify cert file]
20088Private key in /etc/lpd/ssl.ca/signer1.crt
20089
20090Generating user Certificate [papowell] 
20091
20092STEP 1: Generating RSA private key for user (1024 bit)
20093
20094STEP 2: Generating X.509 certificate signing request for user
20095....
20096
20097STEP 3: Generating X.509 certificate signed by /etc/lpd/ssl.ca/signer1.crt
20098...
20099
20100RESULT:
20101/etc/lpd/ssl.certs/papowell.crt: OK
20102
20103STEP 4. Enrypting RSA private key /etc/lpd/ssl.certs/papowell.key
20104  with a pass phrase for security
20105
20106Encrypt the private key now? [Y/n]: Fine, you're using an encrypted
20107  private key to sign CERTS.
20108
20109STEP 5: Combine CERT and KEY file
20110Generate single CERT and KEY file? [Y/n] 
20111
20112Use the following commands to examine the CERT and KEY files:
20113   openssl x509 -text -in /etc/lpd/ssl.certs/papowell.crt
20114   openssl rsa -text -in /etc/lpd/ssl.certs/papowell.crt
20115</screen>
20116</informalexample>
20117</para>
20118
20119<para>
20120After the certificate file has been created,
20121then it should be copied to the appropriate location:
20122<filename>/etc/lpd/ssl.server/server.crt</filename>
20123and the password in
20124<filename>/etc/lpd/ssl.server/server.pwd</filename>,
20125for a server
20126or
20127<filename>${HOME}/.lpr/client.crt</filename>
20128and the password in
20129<filename>${HOME}/.lpr/client.pwd</filename>
20130for a user.
20131</para>
20132</sect2>
20133
20134<sect2><title>Creating Signing Certificates</title>
20135<para>
20136Having only one signing certificate, i.e. - the root certificate,
20137may make it difficult to delegate authority for the creation of user
20138certificates and/or server certificates.
20139The <literal/lprng_certs gen/ facility can be used to create a
20140certificate that can be used to sign other certificates.
20141</para>
20142
20143<sect2><title>Permissions and Certificate Revocation</title>
20144<para>
20145The certificate revocation facility is not implemented in
20146&LPRng;, due to various technical and management issues.
20147Instead, the
20148<literal/AUTHUSER/ and
20149<literal/AUTHCA/ and
20150</para>
20151
20152</sect1>
20153
20154<sect1><title>Using MD5 for Authentication</title>
20155
20156<para>&LPRng; has built-in support for using MD5 digests as an
20157authentication method.
20158The implementation is provided as an example of how to
20159add user level authentication into the &LPRng; system.</para>
20160
20161<para>The method used to do authentication is very simple.
20162Each user has a file containing a set of keys that are used to salt an
20163md5 hash.
20164The information being transferred has its md5 checksum calculated using
20165this salt,
20166and is then transferred to the destination,
20167along with the md5 hash result.
20168At the destination the server will get the user id,
20169obtain the salt value from a key file,
20170and then calculate the md5 hash value.
20171If the two are in agreement,
20172authentication is successful.</para>
20173
20174<para>The keyfile used for md5 authentication contains an id followed by
20175a text string whose binary value is used as a hash key:
20176<informalexample>
20177<screen>id1=key
20178id2=key
20179
20180Example:
20181
20182lpr@h2=tadf79asd%^1asdf
20183lpr@h1=fdfa%$^&amp;^%$
20184</screen>
20185</informalexample>
20186</para>
20187
20188
20189<sect2><title>Printcap Entries</title>
20190
20191<para>Options used:
20192<itemizedlist>
20193
20194<listitem>
20195<para><literal>auth=md5</literal><emphasis>use MD5 authentication</emphasis></para>
20196</listitem>
20197
20198<listitem>
20199<para><literal>auth_forward=md5</literal><emphasis>forward using MD5 authentication</emphasis></para>
20200</listitem>
20201
20202<listitem>
20203<para><literal>md5_id=</literal><emphasis>id for server</emphasis></para>
20204</listitem>
20205
20206<listitem>
20207<para><literal>md5_forward_id=</literal><emphasis>id for server</emphasis></para>
20208</listitem>
20209
20210<listitem>
20211<para><literal>md5_server_keyfile=</literal><emphasis>server keyfile</emphasis></para>
20212</listitem>
20213
20214</itemizedlist>
20215</para>
20216
20217<para>Example printcap entry:
20218<informalexample>
20219<screen>pr:
20220    :lp=pr@wayoff
20221    :auth=md5
20222    :md5_id=lpr@wayoff.com
20223pr:server
20224    :auth_forward=md5
20225    :md5_id=lpr@wayoff.com
20226    :md5_server_keyfile
20227    :md5_forward_id=lpr@faroff.com</screen>
20228</informalexample>
20229</para>
20230
20231<para>The <literal>md5_id</literal> value is used by the client to obtain
20232a hash key that is used to salt the md5 calculation for client to server
20233transfers.
20234The <literal>md5_forward_id</literal> value is used by the server to obtain
20235a hash key that is used to salt the md5 calculation for server to server transfers.</para>
20236
20237<para>The <literal>md5_server_keyfile</literal> contains the keys of users;
20238the id sent as the connection information is used to obtain the key from the file.</para>
20239
20240<para>To set up md5 authentication,
20241all that is needed is the following.
20242<itemizedlist>
20243
20244<listitem>
20245<para>For each user generate a key and place it in the server keyfile.
20246This file should have the form:
20247<informalexample>
20248<screen>user1@host1=asdfasdfadf
20249user2@host2=a8789087asddasdf</screen>
20250</informalexample>
20251</para>
20252</listitem>
20253
20254<listitem>
20255<para>Assign a key to the server, and set its printcap entry to this key.
20256<informalexample>
20257<screen>pr:
20258    :lp=pr@wayoff
20259    :auth=md5
20260    :md5_id=lpr@wayoff.com</screen>
20261</informalexample>
20262</para>
20263</listitem>
20264
20265<listitem>
20266<para>For each user, create a user key file with the following format:
20267<informalexample>
20268<screen>lpr@wayoff = user1@host1 asdfasdfadf</screen>
20269</informalexample>
20270
20271The first entry corresponds to the <literal>md5_id</literal> value in the printcap.
20272The second field is the <acronym>AUTHUSER</acronym> value supplied to the server
20273and which will be used to look up the key in the servers key file.
20274Finally,
20275the last field is the salt value for the md5 calculation.</para>
20276</listitem>
20277
20278</itemizedlist>
20279</para>
20280
20281</sect2>
20282
20283<sect2><title>User Environment Variables and Files</title>
20284
20285<para>Options used:
20286<itemizedlist>
20287
20288<listitem>
20289<para><literal>MD5KEYFILE=5</literal><emphasis>location of user keyfile</emphasis></para>
20290</listitem>
20291
20292</itemizedlist>
20293</para>
20294
20295<para>The
20296<literal>MD5KEYFILE</literal>
20297environment variable contains the path to the
20298user keytab file.</para>
20299
20300</sect2>
20301</sect1>
20302
20303<sect1><title>Adding Authentication Support</title>
20304
20305<para>Additional types of authentication support can be added very easily to
20306&LPRng; by using the following conventions and guidelines.</para>
20307
20308<para>First,
20309the authentication method can be connection based or transfer based.
20310Connection based authentication involves the &LPRng; client or server
20311opening a connection to the remote server,
20312having the authentication protocol provide authentication information,
20313and then having no further interaction with the system.
20314This is the easiest to implement and understand method.
20315Code needs to be provided to do a simple authentication exchange
20316between the two ends of the connection,
20317after which no other action needs to be taken.</para>
20318
20319<para>Transfer based authentication is more complex,
20320but allows encrypted transfers of information between the two systems.
20321A connection is established between client and server (or server and server),
20322and an initial protocol exchange is performed.
20323Then the authentication module transfers the command or job information
20324to the destination,
20325where is it unpacked and/or decrypted.
20326The internal <application/lpd/ server facilities are then invoked by the authentication
20327module,
20328which also provides a destination for any error message or information
20329destined for the client.
20330The authentication module will encrypt or encode this information and then
20331send it to the client program.
20332This type of authentication is more complex,
20333but provides a higher degree of security and reliability than the
20334simple connection based system.</para>
20335
20336
20337<sect2><title>Printcap Support</title>
20338
20339<para>By convention,
20340printcap entries
20341<literal>auth=XXX</literal>
20342and
20343<literal>auth_forward=XXX</literal>
20344specifies that authentication protocol <acronym>XXX</acronym>
20345is to be used for client to server
20346and for server to server transfers respectively.</para>
20347
20348<para>Similarly,
20349the server receiving an authentication request must have a
20350<literal>XXX_id=name</literal> entry in the printcap or configuration information.
20351This allows several different authentication protocols to be accepted
20352by a server.</para>
20353
20354<para>By convention,
20355printcap and configuration entries of the form
20356<literal>XXX_key</literal>
20357contain configuration information for the <acronym>XXX</acronym> authentication protocol.
20358As part of the authentication support process the <literal>XXX_key</literal> values
20359are extracted from the printcap and configuration files
20360and placed in a simple database for the authentication support module.</para>
20361
20362<para>If you are using a routing filter,
20363then you can also place
20364<literal>XXX_key</literal>
20365information in the routing entry for each file,
20366and this will be used for sending the job to the specified destination.</para>
20367
20368</sect2>
20369
20370<sect2><title>Code Support</title>
20371
20372<para>The <filename>LPRng/src/common/sendauth.c</filename>
20373file has the following entries at the end.
20374<informalexample>
20375<screen>#define SENDING
20376#include "user_auth.stub"
20377
20378struct security SendSecuritySupported[] = {
20379  /* name,       config_tag, connect,    send,   receive */
20380  { "kerberos4", "kerberos", Send_krb4_auth, 0, 0 },
20381  { "kerberos*", "kerberos", 0,           Krb5_send },
20382  { "pgp",       "pgp",      0,           Pgp_send },
20383#if defined(USER_SEND)
20384 USER_SEND
20385#endif
20386  {0}
20387};</screen>
20388</informalexample>
20389
20390This is an example of how to add user level authentication support.
20391The <filename>user_auth.stub</filename>
20392file contains the source code for the various modules authentication
20393modules.
20394You can replace this file with your own version
20395if desired.
20396The following fields are used.
20397<variablelist>
20398<varlistentry><term> name </term>
20399<listitem>
20400<para>The authentication name.
20401The <literal>auth=XXX</literal> printcap or configuration value will cause the
20402<literal>name</literal>
20403fields to be searched using a
20404glob match.</para>
20405
20406</listitem>
20407</varlistentry>
20408
20409<varlistentry><term> config_tag</term>
20410
20411<listitem>
20412<para>When a match is found,
20413the <literal>config_tag</literal> value is used to search
20414the printcap and configuration entries for information.
20415If the <literal>config_tag</literal> field has value <acronym>XXX</acronym>,
20416then entries with keys <literal>XXX_key</literal> will be extracted for use
20417by the authentication code.</para>
20418
20419</listitem>
20420</varlistentry>
20421
20422<varlistentry><term>connect</term>
20423
20424<listitem>
20425<para>Routine to call to support
20426<literal>connection</literal>
20427level authentication.
20428This routine is responsible for connection establishment and
20429protocol handshake.
20430If the value is 0,
20431then the
20432<literal>send</literal>
20433field value will be used.</para>
20434
20435</listitem>
20436</varlistentry>
20437
20438<varlistentry><term>send</term>
20439
20440<listitem>
20441<para>Routine to call to support
20442<literal>transfer</literal>
20443level authentication.
20444The
20445<literal>send</literal>
20446routine is provided a file and a connection to the remote server,
20447and is responsible for the transferring files.</para>
20448
20449</listitem>
20450</varlistentry>
20451</variablelist>
20452</para>
20453
20454<para>The
20455<filename>LPRng/src/common/lpd_secure.c</filename>
20456file has the following information at the end:
20457<informalexample>
20458<screen>#define RECEIVE 1
20459#include "user_auth.stub"
20460
20461 struct security ReceiveSecuritySupported[] = {
20462    /* name, config_tag, connect, send, receive */
20463#if defined(HAVE_KRB_H) &amp;&amp; defined(MIT_KERBEROS4)
20464    { "kerberos4", "kerberos",  0, 0, 0 },
20465#endif
20466#if defined(HAVE_KRB5_H)
20467    { "kerberos*", "kerberos",   0, 0, Krb5_receive },
20468#endif
20469    { "pgp",       "pgp",   0, 0, Pgp_receive, },
20470#if defined(USER_RECEIVE)
20471/* this should have the form of the entries above */
20472 USER_RECEIVE
20473#endif
20474    {0}
20475};</screen>
20476</informalexample>
20477</para>
20478
20479<para>This information matches the same information in the <filename>sendauth.c</filename>
20480file.
20481When the authentication request arrives at the server,
20482the
20483<literal>name</literal>
20484field values are searched for a match,
20485and then the <literal>config_tag</literal> value is used to get extract configuration
20486information from the database for the protocol.</para>
20487
20488<para>The
20489<literal>receive</literal>
20490routine is then called and is expected to handle the remaining
20491steps of the authentication protocol.
20492If the routine exits with a 0 value then the lpd server expects
20493<literal>connection</literal>
20494level authentication has been done and proceeds to
20495simply transfer information using the standard RFC1179 protocol steps.
20496A non-zero return value indicates an error and an error is reported
20497to the other end of the connection.</para>
20498
20499<para>If the
20500<literal>receive</literal>
20501module is to perform
20502<literal>transfer</literal>
20503level authentication,
20504then the module carries out the necessary steps to transfer the command and/or
20505job information.
20506It then calls the necessary internal &LPRng; routine to implement the desired
20507services.
20508After finishing the requested work,
20509these routines return to the calling authentication module,
20510which then will transfer data, close the connection to the
20511remote system,
20512and return to the calling system.
20513The combination of 0 return value and closed connection
20514indicates successful transfer level authentication to the server.</para>
20515
20516<para>The <filename>user_auth.stub</filename> file contains the following code that sets the
20517<literal>USER_SEND</literal> variable:
20518<informalexample>
20519<screen>#if defined(SENDING)
20520extern int md5_send();
20521#  define USER_SEND \
20522  { "md5", "md5", md5_send, 0, md5_receive },
20523#endif</screen>
20524</informalexample>
20525</para>
20526
20527<para>If the <acronym>SENDING</acronym> value has been defined,
20528this causes the prototype for <function>md5_send()</function> to be place in the file
20529and the <literal>USER_SEND</literal> value to be defined.
20530This will cause the
20531<literal>md5</literal>
20532authentication information to be placed in the
20533correct table.</para>
20534
20535</sect2>
20536
20537<sect2><title>Connection and Transfer Authentication</title>
20538
20539<para>Rather than go into a detailed description of the code,
20540the <filename>user_auth.stub</filename> file contains extremely detailed examples
20541as well as several working versions of authentication information.
20542It is recommended that the user start with one of these and then
20543modify it to suit themselves.</para>
20544
20545</sect2>
20546</sect1>
20547</chapter>
20548
20549<chapter id=accountingref><title>Accounting </title>
20550
20551<para>In Academic institutions, avoiding printing accounting has been
20552regarded as a challenge,  an ongoing game of fat cat and poor starving
20553mouse, between the brutal and corrupt Administration and the poor, downtrodden, over-charged
20554student.
20555We will disregard the fact that if most students put as much effort
20556into their studies as in finding ways to avoid accounting procedures
20557then they would be Rhodes Scholar material,  but I digress...</para>
20558
20559<para>
20560There are two approaches to printing accounting:
20561use software determine the number of pages that should be printed
20562or use a hardware pagecounter facility on the printer to accurately
20563determine the number of pages used.
20564While the software method works well in a relatively error
20565and security compromise free environment
20566and where print jobs do not jam,
20567for accurate account a hardware level pagecounter or some other
20568method must be used.
20569LPRng provides facilities to use either method to determine page counts.
20570</para>
20571
20572<para>
20573There are also two methods available to store the actual accounting information:
20574the simple <emphasis/save to file/ method and the more complex
20575<emphasis/save to program/ method.
20576LPRng provides support for both methods.
20577</para>
20578
20579<sect1 id="accountingserver"><title>Accounting Printcap Options </title>
20580
20581<para>The accounting facilities are controlled and enabled by the following
20582entries in the printcap file.
20583</para>
20584
20585<informaltable frame=all>
20586<tgroup cols=3 align=left rowsep=1 colsep=1>
20587<thead>
20588<row><entry>Tag</entry><entry>Default Value</entry><entry>Purpose</entry></row>
20589</thead>
20590<tbody>
20591<row><entry>af</entry><entry>NULL</entry><entry>accounting file name</entry></row>
20592<row><entry>as</entry><entry>"jobstart $H $n $P $k $b $t"</entry><entry>accounting info for job start</entry></row>
20593<row><entry>ae</entry><entry>"jobend $H $n $P $k $b $t"</entry><entry>accounting info for job end</entry></row>
20594<row><entry>achk</entry><entry>FALSE</entry></row>
20595<row><entry>la</entry><entry>TRUE</entry><entry>do accounting for 'local' printer</entry></row>
20596<row><entry>ar</entry><entry>FALSE</entry><entry>do accounting for 'remote' transfers</entry></row>
20597</tbody>
20598</tgroup>
20599</informaltable>
20600
20601</sect1>
20602
20603<sect1><title>Accounting Information</title>
20604
20605<para>
20606The <literal/:as=.../ and <literal/:ae=.../ options specify the
20607the start of job and end of job accounting information
20608or a set of programs to be run to record the start and end of job
20609accounting information. 
20610The option values are expanded using the same methods as for the
20611filter options.
20612For example:
20613
20614<informalexample>
20615<screen>:as=jobstart $H $n $P $k $b $t
20616  jobstart '-Hh4.private' '-nroot' '-Pps' '-kcfA938h4.private' \
20617    '-b1093' '-tNov  5 19:39:25'
20618:ae=jobend $H $n $P $k $b $t
20619  jobend '-Hh4.private' '-nroot' '-Pps' '-kcfA938h4.private' \
20620    '-b1093' '-tNov  5 19:39:59'</screen>
20621</informalexample>
20622</para>
20623
20624<para>
20625If the options have the form <literal>:as=|/path ...</literal>,
20626then the specified program is run to record the information.
20627By convention the accounting information is passed as command line
20628values to the program.
20629The programs are run in the same manner as a print filter.
20630When the <literal/:as/ or <literal/:ae/ value specifies
20631a program then logging using the <literal/:af/ option
20632values in the next section is not performed.
20633For example:
20634</para>
20635
20636<informalexample>
20637<screen>:as=|/usr/local/libexec/jobstart $H $n $P $k $b $t
20638  /usr/local/libexec/jobstart '-Hh4.private' '-nroot' \
20639  '-Pps' '-kcfA938h4.private' '-b1093' '-tNov  5 19:39:25'
20640:ae=jobend $H $n $P $k $b $t
20641  jobend '-Hh4.private' '-nroot' '-Pps' '-kcfA938h4.private' \
20642    '-b1093' '-tNov  5 19:39:59'</screen>
20643</informalexample>
20644
20645</sect1>
20646
20647<sect1><title>Accounting File</title>
20648
20649<para>
20650The Accounting File (<literal/:af=/)
20651option value specifies the destination of accounting information.
20652If the format of the <literal/:af/ option is
20653<literal>:as=| ... </literal>,
20654then the value is assumed to be a program to be run to record
20655start and end of job information.
20656The program is run in the same manner as a print filter.
20657The values of the <literal/:as/ and <literal/:ae/ options are written
20658to the program's <literal/STDIN/ and the output from
20659the program's <literal/STDOUT/
20660is used as described below for authorization.
20661</para>
20662
20663<para>
20664If the <literal/:af=/ option has the format <literal/host%port/
20665then a TCP/IP connection is opened to the specified port on the indicated host.
20666The values of the <literal/:as/ and <literal/:ae/ options are written
20667to the remote host.
20668The port that the connection originates from will be in the range
20669set by the configuration or printcap
20670<emphasis remap=tt>
20671<link linkend="lpdport">originate_port</link>
20672</emphasis>
20673option.
20674</para>
20675
20676<para>
20677Finally,
20678if the <literal/:af=/ has neither of these formats then
20679it will be treated as a pathname to a file.
20680If the file exists or the <literal/create_files/ option is true,
20681then the file will be opened and the 
20682values of the <literal/:as/ and <literal/:ae/ options are written
20683to the file.
20684The accounting file should be periodically truncated.
20685
20686</para>
20687<para>
20688
20689By convention
20690the <literal/:af=/ value is passed to filters as a command line option.
20691LPRng will pass the option value only if it is specifies a file or network destination.
20692This implies that
20693accounting information can be written to the accounting file
20694or network destinations by the print spooler,
20695<literal/:of/ filters,
20696or print file filters.
20697The filters are responsible for opening the accounting file or network connection.
20698</para>
20699
20700<para>
20701The following is an example of information written to the accounting file:
20702<informalexample>
20703<screen>jobstart '-Hh4.private' '-nroot' '-Pps' '-kcfA938h4.private' \
20704'-b1093' '-tNov  5 19:39:25'
20705start '-p12942' '-kcfA938h4.private' '-nroot' '-hh4.private' '-Pps' \
20706'-c0' '-Fo' '-tSun Nov  5 19:39:25 1995'
20707filestart '-p12944' '-kcfA938h4.private' '-nroot' '-hh4.private' '-Pps' \
20708'-c0' '-Ff' '-tSun Nov  5 19:39:27 1995'
20709fileend '-p12944' '-kcfA938h4.private' '-nroot' '-hh4.private' '-Pps' \
20710'-b3' '-c0' '-Ff' '-tSun Nov  5 19:39:58 1995'
20711end '-p12942' '-kcfA938h4.private' '-nroot' '-hh4.private' '-Pps' \
20712'-b2' '-c0' '-Fo' '-tSun Nov  5 19:39:59 1995'
20713jobend '-Hh4.private' '-nroot' '-Pps' '-kcfA938h4.private' \
20714'-b1093' '-tNov  5 19:39:59'</screen>
20715</informalexample>
20716</para>
20717
20718<para>The
20719<literal>jobstart</literal>
20720and
20721<literal>jobend</literal>
20722lines are written by <application/lpd/
20723and are the expanded
20724<literal/:as/
20725and
20726<literal/:ae/
20727values.
20728The
20729<literal>start</literal>
20730and
20731<literal>end</literal>
20732line are added by the <literal/:of/ filter.
20733This filter usually queries the printer and gets printer
20734dependent accounting information such as the pagecounter value.
20735The <literal/:of/ filter is then suspended and the job is processed
20736by the various format dependent filters.
20737The the <literal/filestart/ and <literal/fileend/
20738lines are produced by the other filters.
20739</para>
20740
20741</sect1>
20742<sect1><title>Authorization and Quotas</title>
20743
20744<para>
20745In addition to simply recording accounting information the
20746accounting procedures can be used to check print quotas or update
20747databases.
20748This is done by using the
20749Accounting Check <literal/:achk/ flag
20750and the
20751<literal/:as/,
20752<literal/:ae/,
20753and
20754<literal/:af/ network connection or program capabilities.
20755</para>
20756
20757<para>
20758If the <literal/:achk/ flag is set and the
20759<literal/:as=/ option specifies a program to be run,
20760or the
20761<literal/:af=/ option specifies a program to be run or a network connection
20762then output of the program or information read from the
20763network connection is used to control the handling of the job.
20764If the
20765<literal/:as=/ option specifies a program to be run then
20766the program is run and the exit code and output is saved.
20767If the <literal/:as=/ option specifies a string and the
20768<literal/:af=/ option specifies a program to be run or a remote host
20769to be contacted then the <literal/:as=/ value is written to the
20770program STDIN or remote host.
20771The program STDOUT or network connection is read and saved and the
20772program exit code is saved.
20773</para>
20774<para>
20775If the information was read from a program,
20776then the exit code of the program is checked:
20777<informalexample><screen>
20778Exit Code    Action
20779JSUCC (0)    process data read
20780JFAIL        retry with JFAIL status
20781JHOLD        hold job
20782JREMOVE      remove job
20783JABORT       abort processing jobs
20784other        abort processing jobs
20785</screen></informalexample>
20786</para>
20787
20788<para>
20789If the information was read from a network connection or the
20790program exited with JSUCC (0) then the
20791start of the first line of the information read is used.
20792If this line starts with the following case insensitive words
20793then the following actions are taken: 
20794<informalexample><screen>
20795Word         Action
20796(blank)      process job
20797ACCEPT       process job
20798FAIL         retry with JFAIL status
20799HOLD         hold job
20800REMOVE       remove job
20801(other)      abort processing jobs
20802</screen></informalexample>
20803</para>
20804
20805<para>
20806These facilities can be used to implement a wide variety of quota
20807mechanisms.
20808The most simple method is to create a script or program that can be
20809run as the <literal/:as=/ program.
20810This would connect to a database server or check a database to see if
20811user quotas had been exceeded. 
20812If they had,  then it would return a <literal/REMOVE/ or <literal/HOLD/
20813status as appropriate.
20814</para>
20815
20816<sect1><title>Accessing Printer Hardware Pagecounters</title>
20817
20818<para>The following is from Hewlett-Packard documentation,
20819<ulink URL="http://www.hp.com/cposupport/printers/support_doc/bpl02119.html">
20820http://www.hp.com/cposupport/printers/support_doc/bpl02119.html</ulink></para>
20821
20822<para>All HP LaserJet 4/5/6 family printers have a page count feature
20823built into the firmware. However, this feature works differently
20824depending on which HP LaserJet printer is being used. The following
20825is a description of how the page count feature works for each
20826printer within the HP LaserJet 4/5/6 printer families.
20827<informalexample>
20828<screen>HP LaserJet 4/4M printers
20829HP LaserJet 4 Plus/4M Plus printers
20830HP LaserJet 4P/4MP printers
20831HP LaserJet 4Si/4Si MX printers
20832HP LaserJet 4ML printers
20833HP LaserJet 5P/5MP printers
20834HP LaserJet 6P/6MP printers</screen>
20835</informalexample>
20836</para>
20837
20838<para>All of the above printers use the same method for keeping track of
20839the number of copies. There are really two different page count
20840values: Primary and Secondary values. Every time a page is printed,
20841whether it is an internal job (such as a self-test) or a standard
20842print job, the Secondary page count increases by one. This value
20843is stored in standard RAM. Once the Secondary page count value
20844reaches 10, the Primary page count will increase by 10. The Primary
20845page count value is stored in a type of memory called NVRAM
20846(Non-Volatile RAM). This is important, since NVRAM is not cleared
20847when the printer is powered off. Standard RAM, on the other hand,
20848is cleared when the printer is turned off or reset. Thus, the
20849Primary page count only increases in increments of 10.</para>
20850
20851<para>Example</para>
20852
20853<para>You have a brand new HP LaserJet 6P printer and you print a self-test
20854page. When you look on the test page for the Page Count value, you
20855will see that it says 1. Next, you decide to print a two page letter
20856and, after that, another self-test. The page count value now says
208574. Internally, the printers Secondary page count (stored in RAM)
20858has the value of 4 while the Primary page count (stored in NVRAM)
20859still has the value of 0. Now, you turn the printer off, then back
20860on, and print another self-test. The page count value again says
208611 since the previous value of 4, stored in RAM, was cleared when
20862the printer was powered off. Finally, print a ten page document
20863and then turn the printer off. Upon turning the printer back on
20864and printing out another self test, you see that the page count
20865value is 11.  Internally, the Secondary page count value is back
20866at 1 while the Primary page count value (stored in NVRAM) is 10.
20867Added together, you end up with the resulting value seen on the
20868self-test page.</para>
20869
20870<para>
20871The HP LaserJet 4L/5L/6L
20872printers differ from that of the other printers in that they do not have any NVRAM
20873available for storing page count values.
20874Thus,
20875no way exists for the printer to retain a page count value once
20876the printer is powered off. The HP LaserJet 4L/5L/6L printers have
20877only a single page count value that increases in increments of one
20878until the printer is powered off.
20879</para>
20880
20881</sect1>
20882
20883<sect1><title>Reliable Accounting</title>
20884<para>
20885In order to do reliable accounting,
20886the printer must be queueried for the current value of the pagecounter
20887at the start and end of jobs and this information stored in the accounting file.
20888The <application remap=tt>ifhp</application>
20889filter can be configured to obtain the pagecounter values
20890and to record them at the start and end of each part of a print job.
20891We can use the <literal/:of/ filter to read the pagecounter value
20892at the start and end of a job,
20893and have the other file files record information as well.
20894The <literal/ifhp/ filter will record the pagecounter information
20895with the <literal/-p/ option.
20896We need simply take the difference of the starting and ending pagecounter
20897values to find the number of pages used by a job.
20898<informalexample>
20899<screen>
20900Example:
20901 lpd generates:  
20902  jobstart  - from the lpd.conf 'as=' option
20903  jobend    - from the lpd.conf 'ae=' option
20904    -H   - host name
20905    -n   - user name
20906    -P   - printer
20907    -k   - control file name
20908    -b   - byte count of job/file
20909    -t   - current printing time
20910
20911 ifhp filter generates:
20912   start/end         - of filter, for entire job
20913   filestart/fileend - if or other filter, for each file
20914   (options above are same)
20915    -A  - identifier information
20916    -q  - process id of filter
20917    -p  - current value of page counter, 0 indicates no
20918          page counter on printer or it is not readable
20919
20920jobstart '-Hh110.private' '-nroot' '-Plp' \
20921   '-kcfA129h110.private' '-b48780' '-t2001-10-19-09:36:36.000'
20922                           ^^^ bytes in file
20923
20924start '-q26130' '-p105340' '-t2001-10-19-09:36:38.330' \
20925                 ^^^^^^^  starting page counter value for job
20926    '-Aroot@h110+129' '-nroot' '-Plp' 
20927filestart '-q26132' '-p105340' '-t2001-10-19-09:36:38.350' \
20928                      ^^^^^^^  starting page counter value for file
20929    '-Aroot@h110+129' '-nroot' '-Plp' 
20930fileend '-b19' '-T435' '-q26132' '-p105359' '-t2001-10-19-09:43:51.504'
20931                                  ^^^^^^^  ending page countvalue for file
20932         ^^^ number of pages printed for this file
20933    '-Aroot@h110+129' '-nroot' '-Plp'
20934end '-b19' '-T435' '-q26130' '-p105359' '-t2001-10-19-09:43:51.504'
20935                                  ^^^^^^^  ending page countvalue for job
20936     ^^^ number of pages printed for this job
20937    '-Aroot@h110+129' '-nroot' '-Plp'
20938jobend '-Hh110.private' '-nroot' '-Plp' \
20939    '-kcfA129h110.private' '-b48780' '-t2001-10-19-09:43:51.000'
20940                           ^^^ bytes in file
20941</screen>
20942
20943</informalexample>
20944</para>
20945
20946<para>If for some reason the job is
20947killed or terminates due to error conditions,
20948the <literal/:of/ filter may not
20949get to record the ending value for the job.
20950This can lead to accounting files with the following entries:
20951<informalexample>
20952<screen>start '-p100' '-q20005' '-Fo' '-kcfA100taco' '-uuser' '-hhost' '-R...
20953filestart '-p101' '-q20005' '-Ff' '-kcfA100taco' '-uuser' '-hhost' '-R...
20954start '-p110' '-q20005' '-Fo' '-kcfA101taco' '-uuser' '-hhost' '-R...
20955filestart '-p112' '-q20010' '-Fo' '-kcfA101taco' '-uuser' '-hhost' '-R...
20956end '-p112' '-q20010' '-Fo' '-kcfA101taco' '-uuser' '-hhost' '-R...</screen>
20957</informalexample>
20958</para>
20959
20960<para>
20961The missing <literal/end/ is a clear indication that the user's job has been terminated.
20962We simply use the pagecounter value determined at the start of the next job
20963to find the numbers of pages used for this job.
20964</para>
20965
20966</sect1>
20967
20968<sect1><title>&LPRng; accounting.pl Utility</title>
20969
20970<para>The &LPRng;
20971<filename>accounting.pl</filename>
20972utility provides the basic framework for using the
20973<literal/:as=|/,
20974<literal/:ae=|/,
20975and pagecounter information written to the accounting file
20976to do reliable accounting,
20977and may be found in the &LPRng; distribution <literal/UTILS/
20978directory.
20979Usually this is modified according to local site needs
20980and installed in the filter directory.
20981</para>
20982<para>
20983The utility maintains the accounting file by inserting a
20984<literal/START/ record at the start of a job
20985and an
20986<literal/END/ record at the end of the job.
20987It is assumed that the last <literal/END/ record in the file
20988marks the last place that accounting was completed.
20989</para>
20990
20991<para>The following shows the printcap entry for
20992using the <literal/accounting.pl/ utility.
20993The <literal/start/ and <literal/end/
20994options are used to specify that the utility is being called at
20995the job start or end.
20996<informalexample>
20997<screen>printer
20998 :af=acct
20999 :as=|/usr/local/libexec/filters/accounting.pl start
21000 :ae=|/usr/local/libexec/filters/accounting.pl end</screen>
21001</informalexample>
21002</para>
21003
21004<para>
21005At the start of each job the utilty writes
21006a <literal/START/ record into the accounting file.
21007This record can contain information suitable for use by local site.
21008The exit code and information written to the utility <acronym/STDOUT/
21009is used by the <literal/lpd/ server to determine if the job is to be printed.
21010This allows job quotas to be implemented in a simple way by having
21011the <literal/accounting.pl/ utility query a database with the user quotas
21012and reject the job if the user's quota is exceeded.
21013</para>
21014
21015<para>
21016At the end of the job,
21017the utilitity will read the accounting file and use the recorded information
21018to update the accounting information.
21019In order to make this reliable,
21020the following steps are taken.
21021
21022<orderedlist>
21023<listitem><para>
21024The accounting file is read and scanned for the last
21025<literal/END/
21026record.
21027If there is none,
21028then the next step starts at the beginning of the accounting file.
21029</para></listitem><listitem><para>
21030The file is scanned for <literal/START/ lines and <literal/pagecounter/
21031information determined at the start of a job.
21032</para></listitem><listitem><para>
21033If the last line in the accounting file does not indicate successful
21034completetion of the job and contain pagecounting information,
21035then the accounting procedure is abandoned until the next job
21036completes successfully.
21037</para></listitem><listitem><para>
21038If the last line in the accounting file indicates successful
21039completion,
21040then its pagecounter value is used as the last page counter value.
21041</para></listitem><listitem><para>
21042Job information is updated by finding the start and end pagecounter
21043values for each job.
21044It is possible that a job will not have a pagecounter value recorded
21045at its start;  in this case the page usage will be 0,
21046as it did not even get initialized.
21047</para></listitem><listitem><para>
21048After determining the accounting information,
21049the procedure will then update and databases and the accounting
21050file.
21051During this update,
21052interrupts should be disabled and the amount of time taken to update
21053the accounting information and/or file should be minimized.
21054</para></listitem>
21055</orderedlist>
21056</para>
21057
21058<para>Administrators can use this script as a starting point for more advanced
21059accounting.
21060For example,
21061rather than just recording the information,
21062at the job start the script can query either a local database
21063or a remote server to see if the user has permissions to access the printer.
21064At the end of the job or when an <acronym>END</acronym> line is written to the
21065accounting file,
21066the local database or remote accounting server can be updated.</para>
21067
21068</sect1>
21069</chapter>
21070
21071<chapter id=rfc1179ref><title>RFC 1179 - Line Printer Daemon Protocol </title>
21072
21073<para>RFC1179 can be obtained from the &LPRng; distribution, in the LPRng_DOC/rfc1179 directory,
21074or from one of many sites which mirror the RFCs.</para>
21075
21076<para>This RFC is an <emphasis>informational</emphasis>
21077RFC,
21078which means that the information in it is meant as a guide to users,
21079and not as a fixed standard.
21080In addition,
21081the RFC tried to document the behavior of the BSD <application/lpd/ print server,
21082and left out many details dealing with error recover,
21083error messages,
21084extensions to the protocol,
21085etc.</para>
21086
21087<para>In this section,
21088I will try to explain what RFC1179 specifies as a protocol,
21089and many of the problems encountered in trying to use it.</para>
21090
21091
21092<sect1 id="lpdport"><title>Ports and Connections </title>
21093
21094<para>Options used:
21095<itemizedlist>
21096
21097<listitem>
21098<para> <literal>lpd_port=</literal><emphasis>Port for <application/lpd/ connections</emphasis></para>
21099</listitem>
21100
21101<listitem>
21102<para> <literal>lpd_listen_port=</literal><emphasis>Port for <application/lpd/ to accept connection</emphasis></para>
21103</listitem>
21104
21105<listitem>
21106<para> <literal>originate_port=</literal><emphasis>Ports to originate connections on</emphasis></para>
21107</listitem>
21108
21109<listitem>
21110<para> <literal>reuse_addr</literal> FLAG <emphasis>Set SO_REUSEADDR flag on connection</emphasis></para>
21111</listitem>
21112
21113<listitem>
21114<para> <literal>retry_econnrefused</literal> FLAG <emphasis>Retry on connect ECONNREFUSED error</emphasis></para>
21115</listitem>
21116
21117<listitem>
21118<para> <literal>retry_nolink</literal> FLAG <emphasis>Retry on device open or connection ffailure</emphasis></para>
21119</listitem>
21120
21121<listitem>
21122<para> <literal>unix_socket_path</literal> PATH <emphasis>UNIX FIFO pathname for local connections</emphasis></para>
21123</listitem>
21124
21125<listitem>
21126<para>
21127<literal>socket_linger=</literal><emphasis>socket linger timeout</emphasis></para>
21128</listitem>
21129
21130</itemizedlist>
21131</para>
21132
21133<para>RFC1179 requires that the <application>lpd</application> server listen for TCP/IP connections
21134on port 515.
21135This port is registered with the Internet Naming Authority,
21136and the <filename>/etc/services</filename> file or TCP/IP services database usually has an entry:
21137<informalexample>
21138<screen>printer     515/tcp     spooler     # line printer spooler</screen>
21139</informalexample>
21140</para>
21141
21142<para>RFC1179 explicitly states that all connections to port 515 must originate from
21143ports 721-731.
21144The reason for this restriction is due to the UNIX concept of <emphasis>reserved</emphasis>
21145and <emphasis>privileged</emphasis>
21146ports.
21147By convention,
21148ports in the range 1-1023 can only <emphasis remap=bf>bound</emphasis>
21149by processes whose Effective User ID (EUID)
21150is 0 (root).
21151This,
21152ordinary users could not originate a connection from the reserved or privileged port range.</para>
21153
21154<para>In a UNIX environment,  this means that the user programs
21155<application>lpr</application>,
21156<application>lpq</application>,
21157<application>lprm</application>,
21158and
21159<application>lpc</application>
21160would have to be SETUID root.</para>
21161
21162<para>As experience has shown, for security purposes,
21163the fewer programs that need to have privileged status,
21164the better.
21165&LPRng; uses the
21166<literal>lpd_port=printer</literal> configuration option to set the port for the
21167connections to a <application/lpd/ server.
21168By default, this is port 515, but can be set to other values.
21169This port value is used to make connections to a remote <application/lpd/ server.
21170The
21171<literal>lpd_listen_port=printer</literal> configuration option can be used to specify
21172a port for the <application/lpd/ to listen for incoming requests.
21173If no <literal>lpd_listen_port</literal> value is specified the
21174<literal>lpd_port</literal> value will be used as the <application/lpd/ listening port.
21175</para>
21176
21177<para>
21178The <literal/unix_socket_path/ option specifies the pathname of a UNIX FIFO or
21179socket that can be used for connections the <application/lpd/ server if the
21180client and server are on the same host.
21181The  use of a local FIFO restricts connections from outside hosts.
21182The UNIX FIFO path should be to a node in a directory that is writable by
21183by the <application/lpd/ server and not other non-privileged processes.
21184<para>
21185
21186<para>The restriction of originating ports to 721-731 causes another set of problems.
21187Part of the TCP/IP protocol is concerned with avoiding communications problems
21188resulting from the arrival of old or <emphasis>stale</emphasis>
21189packets.
21190When a connection between
21191<literal>sourcehost, sourceport</literal>
21192and
21193<literal>desthost, destport</literal>
21194is made,
21195a set of sequence numbers is established and used for sending and acknowledgement of data.
21196When the connection terminates,
21197the TCP/IP protocol restricts the establishment of a new connection between
21198<literal>sourcehost, sourceport</literal>
21199and
21200<literal>desthost, destport</literal>
21201for a period long
21202enough for all <emphasis>stale</emphasis>
21203packets to be removed from the system.
21204This is approximately 10 minutes long.</para>
21205
21206<para>In order to simplify assignments of ports,
21207timing out connections, and other matters,
21208many TCP/IP packages do keep track of explicit connections
21209<emphasis>originating</emphasis>
21210from a port,
21211but simply prevent the port from being reused for either origination
21212or reception of a connection.
21213They do,
21214however,
21215keep track of the active connections <emphasis remap=bf>to</emphasis>
21216a port,
21217and perform timeouts on these.
21218This is usually much simpler to implement,
21219as it can be done with a list attached to the port.</para>
21220
21221<para>This implementation method creates some problems when
21222a large number of connections must be originated from a
21223relatively small number of port numbers.
21224Observe what happens when host 1 tries to send a large number of jobs to a server 2.
21225The following connections are established and terminated:<!-- <br> -->
21226<literal>host 1, port 721</literal>
21227and
21228<literal>host 2, port 515</literal><!-- <br> -->
21229<literal>host 1, port 722</literal>
21230and
21231<literal>host 2, port 515</literal><!-- <br> -->
21232<literal>host 1, port 723</literal>
21233and
21234<literal>host 2, port 515</literal><!-- <br> -->
21235<literal>host 1, port 724</literal>
21236and
21237<literal>host 2, port 515</literal><!-- <br> -->
21238<literal>host 1, port 725</literal>
21239and
21240<literal>host 2, port 515</literal><!-- <br> -->
21241<literal>host 1, port 726</literal>
21242and
21243<literal>host 2, port 515</literal><!-- <br> -->
21244<literal>host 1, port 727</literal>
21245and
21246<literal>host 2, port 515</literal><!-- <br> -->
21247<literal>host 1, port 728</literal>
21248and
21249<literal>host 2, port 515</literal><!-- <br> -->
21250<literal>host 1, port 729</literal>
21251and
21252<literal>host 2, port 515</literal><!-- <br> -->
21253<literal>host 1, port 730</literal>
21254and
21255<literal>host 2, port 515</literal><!-- <br> -->
21256<literal>host 1, port 731</literal>
21257and
21258<literal>host 2, port 515</literal></para>
21259
21260<para>Now according to the RFC1179 rules and the TCP/IP protocol,
21261we will have to wait until one of these connections terminates before we
21262can make another.
21263On the originating system,
21264if the TCP/IP implementation does timeouts on the originating port,
21265we will have to wait for the timeout to elapse before we can make a new
21266connection.
21267Unfortunately,  there is no way to find out what the status of the port
21268is,  so we will have to try them each in turn until we get
21269a successful connection.</para>
21270
21271<para>The &LPRng; code has tried to provide several methods to deal with
21272these problems.
21273Firstly,
21274the
21275<literal>originate_port=512 1023</literal>
21276option specifies the range
21277of ports used to originate connections
21278when the software is running either as ROOT or SETUID root.
21279By strict RFC1179 rules,
21280this should be
21281<literal>originate_port=721 731</literal>,
21282but it turns out that most BSD <application/lpd/ based implementations only
21283check for a <emphasis>reserved</emphasis>
21284originating port.
21285By using 512 ports we get a greatly reduced rate of errors due
21286to lack of ports due to pending timeouts.</para>
21287
21288<para>However,
21289on some systems which are acting as servers for a large number of
21290printers even increasing this port range is insufficient,
21291and steps need to be taken use the originating port numbers
21292more efficiently.
21293The Berkeley TCP/IP implementation
21294<function>getsockopt()</function>
21295and
21296<function>setsockopt()</function>
21297allows the user to manipulate some of the underlying timeouts and options
21298of the TCP/IP network.
21299When a TCP/IP connection is established,
21300the
21301<function>setsockopt()</function>
21302facility can be used to set the
21303<literal>SO_REUSEADDR</literal>
21304flag on the connection.
21305This flag effectively sets the timeout value on the ports
21306and connections to 0,
21307allowing immediate reuse of the ports.
21308When done on an originating end of a connection,
21309this will allow the originating port number to be reused immediately.</para>
21310
21311<para>It would appear that by setting
21312<literal>SO_REUSEADDR</literal>
21313on the originating end that we have solved our problems.
21314However,
21315unless the destination end of the connection sets its
21316<literal>SO_REUSEADDR</literal>
21317flag on the connection,
21318it will still do a timeout.
21319Thus when we try to make a connection from a port
21320that was active within a short period of time to the
21321same host,
21322then it will reject the connection until the
21323timeout is over.</para>
21324
21325<para>The
21326<literal>reuse_addr</literal>
21327flag (default off) forces
21328the &LPRng; software to set the
21329<literal>SO_REUSEADDR</literal>
21330flag on originating connections.
21331As indicated,
21332this will allow ports to be reused immediately for outgoing connections,
21333rather than waiting for a timeout.</para>
21334
21335<para>While the
21336<literal>reuse_addr</literal>
21337flag usually allows us to reuse ports,
21338there is still the problem of dealing with connections failing due to the
21339remote site rejecting the connection due to a pending timeout
21340from a previous connection.
21341A careful study of the original BSD TCP/IP network code and of some
21342others indicates that when a connection fails due to a pending timeout,
21343an ECONNREFUSED error code is returned to a
21344<function>connect()</function> system call.
21345If this happens and we suspect that the remote site is rejecting
21346the connection due to a timeout problem,
21347then we should retry making the connection but from a new port,
21348and continue retrying until all possible ports are used.</para>
21349
21350<para>The <literal>retry_econnrefused</literal> (default on) flag is used to
21351specify that we retry connections in this manner.
21352When this is set,
21353a
21354<literal>connection refused</literal>
21355error causes the connection to be retried using a new port.
21356This will be repeated until all available ports have been tried.</para>
21357
21358<para>When
21359printing a job and the <application>lpd</application> server connection to a remote
21360site or device open fails,
21361the <literal>retry_nolink</literal> (default on)
21362will cause the attempt to be retried indefinitely.
21363The combination of <literal>retry_econnrefused</literal> and <literal>retry_nolink</literal>
21364will provide robust connection attempts to remote systems.</para>
21365
21366<para>While the above problems cause difficulties when making connections,
21367there are also problems when terminating connections.
21368After closing a socket,
21369the TCP/IP software will try to flush any pending data to the destination.
21370Unfortunately,
21371on some systems it will only do this while the process is active.
21372This has caused problems on systems which terminate
21373a process it has received an abnormal (signal caused) termination.</para>
21374
21375<para>The <function>setsockopt()</function> SO_LINGER option allows the user to specify
21376that when a socket is closed normally,
21377that the process should block until pending data is flushed or
21378for the <literal>socket_linger</literal> period.
21379If <literal>socket_linger</literal> is 0,
21380then no SO_LINGER operation is done.</para>
21381
21382<para>In summary, if you experience problems with connection failures due
21383to port exhaustion,
21384first try setting the
21385<literal>reuse_port</literal> flag,
21386and you should see a reduction.
21387Check to ensure that the <literal>retry_econnrefused</literal>
21388and <literal>retry_nolink</literal> flags are set,
21389and the error code in the log and status files.
21390If the failures continue,  then the problem is caused by the
21391remote end having timeout limitations and there is little you
21392can do except to set a very long <literal>connect_retry</literal>
21393interval, say <literal>connect_retry=120</literal> (2 minutes).</para>
21394
21395</sect1>
21396
21397<sect1 id="remotesupport"><title>Protocol Requests and Replies </title>
21398
21399<para>Options used:
21400<itemizedlist>
21401
21402<listitem>
21403<para> <literal>remote_support=</literal><emphasis>Remote operations supported</emphasis></para>
21404</listitem>
21405
21406</itemizedlist>
21407</para>
21408
21409<para>After a connection has been established,
21410a request can be sent to the <application>lpd</application>
21411server.
21412The request consists of a single octet indicating the request type,
21413followed by the printer (or print queue) name, followed by
21414a set of options for the request,
21415followed by a LF (line feed) character.
21416</para>
21417
21418<table frame=all id=rf1179commands><title>RFC1179 Commands</title>
21419<tgroup cols=4 align=left rowsep=1 colsep=1>
21420<thead>
21421<row><entry>NNN</entry><entry>RFC1179</entry><entry>Operation</entry><entry>program</entry></row>
21422</thead>
21423<tbody>
21424<row><entry>1</entry><entry>yes</entry><entry>start print</entry><entry><application>lpc</application></entry></row>
21425<row><entry>2</entry><entry>yes</entry><entry>transfer a printer job</entry><entry><application>lpr</application></entry></row>
21426<row><entry>3</entry><entry>yes</entry><entry>print short form of queue status</entry><entry><application>lpr</application></entry></row>
21427<row><entry>4</entry><entry>yes</entry><entry>print long form of queue status</entry><entry><application>lpr</application></entry></row>
21428<row><entry>5</entry><entry>yes</entry><entry>remove jobs</entry><entry><application>lprm</application></entry></row>
21429<row><entry>6</entry><entry>&LPRng;</entry><entry>do control operation</entry><entry><application>lpc</application></entry></row>
21430<row><entry>7</entry><entry>&LPRng;</entry><entry>transfer a block format print job</entry><entry><application>lpr</application></entry></row>
21431<row><entry>8</entry><entry>&LPRng;</entry><entry>secure command transfer</entry><entry><application>lpc</application></entry></row>
21432<row><entry>9</entry><entry>&LPRng;</entry><entry>verbose status information</entry><entry><application>lpr</application></entry></row>
21433</tbody>
21434</tgroup>
21435</table>
21436
21437<para>After the request has been sent,
21438then a reply will be returned.
21439In general the reply has the following form:
21440<informalexample>
21441<screen>\000\n    Success
21442\NNN\n    Failure (NNN is error code)
21443text\n    Text or status information</screen>
21444</informalexample>
21445</para>
21446
21447<para>As can be seen,
21448this protocol is extremely simple,
21449but there are a set of problems due to the loosely written language of RFC1179.
21450<orderedlist>
21451
21452<listitem>
21453<para>Firstly,
21454while RFC1179 sets limits on the lengths of commands,
21455it does not strictly set limits on the characters set used in the commands.
21456This can result in problems when trying to print status information,
21457headers on banners,
21458and other details.</para>
21459</listitem>
21460
21461<listitem>
21462<para>The original RFC1179 protocol did not provide any way to do remote control
21463of queues or <application/lpd/ servers.
21464This has been added to the protocol.
21465As a side effect,
21466if you try to use
21467<application>lpc</application> to control a non-&LPRng; printer,
21468it will not work.</para>
21469</listitem>
21470
21471<listitem>
21472<para>You can specify that a network printer is non-&LPRng; by using the
21473<literal>remote_support=RQVMC</literal> option and specify the operations
21474supported by the printer.
21475The letters R, Q, M, and C stand for
21476<application>lpr</application>,
21477<application>lpq</application>,
21478<application>lprm</application>,
21479and <application>lpc</application> operations respectively,
21480and indicate that these are supported.
21481If <literal>remote_support</literal> does not allow a particular operation,
21482then the &LPRng; software will not send a corresponding request to the printer.
21483For example,
21484<literal>remote_support=R</literal>
21485would restrict operations to spooling jobs only,
21486and the &LPRng; software would not query the printer for status.</para>
21487</listitem>
21488
21489</orderedlist>
21490</para>
21491
21492</sect1>
21493
21494<sect1 id="jobtransfer"><title>Job Transfer </title>
21495
21496<para>Options used:
21497<itemizedlist>
21498
21499<listitem>
21500<para>
21501<literal>longnumber</literal> FLAG <emphasis>Long job number (6 digits)</emphasis></para>
21502</listitem>
21503
21504<listitem>
21505<para> <literal>send_data_first</literal> FLAG <emphasis>Send data files first</emphasis></para>
21506</listitem>
21507
21508<listitem>
21509<para> <literal>use_shorthost</literal><emphasis>Use short hostname</emphasis></para>
21510</listitem>
21511
21512</itemizedlist>
21513</para>
21514
21515<para>A job transfer operation starts with a job transfer request,
21516followed by several file transfer operations.
21517At the end of the file transfers,
21518the connection should be closed.</para>
21519
21520<para>A file transfer request has the form:
21521<informaltable frame=all>
21522<tgroup cols=2 align=left rowsep=1 colsep=1>
21523<thead>
21524<row><entry>Command</entry><entry>Purpose</entry></row>
21525</thead>
21526<tbody>
21527<row><entry>\001\n</entry><entry>abort</entry></row>
21528<row><entry>\002nnnn cfname</entry><entry>control file transfer</entry></row>
21529<row><entry>\003nnnn dfname</entry><entry>data file transfer</entry></row>
21530</tbody>
21531</tgroup>
21532</informaltable>
21533</para>
21534
21535<para>The abort operation is used to terminate job transfer and indicate that
21536the job should not be processed for printing.
21537The connection will be closed and the partly transferred job
21538will be discarded.</para>
21539
21540<para>The control file and data file transfer commands have a length (in bytes)
21541of the file and the name of the file to be transferred.
21542When the command is received,
21543the server will reply with a status line:
21544<informaltable frame=all>
21545<tgroup cols=2 align=left rowsep=1 colsep=1>
21546<thead>
21547<row><entry>Status</entry><entry>Purpose</entry></row>
21548</thead>
21549<tbody>
21550<row><entry>\000</entry><entry>Accepted, proceed</entry></row>
21551<row><entry>\nnn</entry><entry>Rejected with error code</entry></row>
21552</tbody>
21553</tgroup>
21554</informaltable>
21555</para>
21556
21557<para>The reply is only a single octet.
21558Some defective implementations of RFC1179 send a LF after the octet,
21559which makes life very difficult.
21560&LPRng; makes an effort to detect these non-conforming RFC1179 systems
21561and will accept jobs from them.
21562However,  it will not send jobs to them.</para>
21563
21564<para>If &LPRng; sends a reject code, as an extension to RFC1179 it also
21565sends an error message.   Note that the values for error codes
21566are not defined,
21567nor are their causes.
21568&LPRng; uses the following values for error codes,
21569which appear to be compatible with many,
21570but not all, of the BSD <application/lpd/ based systems:
21571<informaltable frame=all>
21572<tgroup cols=2 align=left rowsep=1 colsep=1>
21573<thead>
21574<row><entry>Code</entry><entry>Error</entry></row>
21575</thead>
21576<tbody>
21577<row><entry>\000</entry><entry>Accepted, proceed</entry></row>
21578<row><entry>\001</entry><entry>Queue not accepting jobs</entry></row>
21579<row><entry>\002</entry><entry>Queue temporarily full, retry later</entry></row>
21580<row><entry>\003</entry><entry>Bad job format, do not retry</entry></row>
21581</tbody>
21582</tgroup>
21583</informaltable>
21584</para>
21585
21586<para>When the sender gets the reply indicating success,
21587it sends the
21588<literal>nnnn</literal>
21589bytes of the control or data file,
21590followed by a
21591<literal>\000</literal>
21592octet.
21593The receiver will then reply as above;
21594a single
21595<literal>\000</literal>
21596octet indicating success.</para>
21597
21598<para>The above procedure is carried out until all data files and the control
21599file of a job are transferred.</para>
21600
21601<para>RFC1179 is silent on the following issues:
21602<orderedlist>
21603
21604<listitem>
21605<para>When sending a job,
21606do you send the control file first, followed by the data file(s),
21607or the data files first?</para>
21608</listitem>
21609
21610<listitem>
21611<para>When sending multiple jobs,
21612can you send them on a single connection,
21613or do you have to establish a new connection for each job?</para>
21614</listitem>
21615
21616</orderedlist>
21617</para>
21618
21619<para>&LPRng; will <emphasis>accept</emphasis>
21620jobs whether they are sent control or data files
21621first.
21622By default,
21623it sends the control file first,
21624followed by the data file.
21625If the destination system requires that the data files
21626be sent first,
21627the <literal>send_data_first</literal> printcap option can be used to force
21628data files to be sent first.</para>
21629
21630<para>RFC1179 states that:
21631<blockquote>
21632<para>The name of the control file ... should start with ASCII "cfA", followed by a three
21633digit job number, followed by the host name which has constructed the
21634control file.</para>
21635</blockquote>
21636</para>
21637
21638<para>The <emphasis>should</emphasis>
21639in this wording indicates that this is simply a guideline,
21640and that other formats are possible.
21641Some of the major problems with this format are as follows:
21642<orderedlist>
21643
21644<listitem>
21645<para> The restriction to 3 digits means that at most 1000 jobs
21646can be in a queue.
21647Strangely,  some systems generate far more than 1000 jobs a day,
21648and need to archive them on a regular basis.
21649The
21650<literal>longnumber</literal>
21651option will allow &LPRng; to use a 6 digit
21652job number for files in the print queue.</para>
21653</listitem>
21654
21655<listitem>
21656<para>The host name format is not specified.
21657Some implementations consider that this is the short host name,
21658while others think it is the fully qualified domain name (FQDN).
21659&LPRng;,
21660by default,
21661will use the FQDN host name.
21662However,  the <literal>use_shorthost</literal> option will force it to
21663use short host names in control and data files.</para>
21664</listitem>
21665
21666<listitem>
21667<para>The
21668<literal>cfA</literal>
21669control file name was modified to allow the
21670job priority to be used as the A letter of the control file.
21671By default,
21672this is A (lowest, i.e.
21673<literal>cfA</literal>) and
21674but can range to Z (highest, i.e.
21675<literal>cfZ</literal>).
21676All known spoolers except &LPRng; seem to ignore the actual value of
21677the letter.</para>
21678</listitem>
21679
21680</orderedlist>
21681</para>
21682
21683</sect1>
21684
21685<sect1><title>Data File Transfer</title>
21686
21687<para>As mentioned before
21688a data file is transferred using the command below.
21689<informaltable frame=all>
21690<tgroup cols=2 align=left rowsep=1 colsep=1>
21691<thead>
21692<row><entry>Command</entry><entry>Purpose</entry></row>
21693</thead>
21694<tbody>
21695<row><entry>\003nnnn dfname</entry><entry>data file transfer</entry></row>
21696</tbody>
21697</tgroup>
21698</informaltable>
21699</para>
21700
21701<para>From RFC1179:
21702<blockquote>
21703<para>The data file may contain any 8 bit values at all.  The total number
21704of bytes in the stream may be sent as the first operand, otherwise
21705the field should be cleared to 0.  The name of the data file should
21706start with ASCII "dfA".  This should be followed by a three digit job
21707number.  The job number should be followed by the host name which has
21708constructed the data file.  Interpretation of the contents of the
21709data file is determined by the contents of the corresponding control
21710file.</para>
21711</blockquote>
21712</para>
21713
21714<para>There are several surprises in RFC1179.
21715<orderedlist>
21716
21717<listitem>
21718<para>Apparently a job should only consist of a single data file.
21719This is a severe limitation,  and in fact the BSD <application/lpr/ and other
21720print spoolers process jobs with multiple data files.
21721By convention, these data files have names of the form
21722<literal>dfA</literal>,
21723<literal>dfB</literal>,
21724...
21725<literal>dfZ</literal>,
21726<literal>dfa</literal>,
21727<literal>dfz</literal>.</para>
21728</listitem>
21729
21730<listitem>
21731<para>The RFC does not specify that the control file and data file job numbers
21732must be identical.
21733Most implementations follow this convention, which simplifies life
21734tremendously.</para>
21735</listitem>
21736
21737<listitem>
21738<para>The RFC does not specify that the control file and data file job host names
21739must be identical.
21740Most implementations follow this convention, which simplifies life
21741tremendously.</para>
21742</listitem>
21743
21744<listitem>
21745<para>A zero length data file does not cause a data transfer to take place.
21746&LPRng; modifies this action to be slightly different.
21747When a zero length data file transfer is indicated,
21748all of the input until the connection is closed is used as the
21749contents of the data file.
21750</para>
21751
21752<para>When <emphasis/piping/ into the <application>lpr</application> program,
21753this can be very useful as it eliminates the need to create temporary
21754files on the local host.
21755Note that some print spoolers do not use this interpretation,
21756and this option should be used carefully.</para>
21757</listitem>
21758
21759</orderedlist>
21760</para>
21761
21762</sect1>
21763
21764<sect1><title>Control File Contents</title>
21765
21766<para>The control file consists of a set of lines which either provide
21767printing information or specify data files to be printed.
21768The information lines start with upper case letters or digits,
21769while the data files lines start with lower case letters.
21770Here is a sample control file:
21771<informalexample>
21772<screen>Hh4.private
21773J(stdin)
21774CA
21775Lpapowell
21776Apapowell@h4+955
21777Ppapowell
21778fdfA955h4.private
21779N(stdin)
21780UdfA955h4.private</screen>
21781</informalexample>
21782</para>
21783
21784<para>The following are the letters and their meanings in the control file.
21785</para>
21786<table frame=all id=cflines><title>Control File Lines and Purpose</title>
21787<tgroup cols=3 align=left rowsep=1 colsep=1>
21788<thead>
21789<row><entry>Letter</entry><entry>Defined</entry><entry>Purpose</entry></row>
21790</thead>
21791<tbody>
21792<row><entry>A</entry><entry>&LPRng;</entry><entry>Identifier for job</entry></row>
21793<row><entry>C</entry><entry>RFC1179</entry><entry>Class for banner page</entry></row>
21794<row><entry>H</entry><entry>RFC1179</entry><entry>Host name</entry></row>
21795<row><entry>I</entry><entry>RFC1179</entry><entry>Indent Printing</entry></row>
21796<row><entry>J</entry><entry>RFC1179</entry><entry>Job name for banner page</entry></row>
21797<row><entry>L</entry><entry>RFC1179</entry><entry>Print banner page</entry></row>
21798<row><entry>M</entry><entry>RFC1179</entry><entry>Mail When Printed</entry></row>
21799<row><entry>N</entry><entry>RFC1179</entry><entry>Name of source file</entry></row>
21800<row><entry>P</entry><entry>RFC1179</entry><entry>User identification</entry></row>
21801<row><entry>Q</entry><entry>&LPRng;</entry><entry>Queue name</entry></row>
21802<row><entry>R</entry><entry>&LPRng;</entry><entry>Accounting info</entry></row>
21803<row><entry>S</entry><entry>RFC1179</entry><entry>Symbolic link data</entry></row>
21804<row><entry>T</entry><entry>RFC1179</entry><entry>Title for pr</entry></row>
21805<row><entry>U</entry><entry>RFC1179</entry><entry>Unlink data file</entry></row>
21806<row><entry>W</entry><entry>RFC1179</entry><entry>Width of output</entry></row>
21807<row><entry>Z</entry><entry>&LPRng;</entry><entry>Filter options</entry></row>
21808<row><entry>1</entry><entry>RFC1179</entry><entry>troff R font</entry></row>
21809<row><entry>2</entry><entry>RFC1179</entry><entry>troff I font</entry></row>
21810<row><entry>3</entry><entry>RFC1179</entry><entry>troff B font</entry></row>
21811<row><entry>4</entry><entry>RFC1179</entry><entry>troff S font</entry></row>
21812<row><entry>c</entry><entry>RFC1179</entry><entry>Plot CIF file</entry></row>
21813<row><entry>d</entry><entry>RFC1179</entry><entry>Print DVI file</entry></row>
21814<row><entry>f</entry><entry>RFC1179</entry><entry>Print formatted file</entry></row>
21815<row><entry>g</entry><entry>RFC1179</entry><entry>Plot file</entry></row>
21816<row><entry>k</entry><entry>RFC1179</entry><entry>Reserved for use by Kerberized &LPRng; clients and servers.</entry></row>
21817<row><entry>l</entry><entry>RFC1179</entry><entry>Print file leaving control characters</entry></row>
21818<row><entry>n</entry><entry>RFC1179</entry><entry>Print ditroff output file</entry></row>
21819<row><entry>o</entry><entry>RFC1179</entry><entry>Print Postscript output file</entry></row>
21820<row><entry>p</entry><entry>RFC1179</entry><entry>Print file with 'pr' format</entry></row>
21821<row><entry>t</entry><entry>RFC1179</entry><entry>Print troff output file</entry></row>
21822<row><entry>v</entry><entry>RFC1179</entry><entry>Print raster file</entry></row>
21823<row><entry>z</entry><entry>RFC1179</entry><entry>Reserved for future use with the Palladium print system.</entry></row>
21824</tbody>
21825</tgroup>
21826</table>
21827
21828<para>The
21829<literal remap=tt>A</literal>
21830(Identifier)
21831line was introduced to record a unique
21832system wide job identifier for &LPRng; submitted jobs.
21833This is basically formed from the user name,
21834job number, and host at the time of submission.
21835For example: <literal>papowell@h4+955</literal>
21836is job number 995 submitted by papowell from host h4.</para>
21837
21838<para>The
21839<literal remap=tt>C</literal>
21840(Class)
21841line is set by the <command>lpr -C class</command> option,
21842and the value can be used to control printing.
21843For example,
21844the
21845<command remap=tt>lpc class zone </command>
21846command would restrict job printing to
21847only jobs with class
21848<literal>zone</literal>.</para>
21849
21850<para>The
21851<literal remap=tt>H</literal>
21852(hostname),
21853<literal remap=tt>P</literal>
21854(username),
21855and
21856<literal remap=tt>J</literal>
21857(jobname)
21858fields are used to identify the host and user which sent the job,
21859and to provide information to be displayed by <application>lpq</application>
21860when reporting job status.</para>
21861
21862<para>The
21863<literal remap=tt>L</literal>
21864(print banner page) field is one that has caused many
21865problems for users.
21866RFC1179 indicates that its presence causes the banner page to be printed,
21867and its absence suppresses banner pages.
21868The <command>lpr -h</command> option suppresses putting this line into the
21869control file.
21870Usually the
21871<literal remap=tt>L</literal>
21872field is a duplicate of the
21873<literal remap=tt>P</literal>
21874field.</para>
21875
21876<para>The
21877<literal remap=tt>M</literal>
21878(mail information)
21879field supplies a mail address for &LPRng; to send mail to when
21880a job is completed.
21881See
21882
21883<link linkend="jobcompletion">Job Completion Notification Requested</link>
21884
21885for more details.</para>
21886
21887<para>The
21888<literal remap=tt>N</literal>
21889(file name) field is usually provided to identify
21890the file name corresponding to the data file.
21891This can be used to print names on page separators, etc.
21892&LPRng; largely ignores this line.</para>
21893
21894<para>The
21895<literal remap=tt>I</literal>
21896(indent)
21897and
21898<literal remap=tt>W</literal>
21899(width)
21900fields are supposed to specify a page indent and width for printing.
21901These fields are passed to filters if they are present.</para>
21902
21903<para>The
21904<literal remap=tt>Q</literal>
21905(queue name)
21906field is an &LPRng; extension,
21907and contains the name of the print queue the job was originally sent to.
21908See
21909
21910<link linkend="qq">qq printcap option</link>
21911 for details.</para>
21912
21913<para>The
21914<literal remap=tt>R</literal>
21915(accounting info) field was added by &LPRng; to allow
21916a specified account to be billed for job printing.
21917The <command>lpr -Rname</command> option can be used to specify the accounting name.</para>
21918
21919<para>The
21920<literal remap=tt>S</literal>
21921(symbolic link)
21922and
21923<literal remap=tt>U</literal>
21924(unlink after printing)
21925lines were used by the original BSD <application/lpd/ print system to control
21926how it passed files to the print server.
21927&LPRng; ignores these lines.
21928In fact, it will remove
21929<literal remap=tt>S</literal>
21930lines and force the
21931<literal remap=tt>U</literal>
21932lines to refer only to job data files.
21933This closes a nasty security loophole on non-&LPRng; print spoolers.</para>
21934
21935<para>The
21936<literal remap=tt>T</literal>
21937(pr job title) is used with the <command>lpr -p</command>
21938operation to supply a banner to the
21939<literal>pr</literal>
21940program.</para>
21941
21942<para>The
21943<literal remap=tt>Z</literal>
21944(filter options) value is specified with
21945<command>lpr -Zoption</command> and is passed to the data file filters
21946during the printing operation.
21947See
21948<link linkend="filters">Filters</link>
21949for details on how the
21950this is used during the printing process.</para>
21951
21952<para>All of the lower case letters are reserved for format specifications for
21953data files.
21954In the control file, these are followed by the name of the data file
21955to which they correspond.
21956While in principle different data files in the control file can have
21957different formats,
21958this has not been implemented in any known spooling system.
21959See
21960
21961<link linkend="filters">Filters</link>
21962 for details on how the
21963data file formats are used during the printing process.</para>
21964
21965</sect1>
21966
21967<sect1><title><application>lpq</application> Requests</title>
21968
21969<para>The RFC1179 protocol specifies that <application>lpq</application> print status
21970requests can be sent to the <application>lpd</application> server.
21971The lpq requests have the format:
21972<informalexample>
21973<screen>\003printer [id]* \n    short
21974\004printer [id]* \n    long
21975\011printer [id]* \n    &LPRng; extension- verbose</screen>
21976</informalexample>
21977</para>
21978
21979<para>The <application>lpd</application> print server will then return queue status
21980and close the data connection.</para>
21981
21982<para>RFC1179 does not state in any manner what the format of the queue status
21983should be.
21984Thus, implementors have been free to augment or change the status as
21985they like.
21986Even the BSD <application/lpq/ status format has been changed from different versions.</para>
21987
21988<para>See
21989
21990<link linkend=lpq><application/lpq/ - Status Monitoring Program</link>
21991for information on the formats returned.</para>
21992
21993<para>The
21994<literal>id</literal>
21995values are used to select the jobs to be displayed.
21996&LPRng; displays any job whose ID, hostname, or user name information
21997from the control file
21998<literal remap=tt>A</literal>,
21999<literal remap=tt>H</literal>,
22000or
22001<literal remap=tt>P</literal>
22002fields match any of the id values.</para>
22003
22004<para>Note that since there is no identification of the information requestor,
22005then restriction of information is almost impossible.</para>
22006
22007</sect1>
22008
22009<sect1><title><application>lprm</application> Requests</title>
22010
22011<para>The RFC1179 protocol specifies that <application>lprm</application> job removal
22012requests can be sent to the <application>lpd</application> server.
22013The lpq requests have the format:
22014<informalexample>
22015<screen>\005printer user [id]* \n</screen>
22016</informalexample>
22017</para>
22018
22019<para>The <application>lpd</application> print server will search the specified print queue
22020and remove any job whose ID, hostname, or user name information
22021from the control file
22022<literal remap=tt>A</literal>,
22023<literal remap=tt>H</literal>,
22024or
22025<literal remap=tt>P</literal>
22026fields match any of the id values
22027and for which the user has permission to perform a removal operation.
22028See
22029<link linkend="permsref">Permissions and Authentication</link>
22030for details.</para>
22031
22032<para>Most RFC1179 compatible spoolers use the user information in the
22033request as the name of the user which spooled the job.
22034However,
22035in a network environment this is extremely easy to fabricate,
22036and is at best a weak type of authentication.</para>
22037
22038</sect1>
22039
22040<sect1 id="lpcreread"><title>LPC Requests </title>
22041
22042<para>&LPRng; has extended the RFC1179 protocol to allow queue and printer control
22043commands to be sent to the <application/lpd/ server.
22044The format of these commands are:</para>
22045
22046<para>
22047<informalexample>
22048<screen>\006printer user key [options]</screen>
22049</informalexample>
22050</para>
22051
22052<para>The following commands are supported.
22053</para>
22054<table frame=all id=lpccommands><title>LPC Commands</title>
22055<tgroup cols=2 align=left rowsep=1 colsep=1>
22056<thead>
22057<row><entry>Command</entry><entry>Operation</entry></row>
22058</thead>
22059<tbody>
22060<row><entry>Command</entry><entry>Operation</entry></row>
22061<row><entry><literal> active [printer[@host]]</literal></entry><entry>check to see if server accepting connections</entry></row>
22062<row><entry><literal> abort   (printer[@host] | all)  </literal></entry><entry>terminate server process printing job</entry></row>
22063<row><entry><literal> disable (printer[@host] | all)  </literal></entry><entry>disable queueing</entry></row>
22064<row><entry><literal> debug   (printer[@host] | all) debugparms </literal></entry><entry>set debug level for printer</entry></row>
22065<row><entry><literal> enable  (printer[@host] | all)  </literal></entry><entry>enable queueing</entry></row>
22066<row><entry><literal> hold    (printer[@host] | all) (name[@host] | job | all)* </literal></entry><entry>hold job</entry></row>
22067<row><entry><literal> holdall (printer[@host] | all)  </literal></entry><entry>hold all jobs on</entry></row>
22068<row><entry><literal> kill    (printer[@host] | all)  </literal></entry><entry>stop and restart server</entry></row>
22069<row><entry><literal> lpd [printer[@host]]  </literal></entry><entry>get <application/lpd/ PID for server</entry></row>
22070<row><entry><literal> lpq (printer[@host] | all) (name[@host] | job | all)*     </literal></entry><entry>invoke <application/lpq/</entry></row>
22071<row><entry><literal> lprm (printer[@host] | all) (name[@host]|host|job| all)*  </literal></entry><entry>invoke <application/lprm/</entry></row>
22072<row><entry><literal> move printer (user|jobid)* target </literal></entry><entry>move jobs to new queue</entry></row>
22073<row><entry><literal> noholdall (printer[@host] | all)  </literal></entry><entry>hold all jobs off</entry></row>
22074<row><entry><literal> printcap (printer[@host] | all) </literal></entry><entry>report printcap values</entry></row>
22075<row><entry><literal> quit                            </literal></entry><entry>exit LPC</entry></row>
22076<row><entry><literal> redirect (printer[@host] | all) (printer@host | off )*    </literal></entry><entry>redirect jobs</entry></row>
22077<row><entry><literal> release  (printer[@host] | all) (name[@host] | job | all)* </literal></entry><entry>release job</entry></row>
22078<row><entry><literal> reread [printer[@host]]</literal></entry><entry><application/lpd/ reread database information</entry></row>
22079<row><entry><literal> start   (printer[@host] | all)  </literal></entry><entry>start printing</entry></row>
22080<row><entry><literal> status  (printer[@host] | all)  </literal></entry><entry>status of printers</entry></row>
22081<row><entry><literal> stop    (printer[@host] | all)  </literal></entry><entry>stop printing</entry></row>
22082<row><entry><literal> topq    (printer[@host] | all) (name[@host] | job | all)* </literal></entry><entry>reorder job</entry></row>
22083<row><entry><literal> defaultq                         </literal></entry><entry>default queue for <application/lpd/ server</entry></row>
22084<row><entry><literal> local    (printer | all)  </literal></entry><entry>client printcap and configuration information</entry></row>
22085<row><entry><literal> server    (printer | all)  </literal></entry><entry>server printcap and configuration information</entry></row>
22086</tbody>
22087</tgroup>
22088</table>
22089
22090<para>Many of these commands support extremely specialized operations for
22091print queue management,
22092However, the following are the most commonly used and are supported by
22093the BSD <application/lpd/ print spooling system as well:
22094<itemizedlist>
22095
22096<listitem>
22097<para><literal> start, stop, enable, disable </literal><!-- <br> -->
22098 Start and stop will start and stop printing for a specified queue.
22099Enable and disable enable and disable sending and/or accepting jobs
22100for the queue.</para>
22101</listitem>
22102
22103<listitem>
22104<para><literal> abort, kill </literal><!-- <br> -->
22105Abort will cause the process doing the actual job printing to be terminated.
22106Kill does an abort, and then restarts the printing process.
22107These commands are used to restart a queue printing after some disaster.</para>
22108</listitem>
22109
22110<listitem>
22111<para><literal> topq </literal>
22112Places selected jobs at the top of the print queue.</para>
22113</listitem>
22114
22115<listitem>
22116<para><literal> status </literal><!-- <br> -->
22117Shows a status display of the print spools on the server.</para>
22118</listitem>
22119
22120</itemizedlist>
22121</para>
22122
22123<para>The following commands are extensions to the basic set provided by the
22124BSD <application/lpd/ system.
22125<itemizedlist>
22126
22127<listitem>
22128<para><literal> lpq, lprm </literal><!-- <br> -->
22129Invokes the lpq or lprm program from lpc.
22130Useful when in the interactive mode.</para>
22131</listitem>
22132
22133<listitem>
22134<para><literal> hold, holdall, release </literal><!-- <br> -->
22135The hold command will cause the selected jobs to be held until
22136released.
22137The holdall jobs sets all jobs submitted to the queue to be held until
22138released.
22139The release command releases jobs for printing.
22140If a job has had an error and is in the error state,
22141the release command will cause it to be reprinted.</para>
22142</listitem>
22143
22144<listitem>
22145<para><literal> move, redirect </literal><!-- <br> -->
22146The move command will move selected jobs to the specified spool queue.
22147The redirect command sends all jobs submitted to the queue to be
22148sent to the specified queue.</para>
22149</listitem>
22150
22151<listitem>
22152<para><literal> active, lpd, reread </literal><!-- <br> -->
22153The active command will connect to the server for the printer.
22154This is used to check to see if non-&LPRng; print servers are active.
22155The lpd command will connect to the server and
22156get the process id (PID) of the <application>lpd</application> server.
22157The reread command causes a SIGHUP signal to be sent to the lpd process,
22158causing it to reread the
22159<filename>lpd.conf</filename>,
22160<filename>printcap</filename>,
22161and
22162<filename>lpd.perms</filename> files.
22163This is done when configuration information has
22164been modified and the administrator wants to have the server use the
22165new information.</para>
22166</listitem>
22167
22168<listitem>
22169<para><literal> debug </literal><!-- <br> -->
22170This is a desperation facility for developers that allows dynamic enabling
22171of debug information generation.
22172Not normally used in general operation.</para>
22173</listitem>
22174
22175<listitem>
22176<para><literal> local, server  </literal><!-- <br> -->
22177These commands will print out the configuration information in the
22178local
22179<filename>lpd.conf</filename> file,
22180as well as the printcap information for the specified printers;
22181<literal>client</literal>
22182prints what the &LPRng; clients (<literal>lpr, lpq, ...</literal>) would use
22183while
22184<literal>server</literal>
22185prints what the &LPRng; server (<application>lpd</application>) would use if running on this host.
22186This is an extremely useful diagnostic tool for administrators.
22187Not normally used in general operation.</para>
22188</listitem>
22189
22190</itemizedlist>
22191</para>
22192
22193</sect1>
22194
22195<sect1 id="sendblockformat"><title>Block Job Transfer
22196</title>
22197
22198<para>Options used:
22199<itemizedlist>
22200
22201<listitem>
22202<para> <literal>send_block_format</literal> FLAG <emphasis>Transfer job as a block</emphasis></para>
22203</listitem>
22204
22205</itemizedlist>
22206</para>
22207
22208<para>In normal job transfer operations,
22209the sender and receiver have a handshake interaction in order to transfer
22210a print job.
22211Each file is sent individually.
22212The <literal>send_block_format</literal> option forces
22213a Block Job Transfer operation.
22214This causes the sender to transfer a single file containing all the
22215job printing information,
22216including control file and data files.</para>
22217
22218<para>The transfer command line has the form:
22219<informalexample>
22220<screen>\007printer size\n</screen>
22221</informalexample>
22222</para>
22223
22224<para>The receiver will return any acknowledgement of a single 0 octet,
22225and then the size bytes of the job will be transferred by the sender.
22226At the end of the transfer a single 0 octet is added,
22227and the receiver will indicate success by returning a single 0 octet.
22228Any other value returned by the receiver indicates an error condition.</para>
22229
22230<para>The file transferred by the sender is simply the command lines that it
22231would have normally sent for job transfer,
22232followed by the control or data file values.</para>
22233
22234</sect1>
22235
22236<sect1><title>Authenticated Transfer</title>
22237
22238<para>RFC1179 does not provide any authentication or encryption mechanism
22239for the transfer of jobs or commands to the <application>lpd</application>
22240print server.
22241The Authenticated Transfer operation was added to allow an encrypted
22242or authenticated transfer of print jobs or commands.</para>
22243
22244<para>Since there are various restrictions on the incorporation of authentication
22245facilities into programs,
22246&LPRng; supports authentication by providing a simple interface to
22247encryption programs.</para>
22248
22249<para>The idea is that when authentication is required when sending a job,
22250&LPRng; will generate a block transfer job as described for the
22251
22252<link linkend="sendblockformat">Block Job Transfer</link>
22253
22254operation,
22255and then invoke a set of programs to encryt and transfer the file,
22256and encrypt and transfer the returned status.</para>
22257
22258<para>Similarly,
22259when sending a command,
22260the command information will be placed in a file
22261and the encrypted file will be transferred.</para>
22262
22263<para>This technique means that the programs and support to do encryption
22264are external to &LPRng;,
22265and can use any type of method that they choose to implement the
22266secure and/or authenticated transfer.</para>
22267
22268<para>See
22269
22270<link linkend="authref">Authentication and Encryption</link>
22271
22272for details on the authentication interface.</para>
22273
22274</sect1>
22275</chapter>
22276<chapter id=FAQ><title>The Most Frequently Asked Questions </title>
22277
22278<para>In this section, the Most Frequently Asked Questions
22279have been placed, together with their answers.
22280You may notice that some questions have the same answer,
22281but the symptoms appear differently.</para>
22282
22283<para>Some of these answers will reference other material in this FAQ,
22284or the &LPRng; man pages.</para>
22285
22286
22287<sect1><title>Why do I get malformed from address errors?</title>
22288
22289<para>This is the number one question asked by most &LPRng; users
22290who try to use &LPRng; with network printers or other systems
22291supporting <link linkend="rfc1179">RFC1179</link> printing.
22292For details about &LPRng; and RFC1179, see
22293<link linkend="rfc1179ref">RFC1179 and &LPRng;</link>.</para>
22294
22295<para>The
22296<literal> malformed from address </literal>
22297error is usually reported when
22298trying to send a print job from &LPRng; to other BSD <application/lpr/ or RFC1179
22299<application/lpr/ implementations, or with network connected printers
22300that have a built in <application/lpd/ server.
22301This is due to the following RFC1179 rule:
22302<blockquote>
22303<para>Servers originate a connection from ports in the range 721-731.</para>
22304</blockquote>
22305</para>
22306
22307<para>WHY?  These are a subset of the 'reserved' ports in UNIX, and normal users
22308cannot open connections from them.  This provides a small amount
22309of security from UNIX users on the host 'spoofing' a server.</para>
22310
22311<para>IMPLICATION:  in order to do use a reserved port,  the program
22312must have root privileges.  This means the LPR, <application/lpd/, <application/lpq/, etc.,
22313programs must be installed SUID root.  This can open up a can
22314of worms with regard to security,  but &LPRng; has been designed to
22315take as much paranoid care as possible to avoid problems.</para>
22316
22317<para>WHAT TO DO:<!-- <br> -->
22318When installing &LPRng;  you will need to install the executables
22319SUID root.
22320In the <filename>src/Makefile</filename>,  you can remove the comment from the line
22321<informalexample>
22322<screen>PERMS=SUID_ROOT_PERMS</screen>
22323</informalexample>
22324
22325and then do
22326<literal> make install</literal>.
22327This will install the executables
22328SUID, and owned by root.</para>
22329
22330</sect1>
22331
22332<sect1><title>It was working normally, then I get connection refused errors</title>
22333
22334<para>This message usually appears when you have been sending a large number
22335of jobs to a network printer or a remote system.
22336The reason for this is a combination the above port 721-731 restriction
22337and the TCP/IP timeouts.
22338For details, see
22339
22340<link linkend="rfc1179ref">RFC1179 and &LPRng;</link>,
22341but here is a quick explanation.</para>
22342
22343<para>A TCP/IP connection is usually specified as between
22344<literal>srchost:srcport, desthost:destport</literal>,
22345although in practice the order of source (src) and destination
22346(dest) is not important.</para>
22347
22348<para>When a connection is established,  each end of the connection
22349exchanges the necessary flow control and error control information.
22350When a connection is terminated,
22351each end of the connection will not accept another connection from
22352the same
22353<literal>host:port</literal>
22354that was previously active
22355for a specified timeout period,
22356usually 10 minutes.</para>
22357
22358<para>Some TCP/IP implementations go further:  they will not allow
22359<acronym>ANY</acronym> connection to be <emphasis remap=bf>originated</emphasis>
22360(via the <function>bind()</function> system call or API)
22361from a port that was active,
22362or accepted on a port that was active for this timeout period.</para>
22363
22364<para>Now let us see what happens when we have a client program,
22365which must originate a connection on port 721-731, connect
22366to the server, which waits for a connection on port 515.
22367We first try to make a connection from host:port
22368<literal>1.1.1.1:721</literal>
22369to
22370<literal>1.1.1.2:515</literal>.
22371The first time that we make the connection (or the first connection)
22372we succeed.
22373We can transfer a file, etc., and then close the connection.
22374When we try to reconnect from
22375<literal>1.1.1.1:721</literal>
22376to
22377<literal>1.1.1.2:515</literal>
22378we get an error such as
22379"address already in use"
22380or "connection refused".</para>
22381
22382<para>Luckily,  we can use port 722 to originate a connection,
22383and we can connect from
22384<literal>1.1.1.1:722</literal>
22385to
22386<literal>1.1.1.2:515</literal>.
22387We continue on, until we come to port 731,
22388and then we need to wait for our timeouts.</para>
22389
22390<para>SOLUTION:</para>
22391
22392<para>It appears that most RFC1179 implementations do not check for the exact
22393port
22394range 721-731,  but only that the connection originates from a
22395reserved port,
22396i.e. - in the range 1-1023.
22397You can extend the range of ports used by &LPRng; by changing the
22398<informalexample>
22399<screen>originate_port=721 731</screen>
22400</informalexample>
22401
22402value in the defaults (<filename>LPRng/src/common/defaults.c</filename>) file or in the <filename>lpd.conf</filename>
22403file.  I recommend the following:
22404<informalexample>
22405<screen>originate_port=512 1022</screen>
22406</informalexample>
22407
22408This is, in fact, now the default in &LPRng; software.
22409If you get the infamous
22410<literal>malformed from address</literal>
22411error message from your spooler, then
22412you will have to set originate_port=721 731,  and live with
22413a delayed throughput.</para>
22414
22415</sect1>
22416
22417<sect1><title>Job is not in print queue, but it gets printed!</title>
22418
22419<para>In the original BSD <application/lpd/ implementation,
22420the <application/lpr/ program copied users files to a special spool queue directory,
22421and then caused the <application/lpd/ server to peek in the directory and print
22422the files.</para>
22423
22424<para>This type of operation required spool directory space,
22425special SETUID programs,
22426and a slew of headaches in system security and management.</para>
22427
22428<para>The LPR, <application/lpq/, and other user programs in the &LPRng; suite use TCP/IP
22429connections and transfer jobs directly to a <application/lpd/ server running on
22430a remote host,
22431or even the local host if appropriate.
22432Note that this type of operation does not require a <application/lpd/ server to run
22433on each local machine.
22434In fact,  you can have a single host system performing all of your
22435printing.
22436This type of operation is very similar to a central mail server versus
22437individual systems, each having their own mail server and queues.</para>
22438
22439<para>However,
22440some users require or want their jobs to be spooled on the local host system,
22441and then transferred to the remote printer.
22442This is usually the case when some type of processing (filtering)
22443is needed in order to print the job correctly.
22444There are several methods that can be used to force this.</para>
22445
22446<para>Method 1: Explicit Printer Address</para>
22447
22448<para>You can force a job to be sent directly to the
22449<literal> pr </literal>
22450serviced by the <application/lpd/ server on
22451<literal>host</literal>
22452by using the form:
22453<informalexample>
22454<screen>lpr -Ppr@host file</screen>
22455</informalexample>
22456</para>
22457
22458<para>You can also set the <acronym>PRINTER</acronym> environment variable to
22459a similar form, and get the same effect:
22460<informalexample>
22461<screen>PRINTER=pr@host; export PRINTER;
22462lpr file</screen>
22463</informalexample>
22464</para>
22465
22466<para>Method 2: User and Server Printcap Entries</para>
22467
22468<para>If you want to have the benefits of a printcap file,
22469i.e. - you can use aliases or abbreviations for the names of printers,
22470then here is a couple of hints.
22471First,
22472the &LPRng; software scans the <filename>printcap</filename> file for printcap
22473entries, combining information for the same printer into a single entry.
22474Information found later in the printcap file will override earlier
22475information.
22476In addition,
22477you can tag entries as either being used for all utilities or just
22478for the <application/lpd/ server.
22479Here are a couple of examples:
22480<informalexample>
22481<screen># for all utilities
22482pr:lp=pr@host
22483# just for lpd
22484pr:server
22485  :lp=/dev/lp
22486# more information
22487pr:check_for_nonprintable@
22488# --- final result for LPR
22489pr:lp=pr@host:check_for_nonprintable@
22490# --- final result for lpd
22491pr:lp=/dev/lp:check_for_nonprintable@</screen>
22492</informalexample>
22493</para>
22494
22495<para>As you can see,
22496the
22497<literal>server</literal>
22498keyword indicates that the printcap entry is only for the server.
22499The <application/lpr/ utility will send the job to the host, while the <application/lpd/ server
22500will print it on <filename>/dev/lp</filename>.</para>
22501
22502<para>Note that the <literal>lp=...</literal> information overrides the
22503<literal remap=tt>:rp:</literal>
22504(remote printer)
22505and
22506<literal remap=tt>:rm:</literal>
22507(remote machine) fields if they are present.</para>
22508
22509<para>Method 3: Force sending to server on
22510<literal>localhost</literal></para>
22511
22512<para>The
22513<literal>force_localhost</literal>
22514printcap or configuration flag forces non-<application/lpd/ applications to send all
22515requests and print jobs to the server running on the local host.</para>
22516
22517<para>This method is similar to the previous one,
22518but has the benefit that it can be configured as a global (i.e. -
22519applies to all printers) rather than printer specific.
22520You can put this in the <filename>lpd.conf</filename> file for general
22521application,  or have a printcap entry of the following form:
22522<informalexample>
22523<screen># for all utilities
22524pr:lp=pr@host:force_localhost</screen>
22525</informalexample>
22526</para>
22527
22528<para>The <application/lpd/ server will ignore the
22529<literal>force_localhost</literal> flag,
22530and send jobs to the
22531<literal>pr</literal>
22532queue on the
22533<literal>host</literal>
22534machine.
22535However, the LPR, <application/lpq/, etc., utilities will send their requests to the
22536server running on the local host.</para>
22537
22538</sect1>
22539
22540<sect1><title>Job disappears and is never printed, but lpr works</title>
22541
22542<para>This is a rather disconcerting problem,
22543and usually occurs when sending jobs to either a network printer or
22544a nonconforming
22545
22546<link linkend="rfc1179">RFC1179</link>
22547
22548print spooler.
22549For details about &LPRng; and RFC1179, see
22550
22551<link linkend="rfc1179ref">RFC1179 and &LPRng;</link>,
22552but here is a quick explanation.</para>
22553
22554<para>An <application/lpd/ job consists of a control file,  which contains information
22555about the job,  and one or more data files.  RFC1179 is silent on the
22556order that jobs are sent;  however some implementations REQUIRE that
22557the data files be sent first,  followed by the control file.</para>
22558
22559<para>SOLUTION:</para>
22560
22561<para>Set the <literal>send_data_first</literal> flag in the printcap for the particular
22562printer,  or in the <filename>lpd.conf</filename> configuration file.  This is:
22563<informalexample>
22564<screen>:send_data_first:  (printcap)
22565send_data_first    (lpd.conf)</screen>
22566</informalexample>
22567</para>
22568
22569<para>Note that some printers/servers INSIST on the control file first;
22570You can clear the flag using <literal>send_job_first@</literal> if you need to.</para>
22571
22572</sect1>
22573
22574<sect1><title>I get messages about bad control file format</title>
22575
22576<para>RFC1179 describes a set of fields that MAY appear in the control file.
22577It is silent if other ones can appear as well.
22578Unfortunately,  some implementations will reject jobs unless they contain
22579ONLY fields from a very small set.  In addition,  RFC1179 is silent
22580about the ORDER the fields can appear.</para>
22581
22582<para>&LPRng; quite happily will accept jobs from poor or nonconforming RFC1179
22583spooler programs,
22584and fix them up to be conformant.</para>
22585
22586<para>If you are sending jobs to one of a non-conforming spooler,
22587you can force &LPRng; to send jobs with only the fields described
22588in RFC1179 by setting the
22589the
22590<literal> :bk: </literal>
22591(BacKwards compatible) flag in the
22592printcap for your printer.</para>
22593
22594</sect1>
22595
22596<sect1 id="rfc1179"><title>What is RFC 1179, the Line Printer Daemon Protocol?  </title>
22597
22598<para>RFC1179 defines a standard method by which print jobs can be transferred
22599using the TCP/IP protocol between hosts.
22600The standard was developed by simply detailing the way that
22601a version of the BSD <application/lpd/ software did its job.</para>
22602
22603<para>From the RFC Introduction:
22604<blockquote>
22605<para>RFC 1179 describes a print server protocol widely used on
22606the Internet for communicating between line printer daemons (both
22607clients and servers).  RFC1179 is for informational purposes only,
22608and does not specify an Internet standard.</para>
22609</blockquote>
22610</para>
22611
22612<para>Having said this,
22613the RFC then goes on to describe the protocol used
22614by a particular implementation of <application/lpd/.
22615The problem was that the RFC did not provide
22616any way to put extensions to the operations into the system,
22617and failed to specify such interesting details as the order in which
22618print jobs and their components could be transferred.</para>
22619
22620<para>Comment by Patrick Powell
22621<literal> &lt;papowell@lprng.com&gt; </literal>:
22622<blockquote>
22623
22624<para>Since 1988,
22625there have been a large number of print spooling systems developed which
22626claim RFC1179 conformance,
22627but which are mutually incompatible.</para>
22628
22629<para>Rather than live with the limited capabilities of the RFC1179 standard,
22630&LPRng; has extended them by adding capabilities to perform remote control
22631of print spoolers,
22632encrypted and authenticated data transfers,
22633and other operations missing from the RFC1179 specification.
22634However,
22635great effort was made to be backwards compatible with older and other <application/lpd/
22636based systems.</para>
22637
22638<para>&LPRng; was developed in order to be able to both accept and provide
22639interactions with these systems.  It does so by allowing various options
22640to be used to <emphasis>tune</emphasis>
22641how print jobs would be exchanged.
22642Currently,
22643&LPRng; can be configured to send and receive print jobs between a vast number
22644of the existing spooling systems.
22645It is flexible enough to act as a gateway between non-compatible systems,
22646and has provisions to transform jobs from one format to another in a dynamic
22647manner.</para>
22648</blockquote>
22649</para>
22650
22651<para>For a detailed explanation
22652about &LPRng; and RFC1179, see
22653
22654<link linkend="rfc1179ref">RFC1179 and &LPRng;</link>.</para>
22655
22656</sect1>
22657
22658<sect1><title>I want to replace lp, lpstat, etc, but my programs need them</title>
22659
22660<para>&LPRng; was designed as a replacement the BSD printing system. As such,
22661it inherited its command names and options from the latter. As you
22662might know, SystemV uses a totally different set of commands,
22663incompatible with the BSD ones.</para>
22664
22665<para>The good news is that the &LPRng; binaries include an emulation for the
22666SystemV commands.
22667(See
22668
22669<link linkend="lpsimulation">lp Simulation</link>
22670
22671for details.
22672Briefly, you create links to the appropriate programs,
22673and invoke them by the link names.
22674<emphasis>Actually, these links are installed by default in recent versions.</emphasis></para>
22675
22676<para>
22677<informalexample>
22678<screen>ln -s lpr lp
22679ln -s lpq lpstat
22680ln -s lprm cancel</screen>
22681</informalexample>
22682</para>
22683
22684<para>If you make these links, calling
22685<literal>lp</literal>,
22686<literal>lpstat</literal>
22687and
22688<literal>cancel</literal>
22689will give you a (partial) SVR4 emulation. They have
22690their own man pages, which you should read if you need the emulation.</para>
22691
22692<para>Since it is a <emphasis remap=bf>partial</emphasis>
22693emulation, you shouldn't expect everything
22694to work. In particular, I would guess that any script which relies on
22695the output format of one of your system binaries will break.
22696Again, see
22697
22698<link linkend="lpsimulation">lp Simulation</link>
22699
22700for more details or additional suggestions.</para>
22701
22702</sect1>
22703</chapter>
22704
22705
22706<chapter id=remotelogger><title>Remote Logger Operation</title>
22707
22708<para>Several sites have wanted a way to provide central logging of job
22709status and/or information.  In order to do this,  the following functionality
22710is implemented in &LPRng;.</para>
22711
22712
22713<sect1 id="logger"><title>Logger Network Communication </title>
22714
22715<para>Options used:
22716<itemizedlist>
22717
22718<listitem>
22719<para><literal>logger_destination=</literal><emphasis>logger information destination</emphasis></para>
22720</listitem>
22721
22722<listitem>
22723<para><literal>logger_pathname=</literal><emphasis>pathname of temp file for log information</emphasis></para>
22724</listitem>
22725
22726<listitem>
22727<para><literal>logger_max_size=</literal><emphasis>max size in K of temp file for log information</emphasis></para>
22728</listitem>
22729
22730<listitem>
22731<para><literal>logger_timeout=</literal><emphasis>time between connection attempts</emphasis></para>
22732</listitem>
22733
22734</itemizedlist>
22735</para>
22736
22737<para>The printcap/configuration variable <literal>logger_destination</literal> specifies
22738a destination in the standard
22739<literal>host%port</literal>
22740notation used by &LPRng;.
22741Host is the destination host, and can be a name or IP address.
22742Port is the port on the destination host.
22743A TCP/IP connection is made to the indicated port.</para>
22744
22745<para>Log information is save in a temporary file specified by
22746<literal>logger_path</literal>,
22747and up to
22748<literal>logger_max_size</literal>  K bytes of data will be saved.</para>
22749
22750<para>If a connection cannot be made to the
22751<literal>logger_destination</literal>,
22752then every
22753<literal>logger_timeout</literal> seconds a new connection attempt will be made.
22754If <literal>logger_timeout</literal> is 0,
22755then a connection attempt will be made every time new data arrives to be logged.</para>
22756
22757</sect1>
22758
22759<sect1><title>Logger Messages</title>
22760
22761<para>Log messages consist of a single line
22762terminated with a newline (<literal>\n</literal>) character.</para>
22763
22764<para>Each log message reports a system event or status change of the
22765LPD server.
22766When the connection is first established,
22767a complete dump of the status of the LPD server is sent.
22768After this,
22769only status update messages are sent.
22770The remote monitor can force a status dump by simply closing and
22771reopening the connection.</para>
22772
22773</sect1>
22774
22775<sect1><title>Message Format</title>
22776
22777<para>Each message is encoded as a URI escaped string.
22778That is, non-alphanumeric characters are encoded as the 3 character
22779sequence
22780<literal>%xx</literal>,  where
22781<literal>xx</literal>
22782is the hexadecimal value of the character.
22783The message has the format <literal>key=value</literal>,
22784where
22785<literal>key</literal>
22786indicates the message type.
22787For example:
22788<informalexample>
22789<screen>
22790dump=host=h4.private%0aprinter=t1%0aprocess=1613%0a
22791update_time=1999-03-23-20:32:17.148%0a\
22792value=queue=holdall 0%25250aprinting_aborted=0x0%25250a\
22793printing_disabled=0x0%25250aspooling_disabled=\
227940x0%25250a%250a%0a</screen>
22795</informalexample>
22796</para>
22797
22798<para>The following keys are used:
22799<orderedlist>
22800
22801<listitem>
22802<para>dump<!-- <br> -->
22803A status dump of the current contents of a print queue.</para>
22804</listitem>
22805
22806</orderedlist>
22807</para>
22808
22809<para>Each message has a set of headers and a value.
22810For example,
22811the decoded dump message from the previous section would be:
22812<informalexample>
22813<screen>host=h4.private
22814printer=t1
22815process=1613
22816update_time=1999-03-23-20:32:17.148
22817value=queue=holdall 0%250aprinting_aborted=0x0%250a\
22818printing_disabled=0x0%250aspooling_disabled=0x0%250a%0a</screen>
22819</informalexample>
22820</para>
22821
22822<para>Each line consists of a key and a value.
22823The
22824<literal>host</literal>
22825key indicates the host name,
22826<literal>printer</literal>
22827is the print queue,
22828<literal>process</literal>
22829is the process which generated the report or action,
22830<literal>update_time</literal> is the time at which the report was generated,
22831and
22832<literal>value</literal>
22833is the value of the report.</para>
22834
22835<para>The decoded
22836<literal>value</literal>
22837of the above report is:
22838<informalexample>
22839<screen>queue='holdall 0%0aprinting_aborted=0x0%0aprinting_disabled=0x0%0a\
22840spooling_disabled=0x0%0a</screen>
22841</informalexample>
22842</para>
22843
22844<para>The
22845<literal>queue</literal>
22846key provides the current value of the queue control file.</para>
22847
22848</sect1>
22849
22850<sect1><title>Dump Messages</title>
22851
22852<para>Dump messages are generated at the start of operations,
22853and consist of a list of queue status messages.</para>
22854
22855</sect1>
22856
22857<sect1><title>LPD Messages</title>
22858
22859<para>These are used to indicate LPD startup or change in operation.
22860<informalexample>
22861<screen>Decode: lpd=host=h4.private%0aprocess=1672%0aupdate_time=1999-03-23-20:5
228621:10.507%0avalue=Starting%0a
22863host=h4.private
22864process=1672
22865update_time=1999-03-23-20:51:10.507
22866value=Starting
22867lpd: 'Starting'</screen>
22868</informalexample>
22869</para>
22870
22871</sect1>
22872
22873<sect1><title>Job Status Messages - UPDATE</title>
22874
22875<para>Update messages are used to report changes in the queue contents,
22876such as job arrival.
22877<informalexample>
22878<screen>Decode: update=host=h4.private%0aidentifier=papowell@h4+676%0anumber=
22879 ...
22880host=h4.private
22881identifier=papowell@h4+676
22882number=676
22883printer=t1
22884process=1677
22885update_time=1999-03-23-20:51:17.197
22886value=bnrname=papowell%0acf_esc_image=Apapowell@h4+676%250aCA%250aD1999-03-
22887  ...</screen>
22888</informalexample>
22889</para>
22890
22891<para>This update message reports the arrival of a new job at the queue.
22892The
22893<literal>value</literal>
22894field reports the control file contents:
22895<informalexample>
22896<screen>cf_esc_image=Apapowell@h4+676%0aCA%0aD1999-03-23-20:51:17.151%0aHh4.as
22897   tart.com%0aJ/tmp/hi%0aLpapowell%0aPpapowell%0aQt1%0aN/tmp/hi%0afdfA676h4.as
22898   tart.com%0aUdfA676h4.private%0a
22899class=A
22900date=1999-03-23-20:51:17.151
22901file_hostname=h4.private
22902fromhost=h4.private
22903held=0x0
22904hf_name=/var/tmp/LPD/t1/hfA676
22905hold_class=0x0
22906hold_time=0x0
22907identifier=papowell@h4+676
22908job_time=0x36f86f45
22909jobname=/tmp/hi
22910logname=papowell
22911number=676
22912priority=A
22913queuename=t1
22914size=3
22915transfername=cfA676h4.private
22916update_time=1999-03-23-20:51:17.187</screen>
22917</informalexample>
22918</para>
22919
22920<para>The <literal>update_time</literal> field in the section above is the time that the
22921job information was last updated.
22922The <literal>cf_esc_image</literal> value is the URL escaped control file information.</para>
22923
22924</sect1>
22925
22926<sect1><title>Printer Status Messages - PRSTATUS</title>
22927
22928<para>These messages report printing or other activity related to a job.
22929<informalexample>
22930<screen>Decode: prstatus=host=h4.private%0aidentifier=papowell@h4+676%0anumber=
22931676%0aprinter=t1%0aprocess=1692%0aupdate_time=1999-03-23-21:02:04.855%0avalue=
22932finished 'papowell@h4+676'%252c status 'JSUCC'%0a
22933
22934host=h4.private
22935identifier=papowell@h4+676
22936number=676
22937printer=t1
22938process=1692
22939update_time=1999-03-23-21:02:04.855
22940value=finished 'papowell@h4+676'%2c status 'JSUCC'
22941PRSTATUS: 'finished 'papowell@h4+676', status 'JSUCC''</screen>
22942</informalexample>
22943</para>
22944
22945</sect1>
22946</chapter>
22947<appendix id="optionindex"><title>Index To All The Configuration and Printcap Options </title>
22948
22949<table frame=all id=lprngoptions><title>&LPRng; Options</title>
22950<tgroup cols=2 colsep=1 rowsep=1 align=left>
22951<thead>
22952<row><entry>Option </entry><entry> Purpose or Value </entry></row>
22953</thead>
22954<tbody>
22955<row><entry><link linkend="bannerprinting">ab</link></entry><entry>
22956always print banner, ignore lpr -h option <!-- <br> -->
22957<row><entry><link linkend="reception">accounting_namefixup</link></entry><entry>
22958update accounting name information<!-- <br> -->
22959</entry></row><row><entry><link linkend="opendevice">achk</link></entry><entry>
22960query accounting server when connected <!-- <br> -->
22961</entry></row><row><entry><link linkend="normalterm">ae</link></entry><entry>
22962accounting at end (see also af, la, ar, as) <!-- <br> -->
22963</entry></row><row><entry><link linkend="opendevice">af</link></entry><entry>
22964name of accounting file (see also la, ar) <!-- <br> -->
22965</entry></row><row><entry><link linkend="ah">ah</link></entry><entry>
22966automatically hold all jobs <!-- <br> -->
22967</entry></row><row><entry><link linkend="configfile">allow_getenv</link></entry><entry>
22968Allow use of LPD_CONF <!-- <br> -->
22969</entry></row><row><entry><link linkend="jobcompletion">allow_user_logging</link></entry><entry>
22970allow users to request logging info using lpr -mhost%port <!-- <br> -->
22971</entry></row><row><entry><link linkend="allowusersetting">allow_user_setting</link></entry><entry>
22972allow privileged user to impersonate other users<!-- <br> -->
22973</entry></row><row><entry><link linkend="opendevice">ar</link></entry><entry>
22974enable remote transfer accounting (if af is set) <!-- <br> -->
22975</entry></row><row><entry><link linkend="opendevice">as</link></entry><entry>
22976accounting at start (see also af, la, ar) <!-- <br> -->
22977</entry></row><row><entry><link linkend="auth">use_auth</link></entry><entry>
22978authentication type to use <!-- <br> -->
22979</entry></row><row><entry><link linkend="auth">auth_forward</link></entry><entry>
22980authentication type for forwarding<!-- <br> -->
22981</entry></row><row><entry><link linkend="bannerprinting">be</link></entry><entry>
22982Banner at End Generation Program <!-- <br> -->
22983</entry></row><row><entry><link linkend="bk">bk</link></entry><entry>
22984Berkeley <application/lpd/ job file format <!-- <br> -->
22985</entry></row><row><entry><link linkend="filteroptions">bk_filter_options</link></entry><entry>
22986Berkeley <application/lpd/ filter options <!-- <br> -->
22987</entry></row><row><entry><link linkend="filteroptions">bk_of_filter_options</link></entry><entry>
22988Berkeley <application/lpd/ OF filter options <!-- <br> -->
22989</entry></row><row><entry><link linkend="filteroptions">bkf</link></entry><entry>
22990backwards-compatible filters: use simple parameters <!-- <br> -->
22991</entry></row><row><entry><link linkend="bannerprinting">bl</link></entry><entry>
22992short banner line sent to banner printer <!-- <br> -->
22993</entry></row><row><entry><link linkend="bannerprinting">bp</link></entry><entry>
22994Banner Generation Program (see bs, be) <!-- <br> -->
22995</entry></row><row><entry><link linkend="lpdbounce">bq_format</link></entry><entry>
22996Format of bounce queue output <!-- <br> -->
22997</entry></row><row><entry><link linkend="serial">br</link></entry><entry>
22998Serial port bit rate (see ty) <!-- <br> -->
22999</entry></row><row><entry><link linkend="bannerprinting">bs</link></entry><entry>
23000Banner at Start Generation Program <!-- <br> -->
23001</entry></row><row><entry><link linkend="checkfornonprintable">check_for_nonprintable</link></entry><entry>
23002<application/lpr/ checks for nonprintable file <!-- <br> -->
23003</entry></row><row><entry><link linkend="classinstatus">class_in_status</link></entry><entry>
23004Show job class name in
23005<application>lpq</application>
23006status information <!-- <br> -->
23007</entry></row><row><entry><link linkend="printcapparse">client</link></entry><entry>
23008Mark printcap entry for client programs only <!-- <br> -->
23009</entry></row><row><entry><link linkend="cm">cm</link></entry><entry>
23010comment identifying printer (<application/lpq/) <!-- <br> -->
23011</entry></row><row><entry><link linkend="configfile">config_file</link></entry><entry>
23012configuration file <!-- <br> -->
23013</entry></row><row><entry><link linkend="opendevice">connect_grace</link></entry><entry>
23014connection control for remote printers <!-- <br> -->
23015</entry></row><row><entry><link linkend="opendevice">connect_interval</link></entry><entry>
23016connection control for remote printers <!-- <br> -->
23017</entry></row><row><entry><link linkend="opendevice">connect_timeout</link></entry><entry>
23018connection control for remote printers <!-- <br> -->
23019</entry></row><row><entry><link linkend="opendevice">connect_try</link></entry><entry>
23020connection control for remote printers <!-- <br> -->
23021</entry></row><row><entry><link linkend="logfiles">create_files</link></entry><entry>
23022create spool queue files <!-- <br> -->
23023</entry></row><row><entry><link linkend="opendevice">control_filter</link></entry><entry>
23024control file filter <!-- <br> -->
23025</entry></row><row><entry><link linkend="debugging">db</link></entry><entry>
23026debug options for queue <!-- <br> -->
23027</entry></row><row><entry><link linkend="defaultformat">default_format</link></entry><entry>
23028default job format <!-- <br> -->
23029</entry></row><row><entry><link linkend="defaultpermission">default_permission</link></entry><entry>
23030default permission for files <!-- <br> -->
23031</entry></row><row><entry><link linkend="defaultrmrp">default_printer</link></entry><entry>
23032default printer <!-- <br> -->
23033</entry></row><row><entry><link linkend="classpriority">default_priority</link></entry><entry>
23034default job priority <!-- <br> -->
23035</entry></row><row><entry><link linkend="defaultrmrp">default_remote_host</link></entry><entry>
23036default remote host <!-- <br> -->
23037</entry></row><row><entry><link linkend="configsetup">default_tmp_dir</link></entry><entry>
23038default directory for temp files <!-- <br> -->
23039</entry></row><row><entry><link linkend="destinations">destinations</link></entry><entry>
23040printers that a route filter may return and we should query <!-- <br> -->
23041</entry></row><row><entry><link linkend="normalterm">done_jobs</link></entry><entry>
23042save status for last N jobs <!-- <br> -->
23043</entry></row><row><entry><link linkend="normalterm">done_jobs_max_age</link></entry><entry>
23044remove status older than N seconds <!-- <br> -->
23045</entry></row><row><entry><link linkend="reception">fifo</link></entry><entry>
23046enforce FIFO job ordering<!-- <br> -->
23047</entry></row><row><entry><link linkend="opendevice">ff</link></entry><entry>
23048string to send for a form feed <!-- <br> -->
23049</entry></row><row><entry><link linkend="filteroptions">filter_ld_path</link></entry><entry>
23050filter LD_LIBRARY_PATH value <!-- <br> -->
23051</entry></row><row><entry><link linkend="filteroptions">filter_options</link></entry><entry>
23052filter options <!-- <br> -->
23053</entry></row><row><entry><link linkend="filteroptions">filter_path</link></entry><entry>
23054filter PATH environment variable <!-- <br> -->
23055</entry></row><row><entry><link linkend="opendevice">fo</link></entry><entry>
23056send form feed when device is opened <!-- <br> -->
23057</entry></row><row><entry><link linkend="forcefqdnhostname">force_fqdn_hostname</link></entry><entry>
23058force FQDN hostname value in control file <!-- <br> -->
23059</entry></row><row><entry><link linkend="forcelocalhost">force_localhost</link></entry><entry>
23060force clients to send all requests to localhost <!-- <br> -->
23061</entry></row><row><entry><link linkend="qq">force_queuename</link></entry><entry>
23062force use of this queuename if none provided <!-- <br> -->
23063</entry></row><row><entry><link linkend="normalterm">fq</link></entry><entry>
23064send form feed when device is closed <!-- <br> -->
23065</entry></row><row><entry><link linkend="debugging">full_time</link></entry><entry>
23066use extended time format <!-- <br> -->
23067</entry></row><row><entry><link linkend="bannerprinting">generate_banner</link></entry><entry>
23068generate banner page for forwarded jobs<!-- <br> -->
23069</entry></row><row><entry><link linkend="usergroup">group</link></entry><entry>
23070Effective Group ID (EGID) for SUID ROOT programs <!-- <br> -->
23071</entry></row><row><entry><link linkend="normalterm">half_close</link></entry><entry>
23072Use shutdown(fd,1) when sending job to remote printer instead of close(fd)
23073</entry></row><row><entry><link linkend="bannerprinting">hl</link></entry><entry>
23074Header (banner) last, at end of job <!-- <br> -->
23075</entry></row><row><entry><link linkend="classpriority">ignore_requested_user_priority</link></entry><entry>
23076Ignore requested user priority <!-- <br> -->
23077</entry></row><row><entry><link linkend="reception">incoming_control_filter</link></entry><entry>
23078incoming job control filter <!-- <br> -->
23079</entry></row><row><entry><link linkend="printjobformats">if</link></entry><entry>
23080default (f, l) filter program <!-- <br> -->
23081</entry></row><row><entry><link linkend="configsetup">ipv6</link></entry><entry>
23082using IPV6 conventions <!-- <br> -->
23083</entry></row><row><entry><link linkend="kerberos">kerberos_keytab</link></entry><entry>
23084kerberos keytab file location <!-- <br> -->
23085</entry></row><row><entry><link linkend="kerberos">kerberos_life</link></entry><entry>
23086kerberos key lifetime <!-- <br> -->
23087</entry></row><row><entry><link linkend="kerberos">kerberos_renew</link></entry><entry>
23088kerberos key renewal time <!-- <br> -->
23089</entry></row><row><entry><link linkend="kerberos">kerberos_forward_principal</link></entry><entry>
23090kerberos remote principle name for forwarding <!-- <br> -->
23091</entry></row><row><entry><link linkend="kerberos">kerberos_server_principal</link></entry><entry>
23092kerberos remote server principle name <!-- <br> -->
23093</entry></row><row><entry><link linkend="kerberos">kerberos_service</link></entry><entry>
23094kerberos default service <!-- <br> -->
23095</entry></row><row><entry><link linkend="opendevice">la</link></entry><entry>
23096enable local printer accounting (if af is set) <!-- <br> -->
23097</entry></row><row><entry><link linkend="opendevice">ld</link></entry><entry>
23098leader string sent on printer open <!-- <br> -->
23099</entry></row><row><entry><link linkend="logfiles">lf</link></entry><entry>
23100error log file for spool queue <!-- <br> -->
23101</entry></row><row><entry><link linkend="opendevice">lk</link></entry><entry>
23102lock the IO device <!-- <br> -->
23103</entry></row><row><entry><link linkend="configsetup">lockfile</link></entry><entry>
23104lpd lock file <!-- <br> -->
23105</entry></row><row><entry><link linkend="logger">logger_destination</link></entry><entry>
23106destination for logging information <!-- <br> -->
23107</entry></row><row><entry><link linkend="logger">logger_timeout</link></entry><entry>
23108intervals between connection attempts <!-- <br> -->
23109</entry></row><row><entry><link linkend="logger">logger_pathname</link></entry><entry>
23110temp file for log information <!-- <br> -->
23111</entry></row><row><entry><link linkend="logger">logger_max_size</link></entry><entry>
23112max size in Kbytes of temp file for log information <!-- <br> -->
23113</entry></row><row><entry><link linkend="jobtransfer">longnumber</link></entry><entry>
23114use long job number when a job is submitted <!-- <br> -->
23115</entry></row><row><entry><link linkend="simple">lp</link></entry><entry>
23116printer device name or specification <!-- <br> -->
23117</entry></row><row><entry><link linkend="lpdbounce">lpd_bounce</link></entry><entry>
23118force lpd to filter job before forwarding <!-- <br> -->
23119</entry></row><row><entry><link linkend="spoolq">lpd_force_poll</link></entry><entry>
23120force lpd to poll idle printers <!-- <br> -->
23121</entry></row><row><entry><link linkend="spoolq">lpd_poll_time</link></entry><entry>
23122interval between lpd printer polls <!-- <br> -->
23123</entry></row><row><entry><link linkend="lpdport">lpd_port</link></entry><entry>
23124lpd listening port <!-- <br> -->
23125</entry></row><row><entry><link linkend="printcappath">lpd_printcap_path</link></entry><entry>
23126lpd printcap path <!-- <br> -->
23127</entry></row><row><entry><link linkend="lprbounce">lpr_bounce</link></entry><entry>
23128lpr does filtering as in bounce queue <!-- <br> -->
23129</entry></row><row><entry><link linkend="jobcompletion">lpr_bsd</link></entry><entry>
23130lpr does filtering as in bounce queue <!-- <br> -->
23131</entry></row><row><entry><link linkend="abnormalterm">mail_from</link></entry><entry>
23132mail user from user name <!-- <br> -->
23133</entry></row><row><entry><link linkend="abnormalterm">mail_operator_on_error</link></entry><entry>
23134mail to this operator on error <!-- <br> -->
23135</entry></row><row><entry><link linkend="abnormalterm">max_connect_interval</link></entry><entry>
23136maximum time between connection attempts <!-- <br> -->
23137</entry></row><row><entry><link linkend="logfiles">max_log_file_size</link></entry><entry>
23138maximum size (in K) of spool queue log file <!-- <br> -->
23139</entry></row><row><entry><link linkend="spoolq">max_servers_active</link></entry><entry>
23140maximum number of lpd queue servers that can be active <!-- <br> -->
23141</entry></row><row><entry><link linkend="logfiles">max_status_line</link></entry><entry>
23142maximum length of status line <!-- <br> -->
23143</entry></row><row><entry><link linkend="logfiles">max_status_size</link></entry><entry>
23144maximum size (in K) of status file <!-- <br> -->
23145</entry></row><row><entry><link linkend="jobcopies">mc</link></entry><entry>
23146maximum copies allowed <!-- <br> -->
23147</entry></row><row><entry><link linkend="logfiles">min_log_file_size</link></entry><entry>
23148minimum size (in K) of spool queue log file <!-- <br> -->
23149</entry></row><row><entry><link linkend="logfiles">min_status_size</link></entry><entry>
23150minimum size to reduce status file to <!-- <br> -->
23151</entry></row><row><entry><link linkend="minfree">minfree</link></entry><entry>
23152minimum amount of free space needed <!-- <br> -->
23153</entry></row><row><entry><link linkend="checkfornonprintable">ml</link></entry><entry>
23154minimum number of printable characters for printable check <!-- <br> -->
23155</entry></row><row><entry><link linkend="debugging">ms_time_resolution</link></entry><entry>
23156millisecond time resolution <!-- <br> -->
23157</entry></row><row><entry><link linkend="jobcopies">mx</link></entry><entry>
23158maximum job size (1Kb blocks, 0 = unlimited) <!-- <br> -->
23159</entry></row><row><entry><link linkend="opendevice">nb</link></entry><entry>
23160use nonblocking device open <!-- <br> -->
23161</entry></row><row><entry><link linkend="opendevice">network_connect_grace</link></entry><entry>
23162pause between transferring jobs to remote printer <!-- <br> -->
23163</entry></row><row><entry><link linkend="jobfiles">nline_after_file</link></entry><entry>
23164N line after file name <!-- <br> -->
23165</entry></row><row><entry><link linkend="bannerprinting">of</link></entry><entry>
23166banner output filter <!-- <br> -->
23167</entry></row><row><entry><link linkend="filteroptions">of_filter_options</link></entry><entry>
23168OF filter options <!-- <br> -->
23169</entry></row><row><entry><link linkend="printcapparse">oh</link></entry><entry>
23170Printcap entry valid only on these hosts <!-- <br> -->
23171</entry></row><row><entry><link linkend="lpdport">originate_port</link></entry><entry>
23172originate connections from these ports <!-- <br> -->
23173</entry></row><row><entry><link linkend="filteroptions">pass_env</link></entry><entry>
23174clients pass these environment variables to filters <!-- <br> -->
23175</entry></row><row><entry><link linkend="permspath">perms_path</link></entry><entry>
23176lpd.perms files <!-- <br> -->
23177</entry></row><row><entry><link linkend="filteroptions">pl</link></entry><entry>
23178page length (in lines) <!-- <br> -->
23179</entry></row><row><entry><link linkend="pr">pr</link></entry><entry>
23180pr program for p format <!-- <br> -->
23181</entry></row><row><entry><link linkend="printcappath">printcap_path</link></entry><entry>
23182 printcap file <!-- <br> -->
23183</entry></row><row><entry><link linkend="logfiles">ps</link></entry><entry>
23184printer status file name <!-- <br> -->
23185</entry></row><row><entry><link linkend="filteroptions">pw</link></entry><entry>
23186page width (in characters) <!-- <br> -->
23187</entry></row><row><entry><link linkend="filteroptions">px</link></entry><entry>
23188page width in pixels (horizontal) <!-- <br> -->
23189</entry></row><row><entry><link linkend="filteroptions">py</link></entry><entry>
23190page length in pixels (vertical) <!-- <br> -->
23191</entry></row><row><entry><link linkend="queuelockfile">queue_lock_file</link></entry><entry>
23192queue lock file name<!-- <br> -->
23193</entry></row><row><entry><link linkend="queuecontrolfile">queue_control_file</link></entry><entry>
23194queue control file name<!-- <br> -->
23195</entry></row><row><entry><link linkend="logfiles">queue_status_file</link></entry><entry>
23196queue status file name<!-- <br> -->
23197</entry></row><row><entry><link linkend="qq">qq</link></entry><entry>
23198put queue name in control file <!-- <br> -->
23199</entry></row><row><entry><link linkend="remotesupport">remote_support</link></entry><entry>
23200operations allowed to remote host <!-- <br> -->
23201</entry></row><row><entry><link linkend="configsetup">report_server_as</link></entry><entry>
23202server name for status reports <!-- <br> -->
23203</entry></row><row><entry><link linkend="lpdport">retry_econnrefused</link></entry><entry>
23204Retry on connect ECONNREFUSED errors <!-- <br> -->
23205</entry></row><row><entry><link linkend="lpdport">retry_nolink</link></entry><entry>
23206Retry device open or connect failures <!-- <br> -->
23207</entry></row><row><entry><link linkend="shortstatus">return_short_status</link></entry><entry>
23208return short lpq status when request arrives from specified host <!-- <br> -->
23209</entry></row><row><entry><link linkend="lpdport">reuse_addr</link></entry><entry>
23210set SO_REUSEADDR on outgoing ports <!-- <br> -->
23211</entry></row><row><entry><link linkend="reverselpqformat">reverse_lpq_format</link></entry><entry>
23212reverse lpq format when request arrives from specified host <!-- <br> -->
23213</entry></row><row><entry><link linkend="rg">rg</link></entry><entry>
23214clients allow only users in this group access to printer <!-- <br> -->
23215</entry></row><row><entry><link linkend="simple">rm</link></entry><entry>
23216remote machine (hostname) (with rp) <!-- <br> -->
23217</entry></row><row><entry><link linkend="destinations">router</link></entry><entry>
23218routing filter, returns destinations <!-- <br> -->
23219</entry></row><row><entry><link linkend="simple">rp</link></entry><entry>
23220remote printer name (with rm) <!-- <br> -->
23221</entry></row><row><entry><link linkend="opendevice">rw</link></entry><entry>
23222open printer for reading and writing <!-- <br> -->
23223</entry></row><row><entry><link linkend="safechars">safe_chars</link></entry><entry>
23224additional safe characters in control file lines <!-- <br> -->
23225</entry></row><row><entry><link linkend="abnormalterm">save_on_error</link></entry><entry>
23226save job when an error <!-- <br> -->
23227</entry></row><row><entry><link linkend="normalterm">save_when_done</link></entry><entry>
23228save job when done <!-- <br> -->
23229</entry></row><row><entry><link linkend="bannerprinting">sb</link></entry><entry>
23230short banner (one line only) <!-- <br> -->
23231</entry></row><row><entry><link linkend="spoolqueue">sd</link></entry><entry>
23232spool directory pathname <!-- <br> -->
23233</entry></row><row><entry><link linkend="sendblockformat">send_block_format</link></entry><entry>
23234send block of data, rather than individual files <!-- <br> -->
23235</entry></row><row><entry><link linkend="jobtransfer">send_data_first</link></entry><entry>
23236send data files first in job transfer <!-- <br> -->
23237</entry></row><row><entry><link linkend="abnormalterm">send_failure_action</link></entry><entry>
23238failure action to take after send_try attempts failed <!-- <br> -->
23239</entry></row><row><entry><link linkend="printingjob">send_job_rw_timeout</link></entry><entry>
23240print job read/write timeout <!-- <br> -->
23241</entry></row><row><entry><link linkend="printingjob">send_query_rw_timeout</link></entry><entry>
23242status query operation read/write timeout <!-- <br> -->
23243</entry></row><row><entry><link linkend="abnormalterm">send_try</link></entry><entry>
23244maximum number of times to try sending job <!-- <br> -->
23245</entry></row><row><entry><link linkend="abnormalterm">sendmail</link></entry><entry>
23246sendmail program <!-- <br> -->
23247</entry></row><row><entry><link linkend="printcapparse">server</link></entry><entry>
23248Mark printcap entry for lpd server program only <!-- <br> -->
23249</entry></row><row><entry><link linkend="opendevice">server_tmp_dir</link></entry><entry>
23250server temporary file directory <!-- <br> -->
23251</entry></row><row><entry><link linkend="printingjob">sf</link></entry><entry>
23252suppress form feeds separating data files in job <!-- <br> -->
23253</entry></row><row><entry><link linkend="bannerprinting">sh</link></entry><entry>
23254suppress header (banner) pages <!-- <br> -->
23255</entry></row><row><entry><link linkend="logfiles">short_status_date</link></entry><entry>
23256short (hh:mm) timestamp format for status <!-- <br> -->
23257</entry></row><row><entry><link linkend="shortstatus">short_status_length</link></entry><entry>
23258short lpq status length in lines <!-- <br> -->
23259</entry></row><row><entry><link linkend="lpdport">socket_linger</link></entry><entry>
23260set the SO_LINGER socket option <!-- <br> -->
23261</entry></row><row><entry><link linkend="configsetup">spool_dir_perms</link></entry><entry>
23262spool directory permissions <!-- <br> -->
23263</entry></row><row><entry><link linkend="configsetup">spool_file_perms</link></entry><entry>
23264spool file permissions <!-- <br> -->
23265</entry></row><row><entry><link linkend="loadbalance">ss</link></entry><entry>
23266name of queue that server serves (with sv) <!-- <br> -->
23267</entry></row><row><entry><link linkend="stalledtime">stalled_time</link></entry><entry>
23268time after which to report active job stalled <!-- <br> -->
23269</entry></row><row><entry><link linkend="abnormalterm">stop_on_abort</link></entry><entry>
23270stop processing queue on filter abort <!-- <br> -->
23271</entry></row><row><entry><link linkend="serial">stty</link></entry><entry>
23272stty commands to set output line characteristics <!-- <br> -->
23273</entry></row><row><entry><link linkend="loadbalance">sv</link></entry><entry>
23274names of servers for queue (with ss) <!-- <br> -->
23275</entry></row><row><entry><link linkend="debugging">syslog_device</link></entry><entry>
23276name of syslog device <!-- <br> -->
23277</entry></row><row><entry><link linkend="printcapparse">tc</link></entry><entry>
23278Include indicated printcap entries in current entry<!-- <br> -->
23279</entry></row><row><entry><link linkend="normalterm">tr</link></entry><entry>
23280trailer string to send before closing printer <!-- <br> -->
23281</entry></row><row><entry><link linkend="translateformat">translate_format</link></entry><entry>
23282translate data format in control file <!-- <br> -->
23283</entry></row><row><entry><link linkend="lpdport">unix_socket_path</link></entry><entry>
23284FIFO path for local process connections<!-- <br> -->
23285</entry></row><row><entry><link linkend="debugging">use_info_cache</link></entry><entry>
23286read and cache information <!-- <br> -->
23287</entry></row><row><entry><link linkend="jobtransfer">use_shorthost</link></entry><entry>
23288Use short hostname for lpr control and data file names <!-- <br> -->
23289</entry></row><row><entry><link linkend="usergroup">user</link></entry><entry>
23290Effective User ID (EUID) for SUID ROOT programs <!-- <br> -->
23291</entry></row><row><entry><link linkend="normalterm">wait_for_eof</link></entry><entry>
23292Wait for EOF on connection <!-- <br> -->
23293</entry></row>
23294</tbody>
23295</tgroup>
23296</table>
23297</appendix>
23298<appendix id=license><title>License</title>
23299<para>
23300<programlisting>
23301&license;
23302</programlisting>
23303</para>
23304</appendix>
23305
23306<appendix id=testing><title>Testing and Diagnostic Facilities</title>
23307
23308<para>The &LPRng; code has the ability to run as non-setuid software,
23309and to use the non-default TCP/IP ports for communication.
23310This facility allows a <emphasis>Test Version</emphasis>
23311to be run in parallel with the
23312normal &LPRng; software.</para>
23313
23314<para>To simplify testing and portability issues,
23315a simple test version of the spool queues and jobs has been supplied with the
23316&LPRng; distribution.
23317These queues can be placed in a suitable location
23318(<filename>/tmp</filename> is common) and the &LPRng; software tested.</para>
23319
23320<para>The test version of the software will use the <literal>LPD_CONF</literal>
23321environment variable to specify the location of the configuration file.
23322It will read this configuration file on startup and use the values
23323to override the normal defaults.
23324Since a user could maliciously set up their own configuration files
23325with values that could compromise system security,
23326it is strongly recommended that the test version is not made SETUID root.
23327In fact,
23328the &LPRng; code will chatter messages when the LPD_CONF ability is enabled
23329and it is run as root.</para>
23330
23331
23332<sect1><title>Compiling the Test Version</title>
23333
23334<para>Edit <filename>src/Makefile</filename>, and uncomment the indicated line.
23335Then run
23336<literal>make</literal>
23337to regenerate the distribution.
23338<informalexample>
23339<screen>#### ****** TESTING AND SECURITY LOOPHOLE ******************************
23340# Define GETENV to allow the LPD_CONFIG environment
23341#  variable to be used as the name of a configuration file.  In non-testing
23342#  systems,  this is a security loophole.
23343#CF := $(CF) -DGETENV
23344</screen>
23345</informalexample>
23346</para>
23347
23348</sect1>
23349
23350<sect1><title>Setting Up The Test Version Spool Queues</title>
23351
23352<para>The &LPRng; <acronym>TESTSUPPORT</acronym> directory contains a set of shell scripts
23353and files that need to be installed in the appropriate directory.
23354The following steps are used.
23355<orderedlist>
23356
23357<listitem>
23358<para>First,
23359you need to set up your <acronym>HOST</acronym> environment variable to the fully
23360qualified domain name of your host
23361and your <acronym>USER</acronym> environment variable to your user name.
23362This is done in order to get values to put into the Test Version configuration files.</para>
23363</listitem>
23364
23365<listitem>
23366<para>In the <acronym>TESTSUPPORT</acronym> directory,
23367edit the
23368<literal>Makefile</literal>,
23369and specify the location of the
23370<literal>Test Version</literal>
23371spool queues.
23372The default location is <filename>/tmp</filename>;
23373since on most systems these files are deleted or are available to everybody,
23374a more secure location should most likely be used.
23375<emphasis remap=bf>DO NOT USE THE RAW TESTFILE DIRECTORY</emphasis>.
23376These files need to be copied and placed in another directory.</para>
23377</listitem>
23378
23379<listitem>
23380<para>The <literal>LPD_CONF</literal> environment variable should be set to the
23381location of the installed <filename>lpd.conf</filename> file.</para>
23382</listitem>
23383
23384<listitem>
23385<para>In the <acronym>TESTSUPPORT</acronym> directory,
23386run
23387<literal>make</literal>.
23388This will copy and install the necessary files.</para>
23389</listitem>
23390
23391</orderedlist>
23392</para>
23393
23394<para>Example:
23395<informalexample>
23396<screen>  CSH:
23397    setenv HOST {fully qualified domain name};
23398    setenv USER `whoami`
23399    setenv LPD_CONF /tmp/LPD/lpd.conf
23400    set path=( /tmp/LPD $path )
23401    unsetenv PRINTER
23402   Example:
23403      setenv HOST h4.private
23404      setenv USER papowell
23405      setenv LPD_CONF /tmp/LPD/lpd.conf
23406      set path=( /tmp/LPD $path )
23407      unsetenv PRINTER
23408  Bourne Shell:
23409    HOST={fully qualified domain name}; export HOST;
23410    USER='whoami'; export USER
23411    LPD_CONF=/tmp/LPD/lpd.conf.$HOST; export LPD_CONF
23412    PATH=/tmp/LPD:$PATH; export PATH
23413    PRINTER=; export PRINTER
23414   Example:
23415      HOST=h4.private; export HOST
23416      USER=papowell; export USER
23417      LPD_CONF=/tmp/LPD/lpd.conf.$HOST; export LPD_CONF
23418      PATH=/tmp/LPD:$PATH; export PATH
23419      PRINTER=; export PRINTER
23420  cd TESTSUPPORT
23421  make</screen>
23422</informalexample>
23423</para>
23424
23425</sect1>
23426
23427<sect1><title>Running the Test Version Software</title>
23428
23429<para>Set your current directory to the location of the compiled
23430<literal>Test Version</literal>
23431executables.
23432Execute the various executables using <filename>./cmd</filename>,
23433or set
23434<literal remap=tt>.</literal>
23435<emphasis remap=bf> as the first entry in the PATH </emphasis>.
23436If it is not the first entry,
23437then the standard system executables will be used.
23438<orderedlist>
23439
23440<listitem>
23441<para> Run <filename>./checkpc</filename>.
23442this will print out the various values for the spool queues in the
23443<literal>Test Version</literal>
23444setup.
23445If the
23446<literal>t1</literal>,
23447<literal>t2</literal>,... spool queues are not displayed,
23448make sure that the LPD_CONF environment variable is set correctly and that you
23449are using the
23450<literal>Test Version</literal>
23451executable.</para>
23452</listitem>
23453
23454<listitem>
23455<para>Run
23456<literal>./checkpc -f</literal>.
23457This will fix up the (deliberately introduced) problems in the spool queues.</para>
23458</listitem>
23459
23460<listitem>
23461<para>Next,  run
23462<literal>./lpd -F</literal>
23463in one window,
23464and then run
23465<literal>./lpq -a </literal>
23466in another window.
23467This will check that the server is working.</para>
23468</listitem>
23469
23470<listitem>
23471<para>You can now amuse yourself by sending jobs,
23472setting up permissions checking,
23473and other chores.</para>
23474</listitem>
23475
23476<listitem>
23477<para>When everything appears to be working correctly,
23478you can then remove the
23479<literal>Test Version</literal>
23480flag from the
23481<filename>src/Makefile</filename>, recompile,
23482and install the &LPRng; software.</para>
23483</listitem>
23484
23485</orderedlist>
23486</para>
23487
23488</sect1>
23489</appendix>
23490&genindex.sgml;
23491</book>
23492