I have a server on which I have several serial printers set up as raw queues in cups. On each of these, I have installed interfaces scripts to perform some simple output manipulation and to handle IPC with an application that runs on the server and likes to attach directly to printers and write to them, which doesn't jive well with cups thinking that he is exclusively in control of the printer devices. Everything there appears to be working.
Enter another application on the server that, while it does go through cups (after spooling through its own print spooler), appears to be injecting printer-specific escape codes into the files it prints out. In other words, the print produced by this application is not simply a stream of plain text characters, but it contains binary control codes that the printer is meant to interpret.
The problem that I am encountering is that cups appears to be bypassing my interfaces when it receives such files from this second application. I tested this by setting up two nearly identical print files. The first contained the plain text "Hello, world!" followed by a newline character; the second contained some escape codes for one of the printers followed by the "Hello, world!" and newline. I then added a "sleep 5" line to my printer's interface so that there would be a noticeable delay when printing.
When I printed the first file using lp, nothing happened for five seconds, after which the printer came to life and wrote out "Hello, world!" However, when I printed the second file using the exact same lp
command, it immediately printed "Hello, world!" without sleeping. I have also noted that I can use the "-o raw
" option in lp
to force the same behavior with the first file (immediately printing it out without the five-second delay).
My guess is that cups is looking at the actual data being printed and trying to determine its type and, when it sees printer escape codes in the data, it decides that this is "raw" print and bypasses the interface. This is not the behavior that I expected since I set the printer up as a "raw" queue in the first place and assumed this meant that cups would just pass anything sent to it through the interface; nevertheless, this is the behavior that I am seeing.
My question is: Is there a way to send an option to cups (other than -o raw
, which appears to bypass the interface as well) telling him not to detect the type of the print data received and to go ahead and send it to the interface script? Alternatively, is there a way to specify the format of the incoming data (e.g., tell cups that what it is receiving is "plain text" even though it contains escape codes) such that cups will not look at it and simply pass it to the interface?
First, you seem to not be aware what a raw print queue is in CUPS' parlance: a raw queue is one that is not associated with...
...neither an interface script (a script by the same name as the queue itself located in /etc/cups/interfaces/
),
...nor a PostScript Printer Description (PPD) file (a PPD file by the same name as the queue itself with the additional suffix *.ppd, located in /etc/cups/ppd/
).
Since you say you've installed an interface script for your printer queues, by definition these are NOT raw queues!
To send jobs as raw (that means: unfiltered) to non-raw CUPS queues, there is no other way than to use -o raw
on the lp
commandline. You can also use (alternatively) the option -o document-format=application/vnd.cups-raw
... but this has the exactly same meaning: it causes CUPS to use the same job handling and is just 7x more keyboard keys to punch.
Both ways cause CUPS to skip the step of auto-typing the incoming job file and pass it through unfiltered to the queue's backend.
The auto-typing step and its result can be observed in the log file /var/log/cups/error_log
by looking for the keyword Auto-typing
once your cupsd.conf
has LogLevel debug
enabled: the line mentioning Request file type is ...
tells you which MIME type CUPS classifies your incoming job as.)
Use the -o document-format=text/plain
in the lp
command line.
If you want to turn (any) existing print queue into a raw one, just delete the associated PPD file (/etc/cups/ppd/myprinter.ppd
) or the associated interfaces script (/etc/cups/interfaces/myprinter
).
If you want to install a print queue to act as a raw one from the beginning, just use the printername and the backend URI, but do not specify any PPD nor any interface script to be associated with it:
Example command to install a 'raw' print queue:
sudo lpadmin -p my_raw_printer -E -v socket://192.168.177.188:9100
(The -p
is to specify the print queue name, the -E
is to enable the print queue from the beginnning.)
Without seeing your complete system setup and looking at the 2nd application (whose printing seems to behave differently from your 1st one), or without access to a debug level CUPS error_log
file , it's only possible to speculate:
-o raw
print command option.