








               44..33BBSSDD LLiinnee PPrriinntteerr SSppoooolleerr MMaannuuaall


                         _R_a_l_p_h _C_a_m_p_b_e_l_l
                 Computer Systems Research Group
                    Computer Science Division
    Department of Electrical Engineering and Computer Science
               University of California, Berkeley
                       Berkeley, CA  94720


                            _A_B_S_T_R_A_C_T

          This  document describes the structure and instal-
     lation procedure for the line printer  spooling  system
     developed for the 4.3BSD version of the UNIX* operating
     system.



     Revised June 8, 1993


11..  OOvveerrvviieeww

     The line printer system supports:

+o  multiple printers,

+o  multiple spooling queues,

+o  both local and remote printers, and

+o  printers attached via serial lines that require line  initial-
   ization such as the baud rate.

Raster  output  devices  such  as a Varian or Versatec, and laser
printers such as an  Imagen,  are  also  supported  by  the  line
printer system.

     The  line  printer  system  consists mainly of the following
files and commands:







-----------
* UNIX is a trademark of Bell Laboratories.









SMM:7-2                        4.3BSD Line Printer Spooler Manual


     /etc/printcap      printer configuration and capability data base
     /usr/sbin/lpd      line printer daemon, does all the real work
     /usr/bin/lpr       program to enter a job in a printer queue
     /usr/bin/lpq       spooling queue examination program
     /usr/bin/lprm      program to delete jobs from a queue
     /usr/sbin/lpc      program to administer printers and spooling queues
     /var/run/printer   socket on which lpd listens


The file /etc/printcap is a  master  data  base  describing  line
printers  directly  attached  to  a  machine  and, also, printers
accessible across a network. The manual  page  entry  _p_r_i_n_t_c_a_p(5)
provides  the authoritative definition of the format of this data
base, as well as specifying default values  for  important  items
such as the directory in which spooling is performed.  This docu-
ment introduces some of the information that may be placed _p_r_i_n_t_-
_c_a_p.

22..  CCoommmmaannddss

22..11..  llppdd -- lliinnee pprriinntteerr ddaaeemmoonn

     The  program  _l_p_d(8),  usually invoked at boot time from the
/etc/rc file, acts as a master server for coordinating  and  con-
trolling  the  spooling  queues  configured in the printcap file.
When _l_p_d is started it makes a single pass through  the  _p_r_i_n_t_c_a_p
database restarting any printers that have jobs.  In normal oper-
ation _l_p_d listens for service requests on multiple  sockets,  one
in   the  UNIX  domain  (named  ``/var/run/printer'')  for  local
requests, and one in the Internet domain (under  the  ``printer''
service  specification)  for requests for printer access from off
machine; see _s_o_c_k_e_t(2) and _s_e_r_v_i_c_e_s(5) for  more  information  on
sockets  and  service specifications, respectively.  _L_p_d spawns a
copy of itself to process the request; the master daemon  contin-
ues to listen for new requests.

     Clients communicate with _l_p_d using a simple transaction ori-
ented protocol.  Authentication of remote clients is  done  based
on  the  ``privilege  port''  scheme  employed  by  _r_s_h_d(8C)  and
_r_c_m_d(3X).  The following table shows the requests  understood  by
_l_p_d.  In each request the first byte indicates the ``meaning'' of
the request, followed by the name of  the  printer  to  which  it
should  be  applied.  Additional qualifiers may follow, depending
on the request.



















4.3BSD Line Printer Spooler Manual                        SMM:7-3


     Request                                     Interpretation
     -----------------------------------------------------------------------------------------
     ^Aprinter\n                                 check the queue for jobs and print any found
     ^Bprinter\n                                 receive and queue a job from another machine
     ^Cprinter [users ...] [jobs ...]\n          return short list of current queue state
     ^Dprinter [users ...] [jobs ...]\n          return long list of current queue state
     ^Eprinter person [users ...] [jobs ...]\n   remove jobs from a queue



     The _l_p_r(1) command is used by users to enter a print job  in
