2

We have an ancient Business Basic application which prints reports to a simple line printer, and we would like to capture that output to a file (to then scrape the data from it). This runs on Red Hat 8 (circa 2002).

The Basic code OPENs then PRINTs to "LP", which makes its way to lpd printer lp. Inspecting a couple of random spool files that didn't get deleted in /var/spool/lpd/lp/, these look to have suitable content.

So the question is, how to temporarily change something such that the Basic program sends its output only to a file (and that file doesn't get printed).

One could achieve the effect by changing the Basic code, but the system is extensive, has many places where printing is performed, and there would be no easy way to offer an option at those places.

Hence the pursuit of a way to do this, external to the Basic application, which can be instated and uninstated (to return printing to normal) from a script.

In case it's relevant, the printcap entry:

lp:\
:ml#0:\
:mx#0:\
:sd=/var/spool/lpd/lp:\
:af=/var/spool/lpd/lp/lp.acct:\
:sh:\
:rm=[ip address]:\
:rp=pr0:\
:lpd_bounce=true:\
:if=/usr/share/printconf/util/mf_wrapper:

Thanks!

gwideman
  • 125
  • 6
  • 1
    Easiest would be via a `:of=/some/output/filter:` (output filter) or if that version of LPD does not support that, by instead using a `:if` that would save a copy and then run the existing `mf_wrapper`. – thrig Aug 19 '16 at 22:31
  • @thrig12 According to man page on that system, lpd does support ':of='. Do you have a suggestion as to what output filter would save the file? And what is the role of mf_wrapper (google is not helpful on that!). (Bear in mind, when capturing to file, we want to avoid printing to the printer.) Thanks. – gwideman Aug 19 '16 at 22:47
  • 1
    Normally, printing systems differentiate between a queue and a printer. Can you simply do `lpc down` to hold further jobs, inspect them whilst they sit in the spool queue, then `lprm .` to cancel the jobs, and `lpc up` to re-enable the printer. These commands affect the printer, `lpc enable` and `lpc disable` are for the queue. – meuh Aug 20 '16 at 08:15
  • @meuh Thanks, that does look like a promising avenue. Man page says that `lpc down` prevents spooling as well as printing (which I assume means that the file to be printed doesn't end up in the spool directory, and isn't there to be intercepted). So perhaps `lpc stop` is a better choice, or possibly `lpc hold...`. I will investigate when I have someone on-site to ward off accidental printing on paper. – gwideman Aug 20 '16 at 09:21

1 Answers1

3

If you define your printcap entry similar to:

lp:\
    :ml#0:\
    :mx#0:\
    :sd=/var/spool/lpd/lp:\
    :sh:\
    :lp=/dev/null:\
    :of=/var/output/capture:

In this case the lp entry points to /dev/null and so it will never print anything out.

The magic is in the of filter. It's a very simple script:

#!/bin/sh

DIR=/var/output/files
d=`/bin/date +%Y-%m-%d_%H:%M:%S`

output=$DIR/$d.$$

cat > $output
chmod 644 $output
exit 0

Now

mkdir /var/output/files
chown daemon /var/output/files

At this point we can do something like:

% echo this is a test | lpr

And is if by magic:

% ls /var/output/files
2016-08-20_09:44:19.26541

% cat /var/output/files/2016-08-20_09\:44\:19.26541 
this is a test

You can modify the script to your exact needs.

(I've tested this on FreeBSD, which is the only machine I have that still uses lpd !)

Now you had an if filter in your original; if is an "input filter" which is designed to modify the incoming file to a normalised format. I'm not sure what mf_wrapper does ("m format"?), but if you're seeing a mess in your output files then you might change the printcap to include the originalif filter:

lp:\
    :ml#0:\
    :mx#0:\
    :sd=/var/spool/lpd/lp:\
    :sh:\
    :lp=/dev/null:\
    :of=/var/output/capture:\
    :if=/usr/share/printconf/util/mf_wrapper:

For files that' you're happy with you could then manually send them to another print queue with an lpr -Prealqueue or similar.

Stephen Harris
  • 42,369
  • 5
  • 94
  • 123
  • Thanks for writing and testing this. I see key points: in printcap entry `lp:=...` changes the eventual output destination (to nowhere in this case), and in your example output filter, `cat > $output` intercepts the stream and directs it to a file. This really illuminates the mechanism involved. – gwideman Aug 20 '16 at 21:09
  • I've marked this as the answer in recognition of your effort and good explanation. For our specific case, I'm inclined to pursue @meuh's line of thinking, because it only manipulates printer queue status (using intended commands) rather than needing to swap in and out printcap files (though the latter could be done on a per-user basis). – gwideman Aug 20 '16 at 21:16
  • And FWIW, mf_wrapper is a script that sets up some variables and calls `/usr/bin/magicfilter-t` (hence the 'mf' part). – gwideman Aug 20 '16 at 21:20