13.6 LPRng

The LPRng package is an enhanced version of the BSD LPD print spooling system. It was initially developed in the early 1990s by PatrickPowell, first as a rewrite of the LPD spooler that was free of the licensing problems of the original code. Very quickly, however, it began to develop beyond the original LPD capabilities, and it is now a feature-rich version of the original. LPRng is available for virtually any Unix system. The home page for the project is http://www.lprng.com.



Using LPRng does require knowledge of the standard BSD printing subsystem, so you'll need to become familiar with it if your previous experience is mostly with the System V and/or AIX version.

LPRng provides the usual BSD-style user commands: lpr, lpq, and lprm. In addition, it provides versions of lp, lpstat, and cancel for compatibility. It uses the conventional top-level spool directory, /var/spool/lpd.

The LPRng version of lpr is quite a bit smarter than the standard version. It is capable of submitting print jobs directly to a remote system, so there is no longer any need to run the lpd daemon on hosts that are not also print servers themselves (eliminating its modest system load).

Here is an lpr example, which spools a print job directly to the matisse queue on system painters:

$ lpr -Pmatisse@painters files

Another nice feature of LPRng is that lpd may optionally be run as the daemon user rather than root.

Installing LPRng is straightforward and well documented in both the LPRng-HOWTO document and in the Network Printing book mentioned earlier, so I'll simply outline the steps here:

  • Disable all queues, wait for any current jobs to finish, and stop the current print daemon.

  • Back up all current print subsystem components: configuration files, command binaries, and so on.

  • Rename or remove the old printing items.

  • Install the LPRng package (building the software from source code in most cases). If you want to run a less privileged lpd server, uncomment the -- disable-setuid setting in the configure.custom script and run that rather than the usual configure script.

  • Modify system startup scripts to support LPRng.

  • Configure printers and queues within the new printing subsystem.

  • Verify the new configuration with the package's checkpc -f command, which verifies printcap file entries, creates any needed spool directories, log files, accounting files, and the like.

  • Start the spool daemon, and test everything thoroughly.

  • Give users access to the print queues.

The LPRng package provides scripts for some operating systems, which can accomplish some of these tasks. They have names of the form preremove.*.sh (to shut down the printing subsystem before removing it), preinstall.*.sh (remove old printing system components), postremove.*.sh (performs actions needed after the old printing system is removed), and postinstall.*.sh (runs after the LPRng software is built and installed; sets up initial configuration files, spooling directories and the like). The middle component of each script name is the operating system name: e.g., solaris, linux, etc. Check the LPRng package directory and the documentation for the scripts applicable to your systems.

13.6.1 Enhancements to the lpc Command

The LPRng version of lpc provides many new subcommands. The most important are summarized in Table 13-6.

Table 13-6. LPRng enhancements to the lpc command



hold queue [ids]

Places the specified job or all jobs in the queue into a hold state, preventing them from printing.

release queue [ids]

Allow the specified held print job(s) to print.

holdall queue

Place all new jobs entering the queue into the held state. Use noholdall to terminate this behavior (held jobs will still need to be explicitly released).

move old-queue ids new-queue

Transfer the specified print jobs between queues.

redirect old-queue new-queue

Redirect jobs spooled to the old queue to the new queue. Specify off for the latter to turn off redirection.

redo queue [id]

Reprint the specified job.

kill queue

Equivalent to abort plus start: kill the current job, and then restart the queue.

active printer[@host]

Determine whether the specified spool daemon is active or not.

reread printer[@host]

Forces the specified spool daemon to reread its configuration files.

class queue class-list

Limit printing from the specified queue to jobs in the specified class(es), where class is usually a comma-separated list of one or more class letters (see below). The keyword off removes any current class restrictions in effect.[8]

[8] This parameter may also be used for pattern matching against print job characteristics (see the lpc manual page for details).

In most cases, you can substitute the keyword all for a queue name in these lpc subcommands to apply the command to all print queues. Print classes and job priorities

LPRng implements a very simple print job priority scheme. It is combined with its support for print job classes: print jobs have a shared set of characteristics that require specific special handling and/or printer capabilities. The most common use for classes is for jobs requiring special paper.

A user can place a job into a specific class when submitting it using the -C option:

$ lpr -Ccheck -Plaser2 January

This job is placed into the class check on printer laser2.

