CUPS Filter for Fujifilm Printers
At the start of last year, we installed a new Fujifilm multifunction printer (formerly Fuji Xerox) at our church to replace an aging Toshiba MFP. Like our old setup, we rely on user IDs as department codes to track usage and handle accounting.
While Fujifilm provides official Linux CUPS filters, they do not support accounting out of the box. When someone recently asked how to get printing working on Linux, I realised I had never shared the CUPS filter wrapper I wrote to solve this problem.
This solution was originally built for our Gutenberg instance, the web printing interface we run rather than allowing everyone direct network access to the printers - a decision made primarily to keep our network environment secure but also saves us from the headache that is installing, configuring and supporting printer drivers on everyone’s personal devices.
The issue with the vendor provided filter (pdftopjlff) is that it only handles the basic rendering pipeline - converting PDF to PJL, without the accounting or authentication headers the printer expects. When the printer receives a job without these headers, it simply rejects the job.
Since replacing the proprietary binary was not an option, I needed a way to intercept the print stream after the filter rendered it, but before it hit the network socket.
Behold this wrapper script, installed in /usr/lib/cups/filter/pdftopjlffauth and referenced in the printer PPD file - replacing pdftopjlff:
1 |
|
Essentially the script acts like a regular CUPS filter - but calls the original pdftopjlff filter to handle the heavy lifting of converting PDF into PJL, then injects the necessary job attributes into the PJL stream before it gets sent off to the printer.
One limitation with this implementation is that the user ID is hardcoded into the script - for our use case this is not a problem, since all jobs on this CUPS daemon are submitted and logged through Gutenberg, with all users authenticated via OIDC. You may wish to implement a more dynamic solution for your own use case if multiple users is a requirement - you could use username passed by CUPS ($2) as an example.
Quick explanation of the job attributes:
@DAIDis the account ID@ACNAis the title or name of the document being printed@JOAUis the ‘job owner’ (user ID)@LUNAis the local name of the user submitting the job@CNAMis the name of the client or computer submitting the job
If you use passcodes in addition to user IDs, you can specify its value (plaintext without encryption) as @JOAP.
Unfortunately I cannot remember what the other two job attributes were for, and Fujifilm’s own documentation is not very forthcoming. Whilst writing this script, I inspected the PJL generated from a printing job submitted on a Windows client (which had far better vendor support) in an effort to reverse engineer the meaning of these attributes and how they were being used to make this work, but never got around to documenting my findings. My best guesses are:
@JOEPis used for secure printing@JOADis the domain for the user submitting the job