a local queue and to notify the local _l_p_d that there are new jobs
in the spooling area.  _L_p_d either schedules the job to be printed
locally,  or if printing remotely, attempts to forward the job to
the appropriate machine.  If the printer cannot be opened or  the
destination  machine  is  unreachable, the job will remain queued
until it is possible to complete the work.

22..22..  llppqq -- sshhooww lliinnee pprriinntteerr qquueeuuee

     The _l_p_q(1) program works  recursively  backwards  displaying
the  queue  of the machine with the printer and then the queue(s)
of the machine(s) that lead to it.  _L_p_q has two forms of  output:
in  the  default,  short, format it gives a single line of output
per queued job; in the long format it shows the  list  of  files,
and their sizes, that comprise a job.

22..33..  llpprrmm -- rreemmoovvee jjoobbss ffrroomm aa qquueeuuee

     The  _l_p_r_m(1) command deletes jobs from a spooling queue.  If
necessary, _l_p_r_m will first kill off a running daemon that is ser-
vicing  the  queue  and  restart  it after the required files are
removed.  When removing jobs destined for a remote printer,  _l_p_r_m
acts  similarly to _l_p_q except it first checks locally for jobs to
remove and then tries to remove files in queues off-machine.

22..44..  llppcc -- lliinnee pprriinntteerr ccoonnttrrooll pprrooggrraamm

     The _l_p_c(8) program is used by the  system  administrator  to
control  the operation of the line printer system.  For each line
printer configured in /etc/printcap, _l_p_c may be used to:

+o    disable or enable a printer,

+o    disable or enable a printer's spooling queue,

+o    rearrange the order of jobs in a spooling queue,

+o    find the status of printers, and their  associated  spooling
     queues and printer daemons.













SMM:7-4                        4.3BSD Line Printer Spooler Manual


33..  AAcccceessss ccoonnttrrooll

     The  printer  system  maintains  protected spooling areas so
that users cannot circumvent printer accounting or  remove  files
other  than  their  own.  The strategy used to maintain protected
spooling areas is as follows:

+o  The spooling area is writable only by a _d_a_e_m_o_n user and _d_a_e_m_o_n
   group.

+o  The  _l_p_r  program runs set-user-id to _r_o_o_t and set-group-id to
   group _d_a_e_m_o_n.   The  _r_o_o_t  access  permits  reading  any  file
   required.  Accessibility  is  verified with an _a_c_c_e_s_s(2) call.
   The group ID is used in setting up proper ownership  of  files
   in the spooling area for _l_p_r_m.

+o  Control  files  in a spooling area are made with _d_a_e_m_o_n owner-
   ship and group ownership _d_a_e_m_o_n.  Their mode  is  0660.   This
   insures  control  files are not modified by a user and that no
   user can remove files except through _l_p_r_m.

+o  The spooling programs, _l_p_d, _l_p_q, and _l_p_r_m run  set-user-id  to
   _r_o_o_t  and  set-group-id  to group _d_a_e_m_o_n to access spool files
   and printers.

+o  The printer server, _l_p_d, uses the same verification procedures
   as  _r_s_h_d(8C)  in  authenticating  remote clients.  The host on
   which  a  client  resides  must  be  present   in   the   file
   /etc/hosts.equiv  or  /etc/hosts.lpd  and  the request message
   must come from a reserved port number.

     In practice, none of _l_p_d, _l_p_q, or _l_p_r_m would have to run  as
user  _r_o_o_t  if  remote  spooling were not supported.  In previous
incarnations of the printer system _l_p_d ran set-user-id to _d_a_e_m_o_n,
set-group-id to group _s_p_o_o_l_i_n_g, and _l_p_q and _l_p_r_m ran set-group-id
to group _s_p_o_o_l_i_n_g.

44..  SSeettttiinngg uupp

     The  4.3BSD  release  comes  with  the  necessary   programs
installed  and  with  the default line printer queue created.  If
the system must  be  modified,  the  makefile  in  the  directory
/usr/src/usr.lib/lpr  should  be  used  in  recompiling and rein-
stalling the necessary programs.

     The real work in setting up is to create the  _p_r_i_n_t_c_a_p  file
and any printer filters for printers not supported in the distri-
bution system.