The uppercased first letter of the class name is also used as the in-queue priority for the job. Priorities levels run from A (high) to Z. Thus, the preceding job would be assigned a priority level of C. The default value for jobs not specifying a specific class is class and priority level A.

By default, a print queue allows jobs of any class to print, printing them in accord with the priority scheme. To limit printing to a specific class, use an lpc command like this one:

# lpc class laser check

This will allow only jobs in class check to print; all others will be held. To allow any job to print, use this command:

# lpc class laser off

Using classes can be a bit tricky. For example, if you alternate between printing checks and regular output on a printer, you probably don't want to turn off class check after all the checks are printed. Rather, you want check jobs to be held until the proper paper is again in place in the printer. In this case, the following command will be more effective:

# lpc class laser A

This sets the allowed class to class A (the default), so jobs spooled in class check will be held as desired.

13.6.2 Configuring LPRng

LPRng uses three configuration files (stored in /etc): printcap, lpd.conf , and lpd.perms , which hold queue configuration, global spooler configuration and printer access rules, respectively. The first of these is a modified version of the standard LPD printcap file. It uses a relaxed syntax: all fields use an equal sign to assign values rather than having datatype-specific assignment characters (although the form name@ is still used to turn off Boolean flags), multiple line entries do not require final backslash characters, and no terminal colon is needed to designate field boundaries.

Here are two simple entries from printcap:

hp:                                       Example local printer.   :lp=/dev/lp0   :cm=HP Laser Jet printer                Description for lpq command.   :lf=/var/log/lpd.log   :af=/var/adm/pacct   :filter=/usr/local/lib/filters/ifhp   :tc=.common                             Include the .common section. laser:                                    Example remote printer.   :lp=painters@matisse   :tc=.common                             Include the .common section. .common:                                  Named group of items.   :sd=/var/spool/lpd/%P   :mx=0

The first entry is for a local printer named hp on the first parallel port. This printcap entry specifies a description for the printer, the name of its log and accounting files, and a filter with which to process jobs. The final field, tc, provides an "include" feature within printcap entries. It takes a list of names as its argument. In this case, the field says to include the settings in the printcap entry called .common within the current entry. Thus, it has the effect of removing any length limits on print jobs to printer hp and of specifying its spool directory as /var/spool/lpd/hp.

The second printcap entry creates a queue for a remote printer, matisse on host painters, which also has no job length limits and uses the spool directory /var/spool/lpd/laser. The last two items are again set using the tc include field.

The LPRng printcap file allows for variable expansion within printcap entries. We saw an example of this in the sd field in the preceding example. The following variables are supported:


Printer name


Queue name


Simple hostname


Fully-qualified hostname


Remote print queue name


Remote computer hostname


Current date

We will now go on to consider additional LPRng features and the printcap settings that support them. Separate client and server entries

By default, printcap entries apply both to spooling system clients user programs like lpr and servers the lpd daemon. However, you can specify that an entry apply only to one of these contexts, as in these example entries:

laser:server               Entry applies to the lpd daemon.   :lp=/dev/lp0 laser:                     Entry applies to client programs.   :lp=matisse@painters

The first entry defines the printer laser as the device on the first parallel port. The server field indicates that the entry is active only when lpd is using the printcap file (and not when it is accessed by programs like lpr). The second entry defines the printer laser for client programs as a remote printer (matisse on painters). Clients will be able to send jobs directly to this remote printer.

In this next example, clients are required to use the local print daemon in order to print to the printer laser2:

laser2:force_localhost     Force clients to use the local server. laser2:server   :lp=/dev/lp0   :sd=/var/spool/lpd/%P

The force_localhost setting (a Boolean, which is off by default) tells clients accessing this printcap entry to funnel jobs through the local lpd server process. Using a common printcap file for many hosts

One of LPRng's most powerful capabilities is the built-in features for constructing a single central printcap file which can be copied to or shared among many hosts. This flexibility comes from the on setting (for "on host"). Here is an example:

laser:   :oh=*.ahania.com,!astarte.ahania.com   :lp=/dev/lp0

This entry defines a printer named laser on every host in the domain ahania.com except astarte. The printer will always be located on the first parallel port.

The following entry will define a printer named color on every host in the 10.0.0 subnet. For most hosts, the printer points to the color queue on, while for itself, it points to the device on the first parallel port.

