Home > Articles > Operating Systems, Server

Setting Up LPR/LPD on FreeBSD

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

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

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

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

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

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

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

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

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

Creating the Spools

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

#
lp|lo-cal line printer:  :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:
NEC|N-EC Silentwriter 95 PostScript printer:  :lp=/dev/lpt0:sd=/var/spool/output/NEC:lf=/var/log/lpd-errs:
#

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

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

su root
cd /var/spool/output
mkdir NEC
chown bin NEC
chrgrp daemon NEC
chmod 755 NEC

Additional Spool Capabilities

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

  1. During FreeBSD installation, if the administrator knows that a lot of print jobs are going to go through the spooler, /var should be set to a large amount of free space.

  2. Modify the sd capability in the /etc/printcap file to point to a spool directory in a different, larger filesystem, such as /usr/spool.

  3. Use soft links to point the /var/spool/output directory to directories on a larger filesystem.

  4. Don't define a /var directory at all during FreeBSD installation; this would make the installer link /var to /usr/var.

In addition to spools, the following other capabilities are usually placed in a production /etc/printcap file.

  • The entry fo prints a form feed when the printer is opened. It is handy for HPPCL (HP LaserJets) non-PostScript printers that are located behind electronic print-sharing devices. It can also be used for printers that accept input from multiple connections, such as a parallel port, serial port, and localtalk port. An example is an HP LaserJet with an MIO card in it plugged into both Ethernet and LocalTalk networks. It will clear any garbage out of the printer before the job is processed.

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

  • The entry sh suppresses printing of banner pages in case the printer cannot handle ASCII and the client mistakenly requests them.

  • The entry ct denotes a TCP connection timeout. It is useful if the remote printserver doesn't close the connection properly.


Note - FreeBSD 2.2.5 contains a bug in the LPD system: as a workaround, the ct capability must be set very large (e.g., 3,600sec) or the appropriate patch must be installed and LPD recompiled. More recent versions of FreeBSD do not have this bug.


Printing to Hardware Printserver Boxes or Remote Printservers

Hardware printserver boxes, such as the HP JetDirect internal and external cards, need some additional capabilities defined in the /etc/printcap entry: rp, for remote print spool, and rm, for remote machine name.

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

Determining the name used for rp, on the other hand, can be rather difficult. Here are some common names.

  • Windows NT Server: Printer name of the Printer icon created in Print Manager.

  • FreeBSD: Print queue name defined in /etc/printcap.

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

  • HP JetDirect EX +3: External, three-port version of the JetDirect. Use RAW1, RAW2, RAW3, TEXT1, TEXT2, or TEXT3, depending on the port desired.

  • Intel NetPort: Use TEXT for UNIX text conversion printing, or use PASSTHRU for normal printing.

  • DPI: Use PORT1 or PORT2, depending on which port the printer is plugged in to.

For other manufacturers' printservers, refer to the manuals supplied with those devices.

The following is an example /etc/printcap that redefines the default lp print queue to send print jobs to the first parallel port on a remote HP LaserJet plugged into a JetDirect EX +3 named floor2hp4.biggy.com.

#
lp|l-ocal line printer:   :rm=floor2hp4.biggy.com:rp=RAW1::sd=/var/spool/output/lpd:   :lf=/var/log/lpd-errs:
#

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


Filters

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

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

Types of Filters

Three types of filters can be defined in the /etc/printcap file. In this book all filter examples are for input filters.

Input Filters  Input filters are specified by the if capability. Every job that comes to the spool is acted on by any filter specified in the if entry for that spool. Virtually all filters that an administrator would use are specified here. These filters can be either shell scripts or compiled programs.

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

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

Printing Raw UNIX Text with a Filter

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

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

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

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

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

#!/bin/sh
# /usr/local/libexec/crlfilter
#
# simple parlor trick to add CR to LF for printer
# Every line of standard input is printed with CRLF
# attached.
#
awk '{printf "%s\r\n", $0}' –

An alternative filter posted using sed could be written as follows.

#!/bin/sh
# /usr/local/libexec/crlfilter
#
# Add CR to LF for printer
# Every line of standard input is printed with CRLF
# attached.
#
# Note, the ^M is a real ^M (^V^M if you're typing in vi)
#
sed 's/$/^M/' -

Here is an example of a filter that triggers the printer's automatic LF-to-CR/LF converter (this option is useful only on HP LaserJets that support this command).

#!/bin/sh
# Simply copies stdin to stdout. Ignores all filter
# arguments.
# Tells printer to treat LF as CR+LF. Writes a form feed
# character after printing job.
printf "\033&k2G" && cat && printf "\f" && exit 0
exit 2

The /etc/printcap file used to trigger the filter is

# /etc/printcap
# The trailer (tr) is used when the queue empties. I found that the
# form feed (\f) was required for the HP to print properly.
# Banners also need to be shut off.
#
lp|l-ocal line printer:  :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:
  :if=/usr/local/libexec/crlfilter:sh:tr=\f:mx#0:
#

The pr Filter

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

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

Printing PostScript Banner Pages with a Filter

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

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

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

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

#!/bin/sh
# Filename /usr/local/libexec/psbanner
# parameter spacing comes from if= filter call template of:
# if -c -w -l -i -n login -h host
# parsing trickiness is to allow for the presence or absence of -c
# sleep is in there for ickiness of some PostScript printers for dummy
do
   case "$1" in
   -n)	alogname="$2" ;;
   -h)	ahostname="$2" ;;
   esac
   shift
done
/usr/local/libexec/make-ps-header $alogname $ahostname "PostScript" | \ lpr -P lpnobanner
sleep 10
cat && exit 0

Here is the make-ps-header listing.

#!/bin/sh
# Filename /usr/local/libexec/make-ps-header
#
# These are PostScript units (72 to the inch). Modify for A4 or
# whatever size paper you are using:
#
page_width=612
page_height=792
border=72
#
# Save these, mostly for readability in PostScript, below.
#
user=$1
host=$2
job=$3
date=´date´
#
# Send the PostScript code to stdout.
#
exec cat <<EOF
%!PS
%
% Make sure we do not interfere with user's job that will follow.
%

%
% Make a thick, unpleasant border around the edge of the paper.
%
$border $border moveto
$page_width $border 2 mul sub 0 rlineto
0 $page_height $border 2 mul sub rlineto
currentscreen 3 -1 roll pop 100 3 1 roll setscreen
$border 2 mul $page_width sub 0 rlineto closepath
0.8 setgray 10 setlinewidth stroke 0 setgray
%
% Display user's login name, nice and large and prominent.
%
/Helvetica-Bold findfont 64 scalefont setfont
$page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto
($user) show
%
% Now show the boring particulars.
%
/Helvetica findfont 14 scalefont setfont
/y 200 def
[ (Job:) (Host:) (Date:) ] {
   200 y moveto show /y y 18 sub def
} forall
/Helvetica-Bold findfont 14 scalefont setfont
/y 200 def
[ ($job) ($host) ($date) ] {
   270 y moveto show /y y 18 sub def
} forall
%
% That is it.
%
showpage

Here is the /etc/printcap file.

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

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020