<!-- $FreeBSD$ -->
<!-- FreeBSD Documentation Project -->

<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN">

<book>
  <bookinfo>
    <title>The FreeBSD Corporate Networker's Guide</title>

    <author>
      <firstname>Ted</firstname>
      <surname>Mittelstaedt</surname>
    </author>

    <copyright>
      <year>2000</year>
      <holder>Addison-Wesley Longman, Inc</holder>
    </copyright>

    <isbn>ISBN: 0-201-70481-1</isbn>
    
    <legalnotice>
      <para>The eighth chapter of the book, <citetitle>The FreeBSD Corporate
	  Networker's Guide</citetitle> is excerpted here with the permission
	of the publisher.  No part of it may be further reproduced or
	distributed without the publisher's express written
	<email>Chanda.Leary-Coutu@awl.com</email>.
	The other chapters of
	<ulink url="http://cseng.aw.com/book/0,,0201704811,00.html">the
	  book</ulink> covers topics such as system administration,
	fileserving, and e-mail delivery.  More information about this book is
	available from the publisher, with whom you can also sign up to
	receive news of <ulink url="mailto:Chanda.Leary-Coutu@awl.com">related
	  titles</ulink>.  The author's web site for the book includes sample
	code, working examples,
	<ulink url="http://www.freebsd-corp-net-guide.com/errata.html">errata</ulink>
	and a Q&amp;A forum, and is available at
	<ulink url="http://www.freebsd-corp-net-guide.com/">http://www.freebsd-corp-net-guide.com/</ulink>.</para>
    </legalnotice>
  </bookinfo>

  <chapter label="8">
    <title>Printserving</title>

    <para>Printserving is a complicated topic.  There are many different
      software interfaces to printers, as well as a wide variety of printer
      hardware interfaces.  This chapter covers the basics of setting up a
      print queue, using Samba to print, and administering print queues and
      connections.</para>

    <sect1>
      <title>PC printing history</title>

      <para>In the early days of the personal computer, printing was simple.
	The PC owner bought a cheap printer, usually a dot matrix that barely
	supported ASCII, and plugged it into the computer with a parallel
	cable.  Applications would either work with the printer or not, and
	most did because all they could do was output DOS or ASCII text.  The
	few software applications that supported graphics generally could only
	output on specific makes and models of printers.  Shared
	<emphasis>network</emphasis> printing, if it existed, was usually done
	by some type of serial port switchbox.</para>

      <para>This was the general state of affairs with the PC until the
	Windows operating system was released.  All at once, application
	programmers were finally free of the restrictions of worrying about
	how some printer manufacturer would change printer control codes.
	Graphics printing, in the form of fonts and images, was added to most
	applications, and demand for it rapidly increased across the
	corporation.  Large, high-capacity laser printers designed for office
	printing appeared on the scene.  Printing went from 150 to 300 to
	600dpi for the common desktop laser printer.</para>

      <para>Today organizational network printing is complex, and printers
	themselves are more complicated.  Most organizations find that sharing
	a few high-quality laser printers is much more cost effective than
	buying many cheaper dot matrix units.  Good network print serving is a
	necessity, and it can be very well provided by the FreeBSD UNIX
	system.</para>
    </sect1>

    <sect1>
      <title>Printer communication protocols and hardware</title>

      <para>Printers that don't use proprietary vendor codes communicate with
	computers using one or more of three major printing protocols.  The
	communication is done over a hardware cable that can be a parallel
	connection (printer port) or a serial connection (COM port).</para>

      <sect2>
	<title>ASCII Printing Protocol</title>

	<para>The ASCII protocol is the simplest protocol used, as well as the
	  oldest.  ASCII is also used to represent text files internally in
	  the DOS, UNIX, and Windows operating systems.  Therefore, data taken
	  from a text file or a directory listing generally requires little
	  preparation before being sent to the printer, other than a
	  newline-to-carriage return/linefeed conversion for UNIX.  Printers
	  usually follow the DOS text file convention of the print head
	  requiring an explicit carriage return character followed by a
	  linefeed character at the end of a line of text.  Since UNIX uses
	  only the linefeed character to terminate text, an additional
	  carriage return character must be added to the end of each line in
	  raw text print output; otherwise, text prints in a
	  <emphasis>stairstep</emphasis> output.  (Some printers have hardware
	  or software switches to do the conversion)</para>
      </sect2>

      <sect2>
	<title>PostScript Printing Protocol</title>

	<para>Adobe introduced the PostScript language in 1985; it is used to
	  enable the printout of high quality graphics and styled font text.
	  PostScript is now the de-facto print standard in the UNIX community,
	  and the only print standard in the Macintosh community.  Numerous
	  UNIX utilities exist to <emphasis>beautify</emphasis> and enhance
	  text printing with PostScript.  PostScript can be used to download
	  font files into a printer as well as the data to be printed.
	  PostScript commands can be sent to instruct the printer CPU to
	  image, rotate, and scale complex graphics and images, thus freeing
	  the host CPU.  Scaling is particularly important with fonts since
	  the document with the font has been produced on a computer screen
	  with far lower resolution than the printer.  For example, a 1024x768
	  computer screen on a 17-inch monitor allows for a resolution of
	  approximately 82dpi, a modern desktop printer prints at a resolution
	  of 600dpi.  Therefore, a font must be scaled at least seven times
	  larger for WYSIWYG output!</para>

	<para>PostScript printers generally come with a number of resident
	  fonts.  For example, the NEC Silentwriter 95 contains Courier,
	  Helvetica, ITC Avant Garde Gothic Book, ITC Bookman Light, New
	  Century Schoolbook Roman, Palatino Roman, Times Roman, and several
	  symbol fonts.  These are stored in Read Only Memory (ROM) in the
	  printer.  When a page is printed from a Windows client that contains
	  a font not in the printer, a font substitution table is used.  If no
	  substitute can be made, Courier is usually used.  The user should be
	  conscious of this when creating documents - documents with fonts not
	  listed in the substitution table may cause other users problems when
	  printing.  Avoid use of strange fonts for documents that will be
	  widely distributed.</para>

	<para>The user program can choose to download different fonts as
	  outline fonts to the PostScript printer if desired.  Fonts that are
	  commonly used by the user are often downloaded to PostScript
	  printers that are connected directly to the user's computer, the
	  fonts are then available to successive print jobs until the printer
	  is turned off.  When PostScript printers are networked, the clients
	  must download any fonts desired <emphasis>with each print
	    job</emphasis>.  Since jobs come from different clients, the
	  clients cannot assume that downloaded fonts will still be in the
	  printer.</para>

	<para>PostScript print jobs also contain a header that is sent
	  describing the page layout, among other things.  On a shared network
	  printer, this header must also be downloaded with each print job.
	  Although some PostScript drivers allow downloading of the header
	  only once, this usually requires a bi-directional serial connection
	  to the printer, instead of a unidirectional parallel
	  connection.</para>

	<para>PostScript print jobs can be sent either as binary data or as
	  ASCII.  The main advantage of binary data transmission is that it is
	  faster.  However, not all PostScript printers support it.  Also,
	  fonts can generally not be downloaded in binary.  When FreeBSD is
	  used as a printserver, ASCII PostScript printing should be selected
	  on the clients, this is generally the default with most PostScript
	  drivers.</para>

	<para>The Adobe company licenses PostScript interpreters as well as
	  resident fonts to printer manufacturers, and extracts a hefty
	  license fee from any printer manufacturer who wants to use them in
	  its printer.  This presents both a benefit and a problem to the end
	  user.  Although a single company holding control over a standard can
	  guarantee compliance, it does significantly raise the cost of the
	  printer.  As a result, PostScript has not met with much success in
	  lower-end laser and inkjet Windows printing market, despite the fact
	  that Adobe distributes PostScript software operating system drivers
	  for free.</para>

	<para>One issue that is a concern when networking PostScript printers
	  is the selection of banner page, (also known as header page, or
	  <emphasis>burst page)</emphasis> printing.  UNIX shared printing
	  began with ASCII line printers, and since UNIX is a multiuser
	  system, often many different user print jobs piled up in the printer
	  output hopper.  To separate these jobs the UNIX printing system
	  programs support banner page printing if the client program that
	  submits jobs asks for them.  These pages print at the beginning or
	  end of every print job and contain the username, submittal date, and
	  so on..  By default, most clients, whether remote (e.g., a Windows
	  LPR client) or local (e.g., the <command>/usr/bin/lpr</command>
	  program) trigger a banner page to be printed.  One problem is that
	  some PostScript printers abort the entire job if they get
	  unformatted ASCII text instead of PostScript.  (In general,
	  PostScript printers compatible with Hewlett-Packard Printer Control
	  Language [HPPCL] handle banners without problems) Banner printing
	  should be disabled for any printers with this problem, unless
	  PostScript banner page printing is set up on the server.</para>
      </sect2>

      <sect2>
	<title>HPPCL Printing Protocol</title>

	<para>The Hewlett Packard company currently holds the largest market
	  share of desktop inkjet and office laser printers.  Back when
	  Windows was released, HP decided to expand into the desktop laser
	  jet market with the first LaserJet series of printers.  At the time
	  there was much pressure on Microsoft to use Adobe Type Manager for
	  scaleable fonts within Windows, and to print PostScript to
	  higher-end printers.  Microsoft decided against doing this and used
	  a technically inferior font standard, Truetype.  They thought that
	  it would be unlikely that the user would download fonts to the
	  printer, since desktop Publishing was not being done on PC's at the
	  time. Instead users would rasterize the entire page to the printer
	  using whatever proprietary graphics printer codes the selected
	  printer needed.  HP devised HPPCL for their LaserJets, and make
	  PostScript an add-on.  The current revision of HPPCL now allows for
	  many of the same scaling and font download commands that PostScript
	  does.  HP laser jet printers that support PostScript can be
	  distinguished by the letter "M" in their model number.  (M is for
	  Macintosh, since Macintosh requires PostScript to print) For
	  example, the HP 6MP has PostScript, the 6P doesn't.</para>

	<para>HPPCL has almost no support in the UNIX applications market, and
	  it is very unlikely that any will appear soon.  One big reason is
	  the development of the free <application>Ghostscript</application>
	  PostScript interpreter.  <application>Ghostscript</application> can
	  take a PostScript input stream and print it on a PCL printer under
	  UNIX.  Another reason is the UNIX community's dislike of reinventing
	  the wheel.  HPPCL has no advantage over PostScript, and in many ways
	  there are fewer problems with PostScript.  Considering that
	  PostScript can be added to a printer, either by hardware or use of
	  <application>Ghostscript</application>, what is the point of
	  exchanging an existing working solution for a slightly technically
	  inferior one?  Over the life of the printer, taking into account the
	  costs of toner, paper, and maintenance, the initial higher cost of
	  PostScript support is infinitesimal.</para>
      </sect2>
    </sect1>

    <sect1>
      <title>Network Printing Basics</title>

      <para>The most common network printing implementation is a printserver
	accepting print jobs from clients tied to the server via a network
	cable.</para>

      <sect2>
	<title>Printservers</title>

	<para>The term "printserver" is one of those networking terms, like
	  <emphasis>packet,</emphasis> that has been carelessly tossed around
	  until it's meaning has become somewhat confusing and blurred.  To be
	  specific, a printserver is simply a program that arbitrates print
	  data from multiple clients for a single printer.  Printservers can
	  be implemented in one of the four methods described in the following
	  sections.</para>

	<sect3>
	  <title>Printserver on the fileserver</title>

	  <para>The printer can be physically cabled to the PC running the
	    Network OS.  Print jobs are submitted by clients to the
	    printserver software on the fileserver, which sends them down the
	    parallel or serial cable to the printer.  The printer must be
	    physically close to the fileserver.  This kind of printserving is
	    popular in smaller workgroup networks, in smaller offices.</para>

	  <figure>
	    <title>Printserver on the fileserver</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="08-01" format="EPS">
	      </imageobject>

	      <textobject>
		<literallayout class="monospaced"> ,---------.
 | ======= |                        Server
 | ======= |               +---------------------+        ,-----.
