Sharing printers with CUPS

CUPS is Apple Inc's Common UNIX Printing System.

While converting my home network to use CUPS, I had more hassles getting OS/X to work with it, than my NetBSD boxes.

A number of google queries found folk with similar issues, but answers were few and far between. So on the off chance this helps someone else...

Background

My kids were ready to mutiny! My 20 year old hp 4MP laser was on its last legs (either the drum needs replacing, or the last toner cartridge was just a dud), regardless, you can buy a new printer for what that last toner cartridge cost.

Printers are wicked but necessary things, so I caved and started seriously looking for a new printer.

The kids wanted color, my wife wanted a scanner/copier, and I wanted laser to keep the running costs down. I don't try to print photos at home, so laser graphics is fine.

I was going to insist on postscript, until I found that even HP did postscript in their printer driver these days (cf. in the printer), so I decided that was a lost cause, and would have to consider printers that had more elaborate drivers.

Running costs

Printers can be had for the price of a tank of gas these days, but the cost of consumables is an important factor to consider.

Laser printers are more expensive to buy but generally cheaper to run. Some are cheaper than others though. To cut a long story short, I ended up ordering a Brother MFC-9840CDW. Before I ordered it, I checked that Brother had a PPD available for it, which I downloaded and installed in (*/cups/model/).

Apart from the features everyone wanted, and reputedly good print quality, its toner costs seem better than average especially with the high yield cartridges; $65 for 5000 pages (black). That's the mythical 5% coverage page which all vendors use, so while you may not get 5000 pages from a cartridge, you can still compare costs.

Driver support

OS/X support was a must, and generic UNIX support was highly desirable, both of which add up to CUPS.

Most printer vendors these days provide PPD's which are how CUPS knows what their printer can do. I made sure that any printer I considered had a PPD available - from the vendor.

My servers run NetBSD, and while the new printer would be connected via ethernet, I wanted the ability to control it via a server. It was trivial to add the pre-built cups packages from NetBSD's pkgsrc collection.

The next step was to migrate the old printer to being used via CUPS rather than lpd, as a means of ensuring that the new printer (when it arrives) will be up and running with minimal fuss.

Setup CUPS

Let me cut to the chase here, setup is simple, but some particularly poorly named variables cause confusion.

Specifically there are a bunch of knobs Browse* some of which would be more appropriately named Advertise* or Broadcast*.

Based on my setup experience, the following may be useful clues

BrowseInterval

This is actually the interval at which cupsd will broadcast about, or advertise printers that it is servicing.

BrowseTimeout

This is a bit like a DHCP lease period.

BrowseLocalProtocols

This is how printers shared by cupsd will be advertised.

BrowseRemoteProtocols

This is how printers shared by others will be discovered.

NetBSD

This was simple. The default config pretty much just worked.

The one change I made - since I have a couple of servers sharing /usr/pkg/ was make /usr/pkg/etc/cups -> /etc/cups so that each could have its own config.

Also, since I have /var/run on a tmpfs, I modified the supplied /etc/rc.d/cupsd to have a start_precmd function to create the directories that cupsd wants in /var/run/cups/

OS/X

Compared to NetBSD, getting OS/X to spot shared printers was a pain and it gets worse with each new version. Even after getting cupsd on OS/X to listen to the network (rather than just localhost), 10.6 needed BrowseRemoteProtocols cups configured explicitly before things started working.

Trying to add printers via the normal dialogues was very confusing. If you tried to configure an IPP printer, and gave the server address, OS/X would query it, and see the print queues which you could select from, so everything looked OK. But any attempt to print to such a printer failed.

Instead, you needed to fix the CUPS config so that cupsd would see the printer broadcasts from the server, and then the printers would just magically appear - and actually work.

The way to do that is a bit unintuitive, you need to go to System Preferences and under Sharing enable Printer Sharing. That results in /private/etc/cups/cupsd.conf having:

Port 631

rather than just:

Listen localhost:631

With the default setting cupsd never sees printer advertisements from other machines. Also on 10.6 run:

cupsctl BrowseRemoteProtocols=cups

then wait BrowseInterval seconds (as configured on the server), and lpstat -a should show that OS/X has learned of the printer:

$ lpstat -a
hp accepting requests since Thu Mar 10 13:55:27 2011

You can then set the default printer:

# lpadmin -d hp

That doesn't mean that apps like Safari etc will just use it though. You end up having to add a printer; click on the default box at the top left of the dialogue, or select your printer from the displayed list of shared printers, wait a bit, and the Add button will be available to click. This appears to be necessary for each application.

All up, just reminds me why I hate user friendly and the appaling lack of documentation for OS/X.

Update: 10.8

Like I said, it gets worse with each release. I recently bought new laptops for my kids, and while they automatically spotted the printer itself (via Bonjour it seems), they steadfastly refuse to pay any attention to the cups/ipp advertisements from the server.

After the usual googling, and giving up on the blind leading the blind; I finally resorted to running approximately the same lpadmin command on the latop as I did on the NetBSD server to add the queues there:

# lpadmin -p bw -v ipp://server:631/printers/bw -D bw9840 \
-L "computer room" \
-P /etc/cups/ppd/Brother-MFC-9840CDW.ppd -E

Which produced a working print queue, but did not get the desired B&W result.

Update 10.11

El Capitan is the last release that supports my imac. After again noting that the above lpadmin command did not result in a working B&W print queue, I took a look at the Brother-MFC-9840CDW.ppd on the Mac - lo and behold it did not contain any color controls!

So I copied the ppd file that I use on the NetBSD server and used:

# lpadmin -p bw -v ipp://server:631/printers/bw -D bw9840 \
-L "computer room" \
-P /tmp/bw.ppd \
-o BRColorMode=False \
-o BRPrintQuality=black \
-o BRPrintQuality-default=black \
-E

and we at least find the following in /etc/cups/printers.conf:

Option BRPrintQuality black

The new printer

The Brother MFC-9840CDW was connected to the network, and told to use DHCP to get itself configured. The printer really wanted to use its default name BRNxxxxxx where xxxxxx is the last 6 hex digits of its MAC address, I can live with that, I created br as a CNAME for it.

The previous efforts paid off. Both the NetBSD servers, and the OS/X machines immediately spotted the new printer, and it just worked.

The dialogue offered to OS/X apps allowed setting double sided printing, but no control over color, so I added a separate printer on the server, to force black and white:

# lpadmin -p bw -v ipp://brnXXXXXX:631/ipp -D bw9840 -L "computer room" \
-P /usr/pkg/share/cups/model/foomatic-ppds/Brother/Brother-MFC-9840CDW.ppd \
-o BRPrintQuality-default=black -E

You can use lpoptions -p printer -l to get a list of all the options that a printer supports as well as the defaults. That's how I found BRPrintQuality for controling color.

Adding a queue to force double sided:

$ lpoptions -p br/bw2 \
-o BRPrintQuality=black \
-o sides=two-sided-long-edge

So apart from using the printer directly, the following queues are managed by the server:

$ lpstat -a
br accepting requests since Thu Mar 31 22:55:16 2011
br/bw1 accepting requests since Thu Mar 31 22:55:16 2011
br/bw2 accepting requests since Thu Mar 31 22:55:16 2011
br/c1 accepting requests since Thu Mar 31 22:55:16 2011
br/c2 accepting requests since Thu Mar 31 22:55:16 2011
bw accepting requests since Mon Apr 11 07:39:01 2011

One of my kids discovered that if trying to print chinese text, from OS/X, it did not work until she used the printer directly rather than via the bw queue on the server.

LPD printers

Even if a networked printer only has the LPD protocol enabled, you can still leverage its full capabilities via CUPS. Assuming you have a suitable PPD file:

# lpadmin -p br -v lpd://bw9840/ -D br9840 -L "computer room" \
-P /tmp/Brother-MFC-9840CDW.ppd -E

is all you need. Even works on OS/X ;-)


Author:sjg@crufty.net /* imagine something very witty here */