44..11..  CCrreeaattiinngg aa pprriinnttccaapp ffiillee

     The _p_r_i_n_t_c_a_p database  contains  one  or  more  entries  per
printer.   A  printer  should have a separate spooling directory;
otherwise, jobs will be printed on different  printers  depending









4.3BSD Line Printer Spooler Manual                        SMM:7-5


on which printer daemon starts first.  This section describes how
to create entries for printers that do not conform to the default
printer description (an LP-11 style interface to a standard, band
printer).

44..11..11..  PPrriinntteerrss oonn sseerriiaall lliinneess

     When a printer is connected via a serial communication  line
it  must  have  the proper baud rate and terminal modes set.  The
following example  is  for  a  DecWriter  III  printer  connected
locally via a 1200 baud serial line.

     lp|LA-180 DecWriter III:\
          :lp=/dev/lp:br#1200:fs#06320:\
          :tr=\f:of=/usr/lib/lpf:lf=/usr/adm/lpd-errs:

The llpp entry specifies the file name to open for output.  Here it
could be left out since ``/dev/lp'' is the default.  The bbrr entry
sets  the baud rate for the tty line and the ffss entry sets CRMOD,
no parity, and XTABS (see _t_t_y(4)).  The ttrr entry indicates that a
form-feed  should  be printed when the queue empties so the paper
can be torn off without turning the printer off-line and pressing
form  feed.  The ooff entry specifies the filter program _l_p_f should
be used for printing the files; more will be said  about  filters
later.   The  last  entry causes errors to be written to the file
``/usr/adm/lpd-errs'' instead of the console.  Most  errors  from
_l_p_d  are  logged  using  _s_y_s_l_o_g_d(8) and will not be logged in the
specified file.  The filters should use _s_y_s_l_o_g_d to report errors;
only  those  that write to standard error output will end up with
errors in the llff file.  (Occasionally  errors  sent  to  standard
error  output  have not appeared in the log file; the use of _s_y_s_-
_l_o_g_d is highly recommended.)

44..11..22..  RReemmoottee pprriinntteerrss

     Printers that reside on remote hosts should have an empty llpp
entry.  For example, the following printcap entry would send out-
put to the printer named ``lp'' on the machine ``ucbvax''.

     lp|default line printer:\
          :lp=:rm=ucbvax:rp=lp:sd=/var/spool/output/vaxlpd:

The rrmm entry is the name of the remote  machine  to  connect  to;
this name must be a known host name for a machine on the network.
The rrmm entry can also specify the port number of the  _l_p_d  server
on  the remote host with the form ``port@host''.  The rrpp capabil-
ity indicates the name of the printer on the  remote  machine  is
``lp'';  here  it  could  be  left  out since this is the default
value.  The ssdd entry  specifies  ``/var/spool/output/vaxlpd''  as
the   spooling   directory   instead  of  the  default  value  of
``/var/spool/output/lpd''.












SMM:7-6                        4.3BSD Line Printer Spooler Manual


44..22..  OOuuttppuutt ffiilltteerrss

     Filters are used to handle device  dependencies  and  to  do
accounting  functions.   The  output filtering of ooff is used when
accounting is not being done or when all text data must be passed
through  a  filter.  It is not intended to do accounting since it
is started only once, all text files are filtered through it, and
no  provision is made for passing owners' login name, identifying
the beginning and ending of jobs, etc.   The  other  filters  (if
specified) are started for each file printed and do accounting if
there is an aaff entry.  If entries for both ooff and  other  filters
are specified, the output filter is used only to print the banner
page; it is then stopped to allow other  filters  access  to  the
printer.  An example of a printer that requires output filters is
the Benson-Varian.

     va|varian|Benson-Varian:\
          :lp=/dev/va0:sd=/var/spool/output/vad:of=/usr/lib/vpf:\
          :tf=/usr/lib/rvcat:mx#2000:pl#58:px=2112:py=1700:tr=\f:

