Question

I got two Konica Bizhub printers and want Windows machines to print via Samba.

The problem is, these printers work with account tracking for copy/scanning. I dealt with it that way: http://casa.apertus.es/blog/2011/06/howto-account-tracking-konica-minolta-c220-under-linux/ (modified by another post: adding *cupsFilter to the printer PPD).

But now I can't account the printed pages, because every job is accounted with 1.

If I understand everything right, the "pstops" filter has to be applied to count correctly. Is there a way to chain filters?

Another printer managed by CUPS (without custom filters) is accounted correctly and uses the same driver approach (Windows PS driver with printer specific PPD).

Was it helpful?

Solution

"I dealt with it that way: [...] adding *cupsFilter to the printer PPD"

Note, that the *cupsFilter:-entry in the print queue's PPD determines which filter to run as the last instance of a filtering chain for that queue, before passing the job data to the respective queue's backend (which sends it to the final destination printer or file).

So it really depends, what concrete setup is hidden behind your PPDs *cupsFilter:. If your *cupsFilter: tells CUPS to handle the respective data as a "raw" job, then it may not ever see any filter that creates accounting information. Your job data may go unfiltered to the print device. In that case, CUPS only choice is to write as number of copies 1 into the page_log file.

If you mess around with CUPS filtering (by whatever means: write your own filter or wrapper script, *cupsFilter: lines in the PPD, or whatever...), then it's your own responsibility to create a filter chain that creates correct entries in the page_log.

"Is there a way to chain filter?"

Of course there is.

CUPS filters are very picky about the number of arguments and the exact order they are called with. They tell you which way it is by calling one of them without any argument manually in a terminal. Here an example from Mac OSX:

 kp@mbp:> /usr/libexec/cups/filter/pstops 
  Usage: /usr/libexec/cups/filter.orig/pstops job-id user title copies options [file]

So it is:

  1. argument no. 0: Path+name of the filter itself
  2. argument no. 1: CUPS job-id
  3. argument no. 2: CUPS user name
  4. argument no. 3: Job title
  5. argument no. 4: Number of copies requested
  6. argument no. 5: Printjob options for this job. The filter only applies the options it understands!
  7. argument no. 6: File to process. Optional argument. If missing, it means: "process <stdin>".

CUPS filters always deliver output to <stdout>, and must be able to take input from <stdin>.

Some of the above arguments may be empty or may carry dummy values if you call and run a filter manually or via a script. If empty, use empty double quotes like this: "".

The sixth argument (input file name) is optional. If it is missing, then the filter should expect its input from <stdin>.

So you can write your own CUPS filter. There are two different types for you:

  1. Either write a CUPS filter from scratch.
  2. Or write a CUPS filter as a wrapper, running one original CUPS filter (or a chain of CUPS filters)

In any case, your filter calling conventions MUST follow the above rules about number of arguments and the order of their appearance on the command line.

Also note this: if CUPS runs a filter that causes output to <stderr>, it redirects this output to the CUPS log file. So if you write your own CUPS filter, you can control what ends up in CUPS' log by controlling what goes to <stderr>. If you do not want it to appear in CUPS logs, redirect to /dev/null.

If you run the filter manually in a terminal, the <stderr> output will appear in that terminal, of course.

So to manually feed a PDF file on a Mac to a CUPS filter chain called manually, I'd try:

in=a-one-page-pdf-file.pdf
/usr/libexec/cups/filter/cgpdftops 1 kp "testing filter-chain" "1" "" ${in}  \
 | /usr/libexec/cups/filter/pstops 1 kp "testing filter-chain" "1" ""        \
 | /usr/libexec/cups/filter/pstopdffilter 1 kp "testing filter-chain" "1" "" \
 | /usr/libexec/cups/filter/cgpdftoraster 1 kp "testing filter-chain" "1" "" \
 | /usr/libexec/cups/filter/rastertotiff 1 kp "testing filter-chain" "1" ""  \
 | /opt/local/bin/convert - -mattecolor red -scale 25%  -frame 1x1 output.png

(Don't tell me, that this particular filtering chain does not make much sense. I know. It's for demo purposes only. But it works.)

The command processes a PDF, calls a filtering chain of 5 CUPS filters first. Then as its last filter it calls the ImageMagick convert command, which creates a PNG image with a thin red line as a frame around the page.

There's a lot more to it, like:

  • Some filter now how to read and interpret a PPD file, and how to apply job options they read on the command line and whose details are specified in the PPD file. They take the PPD to use from their environment variable PPD.
  • If you prefix the message lines your filter spits out to <stderr> with keywords EMERG:, ALERT:, CRIT:, ERROR:, WARN:, NOTICE:, INFO:, or DEBUG: then these respective lines will appear in the log only if the respective LogLevel setting (or a higher one) in cupsd.conf is active: alert, crit, error, warn, notice, info or debug.

But I'll leave it at that for now...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top