+-----------+              |  +---------------+  |        |     |
|  Printer [ ]------------[ ] |  Printserver  |  |        |_____| 
+-----------+	Parallel   |  |   Software    | [ ]------_________
		 Cable     |  +---------------+  |      / ::::::: \
                           +---------------------+      `---------'
                                                         Network PC</literallayout>
	      </textobject>

	      <textobject>
		<phrase>Printer, connected to a network server running
		  printserver software, with one or more network PCs printing
		  through it.</phrase>
	      </textobject>
	    </mediaobject>
	  </figure>
	</sect3>

	<sect3>
	  <title>Printserver on a separate PC</title>

	  <para>It is possible to run a print server program on a cheap PC
	    that is located next to the printer and plugged into it via
	    parallel cable.  This program simply acts as a pass-through
	    program, taking network packets from the network interface and
	    passing them to the printer.  This kind of server doesn't allow
	    any manipulation of print jobs, jobs usually come from a central
	    fileserver, where jobs are controlled.</para>

	  <figure>
	    <title>Printserver on a separate PC</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="08-02" format="EPS">
	      </imageobject>
	      
	      <textobject>
		<literallayout class="monospaced">                                                     Fileserver
                                                 ,----------------.
  ,---------.                                .---| |          === |
  | ======= |               ,-----.          |   `----------======'
  | ======= |               |     |          |
 +-----------+              |_____|          |
 |  Printer [ ]------------_________---------| Ethernet
 +-----------+   Parallel / ::::::: \        |
                  Cable   `---------'        |
		          Printserver        |          ,-----.
                                             |          |     |
					     |          |_____|
					     `---------_________
						      / ::::::: \
						      `---------'
						       Network PC</literallayout>
	      </textobject>

	      <textobject>
		<phrase>Printer connected to a printserver (typically running
		  FreeBSD), with network files hosted on a separate machine,
		  and a network PC, able to access both resources.</phrase>
	      </textobject>
	    </mediaobject>
	  </figure>
	</sect3>

	<sect3>
	  <title>Printserver on a separate hardware box</title>

	  <para>A printserver on a separate hardware box is exemplified by
	    network devices such as the Intel Netport, the HP JetDirect Ex,
	    the Osicom/DPI NETPrint, and the Lexmark MarkNet. Basically, these
	    are plastic boxes with an Ethernet connection on one side and a
	    parallel port on the other.  Like a printserver on a PC, these
	    devices don't allow remote job manipulation, and merely pass
	    packets from the network down the parallel port to the
	    printer.</para>

	  <figure>
	    <title>Printserver on a separate hardware box</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="08-03" format="EPS">
	      </imageobject>

	      <textobject>
		<literallayout class="monospaced">                                                     Fileserver
                                                 ,----------------.
  ,---------.                                .---| |          === |
  | ======= |                                |   `----------======'
  | ======= |              Printserver       |
 +-----------+             ,--------.        |
 |  Printer [ ]-----------[ ]  ooo [ ]-------| Ethernet
 +-----------+   Parallel  `--------'        |
                  Cable                      |
		                             |          ,-----.
                                             |          |     |
					     |          |_____|
					     `---------_________
						      / ::::::: \
						      `---------'
						       Network PC</literallayout>
	      </textobject>

	      <textobject>
		<phrase>Printer connected to a dedicated print server
		  <quote>appliance</quote>.</phrase>
	      </textobject>
	    </mediaobject>
	  </figure>
	</sect3>

	<sect3>
	  <title>Printserver in the Printer</title>

	  <para>The HP JetDirect Internal is the best known printserver of
	    this type.  It is inserted into a slot in the printer case, and it
	    works identically to the external JetDirect units.</para>

	  <figure>
	    <title>Printeserver in the printer</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="08-04" format="EPS">
	      </imageobject>

	      <textobject>
		<literallayout class="monospaced">                                                     Fileserver
                                                 ,----------------.
  ,---------.                                .---| |          === |
  | ======= |                                |   `----------======'
  | ======= |                                |
 +-----------+                               |
 |  Printer [ ]------------------------------| Ethernet
 +-----------+                               |
                                             |
		                             |          ,-----.
                                             |          |     |
					     |          |_____|
					     `---------_________
						      / ::::::: \
						      `---------'
						       Network PC</literallayout>
	      </textobject>

	      <textobject>
		<phrase>Printer with an embedded print server, connecting
		  directly to the local network.</phrase>
	      </textobject>
	    </mediaobject>
	  </figure>
	</sect3>
      </sect2>

      <sect2>
	<title>Printspools</title>

	<para>Printspooling is an integral part of network printing.  Since
	  the PC can spit out data much faster than the printer can accept it,
	  the data must be buffered in a spool at some location.  In addition,
	  because many clients share printers, when clients send print jobs at
	  the same time, jobs must be placed on a queue so that one can be
	  printed after the other.</para>

	<sect3>
	  <title>Logical location of the print spool</title>

	  <para>Printspooling can be implemented at one of three
	    locations</para>

	  <orderedlist>
	    <listitem>
	      <para>The client.  Clients can be required to spool their own
		print jobs on their own disks.  For example, when a Windows
		client application generates a print job the job must be
		placed on the local client's hard drive.  Once the remote
		print server is free to accept the job it signals the client
		to start sending the job a bit at a time.  Client spooling is
		popular in peer-to-peer networks with no defined central
		fileserver.  However, it is impossible for a central
		administrator to perform advanced print job management tasks
		such as moving a particular print job ahead of another, or
		deleting jobs.</para>
	    </listitem>

	    <listitem>
	      <para>The printserver.  If each printer on the network is
		allocated their own combination print spooler-printserver,
		jobs can stack at the printer.  Many of the larger printers
		with internal printservers have internal hard disks for this
		purpose.  Although this enables basic job management, it still
		restricts the ability to move jobs from one printer to
		another.</para>
	    </listitem>

	    <listitem>
	      <para><emphasis>A central print spooler on a
		  fileserver</emphasis>.  Print jobs are received from all
		clients on the network in the spool and then dispatched to the
		appropriate printer.  This scheme is the best for locations
		with several busy printers and many clients.  Administration
		is extremely simple because all print jobs are spooled on a
		central server, which is particularly important in bigger
		organizations.  Many large organizations have standardized on
		PostScript printing for all printing; in the event that a
		particular printer fails and is offline, incoming PostScript
		print jobs can be rerouted automatically to another printer.
		Since all printers and clients are using PostScript, clients
		don't need to be reconfigured when this happens.  Print jobs
		appear the same whether printed on a 4 page-per-minute NEC
		Silentwriter 95, or a 24 page-per-minute HP LaserJet 5SiMX if
		both printers are defined in the client as PostScript
		printers.</para>
	    </listitem>
	  </orderedlist>

	  <figure>
	    <title>Print spool locations</title>

	    <mediaobject>
	      <imageobject>
		<imagedata fileref="08-05" format="EPS">
	      </imageobject>

	      <textobject>
		<literallayout class="monospaced">                               Client
  ,---------.                                                        PC
  | ======= |                                                      ,-----.
  | ======= |                                                      |     |
 +-----------+                                                     |_____|
 |  Printer [ ]---------------------------------------------------_________
 +-----------+                                                   / ::::::: \
		                                                 `---------'
		                                                    Spool

                               Printserver                          
  ,---------.                                                        PC
  | ======= |                                                      ,-----.
  | ======= |                                                      |     |
 +-----------+               ,----------------.                    |_____|
 |  Printer [ ]--------------| |          === |-------------------_________
 +-----------+               `----------======'                  / ::::::: \
                                   Spool                         `---------'


                               Fileserver
  ,---------.                                                        PC
  | ======= |                                                      ,-----.
  | ======= |         Printserver            Fileserver            |     |
 +-----------+     ,----------------.     ,----------------.       |_____|
 |  Printer [ ]----| |          === |-----| |          === |------_________
 +-----------+     `----------======'     `----------======'     / ::::::: \
                                                Spool            `---------'</literallayout>
	      </textobject>

	      <textobject>
		<phrase>Possible locations for the print spool</phrase>
	      </textobject>
	    </mediaobject>
	  </figure>
	  
	  <para>FreeBSD is an excellent platform to implement centralized
	    printserving and print spooling.  The rest of this chapter
	    concentrates on the centralized print spooler model.  Note that
	    PostScript printing is not a requirement for this model--the HPPCL
	    protocol can be the standard print protocol as well.  For
	    transparent printing between printers with HPPCL, however, the
	    printer models must be similar.</para>
	</sect3>

	<sect3>
	  <title>Physical location of the print spool</title>

	  <para>In some companies, the central fileserver is often placed in a
	    closet, locked away.  Printers, on the other hand, are best
	    located in high traffic areas for ease of use.  Network printing
	    works best when the printers are evenly distributed throughout the
	    organization.  Attempting to place all the major printers in one
	    location, as technically advantageous as it may seem, merely
	    provokes users to requisition smaller printers that are more
	    convenient for that quick print job.  The administrator may end up
	    with a datacenter full of nice, expensive printers that are never
	    used, while the smaller personal laser printers scattered
	    throughout the plant bear most of the printing load.</para>

	  <para>The big problem with this is that scattering printers through
	    the organization makes it difficult to utilize the 3 possible
	    parallel ports on the fileserver due to parallel port distance
	    limitations.  Although high-speed serial ports may extend the
	    distance, not many printers have good serial ports on them. This
	    is where the hardware network print server devices can come into
	    play.  I prefer using these devices because they are much cheaper
	    and more reliable than a standalone PC running printserver
	    software.  For example, Castelle
	    <ulink url="http://www.castelle.com/">http://www.castelle.com/</ulink>
	    sells the LANpress 1P/10BT printserver for about $170.00.  Using
	    these devices a FreeBSD UNIX server can have dozens of print spools
	    accepting print jobs and then route them back out over the network
	    to these remote printserver boxes.  If these hardware servers are
	    used, they must support the Line Printer Daemon (LPD) print
	    protocol.</para>

	  <para>With a scheme like this it is important to have enough disk
	    space on the spool to handle the print jobs.  A single large
	    PowerPoint presentation PostScript print job containing many
	    graphics may be over 100MB.  When many such jobs stack up in the
	    print spool waiting to print, the print spooler should have
	    several gigabytes of free disk space available.</para>
	</sect3>

	<sect3>
	  <title>Network Printing to Remote Spools</title>

	  <para>Although several proprietary network printing protocols such
	    as Banyan Vines and NetWare, are tied to proprietary protocols,
	    FreeBSD Unix can use two TCP/IP network printing protocols to
	    print to remote print spools.  The two print protocols available
	    on TCP/IP with FreeBSD are the open LPD protocol and the
	    NetBIOS-over-TCP/IP Server Messaging Block (SMB) print protocol
	    first defined by Intel and Microsoft and later used by IBM and
	    Microsoft.</para>

	  <para>The LPD protocol is defined in RFC1179 This network protocol
	    is the standard print protocol used on all UNIX systems.  LPD
	    client implementations exist for all Windows operating systems and
	    DOS.  Microsoft has written LPD for the Windows NT versions, the
	    other Windows operating system implementations are provided by
	    third parties.</para>

	  <para>The Microsoft Networking network protocol that runs on top of
	    SMB can use NetBIOS over TCP/IP as defined in RFC1001 and RFC1002.
	    This protocol has a specification for printing that is the same
	    print protocol used to send print jobs to NT Server by Microsoft
	    clients.  To implement this protocol on FreeBSD requires the
	    installation of the Samba client suite of programs discussed in
	    Chapter 7.</para>
	</sect3>
      </sect2>
    </sect1>

    <sect1>
      <title>Setting up LPR on Windows clients</title>

      <para>The program clients use to print via LPD is the Line Printer
	Remote, or LPR program.  The following instructions cover enabling
	this program on Windows clients.</para>

      <sect2>
	<title>Windows 3.1/Windows for Workgroups 3.11</title>

	<para>Several commercial TCP/IP stacks are available for Win31, that
	  provide LPR client programs, in addition to the basic TCP/IP
	  protocol to Win31.  WfW has TCP/IP networking available for free
	  from Microsoft, but it doesn't include an LPR client. Unfortunately,
	  I have not come across a freeware implementation of a 16-bit Windows
	  LPR client, so with the following instructions I use the Shareware
	  program WLPRSPL available from <ulink
						url="http://www.winsite.com/info/pc/win3/winsock/wlprs41.zip">http://www.winsite.com/info/pc/win3/winsock/wlprs41.zip</ulink>.
	  This program must be active during client printing, and is usually
	  placed in the Startup group.</para>
	
	<para>Organizations that want to use UNIX as a printserver to a group
	  of Win31 clients without using a commercial or shareware LPR program
	  have another option.  The Microsoft Networking client for DOS used
	  underneath Win31 contains SMB-based printing which is covered later
	  in the chapter.  DOS networking client setup and use are covered in
	  Chapter 2 and Chapter 7.</para>

	<para>If LPR-based client printing is desired and the organization
	  doesn't want to upgrade to Win95, (which has several LPR clients
	  available) the following instructions can be used. WLPRSPL needs a
	  Winsock under Windows 3.1, so for the example I explain the setup of
	  the Novell 16-bit TCP/IP client.  The stack can be FTPed from
	  Novell, and is easy to integrate into sites that already use the
	  16-bit NetWare networking client, usually NW 3.11 and 3.12.  In most
	  cases, however, sites that use NetWare + Win31 are probably best off
	  printing through the NetWare server, then loading an LPR spooler as
	  an Netware Loadable Module (NLM) to send the job over to
	  FreeBSD.</para>

	<para>As an alternate, the Microsoft Networking DOS 16-bit TCP/IP
	  client under Win31 contains a Winsock, as does Microsoft TCP/IP for
	  WfW.  The target machine used here is a Compaq Deskpro 386/33 with
	  12MB of ram with an operating version of Windows 3.1, and a 3com
	  3C579 EISA network card.  The instructions assume an LPR printserver
	  on the network, named <hostid>mainprinter.my.domain.com</hostid>
	  with a print queue named RAW.</para>

	<para>Use the installation instructions in Exhibit 8.1 for a quick and
	  dirty TCP/IP Winsock for Win31 systems. Administrators who already
	  have the Novell IPX client installed should skip those steps.</para>
      </sect2>

      <sect2>
	<title>Installation of the Novell TCP/IP Winsock client</title>

	<procedure>
	  <step>
	    <para>Make sure that the machine has enough environment space
	      (2048 bytes or more) by adding the following line to the
	      <filename>config.sys</filename> file and rebooting:</para>

	    <programlisting>SHELL=C:\COMMAND.COM /E:2048 /P</programlisting>
	  </step>

	  <step>
	    <para>Obtain the <filename>TCP16.EXE</filename> file from
	      <ulink url="ftp://ftp3.novell.com/pub/updates/eol/nweol/tcp16.exe">ftp://ftp3.novell.com/pub/updates/eol/nweol/tcp16.exe</ulink>.</para>
	  </step>

	  <step>
	    <para>Obtain the Network Adapter support diskette for the network
	      card in your machine.  This should be supplied with the card, or
	      available via FTP from the network adapter manufacturer's FTP
	      site.</para>
	  </step>

	  <step>
	    <para>Now you need the file <filename>LSL.COM</filename>.  This is
	      available on some Network Adapter Driver diskettes, it used to
	      be available from the <filename>VLM121_2.EXE</filename> file
	      from Novell but unfortunately this file is no longer publicly
	      accessible from Novell.</para>
	  </step>

	  <step>
	    <para>If you have <filename>vlm121_2.exe</filename> in a temporary
	      directory, run it.  This will extract a number of files.</para>
	  </step>
	  
	  <step>
	    <para>One of the files extracted is <filename>LSL.CO_</filename>
	      extract this file with the command <command>nwunpack
		lsl.co_</command>.</para>
	  </step>

	  <step>
	    <para>Create the directory <filename>c:\nwclient</filename>. Then,
	      copy <filename>lsl.com</filename> from the temporary directory
	      into the directory.</para>
	  </step>

	  <step>
	    <para>Obtain and install the printer driver for the model of
	      printer that you will be spooling to and point it to
	      <devicename>LPT1:</devicename>.  Win31 and WfW 3.11 have an
	      incomplete printer driver list, so if you need a driver
	      Microsoft has many Win16 printer drivers on their FTP site.  A
	      list is available at
	      <ulink
		     url="ftp://ftp.microsoft.com/Softlib/index.txt">ftp://ftp.microsoft.com/Softlib/index.txt</ulink>.
	      In addition, if you are installing a PostScript printer driver
	      for a printer supplied in Win31, it may be necessary to patch
	      the driver.  The Microsoft PostScript driver supplied in Win31
	      is version 3.5.  (The patch named
	      <filename>PSCRIP.EXE</filename> which brought the PostScript
	      driver to version 3.58 is no longer publicly available.) WfW
	      already uses the more recent PostScript driver, as does Win31
	      version A.  Installing the Adobe Postscript driver for Win31 is
	      also an option.  (see
	      <ulink url="http://www.adobe.com/support/downloads/pdrvwin.htm">http://www.adobe.com/support/downloads/pdrvwin.htm</ulink>
	      for the version 3.1.2 Win31 PostScript driver).</para>
	  </step>

	  <step>
	    <para>Look on the network adapter driver disk for the subdirectory
	      <filename>nwclient/</filename> and then look for the ODI driver
	      with the adapter card.  For example, on the 3com 3C509/3C579
	      adapter driver disk, the driver and location are
	      <filename>\NWCLIENT\3C5X9.COM</filename>.  Copy this driver to
	      the <filename>c:\nwclient</filename> directory.</para>
	  </step>

	  <step>
	    <para>Create a file called <filename>NET.CFG</filename> in the
	      <filename>c:\nwclient</filename> directory.  Often, the network
	      card adapter driver diskette has a template for this file in the
	      same location as the ODI driver.  This can be modified, as can
	      the following example:</para>

	    <programlisting>LINK SUPPORT

BUFFERS 4 1600

MEMPOOL 8192

LINK DRIVER
3C5X9

; PORT 300 (these are optional, if needed by card uncomment)

; INT 10 (optional, uncomment and modify if needed)</programlisting>
	  </step>

	  <step>
	    <para>Attempt to load the network card driver. First load
	      <filename>lsl</filename>, then the ODI driver.  With the 3com
	      card the commands are:</para>

	    <screen><userinput>lsl</userinput>