The ttff entry specifies ``/usr/lib/rvcat'' as  the  filter  to  be
used  in  printing _t_r_o_f_f(1) output.  This filter is needed to set
the device into print mode for text, and plot mode  for  printing
_t_r_o_f_f  files  and raster images (see _v_a(4V)).  Note that the page
length is set to 58 lines by the ppll entry for 8.5"  by  11"  fan-
fold paper.  To enable accounting, the varian entry would be aug-
mented with an aaff filter as shown below.

     va|varian|Benson-Varian:\
          :lp=/dev/va0:sd=/var/spool/output/vad:of=/usr/lib/vpf:\
          :if=/usr/lib/vpf:tf=/usr/lib/rvcat:af=/usr/adm/vaacct:\
          :mx#2000:pl#58:px=2112:py=1700:tr=\f:


44..33..  AAcccceessss CCoonnttrrooll

     Local access to printer queues is  controlled  with  the  rrgg
printcap entry.

          :rg=lprgroup:

Users  must be in the group _l_p_r_g_r_o_u_p to submit jobs to the speci-
fied printer.  The default is to allow all  users  access.   Note
that  once  the files are in the local queue, they can be printed
locally or forwarded to another host depending on the  configura-
tion.

     Remote  access  is controlled by listing the hosts in either
the file /etc/hosts.equiv or /etc/hosts.lpd, one host  per  line.
Note  that _r_s_h(1) and _r_l_o_g_i_n(1) use /etc/hosts.equiv to determine
which hosts are equivalent for allowing logins without passwords.
The  file /etc/hosts.lpd is only used to control which hosts have
line printer access.  Remote access can be further restricted  to
only  allow remote users with accounts on the local host to print









4.3BSD Line Printer Spooler Manual                        SMM:7-7


jobs by using the rrss printcap entry.

          :rs:


55..  OOuuttppuutt ffiilltteerr ssppeecciiffiiccaattiioonnss

     The  filters  supplied  with  4.3BSD  handle  printing   and
accounting  for most common line printers, the Benson-Varian, the
wide (36") and narrow (11") Versatec printer/plotters. For  other
devices  or  accounting  methods, it may be necessary to create a
new filter.

     Filters are spawned by _l_p_d with  their  standard  input  the
data  to  be printed, and standard output the printer.  The stan-
dard error is attached to the llff file for logging errors or  _s_y_s_-
_l_o_g_d  may  be  used for logging errors.  A filter must return a 0
exit code if there were  no  errors,  1  if  the  job  should  be
reprinted,  and  2  if  the job should be thrown away.  When _l_p_r_m
sends a kill signal to the _l_p_d process controlling  printing,  it
sends  a SIGINT signal to all filters and descendents of filters.
This signal can be trapped by filters that  need  to  do  cleanup
operations such as deleting temporary files.

     Arguments  passed  to  a  filter depend on its type.  The ooff
filter is called with the following arguments.

     _f_i_l_t_e_r --wwwidth --lllength

The _w_i_d_t_h and _l_e_n_g_t_h values come from the ppww and  ppll  entries  in
the  printcap  database.   The  iiff filter is passed the following
parameters.

     _f_i_l_t_e_r [--cc] --wwwidth --lllength --iiindent --nn login --jj jobname --hh host accounting_file

The --cc flag is optional, and only supplied when  control  charac-
ters  are  to  be passed uninterpreted to the printer (when using
the --ll option of _l_p_r to print the file).  The --ww and  --ll  parame-
ters are the same as for the ooff filter.  The --nn and --hh parameters
specify the login name and host name of the job owner.  The  last
argument  is  the name of the accounting file from _p_r_i_n_t_c_a_p.  The
--jj parameter is optional and specifies the name of the print  job
if available.

     All other filters are called with the following arguments:

     _f_i_l_t_e_r --xxwidth --yylength --nn login --jj jobname --hh host accounting_file

The  --xx  and  --yy options specify the horizontal and vertical page
size in pixels (from the ppxx and ppyy entries in the printcap file).
The rest of the arguments are the same as for the iiff filter.












SMM:7-8                        4.3BSD Line Printer Spooler Manual


66..  LLiinnee pprriinntteerr AAddmmiinniissttrraattiioonn

     The  _l_p_c  program  provides  local control over line printer
activity.  The major commands and  their  intended  use  will  be
described.    The  command  format  and  remaining  commands  are
described in _l_p_c(8).

