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 installation procedure for the line printer spool- ing 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 ini- tialization 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 follow- ing 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/lib/lpd line printer daemon, does all the real work /usr/ucb/lpr program to enter a job in a printer queue /usr/ucb/lpq spooling queue examination program /usr/ucb/lprm program to delete jobs from a queue /etc/lpc program to administer printers and spooling queues /dev/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 document 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 controlling the spooling queues configured in the print- cap 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 operation _l_p_d listens for service requests on multiple sockets, one in the UNIX domain (named ``/dev/printer'') for local requests, and one in the Inter- net 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 continues to lis- ten for new requests. Clients communicate with _l_p_d using a simple transaction oriented 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 under- stood 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 quali- fiers 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 display- ing 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 servicing 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 ownership 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 pro- cedures 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 direc- tory /usr/src/usr.lib/lpr should be used in recompiling and reinstalling 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 distribution 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 4.3BSD Line Printer Spooler Manual SMM:7-5 directory; otherwise, jobs will be printed on different printers depending 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 out- put 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 output to the printer named ``lp'' on the machine ``ucbvax''. lp|default line printer:\ :lp=:rm=ucbvax:rp=lp:sd=/usr/spool/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 rrpp capability 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 ``/usr/spool/vaxlpd'' as the spooling directory instead of the default value of ``/usr/spool/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=/usr/spool/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 augmented with an aaff filter as shown below. va|varian|Benson-Varian:\ :lp=/dev/va0:sd=/usr/spool/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 specified 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 configuration. 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 4.3BSD Line Printer Spooler Manual SMM:7-7 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 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 standard 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 con- trolling 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 fol- lowing parameters. _f_i_l_t_e_r [--cc] --wwwidth --lllength --iiindent --nn login --hh host accounting_file The --cc flag is optional, and only supplied when control characters 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 parameters 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. All other filters are called with the following argu- ments: _f_i_l_t_e_r --xxwidth --yylength --nn login --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 SMM:7-8 4.3BSD Line Printer Spooler Manual printcap file). The rest of the arguments are the same as for the iiff filter. 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 com- mands 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 daemons from being started by _l_p_r). This is nor- mally used to forcibly restart a hung line printer dae- mon (i.e., _l_p_q reports that there is a daemon present but nothing is happening). 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 unavail- able for a long time. rreessttaarrtt _R_e_s_t_a_r_t allows ordinary users to restart printer dae- mons 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. 4.3BSD Line Printer Spooler Manual SMM:7-9 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 rem- edy the problem. 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 indi- cate 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 /dev/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 dae- mon with the following. % ps l`cat /usr/spool/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/ucb/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 SMM:7-10 4.3BSD Line Printer Spooler Manual 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 generated if the printer is out of paper, the paper is jammed, 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 trou- ble (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 exclusive 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 spec- ified 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 4.3BSD Line Printer Spooler Manual SMM:7-11 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. 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 dae- mon 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 inaccessible 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 dae- mon cannot be started. ccaannnnoott eexxaammiinnee ssppooooll ddiirreeccttoorryy Error messages beginning with ``cannot ...'' are usu- ally because of incorrect ownership or protection mode of the lock file, spooling directory or the _l_p_c pro- gram.