<userinput>3c5x9</userinput></screen>

	    <para>If the driver properly loads it will list the hardware port
	      and interrupt settings for the network adapter.  If it has
	      loaded properly, unload the drivers in reverse order with the
	      <option>/u</option> command:</para>

	    <screen><userinput>3c5x9 /u</userinput>
<userinput>lsl /u</userinput></screen>
	  </step>

	  <step>
	    <para>Go to the temporary directory that contains the
	      <filename>tcp16.exe</filename> file and extract it by running
	      the program.</para>
	  </step>

	  <step>
	    <para>Run the install batch file by typing
	      <command>installr</command>.  It should list <literal>New
		Installation detected</literal>.  It will then copy a number
	      of files into <filename>nwclient</filename>, add some
	      commented-out sections to <filename>net.cfg</filename>, and call
	      <command>edit</command> on <filename>net.cfg</filename>.</para>
	  </step>

	  <step>
	    <para>Read the editing instructions and make the appropriate
	      entries.  The sample <filename>net.cfg</filename> file from
	      above would look like this.</para>

	    <programlisting>LINK SUPPORT

BUFFERS 4 1600

MEMPOOL 8192

LINK DRIVER 3C5X9

FRAME ETHERNET_II

Protocol TCPIP

PATH TCP_CFG c:\nwclient

ip_address 192.168.1.54 LAN_NET

ip_netmask 255.255.255.0 LAN_NET

ip_router 192.168.1.1 LAN_NET

Bind 3C5X9 #1 Ethernet_II LAN_NET</programlisting>

	    <para>Save and exit, the Installer should list <literal>TCP16
		installation completed</literal>.</para>
	  </step>

	  <step>
	    <para>Reload the client with the commands:</para>

	    <screen><userinput>lsl</userinput>
