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&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 <papowell@lprng.com> 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-<version>.tgz | tar xvf -</userinput> 1611<prompt>h4: {5} % </prompt><userinput>cd LPRng-<version></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 >/tmp/candidates</userinput> 1951<prompt>h4: {30} # </prompt><userinput>find /sbin -type f -name lp\* -print >>/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 <---- old 1956/usr/bin/lpr <---- old 1957/usr/bin/lprm <---- 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 <--- old 1968/usr/sbin/lpd <--- old 1969/usr/sbin/lpf <--- 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 >/dev/null 2>& ; then 2080 mv /etc/inetd.conf /etc/inetd.conf.bak 2081 sed -e 's/^printer/# printer/' </etc/inetd.conf.bak \ 2082 >/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 >/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 -> ../../init.d/lp 2110lrwxrwxr-x 1 root bin 1 Dec 29 23:39 /etc/rc2.d/K20lp -> ../../init.d/lp 2111lrwxrwxr-x 1 root bin 1 Dec 29 23:39 /etc/rc2.d/S80lp -> ../../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 >/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>></prompt> <userinput> if [ -f $i -a '!' -f $i.old ] ; then mv $i $i.old ; fi;</userinput> 2148<prompt>></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 <PMSPECIFIC> 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;}'` >/dev/null 2>&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 | -> | lpr | -> | lpd | -> | filter | -> | printer | 3038+---------+ +-----+ * +-----+ +--------+ +---------+ 3039 * * | 3040 printcap V 3041 +-----+ +--------+ +---------+ 3042 | lpd | -> | filter | -> | 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 >/tmp/hi</userinput> 3283<prompt>h4: {87} # </prompt><userinput>echo there >/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" >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>status 3630 Printer Printing Spooling Jobs Server Subserver Redirect Status/(Debug) 3631lp@h4 enabled enabled 0 none none 3632lpc>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>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>status 3876 Printer Printing Spooling Jobs Server Subserver Redirect Status/(Debug) 3877lp@h4 enabled enabled 3 17990 17993 3878lpc>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>stop lp 3883Printer: lp@h4 3884lp@h4.private: stopped 3885lpc>start lp 3886Printer: lp@h4 3887lp@h4.private: started 3888lpc>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 "$@" >&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=> 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<value> 4426$'X -X'<value>' 4427$0X -X '<value>' 4428$-X <value> 4429$'-X '<value>' 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><</literal>), 4543or 4544output redirection (<literal>></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 "$@" >&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=> 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 >/tmp/before 4827fi 4828Args="$@" 4829if -n $Debug ; then 4830 echo "$@" >>/tmp/before 4831fi 4832while expr "$1" : '-.*' >/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 -> flag=1 4849# flag@ -> flag=0 4850# option=value -> option='value' 4851# 4852setpcvals () { 4853 while test "$#" -gt 0 ; do 4854 iI=$1 4855 if expr "$iI" : " *\:" >/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 -> flag=1 4882# flag@ -> flag=0 4883# option=value -> 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 >/tmp/after 4917 echo "$@" >>/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> e=dfA021771h4.private 49332a4,6 4934> l=66 4935> s=status 4936> L=papowell 493710a15,17 4938> j=021771 4939> C=A 4940> J=/tmp/hi 494112a20 4942> a=acct 4943... 494433a58 4945> 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 -> $option{$key}=$value 5009# set :key@ -> $option{$key}="0" 5010# set :key -> $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=- - && 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 >hi</userinput> 5429<prompt>h4: {193} % </prompt><userinput>gzip -c hi >hi.gz</userinput> 5430<prompt>h4: {194} % </prompt><userinput>echo "%!PS-Adobe-3.0" >test.ps</userinput> 5431<prompt>h4: {195} % </prompt><userinput>gzip -c test.ps >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 - <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>&1 1>&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 >&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 >&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'" >&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 <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>&1 1>&2 5499<prompt>h4: {199} % </prompt><userinput>/tmp/majik </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>&1 1>&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>&1 1>&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'" >&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^]&^]&k2G^]&s0C^]&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' >>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 "$@" >>/tmp/trace 6545 cat >>/tmp/trace 6546 cat <<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 $@ >>/tmp/chooser 7636set >>/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=> 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 <<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 ->lp2 <cpy 0/2> 7885 - papowell@h4+235.2 ->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 = <STDIN>; 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, <papowell@lprng.com> 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 '<NULL>' 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 '<NULL>' 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 '<NULL>' 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 >&/tmp/logfile &</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 >& /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 '<NULL>', 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 -> 9023 lp:lp=lp@localhost:... 9024 lpr -Plp@10.0.0.1 -> 9025 lp:lp=lp@10.0.0.1 (no other options) 9026 9027lp:lp=lp@10.0.0.1:force_localhost@:... 9028 lpr -Plp -> 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 >/dev/null 2>&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 < file 10694Example: 10695 nc 10.0.0.25 9100 < 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 -> MIO MENU (use MENU to display MIO MENU) 10963 ITEM -> CFG NETWORK=NO* 10964 + -> CFG NETWORK=YES 10965 ENTER -> CFG NETWORK=YES* 10966 ITEM -> TCP/IP=OFF* (use ITEM to display TCP/IP) 10967 + -> TCP/IP=ON 10968 ENTER -> TCP/IP=ON* 10969 ITEM -> CFG TCP/IP=NO* (use ITEM to display TCP/IP) 10970 + -> CFG TCP/IP=YES 10971 ENTER -> CFG TCP/IP=YES* 10972 ITEM -> BOOTP=NO* 10973 (Enable BOOTP if you want to - see below) 10974 ITEM -> 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 -> 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 -> 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 -> 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 -> 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>&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 >/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>&2 11600 for i in 1 2 3 4 5 6 7 8 9; 11601 do 11602 echo PRINTER $printer $i > $printer; 11603 done 11604 echo -e \\r\\f > $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>&2; cat $1 ) <$DEV >$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 ->t1@localhost <cpy 1/2> 3 10:04:49 13260 - papowell@lprng2+707.2 A 707 ->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 [<space><tab>] in the script 13589printcap.time: $(PRINTCAP) Makefile 13590 if [ -f $(PRINTCAP) ]; then \ 13591 sed < $(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' > .printcap.$$$$; \ 13597 cat .printcap.$$$$; \ 13598 if [ $$? = 0 -a -s .printcap.$$$$ ]; then \ 13599 awk <.printcap.$$$$ '{ FS=":"; OFS="\t"; } { \ 13600 n = split($$1, names, "|"); \ 13601 for (i=1; i<=n; i++) \ 13602 if (length(names[i]) > 0 \ 13603 && names[i] !~ /[ \t]/) \ 13604 print names[i], $$0; \ 13605 }' | $(MAKEDBM) - $(YPDBDIR)/$(DOM)/printcap.byname; \ 13606 awk <.printcap.$$$$ '{ FS=":"; OFS="\t"; } { \ 13607 n = split($$1, names, "|"); \ 13608 if (n && length(names[1]) > 0 && 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 <sr1@os.inf.tu-dresden.de> 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 (<>) { 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 >=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>/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 <whitem@bofh.usask.ca> 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> Apologies in advance if this is way off mark, but we've been 13875> evaluating a commercial print charging package (Geomica) which 13876> works by talking to the printer in what I think is a similar way 13877> to the ifhp filters. Lexmarks are currently a big headache because 13878> they seem to fail to return the message that they have finished 13879> printing which screws things up somewhat. In our case, it is believed 13880> to be a problem with the Lexmark firmware which they are looking 13881> 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 & 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><</literal> 17321or 17322<literal>></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`" >/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-<em>version</em>.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> 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<$(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#> 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>#> chmod 400 lpr.wayoff.com 19626#> scp lpr.wayoff.com root@wayoff.com:/etc/lpd.keytab 19627#> ssh -l root wayoff.com 19628# wayoff > chmod 400 /etc/lpd.keytab 19629# wayoff > chown daemon /etc/lpd.keytab 19630# wayoff > 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%$^&^%$ 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) && 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> <papowell@lprng.com> </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