aabboorrtt and ssttaarrtt

     _A_b_o_r_t terminates an active spooling daemon on the local host
     immediately  and then disables printing (preventing new dae-
     mons from being started by _l_p_r).  This is normally  used  to
     forcibly  restart  a  hung  line  printer  daemon (i.e., _l_p_q
     reports that there is a daemon present but nothing  is  hap-
     pening).   It  does  not remove any jobs from the queue (use
     the _l_p_r_m  command  instead).   _S_t_a_r_t  enables  printing  and
     requests _l_p_d to start printing jobs.

eennaabbllee and ddiissaabbllee

     _E_n_a_b_l_e  and  _d_i_s_a_b_l_e allow spooling in the local queue to be
     turned on/off.  This will allow/prevent _l_p_r from putting new
     jobs  in  the  spool  queue.  It is frequently convenient to
     turn spooling off while testing  new  line  printer  filters
     since  the  _r_o_o_t  user  can still use _l_p_r to put jobs in the
     queue but no one else can.  The other main use is to prevent
     users  from  putting  jobs  in the queue when the printer is
     expected to be unavailable for a long time.

rreessttaarrtt

     _R_e_s_t_a_r_t allows ordinary users  to  restart  printer  daemons
     when _l_p_q reports that there is no daemon present.

ssttoopp

     _S_t_o_p  halts  a  spooling  daemon  after the current job com-
     pletes; this also disables printing.  This is a clean way to
     shutdown  a printer to do maintenance, etc.  Note that users
     can still enter jobs in a spool queue  while  a  printer  is
     _s_t_o_p_p_e_d.

ttooppqq

     _T_o_p_q places jobs at the top of a printer queue.  This can be
     used to reorder high priority jobs since _l_p_r  only  provides
     first-come-first-serve ordering of jobs.

77..  TTrroouubblleesshhoooottiinngg

     There  are several messages that may be generated by the the
line printer system.  This section categorizes  the  most  common
and  explains  the cause for their generation.  Where the message
implies a failure, directions are given to remedy the problem.









4.3BSD Line Printer Spooler Manual                        SMM:7-9


     In the examples below, the name _p_r_i_n_t_e_r is the name  of  the
printer from the _p_r_i_n_t_c_a_p database.

77..11..  LLPPRR

llpprr:: _p_r_i_n_t_e_r:: uunnkknnoowwnn pprriinntteerr

     The _p_r_i_n_t_e_r was not found in the _p_r_i_n_t_c_a_p database.  Usually
     this is a typing mistake; however, it may indicate a missing
     or incorrect entry in the /etc/printcap file.

llpprr:: _p_r_i_n_t_e_r:: jjoobbss qquueeuueedd,, bbuutt ccaannnnoott ssttaarrtt ddaaeemmoonn..

     The  connection  to  _l_p_d  on the local machine failed.  This
     usually means the printer server started at  boot  time  has
     died or is hung.  Check the local socket /var/run/printer to
     be sure it still exists (if it does not exist, there  is  no
     _l_p_d  process running).  Usually it is enough to get a super-
     user to type the following to restart _l_p_d.

          % /usr/lib/lpd

     You can also check the state of the  master  printer  daemon
     with the following.

          % ps l`cat /var/spool/output/lpd.lock`


     Another possibility is that the _l_p_r program is not set-user-
     id to _r_o_o_t, set-group-id  to  group  _d_a_e_m_o_n.   This  can  be
     checked with

          % ls -lg /usr/bin/lpr


llpprr:: _p_r_i_n_t_e_r:: pprriinntteerr qquueeuuee iiss ddiissaabblleedd

     This means the queue was turned off with

          % lpc disable _p_r_i_n_t_e_r

     to  prevent  _l_p_r  from  putting files in the queue.  This is
     normally done by the system manager when a printer is  going
     to  be down for a long time.  The printer can be turned back
     on by a super-user with _l_p_c.

77..22..  LLPPQQ