<userinput>3c5x9</userinput>
<userinput>tcpip</userinput></screen>

	    <para>The TCPIP driver should list the IP numbers and other
	      information.</para>
	  </step>

	  <step>
	    <para>Optionally, create either a <filename>HOSTS</filename> file,
	      or a <filename>RESOLV.CFG</filename> file (pointing to a
	      nameserver) in <filename>c:\nwclient</filename>.  Check to see
	      this is operating properly by pinging a hostname.</para>

	    <para>Add the <filename>c:\nwclient</filename> directory to the
	      <envar>PATH</envar>, as well as the 3 startup commands in step
	      15 in <filename>autoexec.bat</filename></para>
	  </step>
	</procedure>
      </sect2>

      <sect2>
	<title>Installation of the LPR client on 16-bit Windows with a Winsock
	  installed</title>

	<para>The following assumes a running Win31 installation with a
	  Winsock or a running WfW installation with the 32-bit Microsoft
	  TCP/IP protocol installed.</para>

	<procedure>
	  <step>
	    <para>Install the printer driver desired.  See step 8 of the
	      previous set of instructions.</para>
	  </step>

	  <step>
	    <para>Obtain and extract into a temporary directory the
	      <filename>wlprs41.zip</filename> file from the location
	      mentioned above.</para>
	  </step>

	  <step>
	    <para>Run <command>setup.exe</command> from the temporary
	      directory containing the <filename>wlprs</filename> files
	      are.</para>
	  </step>

	  <step>
	    <para>In setup, accept default directory, and check Yes to add to
	      its own group.  Click <guibutton>Continue</guibutton> when asked
	      for group name, and check whatever choice you want when asked to
	      copy the <filename>doc</filename> files.</para>
	  </step>

	  <step>
	    <para>Click <guibutton>No</guibutton> when asked to add the
	      program to <literal>Startup</literal>.</para>
	  </step>

	  <step>
	    <para>On the Unix FreeBSD print spooler, make sure that there is
	      an entry in <filename>/etc/hosts.lpd</filename> or
	      <filename>/etc/hosts.equiv</filename> for the client
	      workstation, thereby allowing it to submit jobs.</para>
	  </step>

	  <step>
	    <para>Double-click the Windows LPR Spooler icon in the Windows LPR
	      Spooler group that is opened.  When it asks for a valid spool
	      directory, just select the <filename>c:\wlprspl</filename>
	      directory that the program installed its files into.</para>
	  </step>

	  <step>
	    <para>When asked for a valid Queue Definition File, just click
	      <guibutton>OK</guibutton> to use the default filename.  The
	      program automatically creates a queue definition file.</para>
	  </step>

	  <step>
	    <para>The program opens up with it's menu.  Click
	      <guibutton>Setup</guibutton> in the top menu, then select
	      <guimenuitem>Define New Queue</guimenuitem>.</para>
	  </step>

	  <step>
	    <para>For a local spool filename, just use the name of the remote
	      queue (RAW) to which the client prints.</para>
	  </step>

	  <step>
	    <para>For the remote printer name, use the same name as the remote
	      queue (RAW) to which the client prints.</para>
	  </step>

	  <step>
	    <para>For the remote hostname, use the machine name
	      of the FreeBSD print spooler.
	      <hostid role="fqdn"><replaceable>mainprinter.ayedomain.com</replaceable></hostid>.</para>
	  </step>

	  <step>
	    <para>For the Description, enter a description such as
	      <literal>3rd floor Marketing printer</literal>.</para>
	  </step>

	  <step>
	    <para>For the protocol, leave the default of BSD LPR/LPD
	      selected.</para>
	  </step>
	  
	  <step>
	    <para>Click on the <guimenuitem>Queue Properties</guimenuitem>,
	      and make sure that the <guilabel>Print unfiltered</guilabel> is
	      selected.  If you're printing PostScript, then also click the
	      <guibutton>Advanced options</guibutton> button.  Make sure that
	      <guilabel>Remove trailing Ctrl-D</guilabel> is
	      <emphasis>unchecked</emphasis>, and that <guilabel>Remove
		Leading Ctrl-D</guilabel> is <emphasis>checked</emphasis>.
	      Also with PostScript, if the printer cannot print ASCII, uncheck
	      the <guilabel>Send header page</guilabel> box. (PostScript
	      header/banner pages are discussed later in this chapter)</para>
	  </step>

	  <step>
	    <para>Click <guibutton>OK</guibutton>.  At the main menu of the
	      program, click <guimenu>File</guimenu>, then <guimenu>Control
		Panel/Printers</guimenu> to bring up the Printers control
	      panel of Windows.</para>
	  </step>
	    
	  <step>
	    <para>Make sure that the <guilabel>Use Print Manager</guilabel>
	      button is checked, then highlight the printer driver and click
	      the <guibutton>Connect</guibutton> button.</para>
	  </step>

	  <step>
	    <para>Scroll down to the <guilabel>C:\WLPRSPL\RAW</guilabel> entry
	      for the spool that was built and highlight this.  Click
	      <guibutton>OK</guibutton>.</para>
	  </step>
	  
	  <step>
	    <para>Minimize the Windows LPR Spooler.  Copy the Windows LPR
	      Spooler icon to the Startup group.  Click
	      <guimenu>File/Properties</guimenu> with the Windows LPR Spooler
	      icon highlighted in the Startup group. Check the <guilabel>Run
		Minimized</guilabel> button.</para>
	  </step>

	  <step>
	    <para>Exit Windows, and when the <guibutton>Save queue
		changes?</guibutton> button comes up, click
	      <guibutton>Yes</guibutton>.</para>
	  </step>

	  <step>
	    <para>Restart windows and make sure that the spooler starts
	      up.</para>
	  </step>

	  <step>
	    <para>Open the Control Panel and look for a new yellow icon named
	      <guiicon>Set Username</guiicon> If you are running the Novell or
	      other Winsock under Win31, click on this icon and put the
	      username of the person using this computer into the space
	      provided.  If you are running WfW, this isn't necessary because
	      Windows will supply the username.</para>
	  </step>

	  <step>
	    <para>If the spooler is not started properly in some
	      installations, there may be a bug.  If placing the icon in the
	      StartUp group doesen't actually start the spooler, the program
	      name can be placed in the <literal>run=</literal> line of
	      <filename>win.ini</filename>.</para>
	  </step>

	  <step>
	    <para>Try printing a print job from an application such as
	      Notepad.  If everything goes properly, clicking on the
	      <guimenuitem>Queues/Show remote printer status</guimenuitem>" in
	      the Windows LPR menu should show the print job spooled and
	      printing on the remote printserver.</para>
	  </step>
	</procedure>
      </sect2>

      <sect2>
	<title>Installation of LPR client on Windows 95/98</title>

	<para>The <command>wlprspl</command> program also can be used under
	  Windows 95, but as a 16-bit program, it is far from an optimal
	  implementation on a 32-bit operating system.  In addition, Win95 and
	  it's derivatives fundamentally changed from Windows 3.1 in the
	  printing subystem.  For these reasons I use a different LPR client
	  program for Win95/98 LPR printing instructions.  It is a full 32-bit
	  print program, and it installs as a <emphasis>Windows 32-bit
	    printer</emphasis> <emphasis>port monitor</emphasis>.  The program
	  is called ACITS LPR Remote Printing for Windows 95 and it is located
	  at <ulink
		    url="http://shadowland.cc.utexas.edu/acitslpr.htm">http://shadowland.cc.utexas.edu/acitslpr.htm</ulink>.</para>
	
	<para>ACITS stands for Academic Computing and Instructional
	  Technologies Services.  The ACITS LPR client includes software
	  developed by the University of Texas at Austin and its contributors,
	  it was written by Glenn K.  Smith, a systems analyst with the
	  Networking Services group at the university.  The filename of the
	  archive in the original program was ACITSLPR95.EXE and as of version
	  1.4 it was free for individuals or organizations to use for their
	  internal printing needs.  Since that time, it has gotten so popular
	  that the university has taken over the program, incremented the
	  version number (to get out from under the free license) and is now
	  charging a $35 per copy fee for commercial use for the newer
	  versions.  The older free version can still be found on overseas FTP
	  servers, such as <ulink
				  url="http://www.go.dlr.de/fresh/pc/src/winsock/acitslpr95.exe">http://www.go.dlr.de/fresh/pc/src/winsock/acitslpr95.exe</ulink>.</para>

	<para>It is likely that the cost of a shareware/commercial LPR program
	  for Win95 plus the cost of Win95 itself will meet or exceed that of
	  Win2K.  As such, users wishing to print via LPR to FreeBSD UNIX
	  systems will probably find it cheaper to simply upgrade to Windows
	  NT Workstation or Win2K.</para>

	<para>ACITS LPR and Win95 have a few printing idosyncracies.  Most
	  Win95 programs, such as Microsoft Word, expect print output to be
	  spooled on the local hard drive and then metered out to a printer
	  that is plugged into the parallel port.  Network printing, on the
	  other hand, assumes that print output will go directly from the
	  application to the remote print server.  Under Win95, local ports
	  have a setting under Properties, Details, Spool Settings labeled
	  "Print directly to the printer".  If this is checked, the
	  application running on the desktop (such as Microsoft Word) will not
	  create a little Printer icon with pages coming out of it or use
	  other means of showing the progress of the job as it is built.  This
	  can be very disconcerting to the user of a network printer, so this
	  option should be checked only with printers plugged directly into
	  the parallel port.  Worse, if this is checked with ACITS, it can
	  cause the job to abort if the remote print spooler momentarily goes
	  offline.</para>

	<para>Another local setting also should be changed. Generally, with
	  local ports, Win95 builds the first page in the spooler and then
	  starts printing it while the rest of the pages spool.  If ACITS
	  starts printing the first page while the rest of the pages are
	  building, timeouts at the network layer can sometimes cause very
	  large jobs to abort.  The entire job should be set to completely
	  spool before the LPR client passes it to the Unix spooler.  The
	  problem is partly the result of program design: because ACITS is
	  implemented as a local printer port instead of being embedded into
	  Win95 networking (and available in Network Neighborhood) the program
	  acts like a local printer port in some ways.</para>

	<para>The LPR program can be set to deselect banner/burst page
	  printing if a PostScript printer that cannot support ASCII is used.
	  The burst pages referred to here are NOT generated by the Windows
	  machine.  Use the instructions in Exhibit 8.3 to install</para>

	<procedure>
	  <title>LPR client on Win95/98 installation instructions</title>

	  <step>
	    <para>Obtain the <filename>ACITSLPR95.EXE</filename> file and
	      place it in a temporary directory such as
	      <filename>c:\temp1</filename>.</para>
	  </step>

	  <step>
	    <para>Close all running programs on the desktop.  The computer
	      <emphasis>must</emphasis> be rebooted at completion of
	      installation or the program will not work.</para>
	  </step>

	  <step>
	    <para>Click <guibutton>Start</guibutton>,
	      <guimenuitem>Run</guimenuitem> and type in
	      <userinput>c:\temp1\acitslpr95</userinput> then click
	      <guibutton>Yes</guibutton> at the InstallShield prompt.</para>
	  </step>

	  <step>
	    <para>Click <guibutton>Next</guibutton>, then
	      <guibutton>Yes</guibutton>.  The program will run through some
	      installation and then presents a Help screen that explains how
	      to configure an LPR port.</para>
	  </step>
	  
	  <step>
	    <para>After the help screen closes, the program asks to reboot the
	      system.  Ensure that <guilabel>Yes</guilabel> is checked and
	      click <guibutton>Finish</guibutton> to reboot.</para>
	  </step>

	  <step>
	    <para>After the machine comes back up, install a Printer icon in
	      the <guibutton>Start</guibutton>, <guimenu>Settings</guimenu>,
	      <guimenuitem>Printers</guimenuitem> folder if one hasn't been
	      created for the correct model of destination printer.</para>
	  </step>

	  <step>
	    <para>With the Printers folder open, right-click over the printer
	      icon that needs to use the LPR program and click on the
	      <guilabel>Properties</guilabel> tab.</para>
	  </step>

	  <step>
	    <para>Under the <guilabel>Details</guilabel> tab, click the
	      <guilabel>Add Port</guilabel> tab, then click
	      <guibutton>Other</guibutton>.</para>
	  </step>

	  <step>
	    <para>Highlight the <guilabel>ACITS LPR Remote Printing</guilabel>
	      line and click <guibutton>OK</guibutton>.</para>
	  </step>

	  <step>
	    <para>The Add ACITS LPR screen opens.  Type in the hostname of the
	      UNIX system that the client spools through&mdash;
	      <hostid role="fqdn"><replaceable>mainprinter.ayedomain.com</replaceable></hostid>.</para>
	  </step>
	  
	  <step>
	    <para>Type in the Printer/Queue name and click
	      <guibutton>OK</guibutton>. (Some versions have a "Verify Printer
	      Information" button.) The LPR program then contacts the UNIX
	      host and makes sure that the selected printer is
	      available.</para>

	    <note>
	      <para>If this fails the client machine name is probably not in
		the <filename>/etc/hosts.equiv</filename> or
		<filename>etc/hosts.lpd</filename> on the FreeBSD printserver.
		Most sites may simply decide to put a wildcard in
		<filename>hosts.equiv</filename> to allow printing, especially
		if DHCP is used, but many security-conscious sites may stick
		with individual entries in
		<filename>hosts.lpd</filename>.</para>
	    </note>
	  </step>
	  
	  <step>
	    <para>If the printer is PostScript and cannot print ASCII, make
	      sure that the "No banner page control flag" is checked to turn
	      off banner pages.  Accessible under Port settings, this flag is
	      overridden if the <filename>/etc/printcap</filename>file
	      specifies no banner pages.</para>
	  </step>

	  <step>
	    <para>Review how the "send plain text control flag" is set.  With
	      this flag unchecked, the LPR code sent is L, (ie:, print
	      unfiltered) meaning that the <literal>if</literal> filter gets
	      called with the <option>-c</option> option.  This is equivalent
	      to the local invocation of <filename>/usr/bin/lpr -l</filename>.
	      With the flag checked, the code is F, (formatted) meaning that
	      the <literal>if</literal>filter gets called without the
	      <option>-c</option> option.  This is equivalent to the default
	      invocation <filename>/usr/bin/lpr</filename>.  (This is also an
	      issue under Windows NT, which retypes the print job to text if
	      this flag is checked.  Some filters understand the
	      <option>-c</option> flag, which is used to preserve control
	      characters, so it should generally remain unchecked.</para>
	  </step>

	  <step>
	    <para>Leave the "Send data file before control file" box
	      unchecked.  This option is used only in rare mainframe spooling
	      circumstances.</para>
	  </step>
	  
	  <step>
	    <para>Click <guibutton>OK</guibutton>, then click the
	      <guibutton>Spool Settings</guibutton> button at the properties
	      page.</para>
	  </step>

	  <step>
	    <para>Make sure that the "Spool print jobs so program finishes
	      printing faster" box is checked.</para>
	  </step>

	  <step>
	    <para>Make sure that "Start printing after last page is spooled"
	      box is checked.</para>
	  </step>

	  <step>
	    <para>Make sure that "Disable bi-directional support for this
	      printer" is checked, or greyed out.</para>
	  </step>

	  <step>
	    <para>Make sure that the "Spool data format" is set to RAW.  Some
	      printer drivers present a choice of EMF or RAW, such as the
	      Generic Text driver, in this case select RAW.</para>
	  </step>

	  <step>
	    <para>Click <guibutton>OK</guibutton>, then
	      <guibutton>OK</guibutton> again to close the Printer Properties.
	      The printer icon now spools through FreeBSD.</para>
	  </step>
	</procedure>
      </sect2>

      <sect2>
	<title>Installation of LPR client on Windows NT</title>

	<para>Unlike WfW and Win95 TCP/IP, Windows NT&mdash;both server and
	  workstation&mdash;includes an LPR client as well as an LPD program
	  that allows incoming print jobs to be printed from LPR clients, such
	  as UNIX systems.</para>

	<para>To install the LPR client and daemon program under Windows NT
	  3.51, use the following instructions.  The TCP/IP protocol should be
	  installed beforehand and you must be logged in to the NT system as
	  Administrator.  This can be done at any time after the NT system is
	  installed, or during OS installation:</para>

	<procedure>
	  <step>
	    <para>Double-click on Main, Control Panel, then
	      Network Settings.</para>
	  </step>

	  <step>
	    <para>In the Installed Network Software window, "Microsoft TCP/IP
	      Printing" should be listed as well as "TCP/IP Protocol".</para>
	  </step>
	  
	  <step>
	    <para>Click the <guibutton>Add Software</guibutton> button to get
	      the Add Network Software dialog box</para>
	  </step>

	  <step>
	    <para>Click the down arrow and select TCP/IP Protocol and related
	      components.  Click <guibutton>Continue</guibutton>.</para>
	  </step>
	  
	  <step>
	    <para>Check the "TCP/IP Network Printing Support" box and click
	      <guibutton>Continue</guibutton>.  LPR printing is now installed.
	      Follow the instructions to reboot to save changes.</para>
	  </step>
	</procedure>
	
	<para>To install the LPR client and daemon program under Windows NT 4,
	  use the following instructions.  The TCP/IP protocol should be
	  installed beforehand and you must be logged in to the NT system as
	  Administrator.  This can be done at any time after the NT system is
	  installed, or during OS installation:</para>

	<procedure>
	  <step>
	    <para>Click on <guibutton>Start</guibutton>,
	      <guimenuitem>Settings</guimenuitem>, <guimenuitem>Control
		Panel</guimenuitem>, and double-click on
	      <guiicon>Network</guiicon> to open it up.</para>
	  </step>
	  
	  <step>
	    <para>Click on the <guilabel>Services</guilabel> tab.
	      <literal>Microsoft TCP/IP Printing</literal> should be listed.
	      If not, continue steps 3 - 4.</para>
	  </step>

	  <step>
	    <para>Click <guibutton>Add</guibutton>, then select
	      <guilabel>Microsoft TCP/IP Printing</guilabel> and click
	      <guibutton>OK</guibutton>.</para>
	  </step>

	  <step>
	    <para>Click <guibutton>Close</guibutton>.  Follow instructions to
	      reboot to save changes.</para>

	    <note>
	      <para>Any NT Service Packs that were previously installed must
		be reapplied after these operations.</para>
	    </note>
	  </step>
	</procedure>
	
	<para>Once LPR printing has been installed, the Printer icon or icons
	  must be created on the NT system so that applications can print.
	  Since this printer driver does all job formatting before passing the
	  printing to the FreeBSD printserver, the print queues specified
	  should be raw queues on the FreeBSD system, which don't do any job
	  formatting.</para>

	<para>To install the printer icon in Print Manager and set it to send
	  print jobs to the FreeBSD UNIX system, use the following
	  instructions under NT 3.51.  You must be logged in to the NT system
	  as Administrator.  This can be done at any time after the NT system
	  is installed, or during OS installation.</para>

	<procedure>
	  <step>
	    <para>Click on Main, and open it.  Then click on Print Manager to
	      open it.</para>
	  </step>

	  <step>
	    <para>Click on <guiicon>Printer</guiicon>, <guibutton>Create
		Printer</guibutton>.  Select the appropriate printer
	      driver.</para>
	  </step>

	  <step>
	    <para>Click the down arrow under Print To and select
	      Other.</para>
	  </step>

	  <step>
	    <para>In the Available Print Monitors window select
	      LPR port and click <guibutton>OK</guibutton>.</para>
	  </step>

	  <step>
	    <para>Enter the hostname of the FreeBSD printserver, and the name
	      of the printer queue and click <guibutton>OK</guibutton></para>
	  </step>

	  <step>
	    <para>Click <guibutton>OK</guibutton> to close the Create Printer
	      window. The Printer icon is created.</para>
	  </step>
	</procedure>

	<para>To install the printer icon in Print Manager and set it to send
	  print jobs to the FreeBSD UNIX system, use the following
	  instructions under NT 4.  You must be logged in to the NT system as
	  Administrator.  This can be done at any time after the NT system is
	  installed, or during OS installation:</para>

	<procedure>
	  <step>
	    <para>Click <guibutton>Start</guibutton>,
	      <guimenuitem>Settings</guimenuitem>,
	      <guimenuitem>Printers</guimenuitem> to open the printer
	      folder.</para>
	  </step>

	  <step>
	    <para>Double-click <guiicon>Add Printer</guiicon> to start the
	      wizard.</para>
	  </step>
	  
	  <step>
	    <para>3) Select the My Computer radio button, not the Network
	      Print Server button and click <guibutton>Next</guibutton>.  (The
	      printer <emphasis>is</emphasis> a networked printer, it is
	      managed on the local NT system. Microsoft used confusing
	      terminology here.</para>
	  </step>
	  
	  <step>
	    <para>Click <guibutton>Add Port</guibutton> and select LPR Port,
	      then click <guibutton>New Port</guibutton>.</para>
	  </step>

	  <step>
	    <para>Enter the hostname and print queue for the FreeBSD
	      printserver and click <guibutton>OK</guibutton>.</para>
	  </step>
	  
	  <step>
	    <para>Click <guibutton>Next</guibutton> and select the correct
	      printer driver.  Continue until the printer is set up.</para>
	  </step>
	</procedure>

	<para>The LPR client in Windows NT allows DOS print jobs originating
	  in DOS boxes to be routed to the central UNIX print spooler.  This
	  is an advantage over the Win95 and WfW LPR programs.</para>

	<sect3>
	  <title>Windows NT Registry Changes</title>

	  <para>Using the LPR daemon program under Windows NT presents one
	    problem.  If the NT server is used as an LPR/LPD "relay", for
	    example, to pass jobs from clients to LPR print queues on a UNIX
	    system, to pass jobs from LPR programs on UNIX terminating at NT
	    print queues, or to pass jobs from Appletalk clients to LPR
	    printers, NT retypes the job if the type code is set to P (text).
	    This can wreak havoc on PostScript files printed through HP
	    LaserJet printers with internal MIO cards in them, if the job
	    originates from the <filename>/usr/bin/lpr</filename> program
	    under UNIX, which assigns a P type code.  The printserver card
	    treats PostScript jobs as text, and instead of the print job, the
	    raw PostScript codes print.  This problem often manifests in the
	    following way: <filename>/usr/bin/lpr</filename> is used to print
	    a PostScript file from UNIX directly to the remote printer
	    printserver, which works fine, but spooling it through NT causes
	    problems.</para>

	  <para>A registry change that can override the NT Server formatting
	    behavior is detailed in Microsoft Knowledge Base article ID
	    Q150930.  With Windows NT 3.51, and 4.0 up to service pack 1 the
	    change is global.  Starting with NT 4.0 Service pack 2 the change
	    can be applied to specific print queues, (see Knowledge Base
	    article ID Q168457).</para>

	  <para>Under Windows NT 4.0, the change is:</para>

	  <procedure>
	    <step>
	      <para>Run Registry Editor
		(<filename>REGEDT32.EXE</filename>)</para>
	    </step>
	    
	    <step>
	      <para>From the <literal>HKEY_LOCAL_MACHINE</literal> subtree, go
		to the following key:</para>

	      <para><literal>\SYSTEM\CurrentControlSet\Services\LPDSVC\Parameters</literal></para>
	    </step>

	    <step>
	      <para>On the <guimenu>Edit</guimenu> menu, click
		<guimenuitem>Add Value</guimenuitem>.</para>
	    </step>

	    <step>
	      <para>Add the following:</para>

	      <informaltable frame="none">
		<tgroup cols="2">
		  <tbody>
		    <row>
		      <entry>Value Name:</entry>
		      <entry>SimulatePassThrough</entry>
		    </row>

		    <row>
		      <entry>Data Type:</entry>
		      <entry>REG_DWORD</entry>
		    </row>

		    <row>
		      <entry>Data</entry>
		      <entry>1</entry>
		    </row>
		  </tbody>
		</tgroup>
	      </informaltable>

	      <note>
		<para>The default value is 0, which informs LPD to assign
		  datatypes according to the control commands.</para>
	      </note>
	    </step>
	  </procedure>
	  
	  <para>Under Windows NT 3.51, the change is:</para>

	  <procedure>
	    <step>
	      <para>Run Registry Editor
		(<filename>REGEDT32.EXE</filename>)</para>
	    </step>

	    <step>
	      <para>From the <literal>HKEY_LOCAL_MACHINE</literal> subtree, go
		to the following key:</para>

	      <para><literal>\SYSTEM\CurrentControlSet\Services\LPDSVC\Parameters</literal></para>
	    </step>

	    <step>
	      <para>On the <guimenu>Edit</guimenu> menu, click
		<guimenuitem>Add Value</guimenuitem>.</para>
	    </step>

	    <step>
	      <para>Add the following:</para>

	      <informaltable frame="none">
		<tgroup cols="2">
		  <tbody>
		    <row>
		      <entry>Value Name:</entry>
		      <entry>SimulatePassThrough</entry>
		    </row>

		    <row>
		      <entry>Data Type:</entry>
		      <entry>REG_DWORD</entry>
		    </row>

		    <row>
		      <entry>Data</entry>
		      <entry>1</entry>
		    </row>
		  </tbody>
		</tgroup>
	      </informaltable>

	      <note>
		<para>The default value is 0, which informs LPD to assign
		  datatypes according to the control commands.</para>
	      </note>
	    </step>

	    <step>
	      <para>Create an LPD key at the same level as the LPDSVC
		key.</para>
	    </step>
	    
	    <step>
	      <para>Click the LPDSVC Key, click <guimenuitem>Save
		  Key</guimenuitem> from the <guimenu>Registry</guimenu> menu,
		and then save the file as
		<filename>LPDSVC.KEY</filename></para>
	    </step>

	    <step>
	      <para>Click the LPD key created in step 5.</para>
	    </step>

	    <step>
	      <para>Click <guimenuitem>Restore</guimenuitem> on the
		<guimenu>Registry</guimenu> menu, click the file created in
		step 6, and then click <guibutton>OK</guibutton>.</para>
	    </step>

	    <step>
	      <para>A warning message appears.  Click
		<guibutton>OK</guibutton> and then quit the Registry
		Editor.</para>
	    </step>

	    <step>
	      <para>At a command prompt window, type:</para>

	      <screen><userinput>net stop lpdsvc</userinput>
<userinput>net start lpdsvc</userinput></screen>
	    </step>
	  </procedure>
	</sect3>
      </sect2>
    </sect1>

    <sect1>
      <title>Printing Postscript and DOS command files</title>

      <para>One problem with printing under Win31 and Win95 with the LPR
	methods discussed is the lack of a <quote>raw</quote>
	<devicename>LPT1:</devicename> device. This is annoying to the
	administrator who wants to print an occasional text file, such as a
	file full of printer control codes, without their being intercepted by
	the Windows printer driver.  Of course this is also an issue with DOS
	programs, but a commercial site that runs significant DOS software and
	wants to print directly to UNIX with LPR really only has one
	option&mdash;to use a commercial TCP/IP stack containing a DOS LPR
	program.</para>

      <para>Normally, under Windows printing, virtually all graphical programs
	print through the Windows printer driver.  This is true even of basic
	programs such as Notepad.  For example, an administrator may have a
	DOS batch file named <filename>filename.txt</filename>containing the
	following line:</para>

      <programlisting>echo \033&amp;k2G &gt; lpt1:</programlisting>

      <para>This batch file switches a HP LasterJet from CR-LF, MS-DOS
	textfile printing into Newline termination UNIX textfile printing.
	Otherwise, raw text printed from UNIX on the HP prints with a
	stairstep effect.</para>

      <para>If the administrator opens this file with Notepad and prints it
	using a regular printer driver, such as an Epson LQ, the Windows
	printer driver encapsulates this print output into a series of
	printer-specific control codes that do things such as initialize the
	printer, install fonts, and so on.  The printer won't interpret this
	output as control code input.  Usually, if the printer is locally
	attached, the user can force a "raw text print" of the file by opening
	a DOS window and running:</para>

      <screen><userinput>copy filename.txt lpt1: /b</userinput></screen>

      <para>Since the LPR client program doesn't provide a DOS driver, it
	cannot reroute input from the <devicename>LPT1:</devicename> device
	ports. The solution is to use the Generic / Text Only printer driver
	in conjunction with Wordpad (under Win95); under Win31 use a different
	text editor.  The Notepad editor supplied with Windows is unsuitable
	for this - it "helpfully" inserts a 1 inch margin of spaces around all
	printed output, as well as the filename title.  Wordpad supplied with
	Win95, can be set to use margins of zero, and inserts no additions
	into the printed output. Also, make sure that banner pages are turned
	off, and the print type is set to raw.</para>
    </sect1>

    <sect1>
      <title>Checking PostScript Printer capabilities</title>

      <para>Following is a PostScript command file that can be used to get a
	PostScript printer to output a number of useful pieces of information
	that are needed to set up a printer icon under Windows properly.  It
	was printed from Wordpad, in Win95, through the Generic / Text Only
	printer driver with the following instructions:</para>

      <procedure>
	<step>
	  <para><guibutton>Start</guibutton>, <guimenuitem>Run</guimenuitem>,
	    type in <userinput>Wordpad</userinput> and press
	    <keycap>Enter</keycap>.</para>
	</step>

	<step>
	  <para><guimenu>File</guimenu>, <guimenuitem>Open</guimenuitem>
	    <filename>testps.txt</filename></para>
	</step>

	<step>
	  <para><guimenu>File</guimenu>, <guimenuitem>Page
	      Setup</guimenuitem>, <guimenuitem>Printer</guimenuitem>, select
	    <guimenuitem>Generic / Text Only</guimenuitem>, click
	    <guibutton>Properties</guibutton></para>
	</step>

	<step>
	  <para>Click <guimenuitem>Device Options</guimenuitem>, select
	    <guilabel>TTY custom</guilabel>, click
	    <guibutton>OK</guibutton>.</para>
	</step>

	<step>
	  <para>Click <guibutton>OK</guibutton>, then set all four margins to
	    <literal>0</literal>; click <guibutton>OK</guibutton>.</para>
	</step>

	<step>
	  <para>Click <guimenu>File</guimenu>,
	    <guimenuitem>Print</guimenuitem>,
	    <guibutton>OK</guibutton>.</para>
	</step>
      </procedure>
      
      <para>This could also have been printed with
	<filename>/usr/bin/lpr</filename> on a UNIX command prompt.  The file
	prints <emphasis>Test Page</emphasis> and some printer statistics
	below that, as follows.</para>

      <programlisting>% filename: testps.txt
% purpose: to verify proper host connection and function of PostScript
% printers.
/buf 10 string def
/CM {
save statusdict/product get (Postscript) anchorsearch
exch pop {length 0 eq
{1}{2}ifelse
}
{2}ifelse exch restore
}bind def
/isCM {
CM 1 ge
}bind def
/Times-BoldItalic findfont 75 scalefont setfont
150 500 moveto
(Test Page) false charpath
isCM{gsave 0.0 1.0 1.0 0.0 setcmykcolor fill grestore}if
2 setlinewidth stroke
/Times-Roman findfont 10 scalefont setfont
150 400 moveto
(Your PostScript printer is properly connected and operational.)show
150 380 moveto
(The border around the page indicates your printer's printable region.)show
{ vmreclaim } stopped pop
vmstatus exch sub exch pop
150 360 moveto
(Max Available Printer Virtual Memory (KB):)show
150 340 moveto
dup 1024 div truncate buf cvs show
150 320 moveto
(Calculated memory size used for PostScript printer icon properties:) show
150 300 moveto
0.85 mul 1024 div truncate buf cvs show
150 280 moveto
(Printer Model: )show
statusdict begin product show end
150 260 moveto
(PostScript Level: )show
/languagelevel where
{ languagelevel 3 string cvs show pop }
{(1) show } ifelse
150 240 moveto
(PostScript Version: )show
statusdict begin
version show (.)show
revision 40 string cvs show end
clippath stroke
showpage</programlisting>
    </sect1>

    <sect1>
      <title>Setting up LPR/LPD on FreeBSD</title>

      <para>When a FreeBSD system is booted, it starts the LPD spooler control
	daemon program if the <filename>/etc/rc.conf</filename> file has
	<literal>lpd_enable="YES"</literal> set.  If this is not set, attempts
	to print through and from the FreeBSD system will fail with an
	<errorname>lpr: connect: No such file or directory</errorname> error
	message.</para>

      <para>The LPD program manages all incoming print jobs, whether they come
	in from the network, or from local users on the UNIX system.  It
	transfers print jobs to all locally attached parallel or serial
	printers, as well as defined remote printers. Several programs also
	are used to manipulate jobs in the print spools that LPD manages, as
	well as the user programs to submit them from the UNIX command prompt.
	All of these programs use the <filename>/etc/printcap</filename>file,
	which is the master control file for the printing system.</para>

      <para>Back when printing was mostly text, it was common to place
	printers on a serial connection that stretched for long distances.
	Often, 9600bps was used because it could work reliably up to a block
	away, which allowed printers to be located almost anywhere on an
	office high-rise floor.  Modern office print jobs, on the other hand,
	are generally graphics-laden and tend to be rather large.  These jobs
	would take hours to transfer over a slower 9600bps serial printer
	connection.  Today, most printers that are not connected to a remote
	hardware print server box are directly connected to the server using
	parallel cables.  All of the examples shown here are direct
	connections that are parallel connections.</para>

      <para>The <filename>printcap</filename> configuration file, like most
	UNIX configuration files, indicates comment lines starting with a hash
	character.  Lines without a hash character are meant to be part of a
	printer queue description line.  Each printer queue description line
	starts with a symbolic name, and ends with a newline.  Since the
	description lines are often quite long, they are often written to span
	multiple lines by escaping intermediate newlines with the backslash
	(<literal>\</literal>) character.  The
	<filename>/etc/printcap</filename>file, as supplied, defines a single
	printer queue, <literal>lp</literal>.  The <literal>lp</literal>queue
	is the default queue.  Most UNIX-supplied printing utilities send
	print output to this queue if no printer is specified by the user.  It
	should be set to point to the most popular print queue with
	<emphasis>local</emphasis> UNIX print users, (i.e.: users that have
	shell accounts).</para>

      <para>The layout of <filename>/etc/printcap</filename>is covered in the
	manual page, which is reached by running the <userinput>man
	  printcap</userinput> command. The stock
	<filename>/etc/printcap</filename> file at the line defining the spool
	<literal>lp</literal>shows:</para>

      <programlisting>#
lp|local line printer:\
    :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:
#</programlisting>

      <para>In this example the first line defines the names by which the
	printer is known, and ends with an escaped newline. The next line
	defines the physical device, the PC parallel port, by
	<filename>/dev/lpt0</filename>, and the directory in which the spool
	files are stored at <filename>/var/spool/output/lpd</filename>, and
	the error log file.  Note that this particular error log file will not
	show all LPD errors, such as bad job submittals, it usually shows only
	the errors that originate within the printing system itself.</para>

      <para>In general, the administrator creates two print queues for every
	printer that is connected to the FreeBSD machine. The first queue
	entry contains whatever additional capabilities UNIX shell users on
	the server require.  The second is a raw queue that performs no print
	processing on the incoming print job.  This queue is used by remote
	clients, such as Windows clients, that format their own jobs.</para>

      <para>If the administrator is setting up the printer to allow incoming
	LPR jobs from network clients, such as other Windows or UNIX systems,
	those systems <emphasis>must</emphasis> be listed in
	<filename>/etc/hosts.lpd</filename>.</para>

      <sect2>
	<title>Creating the spools</title>

	<para>Building new print spools is merely a matter of making an entry
	  in the <filename>/etc/printcap</filename> file, creating the spool
	  directories, and setting the correct permissions on them. For
	  example, the following additional line defines a PostScript printer
	  named NEC (in addition to the <literal>lp</literal>
	  definition):</para>

	<programlisting>#
lp|local line printer:\
    :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:

NEC|NEC Silentwriter 95 Postscript printer:\
    :lp=/dev/lpt0:sd=/var/spool/output/NEC:lf=/var/log/lpd-errs:
#</programlisting>

	<para>Because UNIX is case sensitive, NEC is different from
	  <literal>nec</literal> in both the name of the printer and the name
	  of the Spool directory.  With the print spooler LPD, the Spool
	  directories <emphasis>must</emphasis> be different from each other,
	  or the spooler gets confused and doesen't print.</para>

	<para>After the <filename>/etc/printcap</filename>is modified, the
	  root user must create the <filename>/var/spool/output/NEC</filename>
	  directory and assign ownership of it to the <username>bin</username>
	  user, assign group ownership to <username>daemon</username>, and set
	  permissions with the following commands:</para>

	<screen>&prompt.user; <userinput>su root</userinput>
&prompt.root; <userinput>cd /var/spool/output</userinput>
&prompt.root; <userinput>mkdir NEC</userinput>
&prompt.root; <userinput>chown bin NEC</userinput>	  
&prompt.root; <userinput>chgrp daemon NEC</userinput>
&prompt.root; <userinput>chmod 755 NEC</userinput></screen>
      </sect2>

      <sect2>
	<title>Additional spool capabilities</title>

	<para>Because modern print jobs (especially PostScript) can sometimes
	  reach hundreds of megabytes, the <literal>sd</literal> capability
	  entry in the <filename>/etc/printcap</filename> file should always
	  point to a Spool directory on a filesystem that has enough space.
	  The <filename>/var</filename> directory on a default FreeBSD
	  installation is generally set to a fairly small amount, which can
	  easily overflow the spool.  There are four ways to handle this
	  problem:</para>

	<orderedlist>
	  <listitem>
	    <para>During FreeBSD installation, if the administrator knows a
	      lot of print jobs are going to go through the spooler,
	      <filename>/var</filename>should be set to a large
		amount of free space.</para>
	  </listitem>

	  <listitem>
	    <para>Modify the <literal>sd</literal> capability in the
	      <filename>/etc/printcap</filename> file to point to a spool
	      directory in a different, larger filesystem, such as
	      <filename>/usr/spool.</filename></para>
	  </listitem>

	  <listitem>
	    <para>Use soft links to point the
	      <filename>/var/spool/output</filename> directory to directories
	      on a larger filesystem.</para>
	  </listitem>

	  <listitem>
	    <para>Don't define a <filename>/var</filename> directory at all
	      during FreeBSD installation; this would make the installer link
	      <filename>/var</filename> to
	      <filename>/usr/var</filename>.</para>
	  </listitem>
	</orderedlist>
	
	<para>In addition to spools, the following other capabilities are
	  usually placed in a production
	  <filename>/etc/printcap</filename>file.</para>
	
	<para>The entry <literal>fo</literal> prints a form feed when the
	  printer is opened.  It is handy for HPPCL (HP LaserJets) or other
	  non-PostScript printers that are located behind electronic print
	  sharing devices.  It can also be used for printers that accept input
	  from multiple connections, such as a parallel port, serial port, and
	  localtalk port.  An example is an HP LaserJet with an MIO card in it
	  plugged into both Ethernet and LocalTalk networks.  It will clear
	  any garbage out of the printer before the job is processed.</para>

	<para>The entry <literal>mx</literal> defines the maximum size of a
	  print job, which is a must for modern print jobs that frequently
	  grow far past the default print size of a megabyte.  The original
	  intent of this capability was to prevent errant programs from
	  stuffing the spool with jobs so large that they would use up all
	  paper in a printer..  Graphics-heavy print jobs have made it
	  impossible to depend on this kind of space limitation, so
	  <literal>mx</literal> is usually set to zero, which turns it
	  off.</para>

	<para>The entry <literal>sh</literal> suppresses printing of banner
	  pages in case the printer cannot handle ASCII and the client
	  mistakenly requests them.</para>

	<para>The entry <literal>ct</literal> denotes a TCP Connection
	  timeout.  This is useful if the remote print server doesn't close
	  the connection properly.</para>

	<note>
	  <para>FreeBSD 2.2.5 contains a bug in the LPD system - as a
	    workaround the <literal>ct</literal> capability needs to be set
	    very large, such as 3600, or the appropriate patch installed and
	    LPD recompiled.  More recent versions of FreeBSD do not have this
	    bug.</para>
	</note>
      </sect2>

      <sect2>
	<title>Printing to hardware print server boxes or remote print
	  servers.</title>
	
	<para>Hardware print server boxes, such as the HP JetDirect internal
	  and external cards, need some additional capabilities defined in the
	  <filename>/etc/printcap</filename> entry; <literal>rp</literal>, for
	  remote print spool, and <literal>rm</literal>for remote machine
	  name.</para>

	<para>The <literal>rm</literal> capability is simply the DNS or
	  <filename>/etc/hosts</filename> name of the IP number associated
	  with the remote printserver device.  Obviously, print server
	  devices, such as the HP JetDirect, must not use a dynamic TCP/IP
	  network numbering assignment.  If they get their numbering via DHCP,
	  the IP number should be assigned from the static pool; it should
	  always be the same IP number.</para>

	<para>Determining the name used for <literal>rp</literal>, on the
	  other hand, can be rather difficult.  Here are some common
	  names:</para>

	<para>Windows NT Server: Printer name of the printer icon created in
	  Print Manager</para>

	<para>FreeBSD: Print queue name defined in
	  <filename>/etc/printcap</filename></para>

	<para>HP JetDirect: Either the name <literal>TEXT</literal> or the
	  name <literal>RAW</literal>.  <literal>TEXT</literal> automatically
	  converts incoming UNIX newline text to DOS-like CR/LF text that the
	  printer can print.  <literal>RAW</literal> should be used for
	  PostScript, and HPPCL printing.</para>

	<para>HP JetDirect EX +3: External, 3 port version of the JetDirect.
	  Use <literal>RAW1</literal>, <literal>RAW2</literal>,
	  <literal>RAW3</literal>, <literal>TEXT1</literal>,
	  <literal>TEXT2</literal>, or <literal>TEXT3</literal> depending on
	  the port desired.</para>

	<para>Intel NetPort: Either use <literal>TEXT</literal> for UNIX text
	  conversion printing or use <literal>PASSTHRU</literal> for normal
	  printing.</para>

	<para>DPI: Use <literal>PORT1</literal> or <literal>PORT2</literal>
	  depending on which port the printer is plugged into.</para>

	<para>For other manufacturer's print servers refer to the manuals
	  supplied with those devices.</para>

	<para>The following is an example printcap that redefines the default
	  <literal>lp</literal> print queue to send print jobs to the first
	  parallel port on a remote HP LaserJet plugged into a JetDirect EX +3
	  named <hostid role="fqdn">floor2hp4.biggy.com</hostid>.</para>

	<programlisting>#
lp|local line printer:\
    :rm=floor2hp4.biggy.com:rp=RAW1:\
    :sd=/var/spool/output/lpd:\
    :lf=/var/log/lpd-errs:
#</programlisting>

	<note>
	  <para>The <literal>rp</literal> capability <emphasis>must</emphasis>
	    be defined or the job goes to the default print queue on the
	    remote host.  If the remote device does not have a single print
	    queue, such as another UNIX system, this causes problems.  For
	    example, if the remote device was a JetDirect EX + 3 and
	    <literal>rp</literal> was omitted, all queues defined would print
	    out of the first parallel port.</para>
	</note>
      </sect2>

      <sect2>
	<title>Filters</title>

	<para>The last two important printcap capabilities concern print
	  filters, <literal>if</literal> (input filter) and
	  <literal>of</literal> (output filter) If defined, incoming print
	  jobs are run through the filters that these entries point to for
	  further processing.</para>

	<para>Filters are the reason that the UNIX print spooling system is so
	  much more powerful than any other commercial server operating
	  system.  Under FreeBSD, incoming print jobs are acted on by any
	  filters specified in the <filename>/etc/printcap</filename>
	  <emphasis>no matter where they originate</emphasis>.  Incoming print
	  jobs from remote Windows, Mac, NT, OS/2 or other clients can be
	  intercepted and manipulated by any program specified as a filter.
	  Want a PostScript Printer? There's a filter that adds PostScript
	  capability to a non-PostScript printer.  Want to make a cheap Epson
	  MX 80 dot-matrix emulate an expensive Okidata Microline dot-matrix
	  for some archaic mainframe application? Write a filter that will
	  rewrite the print codes to do it.  Want custom-built banner pages?
	  Use a filter.  Many UNIX <filename>/etc/printcap</filename> filters
	  on many Internet sites can do a variety of interesting and unique
	  things. Someone may have already written a filter that does what you
	  want!</para>

	<sect3>
	  <title>Types of filters</title>

	  <para>Three types of filters can be defined in the
	    <filename>/etc/printcap</filename> file.  In this book all filter
	    examples are for Input filters.</para>

	  <sect4>
	    <title>Input Filters</title>

	    <para>Input filters are specified by the <literal>if</literal>
	      capability.  Every job that comes into the spool is acted on by
	      any filter specified in the <literal>if</literal> entry for that
	      spool. Virtually all filters that an administrator would use are
	      specified here.  These filters can be either shell scripts, or
	      compiled programs.</para>
	  </sect4>

	  <sect4>
	    <title>Fixed Filters</title>

	    <para>Fixed filters are specified by separate capabilities, such
	      as <literal>cf</literal>, <literal>df</literal>, and
	      <literal>gf</literal>.  Mostly, these exist for historical
	      reasons.  Originally, the idea of LPD was that incoming jobs
	      would be submitted with the type fields set to trigger whatever
	      filter was desired.  However, type codes are confusing and
	      annoying to the user, who has to remember which option is needed
	      to trigger which type.  It is much easier to set up multiple
	      queues with different names, and this is what most sites do
	      these days. For example, originally a DVI fixed filter might be
	      specified in a spool for <literal>lp</literal>, triggered by the
	      <option>-d</option> option passed to <command>lpr</command>.
	      Jobs without this option aren't acted on by the DVI filter.
	      However, the same thing can be done by creating a queue named
	      <literal>lp</literal> that doesn't have a DVI filter, and a
	      queue named <literal>lpdvi</literal> which has the DVI filter
	      specified in the <literal>if</literal> capability.  Users just
	      need to remember which queue to print to, instead of what option
	      needed for this or that program.</para>
	  </sect4>

	  <sect4>
	    <title>Output Filters</title>

	    <para>These are specified by the <literal>of</literal>capability.
	      Output filters are much more complicated than input filters and
	      are hardly ever used in normal circumstances.  They also
	      generally require a compiled program somewhere, either directly
	      specified or wrapped in a shell script, since they have to do
	      their own signal-handling.</para>
	  </sect4>
	</sect3>

	<sect3>
	  <title>Printing raw Unix text with a filter</title>

	  <para>One of the first thing that a new Unix user will discover when
	    plugging a standard LaserJet or impact printer into a UNIX system
	    is the <emphasis>stairstep</emphasis> problem.  The symptom is
	    that the user dumps text to the printer, either through LPR or
	    redirection (by catting it to the parallel device) and instead of
	    receiving the expected Courier 10-point printout, gets a page with
	    a single line of text, or two lines of text "stairstepped", text
	    and nothing else.</para>

	  <para>The problem is rooted in how printers and UNIX handle
	    textfiles internally.  Printers by and large follow the "MS-DOS
	    Textfile" convention of requiring a carriage return, then a
	    linefeed, at the end of every text line.  This is a holdover from
	    the early days when printers were mechanical devices, and the
	    print head needed to return and the platen to advance to start a
	    new line.  UNIX uses only the linefeed character to terminate a
	    text line.  So, simply dumping raw text out the parallel port
	    works on MS-DOS, but not on UNIX.</para>

	  <para>If the printer is a PostScript printer, and doesn't support
	    standard ASCII, then dumping UNIX text to it doesn't work.  But
	    then, neither would dumping MS-DOS text to it. (Raw text printing
	    on PostScript printers is discussed later in this chapter) Note
	    also that if the printer is connected over the network to an HP
	    JetDirect hardware print server, internal or external, the TEXT
	    queue on the hardware print automatically adds the extra Carriage
	    Return character to the end of a text line.</para>

	  <para>If the printer is the garden-variety HP LaserJet, DeskJet, or
	    an impact printer, and under DOS the administrator is used to
	    printing raw text from the command line for directory listings,
	    there are two ways to fix stairstep.  The first is to send a
	    command to the printer to make it print in "unix textfile" mode,
	    which makes the printer supply it's own carriage return.  This
	    solution is ugly in a printer environment with UNIX and Windows
	    machines attempting to share use of the same printer.  Switching
	    the printer to work with Unix disrupts DOS/Windows raw text
	    printouts.</para>

	  <para>The better solution is to use a simple filter that converts
	    incoming text from UNIX style to DOS style.  The following filter
	    posted on questions@FreeBSD.org and the sample
	    <filename>/etc/printcap</filename> entry can be used to do
	    this:</para>

	  <programlisting>#!/bin/sh
# /usr/local/libexec/crlfilter
#
# simple parlor trick to add CR to LF for printer
# Every line of standard input is printed with CRLF
# attached.
#

awk '{printf "%s\r\n", $0}' -</programlisting>

	  <para>An alternative filter posted using sed could be written
	    as:</para>

	  <programlisting>#!/bin/sh
# /usr/local/libexec/crlfilter
#
# Add CR to LF for printer
# Every line of standard input is printed with CRLF
# attached.
#
# Note, the ^M is a *real* ^M (^V^M if your typing in vi)
#

sed 's/$/^M/' -</programlisting>

	  <para>Here is an example of a filter that triggers the printers
	    automatic LF-to-CR/LF converter (this option is only useful on HP
	    LaserJets that support this command):</para>

	  <programlisting>#!/bin/sh
# Simply copies stdin to stdout.  Ignores all filter
# arguments.
# Tells printer to treat LF as CR+LF.  Writes a form feed
# character after printing job.

printf "\033&amp;k2G" &amp;&amp; cat &amp;&amp; printf "\f" &amp;&amp; exit 0

exit 2</programlisting>

	  <para>The printcap file used to trigger the filter is:</para>

	  <programlisting>#/etc/printcap
# The trailer (tr) is used when the queue empties.  I found that the
# form feed (\f) was basically required for the HP to print properly.
# Banners also need to be shut off.
#

lp|local line printer:\
    :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:
    :if=/usr/local/libexec/crlfilter:sh:tr=\f:mx#0:
#</programlisting>
	</sect3>

	<sect3>
	  <title>The pr filter</title>
	  
	  <para>Although most filters are built by scripts or programs and are
	    added to the UNIX machine by the administrator, there is one
	    filter that is supplied with the FreeBSD operating system is very
	    useful for raw text files: the <literal>pr</literal>filter.  It is
	    most commonly used when printing from the UNIX command shell. The
	    <literal>pr</literal> filter paginates and applies headers and
	    footers to ASCII text files.  It is automatically invoked with the
	    <option>-p</option> option used with the <command>lpr</command>
	    program at the UNIX command prompt.</para>

	  <para>The pr filter is special - it runs <emphasis>in
	      addition</emphasis> to any input filters specified for the print
	    queue in <filename>/etc/printcap</filename>,
	    <emphasis>if</emphasis> the user sets the option for a print job.
	    This allows headers and pagination to be applied in addition to
	    any special conversion, such as CR to LF that a specified input
	    filter may apply.</para>
	</sect3>

	<sect3>
	  <title>Printing PostScript banner pages with a Filter.</title>

	  <para>Unfortunately, the canned banner page supplied in the LPD
	    program prints only on a text-compatible printer.  If the attached
	    printer understands only PostScript and the administrator wants to
	    print banner pages, it is possible to install a filterinto the
	    <filename>/etc/printcap</filename>file to do this.</para>

	  <para>The following filter is taken from the FreeBSD Handbook.  I've
	    slightly changed it's invocation for a couple of reasons.  First,
	    some PostScript printers have difficulty when two print files are
	    sent within the same print job or they lack the trailing
	    Control-D.  Second is that the handbook invocation uses the LPRPS
	    program, which requires a serial connection to the printer.</para>

	  <para>The following filter shows another trick: calling LPR from
	    within a filter program to spin off another print job.
	    Unfortunately, the problem with using this trick is that the
	    banner page always gets printed after the job.  This is because
	    the incoming job spools first, and then FreeBSD runs the filter
	    against it, so the banner page generated by the filter always
	    spools behind the existing job.</para>

	  <para>There are two scripts, both should be put in the
	    <filename>/usr/local/libexec</filename> directory, and the modes
	    set to executable.  The <filename>printcap</filename> also must be
	    modified to create the nonbanner and banner versions of the print
	    queue.  Following the scripts is the
	    <filename>/etc/printcap</filename> file showing how they are
	    called.  Notice that the <literal>sh</literal> parameter is turned
	    on since the actual printed banner is being generated on the fly
	    by the filter:</para>

	  <programlisting>#!/bin/sh
# Filename /usr/local/libexec/psbanner
# parameter spacing comes from if= filter call template of:
# if -c -w -l -i -n login -h host
# parsing trickiness is to allow for the presence or absence of -c
# sleep is in there for ickiness of some PostScript printers

for dummy
do
  case "$1" in
    -n) alogname="$2" ;;
    -h) ahostname="$2" ;;
  esac
  shift
done

/usr/local/libexec/make-ps-header $alogname $ahostname "PostScript" | \
  lpr -P lpnobanner

sleep 10

cat &amp;&amp; exit 0</programlisting>

	  <para>Here is the <filename>make-ps-header</filename>listing.</para>

	  <programlisting>#!/bin/sh
# Filename /usr/local/libexec/make-ps-header
#
# These are PostScript units (72 to the inch).  Modify for A4 or
# whatever size paper you are using:
#

page_width=612
page_height=792
border=72

#
# Save these, mostly for readability in the PostScript, below.
#

user=$1
host=$2
job=$3
date=`date`

#
# Send the PostScript code to stdout.
#

exec cat &lt;&lt;EOF
%!PS
%
% Make sure we do not interfere with user's job that will follow
%

%
% Make a thick, unpleasant border around the edge of the paper.
%

$border $border moveto
$page_width $border 2 mul sub 0 rlineto
0 $page_height $border 2 mul sub rlineto
currentscreen 3 -1 roll pop 100 3 1 roll setscreen
$border 2 mul $page_width sub 0 rlineto closepath
0.8 setgray 10 setlinewidth stroke 0 setgray

%
% Display user's login name, nice and large and prominent
%

/Helvetica-Bold findfont 64 scalefont setfont
$page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto
($user) show

%
% Now show the boring particulars
%

/Helvetica findfont 14 scalefont setfont
/y 200 def
[ (Job:) (Host:) (Date:) ] {
200 y moveto show /y y 18 sub def
} forall
/Helvetica-Bold findfont 14 scalefont setfont
/y 200 def
[ ($job) ($host) ($date) ] {
270 y moveto show /y y 18 sub def
} forall

%
% That is it
%

showpage</programlisting>

	  <para>Here is the <filename>/etc/printcap</filename> file.</para>

	  <programlisting>#
lp|local line printer, PostScript, banner:\
  :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:
  :if=/usr/local/libexec/psbanner:sh:mx#0:

lpnobanner|local line printer, PostScript, no banner:\
  :lp=/dev/lpt0:sd=/var/spool/output/lpd-noban:\
  :lf=/var/log/lpd-errs:sh:mx#0:
#</programlisting>
	</sect3>
      </sect2>
    </sect1>

    <sect1>
      <title>Printer Accounting</title>

      <para>The FreeBSD print spooler can manage accounting statistics for
	printer usage.  The spooler counts each page printed and generates
	totals for each user.  In this manner departments or individuals can
	be charged money for their use of the printer.</para>

      <para>In the academic world, such as student computer labs, accounting
	is very political.  Many schemes have been developed to attempt to
	gather statistics to charge people (generally students) for printing.
	Administrators in this environment who deal with printers can have
	almost as many accounting problems as printer problems.  In the
	corporate environment, on the other hand, accounting is not as
	important.  I strongly recommend against any corporation attempting to
	implement printer accounting on shared printers for a number of
	reasons:</para>

      <orderedlist>
	<listitem>
	  <para>The entire UNIX accounting system is based on ASCII printouts.
	    It is easy to count the number of ASCII pages, form feeds, or text
	    lines in a print job.  In corporations, however, PostScript and
	    HPPCL are generally the order of the day.  It is almost impossible
	    to figure out by examining the datastream how many pages it will
	    occupy, and even if this could be done accurately, it wastes
	    significant computational resources.</para>

	  <note>
	    <para>It is possible to get some PostScript printers to count
	      pages, but doing so requires a bidirectional connection to the
	      printer and additional programming on the UNIX system.  This
	      task is beyond the scope of this book.</para>
	  </note>
	</listitem>

	<listitem>
	  <para>Banner pages aren't included in UNIX printer accounting
	    counts.  Therefore, someone submitting 20 two-page jobs uses much
	    more paper than does someone submitting one 40 page job, yet both
	    are charged the same amount.</para>
	</listitem>

	<listitem>
	  <para>The username of the submitter can be easily forged, if the job
	    is remotely submitted over the network from a client. (practically
	    all jobs in a Windows client printing environment are remotely
	    submitted) Although some LPR clients can be set to authenticate,
	    and the <literal>rs</literal> capability can be set to enforce
	    authentication, not all can, especially Windows LPR
	    clients.</para>
	</listitem>

	<listitem>
	  <para>It is more difficult for a submitter to hide the IP number or
	    machine name of the remote client, but in a Windows environment
	    there is no guarantee that someone was sitting at a particular
	    desktop machine when the job was submitted.</para>
	</listitem>

	<listitem>
	  <para>A business generates no revenue by monitoring printer usage.
	    In the academic community, however, when a student lab charges for
	    printouts the lab is actually extracting money from an entity (the
	    student) that is separate from the lab.  Within a corporation, the
	    concept of department A getting revenue from user B is pointless
	    and doesn't generate a net gain for the corporation as a
	    whole.</para>

	  <para>For my printer administration, I have found that I can save
	    more money on printing costs by purchasing supplies wisely than by
	    attempting to discourage printing through "chargebacks".  What is
	    the sense of being miserly with printing while spending double on
	    toner cartridges because no one is willing to comparison shop, or
	    signing a "lease" agreement that isn't beneficial for the printer?
	    When you get down to it, corporate users don't care much for print
	    sharing anyway, and they generally only agree to it because the
	    administrator can buy a far bigger, faster, and fancier printer
	    than they can requisition.</para>
	</listitem>

	<listitem>
	  <para>Worse yet, if usage on a shared printer is charged, it
	    encourages employees to look for other places to print.
	    Inevitably, people run out buy cheap inkjet printers for their own
	    use, and the business ends up spending more on paper and supplies
	    for many poor-quality small printers, than it would for a few
	    decent big ones.  Moreover, the inferior output of these printers
	    makes the organization as a whole look bad.</para>
	</listitem>

	<listitem>
	  <para>The corporate spirit should be one of teamwork, not bickering.
	    The surest way to kill a network in a corporation is to set up a
	    situation that puts the administrator into the policeman position
	    or pits one department against another.</para>
	</listitem>
      </orderedlist>
      
      <para>The only justification I've ever seen for running accounting on
	corporate printers is using the accounting system to automate
	reminders to the administrator to replace paper, or toner. Aside from
	this use, a corporation that implements accounting as a way of
	encouraging employees not to waste paper ends up defeating the purpose
	of turning on accounting.</para>
    </sect1>

    <sect1>
      <title>Microsoft Networking Client printing with Samba</title>

      <para>Although LPR is a time-tested and truly cross-platform printing
	solution, sites with a majority of Windows clients running Microsoft
	Networking have an alternate printing mechanism&mdash;Samba.  Samba
	can provide print services to clients running SMB-compatible network
	clients.  With a running Samba installation, the administrator may
	"share out" printers as well as filesystem directories from the
	FreeBSD system.</para>

      <para>Printers accessed with Samba must be defined both in the
	<filename>/etc/printcap</filename> file and the
	<filename>/usr/local/etc/smb.conf</filename> file. If the individual
	printers are defined in the <filename>smb.conf</filename> file with
	the <literal>printer driver=</literal> statement set to the exact
	model name of the printer, the "Auto printer driver install" feature
	of Windows NT and Win95/98 is activated.  This automatically loads the
	correct printer driver if the user clicks on the print queue in
	Network Neighborhood under Windows 95 or NT 4.0 The restriction, of
	course, is that the printer model must be in the Windows client driver
	database.</para>

      <para>The <filename>smb.conf</filename> file also defines the
	<literal>print</literal> command used to pass jobs to the UNIX print
	spool.  It is a good idea to redefine this via the <literal>print
	  command</literal> option to <literal>lpr -s -P %p %s; rm
	  %s</literal>.  This turns on soft linking, so that large print jobs
	don't get truncated.</para>

      <para>In operation, the SMB-networking client builds the print job on
	itself and then transfers the entire job over the network to the Samba
	server.  On the server, Samba has it's own temporary print spool
	directory to which the job is copied.  Once the job has been
	completely received, it is then passed to the UNIX print
	spooler.</para>

      <figure>
	<title>Microsoft Networking Client printing with Samba</title>

	<mediaobject>
	  <imageobject>
	    <imagedata fileref="08-06" format="EPS">
	  </imageobject>

	      <textobject>
		<literallayout class="monospaced"> ,---------.
 | ======= |                   FreeBSD Server
 | ======= |               +---------------------+        ,-----.
+-----------+              |  +---------------+  |        |     |
|  Printer [ ]------------[ ] |    Samba      |  |        |_____| 
+-----------+	Parallel   |  |   Software    | [ ]------_________
		 Cable     |  +---------------+  |      / ::::::: \
                           |                     |      `---------'
                           |  +---------------+  |       Network PC
                           |  |    Print      |  |
                           |  |   Software    |  |
	                   |  +---------------+  |
	                   +---------------------+</literallayout>
	  </textobject>

	  <textobject>
	    <phrase>The Samba software and the print software run on the same
	      host.  Samba receives the print job, then hands it to the print
	      spooler.</phrase>
	  </textobject>
	</mediaobject>
      </figure>

      <sect2>
	<title>Client access issues</title>

	<para>Because a Windows client formats print jobs before sending them
	  to the server, the administrator may want to hide some of the
	  specialty print queues on the server.  For example, the queue that
	  converts LF to CRLF for UNIX text printouts would probably not be
	  shared out.  To make such queues invisible, the
	  <literal>browseable=no</literal> option can be turned on in the
	  <filename>smb.conf</filename> file.  Also, the <literal>load
	    printers</literal> option must be set to no to allow individual
	  printer definitions.</para>

	<note>
	  <para>In general, the only print queues that should be visible
	    through Samba are the "raw" print queues that are set up by the
	    administrator to allow incoming preformatted print jobs.</para>
	</note>
	
	<para>Windows clients that print to Samba print queues on the UNIX
	  system can view and cancel print jobs in the print queue.  They
	  cannot pause them, however, which is a difference between Novell and
	  Windows NT Server print queues.  They also cannot prioritize print
	  jobs from the print queue window, although the administrator can
	  reprioritize print jobs that are in the queue from a command shell
	  on the FreeBSD server.</para>
      </sect2>

      <sect2>
	<title>Printer entries in configuration files</title>

	<para>Following are listings of sample
	  <filename>/etc/printcap</filename> file, and
	  <filename>smb.conf</filename> files used on the system to provide
	  print services.  An explanation of the interaction of these files
	  follows.</para>

	<example>
	  <title><filename>/etc/printcap</filename></title>

	  <programlisting>#
#
# The printer in lpt0 is a Postscript printer.  The nec-crlf entry
# is for testing the printer when it is switched into HP LaserJet III
# mode.
#

lp|local line printer:\
  :lp=/dev/lpt0:sd=/var/spool/output/lpd:\
  :lf=/var/log/lpd-errs:sh:mx#0:

#

nec-crlf|NEC Silentwriter 95 in ASCII mode with Unix text filter:\
  :lp=/dev/lpt0:sd=/usr/lpdspool/nec-crlf:\
  :lf=/var/log/lpd-errs:sh:mx#0:\
  :if=/usr/local/libexec/crlfilter:tr=\f:

#

nec-raw|NEC Silentwriter 95 used for PostScript passthrough printing:\
  :lp=/dev/lpt0:sd=/usr/lpdspool/nec-raw:\
  :lf=/var/log/lpd-errs:sh:mx#0:

#

nec-ps-banner|NEC Silentwriter 95 with Postscript banner page created:\
  :lp=/dev/lpt0:sd=/usr/lpdspool/nec-ps-banner:\
  :lf=/var/log/lpd-errs:sh:mx#0:if=/usr/local/libexec/psbanner:

#
#</programlisting>
	</example>

	<example>
	  <title><filename>/usr/local/etc/smb.conf</filename></title>

	  <programlisting>[global]
comment = FreeBSD - Samba %v
log file = /var/log/samba.log
dont descend = /dev,/proc,/root,/stand
print command = lpr -s -P %p %s; rm %s
interfaces = <replaceable>X.X.X.X</replaceable> (the system IP number goes here)
printing = bsd
map archive = no
status = yes
public = yes
read only = no
preserve case = yes
strip dot = yes
security = share
guest ok = no
password level = 1
dead time = 15
domain master = yes
workgroup = WORKGROUP

[homes]
browseable = no
comment = User Home Directory
create mode = 0775
public = no

[printers]
path = /var/spool
comment = Printers
create mode = 0700
browseable = no
read only = yes
public = no

[lp]
printable = yes
browseable = no

[nec-raw]
comment = Main Postscript printer driver for Windows clients
printer driver = NEC SilentWriter 95
printable = yes
browseable = yes

[wwwroot]
path = /usr/local/www
read only = no
create mode = 0775
comment = Internal Web Server</programlisting>
	</example>
      </sect2>

      <sect2>
	<title>Browsing output</title>

	<para>Following is the output of a <userinput>net view</userinput>
	  command executed at a DOS prompt under Windows 95:</para>

	<screen>Shared resources at \\SERVER

Sharename Type    Comment
--------------------------------------------------------------------
nec-crlf  Print   NEC Silentwriter 95 in ASCII mode
nec-raw   Print   Main Postscript printer driver
tedm      Disk    User Home Directory
wwwroot   Disk    Internal Web Server

The command was completed successfully.</screen>

	<para>In the <filename>/etc/printcap</filename> file four print queues
	  are defined, all tied to the printer plugged into the parallel port
	  on the FreeBSD server.  The first is <literal>lp</literal>, the
	  generic local line printer.  Since this print queue generally has a
	  filter placed on it to format jobs from the UNIX print queue
	  properly, it should not be visible on the SMB network.  (ie: visible
	  in Network Neighborhood) The second queue,
	  <literal>nec-crlf</literal>, has a filter that converts UNIX text to
	  text that prints without stairstepping, so it also should be hidden
	  from the SMB network.  The third, <literal>nec-raw</literal>, should
	  be visible on the network because this is the spool that the Windows
	  clients use.  The last queue, <literal>nec-ps-banner</literal>, is
	  another specialty queue for UNIX local printing and thus should not
	  be visible.</para>

	<para>When the <filename>smb.conf</filename> file is parsed, the
	  default entry <literal>[printers]</literal> is first read and used
	  as a set of defaults for printers that are going to be shared out.
	  Next, the <filename>/etc/printcap</filename> file is read to get a
	  list of all printers on the server.  Last, each printer is checked
	  for a service name in the <filename>smb.conf</filename>file that
	  contains settings that override the set of defaults.</para>

	<para>In the listing of what resources are visible on the network,
	  both <literal>nec-crlf</literal> and <literal>nec-raw</literal>
	  print queues are visible, and <literal>lp</literal>and
	  <literal>nec-ps-banner</literal> is not. <literal>lp</literal> is
	  not visible because there is a specific entry,
	  <literal>[lp]</literal> in the <filename>smb.conf</filename> file
	  that blocks it. <literal>nec-ps-banner</literal> doesen't have such
	  an entry, but because the print queue name is not a legal length for
	  a SMB name, it isn't shared out either.</para>

	<para>The <literal>nec-crlf</literal> printer is visible so as to
	  illustrate another point - comments.  If a print queue has no entry
	  in the <filename>smb.conf</filename> file and is built by scanning
	  the <filename>/etc/printcap</filename> file and using the
	  <literal>[printers]</literal> defaults, the comment is taken from
	  the <filename>/etc/printcap</filename> file next to the queue
	  definition name.  Otherwise, if an entry is made for the printer in
	  the <filename>smb.conf</filename> file the comment is taken from the
	  entry in <filename>smb.conf</filename>.</para>
      </sect2>
    </sect1>

    <sect1>
      <title>Printing between NT Server/NetWare and FreeBSD.</title>

      <para>Up to this point in the chapter, our main concern has been FreeBSD
	and Windows NT printing interoperability with NT as a print client
	passing jobs to the FreeBSD system.  What happens if the situation is
	reversed and the FreeBSD system is itself a printing client of another
	LPD server? This situation can arise in a mixed UNIX/Netware or
	UNIX/NT environment.  The administrator may elect to forgo the use of
	Samba, and use an NT server to provide print services.  Alternatively,
	the administrator may have existing DOS Novell IPX clients that they
	don't want to change, printing to an existing IPX Novell NetWare
	server.  Many of the earlier hardware print servers, such as the Intel
	NetPort 1 and NetPort 2 were IPX only.  A site with a large number of
	these hardware servers may wish to move the clients to TCP/IP, but
	leave the existing IPX-based printing network intact.</para>

      <para>With NetWare it is possible to load an LPD NetWare loadable module
	(NLM) on the NetWare server that takes incoming LPR print jobs and
	prints them on IPX print queues.  Later versions of NetWare may
	include this NLM, it was an extra cost add-on with NetWare 3.X</para>

      <para>With Windows NT Server, loading the TCP/IP LPR printing support
	also loads the LPD print server on NT.  By using LPR client programs
	on UNIX, it is possible to submit, view status, and remove jobs
	remotely from an NT server that has LPR installed as a port for it's
	printers.</para>

      <para>Following is a sample <filename>/etc/printcap</filename>file entry
	that defines a print queue named <literal>tank</literal>on the FreeBSD
	system pointed to an NT LPD server queue named
	<literal>sherman</literal> on a NT Server named
	<hostid role="fqdn">big.army.mil</hostid> in the DNS.  This uses the
	<literal>rm</literal> printcap capability.  Unlike the earlier
	examples, the output print jobs are sent out not by the PC parallel
	port but over the network to the NT server.</para>

      <programlisting>#
tank|sample remote printer:\
  :rm=big.army.mil:rp=sherman:sd=/var/spool/output/lphost:\
  :lf=/var/log/lpd-errs:
#</programlisting>

      <note>
	<para>When using an NT server as an LPD server it may be necessary to
	  make the NT registry changes mentioned under Windows NT Registry
	  Changes, earlier in the chapter.</para>
      </note>
    </sect1>

    <sect1>
      <title>Printing from Unix</title>

      <para>Two commands used at the FreeBSD command prompt are intended as
	general-purpose print commands: <command>lp</command> and
	<command>lpr.</command>.</para>

      <sect2>
	<title><command>lp</command></title>

	<para>The <command>lp</command> command is simply a front end command
	  that calls the <command>lpr</command> command with appropriate
	  options.  It's main use is to allow the running of precompiled
	  binary programs and scripts that assume that the
	  <command>lp</command> command is the <emphasis>official</emphasis>
	  printing command.</para>
      </sect2>

      <sect2>
	<title><command>lpr</command></title>

	<para>The <command>lpr</command> command is the main command that is
	  used to print files from the command prompts under the FreeBSD
	  operating system.  It is frequently spawned off as a child program,
	  or used in pipes.  For example, when the Netscape web browser's
	  Print button is clicked, Netscape may create the PostScript output,
	  but the output goes through the <command>lpr</command>
	  command.</para>

	<para>The <command>lpr</command> command, like many UNIX command-line
	  printing programs, assumes that the default print queue name is
	  <literal>lp</literal>.  When the FreeBSD machine is set up, the
	  administrator usually sets the <literal>lp</literal> queue to print
	  through a filter that allows raw UNIX text sent to it to print
	  properly.  For example, if an HP LaserJet printer that doesn't have
	  Postscript is connected to the server, the
	  <literal>lp</literal>queue specifies in the
	  <filename>/etc/printcap</filename> file the CRLF filter listed
	  earlier.  On the other hand, if an Apple Laserwriter that doesn't
	  support ASCII is connected to the server, the
	  <literal>a2ps</literal>filter would be specified in the
	  <filename>/etc/printcap</filename> for the <literal>lp</literal>
	  queue.</para>

	<para>When printing raw text files usually the <option>-p</option>
	  option is specified to <command>lpr</command>.  When printing
	  preformatted files, such as PostScript files, the
	  <option>-P</option> option is used, which selects whatever queue is
	  used to handle these job types.</para>
      </sect2>

      <sect2>
	<title>Managing the Unix Print Queue</title>

	<para>Once the print jobs coming in from clients are received on the
	  FreeBSD system and placed in the print spool, they are metered out
	  at a slower rate to the various printers.  If traffic activity is
	  light, and few print jobs get sent through, the administrator can
	  probably ignore the print queue as long as it continues to work.
	  However, a busy network printer running at an optimal rate of speed
	  usually has a backlog of unprinted jobs in the queue waiting for
	  print time.  To keep all users happy and to provide for the
	  occasional rush print job, the Unix LPD/LPR printing system has
	  several administration commands which are described here.</para>

	<sect3>
	  <title>Viewing the queue</title>

	  <para>On busy printers, and to troubleshoot stopped printers, users
	    sometimes need to view the print jobs in the queue. Administrators
	    also need to view the queue to see what jobs may need to be
	    expedited.  This can be done from the workstation that remotely
	    submitted the job if the LPR client has the ability to do this.
	    The Windows 3.1 LPR client discussed earlier has this capability.
	    Unfortunately, many LPR clients don't, which means that the
	    administrator must Telnet into the UNIX machine that the print
	    queues are on and view them there.</para>

	  <para>The UNIX shell command used to view the queue is the
	    <command>lpq</command> command It is frequently run as
	    <userinput>lpq -a</userinput> which shows jobs in all queues.  The
	    following is a sample output of the command:</para>

	  <screen>&prompt.root; <userinput>lpq -a</userinput>
nec-raw:
Rank Owner Job Files                         Total Size
1st  tedm  19  C:/WLPRSPL/SPOOL/~LP00018.TMP 105221 bytes
2nd  tedm  20  C:/WLPRSPL/SPOOL/~LP00019.TMP 13488 bytes
3rd  root  3   hosts                         1220 bytes
4th  tedm  1   Printer Test Page             765 bytes
5th  tedm  2   Microsoft Word - CHAPTE10.DOC 15411 bytes</screen>

	  <para>The first two jobs and the last two jobs came from remote
	    clients, the third came from the command prompt.</para>
	</sect3>

	<sect3>
	  <title>Removing print jobs</title>

	  <para>Deleting unwanted print jobs that haven't yet printed from the
	    queue can be done by the remote workstations that submitted the
	    job if their LPR implementations have the necessary commands.  The
	    Windows 3.1 LPR client I detailed earlier this capability.  Many
	    LPR clients don't, however, which means that the administrator
	    must Telnet into the UNIX machine that the print queues are on and
	    delete the jobs there.</para>

	  <para>The administrator can delete any print jobs from any queues by
	    running the <command>lprm</command> command followed by the
	    specified print queue and the job number.  Below is a sample
	    output of the command:</para>

	  <screen>&prompt.root; <userinput>lprm -P nec-raw 19</userinput>
dfA019tedmitte dequeued
cfA019dostest dequeued
&prompt.root; <userinput>lprm -P nec-raw 3</userinput>
dfA003toybox.placo.com dequeued
cfA003toybox.placo.com dequeued</screen>

	  <para>The <command>lprm</command> command is also used under UNIX to
	    delete remote print jobs.</para>
	</sect3>

	<sect3>
	  <title>Advanced management</title>

	  <para>The administrator logged into the FreeBSD system as the root
	    user can also perform several other operations that ordinary users
	    cannot.  These include turning the queues on and off, and moving
	    print jobs within the print queues.  The command used to do this
	    is the <command>lpc</command> command.</para>

	  <para><command>lpc</command> has two modes of operation.  In the
	    first mode, the command is run by itself, which puts the
	    administrator into an <prompt>lpc</prompt> prompt.  Some general
	    help is available for the commands, such as the following sample
	    output:</para>

	  <screen>&prompt.root; <userinput>lpc</userinput>
<prompt>lpc&gt;</prompt> <userinput>help</userinput>
Commands may be abbreviated.
Commands are:
abort enable disable help restart status topq ?
clean exit down quit start stop up
<prompt>lpc&gt;</prompt> <userinput>help disable</userinput>
disable turn a spooling queue off
<prompt>lpc&gt;</prompt> <userinput>help status</userinput>
status show status of daemon and queue
<prompt>lpc&gt;</prompt> <userinput>exit</userinput></screen>
	  
	  <para>In the second mode of operation the <command>lpc</command>
	    command is just run by itself, followed by the command and the
	    print queue name.  Following is a sample output:</para>

	  <screen>&prompt.root; <userinput>lpc disable lp</userinput>
lp:
queuing disabled</screen>

	  <para>Under FreeBSD, there is no command that specifically allows
	    the administrator to move jobs from one queue to another.  This
	    can be done, however, by changing into the raw queue directory
	    then rerunning the <command>lpr</command> command.  Following is a
	    sample run showing three print jobs moved from a dysfunctional
	    queue to a good one:</para>

	  <screen>&prompt.root; <userinput>lpq -a</userinput>
lp:
Warning: lp is down: printing disabled
printing disabled
Rank Owner Job Files                      Total Size
1st  root  51  hosts                      1220 bytes
2nd  root  52  services                   60767 bytes
3rd  root  53  printcap                   2383 bytes
&prompt.root; <userinput>cd /var/spool/output/lpd</userinput>
&prompt.root; <userinput>ls</userinput>
.seq cfA053toybox.placo.com dfA053toybox.placo.com
cfA051toybox.placo.com dfA051toybox.placo.com lock
cfA052toybox.placo.com dfA052toybox.placo.com status
&prompt.root; <userinput>lpr -P nec-raw dfA051toybox.placo.com</userinput>
&prompt.root; <userinput>lpr -P nec-raw dfA052toybox.placo.com</userinput>
&prompt.root; <userinput>lpr -P nec-raw dfA053toybox.placo.com</userinput>
&prompt.root; <userinput>lprm -P lp -</userinput>
&prompt.root; <userinput>lpq -a</userinput>
nec-raw:
Warning: nec-raw is down: printing disabled
Warning: no daemon present
Rank Owner Job Files                      Total Size
1st  root  5   dfA051toybox.placo.com     1220 bytes
2nd  root  6   dfA052toybox.placo.com     60767 bytes
3rd  root  7   dfA053toybox.placo.com     2383 bytes</screen>

	  <note>
	    <para>Moving jobs from queue to queue is feasible only when all
	      printers are similar, as when all printers support
	      PostScript.</para>
	  </note>
	</sect3>

	<sect3>
	  <title>Remote Management</title>

	  <para>Just as the root user can manipulate remotely submitted jobs
	    in the print queue, print jobs can be remotely managed by regular
	    users with the LPR clients that created them. Unfortunately, some
	    LPR clients, such as Win95, don't have enough programming to be
	    able to do this.  Others, like the Win31 client, can manipulate
	    the print jobs remotely.</para>

	  <para>FreeBSD offers some level of protection against inadvertent
	    deletion of print jobs from remote hosts by restricting
	    manipulation of a job to the same host that originated it.  Even
	    if the owner of the job matches a local user account on the
	    server, for an ordinary user to delete remotely submitted print
	    jobs, the request still must come from the remote host.</para>
	</sect3>
      </sect2>
    </sect1>

    <sect1>
      <title>Advanced Printing Topics</title>

      <para>The FreeBSD UNIX LPR/LPD printing system is very flexible, and,
	with the addition of filters, can be adapted to very unusual printing
	environments.  To enhance this flexibility, several useful printing
	utilities are supplied on the FreeBSD CDROM which the administrator
	might wish to install.</para>

      <sect2>
	<title>Ghostscript</title>

	<para>The Ghostscript program, invoked as
	  <filename>/usr/local/bin/gs</filename>, is one of the most useful
	  printing utilities that have been developed for the free software
	  community.  Ghostscript reads incoming PostScript data, (or Adobe
	  PDF files) interprets it, and outputs it as a raster image.  This
	  can be displayed on screen, for example, with the GhostView program
	  under the X Window system, or printed on most graphics printers,
	  such as Epson dot-matrix, HP DeskJet, or HP LaserJet.  In effect, it
	  is a way of adding PostScript printing capability to a printer that
	  doesn't have PostScript firmware code. Ghostscript has been ported
	  to numerous operating systems including Windows.</para>

	<para>The Ghostscript home page is located at
	  <ulink url="http://www.cs.wisc.edu/~ghost/">http://www.cs.wisc.edu/~ghost/</ulink>
	  and contains the most current version of the program.  A prebuilt
	  FreeBSD binary of Ghostscript located in the Packages section of the
	  FreeBSD CDROM.  This can be installed on the FreeBSD system by
	  selecting the package from the prepackaged software list that is
	  accessed through the <command>/stand/sysinstall</command>
	  installation program.  Many packaged programs on the CD depend on
	  GhostScript, and so it may already be installed.</para>

	<para>Installation of the packaged version of GhostScript is
	  recommended in the FreeBSD ports Section because it has been tested
	  with the other packages that require it.  The package creates a
	  directory containing some documentation files in
	  <filename>/usr/local/share/ghostscript/X.XX/doc</filename>.
	  Unfortunately, because of the packaging process on the FreeBSD CDROM
	  not all the useful installation files are copied into this location.
	  So, if the package was version 5.03 (for example) the administrator
	  will also want to get the file
	  <ulink url="ftp://ftp.cs.wisc.edu/ghost/aladdin/gs502/ghostscript-5.02.tar.gz">ftp://ftp.cs.wisc.edu/ghost/aladdin/gs503/ghostscript-5.03.tar.gz</ulink>,
	  and unzip and untar it into a temporary directory.</para>
	
	<para>Extracting the archive file creates a directory structure under
	  the <filename>gs5.03</filename> subdirectory.  To install
	  ghostscript in the <filename>/etc/printcap</filename> file, read the
	  <filename>gs5.03/devs.mak</filename> file to determine which printer
	  driver definition works with your printer and then use the following
	  instructions:</para>

	<procedure>
	  <step>
	    <para>Change to the root user with su.</para>
	  </step>

	  <step>
	    <para>In the <filename>gs5.03</filename>directory, copy the
	      <filename>lprsetup.sh</filename>,
	      <filename>unix-lpr.txt</filename>, and
	      <filename>unix-lpr.sh</filename> files to
	      <filename>/usr/local/share/ghostscript/5.03</filename></para>
	  </step>

	  <step>
	    <para>Change to the
	      <filename>/usr/local/share/ghostscript/5.03</filename>
	      directory. Edit <filename>lprsetup.sh</filename> with a text
	      editor such as <command>vi</command>.</para>
	  </step>

	  <step>
	    <para>Modify the <literal>DEVICES=</literal> entries
		to list your selected printer driver definitions per the
		instructions in <filename>unix-lpr.txt.</filename></para>
	  </step>

	  <step>
	    <para>Modify the <literal>PRINTERDEV=</literal> to
	      <literal>/dev/lpt0</literal>, and the <literal>GSDIR=</literal>
	      to <literal>/usr/local/share/ghostscript</literal>, and the
	      <literal>SPOOLDIR=</literal> to
	      <literal>/var/spool/output</literal>. Save the file.</para>
	  </step>

	  <step>
	    <para>Edit the <filename>unix-lpr.sh</filename> file and change
	      the <literal>PSFILTERPATH=</literal> to
	      <literal>/usr/local/share/ghostscript</literal>.</para>
	  </step>

	  <step>
	    <para>If the printer that you defined in the
	      <filename>lprsetup.sh</filename> file is a monochrome printer,
	      remove the <literal>"-dBitsPerPixel=${bpp}"</literal>and
	      <literal>"$colorspec"</literal> entries on the
	      <literal>gs</literal> invocation line and save the file.
	      Otherwise, if it is a color definition leave them in.  For
	      example, the following line is for a monochrome LaserJet:</para>

	    <programlisting>") | gs -q -dNOPAUSE -sDEVICE=${device} \"</programlisting>
	    
	    <para>Don't remove anything else.  Exit the editor, and save the
	      <filename>unix-lpr.sh</filename> file.</para>
	  </step>

	  <step>
	    <para>Copy the <filename>unix-lpr.sh</filename> file to the parent
	      directory, <filename>/usr/local/share/ghostscript</filename> and
	      set the execute bit on it.</para>
	  </step>

	  <step>
	    <para>Set the execute bit on <filename>lprsetup.sh</filename> with
	      chmod and run the file by typing
	      <userinput>./lprsetup.sh</userinput></para>
	  </step>

	  <step>
	    <para>Follow the instructions on creating the Spool directories.
	      If you will be using accounting and a separate log file, run the
	      <command>touch</command> command to create the empty files per
	      directions in script output.</para>
	  </step>

	  <step>
	    <para>The sample <command>/etc/printcap</command> is located in
	      the current directory; the filename is
	      <filename>printcap.insert</filename>.  Use this as a template to
	      modify the <filename>/etc/printcap</filename> file.  A sample
	      <filename>/etc/printcap</filename> file for a LaserJet 3 is
	      below:</para>

	    <programlisting>#
#
ljet3.raw|Raw output device ljet3 for Ghostscript:\
  :rm=big.army.mil:rp=sherman:sd=/var/spool/output/ljet3/raw:\
  :mx#0:sf:sh:rs:

#

ljet3|Ghostscript device ljet3 (output to ljet3.raw):\
  :lp=/dev/null:sd=/var/spool/output/ljet3:\
  :lf=/var/log/lpd-errs:mx#0:sf:sh:rs:\
  :if=/usr/local/share/ghostscript/filt/indirect/ljet3/gsif:\
  :af=/var/spool/output/ljet3/acct:

#</programlisting>
	  </step>
	</procedure>
      </sect2>

      <sect2>
	<title>a2ps filter</title>

	<para>Another handy utility is the <command>a2ps</command>, short for
	  ASCII-to-PostScript.  This program takes an incoming ASCII
	  datastream and converts it into PostScript.  It can also print
	  multiple pages on a single sheet of paper by shrinking them down. It
	  is a useful tool for a printer that cannot interpret ASCII, such as
	  a PostScript-only printer.</para>

	<para><command>A2ps</command> is not installed in the FreeBSD system
	  by default; it is located in the ports section
	  <filename>/usr/ports/print/a2ps43</filename>.  A prepackaged binary
	  can be installed with <command>/stand/sysinstall</command> but I
	  have had problems with that port.  It is best to install it by
	  running <command>make</command> in the a2ps43 ports directory.  A
	  printcap entry and filter using this follow:</para>

	<example>
	  <title><filename>/etc/printcap</filename></title>

	  <programlisting>#
lp|local line printer with output dumped through a2ps for raw listings:\
  :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:sh:mx#0:\
  :if=/usr/local/libexec/ascii2postscript:
#</programlisting>
	</example>

	<example>
	  <title><filename>/usr/local/libexec/ascii2postscript</filename></title>

	  <programlisting>#!/bin/sh
#
# Simple filter that converts ASCII to Postscript for basic stuff like
# directory listings.
#

/usr/local/bin/a2ps &amp;&amp; exit 0

exit 2</programlisting>
	</example>

	<para>Read the system manual page for <command>a2ps</command> to see
	  the options available with this program, and remember to set the
	  filter script <filename>ascii2postscript</filename>
	  all-executable.</para>
      </sect2>
    </sect1>

    <sect1>
      <title>Miscellaneous</title>

      <para>The large number of other printing utilities cannot be covered
	here.  Some add features such as automatic job type sensing, others
	handle bidirectional communication between the server and the printer.
	There are also a few other experimental LPR printing replacement
	systems.  Commands such as ghostscript and <command>a2ps</command> can
	also be used in pipes that create pretty output on an ordinary impact
	printer.</para>

      <para>One last hint - the system manual pages can be printed with the
	<option>-t</option> option which turns their ordinary ASCII output to
	beautifully formatted PostScript.  Try the command <command>man -t
	  man</command> and send the output through GhostScript or a
	PostScript printer for easier to read manual pages.</para>
    </sect1>
  </chapter>
</book>
