[comp.unix.questions] Filters for the BSD print spooling system

robert@coke.UUCP (03/30/87)

I'm not really sure whether this should go to comp.unix.questions
or comp.unix.wizards, so I send it to both.

I'm trying to write some filters for the different kinds of printers
we have here. The filters will be forked off by Sun's/Berkeley's
lpd printer daemon. So, what's the problem, you might ask. Those
filters should only take the standard input, process it, and send
the result to the standard output. Well, that's what I thought.

The first of my filters, epsonf, worked just fine when run from
the command-line using redirection and/or pipes, but when I
installed it as if (input(?) filter) and of (output filter), only
the banner page got printed and then the filter hung. Seems like
lpd expects the output filter (the one which prints the banner page)
to release its standard output file, or something, before lpd can
let the input filter do the actual printing.

Then I tried to remove the input filter specification from /etc/printcap
and let all output go through the output filter. That seemed to work.
Hmmm, strange, I thought. Just to be sure the problem was in my filter
and nowhere else, I used the standard /usr/lib/lpf filter as both
input- and output filter, which, of course, worked like a dream (the
dream I had about how my filter should work, that is, without any
problems). Using /usr/lib/lpf as the output filter and my filter as
the output filter worked equally well.

So, here comes my question:

How Do I Write a Printer Filter for the Berkeley Printer Spooling System?
What signal's should I trap (the only signal that's documented is SIGINT
that is sent when I use lprm to remove a job), and what should I do when
I have got that signal? Anything else to think about, too?

	Thanks,
	Robert.
_______________________________________________________________________________
NAME:	Robert Claeson				PHONE:	+46 8-730 03 00
PAPER:	Statskonsult Programvaruhuset AB
	P.O. Box 4040				"Whatever it is, it's not
	S-171 04 Solna				 my problem."
	Sweden
UUCP:	{seismo!}mcvax!enea!coke!robert
_______________________________________________________________________________

ken@rochester.UUCP (03/31/87)

I don't know what your specific problem is but here are some things I
discovered while writing lpd filters myself.

Pay attention to the environment of the filter when it is run.  One way
of debugging is to do "su - daemon" to get the enviroment of the
daemon. You will find that only a few directories are on the path. I
personally use absolute pathnames for any commands run in the filter.

I prefer to use sh for filters (and shell programming in general).
Faster and less hassles. I put this line near the top of the filter
script:

	trap "rm -f TEMPFILES" 0 1 2 3 15

Check that the permissions of any files (e.g. logfiles) that need to be
written on are correct for group daemon.

Another thing I discovered only by looking through the lpr code is that
the -d, -n and -t flags imply -l, and the last flag specified
supercedes the previous ones, so don't type "lpr -d -l foo.dvi" because
the job will be queued with the l flag (print raw).

Here is an example of our dvi to press filter running here:

#! /bin/sh
statusfile=/usr/spool/raven/status
trap "/bin/rm -f /tmp/$$.dvi /tmp/$$.press" 0 1 2 3 15
umask 077
/bin/cat > /tmp/$$.dvi
/bin/echo "Converting dvi to Press" > $statusfile
2>&1 /usr/staff/bin/dvip -p /tmp/$$.press /tmp/$$.dvi > /dev/null
/bin/echo "Sending Press file to Raven" > $statusfile
/usr/lib/xpressf < /tmp/$$.press
exit 0

	Ken

jaap@mcvax.UUCP (03/31/87)

If you write an output filter, you have to deal SIGSTOP.
Look in the source of lpf for an example.

	jaap

tony@artecon.UUCP (03/31/87)

In article <111@coke.UUCP> robert@coke.UUCP (Robert Claeson) writes:
>I'm not really sure whether this should go to comp.unix.questions
>or comp.unix.wizards, so I send it to both.

     When in doubt, send it to comp.unix.questions.  IF no response,
(or responses that say it's a wizard question), then post it to
the wizards group.  (At least this is the rule I remember).

>installed it as if (input(?) filter) and of (output filter), only

     I haven't used 'if' before, but my manual says it is for
accounting?  I suppose 'input' could be derived.

>lpd expects the output filter (the one which prints the banner page)

     You can get the banner without an output filter.

Anyways here are a few things to consider:

	1)  Always use absolute path names.  When lpd is spawned by rc
	    at boot time, it on many systems has an empty environment
	    (ie. no PATH)

	2)  Make sure that the error logging file exists.  If your
	    error file is /usr/adm/lpd-errs (or whatever), that file
	    has to exist, or the errors will not be logged.  This
	    can be a big help, it will freqently tell you what the
	    problem is.  However, when you are done with it remove it
	    because it can grow quickly while not being monitored.

	3)  (wait, there is no 3)

Here are a few points from one of my manuals:

	RE: fields in printcap:

		if:  Output filter that can do accounting

		of:  Output filter, if 'if' is specified, 'of' is only
		     used for the banner page.

		tf,cf,vf: other output filters.

		lf: error logging file

	(The point here is that not all filters are used on each job)
	You don't NEED an 'if' AND an 'of'.  The tf,cf,and vf are used
	if certain flags are passed.  I don't see the use of using 
	BOTH 'if' and 'of' when they are the SAME filter (as you specified
	above).

On filters themselfs:

	Filters are spawned by lpd with stdin the data, stdout the printer
	and stderr the file specified by 'lf'.

	Filters should return '0' exit code for success, '1' if job
	should be reprinted, and '2' if job should be thrown away.

	SIGINT is sent to all the processes when lprm is issued to remove
	a job.

	Arguments passed to filters:

		of filter:  ofilter -wwidth -llength
			(see 'pw' and 'pl' in printcap)
			(I wonder how 'of' can print the banner w/o names)
		
		if filter: 

	ifilter [-c] -wwidth -llength -iindent -n login -h host accounting_file

		-c is present when -l is used on the lpr command.

	All other filters:

	filter -xwidth -ylength -n login -h host accounting_file

	   (see 'px' and 'py' in printcap)

Hope this helps

-- 
**************** Insert 'Standard' Disclaimer here:  OOP ACK! *****************
*  Tony Parkhurst -- {hplabs|sdcsvax|ncr-sd|hpfcla|ihnp4}!hp-sdd!artecon!adp  *
*                -OR-      hp-sdd!artecon!adp@nosc.ARPA                       *
*******************************************************************************