wwaaiittiinngg ffoorr _p_r_i_n_t_e_r ttoo bbeeccoommee rreeaaddyy ((oofffflliinnee ??))

     The printer device could not be opened by the daemon.   This
     can  happen for several reasons, the most common is that the
     printer is turned off-line.  This message can also be gener-
     ated  if  the  printer is out of paper, the paper is jammed,









SMM:7-10                       4.3BSD Line Printer Spooler Manual


     etc.  The actual reason is dependent on the meaning of error
     codes  returned  by  system device driver.  Not all printers
     supply enough information to distinguish when a  printer  is
     off-line or having trouble (e.g. a printer connected through
     a serial line).  Another possible cause of this  message  is
     some  other process, such as an output filter, has an exclu-
     sive open on the device.  Your only recourse here is to kill
     off  the  offending  program(s) and restart the printer with
     _l_p_c.

_p_r_i_n_t_e_r iiss rreeaaddyy aanndd pprriinnttiinngg

     The _l_p_q program checks to see if a daemon process exists for
     _p_r_i_n_t_e_r  and  prints the file _s_t_a_t_u_s located in the spooling
     directory.  If the daemon is hung, a super user can use  _l_p_c
     to abort the current daemon and start a new one.

wwaaiittiinngg ffoorr _h_o_s_t ttoo ccoommee uupp

     This  implies  there  is  a  daemon trying to connect to the
     remote machine named _h_o_s_t to send the  files  in  the  local
     queue.   If  the  remote  machine  is  up, _l_p_d on the remote
     machine is probably dead or hung and should be restarted  as
     mentioned for _l_p_r.

sseennddiinngg ttoo _h_o_s_t

     The  files  should be in the process of being transferred to
     the remote _h_o_s_t.  If not, the local daemon should be aborted
     and started with _l_p_c.

WWaarrnniinngg:: _p_r_i_n_t_e_r iiss ddoowwnn

     The printer has been marked as being unavailable with _l_p_c.

WWaarrnniinngg:: nnoo ddaaeemmoonn pprreesseenntt

     The  _l_p_d process overseeing the spooling queue, as specified
     in the ``lock'' file in  that  directory,  does  not  exist.
     This  normally  occurs only when the daemon has unexpectedly
     died.  The error log file for the printer  and  the  _s_y_s_l_o_g_d
     logs  should  be  checked for a diagnostic from the deceased
     process.  To restart an _l_p_d, use

          % lpc restart _p_r_i_n_t_e_r


nnoo ssppaaccee oonn rreemmoottee;; wwaaiittiinngg ffoorr qquueeuuee ttoo ddrraaiinn

     This implies that there is insufficient disk  space  on  the
     remote.   If  the  file is large enough, there will never be
     enough space on the remote (even  after  the  queue  on  the
     remote  is empty). The solution here is to move the spooling
     queue or make more free space on the remote.









4.3BSD Line Printer Spooler Manual                       SMM:7-11


77..33..  LLPPRRMM

llpprrmm:: _p_r_i_n_t_e_r:: ccaannnnoott rreessttaarrtt pprriinntteerr ddaaeemmoonn

     This case is the same as when _l_p_r  prints  that  the  daemon
     cannot be started.

77..44..  LLPPDD

     The  _l_p_d  program can log many different messages using _s_y_s_-
_l_o_g_d(8).  Most of these messages are about files that can not  be
opened and usually imply that the _p_r_i_n_t_c_a_p file or the protection
modes of the files are incorrect.   Files may also be  inaccessi-
ble  if  people manually manipulate the line printer system (i.e.
they bypass the _l_p_r program).

     In addition to messages generated by _l_p_d, any of the filters
that  _l_p_d  spawns  may log messages using _s_y_s_l_o_g_d or to the error
log file (the file specified in the llff entry in _p_r_i_n_t_c_a_p).

77..55..  LLPPCC


ccoouullddnn''tt ssttaarrtt pprriinntteerr

     This case is the same as when _l_p_r reports  that  the  daemon
     cannot be started.

ccaannnnoott eexxaammiinnee ssppooooll ddiirreeccttoorryy

     Error  messages  beginning  with  ``cannot ...'' are usually
     because of incorrect ownership or  protection  mode  of  the
     lock file, spooling directory or the _l_p_c program.



























