如何通过CUPS API为新打印机关联指定驱动?
Great job getting the bare printer setup working—let's fix the driver association part. The key here is understanding how CUPS maps drivers to printers, which relies on PPD (PostScript Printer Description) files. Here's how to nail this with IPP requests:
Core Concepts
CUPS uses PPD files to define printer capabilities and driver behavior. When adding a printer, you have three reliable ways to link a driver:
- Directly reference an existing, CUPS-recognized PPD (best for consistency)
- Upload a custom PPD file (for proprietary or niche printers)
- Use the printer make/model string (let CUPS auto-select the matching PPD, but less reliable for custom drivers)
Step-by-Step Implementation
1. Validate Your PPD First
Before sending the IPP request, confirm your target PPD is compatible:
- Run
lpinfo -min your terminal to list all PPDs CUPS currently recognizes. Look for the exact string corresponding to your printer's driver (e.g.,hp/hp-laserjet-p2015.ppd). - If using a custom PPD, ensure it's formatted correctly (valid PostScript, CUPS-compliant).
2. Build the IPP Request with Driver Attributes
Here's how to structure your request using CUPS' C API (adjust based on your language/library):
Option A: Reference a Pre-Recognized PPD
Use the ppd-name attribute with the exact string from lpinfo -m:
ipp_t *request = ippNewRequest(CUPS_ADD_PRINTER); // Basic printer attributes (required for CUPS to process the request) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://localhost/printers/MyNewPrinter"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, "root"); ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-info", NULL, "My Office Printer"); ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location", NULL, "Third Floor"); // Critical driver association attribute ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name", NULL, "hp/hp-laserjet-p2015.ppd"); // Set printer type (adjust flags based on your printer: local/network, color/mono, etc.) ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type", 1, PRINTER_TYPE_LOCAL | PRINTER_TYPE_PRINT); // Send the request http_t *http = httpConnectEncrypt("localhost", ippPort(), 0); ipp_t *response = ippDoRequest(http, request, "/admin/");
Option B: Upload a Custom PPD File
If you have a custom PPD not in CUPS' default library, use the ppd-file attribute to upload it directly:
// Add this to your existing request instead of `ppd-name` ippAddFile(request, IPP_TAG_PRINTER, "ppd-file", "/path/to/MyCustomDriver.ppd", NULL);
CUPS will automatically process and store this PPD for the new printer.
Option C: Use Make/Model for Auto-Matching
If you prefer letting CUPS pick the driver, use the printer-make-and-model attribute with the exact string from lpinfo -m (not just a generic "HP LaserJet"):
ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-make-and-model", NULL, "HP LaserJet P2015");
Note: This is less reliable if multiple PPDs match the model, or if CUPS doesn't have the driver in its library.
Common Pitfalls to Avoid
- Using physical file paths for
ppd-name: CUPS expects the logical name fromlpinfo -m, not/etc/cups/ppd/MyPrinter.ppd. - Missing basic attributes: CUPS may reject requests that don't include
printer-info,printer-location, orprinter-type. - Permissions issues: If using a local PPD file, ensure it's owned by
root:lpwith permissions644so CUPS can access it. - Incorrect IPP operation code: Make sure you're using
CUPS_ADD_PRINTER(notCUPS_MODIFY_PRINTERunless updating an existing printer).
Verify the Setup
After sending the request, confirm the driver is associated correctly:
- Run
lpstat -p MyNewPrinter -land check for thePPDline. - Access the CUPS web interface (http://localhost:631) to view the printer's details and confirm the driver is listed.
内容的提问来源于stack exchange,提问作者hmtinc




