The program that adds printer queues when a USB printer is connected is hal-cups-utils. It is a simple program that hooks into hal, the hardware abstraction layer, and adds/enables/disables CUPS queues as necessary.
As hal will be going away shortly — that, and the fact that hal-cups-utils doesn’t really work very well — I have had a go at re-writing it as a udev rule over the last few days.
The way it works is as follows. We have two ACTION==”add” triggers: one for the usb_device and one for the USB class driver (usblp) device. We need both of them because:
- at least one, and soon two, of the CUPS backends will most likely unload the usblp module if it is loaded, in order to use libusb. This means that the usb_device is the only reliable object we can track to see when printers have been disconnected.
- if the usblp module is already loaded, libusb won’t work because usblp holds open the raw device.
- the usblp module may be blacklisted altogether, as most printer device users use libusb now.
We have a single ACTION==”remove” trigger for the usb_device.
On “add” we obtain the Device ID by fair means or foul, depending on whether the usblp module is loaded. We match this against devices reported by CUPS using the device-id attribute, and keep a note of this mapping of USB devpath to device URIs. Note that if we fail to contact CUPS we just exit — the idea is that the CUPS initscript will replay the udev events after cupsd is started.
Next, we examine the existing CUPS queues to see if any of them use any of the device URIs associated with our device. If so, and they are disabled, and we’d disabled them, we enable them.
If no queues match, we invoke udev-add-printer to create a queue.
On “remove” we look up the list of device URIs associated with our USB devpath, then examine the existing CUPS queues to see if any of them use it. If so they are disabled.
A walk in the park.
(I know which I’d prefer.)
The code is in the udev branch of system-config-printer.