1.TL 2A Guide to the Lp 3Printer Spooler 4.AU 5Paul Glick 6pg@plan9.att.com 7.AB 8.PP 9.I Lp 10is a collection of programs used to provide an easy-to-use 11interface for printing a variety of document types on a variety 12of printers. 13.I Lp 14is the glue that connects various document language 15translators and printer communication programs together so that 16the users may have a consistent view of printers. 17Most of the glue 18is shell script, which can be easily modified. 19The user need not 20specify options to get sensible output in most cases. 21.I Lp 22is described here 23so that others may make additions and changes. 24.AE 25\" .2C 26.NH 27Introduction 28.PP 29.I Lp 30is used to format and print data on a variety of output devices. 31The need for 32.I lp 33was rooted in the inability of other printer spoolers to do simple 34tasks without a great deal of user specification of options. 35At the time 36.I lp 37was written, there were several printer 38languages, such as ImPress and PostScript, and 39an internally developed printer that would accept 40.I troff 41output. 42Now, all our printers take PostScript, 43but printers that use HPCL and HPGL abound and 44support for those printers may be added easily. 45A great deal of what underlies 46.I lp 47is taken from BSD's 48.I lpr 49and System V's 50.I lp . 51The important features of this system are that most of the programs 52are easily modified shell scripts and the user need not 53learn to use the large amount of underlying software developed by others. 54.I Lp 55runs under Plan 9 and several flavors of 56UNIX. 57This document deals with 58.I lp 59as it relates to Plan 9. 60.I Lp 61was developed using both Datakit and Ethernet to transport data between machines. 62Now only the Ethernet transport mechanism remains. 63.PP 64Text, graphics, and formatted text files are appropriately processed and 65placed into a spool directory from which they are taken to be printed by a daemon process. 66Additional functions include checking the status of a printer queue 67and removing jobs from the printer queue. 68.PP 69All the shell scripts (see 70.I rc (1)) 71associated with 72.I lp 73reside in the spool directory 74.CW /sys/lib/lp 75except for the 76.I lp 77command itself, which resides in 78.CW /rc/bin . 79Commands related to 80.I lp 81that are not shell scripts can most often be found 82in 83.CW /$cputype/bin/aux . 84The directory where all the 85.I lp 86scripts reside is defined within 87.I lp 88by the shell variable 89.CW LPLIB . 90In the remainder of this document, file names will be specified 91with this shell variable as their root. 92.NH 93Usage 94.PP 95.I Lp 96requires an output device to be specified 97before it will process input. 98This can be done in any of three ways described here. 99.IP 1) 100The file 101.CW $LPLIB/defdevice 102may contain the name of a default output device. 103This may not be practical for environments where 104there are many printers. 105.IP 2) 106The user's environment variable 107.CW LPDEST 108may be set to the name of the device to be used. 109This is often a more practical solution when there are several printers 110available. 111This overrides a 112.CW defdevice 113specification. 114.IP 3) 115The 116.CW -d 117.I printer 118option to the 119.I lp 120command specifies 121.I printer 122as the device to which output should be directed, overriding the 123previous two specifications. 124.PP 125.ti 0 126If 127.I printer 128is 129.CW ? , 130a list of printers and other information in the 131.CW devices 132file is printed, as shown in Figure 1. 133Quote the question mark to prevent it from being 134interpreted by the shell language as a metacharacter. 135\" .1C 136.KF 137.P1 138% lp -d'?' 139device location host class 140fn 2C-501 helix post/2+600dpi+duplex 141pcclone - - post+nohead 142peacock 2C-501 cetus post/2+300dpi+nohead+color 143ps83 st8_fl3 rice post+300dpi+reverse 144psu 2C-501 cetus post/2+1200dpi 145 . 146 . 147 . 148% 149.P2 150.ce 151.I "Figure 1. Sample listing of installed printers" 152.KE 153.PP 154Normally, 155.I lp 156uses the 157.CW file 158command to figure out what type of input it is receiving. 159This is done within the 160.CW generic 161process which is discussed later in this paper in the 162.B "Process directory" 163section. 164To select a specific input processor the 165\f(CW-p\fP\fIprocess\fP 166option is used where 167.I process 168is one of the shell scripts in the 169.CW process 170directory. 171.LP 172Troff 173output can be printed, in this case, on printer 174.I fn 175with 176.P1 177% troff -ms lp.ms | lp -dfn 178.P2 179.LP 180A file can be converted to PostScript using the pseudo-printer 181.CW stdout : 182.P1 183% troff -ms lp.ms | lp -dstdout > lp.ps 184.P2 185LaTeX (and analogously TeX) 186documents are printed in two steps: 187.P1 188% latex lp.tex 189 . 190 . 191% lp lp.dvi 192 . 193 . 194% 195.P2 196LaTeX 197produces a `.dvi' file and 198does not permit the use of a pipe 199connection to the standard input of 200.I lp . 201To look at the status and queue of a device, use 202.CW -q : 203.P1 204% lp -dpsu -q 205daemon status: 206: 67.17% sent 207printer status: 208%%[ status: busy; source: lpd ]%% 209 210queue on cetus: 211job user try size 212rice29436.1 pg 0 17454 213slocum17565.1 ches 1 49995 214% 215.P2 216This command can print the status and queue of the local 217and remote hosts. 218Administrators should be advised that working in an environment where the 219.I lp 220spool directory is shared among the local and remote hosts, 221no spooling should be done on the local hosts. 222The format of the status and queue printout is up to the administrator. 223The job started above can be killed with 224.CW -k : 225.P1 226$ lp -dpsu -k rice29436.1 227rice29436.1 removed from psu queue on cetus 228.P2 229.NH 230Options 231.PP 232There are options available to modify the way in which a job is handled. 233It is the job of the 234.I lp 235programs to convert the option settings so they may be used by each of the 236different translation and interface programs. 237Not all options are applicable to all printer environments. 238Table 1 lists the standard 239.I lp 240options, the shell variable settings, and description of the options. 241\" .1C 242.KF 243.sp 244.in 0 245.TS 246center; 247c | c s s | c 248c | c c c | c 249lfCWp-2 | lfCWp-2 cfCWp-2 cfCWp-2 | lp-2w(3i). 250= 251option shell variable action 252\^ name default set \^ 253_ 254-D DEBUG N 1 turn on debugging mode. 255_ 256-H NOHEADER N 1 suppress header page. 257_ 258-L LAND N 1 make long page dimension horizontal. 259_ 260-M \fImach\fP LPMACHID N \fImach\fP set the source machine name. 261_ 262-Q QONLY N 1 do not execute daemon; for debugging. 263_ 264-c \fIn\fP COPIES N \fIn\fP number of copies to be printed. 265_ 266-d \fIprinter\fP LPDEST U \fIprinter\fP set job destination; override other settings. 267_ 268-f \fIfont.pt\fP FONT N \fIfont\fP set font style and point size for printing. 269 POINT N \fIpt\fP 270_ 271-i \fIn\fP IBIN N \fIn\fP T{ 272select input paper tray options. 273The argument given is dependent on the printer type. 274A number can be given to select a particular tray and/or 275.CW simplex 276or 277.CW duplex 278may be used to get single or double sided output, where 279applicable. 280Multiple options should be separated by commas. 281T} 282_ 283-k KILLFLAG 0 1 T{ 284take non-option arguments as job numbers to be removed from queue. 285T} 286_ 287-l \fIn\fP LINES N \fIn\fP T{ 288for printed data, the number of lines per logical page. 289T} 290_ 291-m \fIf\fP MAG N \fIf\fP T{ 292magnify the image by a factor \fIf\fP. 293The factor should be a positive real number. 294T} 295_ 296-n \fIn\fP NPAG N \fIn\fP T{ 297put \fIn\fP logical pages on a single physical page. 298A simple algorithm is used to pack the pages. 299T} 300_ 301-o \fIlist\fP OLIST N \fIlist\fP T{ 302print only those pages specified in the list. 303The list may be a sequence of numbers or ranges separated by commas. 304A range is a pair of numbers separated by a hyphen. 305T} 306_ 307-p \fIproc\fP LPPROC L \fIproc\fP T{ 308use the preprocessor \fIproc\fP instead of the preprocessor given 309in the 310.CW devices 311file for this printer. 312T} 313_ 314-q LPQ N 1 T{ 315print the status and queue. 316T} 317_ 318-r REVERSE L 1 T{ 319this toggles the 320.CW REVERSE 321flag, changing whether or not page reversal should occur in preprocessing. 322Page reversal is needed if a printer delivers pages face up. 323The keyword 324.CW reverse 325can be placed in the 326.I lpclass 327field of the 328.CW devices 329file. 330If a document has already been processed this flag has no effect. 331T} 332_ 333-u \fIuser\fP LPUSERID U \fIuser\fP T{ 334change the user id that appears on the cover page. 335T} 336_ 337-x \fIoffset\fP XOFF N \fIoffset\fP T{ 338move the image \fIoffset\fP inches to the right. 339A negative \fIoffset\fP will move the image to the left. 340The \fIoffset\fP may be any reasonable real number. 341T} 342_ 343-y \fIoffset\fP YOFF N \fIoffset\fP T{ 344same as for 345.CW -x 346except a positive offset will move the image down. 347T} 348_ 349.T& 350l l cp-2 lp-2 s 351l l cfCWp-2 lp-2 s. 352.vs -2p 353 354 default setting definition 355 N set to the null string (`') initially in \fIlp\fP. 356 L set from printer entry in \f(CW\\s-\\n(XPdevices\\s+\\n(XP\fP file. 357 U set from the user's environment. 358.vs +2p 359.TE 360.sp 361.ce 362.I "Table 1. Lp Option List" 363.sp 364.ll \\n(LLu 365.KE 366\" .2C 367.NH 368Devices file 369.PP 370The 371.CW devices 372file is found in the spool directory. 373Each line in the file is composed of 12 fields, separated 374by tabs or spaces, that describe the attributes 375of the printer and how it should be serviced. 376Within the 377.CW lp 378command, a shell variable is set for each attribute; 379the following list describes them: 380.IP "\f(CW\s-\\n(XPLPDEST\s+\\n(XP\fP " 12 381is the name of the device as given to 382.I lp 383with the 384.CW -d 385option 386or as specified by the shell environment variable 387.CW LPDEST 388or as specified by 389the file 390.CW $LPLIB/defdevice . 391This name is used in creating directories and log files that are associated with 392the printers operation. 393.IP "\f(CW\s-\\n(XPLOC\s+\\n(XP\fP " 394just describes where the printer is physically located. 395.IP "\f(CW\s-\\n(XPDEST_HOST\s+\\n(XP\fP " 396is the host from which the files are printed. 397Files may be spooled on other machines before being transferred to the 398destination host. 399.IP "\f(CW\s-\\n(XPOUT_DEV\s+\\n(XP\fP " 400is the physical device name or network address needed by the printer daemon 401to connect to the printer. 402This field depends on the requirements of the daemon and may contain a `\(en' 403if not required. 404.IP "\f(CW\s-\\n(XPSPEED\s+\\n(XP\fP " 405is the baud rate setting for the port. 406This field depends on the requirements of the daemon and may contain a `\(en' 407if not required. 408.IP "\f(CW\s-\\n(XPLPCLASS\s+\\n(XP\fP " 409is used to encode minor printer differences. 410The keyword 411.CW reverse 412is used by some of the preprocessors 413to reverse the order the pages are printed to accommodate different output 414trays (either face up or face down). 415The keyword 416.CW nohead 417is used to suppress the header page. 418This is used for special and color printers. 419The keyword 420.CW duplex 421is used to coax double sided output from duplex printers. 422.IP "\f(CW\s-\\n(XPLPPROC\s+\\n(XP\fP " 423is the command from the 424.CW LPLIB/process 425directory to be used to convert input to a format 426that will be accepted by the device. 427The preprocessor is invoked by the spooler. 428.IP "\f(CW\s-\\n(XPSPOOLER\s+\\n(XP\fP " 429is the command from the 430.CW LPLIB/spooler 431directory which will select files using the 432.CW SCHED 433command and invoke the 434.CW LPPROC 435command, putting its output 436into the remote spool directory. 437The output is sent directly to the spool directory on the 438destination machine to avoid conflicts when client and 439server machines share spool directories. 440.IP "\f(CW\s-\\n(XPSTAT\s+\\n(XP\fP " 441is the command from the 442.CW LPLIB/stat 443directory that prints the status of the device and the list of jobs 444waiting on the queue for the device. 445The status information depends on what is available from the printer 446and interface software. 447The queue information should be changed to show information 448useful in tracking down problems. 449The 450.CW SCHED 451command is used to show the jobs in the order 452in which they will be printed. 453.IP "\f(CW\s-\\n(XPKILL\s+\\n(XP\fP " 454is the command from the 455.CW LPLIB/kill 456that removes jobs from the queue. 457The jobs to be removed are given as arguments to the 458.I lp 459command. 460When possible, it should also abort the currently running job 461if it has to be killed. 462.IP "\f(CW\s-\\n(XPDAEMON\s+\\n(XP\fP " 463is the command from the 464.CW LPLIB/daemon 465that is meant to run asynchronously to remove 466jobs from the queue. 467Jobs may either be passed on to another host or sent to the 468printing device. 469.I Lp 470always tries to start a daemon process when one is specified. 471.IP "\f(CW\s-\\n(XPSCHED\s+\\n(XP\fP " 472is the command from the 473.CW LPLIB/sched 474that is used to present the job names to the 475daemon and stat programs 476in some order, e.g., first-in-first-out, smallest first. 477.NH 478Support programs 479.PP 480The following sections describe the basic functions of the programs 481that are found in the subdirectories of 482.CW $LPLIB . 483The programs in a specific directory vary with the 484type of output device or networks that have to be used. 485.NH 2 486Process directory 487.PP 488The 489.CW generic 490preprocessor 491is the default preprocessor for most printers. 492It uses the 493.I file (1) 494command to determine the format of the input file. 495The appropriate preprocessor is then selected to transform the 496file to a format suitable for the printer. 497.PP 498Here is a list of the preprocessors and 499a description of their function. 500.sp 501.IP \f(CWdvipost\fP 14 502Converts TeX or LaTeX output (\f(CW.dvi\fP files) to PostScript 503.IP \f(CWppost\fP 504Converts UTF text to PostScript. 505The default font is Courier with Lucida fonts filling in 506the remainder of the (available) Unicode character space. 507.IP \f(CWtr2post\fP 508Converts (device independent) troff output for the device type 509.CW utf . 510See 511.CW /sys/lib/troff/font/devutf 512directory for troff font width table descriptions. 513See also the 514.CW /sys/lib/postscript/troff 515directory for mappings of 516troff UTF character space to PostScript 517font space. 518.IP \f(CWp9bitpost\fP 519Converts Plan 9 bitmaps (see 520.I bitfile (9.6)) 521to PostScript. 522.IP \f(CWg3post\fP 523Converts fax (CCITT-G31 format) to PostScript. 524.IP \f(CWhpost\fP 525Does header page processing and page reversal processing, if 526necessary. 527Page reversal is done here so the header page always comes 528out at the beginning of the job. 529Header page processing is very location-dependent. 530.NH 2 531Spool directory 532.PP 533The 534.CW generic 535spooler is responsible for executing the preprocessor 536and directing its output to a file in the printer's queue. 537An additional file is created containing information such as the system name, 538user id, job number, and number of times this job was attempted. 539.PP 540Certain printer handling programs do not require separate 541preprocessing and spooling. 542For such circumstances a 543.CW nospool 544spooler is available that just executes the preprocessing program. 545The processing and spooling functions are assumed by this program and the output is sent to 546.CW OUT_DEV 547or standard output if 548.CW OUT_DEV 549is '-'. 550.PP 551The 552.CW pcclone 553spooler is used to send print jobs directly to a printer connected 554to a 386 compatible printer port (See 555.I lpt (3)). 556.NH 2 557Stat directory 558.PP 559The function of the shell scripts in the 560.CW stat 561directory is to present status information about the 562printer and its queue. 563When necessary, the 564.CW stat 565scripts may be designed 566to return information about the local queue as well as the remote queue. 567This is not done on Plan 9 because many systems share the same queue directory. 568The scheduler is used to print the queue in the order in which the jobs 569will be executed. 570.NH 2 571Kill directory 572.PP 573The 574.CW kill 575scripts receive command line arguments passed to them by 576.I lp 577and remove the job and id files which match the arguments 578for the particular queue. 579When a job is killed, the generic kill procedure: 580.IP 1) 581kills the daemon for this queue if the job being killed 582is first in the queue, 583.IP 2) 584removes the files associated with the job from the queue, 585.IP 3) 586attempts to restart the daemon. 587.NH 2 588Daemon directory 589.PP 590The 591.CW daemon 592shell scripts are the last to be invoked by 593.I lp 594if the 595.CW -Q 596option has not been given. 597The daemon process is executed asynchronously 598with its standard output and standard error appended to 599the printer log file. 600The log file is described in a subsequent section. 601Because the daemon runs asynchronously, it must 602catch signals that could cause it to terminate abnormally. 603The daemon first checks to see that it is the only one running 604by using the 605.CW LOCK 606program found in the 607.CW /$cputype/bin/aux 608directory. 609The 610.CW LOCK 611command creates a 612.CW LOCK 613file in the printer's queue directory. 614The daemon then executes the scheduler to obtain the name of the 615next job on the queue. 616.PP 617The processing of jobs may entail transfer to another host 618or transmission to a printer. 619The details of this are specific to the individual daemons. 620If a job is processed without error, it is removed from the queue. 621If a job does not succeed, the associated files may be 622moved to a printer specific directory in 623.CW $LPLIB/prob . 624In either case, the daemon can make an entry in the printer's 625log file. 626Before exiting, the daemon should clean up lock files by calling 627.CW UNLOCK . 628.PP 629Several non-standard daemon programs have been designed 630to suit various requirements and whims. 631One such program announces job completion and empty paper trays 632by causing icons to appear in peoples' 633.CW seemail 634window. 635Another, using a voice synthesizer, makes verbal announcements. 636Other daemons may be designed to taste. 637.NH 2 638Sched directory 639.PP 640The scheduler must decide which job files should be executed and 641in what order. 642The most commonly used scheduler program is 643.CW FIFO , 644which looks like this: 645.P1 646ls -tr $* | sed -n -e 's/.* *//' \e 647 -e '/^[0-9][0-9]*\.[1-9][0-9]*$/p' 648.P2 649This lists all the job files in this printer's queue in modification 650time order. 651Jobs entering the queue have a dot (.) prefixed to their name 652to keep the scheduler from selecting them before they are complete. 653.NH 654When Thing Go Wrong 655.PP 656There are four directories where 657.I lp 658writes files. 659On the Plan 9 release these directories may be found 660in the directory 661.CW /n/bootesother/lp . 662The four directories are 663.CW log , 664.CW prob , 665.CW queue , 666and 667.CW tmp . 668.I Lp 669binds (see 670.I bind (1)) 671the first three into the directory 672.CW /sys/lib/lp 673for its processes and their children. 674The 675.CW tmp 676directory is bound to the 677.CW /tmp 678directory so that the lp daemons, which run as user `none', 679may write into this directory. 680.NH 2 681Log directory 682.PP 683The log files for a particular 684.I printer 685appear in a subdirectory of the spool directory 686\f(CWlog\fP/\fIprinter\fP. 687There are currently two types of log files. 688One is for the daemon to log errors and successful completions 689of jobs. 690These are named 691.I printer.day 692where 693.I day 694is the three letter abbreviation for the day of the week. 695These are overwritten once a week to avoid the need for regular 696cleanup. 697The other type of log file contains the status of the printer and 698is written by the program that communicates with the printer itself. 699These are named 700\fIprinter\fP.\f(CWst\fP. 701These are overwritten with each new job and are saved in the 702.CW $LPLIB/prob 703directory along with the job under circumstances described below. 704When a printer does not appear to be functioning these files are the 705place to look first. 706.NH 2 707Prob directory 708.PP 709When a job fails to produce output, 710the log files should be checked for any obvious problems. 711If none can be found, a directory with full read and write permissions 712should be created with the name of the printer in the 713.CW $LPLIB/prob 714directory. 715Subsequent failure of a job will cause the daemon to leave a 716copy of the job and the printer communication log in 717\f(CW$LPLIB/prob/\fP\fIprinter\fP 718directory. 719It is common for a printer to enter states from which 720it cannot be rescued except by manually cycling the power on the printer. 721After this is done the print daemon should recover by itself 722(give it a minute). 723If it does not recover, remove the 724.CW LOCK 725file from the printer's spool directory to kill the daemon. 726The daemon will have to be restarted by sending another job 727to the printer. 728For PostScript printers just use: 729.P1 730echo '%!PS' | lp 731.P2 732.NH 2 733Repairing Stuck Daemons 734.PP 735There are conditions that occur which are not handled 736by the daemons. 737One such problem can only be described as the printer entering a 738comatose state. 739The printer does not respond to any messages sent to it. 740The daemon should recover from the reset and an error message 741will appear in the log files. 742If all else fails, one can kill the first job in the queue 743or remove the 744.CW LOCK 745file from the queue directory. 746This will kill the daemon, which will have to be restarted. 747.NH 748Interprocessor Communication 749.PP 750A Plan 9 CPU server can be set up as a printer's spooling host. 751That is, the machine where jobs are spooled and from which those jobs 752are sent directly to the printer. 753To do this, the CPU must listen on TCP port 515 which is the well known 754port for the BSD line printer daemon. 755The file 756.CW /rc/bin/service/tcp515 757is executed when a call comes in on that port. 758The Plan 9 759.CW lpdaemon 760will accept jobs sent from BSD systems. 761The 762.CW /$cputype/bin/aux/lpdaemon 763command is executed from the service call and it accepts print jobs, requests for status, 764and requests to kill jobs. 765The command 766.CW /$cputype/bin/aux/lpsend 767is used to send jobs 768to other Plan 9 machines and is usually called from 769within a spooler or daemon script. 770.NH 771Acknowledgements 772.PP 773Special thanks to Rich Drechsler for supplying and maintaining most of 774the PostScript translation and interface programs, 775without which 776.I lp 777would be an empty shell. 778Tomas Rokicki provided the 779TeX 780to PostScript 781translation program. 782.NH 783References 784.LP 785[Camp86] Ralph Campbell, 786``4.3BSD Line Printer Spooler Manual'', UNIX System Manager's Manual, 787May, 1986, Berkeley, CA 788.br 789[RFC1179] Request for Comments: 1179, Line Printer Daemon Protocol, Aug 1990 790.br 791[Sys5] System V manual, date unknown 792