color:   :oh=,!    Host specification by IP address.   :lp=%P@   :tc=.common color:   :oh=   :lp=/dev/lp0   ...

The %P construct in the first entry's lp setting is not really necessary here, but it would be useful if this setting occurred in a named group of settings, as in this example:

color:tc=.common laser:tc=.common draft:tc=.common .common:   :oh=*.ahania.com,!astarte.ahania.com   :lp=%P@astarte.ahania.com

These entries define the printers color, laser, and draft on every host in ahania.com except astarte as the corresponding queue on astarte (which are defined elsewhere in the printcap file). Special-purpose queues

In this section, we examine how to set up queues for several more complex printing scenarios. Bounce queues

Here is a printcap entry for a simple store-and-forward queue (as we've seen before):

laser:server   :lp=matisse@painters   :sd=/var/spool/lpd/%P

The queue laser collects jobs and sends them on to the queue matisse on host painters as is. However, it is sometimes useful to process the jobs locally before sending them on to be printed. This is accomplished via a bounce queue, as in this example:

blots:server   :sd=/var/spool/lpd/%P   :filter=path and arguments   :bq_format=l                   Binary jobs will be sent on.   :bq=picasso@painters

This queue named blots accepts jobs, runs them through program specified in the filter setting, and then sends them to queue picasso on host painters for printing. Printer pools

LPRng allows you create aprinter pool: a queue that feeds several printing devices, as in this example:

scribes:server   :sd=/var/spool/lpd/%P   :sv=lp1,lp2,lp3

Here, the queue scribes sends jobs to queues lp1, lp2, and lp3 (which must be defined elsewhere in the printcap file), as each queue becomes free (which, of course, occurs when the associated device is free). This mechanism provides a very simple form of load balancing.

Here is part of the printcap entry for lp1:

lp1:   :sd=/var/spool/lpd/%P   :ss=scribes

The ss setting specifies the controlling queue for this printer. Note that it does not prevent jobs from being sent directly to queue lp1; the only effect of this setting seems to be to make queue status listings more readable.

Print job destinations can also be determined on a dynamic basis. Here is an example:

smart:   :sd=/var/spool/lpd/%P   :destinations=matisse@printers,degas@france,laser   :router=/usr/local/sbin/pick_printer

The program specified in the router setting is responsible for determining the destination for each submitted print job. The router program is a standard print filter program. Its exit status determines what happens to the job (0 means print, 37 means hold, and any other value says to delete the job), and it must write the queue destination and other information to standard output (where lpd obtains it). See the LPRng-HOWTO document for full details on dynamic print job routing. Filters

As we've noted before, print jobs are processed byfilter programs before they are sent to the printer device. Filters are responsible for initializing the device to a known initial state, transforming the output into a form that it understood by the printer, and ensuring that all output has been sent to the printer at the end of the job. The first and third tasks are typically accomplished by adding internal printer commands to the beginning and end of the print job. Filter programs are also responsible for creating printer accounting records.

As the examples we've looked at have shown, LPRng provides the filter printcap setting for specifying a default filter for all jobs in a particular queue. In addition, it supports many of the various output type-specific filter variables used in traditional printcap entries (i.e., the *f settings).

The LPRng package often uses the ifhp filter program also written by Patrick Powell. It is suitable for use with a wide variety of current printers. The characteristics of the various supported printers are stored in its configuration file, ifhp.conf (usually stored in /etc). The following printcap entry illustrates settings related to its use:

lp:   :sd=/var/spool/lpd/%P   :filter=/usr/local/libexec/filters/ifhp   :ifhp=model=default

The filter setting specifies the path to ifhp, and the ifhp setting specifies the appropriate printer definition with its configuration file. In this case, we are using the default settings, which work well with a wide variety of printers.



The LPRng facility includes an excellent Perl script that demonstrates the method for getting page count information from modern printers. It is called accounting.pl and is included with the source distribution. Other printcap entry options

It is also possible to store printcap entries in forms other than a flat text file. For example, they could be stored in an LDAP directory. LPRng allows for such possibilities by allowing printcap entries to be fetched or created dynamically as needed. This is accomplished by setting the printcap_path in the lpd.conf configuration file as a pipe to a program rather than a path to a printcap file:


Such an entry causes LPRng to execute the specified program whenever it needs a printcap entry (the desired entry is passed to the program as its standard input). For example, such a program could retrieve printcap information from an LDAP directory. See Chapter 11 of Network Printing for details and extended examples.

13.6.3 Global Print Spooler Settings

The lpd.conf configuration file holds a variety of settings relating to the print spooler service. Among the most important are ones related to printer connection and timeouts and to print job logging. Some of the most commonly used are listed in the example configuration file below:

# communication-related settings connect_grace=3                    Wait period between jobs (default=0). network_connect_grace=3 connect_timeout=600                Cancel job after this interval (default=0). send_try=2                         Maximum number of retries (default is no limit). max_servers_active=10              Max. #  lpd child processes (default is half the                                          system process limit). # logging settings max_log_file_size=256              Maximum file sizes in KB (default is no limit). max_status_size=256 min_log_file_size=128              Keep this much data when the files are too big  min_status_size=64                      (default is 25%). max_status_line=80                 Truncate entries to this length (default=no limit). # central logging server logger_destination=scribe            Destination for log file entries. logger_pathname=/tmp/lprng.tmp     Local temporary file to use. logger_max_size=1024               Max. size of the temporary file (default=no limit). logger_timeout=600                 Wait time between connections to the remote                                          server (default is whenever data is generated).

13.6.4 Printer Access Control

The third LPRng configuration file, lpd.perms, is used to control access to the print service and its printers. Each entry in the file provides a set of characteristics against which potential print jobs are matched and also indicates whether such jobs should be accepted. The first entry that applies to a specific print job will be used to determine its access. Accordingly, the order of entries within the file is important.

The syntax of the lpd.perms file is explained best by examining some examples. For example, these entries allow users to remove their own print jobs and root to remove any print job:


The first keyword in an entry is always ACCEPT or REJECT, indicating whether matching requests are to be performed. These entries all apply to the M service, which corresponds to removing jobs with lprm. The various entries allow the command to succeed if the user executing and the user owning the print jobs are the same (SAMEUSER), or if the user executing it is root (REMOTEUSER=root) on the local system (SERVER). All other lprm requests are rejected.

Available SERVICE codes include C (control jobs with lpc), R (spool jobs with lpr), M (remove jobs with lprm), Q (get status info with lpq), X (make connection to lpd), and P (general printing). More than one code letter can be specified to SERVICE.

There are several keywords that are compared against the characteristics of the print job and the command execution context:


These items are compared to the ownership and other characteristics of the print job to which the desired command will be applied. In addition, the SERVER keyword requires that the command be executed on the local server.


These items are compared to the user, group, and host where or with whom the desired command originated. Note that the "remote" part of the name can be misleading, because it need not refer to a remote user or host at all.

The preceding keywords all take a string or list of strings as their arguments. These items are interpreted as patterns to be compared to the print job or command characteristics.


These keywords require that USER be the same as REMOTEUSER and HOST be the same as REMOTEHOST, respectively. For example, the following entry limits use of the lprm command to users' own jobs and requires that the command be run on the same host from which the print job was submitted:


We'll now examine some additional lpd.perms entries. The following entry rejects all connections to the lpd server that originate outside the ahania.com domain or from the hosts dalton and hamlet:


Note that these entries could not be formulated as ACCEPTs. Hosts may be specified by hostname or by IP address.

The following entries allow only members of the group padmin to use the lpc command on the local host:


The LPC keyword can be used to limit the lpc subcommands that can be executed. For example, the following entry allows members of group printop to hold and release individual print jobs and move them around within a queue:


The following entries prevent anyone from printing to the printer test except user chavez:


User chavez can also remove jobs from the queue and use lpc to control it.

The following command prevents print job forwarding on the local server:


The DEFAULT keyword is used to specify a default action for all requests not matching any other configuration file entry:

# All everything that is not explicitly forbidden. DEFAULT ACCEPT

The default access permissions in the absence of an lpd.perms file is to accept all requests. Other LPRng capabilities

LPRng has quite a few additional capabilities which space constraints prevent us from considering, including the ability for more sophisticated user authentication using a variety of mechanisms, including PGP and Kerberos. Consult the LPRng documentation for full details.

Essential System Administration
Essential System Administration, Third Edition
ISBN: 0596003439
EAN: 2147483647
Year: 2002
Pages: 162

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net