*BSD News Article 31114


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!bunyip.cc.uq.oz.au!munnari.oz.au!constellation!convex!convex!cs.utexas.edu!howland.reston.ans.net!EU.net!sun4nl!news.nic.surfnet.nl!tuegate.tue.nl!rcpt
From: rcpt@urc.tue.nl (Piet Tutelaers)
Newsgroups: comp.unix.bsd
Subject: Making the Berkeley spooler more POSIX compliant
Date: 31 May 1994 10:39:35 GMT
Organization: Eindhoven University of Technology, The Netherlands
Lines: 106
Message-ID: <2sf457$ltv@tuegate.tue.nl>
NNTP-Posting-Host: nms.urc.tue.nl


When we moved from Ultrix (BSD compatible) machines to Irix (SYS5) I needed
a true Berkeley spooler. Although SGI provides a Berkeley spooler it turns
out that this is highly unreliable. Especially the interaction between the
OF filter (run when there is work to do for a printer) and the IF filter
(run on a per file basis). After asking if somebody else already has made a
portable POSIX lpd spooler it turned out that that was not the case. So I
tried to do it myself. Here is what I made from it.

There were several problems to overwin to get a running lpr on SGI:
 - isolation of the spooler sources from other Berkeley sources
   Lpd uses the Berkeley libutil.a library for an implementation of
   daemon(). This function is added to lpd and its Makefile.

 - Make incompatibilities
   The BSD4.3+ Makefiles changed by portable ones.

 - non-ANSI functions index() and rindex()
   replaced by their ANSI equivalents strchr() and strrchr()

 - non-POSIX constructs 
   BSD functions which can be written in POSIX are isolated in
   common_source/posix.c while other non POSIX constructs are marked
   with ifdef's _POSIX_SOURCE in the program source itself.

 - BSD/SYS5 constructs
   BSD functions that could not be ported to POSIX, like the sgtty flags,
   are marked with ifndef SYS5. When for such a function a SYS5 equivalent
   was available this alternative is marked with ifdef SYS5.
   * statfs()	used to determine if the job will not overflow a disk
		(on both platforms but slightly different)
   * isexec()   used to determine if a file is an executable (both
                platforms)
   * setty()    used to set terminal characteristics (BSD)

 - new MS printcap facility
   In stead of spending a lot of time in trying to implement the BSD
   tty flags in terms of POSIX termios flags I have used James Clark's
   solution to add a `MS' printcap entry. With this extra capability a
   tty line can be initiated in a POSIX compatible way (for example):
      ms=-isig,igncr,cstopb,-echok

I have put the NetBSD-current lpr sources, from which I started, as a
reference in NetBSD-lpr.tar.gz.  Hopefully some of the patches find
their way back to the BSD spooler. At the end I have written some
suggestions how to improve the BSD spooler.

Here is a short TODO list:
 - I compiled the sources, to see how portable this piece of software really
   is, on Solaris and UNIXware. Lots of compilation errors are still
   there. These errors don't show up on SGI because that system offers
   a mix of SYS5 and BSD functionality.
 - instead of just one single SYS5 compile time flag it would have been
   better to offer an extra BSD flag so that eventually both can be
   selected. All SYS5/BSD features can be furter subdivided into topic
   specific targets like SGTTY, STATFS, etc. In the common_source/lp.h
   these flags can be predefined for SYS5 and BSD so they can easily be
   changed.
 - thorough testing of `ms' printcap option
 - up-to-date manual page for printcap(5) reflecting the changes made
   to the printcap interface.

The only thing I can say is that the sources provided here produce a
more reliable Berkeley spooler for SGI than their standard version.  I
now can use my perl OF and IF filters to do accounting on our HP4Si/MX
network printer.  These perl filters are written on top of the hpnpf
filter that is part of HP's software package for their laserjet
series.  If I had to redo the job I seriously would consider to use the
SYS5 spooler.  But at the time I started it was not clear that we would
move to SYS5 and I had no experience with that spooler.

The STOP/CONT communication protocol used between LPD (its child that
is spawned for the printer being served) and the OF filter is a bad
design choice. With this scheme the OF filter can not initiate the
output connection because when the IF filter is active this OF filter
is STOPed! To overcome this problem hpnpf (from HP) spawns an OF child
process before the OF parent will STOP itself. This OF child process
listens to a socket to which the IF filter can write.  But this makes
the interaction between OF and IF filters even more complicated.

The BSD spooler is very strictly built on terminal based interfaces.
It would be a great improvement when this spooler would allow a
bi-directional communication channel along a `coprocess' in a user
friendly way. I have the following in mind:
	lp=/usr/bsd/telnet address port:rw:

When LPD needs to initiate the connection and sees that the LP-entry is
no tty but a runnable program (with some arguments) it can setup a
pseudo terminal connection to that program. Giving this possibility
writing the OF and IF filters would be very straightforward. Implementing
this feature can't be difficult after studying the pty program given in
chapter 19 of W. Richard Stevens book (Advanced programming in the UNIX
environment/ Addison-Wesley/ ISBN 0-201-56317-7).

--Piet
30 May 1994

The sources are available in ftp.urc.tue.nl in ~ftp/pub/sgi:
	posix-lpr.README (this file)
	posix-lpr.tar.gz (my ANSI/POSIX enhanced version)
	NetBSD-lpr.tar.gz (the NetBSD-current version as of April 1994)

internet: rcpt@urc.tue.nl       __o      Piet Tutelaers
bitnet: rcpt@heitue5.BITNET   _`\<,_     Computer Center       Room  RC 1.90
phone:    +31 (0)40 474541   (_)/ (_)    Eindhoven University of  Technology
fax:      +31 (0)40 434438  Save nature  P.O. Box 513, 5600 MB Eindhoven, NL