SUNY Potsdam (and probably all SUNY schools) need to accommodate administrative print jobs from a number of legacy (COBOL) sources from SUNY Central in Albany. These jobs arrive bearing many of the marks of the era of mainframes and dot matrix printers: text-only, and replete with inconvenient line feeds, odd characters, and alignment issues. Historically this has meant ruler measurements, physical printer adjustment, and later, perhaps some arcane PCL magic. Unfortunately, these jobs seemingly cannot be modified at the source to make them more palatable for modern PostScript printers.

Printing at SUNY Potsdam has been backed by CUPS for over ten years, and because it is open-source, with well-documented APIs for extension, we have been able to accommodate a wide variety of printing scenarios by writing our own applications. These have included accounting filters, PDF writers, hardware backends, and a bevy of specialized solutions to handle unique printing needs.

The latest offering is lpskim, so named because it is a text manipulation filter designed to be used as a System V interface script. A SYSV interface script differs from the now traditional PPD-driven document-type filtering inherent to CUPS, instead assuming all filtering itself as in the old LPR days. So, rather than define a series of isolated scripts to handle the needs for each queue, many repeated, some unique, all needing maintenance, lpskim arose as a generic universal filter that is driven by a configuration file. It has grown to handle everything we need to print these jobs to modern printers and beyond.

In our case, we created several SUNY queues (SUNY1-SUNYE) on our local CUPS server, each corresponding to an Albany queue for Potsdam. Each will receive these Albany-sourced jobs and merely re-spool to the queues with which our offices are familiar. This gives us a useful, consistent abstraction layer so that local queue and printer changes need no coordination with remote hands in Albany. It is also where we attach lpskim. The following sets up a queue for use this way:

lpadmin -p SUNYD -v file:/dev/null -i /path/to/

Note that the path is wherever lpskim was downloaded, as lpadmin simply copies it to /etc/cups/interfaces/SUNYD. Also note that we define the printer URI as file-backed /dev/null since we handle re-spooling to the final queue in lpskim itself. There we have necessary flexibility to change the destination of print jobs based on patterns in the jobs themselves (more below). This is also a way to create mischief by spooling a job to all queues on the print server, but that is left as an exercise for the reader.

We now need to define configuration for SUNYD in /etc/cups/lpskim.conf, otherwise the job will simply hit /dev/null. The following is assumed to be all one line:

SUNYD | debug : save_job : respool=RAY412-5 : lpoption=cpi=12 : \ 
lpoption=lpi=6.6 : lpoption=page-left=54 : lpoption=page-top=54

Note that we are re-spooling the job to an office queue, and that when doing so, we specify several lp options to affect formatting as the job is converted to the output appropriate for the final destination printer as specified in CUPS. Here, these are all margin adjustments, our simplest setup.

I provide our full SUNY lpskim configuration for all queues across a range of HP and Dell PostScript laser printers for reference. This file should be saved at /etc/cups/lpskim.conf. Notes follow.


  • SUNY1 (checks): Fairly straightforward text manipulation and formatted re-spooling, except for a cut/replace to move the date for new check stock.
  • SUNY4 (batch control): Formatted re-spooling with conf_switch options to re-base the configuration on either the SUNY4_CHECKREG or SUNY4_QUICKPAY configs based on patterns in the job. With all options the same, these proved unnecessary in the end, but were left in case new printers introduced new wrinkles.
  • SUNY9 (refund): Minute adjustments to cpi and lpi so output would fit a rough photocopy of a form, and line deletions near the end to eliminate a few extraneous lines that unavoidably shift to a second page as a result.
  • SUNYE (vouchers): A pair of filters to change line feeds and the like. Also note the commented-out alternate configuration that prepended a PCL string for a previous printer.

The rest of the queues are straightforward formatted re-spooling, a few involving a change to landscape, some margin adjustments, etc.

See to download lpskim and for full documentation of all options. Happy printing.