Version LPRng-3.8.22 - Fri Sep  5 08:45:33 PDT 2003

   Updated the LPRng, IFHP, and LPRngTool LICENSE with the new
   Artistic License from the www.opensource.org web site.

   Updated the DISTRIBUTIONS/FreeBSD port information to meet the current
   (new) port format.

   Renamed LPRng HOWTO to LPRng Reference Manual.  Added notes to the
    Printing Cookbook.

  lpf.c - removed log() and fatal().
    (Suggested by: Torsten Rohlfing <rohlfing@IGL.Stanford.EDU>)
  Filter command line options now allows ${X} to reference a control file
    option.  You can now use:
	$X   with -X<value>      (if present)
	$0X  with -X <value>     (adds space)
	$'X  with -X'<value>'    (adds quotes)
	$-X  with  <value>       (drops key)
	$0-X with  <value>       (same as $-X)
	$'-X  with  '<value>'    (adds quotes)
	${ss}  with value of printcap option ss
	$'{ss} with quoted value of printcap option ss or job control file option

    Example:  filter=ifhp -Z '${S},${O}'
    This will get the O and S options from the job control file.  Note that
    $S is the 'printer comment name' and '$P' is the 'actual printer name'.
    (prompted by a question from: Paul Armstrong <army@cyber.com.au>)

   Fixed vars.c 'fifo' option - 
     -{ "fifo", 0, STRING_K, &Fifo_DYN,0,0,0},
     +{ "fifo", 0, FLAG_K, &Fifo_DYN,0,0,0},
   (Thanks to the Debian folks - especially Craig Small <csmall@debian.org>)

   Fixed up printer@remotehost%port parsing so you can do:
      localhost:lp=pr@%P and it gets expanded to:
      localhost:lp=pr@localhost
    This is pretty far down the extrema of wierd... But somebody
    came up with a use for it. Sigh...
   (Lots of head scratching caused by: Michael J. Carter <mcarter@lanl.gov>)

   Filters no longer have file descriptor 3 connected to the 'accounting
   file'.  Since the '-a accounting_file' option provides the name of the
   file and this should be used instead.

   plp_snprintf now handles '*' in floating precision correctly.
   (Patch by: Henrik Edlund <henrik@edlund.org>)

   if( Run_OF_filter(), Status_file_DYN ) problem found.
   (Thanks to the Debian List: Sam Lown <samuel.lown@cern.ch>
     and Craig Small <csmall@debian.org>)

   If you want to use force_lpq_status according to the docs (HOWTO), the
   following patch has to be applied. Otherwise it doesn't work when you have
   several ip netmasks listed as in the example:
     force_lpq_status=s=pc*.eng.com,130.192.12.0/24,l=sun*.eng.com
   Change is:
     -       Split(&l,t,Value_sep,0,0,0,0,0,0);
        Value_sep DEFINE( = " \t=#@" );
     +       Split(&l,t,File_sep,0,0,0,0,0,0);
        File_sep DEFINE( = " \t,;:" );
   (Pointed out to me by: Henrik Edlund <henrik@edlund.org>)

   Updated the configure and src/krb5_auth.c to be consistent with latest Kerberos
   releases.

   Added 'accounting_namefixup' option as suggested by Henrik Edlund <henrik@edlund.org>
    accounting_namefixup=list[,list]*
       where list is:   host(,host*)[=user(,user*)]
    The incoming job is check to see if the originating host (RemoteHost_IP)
    is in the list of hosts;  the first matching one found is used.

    Each host list has the format: host,host... where host has the
    same format used for the 'oh' and other host name matching
    options.  You can  use '!host' to invert matching.  For example:
    host1,127.*,!somehost

    When a host match is found,  the name to be used for the user
    is determined from the user list; if none is specified then no
    changes are made.  Each entry in the user list has the format
    ${option}  or 'name'; the ${option} values are extracted from
    the control file (capital letters) or printcap/configuration
    information (lower case letters/names).  The first non-empty
    value found is used.

    For example:   ${R},${L},${accounting_name},default
     If the control file 'R' option is present, the R option value is used
     else if the control file 'L' option is present, the L option value is used,
     else if the printcap/config option 'accounting_name' is not empty then
     it is used, otherwise the 'default' value is used.

   (Original suggestion and patches by:  Henrik Edlund <henrik@edlund.org>)

   Fought with the various Kerberos distributions and appear to
   have a new version that compiles with the Kerberos 1.3.1 release
   and with other legacy releases.

   Added the "# REJECT NOT SERVER" comment to the lpd.perms file to cause
   LPRng to reject all jobs/connections from external (non-localhost)
   clients

Version LPRng-3.8.21 - Mon Mar 17 07:06:57 PST 2003

  The LPQ 'stalled' indication is now based on status information updates,
  rather than the job run time.  If there has been no status update for the
  specified stall time, i.e. - log file (lf=...) or status file (ps=...) then
  the stalled indication will be displayed.

  Karol Lewandowski discovered that psbanner, a printer filter that
  creates a PostScript format banner and is part of LPRng, insecurely
  creates a temporary file for debugging purpose when it is configured
  as filter. The program does not check whether this file already
  exists or is linked to another place writes its current environment
  and called arguments to the file unconditionally with the user
  id daemon.
    -- reported by security.debian.org
    -- Debian Security Advisory DSA 285-1
      Fixed.

Version LPRng-3.8.20 - Tue Jan 7 09:18:15 PST 2003

  The lpd.conf now uses (EMPTY STRING) for defaults which are
  empty strings... Before it was '0'. Oops.  Patrick

  At the request of Karl Kopper <karl@unfiw.com> I reviewed the issues
  of queue starting,  polling the queues for done jobs, and other
  issues.  A small side effect of this is that the LPD server process
  now starts printing processes.  This is actually beneficial as it can
  now limit the total number of printing processes and allow some
  LPQ/LPC/LPR etc actions. Here is a summary of the current operation
  and the options that control it:
   Options:
      lpd_force_poll - forces a check of the spool queues, even when there
        is most likely no reason to.  Used when you have some REALLY odd
        programs running that will directly manipulate the LPD spool queues
        and you do not want to have to connect to the server.
        (default is OFF).
     lpd_poll_time - interval in secs between checking queues for work.
        Done if there is some reason to suspect that some spool queue
        had problems and might need to be restarted.  This also handles a
        race condition where a job arrives just as the process servicing
        the spool queue exits.
        (default is 5 minutes or 600 seconds)
     lpd_poll_start_interval - if there are spool queues which need service,
        fork up to 'lpd_poll_servers_started' processes at a time and then
        wait for lpd_poll_start_interval seconds before forking more.
        This prevents the deadly situation where the LPD server is started
        and in turn  starts a gizillion process; the rc starupt scripts
        may fail because there are no free processes (I kid you not on this
        one, it drove me nuts trying to find out why the system would crash
        ONLY when LPD ran with NO debugging - the IO caused it to slow down
        enough so that the other scripts could run).
        (default now 1 second)
     lpd_poll_servers_started - maximum number of processs to fork to be
        spool queue servers at a time.  this prevents the massive forking a huge
        number of processes at once.
        (default now 3)
     max_servers_active - the maximum number of children of LPD that are handling
        spool queues.  Since each spool queue process may have up to 5 children,
        and these in turn make fork other ones,  you should make sure that the
        limits for the LPD server are set as high as possible, or use this
        value to throttle activity.  The actual limit used by LDP value
        is the minimum of max_servers_active value and
           maximum children processes per process/2
        as determined by the getrlimit(), sysconf(), or other appropriate system
        calls.  Most problems reported by systems with heavy load are caused by
        restrictive process limits.  Run 'lpd -F -D1 | grep Get_max_servers'
        (as an ordinary user) and see the limits for processes and file
        descriptors.

    Summary:
     lpd_force_poll=0
     lpd_poll_time=600   (5 minutes)
     lpd_poll_start_interval=1  (1 second)
     lpd_poll_servers_started=3  (3 per start interval)
     max_servers_active=1024

    Experiments with heavily loaded systems (FreeBSD 4.7, Solaris
    2.8, Linux RedHat 7.3, and Mandrake 8) indicate that these
    values should not cause system trauma.  Your milage may vary;
    if the load average goes up very high, then set lpd_poll_start_interval
    to a larger value and/or decrease the lpd_poll_servers_started
    value.  Both is best.  The amount of free memory seems to be
    the limiting factor on the system loading.

    When you send a job via LPR, the LPD server forks a 'service socket'
    process to handle job reception;  in previous versions after receiving
    the job the process would then call Do_queue_jobs() to take on the
    duties of the 'handle the jobs in the spool queue' process.  In
    this version the 'service socket' process sends a 'start queue'
    request to the LPD server and then exits.  The LPD service will
    then fork a process to become the 'handle the jobs' process.
    Similarly, when an lpc operation needs to start a 'handle the jobs'
    process,  a message is sent to the LPD server to start the process.

    While there is no real difference in performance on lightly loaded
    systems,  there is a big difference on heavily loaded systems.  Now
    the LPD server can control the total number of active spool queues
    much easier,  and the system does not get overloaded as easily.

    Also, the LPRng server does not clobber the system at startup
    time as badly now.

    By the way,  queues which are started or have jobs put in them
    by LPC or LPR have priority over queues that are started by the
    LPD process looking for work,  and the LPD server will brutally
    try to start as many as possible.  Thus, if you do an 'lpc start all'
    you can bring the system to its knees for a short time until
    all of the forking and file reading activity is completed.
    Since only the administrator can do an 'lpc start' command,
    this should not be an issue...

  Keith ("HP Printer Dies Horrible Death") Rinaldo
  <rinaldok@egr.unlv.edu> has reported that some HP printers lock
  up and do not report status, etc., and display a nasty low level
  error message on the printer console such as 7900FE.  The IFHP
  filter or LPD would sit there waiting for a response.  The 'keepalive'
  TCP/IP facility does not solve this problem,  as sometimes the
  TCP/IP stack is OK but the job handling code (i.e. - print engine)
  is non-functional.  You need to try to get a response from the
  printer,  which is what the IFHP filter does.

  NOTE: send_job_rw_timeout default value is now 0 (no timeout).
  In order to not surprise new users,  the default value for
  send_job_rw_timeout is now 0, i.e.- no timeout.  Details below.

    The send_job_rw_timeout is now used to set a maximum time that
    the printer (network, parallel port or serial port) connection
    will be 'inactive', i.e. - no data input and not available for
    data output, OR, starting with this release, that the various
    filter processes do not update the status file (by default,
    ${spooldir}/status.printer).  When the timeout expires the job
    will terminate with a JTIMEOUT status, which will be treated
    as a JFAIL status.

       /* LPRng internal        process exit status */
       #define JTIMEOUT 43      /* 12 timeout */
    
    The IFHP filter (ifhp-3.5.11) now has a similar 'send_job_rw_timeout'
    option that has the same effect as the LPD 'send_job_rw_timeout'.
    If the file descriptor used to communicate with the printer is
    inactive for this period of time,  then the IFHP filter will
    exit with a JTIMEOUT error code, which will be treated as a
    JFAIL status.

    This will only work if the printer goes totally catatonic and
    does not reply with status, or the print filter goes catatonic
    and does not update the status file.  This situation, unfortunately,
    can happen when the printer is taken offline in the middle of
    a job in order to put paper in the paper tray.  You can't win
    them all...  but if the time taken to put the paper in the tray
    is less than the send_job_rw_timeout then you should be OK.

Version LPRng-3.8.19 - Thu Dec 5 12:34:45 PST 2002
  Check_for_missing_files was not writing control file.
  (Spotted by Keith ("Wanna bet on that?") Rinaldo <rinaldok@egr.unlv.edu>

Version LPRng-3.8.18 - Mon Dec 2 12:08:34 PST 2002
  Added the 'fifo' option  - this now makes LPRng handle
  one incoming job at a time in FIFO order.  If you send
  jobs A B C then they get delivered in order A B C.
  For users who MUST have sequential delivery of jobs.

  Some Linux distributions set 'unlimited' resources for all
  parameters, such as user processes.  Added limit of 1024
  processes for such cases as the system will die a horrible
  death at startup.


Version LPRng-3.8.17 - Sat Oct 26 20:11:28 PDT 2002
  Found a race condition between LPD printing, LPRM, and LPC actions
   that would cause LPD to stop printing if you removed or did
   an LPC action on a job.  After a bit of thought, decided that
   the job would get moved or removed anyways.  Sigh...
   But you might get a bogus error message about 'cannot
   find id' as the job hold file has been removed.

Version LPRng-3.8.16 - Mon Aug 12 15:26:05 PDT 2002

  lpr now honors :mx=xx values so you can check job size
  before you send it.
   (Suggested by:  Rick Cochran <rcc2@cornell.edu>)

  configure --disable-werror removes the -Werror option from CFLAGS.
   (From the wish list of: Rick Cochran <rcc2@cornell.edu>)

  Bad incoming jobs are removed.  You do not get the jobs
  left in the queue as errors.  Note - spoolers will
  keep trying to send jobs even when they get error and
  sit in an endless loop.  No solution for this one except
  to get a better print spooler or whatever...

Version LPRng-3.8.15 - Sun Aug 11 13:11:48 PDT 2002
  
  Remove_done_jobs
    - checks to see if the INCOMING flag is set BEFORE
    it checks to see if there is an error and only checks
    for the data files if the ERROR or DONE flags are set.
    This removes a race condition.  It was bloody obvious
    when I looked at it... I wonder why I did not see it
    before?

Version LPRng-3.8.14 - Tue Aug  6 09:14:06 PDT 2002

  man page fixes.
    (Spotted by the eagle eyes of: Eric S. Raymond <esr@golux.thyrsus.com>)

  Based on third hand reports, some installations of GNU compilers
  on HPUX and other systems now have 'fd_set' data types.
  I have modified configure so that it checks for 'fd_set' being
  present.  I wish there was a way to read the man pages and
  find out if this was the real case.

  The configure 'enable-ssl/disable-ssl/' option was not working.
  Once again beating on autoconf 1.53 ...  It now understands
  'enable-OPTION' and 'disable-OPTION'.
  
  The Samba examples in the LPRNG-Howto were not consistent.
   changed 
        queuepause command = /usr/sbin/lpc -P%p stop
        queueresume command = /usr/sbin/lpc -P%p start
   to
         queuepause command = /usr/local/sbin/lpc stop %p
         queueresume command = /usr/local/sbin/lpc start %p
   (Suggested by: Jim Van Sickler <vansickj-eodc@Kaman.com>)

Version LPRng-3.8.13 - Mon Jul 22 09:07:57 PDT 2002

  Major Enhancement In Printcap and Configuration Functionality
  After much consideration, added the 'client.xxx' and 'server.xxx'
  facility.  Briefly,  if you have a printcap entry of the form
  client.xxx or server.xxx then this can be used to set the corresponding
  xxx variable when the printcap entry is used by the lpd server
  or the LPRng client programs lpr, lpq, lprm, checkpc, etc.

    Entry               Program Type          Sets
    server.xxx = vvv    lpd (server)          xxx = vvv
    client.xxx = vvv    lpr,lpq... (client)   xxx = vvv

  The purpose of this enhancement is to allow a single printcap
  entry to be used for both client and server operation, especially
  in situations where the lpd server is forwarding or sending jobs
  to another lpd queue.

  Example of use:
    lp:
        # used by clients, forcess them to send to
        # specified server
     :lp=%P@server.hostname:force_localhost@
        # used by lpd server
        # the server will now send jobs to the
        # specified destination
     :server.lp=%P@destination

  This is equivalent to and replaces the :client and :server
  printcap flags, as shown below:

    lp:client
     :lp=%P@server.hostname:force_localhost@
    lp:server
     :lp=%P@destination

  This selection operation also works with values in the
  lpd.conf file, allowing global overrides for clients and
  servers.  (I can't imagine a use for this,  but it is there
  if somebody wants to use it.)

  The lpc client and lpc server commands will display the
  selected client.xxx and server.xxx values.  They are also
  propagated to the PRINTCAP_ENTRY environment variables
  for filters.

  Typo's in documentation corrected.
  (Patch by: Stepan Kasal <kasal@math.cas.cz>)

  lpr Kerberos authentication failures were not being reported.
  (Problem noticed by: Rick Cochran <rcc2@cornell.edu>)

  Added SSL authentication.  See the README.SSL.SECURITY file for
  the truly complicated details.  Note that testing with certificates
  signed by non-root CA indicates that the client is not sending
  a certificate, even though one has been requested and the
  certificates and signing certs are in the right places.

  lpd.conf did not have 'include' functionality working.
    (Patch by: Stepan Kasal <kasal@math.cas.cz>)
  
  Added Yet Another LPRng Option: user_is_authuser
      user_is_authuser:
       if( header_info && User_is_authuser_DYN
               && (s = Find_str_value(header_info,AUTHUSER,Value_sep)) ){
               Set_str_value(&job->info,LOGNAME,s);
               DEBUG1("Check_for_missing_files: authuser '%s'", s );
       }
  printcap:
  lp:auth=kerberos5:user_is_authuser:...
   Causes the principle name to be used as the user name.

  lpq_in_perl was screwed up
  (Patches by: Anthony Thyssen <anthony@cit.gu.edu.au>)

  generate_banner core dumped.  Turned out not to be setting
  banner format ("f") when generating entry, so that control
  file generation core dumped when generating new control file.
  (Problem reported by: "Keith Rinaldo" <rinaldok@egr.unlv.edu>)

  Updated Remove_done_jobs to sort jobs by completion time.
  Added 'Set_nz_flag_value' function to stop the ERROR_TIME value
  from being gratuitously updated by various routines.

  Found possible cause of 'job data files not removed' problem
  in the Remove_done_jobs() code.  There is a possibility of a
  data file being orphaned if a 'done job' is removed by the
  spooler at the same time that another processes such as lpq
  information gathering examines the print job.  Rare, but possible.

  Put warnings in the LPRng-HOWTO section on Samba about the
  done_jobs option and interaction with SAMBA job status.
  (Suggested by: Marcus Manske <manske@dramedia.de>)

  Added yet another wakeup and kick to the master server process
  so that printer pools will respond faster.  Sigh...

Version LPRng-3.8.12 - Mon May 6 08:21:49 PDT 2002

  patch for TCPWRAPPERS added a gratuitous -lwrap to the src/Makefile.
  (Spotted by: Rabellino Sergio <rabellino@di.unito.it>)

Version LPRng-3.8.11 - Thu Apr  4 07:49:30 PST 2002

  Subtle problem when a filter fails and produces zero
  length file.  This is now treated as a JABORT level
  error.  The problem is that RFC1179 treats a file
  length as 0 as a 'read until end of file on socket'.
  This means that folks who have filters that WILL produce
  zero length files need to do something to produce at
  least one byte of 'dummy' output.
    (Brought to my attention by:
      Sergij Kovalenko <s.kovalenko@drgueldener.de>)

  Fixed up a portability issue for Solaris 2.6, in linksupport.c.
  Need to do an unsigned long cast to do comparison of INADDR_NONE.
  (Original patch from: Dr Andreas F Muller <afm@othello.ch>)

  Added patches to support TCP wrappers.  Use:
    configure --enable-tcpwrappers
  (Patch by:  Tobias Burnus <burnus@net-b.de>)

  Added a 'Linux Standards Base' (LSB) style startup script
    for Linux systems.
  (Provided by:  Tobias Burnus <burnus@net-b.de>)

  Missing initialization for statb
  (Patch by: Rob Joyce <robjoyce@EE.Princeton.EDU>)

  Clobbering Logfile_LPD in common/lpd.c
  (Patch by: Hugh McDonald <hugh@gw1.symac.dhs.org>)

  Added a call to 'Remove_done_jobs()' in lpd_status.c;
   then modified Remove_done_jobs to return indication that
   a job was removed so that lpd_status.c would RESCAN
   queue... Sigh... OK, but it now works 'right'.
  (Stale jobs not getting removed noted by:
    Richard Ems <r.ems.mtg@gmx.net>)

  The problem of saturating a server when checking for work was
   re-examined.  The new approach is:
    a) if some work was done,  then check for success at
        lpd_poll_time intervals.  If there remains work to
        be done and there is no process actively doing the
        work, mark the queue as needing service.
    b) for the marked queues, start at most 'lpd_poll_servers_started'
       queues at once,  and start these at intervales of
       'lpd_poll_start_interval' seconds.
   The effect of this will be to limit the number of processes
     that LPD will start at a time.
   (Pushed to look at the problem by: Johan Bengtsson <elijah@dd.chalmers.se>)

  Found a very odd bug... the escape code for '\:' in printcap entries
   appears to be broken.  The fix was to assume that the only places where
   it would be used was in 'filter' or other options where the 'expand
   escape sequences' code would be called and would take care of replacing
   "\:" by a ":".
.
  The 'Printer_device()' routine, when opening a filter as an output
  device, did not provide 'stdout' for the filter.  Some filters such
  as pap from Appletalk seem to need this as they produce messages
  on STDOUT (fd 2) as well as STDERR (fd 3).

Version LPRng-3.8.10 - Sun Mar 31 11:31:19 PST 2002

 printcap.5 had :as and :ae examples reversed
  (Spotted by the guy with the red pen and the eagle eyes:
    Craig Small <csmall@eye-net.com.au>)

 Slew of patches sent in by Tim Waugh <twaugh@redhat.com> 
   - silly little kerberos include file patch
   - can't spell printer patch
   - si no moleste the files in the spool queue patch
     (already done)
   - added configure ability to find 'pr' program
   - GCC flags -W -Wall -Werror -Wno-unused-parms
      - also fixed up &*)*(&)*(& unsigned and signed
        integer casts
 Added patch to allow tcp wrappers to be used.  Configure updated
   configure --enable-tcpwrappers     use tcp wrappers (-lwrap)
   (Patch from: Tobias Burnus <burnus@net-b.de>)

 The authentication and connection information for permissions
  checking is now recorded so it can be used for permissions checking.
  and a couple of new fields have been added.
  The following permission tags now have the indicated values
   UNIXSOCKET - true (match or 1) if connection was over a UNIX socket,
     i.e. - the local host.
   When SERVICE=P 
     REMOTEHOST - the original remotehost from which the job was sent
      (previously was the HOST value)
     REMOTEPORT - the original port from which the job was sent
      (previously was undefined )
     AUTH - true (match or 1) if job sent using authentication
     AUTHTYPE - authentication type
     AUTHUSER - value of authentication key for user who originated
        job.  For example, for kerberos this is the user's principle value
     AUTHFROM - value of authentication key for sender of job.  For example,
        if the job was from the LPR program,  this would have the same
        value as AUTHUSER.  However, if it was forwarded from a server,
        it would have the server's authentication name or value.
  lpd.perms.in update to match the new entries
   (Requested by: Toby Blake <toby@cogsci.ed.ac.uk>)

  Once again the checkpc file creation stuff is modified so that
   it can create files in a directory NOT owned by the lpd group/user.
   This is necessary for log files and other items.  Note that this
   MAY cause problems for log file truncation as you need to copy
   file contents rather than just renaming them.  But it turns out
   that I am already doing this so it appears to be OK.
     CAVEAT EMPTOR.
   (Reported by: Torsten Wiebesiek <wiebesiek@tnt.uni-hannover.de>)

  Usage messages now display version information as well as options
   and available debug flags.  Idea shamelessly swiped from somebody else.
   (Stolen from: 'Guido' Van Rossen)

Version LPRng-3.8.9 - Sat Mar  2 15:02:11 PST 2002

  The 'unix_socket_path' and 'lpd_port' options have been modified
  slightly to correct some ambiguous behaviour, and a 'lpd_listen_port'
  option has been added.
    lpd -p lpd_listen_port -P unix_socket_path
     - the -p and -P command line options override the
       lpd.conf lpd_listen_port and unix_socket_path options
     - the default values for lpd_listen_port is "", indicating
       the use the 'lpd_port' value.
   The value "off" suppresses opening a port or socket.

     This allows the following operation:
     No unix socket:
        lpd -Poff   (/etc/lpd.conf unix_socket_path=off)
     No lpd listening socket:
        lpd -poff   (/etc/lpd.conf lpd_listen_port=off)
        Note that LPD will still open connections to the
        remote LPD servers using 'lpd_port'.
   If you want to override the destination lpd port, you must
      modify the lpd.conf file.

  Jeff Chua of FedEx (Federal Express) <jchua@fedex.com>
  showed up at my office armed with a set of test scripts and a laptop
  running LPRng.  He demonstrated the problem of the 'missing datafile'
  during job transfers.  I have fixed the problem in this release.
  See the UTIL/testpr file.  
   (Thanks to: Jeff Chua: <jchua@fedex.com>)
    
  more autoconf + automake + libtool insanity:
     WITH_LINK removed
     STRIP now used by libtool, changed to STRIP_OPTION
     Added AC_C_VOLATILE (see note on volatile below)
  (Reported by: Rick Troxel <rick@helix.nih.gov>)

  Forced a rescan of the input queue when the number of done jobs
   exceeds 'done_jobs' or the time since the first done job exceeds
   done_jobs_max_age .  This solves a silly problem that shows up
   when you have a slew of jobs in a queue,  the subserver is processing
   them,  and no new jobs arrive while it is processing them.  Under these
   conditions the 'done jobs' would not have been removed until all were
   done.  If you were printing 1000 jobs then you could not submit any
   new jobs, even though you have done 999 of them... :-)

   Sigh... these boundary conditions are the pits.

  Added the 'volatile' option to declarations of static and nonstatic
  variables updated in signal handlers.  You really don't want to
  hear the frothing about over-enthusiastic optimizing compilers, do you?

  Ran the Kerberos tests, discovered minor definition problems with
  krb4_auth.h and Kerberos4 support.  Have no way to test this,  hope
  the problem is resolved.

  The AUTHUSER information received at job submission time was not
  being stored and used later when printing permissions were checked.
  (Discovered by: Toby Blake <toby@cogsci.ed.ac.uk>)

  Added a 'UTILS/README.ForKerberosHackers' file so that Kerbero Hackers
  can quickly and brutally set up a test LPRng system.  Not for the
  faint hearted.  Carry a dog nummy when you read this stuff...

  Some users hit themselves in the head and complain about headaches.
  If the 'lpd_port' value is 0,  then checkpc and lpd squawk.
   (Not telling me who the user was, but reported by:
      Craig Small <csmall@eye-net.com.au>)

 

Version LPRng-3.8.8 - Sat Feb 23 07:35:45 PST 2002

  Restored include file functions to lpd.conf.  Also put in recursion
  depth checks so that it will stop if you have a loop.

Version LPRng-3.8.7 - Fri Feb 22 12:24:38 PST 2002

  Modified the wildcard lookup so that it returns some sane
   values for defaults, i.e. - '*' is not treated like
   a real printer and the first 'real' printer is used.
     Sigh...

  autoconf, automake, and libtoolize insanity.
    Each of these facilities has a different version of the
    config.guess and config.sub files, and will brutally copy
    them to the distribution directory when you run automake,
    autoconf, or libtoolize.  Problem sort of solved by
    running through the /usr/local/share/{auto*,libtool}
    directory and finding latest versions of things.  As the
    CarTalk guys say, "Bo-0H-OH-OH Gus!".  Sigh. 

  The 'Service_connection: bad request...' error message now has
   the IP address of the sender added.
  (Good idea from: Rainer Tammer <rainer.tammer@spg.schulergroup.com>)

  Makefile.in had the diagnostic options left enabled after
   regression tests.
   BAD! Bad Programmer! BAD! No coffee for you today.
   (Reported by: Petri Kaukasoina <kaukasoi-lprng@elektroni.ee.tut.fi>
      among others...)

  Portability stuff,  // comments, and src/Makefile referencing
   ${SRC}/../UTILS instead of ../UTILS.
   (Reported by: Hans Peter Verne <h.p.verne@usit.uio.no>)

  Missing check in lpstat for end of string condition:
   for( t = Printer_DYN; t && !isspace(cval(t)); ++t );
    => for( t = Printer_DYN; !ISNULL(t) && !isspace(cval(t)); ++t );
   (Reported by: Villy Kruse <vek@pharmapartners.nl>)

  psbanner was creating a /tmp/before file.
   (Reported by:
     Anthony R Iano-Fletcher <Anthony.Iano-Fletcher@cbel.cit.nih.gov>)

  Fixed the 'job done' status message so that it shows the job id.
   (Suggested by: Christoph Beyer <christoph.beyer@desy.de>)

  Added some sanity checks to handle cases when hold files and
   control files do not have identifier information in them.

  Checkpc now checks for duplicate spool directories.

Version LPRng-3.8.6 - Fri Feb  8 19:31:52 PST 2002

  HF_NAME not getting set when hold file read and it is not
  in file.  This makes updates miserable.
  (Problem spotted by: Helmut Jarausch <jarausch@igpm.rwth-aachen.de>)

  Fixed typeo in configure where I had unixsocket and unixsocketpath
  instead of unix_socket and unix_socket_path...
  (Pointed out by: Craig Small csmall@eye-net.com.au)

  Modified the host/printer lookup behavior when clients
  are using 'force_localhost'.  You now use the 'original'
  queue name rather than the 'destination' queue name.
  Wonder how long this has been there.
  (Prompted by a problem report from: Andrew Gray" <grayaw@egr.unlv.edu>)

  Missed a 'AF_UNIX' definition.  Now guarded with ifdefs.
 
  Corrected LPRngHOWTO accounting information:
   (Error reported by: "Dirk Krause" <d.krause@fh-sm.de>)

    Example:
     lpd generates:  
      jobstart  - from the lpd.conf 'as=' option
      jobend    - from the lpd.conf 'ae=' option
        -H   - host name
        -n   - user name
        -P   - printer
        -k   - control file name
        -b   - byte count of job/file
        -t   - current printing time
        -J   - Jobname (if present in control file)
        -C   - class (if present in control file)
        -M   - mailname (if present in control file)
    
     ifhp filter generates:
       start/end         - of filter, for entire job
       filestart/fileend - if or other filter, for each file
       (options above are same)
        -A  - identifier information (if present in control file)
        -q  - process id of filter
        -p  - current value of page counter, 0 indicates no
              page counter on printer or it is not readable
    
    jobstart '-Hh110.private' '-nroot' '-Plp' \
       '-kcfA129h110.private' '-b48780' '-t2001-10-19-09:36:36.000'
                               ^^^ bytes in file
    
    start '-q26130' '-p105340' '-t2001-10-19-09:36:38.330' \
                     ^^^^^^^  starting page counter value for job
        '-Aroot@h110+129' '-nroot' '-Plp' 
    filestart '-q26132' '-p105340' '-t2001-10-19-09:36:38.350' \
                          ^^^^^^^  starting page counter value for file
        '-Aroot@h110+129' '-nroot' '-Plp' 
    fileend '-b19' '-T435' '-q26132' '-p105359' '-t2001-10-19-09:43:51.504'
                                      ^^^^^^^  ending page countvalue for file
             ^^^ number of pages printed for this file
        '-Aroot@h110+129' '-nroot' '-Plp'
    end '-b19' '-T435' '-q26130' '-p105359' '-t2001-10-19-09:43:51.504'
                                      ^^^^^^^  ending page countvalue for job
         ^^^ number of pages printed for this job
        '-Aroot@h110+129' '-nroot' '-Plp'
    jobend '-Hh110.private' '-nroot' '-Plp' \
        '-kcfA129h110.private' '-b48780' '-t2001-10-19-09:43:51.000'
                               ^^^ bytes in file

Version LPRng-3.8.5 - Tue Jan 22 15:58:46 PST 2002

  Added a minor fix to lpq so that it will check all queues.
   (Courtesy of Jim Trocki <trockij@transmeta.com>)

Version LPRng-3.8.4 - Thu Dec 13 08:25:17 PST 2001

   ARGH! ARGH!  screwed up lpq -a by forgetting to
   get the 'all' printer information.  Doh!
   (Spotted by and slapped his forehead by:
      Patrick Powell <papowell@lprng.com>)

   "Why do we need a TCP/IP port?"  quoth the raven,  I mean
   Craig Small <csmall@eye-net.com.au>.
   "I have a version that has this facility..." respondeth
   Patrick ("Mr. Grumpy") Powell.  "But I think you will not
    be happy".  I merged the two versions.  Be Happy.

   configure:
     Added these options
       --enable-unix_socket  (default disabled)
       --with-unix_socket_path=PATH  (default /dev/lprng)

   /etc/lpd.conf:
    OPTION      TYPE   DEFAULT PURPOSE
     unix_socket FLAG   1       enables/disables the UNIX socket
     unix_socket_path STR   /dev/lprng    path to the pipe using this

    Also: lpd_port = 0 will disable the TCP/IP port

     lpd -p 0    - disables the TCP/IP port
       or /etc/lpd.conf  lpd_port=0
     lpd -P /path   - enables, unix socket specified by path
       or /etc/lpd.conf  unix_socket@
     lpd -P off     - disable unix socket

      Permissions:
       Connections to the UNIX socket will appear to come
       from localhost, (127.0.0.1) port 0.  You can use the
       UNIXSOCKET to check for this condition, or explicitly for
       localhost/port 0
         ACCEPT/REJECT ... UNIXSOCKET
    Also updated the INSTALL note.

   checkpc:  I was using 'To_daemon()' calls all through the
     code.  This was not needed and would cause a substantial
     slowdown in operation.  I now do exactly ONE call at the
     start of operations.

   updated the config.guess and config.sub to the latest version
   provided by autoconf.

   Incoming jobs now have a status entry.  This is to support IPP
   and status reporting for incoming jobs.  The idea is that you
   can start transferring a job and then,  when the whole job is
   transferred,  the job will be done.  To make this happen you
   need to put an entry in the queue to act as a place holder and
   reserve the job number for this action.  When transfering an
   IPP job,  you can send it in chunks.  This now allows the IPP
   system to send the job header (request), set up the job status,
   and then the job contents.  Just to make life interesting...

   Found some places where I was using 'sizeof(xxx)' instead of a
   passed value for an error message buffer.  Very short error
   messages - 3 chars long... :-)

   LPD now REALLY uses the lock files to prevent multiple
   instances from running.  This might/will/could break on
   systems that NFS mount their lock directories.

   Cleaned up the error message about bad print job formats.
    Clearly there are some REALLY strange printing systems out there.
    (reported by: Phil Moses <pmoses@physics.ucsd.edu>)

   Checkpc -A XX -r now has nicer format:
     t1:  file 'hfA877', age 24.57 hours > 24.00 hours maximum
     (Spotted by: (Craig Small) csmall@eye-net.com.au)

   Added the following to the pass_env options:
    LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
    LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
    LC_IDENTIFICATION LC_ALL
    This should help with LOCALE support.

Version LPRng-3.8.3 - Mon Dec 10 20:40:02 PST 2001

   Fixed the operation of 'lpr -Pxx' when printcap for xxx
   has the format:
     xx:direct:lp=...
     Sigh... too many special cases...
       (Pointed out at LISA2001, and fixed on site...
       Now who was that masked Sysadmin???...)
    (From the mailing list:
      James Thomas Klaas <jklaas@engin.umich.edu> )

   Removed spurious commas in control file Z options.

   Configure did not set 'done_jobs_max_age' correctly.
   (Patch from: Dejan Ilic <dejan.ilic@home.se>)

   lpc flush now cleans out status as it should have done...
    GRRR... user pointed this out at LISA 2001...

   Fixed up a problem with global variable Name.
      From:  Rick Cochran <rcc2@cornell.edu>
    I got LPRng to build under OSX.  It required only one patch which
    seems to be due to the fact that "Name" is declared "extern" all
    over the place, but is only defined in getopt.c.  Since lpstat
    doesn't use getopt, ld complains.  I'm not sure why GNU ld should
    complain under OSX and not on other platforms.
     (Patch by:  Rick Cochran <rcc2@cornell.edu>)

   Editted the lpr man page.  Updated the information about
    obsolete options.

   Updated the installation procedures for FreeBSD, linux, etc.
   The STANDARD_configuration script now checks to see if there
   is a /usr/share/man and if so, runs  configure with
   --mandir=/usr/share/man.  Man pages now show up in the
   right place.  This was true on *BSD, various LINUX distros,
   and some versions of SunOS/Solaris.

   Updated the DISTRIBUTIONS/FreeBSD entry and the postinstall
   scripts so that the port stuff works better.  Now if you do:
         cd LPRng/DISTRIBUTIONS/FreeBSD*
         make PREFIX=/usr SYSCONFDIR=/etc
   You will get the same effect as:
         cd LPRng
         sh STANDARD_configuration
         make clean all install
   But, as you might suspect, there are some minor gotchas.
   The man pages usually get installed in /usr/share/man, but
   when you use the PORT system and override PREFIX it
   insists on installing them in /usr/man... and various
   versions of the FreeBSD and OpenPort stuff INSISTS that
   when generating a port that the originals of the man pages
   are in the ${PREFIX}/man/manX directories.

   I gave up and cheated:  you get an obnoxious warning to
   either create /usr/man or to make a symbolic link from
   to /usr/share/man from /usr/man before installation starts.
   I know, I know.  But I don't have that many brain cells
   left to fry...


Version LPRng-3.8.2 - Mon Dec  3 12:26:52 PST 2001

  MAJOR CONFIGURATION CHANGE:

  LPRng can retain status of last N completed jobs
     configure --with-done_jobs=N
         - set done_jobs value, default 1
     configure --with-done_jobs_max_age =N
          - set done_jobs_max_age value, default = 0 (no expiry)

     Or in the printcap/lpd.conf:
       :done_jobs=1
       :done_jobs_max_age=1

   Example:
    Printer: t1@h110 'Test Printer 1'
     Queue: no printable jobs in queue
     Server: no server active
     Status: job 'cfA231h110.private' removed at 18:25:36.281
     Rank   Owner/ID         Class Job Files             Size Time
    done   papowell            A   278 /tmp/hi              3 18:25:31

  Controlled by:
    :save_on_error        - all jobs with error saved, status not removed
    :save_when_done       - all jobs with no error saved, status not removed
    :done_jobs=N          - last N jobs completed (error or no error) saved
    :done_jobs_max_age=N  - jobs with status older than N seconds removed

  This is best explained by:
    On job completion:
    if( (no error && save_when_done)
       || (error && save_on_error)
       || done_jobs > 0 || done_jobs_max_age > 0 ){
      do not remove job
    }

    When queue updated:
    if( !(save_on_error || save_when_done) ){
       while( done_jobs_max_age >= 0
         && the time since completion of oldest done job > done_jobs_max_age ){
               remove the oldest done job
       }
       while( done_jobs >= 0 && total number of done jobs > done_jobs ){
          remove the oldest done job
       }
    }

  Fixed up the order of 'require_explicit_q' in the variable list.

  Added 'lpd -p port' so that lpd port can be specified at run time.
   (Suggested by: Chris J. Herbst <chris@herbst.com>)

  Added 'PrintingCookbook' to the distribution.

  The 'shorthost' DNS lookup result was not being set correctly
  if DNS lookup failed and you had to drop back to using IP address.
  Clearly the shorthost form of IP10.0.0.1 is IP10.0.0.1, not
  IP10.

  Added patches to help support Win32 porting using Cygwin:
  UID 0 is now ROOTUID instead of 0 value.
  ROOTUID is set by ifdef in portable.h

  checkpc -f no longer puts out the annoying '/var/run/lpd.515
   does not exist' message.

  List_sep (which is only used in Check_for_rg_group) needs
  a comma.
    (Discovered by: Graeme Wood <Graeme.Wood@ed.ac.uk>)

  Reworked the 'start lpd subprocess' code so that it is a little more
  civilized.

  Modified portable.h so that LPRng compiles properly on HPUX 11.xx
  systems.

  lpc help fixed up - 'redo - reprints jobs'

  Cleaned up the 'Make_sort_key' code so it does not do needless
   malloc.

Version LPRng-3.8.1 - Thu Nov 15 16:08:41 PST 2001

  The original default actions and values for the LPD_PRINTCAP_PATH
  have been restored, as it broke too many other things.  A work around
  for the problems with using LPD and database based configuration
  has been found... ugly, but it works.

  Chooser also now will wait when it cannot find a queue instead of
  just exiting.  This solves the problem of 'hung' load balance print
  queues using 'chooser' support.

  Trim the accounting file information.  This now solves the 'mysterious
  full spool partition' error messages.

  'indefinately' is really 'indefinitely' ... so says 'ispell'

  The 'remove_z' now really removes 'Z' options.
   (Found by: Ryan Lovett <ryan@stat.Berkeley.EDU>)

  The 'require_explicit_q' added for those folks who absolutely require
  that a queue be specified and do not want them to use a default queue.
   (Patch to code supplied by: James Thomas Klaas <jklaas@engin.umich.edu>
     with a little help from Dan Escapa)

  Grrr... left in a line of code when I was doing some testing of the
  setuid functions in Win32 and screwed up the setuid stuff.

  Fixed up a silly problem with file descriptor 0 not bound to
  /dev/null in lpd subprocesses.

  Fixed the 'Trim_status_file' routine so that it now treats file
  descriptor 0 and -1 as 'closed' files.  This prevents some silly
  problems with initialization.

Release LPRng 3.8.0 Mon Oct 15 12:09:13 PDT 2001

   At line 174 in accounting.c:
     } else if( safestrncasecmp( s, "hold", 4 ) ){
   This should be
     } else if( !safestrncasecmp( s, "hold", 4 ) ){
   otherwise anything send back to lpd from the accounting filter
   other than accept will result in a JHOLD!
    (Spotted by: "C. L. McAvaney" <chrismc@deakin.edu.au>)

   Added :force_ipaddr_hostname option.  This causes the IP address of the
   remote host to be used for the hostname, overriding the information
   in the control file.  This can be used when you really need the
   IP address rather than the hostname in the control file.
     (Needed by: Rick Cochran <rcc2@cornell.edu>)

Release LPRng 3.7.9 Mon Oct 15 06:18:43 PDT 2001

  Version control strikes again.  Sigh...
  Now all the files are carefully put into place
   (Fumble fingers by:  Patrick Powell <papowell@astart.com>)

Release LPRng 3.7.8 Tue Sep 25 12:35:46 PDT 2001

  Can't spell... fixed typos in man pages.
  (Corrections from: Karsten Weiss <knweiss@gmx.de>)

  lpd_logger.c - free(sp); s=0 ... this sure does make
   free() and malloc() unhappy...
   (Found totally by accident: Patrick Powell <papowell@astart.com>)

  lpr '-Y' (enable lpr_filter) processing fixed up a bit.  Now has better
   diagnostics and information.

  An extremely rare but annoying network condition causes LPQ print
  status to fail.  When running as root (setuid root),  and doing an LPQ
  operation,  the lpq process will try to bind to a port in the low
  port range (512 - 1023).  This will sometimes fail with a timeout
  if the port has been recently used and bound to.  I have put a bit
  more 'randomization' into the selection of the port,  but there is really
  nothing that can be done,  as the TCP/IP error status does not distinguish
  between 'connection refused because you just connected from this port'
  and the remote printer being off line.  Sigh...  The obvious answer
  to this is to bind to the low ports only when needed, but this requires
  users to know when to set the option.  I give up.


Release LPRng 3.7.7 Fri Sep 14 15:54:48 PDT 2001

  checkpc whooped its cookies when running checkpc -f and
  the device is /dev/null (lp=/dev/null).   Apparently I
  cannot set /dev/null to use blocking IO...  Sigh...  So I
  do not count 'changing non-blocking IO to blocking IO'
  as an error.

  i8n French Translation (gettext) added.
  (Supplied by: Francois Mescam <Francois.Mescam@onera.fr>)

  The files generated by the 'incoming control filter' were not
  being re-read by the LPRng system.  Silly me.
  (Discovered by: Tuomas Toropainen <tuomas@nic.funet.fi> )

  The 'bq_format' option was not being handled correctly
  for defaults.  This option has the value:
    bq_format=IoIo...D
       I = original input format (or '*' for wildcard match)
       o = filter output format
       D = default (if present),  otherwise keep original
  It now handles the case where no translation is required
  correctly.
  (Prompted by a question from:
     Rainer Tammer <rainer.tammer@spg.schulergroup.com>)

  Did not check to see that I was a client before doing
    setgroup to daemon.  Stupid of me.  GRRRR... I now have
    a test for this in the code.
   (Warning from: Petri Kaukasoina <kaukasoi-lprng@elektroni.ee.tut.fi>)

Release LPRng 3.7.6 Fri Sep  7 05:36:00 PDT 2001

  There was no call to Getdaemon_group so the default daemon group
  was 0.  This, as they say, was double plus ungood.
   (Spotted and reported with a cackle of diabolical laughter by:
       Petri Kaukasoina <kaukasoi@elektroni.ee.tut.fi> )

  I added a 'half_close' flag so that you can force a 'close(fd)'
  rather than a 'shutdown(fd,1)' to be done for those problem child
  network printers that whoop their TCP/IP stacks and die horrible
  deaths when they get a half closed connection.  This is,  as they
  say, a bug in the print server,  but I have encountered worse.
  The same printers also whoop their cookies when reporting status
  but I don't seem to be doing a half-close on 'lpq' connections
  so this doesn't seem to be a problem.  I have modified the 'lpq'
  code so it does not do a 'half-close'.

   Example:
     lp:lp=host%9100    # happy, well behaved, print spooler box
     lpb:lp=host%9100:half_close@  # buggy print spooler box

  Grammar fixed in LPRng-HOWTO.
    (Red pencil work done by: <Jeffrey.H.Knodel@chase.com>)

Release LPRng 3.7.5 Sun Sep  2 12:43:39 PDT 2001

  I was not closing all open file descriptors.  This caused checkpc and
  lpd (when running as 'spool queue server') to die mysteriously after
  processing a couple of jobs.
  (Clue to cause supplied by: Heiko Burghardt <burghardt@riege.de>)

  The lpc -s status only reported number of jobs.  Now it also reports
  queue status,  as it used to, and should have.  And it reports only
  the number of printable jobs.
  (Patch by:  Garry Zacheiss <zacheiss@MIT.EDU>)

  Patch to accommodate Broken RFC1179 Implemenation #39 from Apple.
  (Gory details and a patch by: Darius Davis <s328919@student.uq.edu.au>)

  The 'Read_fd_len_timeout' and 'Write_fd_len_timeout' code would not
  pause indefinately if the timeout value was 0.
  (Noticed by: David E. Cross <crossd@cs.rpi.edu>)

  A slew of patches from Crutcher Dunnavant at redhat.com:
  From the LPRng-3.7.4-23.src.rpm at the RedHat ftp site:
    LPRng-3.7.4-direct.patch - fixed a typeo in vars.c
    LPRng-3.7.4-inet_ntop.patch - conflicting/duplicate
        definition of inet_ntop.
        NOTE: I also fixed the inet_pton() definition to
        be consistent with the patch.
    LPRng-3.7.4-jobfilescan.patch, LPRng-3.7.4-lockfile.patch
        a little less agressive checkpc operation.  Checkpc
        now does not NOT update the targets of symbolic links.
        This solves the problem of various tools creating
        files in the spool directory as well as symbolic links
        to filters.  The FILES need to be accessible by
        filters running as the LPD user, the targets of the
        symbolic links should not be touched.
    LPRng-3.7.4-kerb5.patch - not used, do not want to hardwire
        paths into configure.  Modified RPM config file to add
        /usr/kerberos/{include,lib} instead
    LPRng-3.7.4-lockfile.patch - lockfile created now
    LPRng-3.7.4-manpage.patch - typo in lpr.1 fixed
    LPRng-3.7.4-nointl.patch - configure using wrong -lintl
        value.
    LPRng-3.7.4-nonblock.patch - changed some blocking opens
        to nonblocking opens in checkpc so that checkpc did not
        hang.  Silly of me not to have done this,  as the
        Check_write() routine even had a nonblocking flag just
        for this purpose.
    LPRng-3.7.4-s390.patch, LPRng-3.7.4-setgroups.patch
        This is a fiddle, not a major problem.  The only
        exploit possible is if the lpd server is started
        with "extra" groups besides the default one.  If
        you do not install lpd SETUID root (which is the default)
        then you have to be root to start this (su root OR login
        as root),  and this means that either login or su is
        not setting up the group membership correctly.
        But it is better to err on the side of paranoia than
        be careless.
    LPRng-3.7.4-shutdown.patch
        Note: the 'shutdown()' patch was NOT applied as it breaks
        a slew of other things.  Clearly we have some problem
        printers out there that need to be identified.
  (Courtesy of: Crutcher Dunnavant <crutcher@redhat.com>)

  Updated GETTEXT/i8n support to gettext-0.10.39.

  The printcap option 'prefix_option_to_option' is declared as a flag in
  src/common/vars.c in both versions 3.7.4 (line 355) and 3.6.26.
  { "prefix_option_to_option", 0, FLAG_K, * &Prefix_option_to_option_DYN,0,0},
  should be:
  { "prefix_option_to_option", 0, STRING_K, &Prefix_option_to_option_DYN,0,0},
  (From: Anthony R Iano-Fletcher <Anthony.Iano-Fletcher@cbel.cit.nih.gov>)

  Redid the authentication documentation and code...  cleaned it up a bit.
  And comments.  And printcap.5 updated, HOWTO updated.  Sort of works now.
  Fixed up '$a' filter options so that :af=xxx is put on command line only
  if it is NOT a filter.  This clears up the mysterious Linux Printfilter
  deaths.

  Permission checking now works for SERVICE=X.  You can only do remote host
  and port comparisions (REMOTE_IP=, REMOTE_HOST=, PORT=).  This was initiated
  by a bug report about address mask generation.
  (From: Willi Burmeister <wib@cs.uni-kiel.de>)

  'lpc client' now displays defaults.

  The changes to use the 'initgroups()' call for setting process group and
  effective group also cleared up problem reported by some Debian users.

  You can now put a colon in printcap entry values using: \:.  This makes
  life a little easier for some folks who need to have options of the form
  "http://...".  You can now do:  filter=/.../sendftp -d ftp\://some/site

  The configure defaults for filter_path (PATH value for filters)
    are now /bin:/usr/bin:/usr/local/bin
  The configure defaults for filter_ld_path (LD_LIBRARY_PATH value for filters)
    are now /lib:/usr/lib:/usr/local/lib

  Reviewed LOTS and LOTS of documentation.  Fiddles all over the place.

Release LPRng 3.7.4 Wed Dec 27 07:10:27 PST 2000
  ARGH ARGH!  Distributed the test version and not the release
  version for 3.7.3 - this has not been a good week.

  The printcap entry '*:client:rm=IPADDR:force_localhost' now works correctly
  with lpq -a.  Side effect: you do not get status if you do not have a
  default printer.  i.e. - 'lp|*:client:rm=IPADDR' is better.

  I now kill off process by using SIGHUP, SIGINT, SIGQUIT and SIGCONT.
    Even Guido thinks this is overkill but expects that there will be
    some system where even this does not work.

  Added a check for the VERSION of gdbm as well.

  ARGH ARGH ARGH... I fixed a problem with signals (SIGINT) killing off
   the process waiting for a lock on a file descriptor,  but I did
   it wrong.
   (Pointed out most gleefully,  complete with TRUSS output by:
     Doug Morris <doug@daynetwork.com>
       AND
     John Perkins <john@cs.wisc.edu>)

Release LPRng 3.7.3 Sun Dec 24 17:47:52 PST 2000
  Updated the default printcap file with a simplified set
   of instructions.
  There was a 'sleep(1000)' instead of a 'plp_usleep(1000)'.
   Needless to say,  this did slow things down a bit.
  LPRng HOWTO Section on Samba had 'printcap file' instead of 'printcap name'
   (Spotted by: Marcel Kunath" <kunathma@pilot.msu.edu>)
  HPUX compilation without GCC had a gratuitious CFLAGS=-Aa.  I removed the flags.
   (Reported by: Ryan Novosielski <novosirj@umdnj.edu>)

Release LPRng 3.7.2 Fri Dec 22 10:45:00 PST 2000
  Discovered that job moves were not working correctly.  Was
  removing the lpd_port value by mistake.

  Close_gdbm() was not defined,  and the #if HAVE_GDBM_H
   confused some compilers.
  (Reported by: Shane Voss <Shane.Voss@glg.ed.ac.uk>)

  ifhp.conf got the 'reverse_priority' description wrong.
  (Proof-reder was: Michael J. Carter <mcarter@lanl.gov>)

  When I added the user printcap stuff I did not set a return
  value and the 'tc=' broke.  Sigh.
  (Reported by:  gizillions of people, including
     Michal Kouril <mkouril@ececs.uc.edu>)

  RFC1179 does not ABSOLUTELY PROHIBIT some print spooler
    expecting multiple LPQ request.  So it does not close
    the connection after sending status.  So I now do a
    shutdown() to cause it to not expect further commands.
   (Detective work done by Rainer Tammer <rainer.tammer@spg.schulergroup.com>)

  The 'short_status_date' and 'full_time' options seem to conflict
    with each other.  The 'full_time' means to use full time formats
    in LPQ status,  and the 'short_status_date' means to use short
    date formats.  The 'full_time' option now controls both of these,
    which is probably what was intended in the first place.
    (Pointed out by: Bill Kemp <bkemp@srp.gov>)

  Get_all_printcap_entries() was not clearing All_line_list so you
    would get duplicate entries. Solved the 'mystery duplicate printer'
    problem observed during testing.

  Natter in the README and INSTALL for Solaris users.

Release LPRng 3.7.1 - Tue Nov 28 06:33:32 PST 2000

 Major Changes That Effect Backwards Compatibility

  1. local printcaps for users - ${HOME}/.printcap
     This allows users to specify a printcap in their local
     directories.  Of course, you can use the 'user_printcap@'
     option to disable this.  But why bother?

  2. job file filtering always enabled

     The classical 'store and forward' behavior has been changed.
     If you have a print queue with filters
        AND you have a file with the format specified for a filter
        THEN the file is filter and the filtered output is used.

     This is CONTRADICTORY to 'vintage' BSD and 'legacy' LPRng
     behavior.

     If you want to have 'job flattening',  that is,  to have
     the job combined into a single file with all the files
     processed, you need to use 'lpd_bounce'.  If you are currently
     using 'lpd_bounce' you will see no difference in behavior.

     The bq_format option is used to get the 'new' formats after
     filtering.  Bq_format has the form:
       OnOnOn...D
         where O is the original format, n is new format,
         and D is default if there is the original format
         is not present.

         If no default then original is retained.

     The bq_format default is now 'f', not 'l'.

     Example:
       bq_format=f    (default)
          all processed files have 'f' format
       bq_format=flmf (default)
          f -> l, m -> f, others unchanged if processed.

   3. lpr -k option is now re-enabled to allow lpr to handle
       pipe input without creating large data files.  Note
       that if you kill programs off then you might end up
       with a truncated job.

       You can use:  cat | lpr -k  OR cat | lpr -k -- -

   4.  You can now have :lpr= Command Line Options
      This will prepend the command line option flags to the lpr
     command.  Note that this now allows you to set up a user printcap
     entry that has command line options suitable for lpr.

   5. Super lightweight no spooler printing to devices
      with filter support.
        New command line options:  -B, -X filter, -Y
        New printcap option: :direct

      SEND JOB DIRECTLY TO REMOTE TCP/IP PORT:
          lpr -Y -Phost%port file1 file2
       OR:
          use :direct flag in printcap
          In your ${HOME}/.printcap or /etc/printcap file put:
            lp:direct:lp=h14%9100:remote_support=R:client
          And use:
            lpr -Plp file  (:direct is effectively the same as -Y)

          Effectively:
            ( for i in file1 file2 ; do ${filter} <$i; done ) > h14%9100
          where ${filter} is chosen from the printcap entry.

          Note: if you do not specify a file then this reduces to reading
                  from STDIN, e.g.-
                  ${filter} > h14%9100

      NOTE EXTREMELY WELL- for 1 file jobs:
             The STDOUT of the filter is the TCP/IP port connection.
      This allows the filter to get status and other information from the
      remote printer.

      SEND JOB VIA A PROGRAM (SAMBA smbclient, for example):

          lpr -Y -P '|/smbclient //server/share' file
       OR:
             lp:direct:lp=|/smbclient //server/share:remote_support=R:client
          lpr -Plp file
             Effectively:
                   ${filter} <file |/smbclient //server/share

      SEND JOB TO LPD SPOOLER (Network Print Server):
          Ummm... well we already do this.  The :direct flag
      and the -Y flag are basically NO-OPS for this.

          lpr -Y -P pr@host file  == lpr -Ppr@host file
        OR:
          lp:direct:lp=pr@host:client
             == lp:lp=pr@host:client

          lpr -Plp file1 file2
             Effectively:
            for i in file1 file2; do filter $i >temp.$i ; done
             lpr -Ppr@host temp.file1 temp.file2 ...

      USER SPECIFIED FILTER:

      To use a user specified filter: lpr -X filter

        Example
           lpr -Y -Phost%port -X userfilter file
        OR:
           lp:direct:...:filter=userfilter:client

           Effectively:
               cat file | userfilter >host%port

      NOTE EXTREMELY WELL- for 1 file jobs:
             The STDOUT of the filter is the TCP/IP port connection.
          This allows the filter to get status and other information from the
           remote printer.


       SPECIAL CASE for lp=queue@host:

            lpr -X userfilter -Pqueue@host file1 file2
            Effectively:
              send control file;
              for i in file1 file2 ; do
                 userfilter $i > tempfile
                 send tempfile;
              done

       EXTREMELY SPECIAL CASE:  -k option

          The -k option with RFC1179 spooling AND a single file will
          case the following actions to be taken:

                send control file
                send a 'expect BIG file' command
                cat userfile | filter > server

         You can also add -X userfilter and get:

                send control file
                send a 'expect BIG file' command
                cat userfile | userfilter > server


       This is done so that you could run
    lpr as a filter and send HUGE data files to the printer.
    This is done by invoking the '0 length file is read to
    EOF' facility of RFC1179.  Unfortunately,  this is
    not supported by all network print spooler boxes,  so the
    'fakelargefile' option allows you to fake this by sending
    a very large file number (in K bytes).  I suggest using
    1000000 - i.e. - a 1 Gigabyte file.

 Start of a new branch:
  iNTERNATIONALIZATIOn (i18n) Support Revisted

 iNTERNATIONALIZATIOn support has been reviewed and incorporated
  in a much more stable and maintainable manner.  Rewrote the
  ABOUT-NLS.LPRng file.  Modified the Makefile to update version
  information in the po/*.po files as well.  Reviewed much of the
  error message and status messages,  and added them to the translation
  list.  Added the N_() facility for 'static' messages and tables.

  On 4 Sep 2000,  a compromise problem with the gettext facility
  was announced.  This was based on the standard 'fprintf' functions,
  which have a '%n' option to allow values to be written to memory.
  I have totally eradicated the use of the standard printf, fprintf,
  and so forth,  and use a safe version of snprintf without this
  capability.  This allows LPRng to be used on systems where similar
  attacks can be launched.  In addition, if the executable is running
  with uid or euid 0 (i.e. - root), then NLSPATH environment variable
  is unset.  This may break some of the 'set process name' code on
  some systems, but I cannot think of another method that will do this.

 You can now use FreeBSD/BSDI/ and most likely some other newer versions
  of the BSD Make in addition to GMake.  What a pain this was.
  If your make supports VPATH it should work.  Hopefully.

 GDBM used to store information.  This now makes handling LARGE numbers
  of files, etc., in a spool queue directory feasible.  Needless to say,
  status generation time is VERY small.

  There are several caveats on this. If you kill off the lpd server
  when it is in the middle of updating the database file,  you will
  end up corrupting the database file or having an incomplete one.
  To resolve this problem, the 'checkpc -f' command can be used,
  as well as the 'lpc flush' command.  Also,  the initial queue
  scan done at system startup will rebuild the databases.

 IPV6 portability was not quite there.  Some minor fiddles.  So I stopped
  playing the violin.  Maybe some time in the future.
  (Fiddling done and patch supplied by: John Perkins <john@cs.wisc.edu>)

 Fixed the lpq.c status trimming functions to be a little more robust.
  Also, put back the recursive lpq functionality.
  (Recursion loss spotted by: Christoph Beyer <christoph.beyer@desy.de>)

 The lpraccnt program is removed from the distribution.  The 'monitor' program
  can be used instead.  I wonder why I had two of these in the distribution.

 The load balance queues are now treated like 'first class' queues and jobs
  moved to them are treated like incoming jobs.  This allows all of the
  incoming filters to be run,  routing to be done, and other abuses
  far too esoteric to grace these CHANGES notes.  This involved doing some
  very odd things with chdir(), etc. to make sure that the filters would
  run with the correct directory.  Also, status information for load balance
  queues changed so that you don't get silly messages about non-existent
  jobs which have been moved to the load balance queue.  Fixed up problems
  when you run out of file space with load balance queues.  Fixed up debug
  and status file information logging with load balance queues.  Fixed
  a really silly design flaw in Setup_printer() that closed the status
  file just when you did not want it closed - and then truncated it.
  Debug file is now closed and opened only ONCE during a call to Do_queue(),
  making it possible to debug the queue service.  All in all, a really
  thorough redoing of the queue handling was necessary to make them
  into first class citizens.
  (Motivated by the questions of: Jason Keltz <jas@cs.yorku.ca>)

 lpd now mumbles at you when you try to start it up and it has
  problems.  Of course, most folks do 'lpd >/dev/null 2>&1' but
  we will ignore them...
  (Inspired by the well chosen arguments of:
   <eric@lammerts.org> and Craig Small <csmall@eye-net.com.au>)

 lpd now CORRECTLY opens output filters - lp=|/path
  (Spotted by: Seth Chaiklin <seth@psy.au.dk>)

 LPRng-HOWTO - Samba example corrected
  (Correction by: Philippe Weill <philippe.weill@aero.jussieu.fr>)

 lpd_port=[ipaddr%]port now will cause lpd to bind to the interface with
   the specified IP address.
   (Prompted by the whingings of some anonymous Debian user and
     forwarded by: Craig Small <csmall@eye-net.com.au>)

 checkpc runtime help was wrong.
   (Spotted by: James P. Dugal <jpd@louisiana.edu>)

 INSTALL_PREFIX replaced by DESTDIR to be consistent with other distributions
   and packages.

 lp -f formname now makes the CLASS information 'formname' as well.
   (Inspired by: Dave Lovelace <dave@fci.izzy.net>)

 In LPRng/common/linelist.c,  many missing checks for null pointers.
   (Found in a core dump supplied by: Mike Whitson <mwhitson@MIT.EDU>)

 lpr -o option is now the same as lpr -Z option
   (Suggestion to save sanity of SYSV users by: Joseph Krahn <jkrahn@nc.rr.com>)

 lpq did not always have a space before job file size.
   (Noted by: Jonathan Briggs <jbriggs@esoft.com>)
Release LPRng 3.6.26 Fri Oct 13 07:38:38 PDT 2000
 unsetenv() is not available on some systems.  Fallback
   to setenv and then putenv() if not present
 (Found by: Niklas Edmundsson <nikke@ing.umu.se>)

Release LPRng 3.6.25 Tue Oct  3 09:19:11 PDT 2000
 syslog Compromise -
   modified syslog to use 'syslog(xx,"%s", msg).
 gettext Compromise -
   added the following to Initialize():
    if( getuid() == 0 || geteuid() == 0 ) unsetenv("NLSPATH");
 IN6_ADDR removed,  in fact IPV6 stuff removed.

   See the various CERT advisories.  Sigh...

Release LPRng 3.6.24 - Fri Aug 11 08:03:23 PDT 2000
 LPRng-HOWTO - added update for Samba print queue configuration.
 LPRng-HOWTO - added section on how to configure Solaris lp printing
  to communicate with LPRng.
  (Changes courtesy of: Gerald Damian <gdamian@ford.com>)
 Typo in gethostinfo.c spotted.
  (Courtesy of the debugging talents of: Robin Sommer <rsommer@uni-paderborn.de>)
 And I removed the wrong line so that the data files were not being
  deleted when a job was completed.  Helps to read the control file and
  get the data file names...
  (Pointed out by: Thomas Emmel <emmel@mechanik.tu-darmstadt.de>)
 There was a 'cut and pasteo' that caused me to use the wrong value
  to get trim lpq status.
  (Core dump and clues supplied by: John Perkins <john@cs.wisc.edu>)
 LPRng HOWTO - added small section on setting up Solaris lp queues to
  forward jobs to LPRng/BSD printers.
 IPV6 Support fixed up a bit to actually work...
  (Spotted during testing,  now that we actually have IPV6 working
  on our router.)
 Added a 'flush cached status' when a spool server exits.  Now you
  get the correct status when there is no active server.
 Modified the 'Read_write_timeout' code to be consistent with reading
  status from parallel port printers the way that the ifhp filter
  does it.
 Found a minor sillyness in the 'send_to_logger()' code - I carefully
  format data and then toss it way.  Now I do checks first.
 Fixed up lpq status generation - only read a small part of the status
  file for information.

Release LPRng 3.6.23 - Fri Aug 11 08:03:23 PDT 2000

 The Linux Printing Summit was held from July 27-28, 2000
  in San Jose,  and was Sponsored by VA Linux.  There was an
  extremely enjoyable interchange of views between all of the
  various interested factions.  You will see some additional changes
  in LPRng as a result of these meetings and the input from users
  and developers.

 Support for status caching has been incorporated in LPRng.
  In addition, 'spool queue lookup throttling' has been
  added in order to improve the speed of status gathering.
  And there are now facilities to control the format of returned
  status.

  This is implemented as follows:

    a) Each queue has a file containing keys corresponding to
       status queries.  For example, if you do 'lpq' then the
       query key would be "4_"  corresponding to the "\004\n"
       query sent to the server.  If you do 'lpq this that'
       you have the key "4_this_that_" and so forth.

    b) Corresponding to each query is a file containg the status
       for the query.  If the status is 'stale', that is,
       older than 'lpq_status_stale' seconds,  then the lookup
       is redone.

    c) When a job is submitted to a queue,  or the status of a job
       changes,  or a control operation is performed on the queue,
       then the cache is flushed.  Currently,  this means that
       the status has to be regenerated for all queries.

    d) If the queue status was changed less than 'lpq_status_interval'
       seconds ago,  then the cached status (if any) will be used.

    e) If the process needs to update the print queue, it will
       attempt to lock the status file.  This means that at most
       one process will be scanning the print queue for status
       at a time.  This has had an extremely good improvement on
       status reporting, especially under high load conditions
       and multiple processes attempting to scan the queue.
       This locking actually improved throughput much to my
       surprise.  A careful analysis showed that by having only
       one or two processes scanning the directory at a time,
       the OS was better able to cache and buffer data.  In actual
       fact,  the second process would then find the files that
       it was looking for already in memory or in the buffer cache.
       Also,  if the two processes were getting the same data
       (lpq -a),  the first one would set up the data in the cache
       and the next one would simply read the cached data.

  The 'lpc flush' command has been added to flush all of the
    cached status.  This was added for testing and for administrative
    purposes.

  A new Super Secret option (well, it is documented now) has
    has been added to the 'lpq' facility.  The following
    only works with LPRng servers (as of this release, of course):

        lpq -- -lines=N   (in general: lpq -- -opt=v,opt=v)

    The '-lines=N' is passed directly through to the LPRng
    lpd server,  where used to set the size of the returned status.
    It is NOT propagated to other servers,  BUT it is used to
    truncate status returned from them.  This will effectively
    give you a VERY compressed status extremely quickly when
    combined with the caching facility.

    The -- is used to indicate that the -lines=N is actually an
    option to be passed through to the server.  This capability
    has been in LPRng,  but this is the first documented use
    of it that will be supported.

    The addition of this facility has some interesting implications.
    You can now have a VERY lightweight lpq facility,  for getting
    the status of one printer,  if you know the server it is on:

    echo "\004printer -lines=2 xx xx xx" > nc host 515
     (nc is the 'netcat' program written by mudge@avian.org)

    Of course you do not have authentication,  etc., but this is
    One Of Those Tradeoffs.  YOU ARE WARNED: USE THE SOCKET CONNECTION
    METHOD AT YOUR OWN RISK AND DON'T WHINE WHEN YOU DISCOVER THAT
    THE LACK OF AUTHENTICATION IS CAUSING YOU PROBLEMS.  If this
    is a problem, use the 'lpq' application and turn on authentication.

    On the other hand,  you can now get printer status WITHOUT the
    use of an 'lpq' process to format it.  I expect the various
    folks building WebServer interfaces for LPRng print status will
    be more than happy now, as this works well in a multi-threaded
    environment,  is strictly socket/connection based.

    Another benifit is that NonLPRng (can you say Microsoft?)
    based applications can now use the -lines=N entry to select
    the amount of status that they want returned.  This allows
    remote clients not LPRng based to select the level of verbosity.

  This work was inspired by the Samba Developers, especially Andrew
  Tridgell, John Terpstra, and Jeremy Allison,
  <http://www.samba.org/samba/team.html>,  and their presentations
  and discussions at the Linux Printing Summit held in San Jose,
  July 26-31, Sponsored by VALinux.

 You can now specify a filter for your input files at the user level.
  This is to support the requirements and/or desires of the various
  users of print spooling software to have a filter applied at the
  application end.

  The syntax is:
     lpr -X /path file1 file2
  equivalent to:
     for each file in filelist; do
       tempfile=maketempfile;
       /path <$file >$tempfile
     end
     lpr $tempfile1 $tempfile2 ...

  The filter is invoked once per job file,  on each job file.
  The options passed to the filter are the usual ones for all
  LPRng filters.  Some will not have any meaning,  such as job
  number, etc., and will not be present or have a '0' value.
  The filter will run as the user's id, and will not have root
  capabilities.  If this is needed,  then the filter must have
  the capability of acquiring them.

  This work was inspired by the GIMP Project presentation of Robert
  Krawitz <rlk@alum.mit.edu> http://www.tiac.net/users/rlk/ Project
  lead for The Gimp Print --  http://gimp-print.sourceforge.net at
  the Linux Printing Summit held in San Jose, July 26-31, Sponsored
  by VALinux.

  I ran into problems with the SysV to LPRng option passing. Apparently
   different versions of SysV printing pass options as S, O, or
   whathave you values in the control file.  The prefix_o_to_z
   option has been replaced by the more general 'prefix_option_to_option'
   facililty.  This specifies the control file option lines to
   prefix to a control file option line.  For example:

    prefix_option_to_option=S,O Z  will prefix S and O to Z
    prefix_option_to_option=Z O    will prefix Z to O.

    This now appears to cover all cases,  and the LPRng HOWTO
    has been modified as well.

  The simple minded 'send mail to user' facility had some problems.
   I fixed them up,  and added a 'sendmail_to_user' flag that allows
   the facility to be disabled for sending mail to users,  but still
   sends mail to operator.  I have also updated the HOWTO with some
   notes about using this facility.
   (Patches sent by: Maja Gorecka-Wolniewicz <M.Gorecka-Wolniewicz@cc.uni.torun.pl>)

  Several calls to Print_job(...) assumed that a file will respond with
   status information,  as would a real printer.  Not a good assumption.
   I wonder where my mind is at somedays...
  The 'Network Grace' timeout should only be used when a server is trying
   to connect - clients should not have to wait.

  I have once again changed the checkpc code to be very very very
   conservative in what it removes from the spool queues.  This will make the
   folks who use netatalk,  etc.  very happy.  The bad news is that files
   put into these directories by other tools will not get removed.  C'est
   la vie,  C'est la guerre...
   (Patches inpiring the changes sent by: "William R. Knox" <wknox@mitre.org>)

  pclbanner had a stupid typeo left over from debugging.
   It wrote debugging information out to /tmp/before
  The 'lpr_bounce' code did not work after the last fix to solve problems
   with Print_job closing files.  Now you can use filters again from lpr.

  I have added the 'wildcard' print queue names and 'incoming_control_filter'
   options.  Together, they implement a way to put options and
   other information into the control file when a job is submitted.
   This method was exploited by Adeel Khurshid <kurshid@cs.odu.edu>
   while at Fujitsu Network Communications,  and is used by the
   'apsfilter' by Andreas Klemm and Thomas Bueschgens.

     Example:
      lp|lp_*:lp=%P@server
      lp|lp_*:server
        :incoming_control_filter=/.../update_z
        :...

   When you use lpr -Plp_landscape_ledger you will actually end up
   sending the job to the lp queue, with the queue name (Q control
   file line) set to lp_landscape_ledger.  This information can be
   used to update the various control file lines.  The LPRng/UTILS/update_z
   file has an example of a script that will do this.  Note that this
   makes the use of the apsfilter utility even easier.
   (Inpired by a control filter by: Adeel Khurshid <kurshid@cs.odu.edu>)

  I removed a couple of bogus entries that I was putting into the
   job control file.  These appear to be holdovers from some testing.
   They were put in but never used.  Strange, that.

  The append_z, prefix_z, and other related Z operations are done
   only when the job is received.  This now allows the job to be
   processed by filters and not have the work undone.  sigh.
   Documentation cleaned up as well.

  The control file processing has been cleaned up and the redunant
   and erroneous (sigh) copy of the control file in the job{} data
   structure has been ruthlessly purged.  I sure wish Ruth worked
   for me,  I seem to be doing so much ruthless cleanup.
   I see the hand of testing and debugging in much of this stuff,
   and the tracking down of memory leaks as well.

  You can now use [^x] in the glob patterns.  Sigh...  The things
   people do when they get the bit in their teeth.

  The LPD support for 'lpq' and 'lprm' requests has been modified so that
   if there are chained queues and each queue is on the server THEN
   I simply call a routine and do not fork a process.  This solves a
   problem with process exhaustion when somebody had a loop in their
   printcap.  I also put in some tests for this.  However, without
   adding Yet Another Option to the LPRM and LPQ stuff I don't see
   how I can do it.

  You can now send up to 'max_jobfiles' (default 52) to the server.
   Note:  you can actually only send 52*52 = 2704
   The data files are given names
     dfAnn -> dfZnn -> dfann -> dfznn ->
     dgAnn -> dgZnn -> dgann -> dgznn ->
     dzAnn -> dzZnn -> dzann -> dzznn ->
     daAnn -> daZnn -> daann -> daznn ->
     deAnn -> deZnn -> deann -> deznn ->
     dAAnn -> dAZnn -> dAann -> dAznn ->
     dZAnn -> dZZnn -> dZann -> dZznn

  There is now support for the HP extensions:
  (Courtesy of Richard Hart USG <hart@zk3.dec.com>,
    who sent me the following information)

     Summary of HP's Extensions to RFC-1179

     1. 4-Digit Job Numbers
     HP preserves the System V-style 4-digit sequence number, or job number, in
     file names and attributes, while BSD uses 3-digit job numbers.

     2. Control and Data File Naming Conventions
     Control files are named in the following format:
        cA<seqn><host>
        <seqn> is the 4-digit sequence number (aka job number).
        <host> is the originating host name.
     The data file naming sequence format is:
         dA<seqn><host>   through   dZ<seqn><host>     followed by...
         da<seqn><host>   through   dz<seqn><host>     followed by...
         eA<seqn><host>   through   eZ<seqn><host>     followed by...
         ea<seqn><host>   through   ez<seqn><host>     ... etc. ...
     So the first data file name in a request begins with "dA", the second with
     "dB", the 27th with "da", the 28th with "db", and so forth.

     3. HP-Specific BSD Job Attributes (Control File Lines)
     The following control file lines are extensions of RFC-1179:
        R<login>
           Write to the named login's terminal when the job is complete.  This is
           an alternate to the RFC-1179-style e-mail completion notification.
           This notification is selected via the lp "-w" option.
  -- R line -> M line
        A<priority>
           Specifies the System V-style priority of the request, a single digit
           from 0-7.
  -- A value -> priority
        N B<banner>
           Note that this line begins with an "N", a space, and then a "B".  The
           argument is the banner page title requested via the lp "-t" option.  If
           that option was not given then the argument is null.
  -- banner -> T banner
        N O<options>
           Note that this line begins with an "N", a space, and then an "O".  The
           argument contains the System V-style "-o" options specified in the lp
           command line.  The option names appear without a leading "-o".  The
           first option name begins in the fourth character of the line; each
           option is separated by a blank.  If no "-o" options were given then the
           argument is null.
  -- <options> -> appended to Zvalue <options>

     The following control file lines are generated differently than in standard
     BSD:
        J<jobname>
           The argument is the System V-style request-ID, for example,
           "printer-42".  Note that leading zeros are not present in the sequence
           number.  If a System V-style title is requested then it is sent using a
           "N B" attribute, and not the "J" attribute.

  There is now a new and improved error message for fumble fingers:
   h4: {1185} % lpq -Pxx
   Printer: xx@h4 - ERROR: spool queue for 'xx' does not exist on server h4.private
      non-existent printer or you need to run 'checkpc -f'
   h4: {1186} % lprm -Pxx
    ERROR: spool queue for 'xx' does not exist on server h4.private
      non-existent printer or you need to run 'checkpc -f'
   h4: {1187} % lpc -Pxx status
    Printer           Printing Spooling Jobs  Server Subserver Redirect Status/(Debug)
   xx@h4: spool queue for 'xx' does not exist on server h4.private
      non-existent printer or you need to run 'checkpc -f'
   I hope that this cuts down on the problems reported by people who do not
   RTFM about 'checkpc -f'.

  I have added code to track the maximum open file descriptor so that
    the 'cleanup' code is a little more intelligent.

Release LPRng 3.6.22 - Sun Jul 23 17:37:02 PDT 2000
  There is yet one more problem with high load levels -
   I did not set the timeout to reasonable value and the lpd server
   goes into a tight loop waiting for it.

Release LPRng 3.6.21 - Sun Jul 16 16:58:19 PDT 2000
  Clean up some Tru64 system warnings about casts.
   (Supplied by: "Justus J. Addiss" <jjaddiss@mmm.com>)
  Seemed to have found a solution to the parallel port problem
   by brutally using fstat() to see if we have a device,  and if
   so, then unless it is a tty, assuming that it is a write only
   device.  This is stupid,  and I just KNOW that when somebody
   adds a USB device I will suffer for this.  When you have a
   'write only' file descriptor,  you just do a 'write' with timeout.
   No select, nothing.  Just a write.  This seems to solve the
   problem.  Oh yes.  You also make sure the file descriptor
   is non-blocking.
   (By:  Patrick Powell <papowell@lprng.com>)
  There is a bizzare problem with doing select for read on some Solaris
   systems with certain patch sets on file descriptors that have
   been set for non-blocking.  The select call will actually return
   and indicate that the device can be read...  But when you do,
   you get -1, and EUNAVAIL or some similar code indicating no data
   to be read.  This is truly bizzare.  To ensure that this does
   not happen,  you must do a select on a nonblocking file descriptor.
   To add injury to insult,  this seems to not be reliably reproducible.
   You really had to be there for this one.  I now set all the file
   descriptors into blocking mode and then do select,  then put them
   in nonblocking mode to do the write or read.
  The mysterious 'lpc reread' killing lpd was discovered to be caused
   by trying to free an already freed pointer, which was garbage.
   This was related to cleaning up the memory leak problem in 3.6.20.
   Sigh...
  I cannot spell krbros... krb5... or kb5... and thus cannot invoke the
   dog in the configuration script.
   (Happily pointed out by:  John Perkins <john@cs.wisc.edu>)

Release LPRng 3.6.20 - Sat Jul  8 12:32:38 PDT 2000
  One of the silly memory leaks that has been reported, tested for,
   analyzed, etc., finally was found.  The problem was in the
   child.c file,  where I keep track of children processes
   by dynamically allocating a list.  While I carefully cleaned
   up the list in children of the main LPD process,
   I never cleaned up the list in the main LPD process.  Thus,
   if you created a large number of children the list would grow
   a small amount (4 bytes) for each child.
   This problem was found by brutally using the 'DMALLOC' debugging
   package,  finding every 'malloc' call in the main LPD process
   and then looking for a matching free call in the main line loop.
   When one was not found for the case where I had 0 processes
   I knew that I had found the problem.  Sigh.
   (Stumbled over after staring at the code for a week by:
      Patrick Powell <papowell@lprng.com>)
  Makefile now checks that POSTINSTALL is 'NO' or 'no'
    (Noted by: Craig Small <csmall@eye-net.com.au>)
  checkpc -C and checkpc -c file removed.  Legacy options and
   I don't know why they were still there.
   (Noticed by: Jesper Dangaard Brouer <hawk@diku.dk>)
  The call to 'Remove_tempfile()' routine was removed from
   the 'cleanup()' when trying to find the above mentioned memory
   leak and was not put back.  Bad Coder! Bad!
   (Found by: A Earle <ae@play.psych.mun.ca>)
  The pclbanner and psbanner had some errors that showed up under
   bash.  Very odd that the ksh and /bin/sh did not whoop on them.
   (Clever debugging by: David Livingstone <davidl@cn.ca>)
  checkpc -r -A was a little too agressive and it blew away all
   sorts of files.  The -r now only works on job files.
   I do NOT remove job files unless the -r -A age options are
   given.  This prevents some problems with jobs being moved
   into a queue just as checkpc is being run from cron.  Sigh...
   Cron.  I forgot all about Cron.
   (Noticed by: Craig Small <csmall@eye-net.com.au>)


Release LPRng 3.6.19 - Sun Jun 25 11:13:35 PDT 2000
  The filter status was not getting used correctly.  This was
   a side effect of trying to clean up aborted jobs and
   accounting.  One step forward, one step back.  Sigh.
  The Tru64 compiler objects to casting pointers to ints, so
   we have to cast to a long THEN to an int.
   (Reported by: Justus J. Addiss <jjaddiss@mmm.com>)
  Did not update the 'Tempfile' variable when I was checking multiple
   print queues.  This meant that it was using a stale queue name.
   Only shows up if the queue directories are on different
   file systems.
   (Spotted by the eagle eyes of: Robin Sommer <rsommer@uni-paderborn.de>)
  Apparently the CHANGES file had 'z_append' instead of 'append_z'.
   So it is changed.  Do we need a Meta-CHANGES file to record changes
   to the CHANGES file?
   (Caused by the readings of: Michael J. Carter <mcarter@lanl.gov>)

Release LPRng 3.6.18 - Mon Jun 19 09:37:04 PDT 2000
  The UTILS/accounting.pl script did not handle malformed
  lines caused by truncation well.   It now does,  but
  insists that you have lines starting with
    start, filestart, end, fileend for status.  This ties
    into ifhp-3.6.15
  Updated the DISTRIBUTIONS/FreeBSD to make the port correctly
  Updated the DISTRIBUTIONS/RPM to make the port correctly
  Changed the psbanner font to a more readable font
   (Artistic criticsm by: Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>)
  Lowercased DNS lookup return values.
   (Need discovered by: Alf Wachsmann <alfw@slac.stanford.edu>)
  Tru64 cc compiler whoops its cookies on void * conversions...
   (Reported by:  Justus J. Addiss <jjaddiss@mmm.com>)

Release LPRng 3.6.17 - Sat Jun 17 15:58:21 PDT 2000
  Analysis of the Setuid Compromise for LINUX done; LPRng
   is only susceptible if a non-root user manages to run a client
   program that in turn runs a program that she has compromised.
   Since the programs run by LPRng and other servers should owned
   by root and not writable,  this would require the compromiser
   to have already modified these - by alreadying having root perms.
   This means that they have already compromised the system.

   Replaced the agressive 'check at all times and costs' with
    a) a configure time check for the 'bad linux kernel'
    b) a run time check done only by clients for a compromise.
    c) not installing LPD setuid ROOT so that it cannot be
       started and used as a compromised process.

Release LPRng 3.6.16 - Thu Jun  8 15:24:37 PDT 2000
  Long numbers and the silly 'is this really and IP address code'
   conflicted.  Fixed it again.
   (Spotted and reported 32 minutes after the release was out by:
      Thomas Vogt <t.vogt@drgueldener.de>)
  Did not check for null pointer, the following printcap was not
    read correctly:
      .junk:
      stuff:tc=.junk  <- ummm... nothing there, CRASH
   (Spotted and reported 30 minutes after the release was out by:
      Justus Addiss <jjaddiss@mmm.com>)
  Changed :as and :ae checks so that you can use :as=/path as well as
    :as=|/path
   (Inspired by comments from: Sree Lakshmi <chinnu@jncasr.ac.in>)
  pclbanner did not work under RedHat.
   (Spotted by:  David Kerr Livingstone <davidl@cn.ca>)
  Goofs in the HOWTO spotted.
   (Spotted by: Zanferrari Domenico <domenico.zanferrari@kone.com>)
  Updated the HOWTO format.  Now using DocBook to generate output.
  RPM packages not generated correctly
  If the -Dxxx option is the VERY FIRST on the command line,
   then you set up the debug options very early in the parsing
   and operation.  This can lead to a GREAT deal of rubbish unless
   you need it.

Release LPRng 3.6.15 Thu Jun  8 15:24:37 PDT 2000
  postinstall.generic.sh was sytactically incorrect.
   (Patch by:  Justus Addiss <jjaddiss@mmm.com>)
  RPM Fixes:
    /usr/docs/LPRng now removed
  Linux (and possibly other) SETUID BUG compromise detection
    added.  The setuid(n) call is supposed to be a one-way trip to
    uid n,  but this can be compromised by users setting
    flags.  Present in kernels before 2.2.16,  and possibly
    other capabilities based systems.  Added a test to make sure
    that this is really a one-way trip.
       As far as I can tell,  this would only be an issue if the
    user had a shell script that was executed by LPRng and the script
    could be replaced by something else.  This is possible in systems
    which are using NFS - I have exercised the compromise and it
    exists.

Release LPRng 3.6.14 Sat May  6 08:46:26 PDT 2000

  configure now has --with-lockfile=path.
   (Courtesy of:  Willi Burmeister <wib@cs.uni-kiel.de>)
   Complete configure options are now:

  --with-cc=COMPILER      select compiler to use
  --with-ccopts=CFLAGS    select compiler command line options
  --with-linker=LINKER    select linker to use
  --with-ldopts=LDFLAGS    select linker command line options
  --with-cppopts=CPPFLAGS  select compiler preprocessor command line options
  --disable-setuid                  disable setuid root client and server executables
  --enable-priv_ports               require connections to be from privileged ports
  --disable-force_localhost         force_localhost default to disabled
  --disable-require_configfiles     client programs require lpd.conf, printcap
  --enable-kerberos                 enable kerberos support
  --enable-mit_kerberos4            enable MIT Kerberos 4 support
  --disable-kerberos_checks         disable kerberos library location and checking for support
  --with-lpddir=DIR                 lpd executable directory (default ${sbindir})
  --with-lpd_conf_path=PATH         path of lpd.conf (default: ${sysconfdir}/lpd.conf)
  --with-lpd_perms_path=PATH        path of lpd.perms (default: ${sysconfdir}/lpd.perms)
  --with-printcap_path=PATH         path of printcap (default ${sysconfdir}/printcap)
  --with-lpd_printcap_path=PATH     path of lpd_printcap (default ${sysconfdir}/lpd_printcap)
  --with-lockfile=PATH              lockfile PATH, default /var/run/lpd
  --with-ld_libary_path=PATH        LD_LIBRARY_PATH value
  --with-filter_path=PATH           filter PATH value
  --with-userid=NAME                run LPRng software as this userid, default daemon
  --with-groupid=NAME               run LPRng software as this groupid, default daemon
  --with-chooser_routine=NAME       load balance queue chooser routine name in user object file
  --with-order_routine=NAME         queue order routine name in user object file
  --with-user_objs=NAME             user specified object file
  --with-user_include=NAME          include file with function prototypes for user object file
  --with-filterdir=DIR              filter directory (default ${libexecdir}/filters)
  --disable-strip                   disable stripping binaries by default
  --enable-nls           use Native Language Support
  --with-included-gettext use the GNU gettext library included here
  --with-catgets          use catgets functions if available

  Terminal clearing now done by using 'clear' program.
   Configure will look for a clear program and LPQ will fork and
   exec it.  If no clear,  then simply send a '^L' or '\014' (form
   feed) to the stdout.  This is due to the horrible support in
   most OS's for curses, termlib, termcap, term...  well,  you get
   the idea.  For a true trip through hell, read the configure
   script for 'vim' and see what they do.  Not for me,  when this
   is only a VERY small part of a much larger system.
   (Changed after finding curses, ncurses, and sys5 curses on
     a system by: Patrick Powell <papowell@lprng.com>)

  Makefile.bsd  is now a VERY small makefile:
    # List the things you want to generate:
    all clean install uninstall:
       gmake $(MAKEFLAGS) $@

    I know that some of the BSD folks will hate me for this,  but
   I have decided that trying to support both types of Makefiles
   and making them work was just too much effort.  Also,  the BSD
   folks now have much better supporort for Gmake in their build
   scripts.  Also, see below... Enhanced Install and Package Creation
   Support.

  Enhanced Install and Package Creation Support
   (Laid at the feet of: Craig Small <csmall@eye-net.com.au>)
    One of the problems that is encountered when trying to build a package
   or do an install is to compile stuff in one directory and then install
   it in another.  The trouble is,  you want to install it in a MIRROR
   directory.
   For example,  you have
    ${SYSTEMSRC}=/private/src,  where the source is,
    ${BUILD}=/var/tmp/BUILD/ where you are going to build all the stuff,
    ${MIRROR}=/var/tmp/MIRROR where you want to place what you created

   The following is generally what is done during distribution creation to
   do this:
     cd ${BUILD}/.../LPRng;
     ${SYSTEMSRC}/.../LPRng/configure --prefix=/usr/local --sysconfdir=/etc
     make
     make install XX=${MIRROR} -> puts thing in
              ${MIRROR}/usr/local
              ${MIRROR}/etc

   After trying 9 (nine) different variations on a theme,  I now have the
   following method to do this:
     make install INSTALL_PREFIX=${MIRROR} POSTINSTALL=NO

   What is this?  The install script/steps will install files in
   ${INSTALL_PREFIX}${prefix}, ${INSTALL_PREFIX}${sbindir}, etc.
   etc., where ${prefix}, ${sbindir}, etc, are hardwired by the
   configure step to the /usr/local/, etc.  Now you might wonder
   why this is done.  The reason is that GMAKE, bless its little
   heart,  will use the $PREFIX environment variable value if it
   is set.  So you cannot do ${PREFIX}/${sysconfdir}  in install
   scripts,  and if you do not set it on the command line,  have
   it put in the right place.

   The POSTINSTALL=NO is used to suppress 'true' postinstallation
   stuff that would copy files into 'unexepect' places, such as
   '/etc/printcap' or '/etc/lpd.perms' or '/etc/lpd.conf'.  Now
   if you are building a system distribution for raw install,
   then you want this to be done,  and you would use:
     make install INSTALL_PREFIX=${MIRROR}

   If you are building,  say a FreeBSD 'package' distribution
   or a RedHat RPM then you would use:
     make install INSTALL_PREFIX=${MIRROR} POSTINSTALL=NO

   Now for all of you who want to make a package and need to find
   the files that LPRng will install,  I suggest you look at the
   following:

     INSTALL_PREFIX=/var/tmp/LPRng  #note that you do NOT export this
     (
    cd $INSTALL_PREFIX;
      mkdir usr/local/bin usr/local/sbin /usr/local/libexec /etc /usr/local/etc/rc.d
        ....
     )
     make; make install INSTALL_PREFIX=${INSTALL_PREFIX}
     (cd $INSTALL_PREFIX;
     find . -type f | sed -e '/man[0-9]/d' \
        -e '/\/info\//'d -e 's/..//'  >/tmp/files
     find . -type f | sed -n -e '/man[0-9]/s,.*man[0-9]/,,p' \
        -e 's/..//'  >/tmp/manpages

   You can now find the non-doc files, manpages, etc. etc. etc.
   and then update the various locations as you need.  Clearly this
   should be done only as root,  on a system where you do not have
   other users running,  where somebody cannot do 'ln -s /etc/passwd
   /tmp/manpages' and so forth.

   For a truly abusive use of this method,  look at the
   DISTRIBUTIONS/FreeBSD* and DISTRIBUTIONS/Solaris* directories.

   Yes,  I have no shame.
   (Put into the distribution after telling people 5 times how
     to use this by:  Patrick Powell <papowell@lprng.com>)

  lpr -U option did not work correctly when UID was root.
    (Patch happily submitted after a long search by:
        Roberto Togneri <roberto@ee.uwa.edu.au>)
  lpd was mangling jobs with more than 26 files - caseless compare
     strikes again.
    (Found with great consternation by: Peter Scheurer <scheurer@sopra-gmbh.de>)
  permissions and filters:
    When you use a filter for "perms_path" was not executed when a
    connection to the lpd is made. So there are no rules then and the
    result of the permission check simply is the default_permission (and
    it results in having no rules for the 'R'-check as well)
    By convention,  a line containing the name of the printer for which
    permission is wanted.  Now a blank line is written for 'X' rules.
    Added capability of filter getting permissions to Setup_printer().
    (Found by: Robin Sommer <rsommer@uni-paderborn.de>)
  lpd_jobs: race condition eliminated at the cost of a high system
    overhead when multiple jobs are spooled to the same queue.
    (Inspired by: Shawna Chase" <chase@crd.ge.com>)
  client connections on Solaris 2.5 systems fail with EADDRNOTAVAIL,
    and need a 'retry'.  Alternative is to use non-priveledged port.
    (Found by: Peter A. Harris <peter.a.harris@exgate.tek.com>)
  innetgr() needs FQDN on some systems, and 'shorthost' on others.
    Added check to do both.
    (Reminded by: Robin Sommer <rsommer@uni-paderborn.de>)
  syslog messages not working.  May need to add 'ordering' test to
    configure for level comparison.
    (Noticed by: Jurgen Northe <juergen.northe@junghans-fwt.de>)
  RFC1179 transfer failures to remote spool queue did not do retries
    correctly.  The 'JFAIL' status was treated as a permanent failure,
    not a temporary.  The 'Service_printer' code now uses the number
    of send attempts to do a retry and backoff on transfer times:
    configuration and/or printcap options:
      send_try:  maximum number of times to send to remote
        (0 = infinite) - default 3
      connect_grace: minumum time between attempts - default 0
      connect_interval: interval between attempts - default 10 sec
      max_connect_interval: maximum time to wait - default 60 sec
        if( attempt > 0 && max_connect_interval > 0 ){
            n = connect_interval * (1 << (attempt-1)) + connect_grace;
            if( n > max_connect_interval ) n = max_connect_interval;
            sleep(n);
        }
    (Discovered by: Christof Drescher <drescher@pro-image.de>)
  Default filter options were missing '$b'.
    (Pointed out by: Jose Carlos Rodrigues Lopes <jrl@europa.fcee.ucp.pt>)
  The md5 authentication support did not return back 'error' status for
    lpr operations.
    (Noticed by: Patrick O'Brien <pdo@cs.umd.edu>)
  The 'IS_OS' macros are now set to the OSVERSION;  this makes tests like
       #if defined(IS_BSDI) && IS_BSDI > 401
    possible.  Sigh...
  The filter_path (PATH environment value for filters) added /usr/contrib/bin
    (Suggested by: Jeffrey C Honig <jch@bsdi.com>)
  UTILS directory needs to be part of the global 'make' so that
    tools are created with the right paths.
    (Discovered when fixing a problem found by: Jeffrey C Honig <jch@bsdi.com>)
  check_for_nonprintable default is now OFF due to 85 distinct problems reported
    by various users.
    (Email that broke the camel's back sent by: John Hawley <jhawley@bgea.org>)
  lp -s was printing status.
    (Discovered and fix by:  Mark.Belton@mgc.com.au)
  proctitle() code was mangling the envp[] - this only showed up if you
    happened to set debug level 6 or higher.
    (Discovered by: Vincent Fox <vincent@cad.gatech.edu>)
  Microsoft now sends the IP address as part of the control
    and data file names.  OK.  We can handle that.
    (Pointed out by: Rainer Schoepf <schoepf@uni-mainz.de>)
  When using a routing filter, the DATAFILES environment variable
    contains the data files.  The routing filter can modify
    the datafiles,  but cannot remove them or truncat them.
  The default for bq_format is now 'f' - i.e. - you  can reprocess
    outputs of bounce queues.  The old default was l (binary),
    which was not processable.
  The 'lpq -s ID' command was not reporting information correctly.
    It always reported the total printable, not the ones selected
    by the options.
   (Discovered by: Patrick Powell <papowell@lprng.com>)
  Retested Kerberos 5 and Kerberos4 stuff with Kerberos 1.1.1,
   found problems with compilation,  fixed them.
   (Helped by: Mike Whitson <mwhitson@MIT.EDU>)
  Updated Version and Copyright information.
  Added configure --enable-kerberos option for folks who need to build
   'non-exportable' binaries.
  Added a '$(INSTALL_PREFIX) entry to the install scripts to allow folks
   who want to install the binaries in a different subtree to do so.
   I might make this 'PREFIX' to fit in better with feedback.
  More fixing of Kerberos stuff - fixed up the problems with different
   uses of krb5_xfree.  Added tests for the krb4des library.
   (Helped by: Mike Whitson <mwhitson@MIT.EDU>)
  The spool_file_perms option was not being used to set permissions for
   files in the spool directory.  Noted in the Debian LINUX bugs list.
   It was also noted that the user was trying to set some very odd permissions
   that would result in a possible security loophole,  but Hey!  I just
   do LPRng...  Users (not the LPD server) use 0600 permissions,  just
   to avoid those nasty security problems.

  Nit pick on man pages: SEE ALSO should not reference same man page.
   (Submitted by: Debian Linux Bug List)

  checkpc now checks for server printcap entries with lp=xxx and rm=yyy
   values.  This way you at least warn the users when they screw up.
   (Good suggestion by: Craig Small <csmall@eye-net.com.au>)

  Moved tests for 'setproctitle' in configure around to deal with some
   problems of libraries being included when they should not have been.

  Fixed up the distclean.  Removed junk files.  Move the LPRng_DOCS
   into the HOWTO,  as there were no other files left.

  Fixed permissions.  Did some fiddling to add easier FreeBSD/NetBSD
   etc. support.  Side effect was that testing install is easier.
   Added a 'INSTALL_PREFIX' to the installation paths that allows
   me to make sure that things go to the right places.

  Move the various distribution specific information into DISTRIBUTIONS
   directory.

  Made the LPRng and ifhp configure.in mainly identical.  Also use the
   same portable.h file.

  Fixed (once again) typeos in the man pages, and the installation
   of compressed man pages.  Sigh...

  Added a 'filter_stderr_to_status_file' flag that causes print filter
   errors to be written to the status file (:ps=file) rather than to
   the status log file.  Also added truncation of the status file.
   (Inspired by : "William D. Colburn (aka Schlake)" <wcolburn@nmt.edu>)

  Discovered, as a result of testing the 'filter_stderr_to_status_file'
   flag that backslash '\' escapes were not being handled correctly
   on the filter line.  Fixed this.

  If a filter has <,>,;, or | in it, or starts with (
    then it is executed by using:
    :if=/.../filter xxx   -> /bin/sh -c '/.../filter xxx'
    This allows you to do things like '/.../filter 2>>status'
    Updated checkpc to check for matching () for filters.

  Modified the src/linksupport/connection() code so that the
   lpq and other clients do not try binding to port 515.  This
   can cause problems when used with Samba.  The code in
   linksupport.c that set SO_REUSEADDR and SO_KEEPALIVE was
   also tidied up.

  lpc -a now works sort of correctly and the documentation has
   been changed to reflect it.

  The LPC=xx permissions checking did not require a 'C' operation.
   Also, cleaned up some message printing.

  Make_passthrough was examined and a couple of changes made to
   handling the case when the filter path contained a meta character.
   The path now has parenthesis put around it.  By default,  this
   form of invocation does NOT have options passed to it.

  Added a '$*' parameter to provide all the default command line
   options.  This now allows you to do:
    :if=(/some/path $* | output filter)

  New functionality: remove_z, prefix_z, and append_z
   (Inspired by a comment by: Richard Kaszeta <kaszeta@me.umn.edu>)
    remove_z=pattern,pattern,...
      remove the -Z option specified by the pattern.
      Example: -Ztest,this,thing   + remove_z=th*,out -> -Ztest
    append_z=option,option,...
      appends this to the -Z options
      Example: -Ztest   + append_z=landscape -> -Ztest,landscape
    prefix_z=option,option,...
      prefixes this to the -Z options
      Example: -Ztest   + prefix_z=landscape -> -Zlandscape,test

    Example of use:
      You want to have a set of queues where you can have the
    queue set the functionality:

    landscape:append_z=landscape:lp=remote@host
    portrait:append_z=portrait:lp=remote@host
       lpr will add these options before the job
     is sent.

     OR you have a 'bounce queue' situation where you
    want to add -Z options as the job goes through:
      portrait:append_z=portrait
         :lp=remote@host:server
      lpd will put these options into the job file
      ON RECEPTION.  Also,  before sending to a remote
      queue as well.  Kinda bombproof, but covers most
      situations.

  If you have force_localhost then you want to connect to
    the server with the primary name of the printcap entry.
    The clients were using the lp=pr@remote pr value instead.

  CONFIGURATION OPTION:  ld_library_path and filter_path
    you can set these values through configure.

  Portability Support:  DISTRIBUTION directory and init files

    Put the init scripts for various OS's in the main directory.
    This helps the poor administrator who is trying to figure
    out what init script he needs.

    Gathered up all of the various system dependency stuff and put
    it in one big directory.

  Fixed up the DISTRIBUTION/Solaris.pkg stuff

  The 'subserver' queue management now works.  The problem was that
    the main queue server process had to fork a subserver process
    for the subserver queue,  and it could not tell that the subserver
    queue had been changed.  The following solved this:
     a) in the lpd_control.c code, if the queue is a subserver
        queue,
        1. I set a 'changed' flag in the spool control file.
        2. I send a SIGUSR1 signal to the process that is the server
           for the subserver queue.
        3. If that signal is unsuccessful, then I send a SIGUSR1 signal
           to the main queue process.
        4. If that signal is unsuccessful I restart the server
    b) in the lpd_jobs.c code, in the Process_jobs() routine:
        1. I check to see if this queue has subservers,  and then
           check the subserver queues.  If the 'changed' flag was set or some
           other reason exists to start the subserver, I start a
           subserver process.
        2. In the main queues 'wait for work' loop,  when I get a
           'SIGUSR1' I scan the subserver queues and check to see
           if their 'changed' flag is set.
           If it is set AND there is no subserver process THEN I will
           start a server process.  Otherwise I wait until the subserver
           process exits.
        3. In the main queues 'wait for work' loop,  when I look for
           a free subserver queue to use AND I find one which is
           available AND it has a change flag set THEN I start a
           subserver process.
     As you suspect,  this was NOT a simple set of changes.
    (Painfully debugged by: Patrick Powell <papowell@lprng.com>)

  Kerberos Fix From MIT: added auth=none support, and allow default
    principal lookup.
    (Patch by: Robert A Basch <rbasch@MIT.EDU>)

  FreeBSD port/package support, Solaris pkg support, RPM (RedHat) Support
    The configuration, build, and install process has been modified
    to better support package generation.  (I know, it is a dirty business
    and I am trying to make it easier for the vendors.)

    I have been driven to this by problems that people have with installing
    stuff for the first time,  and the rising level of 'Did not RTFM'.

    a)  postinstall script selection
        The last step of the make install process is to find
      a 'postinstall' file and execute it.  The file is chosen by
      looking in the configuration directory for a suitable file.
      The file is found by using the 'OSNAME' value found by the
      configure script.  Linux is a special case - mainly because
      I tested several versions and found that they had different
      'linux-this' and 'linux-that' suffixes.
        I also locate a 'preremove' script and do the same selection.
      There is a default 'postinstall' and 'preremove' script as well.

        OSNAME=${OSNAME}; case "$${OSNAME}" in *linux* ) OSNAME=linux;; esac; \
        echo "OSNAME orig $(OSNAME) '$${OSNAME}'"; \
        s=`ls postinstall.$${OSNAME} 2>/dev/null`; \
        echo POSTINSTALL "'$$s'"; \
        if test -n "$$s" ; then cp $$s postinstall; fi; \
        s=`ls preremove.$${OSNAME} 2>/dev/null`; \
        echo PREREMOVE "'$$s'"; \
        if test -n "$$s" ; then cp $$s preremove; fi;

     b) postinstall script execution
        If the POSTINSTALL option is not NO, then I execute the postinstall
      script as the last step of the 'install' process:

    if [ "${POSTINSTALL}" != "NO" ] ; then
        MAKEINSTALL=YES INSTALL_PREFIX=$(INSTALL_PREFIX) $(SHELL) postinstall ;
    fi;

       Note that the 'MAKEINSTALL' environment variable is set to YES.
       This can be used to determine that the postinstall script is being
       executed by the 'make install' step.

     c) "pseudo root" or "PREFIX" support

       I have put a "${INSTALL_PREFIX}" variable at all points where
       a normal script would have a target.  Thus if you do:

           mkdir /var/tmp/LPRng-root
           make install INSTALL_PREFIX=/var/tmp/LPRng-root

       you will find that all of the files are now put in sub
       directories of /var/tmp/LPRng-root.  You can now do:

       (cd /var/tmp/root; find . -type f -ls ) >/tmp/files
       (cd /var/tmp/root; find . -type d -ls ) >/tmp/directories
       cat /tmp/files | grep 'man[0-9]' >/tmp/manpages
       cat /tmp/files | grep '/doc' >/tmp/doc
        and so forth.  Your Imagination and Creativityy Ma Vary
      (YIACMV).  It is left as an exercise for the student on how to
      use this with their favorite (Ummm... ok - least hated) package
      method to generate a %files, pkg/PLIST,  packinglist, etc. etc.,
      for use in package generation.

     d)  sample 'init', 'preremove', and 'postinstall' scripts.
      I have ruthlessly taken example scripts for FreeBSD, BSDI,
      and RedHat Linux and put them in the root directory so that
      people can see these scripts.

     e) If you want to see how to use these, look in the DISTRIBUTIONS
     directory.

     Here is the postinstall.freebsd.sh : - comments are marked with *** ....

     # FreeBSD Convenience Script for Source Install
     # -- START --
     # CHANGES,v 1.1 2001/08/21 20:33:14 root Exp
     #
     #  If you are building a PORT, see the
     #  DISTRIBUTIONS/Freebsd directory for a complete port
     #  building package.
     #
     # This is the shell script that does the postinstall
     # dynamic fixup
     #  It needs to be massaged with the information for
     #  various paths.
     # If you are building a package,  then you do NOT want
     #  to have this executed - it will put the sample files
     #  in place.  You need to do this during the postinstall
     #  step in the package installation.
     #
     echo RUNNING postinstall.freebsd.sh PACKAGE="$PACKAGE" MAKEINSTALL="$MAKEINSTALL" PREFIX="$PREFIX" cwd `pwd`
        **** you can remove this,  but it sure helps when you are trying to
        **** figure out what is happening.
     ****  - fix is used to put the /etc/lpd.conf, /etc/lpd.perms, and /etc/printcap
     ****    or their variants into place.  This is truly ugly,  as there is
     ****    no easy way to do this well.  You first assume that you will have at
     ****    build time a file with the name 'lpd.conf' (for example) in the
     ****    current directory.  If you have this,  then you copy it brutally to
     ****    the destination, $TARGET/lpd.conf.sample and,  if there is not an existing
     ****    $TARGET/lpd.conf file.
     ****
     ****    Now we get into some ugly stuff.
     ****
     ****    When doing a package install,  you will want to copy the package version's
     ****    of this file into the same place.   But we do not want to overwrite the
     ****    existing lpd.conf, as it will break existing printing.  Note that this
     ****    is exactly what happens with RPM - it clobbers the existing config file,
     ****    and widdles by telling you about it.  Right.  Who reads all of the rpm output?
     ****
     ****    So here is what we do.  We will force a package to have only the
     ****    lpd.conf.sample file, and we will COPY it to the right destination.
     ****
     ****    The FreeBSD port/package system functions by having a pkg/PLIST file
     ****    that contains all of the files we will put in the package.  If you have
     ****    done 'make install INSTALL_PREFIX=/var/tmp/LPRng'  you will get all the
     ****    files installed in the /var/tmp/LPRng, and now can simply use file to
     ****    list them.  For an example,  see DISTRIBUTIONS/FreeBSD/Makefile and
     ****    the 'make plist' target.   I call this a 'chroot' image, cause it is
     ****    (hopefully) the same as though you did a 'chroot' to the $INSTALL_PREFIX
     ****    directory.
     ****
     ****    Unfortunately,  this simple picture breaks down when somebody decides
     ****    to use the 'PREFIX' facility of the package/port installation facilty.
     ****    So we add yet another wrinkle to this.  Use:
     ****    'make install INSTALL_PREFIX=/var/tmp/LPRng PACKAGE=YES'
     ****    when you are generating a 'chroot' image.  Then you test for this in the
     ****    script and put things in a nice place when you are making a package,
     ****    and then forcefully reinstall them.

     fix () {
        v=`echo $1 | sed -e 's/[:;].*//'`;
        p=`echo $2 | sed -e 's/[:;].*//'`; d=`dirname $p`;
        if expr "$p" : "|" >/dev/null; then
            echo "$v destination is filter - '$p'"
            exit 0;
        fi
         echo "Checking for $p in $d"
        if [ ! -d "$d" ] ; then
            echo "Directory $d does not exist!"
            mkdir -p $d
        fi
        if [ -f $v.sample ] ; then
            if [ $v.sample != $p.sample ] ; then cp $v.sample $p.sample; fi
        elif [ -f $v ] ; then
            if [ $v != $p.sample ] ; then cp $v $p.sample; fi
        else
            echo "Do not have $v.sample or $v"
        fi
        if [ ! -f $p.sample ] ; then
            echo "Do not have $p.sample"
        elif [ ! -f $p ] ; then
            cp $p.sample $p;
            chmod 644 $p;
        fi;
     }
     # we use the /usr/local/etc/rc.d method to start lpd
     echo "Installing configuration files, cwd " `pwd`
     # we have to take them from one place and put in another
     if [ "X$PACKAGE" = "XYES" ] ; then
        # we put files into the destination
      ****  when we make a package,  we need to put the files in the
      ****  ${PREFIX}/.... location to be FreeBSD standards compatible
         fix lpd.perms "${INSTALL_PREFIX}${PREFIX}/etc/lpd.perms"
         fix lpd.conf "${INSTALL_PREFIX}${PREFIX}/etc/lpd.conf"
         fix printcap "${INSTALL_PREFIX}${PREFIX}/etc/printcap"
         init=${INSTALL_PREFIX}${PREFIX}/etc/rc.d/lprng.sh
         echo "Setting up init script $init using init.freebsd"
         if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi;
        cp init.freebsd $init
     elif [ "X$MAKEINSTALL" = "XYES" ] ; then
      ****  OK, now we are doing a make install - this could be a
      ****  real install by the user,  or the deadly 'make install'
      ****  done by the port package Makefile generation.  But
      ****  we know what to do:  install it in BOTH places.  This will
      ****  always end up with a copy in .../lpd.perms,  and perhaps
      ****  an extra copy as well in perhaps /usr/local/etc/lpd.perms

         fix lpd.perms "${INSTALL_PREFIX}${PREFIX}/etc/lpd.perms"
         fix lpd.conf "${INSTALL_PREFIX}${PREFIX}/etc/lpd.conf"
         fix printcap "${INSTALL_PREFIX}${PREFIX}/etc/printcap"
         fix lpd.perms "${INSTALL_PREFIX}${LPD_PERMS_PATH}"
         fix lpd.conf "${INSTALL_PREFIX}${LPD_CONF_PATH}"
         fix printcap "${INSTALL_PREFIX}${PRINTCAP_PATH}"
         init=${INSTALL_PREFIX}${PREFIX}/etc/rc.d/lprng.sh
         echo "Setting up init script $init using init.freebsd"
         if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi;
        cp init.freebsd $init
         chmod 744 $init
        echo "Stopping LPD"
        pid=`cat ${LOCKFILE}* 2>/dev/null`;
        if [ -n "$pid" ] ; then kill -INT "$pid" 2>/dev/null; fi
        if [ -n "${KILLALL}" ] ; then ${KILLALL} 2>/dev/null; fi
        # check the printcap information
        echo "Checking Printcap Info and fixing permissions"
        ${SBINDIR}/checkpc -f
        # restart the server
        echo "Restarting server"
        sh $init start
     else
       ****  OK, this is done when we do a package install.  You will
       ****  be amazed to discover that the ./etc/lpd.perms file is now
       ****  present here - so you can install this.  Gahh... The reason
       ****  for this seems to lie with the way that the package/port
       ****  mechanism works.  If this is changed,  then it is back to the
       ****  trenches to find out where and if the file location has
       ****  changed.

        # when doing an install from a package we get the file from the package
         if [ -f etc/lpd.perms.sample ] ; then
             fix etc/lpd.perms "${LPD_PERMS_PATH}"
             fix etc/lpd.conf "${LPD_CONF_PATH}"
             fix etc/printcap "${PRINTCAP_PATH}"
             init=etc/rc.d/lprng.sh
             echo "Checking init script $init"
             if [ ! -f $init ] ; then
                 echo "WARNING: $init missing!"
                 exit 1
             fi;
             cp $init /usr/local/$init
             chmod 744 $init
         else
             echo "WARNING: configuration files missing from package!"
         fi
     fi

  Here is the postinstall.linux.sh:

    # LINUX/RedHat Source Installation Convenience Script
    # -- START --
    # CHANGES,v 1.1 2001/08/21 20:33:14 root Exp
      *** same as above
    fix () {
      *** same as above
    }
    echo "Installing configuration files"
    init=${INSTALL_PREFIX}/etc/rc.d/init.d/lprng
    if [ "X$MAKEINSTALL" = "XYES" ] ; then
        if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi;
        cp init.linux $init;
        chmod 744 $init
        fix lpd.perms "${LPD_PERMS_PATH}"
        fix lpd.conf "${LPD_CONF_PATH}"
        fix printcap "${PRINTCAP_PATH}"
    else
        *** this is tricky ....
        fix "${LPD_PERMS_PATH}" "${LPD_PERMS_PATH}"
        fix "${LPD_CONF_PATH}" "${LPD_CONF_PATH}"
        fix "${PRINTCAP_PATH}" "${PRINTCAP_PATH}"
    fi
    if [ "X$PACKAGE" != "XYES" ] ; then
        echo "Configuring startup scripts"
        if [ ! -f $init ] ; then
            echo "Missing $init";
        fi
        if [ -f /etc/redhat-release -a -f /sbin/chkconfig ] ; then
            echo "RedHat Linux - running chkconfig"
            /sbin/chkconfig --del lpr
            /sbin/chkconfig --add lprng
            echo "Starting Printer"
            sh $init start
        else
            echo "Hand install the configuration files"
        fi;
    fi;

   Cleaned up the 'Make_passthrough' use by having a single
    'Filter_file' routine.  Problems of unclosed file descriptors
    disappeared.   Sigh...

   Discovered that the 'generate banner' code was not working, and
     has probably not worked since 3.5.4.  Shows how many people
     use this.  Fixed.

   Discovered that the 'af=|/...' option caused 'orphaned' children
     which would hang around until the main lpd server process
     exited.  Problem unsolvable on the systems where the problem
     exits.  The :as and  :ae provide better functionality for
     this case.

   If you have an OF filter and one of the other filters dies,
    then you invoke the final OF filter,  even though the job
    will exit with an error.  This allows you to do some cleanup
    in the OF filter.  Implemented by modifying the common/printjob.c
    code so that it did a 'goto end_of_job' rather than 'goto error'.
    I wonder why I did not see this before.

   Fixed a really dumb idiot problem with portability.  I simply do
    not allow lp=|/filter on systems without the 'socketpair'
    function.  Sigh...  There must be a way around this but I can't
    see one.

   Added a 'JSUSP' to the error codes.  Sigh...  Needed this to
    indicate that a filter had suspended itself correctly.

   Check the size of the status file before writing - this adds one
    fstat() call per write,  but you don't update the status file
    very often.
    (Pointed out when his status file filled up the /var spool
      directory by: Dmitry Bely <dbely@mail.ru>)

  We don't steal,  we borrow:  the :sh flag in the printcap causes
   lpr to act like the -h (no header) flag was present.
   (Showing the tattered edges from cutting it out of the
     the FreeBSD lpr code, sent by: Garance A Drosihn <gad@eclipse.acs.rpi.edu>)

  pclbanner and psbanner now back in /bin/sh.  Sigh.  Some supported
   systems do not have Perl.
    (Grudgingly ported to /bin/sh scripts by:
      Patrick Powell <papowell@lprng.com>)

  The printcap 'x:' is now a real printcap.  You use the default
    entry values for it.  Strange how this one did not get caught
    earlier.  The 'lpc client x' and 'lpc server x' now looks up the
    wildcard as well as the normal information.  And finally, checkpc
    will squawk if you try to use a wildcard as a queue name,
    rather than an alias.

  You can now do run time load balancing using user specified program
   OR a built in filter.

   Printcap/configuration option:
     chooser=/path/to/program
         STDIN = list of queues to choose from, one per line
         STDOUT = single queue to use
              (if none, job is skipped)
       exit code: == 0 handle job and put it into specified queue
           if any
                  != 0 treat job as though error code was returned
                       for processing.  Allows job to be held, etc.
     chooser_routine
       chooser_routine@  - default - do not use chooser routine
       chooser_routine   - use chooser routine

       configure --with-chooser_routine=name --with-user_objs=objectfile.o
          defines the CHOOSER_ROUTINE compilation option to name
          includes the objectfile.o in the library.

      routine usage is described in common/user_objs.c

      Now you can have a very optimized routine that will do all sorts
       of horrible things.  Enjoy.

  You can now do queue ordering using a user provided routine

     order_routine
       order_routine@  - default - do not use order routine
       order_routine   - use order routine

       configure --with-order_routine=name --with-user_objs=objectfile.o
          defines the CHOOSER_ROUTINE compilation option to name
          includes the objectfile.o in the library.

      routine usage is described in common/user_objs.c

      Now you can have a very optimized routine that will do all sorts
       of horrible things.  Enjoy.  Note that the overhead for a filter
       was horribly high and I could not come up with a clean interface.
       Besides, if you are mucking around with this stuff, you better
       make sure you know what you are doing.  See the user_objs.c
       and LPRng/src/common/getqueue/Make_sort_key() for details.

  When you did a redirect of a queue, would not move the jobs in
   the queue.  This is now fixed.

  Updated the printcap.5 man page so it is a bit closer to reality.

  Finally got slammed with a 'blank page' of output once too
   often.  The ':sf' (supress form feeds between job files) flag
   is now history.  If you need a form feed between a job file,
   then use 'ff_separator'.

  Yet another version of the UTILS/accounting.pl file.

  The client -A option (use authentication) now selects the authentication
  type from the AUTH environment variable.

Release LPRng 3.6.13 Fri Jan 28 08:03:07 PST 2000
  MIT Kerberos support:  added code to detect when sending job to server
   and the server name is 'localhost'.  This requires a special ticket
   lookup to get the right ticket,  as there is no lpd.localhost ticket,
   only lpd.servername.
   (Supplied by: Mike Whitson <mwhitson@MIT.EDU>)
  src/Makefile.in:  ln ${STRIP} -> ln -s
   (Noticed by: Mike Whitson <mwhitson@MIT.EDU>)
  The filter $- specification did not handle $-/xxx and $-root/xxx
   correctly.
   (Spotted by: Simon Wilkinson <sxw@dcs.ed.ac.uk>)
  When using 'user' or 'custom' authentication,  lpr errors were
   not printed out.  This was due to common/sendjob.c:Send_auth()
   not setting non-zero return status when there were error conditions.
   (Reported by: Patrick O'Brien" <pdo@cs.umd.edu>)
  man/install-sh missing, and ifhp src/install-sh as well.
   (Reported by: Bill Kemp <bkemp@srp.gov>
  LPRng/Makefile.in referenced the wrong location for lpd.conf and lpd.perms
   sample files.
   (Spotted by:  Marty Leisner <leisner@sdsp.mc.xerox>)
  LPD: now do accept in the main lpd process, and this time we brutally
   send a message to the remote end if we cannot fork the child
   process.
  Some linksupport.c routines modified to NOT close sockets on
   error condition.  This allows us to try to read additional error
   information from the remote system.
  Tested the kerberos5 authentication with kerberos-1.0.5.  Fixed
   sserver.c and sclient.c.
  LPRng-HOW corrected.  Filters only get SIGINT and SIGCONT sent
   to them to kill them off.
   (Spotted by: Robin Sommer <rsommer@uni-paderborn.de>)
  Authentication support code rewritten to support error message and status
   returns.  Also,  added error messages and status reports.
  lpd started too many servers.  The Get_max_server() code returned
   the maximum number of server processes that should be running,
   and I would try to start this number.  This would lock up the system
   until one had exited.  Now I start up max_servers - 4 at most
   at startup time.  This is still high,  but seems to work.
  lpq.c: missing argument to plp_snprintf()
    (Patch by: Craig Small <csmall@eye-net.com.au>)
  The environment variables passed to filters were not getting their
    escaped characters expanded.  Thus, PATH=xx\072xx\072xx was
    getting passed instead of PATH=xx:xx:xx
  The default lpd.conf has been fixed so that it has escaped values for
    : instead of : in the file.
  Some filters require a killpg() AND a kill(SIGINT) AND a kill(SIGCONT)
    to die.  Next it will have to be garlic and a stake... Sigh.
    (Noted by:  Peter Scheurer <scheurer@sopra-gmbh.de> )
  The translate_format and translate_incoming_format options can now have
    '*f' entries - the * matches all formats.  This would translate all
    file formats to f.

  The LPRM forward in common/lprm.c did not pass the user's name correctly.
    (Found by: John Perkins <john@cs.wisc.edu>)
  Reformatted LICENSE so that the words GPL are in the first lines
    so that people can tell right away.
  Updated dates to match Jan, 2000
  LPQ and LPRM commands were not being forwarded correctly.

  RADICAL CHANGE IN CODE ORGANIZATION:
    In the next major release I will be restricting authentication to
  code modules only,  and users will have to write (gasp!) C code to do
  this.  This is due to the problems with adding various types of
  encryption, etc., which are not well supported by shell scripts,
  etc.  (I won't discuss the legal issues, these are ugly.)

    The following restructuring of the Authentication API has now been done.
  a) Printcap, lpd.conf information
     The auth=xxx and auth_forward=yyy set the type of authentication
    to be used by the sender.  The auth=xxx is used by the clients
    to communicate with the server and the auth_forward for server to
    server communication.
  b) for each authentication type there is an unlimited amount of configuration
    stuff available now.  The configuration/printcap entries have the
    format xxx_key.  The xxx_id entry is used by clients to identify the
    id of the remote server that they are to use for authentication type
    xxx.  When the server accepts a connection,  it will use the xxx_id
    value as its 'key' or whatever for the connection.  Similarly,  when
    doing server to server communication,  the xxx_forward_id is the
    id of the remote server;  the remote server will still use xxx_id.
    The reason for this has to do with printcap organization.  You want
    to have both entries present in a printcap,  one for a client to send
    to the server, and the other for the server to forward to another
    server.
      You should note that this will break down a little bit when you
    have bounce queues.  Since there is only one xxx_forward_id available
    for all of the destinations,  all of the destinations will need to
    use the same xxx_forward_id value.  This problem will have to be solved
    at the authentication module level,  probably by not using the xxx_id
    and xxx_forward_id for anything but advisory information.
      For backwards compatibility, kerberos can also use kerberos_server_principal
    and kerberos_forward_principal instead of kerberos_id and kerberos_forward_id
    respectively.
  c) for server to server authentication,  use the 'auth_forward=type' to
    set the authentication type for forwarding.
  d) For example, to use kerberos authentication the client printcap
    entry would have:
        auth=kerberos
        kerberos_id=lpr/lpr@server.host  OR
        kerberos_server_principal=lpr/lpr@server.host
        kerberos_service=lpr
        kerberos_life=...   (this are usually not used)
        kerberos_renew=...  (this are usually not used)

    The server printcap entry would have:  (note no 'auth=' stuff used)
        forward_auth=kerberos    (to use kerberos to forward)
        kerberos_id=lpr/lpr@server.host  OR
        kerberos_server_principal=lpr/lpr@server.host
        kerberos_service=lpr
        kerberos_life=...   (this are usually not used)
        kerberos_renew=...  (this are usually not used)
        kerberos_keytab=/etc/krb5.keytab
        kerberos_forward_id=lpr/lpr@anotherserver.host

    In addition,  you will find that PGP authentication has been more fully
    supported.
      CLIENTS:  use environment variables
        PGPPASSFILE = location of a file with the PGP password
        PGPPASSFD   = fd to read the password from (very very rarely used)
      Client Configuration:
        auth=pgp
        pgp_id = pgp id of the server, used to get server key from key ring
        pgp_path = /...  - path to PGP executable on user system

      Server Configuration
        pgp_id = pgp id of the server, used to get server key from key ring
        pgp_path = /...  - path to PGP executable on server system
        pgp_server_passphrasefile = file containing passphrase to be used by server
           to unlock key file
         Server keyring files are in the server user home directory,
        i.e. - if server runs as 'daemon' it is ~daemon/.pgp/pubring.pgp and
        ~daemon/.pgp/secring.pgp.  Don't fight it.

    Note that user level authentication using shell scripts is still there,
    but I am making it hard to use.  Don't use it.  Evil.  Bad.  See the
    notes below on how to add C code to do this.

   And I have added some interesting code to use md5 authentication and
    shared secrets:
      CLIENTS:  use environment variables
        MD5KEYFILE  - file containing md5 keys format is:  name=key.
      keys are currently 16 chars long - the ASCII values are used
      to set the 'key' value.  Yes, yes, I know there are only approx
      76**16 = 5 * 10*29 possible keys using this.  Tough.  A key for the
      user name (login name) and the md5_id need to be present

         Example:
         User Keyfile
           # from the configuration information: md5_id=key
           # we use 'key' to look up the host information
           # the entry has the format '[user_auth] salt'
           #  if user_auth is present then it will be used as the
           #  'from' or 'client' information.  The recipient will use
           # this value to look up the corresponding hash key value in
           # servers keyfile
           #key  = user_auth   salt
           lpr@h4=papowell-h4  xx01223750adfj9098789sdfadf
           lpr@h5=papowell-h5  asdfu189asdfasdfasdfasdfasd

        Server Keyfile (host h4)
           #key  = user_auth   salt
           # user key
           papowell-h4=xx01223750adfj9098789sdfadf
           # key for forward transfer to host h5
           lpr@h5=lpr-h4 adfa9ipioasdfasdfjklsf
           # key for forward transfer from host h5
           lpr-h5=adfa9ipioasdfasdfjklsf

        Server Keyfile (host h5)
           #key  = user_auth   salt
           # user key
           papowell-h5=asdfu189asdfasdfasdfasdfasd
           # key for forward transfer to host h4
           lpr@h4=lpr-h5 adfa9ipioasdfasdfjklsf
           # key for forward transfer from host h4
           lpr-h4=adfa9ipioasdfasdfjklsf

        Configuration:
          auth=md5


    Just to make life interesting,  I have also added a demonstration
      of how to do md5 signing and authentication.

   e) Code reorganization
       The LPRng/src/common/sendauth.c and LPRng/src/common/lpd_secure.c
    files have the following stuff added at the end.

  #define SENDING
  #include "user_auth.stub"

   struct security SendSecuritySupported[] = {
      /* name,       config_tag, connect,    send,   receive */
      { "kerberos4", "kerberos", Send_krb4_auth, 0, 0 },
      { "kerberos*", "kerberos", 0,           Krb5_send },
      { "pgp",       "pgp",      0,           Pgp_send },
      { "user",      "user",     0,           User_send },
  #if defined(USER_SEND)
  USER_SEND
  #endif
      {0}
  };

     This is an example of how you add user level stuff for encryption
   and not go to jail for international arms smuggling.  The "user_auth.stub"
   file contains the source code for the various modules, or you can put the
   source code in another file and link it in.  This is recommended when you
   want to use a dynmically loadable library and ship the library. (Note:
   yes, I looked at loadable modules a la Apache,  but LPRng runs on systems
   that do not support this, so I gave up.  This is the older method from
   other real time software that seems to work.)

     The data structure has the name of the authentication, used with the
   auth=xxx tag.  The name field corresponds to the xxx value.

     The config_tag is used to do lookups in the various configuration and
   printcap files to get values.  Why not make them the same?  As you see
   in the example, we have kerberos4 and Kerberos 5,  but we use different
   support routine with the same key values.  Backwards compatibility is
   thus assured.  Oh, yes. Note that you can use wildcards for the name value.
   The connect, send, and receive fields are the support routines that are
   used for handling encryption.

   connect:  make a connection,  fumble around and do authentication,
    and then return.  Kind of like a 'connect' call,  but does handshaking.
    Note that the data link and other stuff is handled by LPRng.  Very
    lightweight and fast.

   send: this is an alternative to connect.  The routine is handed a file
    that it packs up and then sends to the remote end.  In response
    it gets data back that it will unpack and deliver to the user as
    status or error messages.

   receive:  this routine is called when the LPD server gets an authentication
    request.
      If the 'connect' routine is used,  'connect' sends a magic
    string to the server that will cause it to call this routine.  The routine
    will do the hand shaking,  and then return.  The normal LPD service
    routine will take over.
      If the 'send' routine is used,  this routine will get the stuff sent
    by the remote end, unpack it, or what ever is appropriate,  and then
    call the LPD service routine.  By convention, it passes the routine
    a file to put its error messages, etc., into.  When the routine returns,
    the file contents are packaged up and sent back to the server.

     Note:  Kerberos4 :  uses connect / receive
            Kerberos5 :  uses send / receive
            PGP       :  uses send / receive
            MD5 'send':  uses send / receive
            MD5 'con' :  uses connect / receive

   The source code for PGP authentication is in LPRng/common/linelist.c
   (don't ask).  You can get an idea of how to add more authentication by
   looking in LPRng/common/user_auth.stub for excruciatingly detailed
   discussions and examples.

   The #define SENDING controls what stuff in the user_auth.stub
   gets included.  If you look in the sample file,  you will find:

   #if defined(SENDING)
   extern int md5_send();
   #  define USER_SEND \
      { "md5", "md5", md5_send, 0, md5_receive },
   #endif

   This little bit of code causes the prototype md5_send() to be put in place,
   and then the USER_SEND to be defined.  Note that in the original file (send_auth.c)
   that this is used in a table to insert the correct authentication stuff.

   Enjoy.

Release LPRng 3.6.12 Tue Oct 26 16:59:35 PDT 1999
  AIX does not like control files where Nxxx comes before data file lines.
   Added a 'nline_after_file' option to cause LPRng to put Nlines after
   data file lines.
   (Noticed by: Nik Conwell <nik@bu.edu>)
 configure - kerberos libraries are now specified at the start
   of the library list (LIBS="-lkrb5 $LIBS")
   (Suggested by: John Perkins <john@cs.wisc.edu>)
 Typo caused LPD not to read the permissions file.
   (Noticed by EVERYBODY,  but first by: Patrick O'Brien" <pdo@cs.umd.edu>)


Release LPRng 3.6.11 Sun Oct 24 13:37:44 PDT 1999
  Permissions checking: SERVICE=* was not getting handled correctly.
   (Found by: Dejan Ilic <svedja@lysator.liu.se>)
  Jobs with more than 26 files were quietly being mangled.
   (Found by: Derek Masseth <dmasseth@u.arizona.edu>)
  lp simulation now returns a 'job identifier' consistent with
   Solaris 2.5 format.
   (Noticed by:  Martin Mokrejs <mmokrejs@natur.cuni.cz>)
  Added support for case sensitive key lookup in sorted lists.
   (General cleanup and tidy: Patrick Powell <papowell@lprng.com>)
  Set_linger() (setsockopt socket linger timeout) failure is
   now ignored,  rather than treated as failure.  This now
   handles the case where pipes are actually second class citizens
   and the operation fails.  Note that this probably could
   be fixed by testing the file descriptor for type and then
   determining the exact socket type,  but this is NOT portable.
  Set the default paper size for the IFHP-HOWTO to letter.
   The psutils package can be used to resize this for a4, which
   is slightly larger.
  Did horrible things to job reception to handle jobs with
   spaces and more bogus entries in the name fields.  This
   is really strange.  Note: still one quirk - if the server name
   has a space in it AND the job is originated on the server,
   THEN the originating host is set to 'localhost'... which is
   correct but may be odd when forwarding to another system.
  Compaq AKA DEC True 64 support added - configure.in now does
   odd things to detect correct libraries to be used to get
   gethostbyaddr() support.  Portablility.
  configure --disable-strip will disable stripping of binaries.
   (Requested by: Marty Leisner <leisner@sdsp.mc.xerox.com>)
  Permissions, 'SERVICE=P', and job removal:
   if a print job gets through the 'R' (lpr job sumission) checking,
   and gets into the queue,  there is another check ('P' or print
   time checking.  This was done to subdue complaints from systems
   which could not handle a 'no permssions' error and would sit
   there endlessly trying to send the same job to the printer
   queue, and other users would not get their jobs through.

   When a job is ready to be printed and fails the 'SERVICE=P'
   permissions check,  it is now removed and not printed,
   UNLESS the 'save_on_error' flag is set,  in which case it
   is marked with a permissions error and left in the queue.

   Note 1:  the lpd.perms file has been updated to reflect this
   behavior.
   Note 2:  the HOWTO has been updated to reflect this behavior.
   Note 3:  if you have a DEFAULT REJECT in your lpd.perms,  this
   means that no jobs will get printed. :0).  Enjoy.

  Set the 'SO_KEEPALIVE' option on sockets to force keepalives to be
   sent so that dead connections would be detected.
  Updated some code in the common/lpd_remove.c file to close a small
   timing race condition for job removal.  Sometimes a job would get
   removed and the server process would not be killed.  Note that
   the kill is done by sending SIGINT to the processes.
  Changed a int to double for file length in common/lpd_rcvjob.c.
  Modified UTILS/cheap_lpr and UTILS/LPRng.pm to handle more than
   one file in print jobs.
  Checked out a few problems with PGP and user specified authentication.
   (Spotted by: Patrick O'Brien" <pdo@cs.umd.edu>)
  LPQ - use the file name information if no 'J' (job) line in control
   file, and finally "NULL" if no information. This prevents many scripts
   from breaking.
  getqueue.c:Get_datafile_info() was not getting the N,U, and format
   values correctly under all circumstances,  i.e. - duplicates,
   out of order N lines,  totally bogus or missing N information.
   What a mess.
   (Spotted and patch by: Edwin Lim <elim@research.att.com>)
   (And lots of others, with comments, flames, and snickers as well.)
  Fixed a problem when you used a filter to get printcap information,
   and you did a recurive get,  and you had a tc=xxx entry.
   (Spotted and debugged by: Simon Wilkinson <sxw@dcs.ed.ac.uk>)
  configure --enable-priv_ports action was reversed...
   (Spotted by: Robert Montjoy <Rob_Montjoy@ececs.uc.edu>)
  Warning message about '@' in a printcap name was malformed.
   (Spotted by: Andreas Kahnt <ak@m-ebert.de>)
  Added a 'tc_only' flag to allow printcaps to be explictly
   marked for 'tc=name' use only.  This allows people using
   NIS, NIS++, and other database engines to put printcap
   information in database forms.
  Now 'checkpc -P printer' will only check specified printer.  Handy
   for 'checkpc -f -P printer' type of operations when you add a
   new printer to a system.
   (Suggested by: Wilfried Gaensheimer <wilfried.gaensheimer@hl.siemens.de>)


Release LPRng 3.6.10 Sun Sep 12 19:46:33 PDT 1999
  lpc.1 man page moved to lpc.8 man page
  (Suggested by: Craig Small <csmall@eye-net.com.au>)

  PERMISSIONS CHECKING:
    The USER, HOST, IP, SAMEUSER, SAMEHOST, entries will now SUCCEED
    when checking permissions for an operation to be applied to a
    spool queue;  when the individual jobs in the queue are checked
    the comparisons will then be done.  This has the effect of allowing:
       ACCEPT SERVICE=C LPC=hold,release SAMEUSER SAMEHOST
       ACCEPT SERVICE=M SAMEUSER SAMEHOST
    to be specified and allows a user to hold, release, or delete
    their jobs.
    (Need pointed out by: Jens Noelle <noelle@amica.rwth-aachen.de>)

  Updated the lpd.conf file generation to put in the types of options.

  NONE renamed to NONEP due to conflicts with some <sys/types.h>
    definitions.

  Added a $_ capability to filter options.
    (Patch by: Mike Whitson <mwhitson@MIT.EDU>)

  Added a configure option to set the :sh default to 1 (on).

Release LPRng 3.6.9 Mon Aug 30 13:30:58 PDT 1999
  reverse_priority_order flag - priority z-aZ-A, i.e. - A is lowest
   (Requested by: Dennis Bush <Dennis.Bush@dowjones.com>)
  LPD now does a chdir("/") so that it is in a well known location.
   (Requested by: Craig Small <csmall@eye-net.com.au>)
  Time used to sort job is now the arrival time of the last byte
   of the job.

Release LPRng 3.6.8 Fri Aug 27 17:06:10 PDT 1999
  *** WARNING:  configure strikes again
  ***
  *** printcap, lpd.conf, lpd.perms now default to:
  ***  /usr/local/etc/{ printcap, lpd.conf, lpd.perms}
  ***
     You may want to do:
       ln -s /etc/printcap /usr/local/etc/printcap
     OR
       configure --with-printcap_path=/etc/printcap

     Please move your lpd.conf and lpd.perms files to /usr/local/etc/

  Why?  Because when trying to port this to XxxxBSD, BSDI, Solaris,
  SunOS, HPUX, DGUX,  etc etc etc I have run into so many inconsistencies
  that I have just given up.

  You might as well assume that the following is true for a default install.

  Updated configuration to be a little more consistent with other packages
   default installation directories:
     ${prefix}  is usually /usr/local
     ${bindir}  is usually ${prefix}/bin, (/usr/local/bin)
     ${sbindir} is usually ${prefix}/sbin (/usr/local/sbin)
     ${libexecdir} is usually ${prefix}/libexec (/usr/local/libexec)
     ${sysconfdir} is usually ${prefix}/etc (/usr/local/etc)
     ${mandir} is usually ${prefix}/man     (/usr/local/man)

   We install the executables in:
         (* indicates default SETUID Root install)
     ${bindir}/ lpr *, lprm *, lpq *, lpstat *
     ${sbindir}/lpc *, checkpc, lpd *
     ${libexecdir}/filters/ lpf, banner, etc
     ${sysconfdir}/ lpd.conf, lpd.perms, printcap
     ${mandir}/ man pages

   Suppose you wanted to put them in /usr/bin, /usr/sbin, and /etc:
     configure --prefix=/usr --sysconfdir=/etc


   Note the following explicit overrides:
  --disable-setuid        disable setuid root client and server executables
  --enable-priv_ports     require connections to be from privileged ports
  --disable-force_localhost force_localhost default to disabled
  --with-lpddir=DIR       lpd executable directory (default ${sbindir})
  --with-filterdir=DIR     filter directory (default ${libexecdir}/filters)
  --with-lpd_conf_path=PATH     path to lpd.conf (default: ${sysconfdir}/lpd.conf)
  --with-lpd_perms_path=PATH    path to lpd.perms (default: ${sysconfdir}/lpd.perms)
  --with-printcap_path=PATH     path to printcap (default ${sysconfdir}/printcap)

  Fixed up the INSTALL and HOWTO documentation as well.

  Note 1:  you can make a symbolic link from /usr/local/etc/printcap to
   /etc/printcap and this will solve the issue as well.

  ---
  Job time is now recorded down to the millisecond a jobs sorted according to that
    time.  This will slightly improve the situation due to multiple jobs arriving at
    at (approximately) the same time.  Jobs are sorted accordingly.
    (Suggested by: Abramo Bagnara <abbagnara@racine.ra.it>)

Release LPRng 3.6.7

  LPRng now handles files larger than 2 gigabytes on systems where the max
    size_t is larger than 2 gigabytes.
  configure now checks to see that there is a prototype for lseek().
    (Both inspired by somebody trying to print a 2G file:
       John Kimberley <jkimberly@harland.net>)
  lpq -n linecount
     Limits number of status lines to linecount.  Can be used when
   you want an exact number rather than using -llll.
  lpc now puts debug flags in () -
     Printer    Printing Spooling Jobs  Server Subserver Redirect Status/(Debug)
    t1@h4       enabled  enabled    0    none    none          (4)
  There is a horrible problem with load balance queues, SIGCHLD, and missing
    SIGUSR1 signals on Solaris 2.4, 2.5, and 2.5.1.  The code in lpd_jobs.c
    has been rewritten,  silly things have been done and it now looks awful,
    but it works,  is portable,  and ugly.  So much for elegance.
  Added more %U option to lpc, lprm to allow SAMBA to specify users.

Release LPRng 3.6.6 Sun Aug 22 10:42:20 PDT 1999
  LPD did not exit with non-zero success code when there was another
    lpd active.
    (Patch from: Stephen Fischer <fischer@cse.unsw.edu.au>)
  LPD bounce queues changed the 'N' data in the control file.  Should not
    do this.
    (Noticed by: John Rothlisberger <rthlsbrj@pprd.abbott.com>)

  New timeout - exit_linger_timeout
    When an LPD server process exits,  it needs to try to 'flush' data over
    the various pipes, sockets, etc, that are part of the IPC.  The problem
    is that on some OS's,  when a process exits the data in a pipe buffer
    may be discarded if the process exits due to a signal.  Added
    'exit_linger_timeout'  to force all pipes/sockets to be 'lingered' on
    during cleanup.  This is a totally bogus method.  What is needed is a
    setsockopt() function similar to 'fflush' that would not return until
    all the data is flushed to the remote end.  It turns out that the
    SO_LINGER with a 0 value should have done this,  but the 0 value causes
    a 'default' value to be used.  Grr...  Needless to say this is a hack
    of the worst type,  does not work on all systems.

  LPR was failing due to connnections closing due to lack of processes.
    When a connection is made to the LPD server,  it used to do accept()
    and would then fork a process.  This would lead to some ... interesting...
    denial of service attacks,  and some very odd problems when you ran out
    of processes.  The code now does the following:
       creates a pipe()
       forks a process =
         = child will now do an accept
         = child will then close the pipe
       parent WAITS until the child pipe is closed.
    This has the effect of making sure that the child process has
    done the accept,  and will BLOCK until the accept is done.
    This makes sure that there is a process to handle the connection.
    Wierd, I tell you.  Note that there is a way to do a DOS attack on
    some systems that signal a connection is available BEFORE the 3 way
    handshake completes,  and should cause endless problems.  You can
    also launch DOS attacks on inetd, ftp, etc. etc. on these systems
    as well.  See CERT for more nasty details.

  LPQ now correctly reports all jobs, even ones from different
    machines with the same job numbers.  Yeah, it looks confusing
    in the output to have two job 12's,  but HEY!  what do you want
    on 80 columns?

  LPQ now confuses people trying to figure out why there are
    duplicate jobs in the status listing.  See above.  Isn't this
    marvellous?

  lpd_jobs: when processing long queues a huge number of tempfiles
    would be created.  Now these are removed each time the queue is scanned.
    Sigh...

  lpd_jobs: when you have a connection opened using lp=host%port,
    then lpd now do a shutdown(port,1) on the socket.  Now we get
    into the really odd stuff.  We first set the linger value to
    'read_write_timeout' if nonzero otherwise the 'exit_linger_timeout'.
    IF the 'wait_for_eof' flag (default TRUE) is set,  we try
    READING from the socket until we get an eof.  We then close
    (with the linger) the socket.

    Here are the problems that this tries to solve.

    When you send a job to a printer over a socket connection,
    you stuff the files into a socket and then expect the OS to
    deliver the data.  WRONG!  The OS puts this in some buffers.
    It returns from the WRITE call with success.  You now do a
    close().  At this point there are some interesting possibilities:
    a) your data is delivered,  even after waiting 6 weeks for the
    other end to respond (BAD choice); b) the system attempts to
    deliver your data for,  say,  120 seconds (default 'linger'
    time on some BSD systems);  c) you can specify how long you
    want to have the system try to deliver the data.  While this
    is going on of course, you cannot open a connection to the
    device,  as it is still busy with the previous connection.

    You really want to treat the 'close' like a 'write' and wait
    for a reasonable (read_write_timeout) time for this to happen.
    When you do a write 'shutdown',  the TCP/IP connection sending
    (write) capability is terminated, and the TCP/IP stack does a
    handshake with the other end telling it that no more data will
    be sent.  The receiver will get an EOF when it tries to read
    more data, and will, in turn, close the connection.  Note that
    this must be a 'shutdown' and not a 'close'.  All close does
    is closes the process's copy of the file descriptor information.
    Shutdown is brutal and will terminate with predjudice the tcp/ip
    level communication (thank the Diety).  How do you know that
    the receiving end has closed the connectio? You do a read from
    the socket until you get an EOF.  Of course,  you should be
    reading from the &*()*& socket at all times,  as the printer
    will be sending status, error messages, etc. etc.  back to you.
    But your filter should be doing this,  right?  Oh... you do
    not have a filter... well, you MUST have a filter that does
    the reading - this is what the IFHP filter was designed to do,
    and in fact goes overboard to solve this problem.  Even when
    you say 'status@' it STILL tries to read from the file descriptor
    because there might just be stuff coming back.  Sigh...

Release LPRng 3.6.5 Sun Aug  1 16:46:31 PDT 1999
  The date format in the status messages has been changed so that
    you can have a short or long format displayed.  By default, the short
    format is displayed (short_status_date option is true).  Note that this
    sillyness is partly forced on us by Y2K issues.
    New flag option: short_status_date - when set, status time/date displays
    only time.
    (Sigh... by: Patrick Powell <papowell@lprng.com>)
  Remote logging information now contains full date and time and process id.
    (Sigh... by: Patrick Powell <papowell@lprng.com>)
  Update LPRng HOWTO to specify that filter STDERR output is now merged with
    the status messages.  This allows errors reported by the filter to appear
    on the lpq status.
  You can specify filter arguments as the form xxx 'yy yy' "zz zz" and they
    will get passed as a block.
    (Suggested by:  Martin Forssen <maf@crt.se>)
  The lpstat -a code has been fixed so that it correctly searches for
    printer names.
    (Reported by: Martin Forssen <maf@crt.se>)
  Removed duplicate status information lines in status file.
    (Discovered by: Patrick Powell <papowell@lprng.com>)
  Added 'send_failure_action' information to status output to allow users
    of this very odd feature to figure out what is happening.
  Fixed up LPRng to handle a stupid RFC1179 idiocy.  If you have a control
    file, then the order of N and data file lines is not defined.  So
    you have to handle them in any order.  Also,  you can have the same
    data file line with DIFFERENT formats - sigh... this means that you
    can print it several times with different formats.
  The 'generate_banner' option, which was present in 3.5.1, has been restored.
    This is only operational when you have a 'normal' forwarding queue.
    It uses the 'ab' (always banner), bp (banner printer), bs (banner
    printer program for banner at start), and be (banner program for banner
    at end), hl (header or banner last) and the user banner information.
  The "cm" (comment) option has escapes processed.  Now you can put ":"
    in the comment line by using "\072"
    (Wanted by: Johan Claesson <Johan.Claesson@uab.ericsson.se>)

Release LPRng 3.6.4 Sat Jul 24 14:29:09 PDT 1999

  Cut and Paste-o observed in the configure.in file - LPD_CONF_PATH
   should be LPD_PERMS_PATH.
   (Reported and patched by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu)
  Added: AC_PROG_AWK, AC_SUBST(AWK), to configure.in to find the version
   of awk to use.
   (A good suggestion by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu)
  SAMBA Assistance.
   The -U option has been extended to the LPRM program as well as the LPR
   program.  This allows facilities such as SAMBA to submit jobs on behalf
   of users.  In order to allow SAMBA and these facilities not run as root,
   the allow_user_specification=name,name,... configuration option will allow
   either root or the named users to forgre... I mean impersonate any user.
   The SAMBA printing configuration file will now look like:
    [global]
        printing = lprng
        print command = /usr/local/bin/lpr  -P%p -r %s
        # alternative to allow userid to be specified as well
        # You will have to add the samba UID to the 'allow_user_setting'
        #   option in the /etc/lpd.conf file.
        # print command = /usr/local/bin/lpr -U%U -P%p -r %s
        lpq command   = /usr/local/bin/lpq  -P%p
        # alternative
        # print command = /usr/local/bin/lpr -U%U -P%p -r %s
        lprm command  = /usr/local/bin/lprm -P%p -U%u %j
        printcap name = /etc/printcap
        load printers = no
    [printers]
       comment = All Printers
       path = /tmp
       browseable = no
       printable = yes
       guest ok = no
       writable = no
       create mode = 0700
    man pages and HOWTO have been update to reflect these changes.

  commmon/linelist.c: Escape() had a malloc() size error.
  man/lpd.8 man page editted and fixed up for consistency.
   (Found by: Patrick Powell <papowell@lprng.com>)

  FreeBSD Support: FreeBSD.ports.sysutils has the files for a Ports Install
  RedHat RPM: pkg has the files needed to build a RedHat RPM distribution.


Release LPRng 3.6.3 Fri Jul 16 16:01:27 PDT 1999

  CONFIGURE CHANGES
   Please note that the configure and 'make install' have been modified in
   order to deal with different installation locations and configuration setups.
   Here are the options to configure that you should be aware of:
    --with-cppopts=CPPFLAGS  select compiler preprocessor command line options
        **** note: these flags will also be passed to CC, so set your options using
        **** this configuration option.
    --disable-setuid      disable setuid default
        **** note:  use this if you want to install without setuid
    --disable-priv_ports   set default lpd.perms to reject connections from non-privileged ports
        **** note:  if you disable priv-ports, you MUST install setuid.
        ****   Thus, you can have --disable-setuid, --disable-priv_ports, but not both
    --disable-force_localhost      disable force_localhost default
    --with-lpddir=DIR       where to install the lpd binary.
        ***   where you want LPD to be installed.
    --with-admindir=DIR     where to install the administrative commands, like
                            checkpc, lpc, etc.
        ***   where you want the other stuff installed
    --with-filterdir=DIR     where to install filter (default ${libdir}/filters)
                            checkpc, lpc, etc.
        ***  where you want the filters installed
    --with-lpd_conf_path=PATH     where to install lpd.conf (default /etc/lpd.conf,/usr/etc/lpd.conf)
    --with-lpd_perms_path=PATH     where to install lpd.conf (default /etc/lpd.perms,/usr/etc/lpd.perms)
    --with-printcap_path=PATH     where to install printcap (default /etc/printcap,/usr/etc/printcap)
    --enable-nls           use Native Language Support
    --with-included-gettext use the GNU gettext library included here
    --with-catgets          use catgets functions if available

  MAKE INSTALL changes
     These tie into the changes with configure.  You should be aware of them.
     You have been warned.

     Note 1: FreeBSD
       To put LPD in /usr/libexec/lpd,  admin in /usr/sbin, and other stuff in /usr/bin
       configure -with-lpd_conf=/usr/libexec/lpd -with-admindir=/usr/sbin --prefix=bin
     Note 2: RedHat Linux
       To put LPD in /usr/sbin/lpd,  admin in /usr/sbin, and other stuff in /usr/bin
       configure -with-lpd_conf=/usr/libexec/lpd -with-admindir=/usr/sbin --prefix=bin

  Minor fix to configure, src/Makefile to link only lpq with terminal library
    (Supplied by: Roderich Schupp  <rsch@ExperTeam.de>)
  Set spool_dir_perms to 0600 instead of 042600.
    (Supplied by: Roderich Schupp  <rsch@ExperTeam.de>)
  Typos and More Typos in HOWTO
    (Spotted by the Eagle Eye of: Wolfgang Schludi <schludi@syscomp.de>)
  Printcap 'oh=' was using wrong entry.
    (Reported by: Wolfgang Schludi <schludi@syscomp.de>)
  lpd -D= did not tell you what you did wrong.
    (Reported by: Niklas Edmundsson <nikke@ing.umu.se>)
  Kerberos authentication forwarding was incorrect.
    (Fixed by: Mike Whitson <mwhitson@MIT.EDU>)
  Printcap includes were not being processed correctly.
    (Reported by: Don Badrak <dbadrak@census.gov>)

  The spool queue control, status, and unspooler files (control.%P,
    status.%P, and unspooler.%P) are now specified by the
    queue_status_file and queue_control_file options.  This allows
    you to relocate the files to another spool queue, or even use
    the file.%D option to have a date appended to the file name.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)
  When the lpd logger facility makes a connection to the receiver of the
    log information,  it sends a dump of the system status.  The dump
    consists of a set of lines, one line per print spool entry.
    The end of this dump information is indicated by a single END
    line, i.e: END\n.  This enables a database management system to
    know that all of the queue information has arrived and can then
    undertake to do any consistency checks.
    (Need determined by:  Patrick Powell <papowell@lprng.com>)

  When a 'lpc reread' is done,  the logger process is killed and restarted.
    This forces the logger process to use the new printcap or configuration
    information.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)
  When an unspooler process is active,  a SIGUSR1 signal is sent to it
    to force it to rescan the spool queue.  The SIGUSR1 signal
    handler sets the Susr1 flag,  and this flag is checked.  There
    is a small window between the time that the flag is checked,
    the process decides that no new jobs have been put in the queue,
    and the process exits.  This window has now been narrowed down even
    more by performing a final check just before the process exits.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)
  On a heavily loaded system where a large number of files are being
    created and/or destroyed,  the spool queue scanning code would
    miss some jobs at the start or end of the queue.  This was due
    to the fact that the scandir() routine does not lock the spool
    directory,  and it can change as the directory is being read.
    In order to reduce this window to the smallest possible size,
    the directory is now scanned for files and then the files are
    processed.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)

  Updated HOWTO to reflect these changes.  Updated MAN pages.

Release LPRng 3.6.2 Sat Jun 12 16:44:15 PDT 1999
  LPRng-HOWTO corrections.
   (Corrections by: Vladimir V Egorin <vladimir@math.uic.edu>)

  Used the wrong process exit status variable in common/lpd_jobs.c
   (Noted by: Olav Kolbu <olav.kolbu@usit.uio.no>)

  Added STATE and LPC command execution tracing to the
   logger messages.  This allows a remote system which is
   monitoring LPRng operation via the logger interface to
   monitor when a job is submitted and printed.

  Updated format of message sent by logger.
    UPDATE message now has a
      hf_image= and (optional) lpc= encoded portion
    QUEUE message now has a
      queue= and (optional) lpc= encoded portion

    The lpc identifies that the udpate was done by LPC operation
    rather than by LPD as part of normal operation.

  File locking had problems under SunOS 4.1.4.

  You can now have single letter printer names.
    (Sigh... noted by: Patrick Powell <papowell@lprng.com>)

  Accounting information now has options (correctly) quoted:
   start '-H...' '-c' '-JThis is a job'
   This is consistent with ifhp 3.3.2.

Release LPRng 3.6.1 Mon Mar 22 09:42:07 PST 1999

  This release is a major rewrite of the LPRng software and uses
  dynamic memory allocation and as few static and global variables as possible.
  This is intended to simplify the porting of the LPRng software
  to a multi-threaded environment. In addition,  substantial
  cleanup of much of the code was done.

  Due to time constraints,  some functionality that is present in other
  test versions was not put into this release.  This includes
  setting user information by originating IP address.
  The 4.x.x release will have support for the new IPP print protocol,
  SNMP MIB,  and a HTTP server interface.

  As far as possible, existing functionality has been preserved,
  with the following notable exceptions.  These are divergent enough
  to cause a new major release number to be used, i.e. - 3.6.x

  License

    Due to various technical legal reasons,  the License for this
  release of LPRng has been changed from the GNU Copyleft to the slightly
  different but similar in intent Artistic License.

  Load Balance Queues and Class types

    Assume: a load balance queue with several printers, say
       master -> S1, S2;
    You can now set the class types accepted by S1 and S2, and
    the Master Queue will check the job types against the class
    types before sending the job to the appropriate queue.

    What is this all about? If S1 has blue paper you can set the
  currently printing class to blue (lpc class blue).

    Now do lpr -Pmaster -Cblue and your job will be routed to printers
  which currently are printing class 'blue'.  Clearly this can be
  extended to other things besides paper.

    Note that when you use this option you should set the master
  queues ignore_requested_user_priority flag so that the first
  letter of the class type is not used as the priority.

  *********************************
  ******* force_localhost *********  distribution default is ON
  *********************************

    The Most Frequently Reported Problem with 3.4.X and 3.5.X was the following:

      lpr is not sending jobs to my lpd server.  Why?

  The reason is that other BSD based spoolers ASSUME that the
  lpd server will be running on localhost,  and the clients
  (lpr, lpq, etc) will connect to the server.  So the printcap
  files are written as:
   lp:sd=/usr/spool/whatever
     :rm=remoteserver:rp=remoteprinter

  Of course, lpr reads this as meaning 'connect to the remoteserver',
  and never sends the job to the server running on the localhost.

  The 'force_localhost' option will FORCE lpr, lpc, etc to connect to
  the localhost UNLESS lpr -Ppr@remoteserver is used, i.e.- a command
  line override.  In LPRng 3.5.X, the default value of 'force_localhost'
  was OFF.  In LPRng 3.6.X, the default value is ON.

  Bounce Queues, lpd_bounce,  and LPR Side Filtering

    The lpd_bounce option REPLACES bq=xxx
  Example:            ->
    pr:lp=pr@xxx         pr:lpd_bounce
      :bq=far@server       :lp=far@server

    This makes bounce queues consistent with remote print queues.

    The entire print job job is passed through the various filters,
  and the entire output is now sent as a single file to the next
  queue.  The format of this file is set by the bq_output=X option.

    This now allows the full use of leaders, trailers,
  banner page generation, etc., to be used.

  Printcap tc=xxx:tc=yyy handling
    printcap includes (tc) are done BEFORE setting the values
  in the printcap entry,  and in order.  Thus:

     lp:s=X:tc=.t1,.t2:tc=.t3
     .t1:s=Y
     .t2:z=W
     .t3:z=P

   would result (for lp) in:
     lp:
      :s=Y # from .t1
      :z=W # from .t2
      :z=P # from .t3
      :s=X
    and a final result of
     lp:s=X:z=P

   (Requested by and faultless arguments by: the lprng mailing list...)

  Permissions List File:
    You can now say XXX=<filename and the whitespace separated
  contents of the file are used as the options value.

  Example:
    ACCEPT REMOTEHOST=</usr/local/etc/lpd_hosts
   and have /usr/local/etc/lpd_hosts contain:

    *.site.com
    10.0.0.1/24  pc.*.mystuff.org

  LPC Permissions Checking

  You can now use:
    ACCEPT LPC=hold,remove,topq
  If you are doing an LPC operation, then this matches the operation.
  This replaces the lpc_user=.... printcap abomination.

  For example, to allow user X on the server to do hold operations,
  use:

    ACCEPT LPC=hold USER=x SERVER

  The 'ms', 'sy' and 'ty' serial port configuration options are now
  the single option 'stty' which makes more sense and is compatible
  with other LPRng software.

  The 'rt' and 'send_try' options were accidentally aliased - removed
  the 'rt'.

  There is now finer control for remote LPQ queries.
   force_lpq_status=KEY=hostlist;KEY=hostlist
     Specifies a set of hosts and the format for lpq status queries,
     overridding the requested format.
      KEY = l (long) or s (short)
      hostlist = list of IPaddress/Mask or GLOB patterns for hostnames
     Example:  force_lpq_status=s=*pc.site.com,10.0.25.0/24;l=sunsystem.site.com
   reverse_lpq_format=hostlist
     Reverse l and s query formats when a request arrives from these
     hosts.
   return_short_status=hostlist
     Return short_status_length status lines when a request arrives from
     these hosts
  short_status_length=N
     Number of status lines to return when return_short_status matched

  LPC added commands
    active   - checks for an active server
    local (all | printer) - show printcap and configuration information
      for a local printer.  Debugging aid.

  LPQ added option
     -L   - equivalent to -llllll....

  CHECKPC
      checkpc -V now prints out all sorts of additional information for
    debugging and problem solving.
      checkpc now checks both for server AND client mode.  No fixing done
    for client information, just displays it.
      checkpc now checks for missing tc=xxx entries.

   LPD_CONF_PATH and PRINTCAP_PATH compilation option
     make LPD_CONF_PATH=/usr/local/etc/lpd.conf
     make PRINTCAP_PATH=/usr/local/etc/printcap
       - changes the /etc/lpd.conf and  /etc/printcap file
     default locations

  AUTHENTICATION

     The entire authentication interface has been redone,  and PGP,
  Kerberos 5, and MIT Kerberos 4 Print System compatibility has
  been added.  The permissions checking method has been changed as
  follows,  with respect to the following keys:
    AUTH       match or TRUE  if authenticated transfer done
    AUTHTYPE   matches the authentication type
    AUTHUSER   client or user's authentication id
    AUTHFROM   originating server's authentication id when forwarding job
    AUTHSAMEUSER   match if the client id in the request and the
               (saved) client ID used to spool a job are identical.
    AUTHJOB    match or TRUE if a job was submitted with authentication

  Options have been redone to put a bit of consistency into things

    auth=xxx                   authentication type for client to server
    auth_client_filter=/path   client to server authentication filter
    auth_forward=xxx           authentication type for forwarding
    auth_forward_id=xxx        authentication id for remote end when forwarding
    auth_forward_filter=/path  server to server authentication remote server id
    auth_recieve_filter=/path  server filter to recieve authentication
    auth_server_id=xxx         client to server - id of server
                               receiving server - id for reception
                               server to server - id for origination
    pgp_path=/path     path to pgp program for auth=pgp
    pgp_passphrase=clientkey   file in $(PGPPATH) or $(HOME)/.pgp
                               holding client passphrase
    pgp_server_key=~daemon/.pgp/serverkey   file holding LPD server passphrase

  SOLARIS Package Support
    Start of generating binary distributions.
    (Contributed by: Martin Forssen <maf@crt.se>)

  LPD lock file:  now defaults to /var/run/lpd
    (Pointed out by: Martin Forssen <maf@crt.se>)

  %D expansion,  create_files flag
    If you have %D in a printcap value,  it gets expanded to the
  current date in YYYY-MM-DD format.  If you have the create_files flag
  set,  then the files that normally get trimmed (max size specified)
  are created.  This allow you to do:
     lf=log-%D
  Your log files now will have the pathname sd.../log-YYYY-MM-DD
  and you can now get rolling log files on a daily basis.
  The files that have this done are the log file, status file,
  and accounting file.

  PCLBANNER and PSBANNER - new banner printing programs using PERL produces
   pcl or PostScript banner page.

   lp:bp=/usr/local/.../pclbanner
     :of=....
     :if=....
   OR

   lp:bp=/usr/local/.../psbanner
     :of=....
     :if=....


  Bug fixes:
    Gadzillions.  Many.  Some were not bugs but simply inconsistencies with
  documentation.  Sometimes documentation changed, sometimes the code.

  Default Server Print Queue:

   The default_printer_when_unknown configuration option
   allows you to specify a print queue that the server will use when
   it cannot find one in the printcap.  This print queue should have
   the format:

   /etc/lpd.conf:
    default_printer_when_unknown=fallback

   /etc/printcap:
   fallback:server
    :sd=/usr/spool/lpd/%P
    :router=/..../router_for_misdirected_jobs

    The router should output the correct destination (see router documentation
    in LPRng-HOWTO),  and exit with 0, or exit with JREMOVE to cause the job
    to be dropped in the bit bucket.

Release LPRng 3.5.4 Mon Nov  9 10:07:42 PST 1998
  Bug fixes:
  Bad link to site in LPRng.smgl documentation.
   (Reported by: Anthony Thyssen <anthony@cit.gu.edu.au>)
  LPQ status was missing a space separator when reporting
    subserver name list.
   (Spotted by the Eagle Eyes of: John Callaghan <callagh4@pilot.msu.edu>)
  The xt flag has been expurgated,  totally.  As was documented.
   (Spotted by: James P. Dugal <jpd@usl.edu>)
  LPR_bsd option added so that -m does BSD mail option.
   (Requested by various folks)

  Testers and bug fixers:
   (Compilation: Bernie Kirby <bernie@ecr.mu.oz.au>)




Release LPRng 3.5.3 Mon Nov  9 10:07:42 PST 1998
  Documentation Error:
    LPRng-HOWTO, Section 8, indicated that the lpd.conf file
  could be obtained using a filter.  This is not correct.
  (Noticed by: David Stenglein <david.stenglein@citicorp.com>)

  Major Modification:
    removed the 'xu' (per spool queue permission file) after trying
  to make the semantics work.  Now we have a single permission file
  for all printers

  Major Modification - Load Balance Queues:
    Some users reported very slow operation of the load balance
    queues.  This was verified,  and extensive modifications were
    made to the functionality.

    CHANGE:
        The subserver queues are only scanned at startup
      and when there is an explicit indication that a new
      job has been put into or removed from the queue
      (SIGUSR2 received)

  Major Modification - LPD Does Not Ignore LPR, LPC Requests

      Some users with either large numbers of spool queues or
    spool queues with large numbers of jobs noticed VERY slow
    LPD response.
      This has been improved considerably.

    CHANGE:
      LPD server would run through the Spool queues, looking for
    trash to be removed or jobs to be started.  This polling is
    necessary due to the possibility of a race condition between
    the time that a job is put into the queue and the time that
    the unspooler checks the queue for entries.
      The operation has been modified so that only a SINGLE PROCESS
    runs down through the spool queues.  When it finds work to do,
    it informs the LPD server,  which now will start ANOTHER process
    to check other queues for work.  Note that while these processes
    are working their little hearts out,  chewing up swap space
    and reading directory entries like mad,  the LPD server can
    accept requests for LPQ, etc.

  Major Modification - LPR speedup:
    The LPD server now accepts jobs for spooling WITHOUT extensively
    checking the spool queue.  This eliminates problems with printing
    to queues with a large number of entries.

  Speed Improvement:
    A bit of time analysis showed that LPRng was spending a large
    amount of time during queue scanning in the fcmp() routine.
    This has been rewritten and is now a strcmp().

    During queue scan, Get_controlfile() generates a 'cmp_str' value
    that represents the information needed to do sorting.  This is
    is then used during queue sorting as the comparison value.

    The 'struct cmp_struct' in the include/sortorder.h is used to
    make sure that sufficiently long string buffers are allocated.
    The make_cmp_str() in common/sortorder.c can be replaced with
    a users version if they desire.

  Bug Fix:
  safestrncpy, mystrncpy, safestrncat, mystrncat now used for string
   copies where there is doubt on the buffer/string length.  Note that
   these versions will always make sure the buffer is terminated with
   a 0 value.

  lpr -U xx is supposed only to work for ROOT. Check for root perms
    was not done correctly.
    (Patch by: Paul Szabo <psz@maths.usyd.edu.au>)
  permissions checking:  the C=value1,value2 permissions checking
    option wants a C (control file) line starting with character C
    and glob matching the indicated value1, value2, etc.  For example,
    N=patrick*,powell* should match against line Npatrickwashere or
    Npowellwasthere.  The check was done incorrectly.
    (Patch by: Paul Szabo <psz@maths.usyd.edu.au>)
  LPD/lpd_rcvjob.c - removed limits on lengths of class and host names
  When using bounce queues and the generate_banner to cause a banner to
    be added to a job,  the 'ab' (always banner) and the lpr -h (no header)
    flags now are used in the decision for banner generation.
    (Noticed by: Charles Karney <karney@pppl.gov>)
  Filters were not being passed -Knnn option.
    (Noticed by: Charles Karney <karney@pppl.gov>)
  Permissions:  SERVER keyword was not used for X permissions.
    (Fix by: Patrick Powell <papowell@lprng.com>)
  File Permissions:  spool_file_perms was being ignored due to the
    umask() not being (un)set before creating a file.
    (Discovered by: Albert Fluegel <albert.fluegel@hl.siemens.de)
  ConnectTimeout now times out on connect() calls.
    (Reminded by: Heinz-Ado Arnolds <arnolds@ifns.de>)
  Accounting filter:  when the filter returns 'JHOLD' the job
    will be held (as documented).
    (Patch by: Rainer Schoepf <schoepf@uni-mainz.de>)
   LPRM incorrectly gives the "clean" usage instead of "lprm" usage.
    (Fix by:  Edan Idzerda <edan@mtu.edu>)
   The 'xt' and 'check_for_nonprintable' flags were in conflict.  Removed
    the 'xt' flag.
    (Reported by: "Dugal James P." <jpd@usl.edu>)
   The LPD/lpd_remove.c code did not remove jobs correctly when a
    :destination=... entry was present
    (Patch by: john@cs.wisc.edu)
   Log files not being truncated.  Well, they are now.
    (Fix by: Patrick Powell <papowell@lprng.com>)
   LPR not printing multiple copies (-K option)
    (Patch by: Keith Richardson <keithr@ms.com>)
   LPD did not check spool queue just before exiting from printing loop.
    This opened a BIG race window on systems with lots of jobs in the
    spool queue.
    (Fix by: Patrick Powell <papowell@lprng.com>)
   Expand_command did not check for Do_dollar() returning 0, indicating
    a string overflow condition, which it then dereferenced and core dumped.
    (Reported by:  (Walter Misar) <misar@rbg.informatik.tu-darmstadt.de>)
   Control file filters were not being invoked correctly.
    (Reported by: Tony Graham <Tony.Graham@uni-c.dk>)
   Memory trashing being done by different behaviour of strncat() on some
    systems.  Replaced by mystrncat() and took the performance hit in return
    for reproducible behaviour and non-trashing copies.  Sigh.
    (Fix by: Patrick Powell <papowell@lprng.com>)
   strncpy() and strcpy() does not handle overlapping strings correctly, or
    at least that is what the man page says.  Replaced several of these
    calls by memcopy() and friends.
    (Fix by: Patrick Powell <papowell@lprng.com>)

Release LPRng 3.5.2 Fri May  1 14:39:55 PDT 1998
  Bug Fix:
   lpr -k did not pass the correct length (0) to the
   remote system.
    (Reported and patch by:  Wolfgang Scherer <ws@ecosys.de>)
   common/pr_support/ checks Do_lock() for <= instead of < for
    failure condition.
    (Reported by:  Wolfgang Scherer <ws@ecosys.de>)
   common/proctitle.c had a strdup() call - not supported
    under ULTRIX.
    (Reported by:  "Todd C. Miller" <Todd.Miller@cs.colorado.edu>)
   force_localhost was being tested BEFORE it was set in the printcap
    entry.  Now is checked AFTER the printcap entry is processed.
    (Reported by: Petri Kaukasoina <kaukasoi@elektroni.ee.tut.fi>)
   LPD returns 'o connect permissions' instead of 'no connect ...'
    (Noted by: Reinhard Zierke <zierke@informatik.uni-hamburg.de>)
   LPD records filter name in error message correctly.
   LPQ now reports full class name in status message if
     'class_in_status' flag set in printcap.
     (Requested by: Philip J. Nesser II <pjnesser@nesser.com>)
   common/sendlpc.c - missing Lp_device = 0
     (Reported by: "Dugal James P." <jpd@usl.edu>)
   LPD reported the wrong host name in 'no permission' messages.
     (Noticed by: Patrick Powell)

Release LPRng 3.5.1 Fri May  1 14:39:55 PDT 1998
  Baseline Stable Release

Release LPRng 3.4.12 Fri May  1 14:39:55 PDT 1998
  Legacy support modification:
    control file now has printer information in:
       controlfile
       Ninfo
       Uinfo
    order.  Some legacy printer spoolers require this order.
   (Reported by: Don Badrak <dbadrak@geo.census.gov>)

  Minor cleanups of:
    Get_printer() calls - some silly comments and orders
    common/fileopen.c/Init_tempfile() - clarified the
      use of the various directories and defaults.
    Force_localhost:  now done in Get_printer(), where it should
      have been done in the first place;  LPQ  and LPRM
      now send requests to localhost unless explicitly overriden
    Force_fqdn will now brutally assume that the domain of the
      sender is the one reported by the FQDN of the originator
      of the connection.

Release LPRng 3.4.11 Thu Apr 30 11:46:25 PDT 1998

  Functionality Change:
   JABORT and stop_on_abort default value changed
   JNOPRINT filter exit status stops printing
   JFAILNORETRY filter exit status stops retries

  In previous versions,  when a filter exited with unknown or
  JABORT status,  the default action was halt processing of
  PENDING jobs.  When a new job was sent to the queue,
  or a lpc start was performed,  processing was restarted started.
  Under heavy load conditions,  the effect of the JABORT was
  nullified by the arrival of new jobs.

  The LPRng behaviour has now been modified to handle JABORT
  conditions in a predictable manner, using the 'stop_on_abort'
  flag.

  1. The default for 'stop_on_abort' is now FALSE.
     This means by default that the JABORT status will simply be
     treated as a 'do not retry this job' error status.
     If the 'save_on_error' flag is FALSE (default), the job
     will be removed from the queue.

  2. If 'stop_on_abort' is set to TRUE,  then when a filter
     exits with a JABORT on unknown status,  further processing
     will stop, and NO pending jobs will be printed.  If the
     'save_on_error' flag is FALSE, the job will be removed from
     the queue.

  3. If 'stop_on_abort' is set to TRUE, the abort condition is
     sticky, i.e. - it will persist until
     action is taken to clear it.  Any of the LPC commands which
     cause printing to be restarted will clear it:
       LPC start, up, kill, topq, release, or redo

  4. LPQ and LPC will report if there is an aborted job condition.

  Note that for most users, the default action is now the desired
  action, i.e. - to continue processing jobs.

  However,  certain administrators will most likely need to assume
  that when a filter exits with JABORT that further printing on this
  queue will fail.  The sites should set 'stop_on_abort' to TRUE.

  JNOPRINT:

  If a filter exits with JNOPRINT,  then printing will be stopped;
  this will have the same effect as an LPC stop command.  The job
  will NOT be treated as an error job and will remain pending in the
  print queue.

  This allows filters to detect conditions that would normally cause
  printing to fail before a job is started,  and halt printing under
  these conditions.

  JFAILNORETRY:

  Under various arcane conditions,  it is possible for a filter to
  determine that a job has failed,  and should not be retried.  Most
  filters would return a 'JREMOVE' error code,  but for various arcane
  reasons (lots of Arcania here, folks), the 'save_on_error' flag
  might be set,  and the adminstrator would like to have the job
  marked as erroneous,  but NOT removed.

  If the filter exits with JFAILNORETRY,  then the job is treated
  as though it had an error, but no retries are performed.

  Extended Functionality:  'mail_from' option
    Allows specification of the 'From:' user.  If not specified
    default is to use the printer name.
   (Patch By: Rainer Schoepf <schoepf@uni-mainz.de>)
  Portability Extension:
   LPD_CONF_PATH compilation option
   The location of the LPRng configuration file is specified
   by the config_path value in the src/common/vars.c file.
   The compilation option -DLPD_CONF_PATH=path can be
   used to override the default locations.
   Example:  make LPD_CONF_PATH=/usr/local/etc/lpd.conf all
  Nit Fix:  spelling errors corrected.
   (Reported by: Don Badrak <dbadrak@geo.census.gov>)
  Incredible 9 Gigabyte Partition Fix:
   (Reported by: Don Badrak <dbadrak@gesg34.geo.census.gov>)
   Apparently the common/freespace/plp_fs_free_bytes cannot handle
   a >4 gigabyte partition.  The fix was to cast values to a
   double - this should be sufficient until we get 10**38 byte file
   systems. :-)
  Bug Fixes:
   LPD usage() had (erroneous) -i option.
     (Reported by: wcolburn@nmt.edu (William Colburn (aka Schlake)))
   get_max_servers did not get max servers.
     (Patch by: Don Badrak <dbadrak@gesg34.geo.census.gov>)


Release LPRng 3.4.10 Thu Apr 23 18:01:37 PDT 1998
  Added Functionality:
   sync_lpr flag- this suppresses the closing of the lpr to lpd
   network connection until the LPR job is completely processed
   by the LPD server.  This can,  under various arcane and odd
   situations,  result in the lpr processes 'hanging' until the
   LPD server queries DNS servers, looks up permissions, etc etc.
   However,  if users are trying to figure out why LPR has returned
   and their job is not in the queue,  or you have some desire to
   write shell scripts that create jobs and then remove them
   in order to see 'just how fast LPRng is',  this flag will SLOW DOWN
   the operation by making it synchronous.  Any little thing
   to make folks happy... :-)
 Modified Functionality:
   The 'force_localhost' flag has now been modified to (literally)
   force a connection to one of the 'localhost' addresses returned
   by a DNS lookup.  This should have no effect on 'normal' users,
   but might have the result that the status returned by LPQ
   will now differ a little.  For example, if you have a printcap
    pr:lp=pr@host2:force_localhost
   you will discover that lpq -Ppr will now print:
    Printer: pr@localhost
     ... status for localhost queue
    Printer: pr@host2
     ... status for host2 queue
   This is correct and accurate reporting, compared to the previous
   lpq format.
    (Brought to my attention by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)

 Bug Fixes:
 Job_printable_status() did not report active jobs, so lpq and lpc job count
   was off by one.
   (Reported by:  Al Marquardt <almar@uiuc.edu>)

Release LPRng 3.4.9 Mon Apr 20 12:42:55 PDT 1998
  Enhanced Functionality:
   For those folks who want to 'masquerade' their servers,
   the 'report_server_as=hostname' will now report your printer@server
   as 'pr@hostname'.
   (Requested by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)
  EXTA/EXTB:
    ifdef'd for folks with REALLY vintage systems...
    (Requested by: David Coelho <drc@ppt.com>)
  Added debugging code to determine when servers started.
  LPD now clears job 'move' indications so that a job can
    be saved (save_when_done) and then reprinted with
    out being moved to the destination again.
  lp -s (Silent) now does not print job id information.
    (Noticed by: David Coelho <drc@ppt.com>)
  Jobs which do not have print permissions now get removed.
    (Reported by: Al Marquardt <almar@uiuc.edu>)
  lpq -tN -c now will not core dump.

Release LPRng 3.4.8 Sat Apr 18 15:23:22 PDT 1998
  Portability Fix:  AIX 4.1.5 has definition conflicts when
  doing #include a.out.h.
   (Reported and Fix by: Niklas Edmundsson <nikke@ing.umu.se>)
  Also, Solaris4.1.4 has conflicts with tgetent() definition.
   (Reported by: wcolburn@nmt.edu (William Colburn (aka Schlake)))
  Y2K checked - ISO conformant date format is used in log and other
   messages.
  :force_fqdn_hostname flag causes FQDN host name rather than
   short hostname to be put into control file.

  Bug Fixes:
  Accounting at end was failing do to closing output device
   too early in the algorithm.  Device now closed AFTER last
   accounting script is called.
   (Reported by: Niklas Edmundsson <nikke@ing.umu.se>)
  Time_t strikes again.  I just discovered that there were some
   places where I was using long instead of time_t for time values.
   This has been fixed.  However, there is also now the problem
   of snprintf( "%d", time((void*)0)) being used for output and
   t = atoi("xxx") for input of time values.  Sigh... will fix
   this later.
  "lpc lprm pr all" operation now works correctly
   (Reported by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)

Release LPRng 3.4.7 Wed Apr 15 08:40:25 PDT 1998
  Bug Fix:
    Stupid system implementor used snprintf() instead of
    plp_snprintf,  causing headaches for unsuspecting
    folks on systems that did not have snprintf().
    Better fix is to insist that systems have snprintf() :-)
    (Reported by: Helmut Jarausch <jarausch@igpm.rwth-aachen.de>)
  Enhancements:
    The code for doing 'polling' of spool queues had a very high
    overhead in terms of process creation.  This code has been
    modified to have a single process run down the queues and
    check for work.  There is a bit of overhead,  but much less than
    the overhead in creating a large number of processes.
  Bug Fix:
    when generating banners using :generate_banner,  it did not
    work.  System developer forgot to include banner... :-)
    (Reported by: Cecil R. Whitaker <cwhitak@nswc.navy.mil>)

    Jobs that did not get permission to print and were flagged
    with JREMOVE did not get removed.
     (Reported by: Al Marquardt <almar@uiuc.edu>)

    When putting in a new 'From this host' line in a control file,
    did not remove the old one.  Also 'Q' entry as well.
     (Reported by: Al Marquardt <almar@uiuc.edu>)

    Multi-homed hosts that do not recognize interfaces need
    special coddling when trying to connect to them.  Link_support.c
    gets yet another special case for connections.
     (Patches by: Giray Pultar <pultar@pprd.abbott.com>)

    listen(backlog=64) - used to be 10, which caused connections
    to be dropped under heavy loads.

    checkpc was adding a / to end of file names.
    (Noticed and fixed by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)

Release LPRng 3.4.6 Tue Mar 31 18:10:59 PST 1998
  Bug Fix or Nit Pick:
    When sending a job AND the :qq or :use_queuename flag
    is set AND the job arrives without a Q entry THEN
    the name of the queue it was spooled to is used.
    (Noticed by:Cortney Sampson <sampson@physics.utoronto.ca>)

    Missing initialization in src/common/permissions.c
    Discoverer got the 'Gold Star with Flashy Sequins' bug hunting
    award.
    (Found by and Award to: Duncan McEwan <duncan@MCS.VUW.AC.NZ>)

  Lpr -Z options now accumulate, rather than overwrite, if the
    Allow_duplicate_options flag is not set.  This makes life
    easier for the user when specifying multiple -Z options.

  Allowed a LPR to LPD job transfer ending in a 'blank line' to be accepted.
    This is generated by some oddball LPR programs.
    (Reported by:  Patrick Hildenbrand <patrick@emea.ers.ibm.com>)

Release LPRng 3.4.5 Sun Mar 29 18:37:09 PST 1998
  LPF:
    Cleaned up some minor nits with options.
    (Noticed by: Patrick Powell <papowell@lprng.com>)

  LPRng-HOWTO:
    A huge number of corrections from:
    (Tim Mooney mooney@dogbert.cc.ndsu.NoDak.edu)

  Enhancements: max_log_file_size, min_log_file_size

    Sometimes it is desireable to run a log file in order to try
    to find problems.  But if you do not truncate the log file, it
    can grow to enormous lengths.  The max_log_file_size#nnn
    (size in Kbytes, default = 0 or unlimited size)
    printcap/configuration variable will
    cause the LPD server to check for the size of the log file
    on opening it and if larger than max_log_file_size K bytes
    truncate it to min_log_file_size
    (default 0 specifies max_log_file_size/4) Kbytes.  It preserves
    the last part of the file.

    Note that when the truncation operation occurs and there is
    heavy logging activity from multiple processes that the log
    file may get jumbled.  Recommended value of max_log_file_size
    should be pretty large in order to make the truncation activity
    minimal - 10240 (10 Megabytes) is what I have been using with
    pretty reasonable success.

  Enhancements:
    The time of a job error is now logged in the hold file.
    This allows the time of the error to be determined.

  Bug Fixes:
    Modified reporting of subserver processes that have been
    killed off or have core dumped.  This solved a problem with
    a system that would generate a SIGTERM signal.

    UTILS/accounting.pl fixed up. Also, psfilter and hpif now
    working correctly with the filter.
    (Patches, suggestions, and advice by:
      Gordon Haverland <haverlan@agric.gov.ab.ca>)

    The LPD/lpd_jobs code for retrying has been redone to make it
    more robust when printing fails.  The LPRng system will now
    agressively retry sending jobs.  Needless to say,  there are
    magic debugging flags to turn this off for testing purposes.
      (Noticed by:  Jesse Off <joff@cnde.iastate.edu>)

    The bogus 'server starting' and 'server done' messages have
    been removed from the status file.

    Now send a trace/logging message before the job is finally put
    in the spool queue.  Removes disturbing occurrence of 'success'
    messages being sent for a job that has not yet arrived according
    to log messages.

    More informative error messages and logging messages added at
    appropriate points.

Release LPRng 3.4.4

  Bug Fixes:

  termclear.c - tgetent() misdefined.
     Also,  configure now checks for Solaris systems and tries to
     handle their brain damaged colliding definitions in term.h, curses.h,
     terminfo.h and termcap.h files.

  ignore_name_format_errors is now documented.  Actually, it is really
    fix_bad_jobs.
    (Pointed out by:  Bruce S. Marshall  bmarsh@wwnet.com)

  Fixed a minor but annoying problem with hold files and very fast
    system.  Better solution would be to have an indexed database,
    but it is almost more trouble than it is worth to implement.

  Fixed a problem with 'Destination' being a pointer to dynamically
    allocated memory,  which would get deallocated by Set_job_status()
    calling Get_job_status().

  Fixed a problem with control file names not being formatted correctly.
    (Reported by:  John Perkins <john@cs.wisc.edu>)

  Fixed up LPRng-HOWTO,  created new version.

  snprintf() used instead of plp_snprintf()
    (Reported by: lots and lots of folks, including
        "Reinhard Zierke" <zierke@informatik.uni-hamburg.de>)

Release LPRng 3.4.3
  Bug Fixes:
    Serial Port Configuration.  Do_stty not called to set up serial
      ports.  Reported by LOTs and LOTs of folks.
    Fixed the GetMaxServers() code to really find the maximum number
      of processes.
      (Fixes by: Don Badrak <dbadrak@gesg34.geo.census.gov>)
    Memory Leaks From Hell
      Found them.  Found the problem.  Decided that fixing the problem
      was not worth it.  Found an alternative method to the current one
      for starting processes that AVOIDS the memory leaks.

      In the new version of code,  the LPD main() process will start
      subprocesses only when it needs to.  Periodically,  it will run
      down the list of print spools,  starting (forking) a process.

      In the previous version,  it would call the Setup_printer() code
      which would then in turn all the routines which would allocate
      (malloc) memory that would never get deleted.  If there were jobs
      to be printed,  the main() process would then fork and create a
      server process.

      In the current version,  the main() process will create a pipe(),
      and then fork the child process,  which will call the *&I*(&()
      Setup_printer() code,  and then checks for work.  If there is NO
      work,  it exits (exit code 0), and as a side effect, the pipe is closed.
      The parent process will read 0 bytes, and say, 'Ah, No work'.  As
      a side effect,  it also gets the status.  If there is work,  the
      daughter will write a string to the pipe and THEN close the pipe.
      The parent will read the data,  and say 'Ah, work to be done'.

      There are several elegant little side effects of this method.  Firstly,
      the main() process will block until the child decides if there is work
      to be done.  In effect,  this will allows the child to proceed ASAP
      to the decision point.  Secondly, the parent process has a VERY small
      amount of memory allocated,  and does not grow at all large.  This
      helps,  as the children,  when created, have very small memory needs
      and process creation is sped up tremendously.

      I am surprised to find just how much better this is...  I probably
      should have done this before,  but I was trying to avoid process creation
      problems, and ended up with large memory footprints.

      (Proddings, pokings,  help, suggestions, and lots of tracking down by:
          Al Marquardt <almar@uiuc.edu> - who found the cause of the memory
            leak
          Branson Matheson <Branson.Matheson@FergInc.com> - who came up with
            another memory leak

         If you ever want to debug memory leaks,  please look at the
         malloc debugging package by Gary Watson.
              http://www.letters.com/dmalloc/
       )

     lpc move
       In the previous versions,  lpc move only worked if the spool
       queue was active.  This meant that you could not stop a spool queue and then
       move the jobs to a different queue.  Now you can.  However, if you
       redirect a queue, then it must be active for jobs to be redirected.
       C'est la Vie.
       (Reported by:  Gary Cender <gcender@eng.dowjones.com>)

     Some logging numbers were not being reported correctly.  They now should be.
       (Reported by:  Gary Cender <gcender@eng.dowjones.com>)

     The QQ option was not working correctly due to a coding typo.
       (Reported by:  Gary Cender <gcender@eng.dowjones.com>, and others)

     LPR was doing translate_format, which was wrong.
       (Reported by:  Chad Mynhier <mynhier@cs.utk.edu>)

     LPR does not use '-' as a flag to read from STDIN.  Documentation changed
       to reflect this;  easier than fixing LPRng... :-)
       (Reported by: "James P. Dugal" <jpd@usl.edu>)

     LPR now allows LOOOONG options to -Z.
       (Requested by:  George Lindholm <lindholm@cheshire.ucs.ubc.ca>)

     Race condition with job completion and testing for completion once
       again explored.  Now err on the side of 'slow but correct' rather than
       'fast but sloppy'.  Only happens on FAST servers,  and the alternative
       to run LPRng on slow servers was not taken well :-).
       (Reported by: Gary Cender <gcender@eng.dowjones.com>)

     OS/2 sends very odd control file format - now should parse this format correctly.
       (Reported by:   "Patrick Hildenbrand"<patrick@emea.ers.ibm.com>)

Release LPRng 3.4.2
  Bug Fixes:
    Connect_timeout was not used uniformly or documented accurately.
    (Fixes by: Heinz-Ado Arnolds <arnolds@ifns.de>)
    configure was too agressive in checking for -lresolv.  Now includes
     -lresolv only if gethostbyname2 is not found.
     (Problem reported by: Uri Blumenthal <uri@ibm.net>)
    It was observed that under heavy load conditions that some files
      were getting printed twice.  This was due to a race condition.
      The race condition has been eliminated by introducing another
      field into the job control information specifying the subserver
      process id.

Release LPRng 3.4.1
  New Baseline Release - Stable version

  Enhancements:
   The configure script now supports setting the installation directories
    configure --with-lpddir=DIR --with-admindir=DIR
      - sets the install directory for lpd and lpc/checkpc respectively.
   (Patches by:  Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)
   Added a 'retry_etimedout' flag as well to handle connections to devices
    that have a very long connection time due to slow network connections
    over dialup devices.
   The lpq status now will show 'stalled' when 'stalled_time' is non-zero
    and the job is active for more than stalled_time seconds.
    (Suggested by: lots of folks)
   The check_idle=program facility can now be used to check that a printer
    is idle before processing jobs.  This is useful when you have multiple
    server queues. For example:
     lp:sv=lp1,lp2:...
     lp1:check_idle=/prog:...
     lp2:check_idle=/prog:...
    When the lp server starts up,  it will check the lp1 and lp2 queues,
     and will only send jobs to the one whose check_idle program reports
     an idle condition.

  Bug Fixes:
    Updated LPRng-HOWTO.
    Fixed missing permission check checkpc.
    Also (correctly) implemented ${option} expansion in filter commands.
     This now gets expanded to the printcap option value,  as documented.
    (Made by: Patrick Powell <papowell@lprng.com>

Release LPRng 3-3-7

 Ports:
   Solaris 2.6.  Also update README.install for new startup/shutdown script

 New functionality:

   reverse_lpq_format : reverse returned lpq status format when from
      specified host.

    There is a defect in some System V support for RFC1179 printers.
    The lpq facility will send a 'SHORT' status request when a 'LONG'
    is desired,  and vice versa.  This results in the wrong status format
    being returned.

    The reverse_lpq_format=(globhost|ip/mask)+ option allows you to specify
    that when a request is received from a host whose name or address matches
    an entry in the list,  then SHORT/LONG format requests will be reversed.
    When the LPD is acting as an intermediate host,  the reversed request
    will be sent to the next destination on the list.  For example:
      reverse_lpq_format=*.eng.com,130.29.0.0/16
    will select hosts whose FQDN ends in eng.com or in subnet 130.29
    to have reversed lpq formats.

   return_short_status : return limited length status information
   short_status_length : number of lines to return

    Some users have expressed a desire to have the LPD server return
    short (i.e. - limited length) status to the requestor.
    The return_short_status=(globhost|ip/mask)+ option allows you to specify
    that when a request is received from a host whose name or address matches
    an entry in the list,  then only short_status_length (default 3)
    Status: and Printer_status: lines returned.

   lpc redo command:
    this forces a job to be totally reprinted, if it has been held
    in the spool queue.  This command has been added in order to allow
    the reprinting of jobs that have been printed and held in the spool
    queue, i.e. - the save_when_done printcap flag is set.

   routing filter 'priority N' output:
    the routing filter can set the destination, copies, and now the
    priority of jobs.  If the routing filter output is:
      dest t1
      CB
      priority B
      copies 2
      end
    then two copies of the job will be routed to the destination
    with priority B, and the C line in the control file will be
    set to CB.

   safe_chars=nnn  configuration file option.
    By default, LPRng detects and optionally eliminates suspicious characters
    from the control file;  the fix_bad_job option will enable removal.
    The safe_chars=nnn specifies that in addition to the normal safe
    characters, the indicated ones can be used as well. For example,
    save_chars=#" will allow # and " to be used in the control file.

Release LPRng 3-3-6

 New functionality:

  Timeouts: send_job_rw_timeout, send_query_rw_timeout replace send_timeout

    The printcap send_job_rw_timeout and send_query_rw_status options
    now set timeouts on read/write operations when printing or sending
    jobs to a remote host or doing a status or query operation respectively.
    If the value is zero, there is no timeout on the operation.
    These timeout values and the associated read/write operations
    solve a problem when LPQ or LPR tries to attach to a printer or system
    which accepts a connection but then does not reply to the request
    in a reasonable amount of time.  Note that the send_job_rw_timeout
    should be quite large (6000 or 100 minutes) in order to accommodate
    transient problems like paper outages on a printer.
    (Suggested by: Brad Rogers <brad@ast.lmco.com> and
        Alek Komarnitsky <alek@ast.lmco.com>)

  lpc active, lpd, and reread commands
    The lpc active command will try to open a connection to the remote
    server.  This allows non-LPRng remote servers to be polled to see
    if they are active.

    All of the active, lpd, and rereads now take a printer[@host] argument,
    allowing the specified server for the printer to be queried.
    (Deficiency noted by:  James P. Dugal <jpd@usl.edu>)

  stop_on_abort printcap flag (default TRUE)
    If a filter aborts and this flag is TRUE then all further processing
    of the queue stops until restarted by some other action and the job
    will not be removed from the queue.

  max_connect_interval (default 60)
    maximum interval between attempts to send a job to a remote site.

  user_lpc configuration option, SERVICE=U, and lpc command
    There was a request to allow a selected set of lpc commands
    to be performed by users on their individual jobs in a queue.
    This has been accommodated using the following method.

    1. A new user_lpc=cmd,cmd,... printcap operation enables the
       SERVICE=U permissions facility.  The cmd can be:
       hold, release, move, topq, kill, and abort.
    2. When the lpc command is checked for permissions by the LPD
       server,  and the cmd is one of the specified in the user_lpc
       printcap,  rejection is delayed until the point where individual
       jobs are checked for action.  At this point a check for
       SERVICE=U is performed on the permission database.  If,
       at this point the action is rejected OR the default action is
       to reject,  the action will not be performed.
    3. While users can perform a kill or abort operation,  they can
       only do this while their job is active or at the top of the queue.

Release LPRng 3-3-5
  HOWTO and README:
   The HOWTO/LPRng-HOWTO has been extensively editted and extended.
  This will replace the README.* files in the distribution.

  Enhancements:
   configuration/printcap flag: force_localhost
    force_localhost forces client programs (lpq, lpr, lpc, lprm, etc)
    to connect to the server on the local host, as is done on the
    BSD LPR system.

    This option has an effect ONLY if you use the destination
    in the printcap information for the printer.

    If you explicitly specify a printer@host as the destination
    (-Pprinter@host) then the force_localhost flag is ignored.

    The default is force_localhost = TRUE.

    Question: why this flag?

    Answer: the Most Frequently Asked Question in the LPRng mailing
    list is from users asking why lpq/lpr/lprm does not send the
    job to the local server, and why they are sending them directly
    to the remote printer instead of spooling them.  After having
    referenced folks to the documentation multiple times,  I have
    thrown in the towel on this one and have put in this flag.

    Question: what does this change?
    Answer:  If you are running a server on your system,  jobs will be sent
    to the server and then spooled.  You may need more spool queue space.

    If you want to use the "lpr_bounce" option,  you will need to turn
    try_localhost and force_localhost OFF (:try_localhost@:force_localhost@:)
    to get the old behaviour and not have the job run through the filters
    by both LPR and LPD.

    Question: Wouldn't it be easier to ask people to read the documentation?
    Answer: No.
    I gave up asking.  The LPRng behaviour was too different from the BSD LPD
    behaviour and folks who wanted a "rip out and replace" solution were
    too frustrated by the different behaviour.

   User Requested Status Information:
    lpr -mhost%port  now causes LPD to open a UDP (by default)
    connection to port on host and send status updates for the job
    being processed.  The form host%port,TCP  will open a TCP port
    rather than a TCP port.  Users can now use the monitor program
    (or a variant) to have job status reporting done.  This has the
    side effect that mail addresses of the form host%port will
    not get mail sent to them.

   Routing Filters:
     During job reception,  the :routing_filter: option specifies that the
   received job information is to be processed by a routing filter,  which
   supplies additional destination information or modifications.
     STDIN of the filter is attached to the control file (read/write)
   and STDOUT of the filter should be the additional control/routing
   information.  Note that routing filters that need to modify the
   control file can now do so by using FD 0 and making the modifications
   directly to the file.  After processing by the routing filter, the
   control file will be re-read by the lpd server, and checked for correctness.
   See the HOWTO (/HOWTO/LPRng-HOWTO.html) for more information.
     Exit codes for routing filter:
      JSUCC (0) - processing continues;
      JHOLD     - job will be held
      anything else - job will be removed (not accepted for printing)

  socket_linger#secs
     This option/flag has been added to solve a nasty problem
   involving closing network connections and process exit.
     When a process exits, the system will attempt to finish IO
   operations, flushing pending data to the destination.  However,
   It has been observed that when the LPD process which is doing
   the actual printing exits, it will sometimes terminate and the
   last output is lost.
     Experiments have shown that when the SO_LINGER flag is set on these
   connections,  the LPD process will not terminate until the last data
   has been transferred, which is the desired behavior.
     The 'socket_linger#nn' flag can be used to force setting the SO_LINGER
   timeout value.  By default,  this is now set to 10 seconds,  which
   appears to be compatible with most TCP/IP connections.  Note that the
   documentation is very blank on what happens when the connection is still
   "active" but no data is being transferred.
     If you are having problems with network connections and lost data
   at the end of jobs, try using:
       :socket_linger#120
   in the printcap for the printer.

   LPRng executables default to SUID root at installation:
       By default, LPRng executables are now installed SUID root.
     This will reduce the number of problems encountered by folks who
     do not read the README.install instrucutions.
     (Noted by: Patrick Powell <papowell@lprng.com>)

  :remote_support=RMQVC (default)
    R = lpr, M = lprm, Q = lpq, V = verbose lpq, C = lpc : allowed operation
    This option specifies the allowed operations to a remote printer.
    This solves the problem of printer servers 'hanging on lpq', due
    to their inability to handle multiple requests.  Note that the hang
    appears to be permanent - i.e. - the printer locks up.  Thus, you
    should never do a lprm, lpq, or lpc operation to the printer. The
     :remote_support=R: setting will do this.

  :rg=group[,group] - allow clients to use printer only if user
    is a member of one of the specified groups.
    (Requested by: Oved Ben-Aroya <oved@ns.technion.ac.il>)

  Bug Fixes:
   After a LOOOONG study,  the problem with non-LPRng servers terminating
   with 'out of space' error status has been resolved,  and hopefully fixed.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   Order of variables in sorted list was incorrect.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   README.pgp_authentication referenced 'client_auth*' names; should be
    'user_auth*' names.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   The print job transfer (LPD/lpd_rcvjob.c) code has been reviewed,  and
     the underlying method has been modified to accomodate reception of
     multiple jobs in a more consistent manner.
     1. On start of job transmission,  a 'lock file' is created.
     2. Data and control files are placed in 'temporary files' during transfer.
     3. At the end of job transfer,  rename() is used to change temporary
        files to permanent ones.
     4. The routing filter (if any) is invoked.  Note that the data files
        are available for reference during this stage.
     5. The control file is renamed to the final version.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   The plp_waitpid() code has been extensively modified,  together with the
     fdfork() code,  the killchildren() support,  and the Print_abort()
     code.  Hopefully,  this will now solve the problems of processes
     not being terminated and/or zombies accumulating.  This has the
     (desirable!) side effect that child exits will not cause system calls
     to terminate with EINTR status.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   By default, LPRng executables are now installed SUID root.
     This will reduce the number of problems encountered by folks who
   do not read the README.install instrucutions.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   Race condition with Set_control_info fixed.  Now file locking works
     correctly.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   For HP configurations and no GCC,  added a -Aa flag to CFLAGS
     (Suggested by:  Brad Rogers <brad@ast.lmco.com>)

   The logger support was flawed somewhat.  Previously, each process
     would open a socket (connection) to the logger - this would soon
     use up a lot of connections.  Now the LPD server opens a connection
     at initialization,  which is then inherited by the various processes.
     (Found by: Desmond Macauley <desmondm@eng.dowjones.com>)

   By default, LPRng executables are now installed SUID root.
     This will reduce the number of problems encountered by folks who
   do not read the README.install instrucutions.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   The SERVER permissions checking did not handle localhost correctly.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   Passed the PRINTCAP_ENTRY to routing filters and control file filters.
    (Patch by: George Lindholm <lindholm@ucs.ubc.ca>)

   Only LPD now does killpg() otherwise this effects output from the
     lpq, lpc, etc., programs.
     (Noted by: Patrick Powell <papowell@lprng.com>)

   Jobs were being thrown away with Send_try#0
     (Patch by: George Lindholm <lindholm@ucs.ubc.ca>)

Release LPRng 3-3-4
  Enhancements:
    When using routing_filters to cause jobs to be sent to multiple
     destinations,  you might want LPQ to report the status of the
     destinations as well.  The 'destinations=pr1,pr2,pr3' will now
     case LPQ to report the status of destination queues.
      (Work, patches, and slugging by: George Lindholm <lindholm@ucs.ubc.ca>)
    LPR and LPRM duplicate arguments:
      Some users would like LPR's and LPRM's arguments to be 'cumlative', i.e. -
        lpr -a x -a y   would be identical to lpr -a
      The allow_duplicate_args configuration flag will now enable this behaviour.
      Also, by default the class name and the job priority are identical.  The
        break_classname_priority_link flag breaks this link, and the class can be
        specified separately from the priority.  Also, the maximum classname
        size specified by RFC1179 is 32 characters;  the 'classname_length#nnn'
        (default 31) allows a longer classname to be used.
      (Patches supplied by: George Lindholm <lindholm@ucs.ubc.ca>)

  Bug Fixes:
    checkpc -p and -c options were not functioning as documented.
      (Noted by: Christophe Kalt <kalt@research.bell-labs.com>)
    README.bouncequeues indicated that exit status returned by
      the control_filter program was used to control job processing.
      README and common/fixcontrol.c updated to agree.  When control_
      filter exits with: JSUCC (0) - normal processing, JHOLD (37)
      job is held, JREMOVE, job removed, etc.
      (Noted by:  George Lindholm <lindholm@ucs.ubc.ca>)
    Generate_banner did not put banner in correct position.
      (Reported by: Jost Krieger <Jost.Krieger@ruhr-uni-bochum.de>)
    LPD/lpd_rcvjob.c - control file is now written to a temp file and then
      renamed as the control file.  This elminates problems with locks.
      (Suggested by:  George Lindholm <lindholm@ucs.ubc.ca>)

Release LPRng 3-3-3
  Updated the sample lpd.perm, README's to use the 'REMOTEUSER'
   rather than USER in the permissions value.
   (Spotted by:  Chen Shiyuan <csy@hjc.edu.sg>)
  Cleaned up filter and server killing code - added more robust
   exit and abort facilities.  This was done in several places
   in order to try to make sure that processes created for filters would
   be killed off when the server process exited.
  Cleaned up logging and some minor error messages.
  Removed 'intl/po2tbl.sed' and 'po/POTFILES' from distribution.
   (Noted by: George Lindholm <lindholm@ucs.ubc.ca>)

Release LPRng 3-3-2
  Thu Oct  9 20:03:30 PDT 1997
  lpr, lpq,... usage message formats fixed.
    (Patches by: Jan Barte <yann@plato.uni-paderborn.de>)
  Autohold support was accidentally removed from LPD/lpd_rcvjob.c


Release LPRng 3-3-1
  New Baseline Tue Oct  7 18:29:55 PDT 1997
  Comments:
    README.account updated to show how to use psfilter and CTI-hpif
    filters and accounting scripts.
  Bug Fixes:
    Permissions checking patch did not work correctly. Patcher patched
     patch to make patchwork code work correctly.
    (Originator of patch: Simon Wilkinson <sxw@dcs.ed.ac.uk>)

Release LPRng 3-2-12
  Bug Fixes:
  The sample lpd.conf file had ff=\\f which confused folks.  Now it
    has correct syntax.
  The end of job and Print_abort code has been clean up and modified
    so that exit is now fast and brutal.  When you do LPRM you now GET
    LPRM action fast and quick,  and no processes hanging around.
  The code for reporting fatal 'filter errors' has been modified to put
    the termination conditions into the LPQ status report.  This will
    simplify the job of finding out why your job died much easier.
  Jobs that now exceed their maximum number of print attempts are deleted
    by default instead of being retried indefinately.  This can be be
    suppressed by setting retry to 0, as documented.
  The above bugs/changes were the result of a long standing report of
    the LPD server being slow to respond when printing bad jobs.
  (Added by: Patrick Powell <papowell@lprng.com>)

Release LPRng 3-2-11
  Enhancements:
   printcap/configuration 'network_connect_grace#nnn' variable
   is similar to the 'connect_grace' variable,  but pauses for
   the specified time between connections to LPD or other servers.
   Useful when using LPD prototcol to network based printers that
   need some recovery time between jobs.
   (Suggested by: Christian Illinger <illinger@lepsi.in2p3.fr>)
  Bug Fixes:
   all:all=p1,p2,p3 did not check correctly for separators.
    (Reported by: Bertrand Decouty <Bertrand.Decouty@irisa.fr>)
   configure.in - checks for random() defined in stdlib.h
    (Suggested by: Bernhard Rosenkraenzer <root@BOL-SubNet.ml.org>)
   Logging:  the JOBNUMBER is now reported correctly.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)
   LPC move:  the job is deleted from the queue after being moved,
    even if save_when_done is set.
    (Requested by:  Gary Cender <gcender@eng.dowjones.com>)

Release LPRng 3-2-10
  Bug Fixes:
    In cleaning up the routing support in LPD/lpd_jobs.c and
    LPD/lpd_rcv.c,  I cleaned it up so much that only the first
    routed job was printed.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)

Release LPRng 3-2-9
  Bug Fixes:
    Typo in src/common/linksupport.c caused very wierd error messages to be
    printed.
    (Reported by:  lots and lots of people)


Release LPRng 3-2-8
  Bug Fixes:
   snprintf used instead of plp_snprintf()
   (Reported by:  Dirk Wrocklage <dirkw@uni-paderborn.de>
     and Helmut Jarausch <jarausch@igpm.rwth-aachen.de>)
   Max_servers code did not function correctly - there was a logic error
     in the design.  As a result,  it would lock up and refuse incoming
     jobs.
    (Reported by: Jim Stosick <Jim.Stosick@Forsythe.Stanford.EDU>)
   Poll_time:  Under certain very odd conditions,  a spool queue could
    have a job in it and the LPD server would not fork a process to
    serve the queue.  The poll_time (default 6000 seconds) is a timer
    that will scan the print queues for a pending job and no server.
    The previous version had a race condition in it that would
    periodically spawn too many servers.  The new code not only fixes
    this problem,  but also enforces a true idle condition on the
    lpd server.  If there is no activity and no jobs,  then the server
    will not periodically wake up and check the spool queues.
  Force_poll:  Some users have software that places jobs in the
    spool queues,  and want LPRng to periodically poll the queues
    for these jobs.  The 'force_poll' flag has been added to provide
    this functionality.

Release LPRng 3-2-7
  Major Revisions:

  Hold file names and creation:
    When the server creates a job in a job queue,  it also creates
  a hold file along with the data and control file in the spool
  queue directory.  During job processing the hold file is updated
  by various processes.  As a result,  this file must be locked
  and carefully updated.  The implemented method of locking and
  holding locks for jobs was flawed,  resulting in race conditions,
  etc.

    The routines responsible for reading and writing hold files are
  Lock_job_control, Get_job_control and Set_job_control.  These have
  been modified as follows.
  0. A Lock_job_control() routine now generates and locks a control
     file.
  1.  The Get_job_control() routine may now open the job file in a LOCKED
     or UNLOCKED mode. It will open the file UNLOCKED if not passed
     a file descriptor (FD) created by Lock_job_control(),
     reads the file and then closes the file if not locked.
  2.  The Set_job_control() file now updates the hold file as follows.
     a) It creates a temporary file (open, locked).
        This file has the name _fAnnn, while the lock file is
        cfAnnn.
     b) It writes the job file to the temporary file.
     c) It RENAMES the temporary file to the hold file.
     d) If it has been passed a FD created by Lock_job_control()
        it will close the passed FD and return the locked FD;
        the effect is to maintain the lock on the control file.
     e) if not passed an FD, it simply closes the FD, effectively
        releasing the lock.

  This functionality guarantees the following:
   1. While there might be a race condition in time over a particular
      control file,  the Get_job_control() routine will always open
      either a 0 length hold file (i.e. - file is in an initial state)
      or a VALID COMPLETE non-zero length hold file.
   2. Get_job_control() (no lock) will always read correct status information
      or NO status information.
   3. If a Write operation is needed, Set_job_control() does this correctly
     and indivisibly.
   4. If a Read/Modify/Write is needed, Get_job_control() is requested to
     read and lock the file,  and then Set_job_control is used to modify
     the information.

   Hold File Name Format:
     In order to guarantee that jobs placed into the hold file have unique
   job numbers, i.e. - so you can reference them by job number,  the hold
   file name format is now hfAnnn.  Note that this means the host name is
   now not used.  The Find_unique_job_number() routine will attempt to find
   and create a hold file with a unique job number in the queue.

   Jobs Placed In Queues Always Get Unique Job Numbers:
     In the previous version of LPRng,  when a job was placed in a queue
   with an existing job with the same control file name,  the job overwrote
   the existing job.  This had some interesting side effects, mostly concerned
   with duplicate jobs.  If you have the 'Save Job After Printing' flag
   set,  you may run out of job numbers.

   Full_time printcap/lpd.conf flag
     Specifies that you want to have a full year-mo-dy-hr:... time
   format in log and status message.

   Binding to random ports
     The RFC1179 specifies connections must originate from port 721-731;
   most BSD implementations relax this to 512-1023.  There is a problem
   when trying to reuse a port and connecting to the same system;
   TCP/IP requires about a 10 minute timeout on a IP:port/IP:port pair.
   The code that tried to do connections originally tried the ports in
   sequential order, leading to long delays.  Now it will try them in
   RANDOM order, and will try at most 'connect_try' ports at a time
   before admitting failure.

  Bug Fixes:
    Minor nit with lpc commands fussing about RemotePrinter values.
      (Reported and patch by: Martin Pahl <pahl@tnt.uni-hannover.de>)
    File descriptors are lost if the remote system that we are trying to send
    a job to doesn't like the printer name we are trying to use.
      (Reported by: George Lindholm <lindholm@ucs.ubc.ca>)
    Permissions checking for PRINTER=host,@netgroup was done incorrectly.
      checking now done by match_pr().
      (Reported by: Sergio Tessaris <tessaris@ictp.trieste.it>
        and Warren Marts <warren@nmt.edu>)
    Problems with Get_perms() when rereading the permissions database.
      The actual problem was trying to be too tricky and preallocate data
      structures.  When this was done incorrectly,  you had some very odd
      results when rereading the same database.
    LPR: when printing multiple files,  data files were duplicated.
      i.e. - dfA..., dfB..., ..., dfZ..., dfA...
      Fixed LPR/lpr_cpyjobs.c so that now we have dfA... dfZ, dfa..., dfz
      (Reported by: Simon Wilkinson <sxw@dcs.ed.ac.uk>)
    User detected a bug where the "-r" option to LPR (LPRng 3.2.6)
      actually removes files even if the job was not spooled successfully.
      my patch to fix this problem.  Updated LPR man page to reflect the dreaded
      -r (remove after printing) option.
      (Reported and Fixed by: Garrett D'Amore" <garrett@qualcomm.com>)
    Permissions checks for group did not check the group id, just the
      user name.
      (Reported and Fixed by:  Simon Wilkinson <sxw@dcs.ed.ac.uk>)
    Race conditions src/LPD/lpd_jobs.c between printer server
      and worker process caused a null pointer reference.
      (Reported and Fixed by: George Lindholm <lindholm@ucs.ubc.ca>)
    Checkpc did not use correct lockfile format.
      (Reported by: Jan Barte <yann@plato.uni-paderborn.de>)
    When routing a file,  the route Xnnnn information was not used.
      Updated Fix_control to use this information as per documentation.
      (Reported by: Patrick Powell <papowell@lprng.com>)
    Control file not reparsed after 'control_filter' processing.
      It is now reparsed,  and only the new contents are sent
      to the destination.  This includes the data files.  The
      control file filter MUST remove excess data files.
    End of job accounting to a remote server was erroneously expecting
      an 'ACCEPT' reply. Fixed.
      (Reported by: Markus Fleck <fleck@informatik.uni-bonn.de>)

Release LPRng 3-2-6
    README.accounting, lpd.8, printcap.5 man pages - accounting file is
      documented as not being created.
      (Reported by: Christophe Kalt <kalt@research.bell-labs.com>)
    LPRM/LPD did not forward remove commands correctly.
      (Reported by: Paul Zablosky <zablosky@ucs.ubc.ca>)
    Permissions:  PRINTER attribute can now be a netgroup.  This allows
      things like:
       ACCEPT SERVICE=R,P PRINTER=@PRIP_printers REMOTEGROUP=@PRIP_users
       REJECT SERVICE=X,R,P PRINTER=@PRIP_printers
      makes management of printers... easier... I suppose.
      Updated lpd.perms.5 as well.
      (Suggested by: John R Lane <lanejohn@cps.msu.edu>)
    Removed mention of "co" flag (obsolete) from lpd.conf man page.
      (Reported by Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)
    HP/UX version 10.x needs to use termiox IOCTL call to set
      hardware handshaking on.
      (Reported and patches supplied by:
        Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)
    lpc printcap command now only needs STATUS (S) privileges.
       New DEFAULTQ protocol message added.  This allows lpc to request
       the default queue used by LPD.
    fix_bad_job flag now ignores duplicate control lines,  and replaces
       bad characters with blanks in control file.

Release LPRng 3-2-5
    configure:  now checks to see if inet_ntop() is in resolver
      library (-lresolv),  and includes it when doing checks for
      other functions.
    termclear now uses IS_LINUX instead of __linux__
      (Reported and fixed by: Horst <horst.fickenscher@it.erlm.siemens.de>)
    memory leak fix of 3-2-4 interacted with other code in unexpected
      manner - revised memory fix.
      (Reported and fixed by:  Patrick Powell <papowell@lprng.com>)
    LPD/lpd_status.c - status display line length now controlled by
      max_status_line configuration/printcap variable,  which allows
      the maximum line length to be exceeded if desired.  Default is
      still 79.
    src/Makefile.in COMPILATION FLAG: STRICT_RFC1179
      default originate_port value is now 512 - 1022,
      rather than RFC1179's 721 - 731.  compiling with -DSTRICT_RFC1179
      sets the default to 721 - 731.

Release LPRng 3-2-4
    LPD - pursued and found an extremely minor memory leak that
      was exercised only under a very unusual set of conditions.
      (Reported and fixed by:  Patrick Powell <papowell@lprng.com>)
    Batch of patches and errors: Tom Bertelson <tbert@pamd.cig.mot.com>
      include/portable.h - minor changes in SUNOS prototypes
      CHECKPC/checkpc_port.c - better check to see if setproctitle worked
      PAIR() macro has added guards for _PROTO_ problems
      rw_pipe() has a minor portability problem clean up.
    LPQ, LPR, LPRM option checks were done incorrectly.
      (Reported by: Scott Nelson <nelson@canopus.llnl.gov>)
    umask(0177) should really be umask(0077) to allow correct directory
      permissions checking.
      (Reported and fixed by: Guy Geens <Guy.Geens@elis.rug.ac.be>)
    lpd - the lpc reread function sends a signal to the LPD server,
      which then calls 'Read_pc' from a signal handler.  This can cause
      problems.  In addition, there was a memory leak in the Read_pc()
      routine.
      (Reported by: Rainer Schoepf <schoepf@uni-mainz.de>)

Release LPRng 3-2-3
 BUG FIXES:
    src/Makefile(Makefile.in), man/Makefile.in did not do 'make install
      prefix=/xxxx' operations correctly.
      (Reported by: Chris O'Regan <chris@ECE.concordia.CA>)
    Get_remote_hostbyaddr() used host_ent when it was undefine/null.
      (Reported by: Carson Gaspar <carson@lehman.com>)
    Patch for HAVE_SIGLONGJMP did not include common/timeout.c and
      include/portable.h.
      (Reported and fixed by: Guy Geens <Guy.Geens@elis.rug.ac.be>)

Release LPRng 3-2-2
 BUG FIXES:
    Not freeing memory allocated by Expand_value().
    (Reported by: "Todd C. Miller" <Todd.Miller@cs.colorado.edu>)
    Added logging for non-job related operations.
    Added finer time resolution on job changes
      (Requested by: Chao-Wen Young <kiki@eng.dowjones.com>)
    Added LPDEST environment variable for  printer as well as PRINTER
      and NGPRINTER
      (Suggested by: Garrett D'Amore <garrett@qualcomm.com>)
    Moved Print_flush() to Print_abort().
      (Motivated by: Gerhard Schneider <gs@ilfb.tuwien.ac.at>)
    MONITOR/monitor.c had duplicate include references.  This caused some
      portability problems with systems that did not have 'guards' in their
      include files for multiple inclusion.
      (Reported by: John Perkins <john@cs.wisc.edu>)
    lpstat format fixes.
      (Reported and Fixes: Carson Gaspar <carson@lehman.com>)
    common/getqueue() rejects control files with duplicate remove lines -
      this is not a big problem,  so added code to ignore them.
      (Reported and Fixes: Frank Terhaar-Yonkers <fty@cisco.com>)

Release LPRng 3-2-1
    Baseline Release

Release LPRng 3-1-13
    Changed sleep() calls to plp_sleep(), which uses select mechanism,
      to avoid interactions with SIGALRM signal handler in Linux.
    In the waitchild() code,  the signal(SIGCHLD,SIG_IGN) caused
      some systems to automatically perform a 'wait()' on child
      processes.  The SIG_DFL only ignored the signal, and the
      waitpid() would then succeed.  Note that this action is implied
      by the POSIX standard wording for _exit().
    The code for job queue scanning will not report 0 length
      control files as errors until they are older than an hour.
    The LPD/lpq_status() now ignores jobs being transferred,
      and does not report their status.
    LPD/lpd_rcvjob() now allows multiple jobs to be transferred on a single
      connection.  This is a violation of RFC1179 but it is now done.
    Expanded \xx entries in Banner line, so that very strange
      filters that insisted on these characters would get them.
      If a banner line had these characters,  a \n is not appended.
    Bounce queue destinations no longer have to be printer@host,
      they can just be printer.  The default destination is the
      server host.
    CHECKPC/checkpc.c - To_root() interferred with Test_code();
      reordered code.
      (Reported by: Todd Rannow <rannow@msc.edu>)
    common/check_remotehost() - added checks for Is_server, moved some
      tests into LPD/lpd_status.c, LPD/lpd_remove.c
      (Reported by: Damon W Atkins <zdxa21@gascor.vic.gov.au>)
    Solaris 2.4 LPD server insists on sending REQ_START messages -
      and gets peeved when it gets an error.  Now messages are NOOPs.
      (Reported and fix suggested by: Jussi Eloranta <eloranta@voimax.voima.jkl.fi>)
    Read_fd_len_timeout() closed fd on timeout - this was not correct behaviour.
      (Reported by: Todd Rannow <rannow@msc.edu>)
    Clients (LPR, LPQ, LPC) were not expanding printcap %P, %H, etc., entries.
      (Reported by: Damon W Atkins <zdxa21@gascor.vic.gov.au>)

Release LPRng 3-1-12
    Check_remote modifications exposed logic error in various places-
      need checks for both RemotePrinter and RemoteHost, not just
      RemoteHost.

Release LPRng 3-1-11
    Missing check for Is_server in Check_remote() caused clients to
      not connect to LPD server.

Release LPRng 3-1-10
    LPR/lpr_cpyfiles() did not handle multiple copies of stdin
      correctly.
      (Reported and fixed by: Jens Thiel <thielj@uran.informatik.uni-bonn.)
    LPR and clients updated hold files.  Added checks for Is_server in the
      appropriate places.
      (Reported by: Lee Muh Hwa <cceleemh@dolphin.cc.nus.sg>)
    Problem with bad printer name detection.
      (Reported and fixed by: Martin Pahl <pahl@tnt.uni-hannover.de>)
    setstatus() was not sending STATUS information to the logger.
      (Reported by: Chao-Wen Young <kiki@eng.dowjones.com>)
    Bad non-existent printer,  printcap file misconfiguration code.
      (Reported and fixed by: Dirk Nitschke <ms3a512@math.uni-hamburg.de>)
    Documentation and man page editting - minor corrections, missing entries.
      (Comments and patches by: Florian La Roche <florian@knorke.saar.de>)

Release LPRng 3-1-9
    lpq -v format modified so Destination was printed correctly.
    Remove_job() did not remove all the data files or hold files.
    dofork() did not zero Tempfile->pathlen.
    LPR/lpr_cpyfiles() did not preallocate the job file array,
      leading to problems when realloc() was called.
    printcap(5) and lpd.conf(5) man page cleanup.
      (Done by: Florian La Roche <florian@knorke.saar.de>)

Release LPRng 3-1-8
    Print_job() did not use correct queue name.
    Man Pages did not get right version number.
    force_queuename not in printcap(5) man page.
      (Reported by: Guy Geens <guy.geens@elis.rug.ac.be>)
    In LPC, Queue_name is not NULL when getprinter() is called.
      (Reported by: Jussi Eloranta <eloranta@voimax.voima.jkl.fi>)
    The filter environment variable PRINTCAP_ENTRY now holds the
      printcap entry for the printer.  In conflict with some filters
      using PRINTCAP to hold the pathname of the /etc/printcap file.
      (Reported by: Guy Geens <guy.geens@elis.rug.ac.be>)
    waitchild() had an alternate wait3 implementation that turns
      out to be broken on some systems.  Force use of the waitpid()
      version.

Release LPRng 3-1-7
  New Functionality: poll_time configuration variable
    There is a small, but almost impossible to eliminate, race condition
    when a job is put into a busy queue.  If the server process checks to
    see if there is work to be done, and the job is put into the queue
    after that point,  then there is a possiblity that the server may
    exit with a job in the queue.  This can be solved by using semaphores,
    locks, etc., but is almost impossible to do in a portable and efficient
    manner. The 'poll_time#nnn' configuration entry has been added to
    allow the administrator to specify an interval at which the queues
    can be periodically checked for unprinted jobs.
    The default poll_time value is 6000, i.e. - 10 minutes.

  Bug Fixes:
    printcap.5 documents :mi: (spool directory space needed) as number
      but it is a string.  Fixed documentation.
      (Reported by: Jeff Bacon <bacon@twinight.org>)
    Install.txt, Install.ps - lp=host%port misdocumented.
      (Reported by: Jeff Bacon <bacon@twinight.org>)
    printjob.c - check to see if there is a filter; if not, shove
      file directly out.
      (Reported by: Guy Geens <guy@abacus.elis.rug.ac.be>)
    src/Makefile - SUID_ROOT_PERMS= 04755 -oroot should be -o root
      (Reported by: Dave Goldhammer <Dave.Goldhammer@Colorado.EDU>)
    POSIX uses LOGNAME environment variable - check this first, then
      USER for user information.
      (Suggested by: Todd C. Miller <Todd.Miller@cs.colorado.edu>)
    lpc now allows printer@host specification.
      (Reported by: Doug White <dwhite@gdi.uoregon.edu>)
    printer queue loop detection algorithm modified
      The code to detect print queue loops was too agressive, and gave
      false warnings about print queue loops. Now only checks for explicit
      loops.
      (Reported by: Yuji Shinozaki <yuji@cs.duke.edu>)
    Start_all() code did not check for a limit on the number of processes
      that would be started by the server.

Release LPRng 3-1-6
  Bug Fixes:
    The :direct_read: flag now works for bounce queues.  Tested with aps
      filter.  The aps filter distribution of globals/GLOBALS.sh has been
      modified to have defaults for various options that allows even a
      (possibly) misconfigured filter to produce some sort of output
      instead of dying with a strange error message.
    setstatus() was not putting \n on end of lines, but only when used
      on Solaris 4.1.4 with Sun's ACC compiler.  Compiler bug.  Rather
      than fix the compiler,  we (hopefully) modify the code.
      (Reported by: Reinhard Zierke <zierke@informatik.uni-hamburg.de>)
    LPSTAT simulation:
      Progress reporting too coarse.
      lpstat -s too verbose.
      lp now reports 'request id is ....'
      (Reported by: David Livingstone <davidl@scdes.cn.ca>)

Release LPRng 3-1-5

  New Functionality: PCNFSD compatibility
    PCNFSD - Public Domain version,  from Geoff Arnold (Geoff.Arnold@Sun.COM,
      geoff@East.Sun.COM).  Assumes that LPC will return list of
      printers,  indented one space.  (Fixed).
      Added README.pcnfsd as a guideline for users.
    LPRM now says 'dequeueing' (yech!) instead of 'removing' to make it
      consistent with lprm and PCNFSD implementations.
    PCNFSD distribution put into LPRng collection.

  Bug Fixes:
    cleanup() was causing early exits due to use of killpg();
      commands such as lpq |more would not work correctly.
      Fix was to suppress top level process from killing itself.
    autoconf bizzarness - src/Makefile.in now has ${prefix} entries
      to match the INSTALL documentation.  You can now do
      make prefix=xxx and software will be installed in xxx/bin
      Default directories made to conform with existing LPRng ones,
      not Linux/GNU ones.
    LPD/lpd_jobs: when a job is aborted, the return status is
      clobbered.  Now it is not clobbered.


Release LPRng 3-1-4

  New Functionality - :oh: entry does globmatch on FQDN host name.
    The :oh=*val*: entry can now be used to do matching on the
    FQDN host name.  This allows such things as defining classes
    of printers, i.e.:
      lp:oh=*lab1*:lp=pr1@server
      lp:oh=*lab2*:lp=pr2@server
    (Inspired by: Nathan Neulinger <nneul@umr.edu>)

  Bug Fixes:
    Debugging stuff added to Is_printable();  LPR/lpr.c and company had
      the control file generation fixed up so that lpr -K worked correctly
      when taking input from stdin; also when using it with lpr_bounce.
      (Reported by: Andrew Leahy <A.Leahy@st.nepean.uws.edu.au>)
    autoconf Version 2-12 has a bug and was not generating configuration
      files correctly;  fixed this and now the --exec_prefix option
      appears to work correctly.  To regenerate configure from configure.in,
      the following acgeneral.m4 file lines must be changed:
          .... original .....
          test "x$prefix" = xNONE && prefix=$ac_default_prefix
          # Let make expand exec_prefix.
          test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

          .... correct ......
          test "x$prefix" = xNONE && prefix=$ac_default_prefix
          # Let make expand exec_prefix.
          test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
    Permissions checking in Is_printable() was erroneous.
      (Reported by: Dirk Nitschke <ms3a512@math.uni-hamburg.de>)
    Find_non_colliding_job_number() did not check to see if job priority
      was available, and was generating bogus hold file names.  This only
      occurs when data files are sent first.

Release LPRng 3-1-3

  New Functionality - Kerberos authentication uses encryption
     Send encrypted and authenticated information by default.
       (Greateful thanks to: Ken Hornstein <kenh@cmf.nrl.navy.mil>)

  Bug Fixes:
    Fix_str(): missing null pointer check
      (Reported by: Christian Kuehnke" <Christian.Kuehnke@arbi.Informatik.Uni-Oldenburg.DE>)



Release LPRng 3-1-2

  New Functionality - glob matches for printer names:

    At USENIX97,  somebody mentioned that they wanted to have a 'wildcard'
    entry that would allow them to 'trap' all sorts of printers, and then
    do formatting based on the printer name.  I puzzled over this, until
    I realized that the combination of the :qq: (put queue name in job)
    and a wildcard match would do exactly what this person wanted.
    The more I thought about it,  more functionality seemed to be
    provided by this - you could match various arcane printer names
    against patterns, etc.

    Now when a job arrives and the LPD server is searching for the queue
    name, the search is done using a glob match.  Note that you
    cannot have a primary printer name with a GLOB character,  but it
    is allowed to have an alias with one. For example:

        pr1|pr*|all printers which start with pr
            :lp=pr1@host
            :qq
        pr2|*|wildcard match
            :lp=pr2@host
            :qq

  New Functionality - munging control files:

    There is now a 'control_filter' option that will cause the control
    file to be passed through a filter.  This takes place only when a job
    is transferred to a remote printer.  It was intended to be used by
    bounce queues whose destination required extremely whacko formats
    for their control files.  See README.bouncequeues for details.

  New Functionality - generating banner pages for remote printers:
    The :generate_banner: printcap option will now generate a banner
    page for remote print jobs and/or when using LPR and :lpr_bounce:
    is set.  The banner is generated by the banner printer specified
    by :bp: or the default banner printer.  If the :hl: (header or
    banner last) flag is set, it will be the last part of the job printed.

  New Functionality - spreading job numbers to avoid collisions:

    Some users have been encountering job number collisions when using the
    routing facility and making multiple copies.  The "spread_jobs" printcap
    and configuration variable now allows you to spread out job numbers
    by the indicated factor.  The job number is based on the process id;
        jobnumber = processid * spread_jobs;
    Under heavy use,  this value should be set to the expected maximum
    number of jobs copies that will be made.

  Fixes and Extensions:
    fixcontrol.c - badly formatted DEBUG message.
        (Reported by: Reinhard Zierke <zierke@informatik.uni-hamburg.de>)
    configure - cray-unicos is now just unicos in the system targets.
       In addition, HAVE_SYS_SIGLIST botches have been fixed.
    fix_create_dir() segment faulted
        (Reported by: Reinhard Zierke <zierke@informatik.uni-hamburg.de>)
    LINUX has undocumented (and in my opinion broken) gethostbyname()
        and gethostbyaddr() interactions.  The code that does lookup
        now performs extremely picky checks, copies, etc., to avoid
        problems with this.
        (Reported by: just about every LINUX user...)
    Makefile: install was missing a value.
        (Reported by: Doug White <dwhite@gdi.uoregon.edu>)
    :bk: (Backwards compatible) now forces short job names and
        short job numbers as well.
    LPC - lpq command now takes the last printer specified as its default.
        (Suggested by: Jeff Bacon <bacon@twinight.org>)
    IRIX and UNICOS compilation mods.
        (Suggested by: Paul Burry <rpburry@magi.com>)
    Aborted LPR caused 0 length files to be left in spool directory
    Multiple copies and routing interact
        (Andrew Leahy <A.Leahy@st.nepean.uws.edu.au>)
    config.sub now recognizes i686 as a proper machine type.
        (Reported by: Michel Robitaille <robitail@IRO.UMontreal.CA>)

Release LPRng 3-1-1

  New Functionality:

    Support for client to server and server to server authentication.
    See README.authentication and lpd(8) man page, as well as
    README.pgp_authentication.  Currently, pgp is supported for
    client to server and server to server authentication; Kerberos
    is supported for client to server authentication.

    Printcap entries can contain the following:
       %a  - architecture
       %H  - fully qualified domain name of host
       %h  - shost host name
       %P  - printer (when in printcap entry)
       %R  - remote printer (when in printcap entry)
       %M  - remote host (when in printcap entry)
    This is the same as for the configuration information.  Note
    that these keys are marked by %; keys marked with $ such as $P
    are expanded only when used by filters.  Currently only the
    :sd: (spool directory),  :server_user:,  and :remote_user: (for
    authentication) are expanded.

    Support for lp(1) simulation (Solaris SystemV R4) print facilities
    now built in.  This is done by checking the name that the program
    is invoked with:
      lpr invoked as lp - simulates lp operation
      lpq invoked as lpstat - simulates lpstat operation
      lprm invoked as cancel - simulates cancel operation
    Note that this is not full functionality,  but it will provide
    a usable interface for programs that need lp, lpstat, and clean.

    man pages updated and rewritten to reflect latest changes.

    IPV6 awareness is being planned for.  The permissions checking is
    now done assuming that information returned by gethostbyname()
    and/or gethostbyaddr() may be for IPV6.  Host names checking
    is done not only on the cannonical (main) host name, but also
    for aliases;  the IFIP permissions check has been added to allow
    access to the IP address reported by the accept() system call
    that reported a connection.  See README.lpd.perms for details.

    A new printcap flag, :direct_write: now passes a file descriptor
    to print filters.  This is backwards compatible with the old BSD
    filters,  but you lose the ability to monitor the printing
    process.  In addition,  you are stuck with 'send_timeout'
    seconds for printing a job,  which may not be suitable if a job
    hangs up on a printer.

    Makefiles compatible with the BSD make are now provided;  these
    are generated from the basic Makefiles using a simple conversion
    script.  Of course, the Makefiles were redone in order to make this
    feasible...

    LPR now can do filtering if the :lpr_bounce: flag is set.

  LPR Protocol Extensions:

    REQ_SECURE: an authenticated transfer of job and control information.
     See the details in the README.authenticate and lpd.8 man page.

    REQ_VERBOSE: provides a hideously detailed set of information about
     the print queues and their status.  This is of interest to persons
     who are trying to provide tracking for jobs and other information
     and need more than the status provided by the high level LPQ
     dumps.  The LPQ -v format now will generate this.

  LPQ and Status Generation
     LPQ now prints each queue status once.  In addition,  when getting
     status, LPD makes a valiant effort to avoid forking and creating
     processes.  This makes things much more easy on the system load.

  Source Code Reorganization:
    A major source code reorganization was done in order to support
    configuration management tools in a more effective way.

  System configuration and printcap initialization is now done by
    the values in the lpd.conf file,  which can contain printcap
    flags as well as configuration information.  This allows
    defaults to be set in a much simpler manner.

  Beta Testers:
    Pseudo Anonymous, <pseudo@erehwon.org>
    Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>
    Dirk Nitschke <nitschke@math.uni-hamburg.de>
    Paul Burry <rpburry@magi.com>
    Thierry.Besancon@lps.ens.fr (Thierry BESANCON)

  Fixes and Extensions:
    configure and Makefile support for CRAY (by Paul Burry <rpburry@magi.com>)
    using the lpc class facilities now prevents held class jobs from being
      printed.
      (Reported by: Chao-Wen Young <kiki@eng.dowjones.com>)
    gethostbyname() has a possible problem.  Added checks for
      parameters.
      (Reported by: Jens Thiel <thielj@uran.informatik.uni-bonn.de>)
    printcap '@' operator did not set clear entries.
      (Reported by: Park Jae-hyon <jhpark@entropy.kaist.ac.kr>)
    filter error code 'JFAIL' now causes job removal.
      (Reported by: Norman R. McBride <N.R.McBride@city.ac.uk)
    SAMEUSER permission check was not working correctly.
      (Reported by: Carsten Benecke <benecke@informatik.uni-hamburg.de>)
    LPD now checks for the number of servers it has active;  Max_servers_active
      configuration variable sets this.  In addition,  uses the getrlimit()
      to determine real value if available.  This should throttle back
      problems when a lot of LPR connections are being made and the server
      proceeds to die or lose jobs.
    getconnection() now tries to open a connection with different
      originating ports.  This solves a problem with some systems that
      did not like LPRng originating connections from the same reserved
      ports.  Users encountering this difficulty might have to use
      a wider port range;  this can be done now by modifying the printcap
      entry for the printer.
    checkpc now has Is_server set to 1, so it should do the full
      server compatibility checks.
    Queuename not being set correctly.
      (Reported by: Thierry.Besancon <Thierry.Besancon@lps.ens.fr>)
    LPC now calls 'lpq' via a bombproofed system() call
      (Suggested by Paul Burry <rpburry@magi.com>).
    LPR now generates correct job names for more than 26 files.
      (Reported by: Guy Geens <ggeens@elis.rug.ac.be>)

Release LPRng 2-4-3
  New Functionality:
    Printcap Files
      The printcap reading and configuration file reading code
      now supports the following:
      1. you can have multiple :tc=name: references.
      2. printcap entries whose main name starts with a punctuation character
          is not used as a printer.  However,  it can be referenced by
          :tc=: entries.  For example,  the following shows how to
          use this facility.

      @filter:if=/bin/whatever:of=/bin/whatever
      @banner:sh:sb
      @spool:sd=/var/spool/%P
      p1:tc=@filter:tc=@banner:@spool

      In addition,  the following printcap entries have %P (printer),
      %h (short host name), and %H (Fully qualfied domain name of
      host) replaced by the current values before jobs are processed;
      other values are ignored and replaced by which space.  A %% is
      replaced by a single '%'.  The variables which are expanded are
      controlled by the flags value of the src/printcap.c/Pc_var_list[]
      array;  currently the following are expanded:
        :sd=: (spool directory)
    Device Locking:
      This code was originally put in place for systems where you might
      have multiple people trying to use a printing device.  The 'lk'
      flag now controls if you want to lock the IO device.  Default
      is no locking.

  Portability Fixes:
    Quicksort is not a stable sorting algorithm - if two entries are
    identical, then their position can be reversed.  The order of entries
    is important and needs to be preserved when reading information,
    so mergesort() is now used.

    The organization of the include files was causing problems with
    testing packages.  There is now one include file for each major
    functional component.  Global variables are now in a single file,
    and are the same for all packages.  The difference in size of
    the executables was minor.

  Bug Fixes:
    Printcap reading code: now handles forward references correctly.
     (Reported by:
       Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)
    Ruthless purging of metacharacters passed to filters.  This includes
      quotes, backslashes,  and all other even vaugely funny characters.
      (Reported by:Bertrand Decouty-INRIA Rennes-France
        <Bertrand.Decouty@irisa.fr>)

Release LPRng 2-4-2
    Missing REMOTEGROUP check in permissions.c
      (Reported: Michel Robitaille <robitail@IRO.UMontreal.CA>)
    configure.in: Added more robust check for undefined functions
      on various systems,  added checks in source code for various
      variants: termclear.c, gethostinfo.c
      (Reported by: Doug White <dwhite@gdi.uoregon.edu>,
        Sven Rudolph <sr1@inf.tu-dresden.de>)
    LPQ: status line now too long, truncated it to 79 chars.
    LPD: time of day format changed to YY/MM/DD/HH:MM:SS
    LPC: autohold and noautohold command changed to 'holdall'
      and 'noholdall';  LPQ: autohold and holdall status reporting
      added.
    lockfile.c: Added #if !defined(LOCKDEV) code to not do locking
      on serial devices.
      (Reported by: bennett@nomolog.nagoya-u.ac.jp (Bennett))
    Printcap printer names: primary printer names starting with
      punctuation are now treated as simply entries and not valid names.
      This means that they can be referenced as tc=@name, i.e.
        @name:if=/whatever
        prname:tc=@name
    Multiple Server Queues: ss/sv code reworked again - got rid of several
      race conditions,  lost files.
    Routing filters: added code to handle dropped jobs better.

Release LPRng 2-4-1
  minor problems with Makefiles, portability fixes.
   (Reported by: Michel Robitaille <robitail@IRO.UMontreal.CA>)
  malloclist.c error message format wrong.
   (Reported by: Jens Thiel <thielj@uran.informatik.uni-bonn.de>)

Release LPRng 2-3-14
  New Functionality:
    Jobs are now sorted by priority.
      (Reported by: syl@ecmwf.int (Lennart Sorth))
    LPC CLASS option added.  Classes of jobs can now be held and/or
      released.  lpc class printer A,B,C would release jobs with
      classes A,B,C; lpc class printer J=*form1*  would release jobs
      whose job name contained the form1 string.
      (Requested by: garyc@eng.dowjones.com (Gary Cender))
    Printcap and Configuration :send_failure_action:
      when a job fails to be printed or transferred, it is automatically
      retried :rt: (:send_try: or configuration send_try) times. A 0
      :rt: means infinite retries.  It may be desirable under various
      circumstances to have a method of dynmaically deciding if an error
      threshold is exceeded or some other action is needed.  The
      :send_failure_action: printcap and/or configuration variable specifies
      the default action when :rt: is exceeded.  It can have the following
      form:
        1. The string "success", "abort", "retry", "ignore", "hold"
           which will cause the job/spooler to treat as successful,
           abort, retry, ignore, or hold the job respectively.
        2. A filter of the form: |/filtername.  The filter is executed
           with the default set of filter options,  and the number of attempts
           is printed to its standard input.  It can print error messages
           to standard error, which are placed in the spool error log.
           The exit codes JSUCC (0), JFAIL (1 or 32), JABORT (2 or 33),
           and JREMOVE (3 or 34), JIGNORE (5 or 36), etc. will force
           removal as if successful, retry, etc. as for the text form.
    README.nis: new script for creating NIS (YP) databases.
      (Contributed by: Sven Rudolph <sr1@inf.tu-dresden.de>)
    LPF: modified the -T option, added -D (debug level option)
      (Contributed by: Sven Rudolph <sr1@inf.tu-dresden.de>)
    LPD cannot be started from inetd.  This functionality
      puts a very heavy load on the system and trying to make
      it function correctly was very difficult.
    Makefile: PREFIX variable defined, to allow overriding default
      prefix value.
      (Suggested by: Sven Rudolph <sr1@inf.tu-dresden.de>)
  Major Fixes:
    File Locking:
      The code for dealing with file locking and job name collision was not
      sufficient to handle the case where multiple jobs were being submitted
      simultaneously.  The new code uses the hold file for locking jobs,
      in addition to locking the control file.  When a job is submitted via
      LPR or forwarding,  the hold file is created, written with the
      receiving process PID,  and is then released.  When other processes
      try to submit a job,  they will lock the hold file, check for the running
      process, and then try anther job if the process is still delivering
      the job files.  When all of the job files are delivered,  the process
      will then write the hold file with -1, i.e. - a signal that all files
      have been delivered.  If a job is submitted by other means, i.e.-
      copied directly to the spool directory,  there is no guarantee that
      collisions can be avoided.  Note that sometimes hold files will
      be left in the spool queue, but these can be clean up periodically
      by using checkpc for example.
  Bug Fixes and/or Deficiencies:
    Added Hold_all variable that is controlled by LPC command -
      :ah: printcap entry cannot be overridden now.
      (Reported by: garyc@eng.dowjones.com (Gary Cender))
    LPD/lpd_control.c: STOP was killing off server;  now it prevents
      next job from being started.
    common/printjob.c/Fix_string() - missing check for 0 length string.
      (Zygo Blaxell <zblaxell@myrus.com>)
    Printing filter exit codes 1->5 are translated to JFAIL->JABORT
      This makes vintage filters compatible with LPRng.
    Find_key() can return a 0 value under extreme circumstances - 0 check
      added. (Reported by: Ron Roskens <roskens@cs.umn.edu>)
    lpr -l or lpr -b did not get IF filter invoked with -c option.
      (Reported by:Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)
    trailers are not sent to printers; caused by premature close of output.
      (Reported and Fix by: Helmut Jarausch <jarausch@igpm.rwth-aachen.de>)
    permissions checking once again has a problem - if no match is found
      incorrect use of defaults.
      (Reported by: QingLong <qinglong@Bolizm.ihep.su>)
    LPQ: queue status not reported correctly.  Caused by a memory leak,
      and also incorrect buffer length specified to allocation routine.
      (Reported by: Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)

Release LPRng 2-3-13
    Linux has inconsistent ncurses (curses.h) and termlib (termlib.h)
     definitions for tgetent().  Use only one.
      (Reported by Elliot Lee <sopwith@cuc.edu>)
    The 'printed 10% of 1000 bytes" message gets scambled when
      processed by other systems where the % is interpreted as a
      format character by printf.  Changed to 'percent' instead.
      (From: Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)

Release LPRng 2-3-12
    waitchild.c does not enable the SIGCHLD signal.  This was causing
      problems when a child would die during a read/write operation and
      interrupt the read/write operation.
    checkpc - now checks to see if the LPD lockfile directory exists,
      and creates it if necessary.
    getopt.c - strdup() changed.
      (Reported by  Brad Greer <brad@cac.washington.edu>)
    src/Makefile.in - LOCK_DEV_CFLAGS -> LOCK_DEVS_CFLAGS
      (Reported by Klaus Guntermann
        <guntermann@iti.informatik.th-darmstadt.de>)
    LPD, lpr -p and :pr: filtering.  Documentation claims that LPD will
      filter 'p' format jobs through :pr: filter and :if: filter.  It was
      not doing it,  and now does.  However, when using a bounce queue,
      it will not filter :pr: formats unless a :pf: filter is present.
      (Reported by Scott Sutherland <scott@math.sunysb.edu>)
    :translate_format: printcap variable, and functionality added for
      bounce queues.  A bounce queue can now also modify the job file format
      using the :translate_format: printcap entry. For example,
      :translate_format=mfpl: would change m to f and p to l format
      job files.

Release LPRng 2-3-11
    MAJOR ADDITIONAL FUNCTIONALITY:
    Logger: filter error output is now written to the logger as well as
      status information.

    lpr -p and LPD: the pr filter support was not updated.  It now invokes the
      traditional 'pr' program correctly.
      (Reported by: K.D. Meyer" <meyer@uni-trier.de)
    LPD/lpd_control.c - reporting duplicate status line information.
      (Carl Hilton <chilton@dns2.sac.usace.army.mil>)
    LPR: exits with a nonzero error when 0 length job or invalid queue.
      (Paul Haldane)
    lpbanner.1 and lpraccnt.1 man pages created.
      (Carl Hilton <chilton@dns2.sac.usace.army.mil>)
    lpq -Pall - sendstatus() returned wrong status.

Release LPRng 2-3-10
    MAJOR ADDITIONAL FUNCTIONALITY:
    routing to multiple destinations, multiple copies, via a bounce queue
        A bounce queue can now route jobs to multiple destinations
        and/or make multiple copies of a job.  This action is controlled
        by the printcap/configuration variable router=filter.
        See README.routing and the LPD.8 manual page for details.

    Identifiers:
        The 'A' control file line is now used to store a 'unique' job
            identifier.  This follows a job through the system, and is
            used to identify a job.  It can also be used in LPRM and
            LPC messages.
        The :use_identifier: printcap and configuration variable controls
        the addition of this information to the control file.
    Job ID Wildcards:
        LPRM, LPC now take wildcard entries as well use job numbers and
        user IDs for jobs. (Updated LPRM, LPC man pages).
    Logger:
        Added code to record the actions of jobs passing through the
        system.  SetStatus messages now sent to a logger process as
        well as recorded in a status file. Added:
        printcap/configuration:
            logger_destination = host[%port][,(TCP|UDP)]
                host%port is destination host%port combination.
        configuration:
            default_logger_port = 560  - default port for logging
            default_logger_protocol = UPD  - default protocol for logging

    lpd_rcvjob.c - error message has a missing '%s' entry.
        (Brad Greer <brad@cac.washington.edu>)
    Link_read() in link_support.c - minor error - zero length read
      reported as error, not EOF condition.
    lpd: multiple copies (lpr -K option) were causing malformed job control
      files to be generated by LPD when it checked them.  Off by one problem
      with pointers fixed.
      (Reported by: Andrew Leahy <A.Leahy@st.nepean.uws.edu.au>,
        details of problem by Dirk Wrocklage <dirkw@uni-paderborn.de>)
    cleanup() - exited with erroneous error code when NOT sent a signal.
      (Reported by Ed Santiago <esm@lanl.gov>
        and Sven Rudolph <sr1@os.inf.tu-dresden.de>)
    HOST and REMOTEHOST permissions now can be netgroups, i.e. -
      HOST=@netgroup or REMOTEHOST=@netgroup will check to see
      if a host in in the netgroup.
    permissions.c - Mods by Geoff Ballinger <geoff@chemeng.ed.ac.uk>
      These modifications fixed a problem with checking for user
      permissions,  and now the permissions 'user' or 'remoteuser'
      is checked according to documentation.
    REMOTEUSER, REMOTEGROUP added to permissions checking.  Permissions
      checking now done in much more rigorous way.
    LPD/lpd_rcvjob.c - fixed up hold file removal on bad job submission.
    Setup_waitchild() - moved to Initialize(), done for all programs


Release LPRng 2-3-9
    killchild.c - minor bug on cleanup.  If cleanup called with 0
      argument, never killed off children.  Under very rare circumstances,
      this resulted in a OF filter process hanging up,  and never exiting.
    LPR: the -s option is now silently ignored.
      (Jon E. Ferguson" <jon@media.mit.edu>)
    ULTRIX has a sys/syslog.h and a syslog.h file, need to use sys/syslog.h
      (Per Foreby <perf@efd.lth.se>)
    Accounting Filters: the :as: (accounting start) filter returning JREMOVE
      did not cause the job to be removed. Fixed.
      (Reported by Panos Dimakopoulos <dimakop@cti.gr>)

Release LPRng 2-3-8
    lpr_makejob.c - not handling -w and -0 (font options) correctly.
      (Reported by Jens Thiel <thielj@athene.informatik.uni-bonn.de>)
    Comments in sendjob.c updated to reflect reality.
      (George Lindholm <lindholm@ucs.ubc.ca>)

Release LPRng 2-3-7
    lpd.conf default file - updated example configuration values
    Documentation miswordings, downright errors, and missing information
      corrections and comments added.
      (Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)
    struct fd_set declarations changed to fd_set to make it compatible
      with POSIX.
      (Reported by Alan Shutko <ats@shep1.wustl.edu>)
    use_shorthost flag not working - fixed.
      (Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)
    setup_filter.c - %h in an option string is now expanded to the short
      form of the host name.
    ROOT perms for filters - added the ROOT_PERMS_TO_FILTER_SECURITY_LOOPHOLE
      definition to the src/Makefile, modified common/setup_filter.c.
      Added comments to man/lpd.8. Comments by Patrick Powell, mods by
      (Jens Thiel <thielj@uran.informatik.uni-bonn.de>)

Release LPRng 2-3-6
    LPR/lpd_rcvjob.c - snprint() replaced by plp_snprintf()
    src/common/defaults.c - erroneous LD_LIBRARY_PATH= and PATH= values in
      configuration variables.
      (Reported by Jens Thiel <thielj@athene.informatik.uni-bonn.de>)

 LPRng 2-3-5
    printcap.c - when lpd-perms array gets longer than 40kB or so,
      lpd crashes with an segmentation fault when it's getting started.
      fixed by: Dirk Wrocklage <dirkw@uni-paderborn.de>
    permissions.c, globmatch.c - updated error reporting, and added
      check for user's default group when checking GROUP permissions.
      (Stefan Monnier" <stefan.monnier@lia.di.epfl.ch> and
      Ron Roskens <roskens@cs.umn.edu>) Also, changed strcmp to strcasecmp
      to make comparisons case insensitive.
    LPD/lpd_control.c - modified error message to better indicate failure.

    long job numbers - lpd_rcvjobs.c, cleantext.c, lpr_makejob.c, printcap.c
      added the capability to have long (6 digit) job numbers.  This is done
      by reformatting the job control file and the job file names.
      printcap :longnumber: and configuration longnumber=yes enables this.
      Note that :bk: (Backwards compatibility) overrides long numbers.
      If a queue is marked :bk: then it will attempt to shorten long numbers
      to produce a short number file.  This can be used with a bounce queue
      to produce files compatible with the older vintage systems.
      As a side effect, tightened up format checking of unlink entries,
      and other issues reported by the following folks.
      (Lennart.Sorth@ecmwf.int, Desmond Macauley <desmondm@eng.dowjones.com>)

    lprm - fixed the removal algorithm so that multiple tags select multiple
      jobs.  i.e. - lprm 1 2 3 removes jobs with numbers 1, 2, and 3.
      If you do lprm user, all jobs with the tag 'user' are deleted.
      This allows much easier job purging,  which is usually why you
      are using lprm...

    use_info_cache flag - printcap.c(Free_pc()) routine brutally wipes
      out all data now.  This will either force the reread or crash the
      process.
      (reported by Dirk Wrocklage <dirkw@uni-paderborn.de>)

    configuration variables: added default_format, default_priority
      to configuration as well as printcap variables. lpd.conf.5 and
      printcap.5 man pages have been updated.  Apparently they were never
      documented in man pages.
      (reported by Stefan Monnier <stefan.monnier@lia.di.epfl.ch>)

    common/sendjob.c:  error reporting for DATAFILE was incorrect.
      (reported Brad Greer <brad@cac.washington.edu>)

    :send_data_first: printcap and configuration variable added.
      causes data files to be sent to the destination first, before
      control files.  (Supports horrible spoolers that violates RFC1179)
      (suggested Brad Greer <brad@cac.washington.edu>)

    :connect_grace#nn: printcap and configuration variable added.
      Klaus Steingerger reports that some printers require a grace
      period between connection attempts.  This variable provides
      a suitable delay.  Also, the Clear_timeout() routine now
      restores the ORIGINAL signal handler.  This means you can
      only have one timeout pending at a time - which makes sense
      in this implementation.
      (reported and mods by Klaus Steinberger
       <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)

    globmatch.c - a bug with checking for upper and lower case chars.
      (reported by Per Foreby <perf@efd.lth.se>)

Release LPRng 2-3-4
    typos in the documentation - fixed

Release LPRng 2-3-3
    getcfng.c - "use_info_cache" entry out of order.
     (Alan F Lundin <aflundi@sandia.gov>)

Release LPRng 2-3-3
    LPR and :qq: printcap entry,  use_queuename configuration information
    Added 'use_queuename = no' to the common/default.c file - the
    use_queuename will force control files to have the 'Qqueuename' entry
    placed into them.  The :bk: (backwards compatible) entry can be used
    to override this when sending to non-LPRng systems.  When receiving
    a job and use_queuename is TRUE,  then LPD will add the name of the
    spool queue to the control file.

Release LPRng 2-3-2
    common/defaults.c - removed :xt: from the printcap defaults.
    common/getcnfinfo.c - added "true", "all", "false" keywords for flags.
    common/termclear.c - for LINUX, added include <termios.h>
      (Avery Earle <ae@play.psych.mun.ca>)

Release LPRng 2-3-1
    printcap.5 :xt: entry updated
    bk, qq, and bounce queue filter interaction: printjob.c modified to
        add Queuename information for filters if :qq: option or Q entry
        in job file.

Release LPRng 2-3-0
    Minor rewording on printcap.5 man page.
    common/termclear.c - defined(solaris) changed to defined(SOLARIS)
        (Andrew Richards <physajr@phys.canterbury.ac.nz>)
    common/printcap.c, CHECKPC/checkpc.c - subtle bug when reading
        printcap information from a filter AND the 'oh=host' specified
        AND the host is not the current host.  Fixed.  In addition,
        checkpc will not create queue entries for queues not used/defined
        on the current host.
        (Dirk Wrocklage <dirkw@uni-paderborn.de>)

Release LPRng 2-2-9
    printcap.c - malformatted printcap entries ending with a \
    at the end of the file are now accepted.

Release LPRng 2-2-8
    LPR now uses a reasonable size buffer when copying files.

Release LPRng 2-2-7
    lpq:  back to the previous format!
      lpq -s - does the very short format
      lpq    - prints short form of detailed information
      lpq -llll... - each l doubles status information
    lpq.1 - man page updated.
    printcap, lpd.conf: send_failure_action - added a 'hold'
      keyword that will hold the job on error rather than deleting it.
      updated printcap.5, lpd.conf.5 man pages
    lpd_jobs.c - added checks for filter non-zero status exit.
    configure.in - printf("%s",sys_siglist[0]) added
      (<harlan.stenn@pfcs.com>)

Release LPRng 2-2-7
    lpq:  by default, a very very short format-  pr@host:(status stuff) NN jobs
        lpq -l  -  short, verbose format
        lpq -l -l or lpq -ll - longer format
    lprm: was not removing all jobs when 'lprm all' specified.
    lpr.1 man page: priority of jobs is A (highest) to Z (lowest)

Release LPRng 2-2-6
    lpr: -K option did not have ':' in getopt options string.
      (Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)
    lpr: -# has been readded, in spite of my better judgement, to be
        compatible with antique LPR systems.
    lpd: 'sending job to...' message error
      (Dwaine C. Gonyier <virtual@panthra.catt.ncsu.edu>)
    printcap.c, getcnfginfo.c - ordering of parameters not alphabetical.
      (Ron Roskens <roskens@cs.umn.edu>)
    lpr, configuration - check_for_nonprintable code got mushed,  fixed
      now; the :xt: (check text) printcap flag added as well. man page fixed.
      (Ole Benner <olb@kom.auc.dk>)
    configure.in- library check fixed, added additional library check
      (Harlan.Stenn@pfcs.com)
    lpc - the 'lpc lpd xx' operation set the current printer to xx. Fixed.
      (Jos Backus <jos@oce.nl>)

Release LPRng 2-2-5
    ** changed the bqfilter flag to bq=destination_queue
        This now forces all input to be passed through the filter.
        Changes in the bq filter information as well.
    Bounce_filter: removes temporary bounce queue file on exit unless
        debugging is high level.  bounce queue file name is bfAnnnHost,
        i.e.- has same format as a job file.  This makes job related
        processing easier to debug.
    lpc - Updated queue status display
      lpc status now shows autohold status
      lpc noautohold now restarts printer on 'NOAUTOHOLD' command
    lprm with no options removes first removable job in queue
      This is compatible with BSD lprm functionality
    configure - GCC version checks moved to start of configuration
        added checks for sys/utsname.h, utsname.h
    common/gethostinfo.c - uses sys/utsname.h
        configure.in has check added for utsname.h
    lpd - printjob now checks for exit status of filters - should
        terminate now if filter has bad exit status.
        (Note: this may not be bombproof in all situations.)
    printcap and configuration - connect_retry was defined as connect_try
        documentation fixed as well.
    CHECKPC- checkpc -r -A nD now removes all job related files older than
          n Days.  This can be put into crontab and run periodically.
    printcap :ah: (autohold) now operational.  Note that LPC will
        override printcap default.  lpc status now indicates if autohold
        is on.

Release LPRng 2-2-4
    :bk: (backwards compatible) flag now causes removal of non-BSD compatible
        control file entries as well as modifying the order.
    :qq: (Queuename in control file) flag is now  overridden by :bk: flag.
        This will now generate Berkeley compatible job files.
    lpr - improved 'connnection failed' message format.
    accounting_server and accounting_check added for accounting.
        printcap.5, README.accounting,  and other documentation updated.

Release LPRng 2-2-3
    Once more the portability/bugfix Gods need yet another sacrifice.
        BSDI V2.1 setreuid() returns erroneous error codes - setuid.c
        fixed yet again...  I suspect other BSD derivatives to have same
        problem.  Sigh...
    cleanup() now unblocks signals before exiting.
    Print_open() - better status messages on open failure.

Release LPRng 2-2-2
    TESTSUPPORT: removed lpf generation
    Perms_check(): missing ntohl(HostIP), needed for host order of addresses.
    Lock_fd(): - saves errno error codes and returns them correctly
    Prefix_line in malloclist(): - copy now done in correct order
        fixes print queue bug.
    Accounting Filters:
        1. the filter command is not passed as an argument to the accounting
           filter.  This solves some problems with shell script filters,
           as the last filter command would have the form:
             filter -H... -a|filter |filter
        2. Accounting information now logged at start and end of job.
    GROUP Permissions: permissions.c now checks to see if a specified
        group exists first, using getgrnam(), then tries wildcard
        search next.
    Permissions: IP=host/netmask format updated- allow /n to be n bit mask
        i.e. - 130.191.163.12/16 -> 130.191.163.12/255.255.0.0

Release LPRng 2-2-1
    LPF filter: added source code to the LPRng main distribution.
        This provides a passthrough filter for most applications.
    README.printcap: updated to reflect use of lpf filter and
        banner printing
    LPRM/LPD: lpd restarts printing if the active job is removed.
    LPQ: more robust handling of bad printcap entries
    LPD: attempt to solve problems of filters which print to
        serial devices hanging because the device has pending
        output, has been sent a ^Q to stop output,  and has not
        received a ^S to restart.  Uses tcflush() to flush serial devices.
    LPR: added a 'use_shorthost' configuration and printcap variable
        to force the use of short host names for print job control and data
        files.  The code was present in LPR,  but not enabled.
        Update lpd.conf.5 and printcap.5 man pages.
    Debugging Flags: added keyword and flag capability.  For example:
        -Dthis,that@  can be used to set the 'this' flag and clear the
        that flag.  see common/parsedebug.c for details.
    NGPRINTER environment variable added. Used to override PRINTER environment
        variable.  Allows one format for PLP/LPR/Solaris, one for LPRng.
        (marty leisner@sdsp.mc.xerox.com)
    LPC: command of form 'status printer@host' was not formatted correctly.
        (Jarrod Douglas <jarrod@cs.curtin.edu.au>)
    man/printcat.5 - added a functional listing as well as alphabetical.
        (Sherwood Botsford <sherwood@space.ualberta.ca>)
    LPD, LPQ: added termination error messages to status output.
        Details for job failure now available.
    printcap :qq: and lpr -Q option now fully operational.
         lpr -Q or :qq: printcap field sets Qqueuename in job file;
         lpd bounce queue will add Qqueuename line to the control file.

Release LPRng 2-2-0
    Updated README files.
        README.1st     - overview
        README.install - much more complete
        README.lpd.conf - explains lpd.conf
        README.lpd.perms - lpd permissions structure listed
    man/lpr.1 - missing -k information added.
    man/lprm.1 - fixed typos
    man/lpd.perms.5 - lpd.conf documented
    DOC/Tutorial - added additional information
    DOC/Install - extended to include more testing and installation
        details.
    strdup() changed to plp_strdup() to avoid problems with C library.
    configure.in - check for sys_siglist[] improved.
    src/commmon/decodestatus.c - fixed problem with Solaris 2.5
        and sys_siglist[]
    Makefile - added default target to install default lpd.conf and
        lpd.perms files;  prototype files added as well.
    man/lpd.conf.5 man page added
    src/common/permission.c: added a SERVER key, to allow restriction
        to users on the server.
    checkpc - truncation now done on log, accounting, and status files.
    LP_SIMULATION - SVR4 simulation with lp.sh and lpstat.pl scripts

Release LPRng 2-1-3
    waitchild.c - race condition with malloc() in the SIGCHLD handler
      would result in rare, very very rare problems.  Data structures
      are now pre-allocated.
    LPD/lpd_jobs.c - WIFSTOPPED and WIFSIGNAL checks done improperly.
      Shows up in OSF1 based systems.  The test is now done correctly.
    AIX portability - added sys/select.h to include list
    LPQ status display modified to be consistent-
      Filter status:  -> Filter_status:
      Now all the comment and information lines have a : at the end
      of the first field.  This makes parsing by perl/awk, etc. simple
      Note that the Rank Owner ... line still does not have a colon
    joost@cadlab.de - minor fixes for Apollo DN4500 and portability
      TESTSUPPORT/Makefile.in, as well as minor fixes in portable.h


Release LPRng 2-1-2
    STATVFS typeo corrected in in configure.in, portable.h, freespace.c
      (curt@ltpmail.gsfc.nasa.gov (Curt Tilmes))
    Missing VARARGS declaration for setstatus() in lp.h
      (Marc Baudoin <Marc.Baudoin@hsc.fr.net>)
    Makefile.in (in general) - fixed realclean mostlyclean targets
      (Paul Eggert <eggert@twinsun.com>)
    setproctitle() - check made in configure, and if not present
      the proctitle.c code is used. (Marc Baudoin <Marc.Baudoin@hsc.fr.net>)
    Makefiles - realclean and distclean targets did not remove Makefile
        (Paul Eggert <eggert@twinsun.com>)
    Missing read permissions on various files
        (Paul Eggert <eggert@twinsun.com>)
    configure.in (CFLAGS): Use a more accurate test to decide
      whether we are using GCC version 2.4.5 or earlier.  The old
      test didn't handle GCC snapshots correctly.
      (Paul Eggert <eggert@twinsun.com>)


Release LPRng 2-1-1
    CHECKPC- added test for the printcap 'ps' - printer status file
      - fixed up test for printer device, now ignores remote and filters
      - added 'checkpc -s' option to not create/check printer status file
    common/sendjob.c - Bounce Queue Filters are only invoked by the server;
        added a check for Interactive and printcap :bqfilter: flag BOTH
        set before invoking filter.  This prevents clients from invoking
        filters.

Release LPRng 2-1-0
    Added 'rs' (time between spool queue rescans) printcap entry
    Added 'oh' (option for host) printcap entry
    Added check for NULL printcap pointers.  Printcap files entirely
        consisting of comments and empty lines are now handled
        correctly.
    Added ntohl() and htonl() calls to fix IP addresses for permissions
        checking.  This showed up on X86 systems.

Release LPRng 2-0-9
    Patch to make sigsetjmp() work correctly on Solaris.  Sigh...

Release LPRng 2-0-8
    Solaris 2.5 requires sigsetjmp() and siglongjmp() for alarms and
        timeouts to work reliably.  Note that GCC now does not put out
        warnings about 'variables may not be restored after longjmp'
        C'est la vie, c`est le guerre...
    Documented getting permission database with a filters, allowing
        dynamic checking of a database.


Release LPRng 2-0-7
    Fixed up the setuid() code yet again - portablility issues on
        BSDI and FreeBSD - need to do a setuid() operation first.

Release LPRng 2-0-6
    Removed default non-blocking open() operations;
        added printcap 'nb' (Nonblocking_open) variable to allow
        nonblocking open for specific devices
    Updated man pages and DOC files to reflect new open() capabilities

Release LPRng 2-0-5
    getuserinfo() was not using the original RUID value.
    Fixed device locking again,  this time to do a fallback to
        fcntl() based locking if TIOCEXCL is not functioning
    Removed MFLAGS from Makefiles, also put in cleaner test for GNU Make
    The sleep() implementation on linux is defective; replaced
        by a plp_sleep() using select().

Release LPRng 2-0-4
    src/cleantext.c - Check_format() was too strict in checking
        hostnames - now allow '-' as well as . and _ in name.
    configure.in - SGI IRIX configuration needs SVR4 definition forced.
    added more specifics for solaris

Release LPRng 2-0-3
    - mostly portability fixes
    man/Makefile.in - removed $(FILES) targets
        did updates in a 'sane' manner
    Fixed missing declarations of functions for fussy compilers.
    Fixed CHECKPC/checkpc_port.c - SunOS4.1.4 has two versions of
        stty - /bin/stty and /usr/5bin/stty
        forced use of /bin/stty
    configure.in - added gcc version check,  fixed up CFLAGS
    HPUX portability kludges -
        1. O_NDELAY and O_NONBLOCK interact - removed one of them
        2. Need to use fcntl() after open to fix the non-blocking
            read operation.
    device locking now works on Solaris 5.4
    checkpc- added a couple of sanity check functions for internal
        tables - Check_pc_list() and Check_config_list()
        discovered a couple of entries in wrong order (bp was one)
        that prevented use of banner printing.

Release LPRng 2-0-2
    Modified configure to use config.guess; fixed config.guess as well.
        - config.guess did not recognized BSDI systems,  and exited
            with an error.
    Fixed configure.in to force library order if necessary.
    Ripped out several SVR4 dependencies; src/killchild.c
    Filters + Bounce Queues - added filtering capability
     printcap variables - bqfilter (flag)
     If a bounce queue (one that sends files to a remote printer/host)
     has filters speicified, and the :pqfilter: printcap flag is set,
     the data files will be passed through a filter,  if there is a
     filter for that format.  Updated printcap.5, lpd.8 documentation,
     as well as DOC/Intro.

Release LPRng 2-0-1
    configure.in -
        WARNING ** gcc version 2.4.5 and below
        The -O option produces erroneous code several places.
        configure.in has been modified to remove the -O option.
    configure.in - added explicit check for elf.h - now defines
        SVR4 if the file is present (see autoconf documentation
        for test).  Compatibilty check.  Updated CFLAGS with define
        for HPUX and uses the @CFLAGS@ edit in Makefiles.  This
        solves a problem when configure sets CFLAGS and the
        default GNU Make .o.c rule set needs to be used.
    LPRM: If a user has LPC CONTROL permissions, he can now remove
        jobs from a queue.
    Makefile.in, Makefile - Added various GNU compatible targets
        such as clean, dist, reallyclean, etc.
    Fixed the man/Makefile to better update the man pages when
        installing them.
    checkpc -T line : fixed up the STTY reporting to be more robust
        should work with SVR4 better.
    LPR: added locale initialization; printable checks now use
        8 bit characters if the locale has been enabled.
    O_NONBLOCK|O_NBLOCK - these both must be set on a SVR4 system to
        do a non-blocking open.  This might be considered a documentation
        feature in some circles.
    FreeBSD defines: various files have had #ifdefs for FreeBSD added.
    Accounting: modified the default accounting string to add the
        control file name;  allowed the accounting filter to exit
        with error status and write an error message.

Release LPRng 2-0-0
    Baseline Release Version

Release LPRng 1-2-6
    PERMISSIONS: permissions checking was defective- correct values now
     used.
    LPC: usage message updated
    Error reporting: connection permission errors reported to connecting
     system now.
    LPR: now reports server error msgs to user on STDERR.

Release LPRng 1-2-5
    PERMISSIONS: lpc operations split, 'C' are control, 'S' are status
     this allows 'lpc status' command to be used by non-privileged users
     Updated documentation to reflect this change as well.
    Updated lpq, lpc, lprm -V option to be less verbose
     by default;  -V -V will show copyright information.
     ("Marty Leisner" <leisner@sdsp.mc.xerox.com>)
    Control file format: allowed first 'N' line to appear before
     data file information, and stuck in middle of control file.
     This makes it compatible with other LPR implementations.  Sigh.
    If a filter is not available,  this is logged in status and the
     job is discarded.  This prevents a job with bad format information
     locking up the printer queue.
    Filter program lookup in printcap entry has been fixed to be a little
     more effective.
    Fixed checkpc and setproctitle() to work with FreeBSD
     (Richard Letts  R.J.Letts@salford.ac.uk University of Salford)

Release LPRng 1-2-4
    Harlan Stenn <Harlan.Stenn@pfcs.com>
    termclear.c - there is an interesting problem with termcap.h, curses.h,
      terminfo.h.  On some systems you do not want to include curses.h,
      but not terminfo.h and termcap.h.  I recommend putting guards in the
      terminfo.h include file so you can include it multiple times without
      redefinition problems.
    curt@ltpmail.gsfc.nasa.gov (Curt Tilmes)
      - removed O_NDELAY from various open statements
    Makefile.in - removed ${SRC}/src, etc. to allow compilation
      in separate directories.

Release LPRng 1-2-3
    Fixed lprm -a flag;  documentation error as well
    common/jobcontrol.c - erroneous error field update
    miscellaneous errors reported by users.
    SVR4 - added sys/systeminfo.h, sysinfo() call replace gethostinfo()
    printcap - added 'qq' (save queue name in job file)

Release LPRng 1-2-2
    This sounds ridiculous,  but there is yet ANOTHER problem with
    implementing portable file locking.  It turns out that some systems
    allow file locking only if the files are opened R/W, no APPEND.
    This is only a problem in pr_support.c;  the permutations and
    combinations of files, devices, etc., are too much to deal with
    algorithmically.  An new printcap flag 'lk' (lock LP device) is
    introduced to handle this.  By default, no file or device locking
    is done.

Release LPRng 1-2-1
    Martin Forssen: maf@dtek.chalmers.se or maf@math.chalmers.se
     - fixed an erroneous test in checkremote.c - missing data
     initialization in LPD/lpd_jobs.c, LPD/lpd_status.c
     - common/getqueue.c off by one error - LPD/lpd_remove.c - cfpp
     uninitialized in Get_queue_remove()
    hagberg@mail.med.cornell.edu (Eric Hagberg) A/UX portability
     fixes in portable.h Fixed lpr, lprm MAN pages;  fixed usage
    messages.  Added CONTROL permission checking for LPRM operation;
    i.e. - if you have CONTROL permission you also can remove files.

Release LPRng 1-2-0
    Documentation - DOC/Intro and DOC/Install
    Filters: CTI-ifhp-1.1.1 lp-pipe-1.0.0  lp-support-1.0.0 psfilter-1.0.2
    Fixed a minor bug in LPD/lpd.c - geteuid() missing


Release LPRng 1-1-2

    Documentation (Introduction, and Installation) added
    psfilter-1.0.1 added to FILTERS
    Added test for signal.h to configure.in.
    reported by Martin Forssen <maf@math.chalmers.se>
      fixed missing bounds check in common/printcap.c,  put install-sh in
      directories needed (autoconf does not fix up $(INSTALL) correctly)
      lookup loop for remote hosts in common/checkremote.c
      Link_listened(void) missing in include/lp.h

Release LPRng 1-1-1

    Added lp,lpsched, lp-pipes support
    Fixed a bug in the job renumbering code in lpd_rcvjob.c; always started
    with 0, instead of next job in sequence.
    Fixed a bug in lpd_rcvjob.c, additional 0 ACKS being sent.
    Fixed a bug with the filter options;  added $0, $-, $'
    Fixed the default filter parameter list - accounting file at end

Release LPRng 1-1-0

    Cleaned up all sorts of minor problems with duplicate variables
        being declared in two places.
    Hopefully cleaned up the problems with Errormsg() not getting
     sys_nerr; sigh.
    Fixed accounting. Again. Sigh.
    Added (fixed) support for host%port
    Added install/test documentation.

    Added even more portability tests to checkpc. - device locking,
        stty, file locking.

Release LPRng 1Alpha9

    Accounting has been added.

    Fixed up a very very very rare problem with file locking by
    redoing some tests.

    Added the checkpc -T serial_line option
    This performs a whole series of portability tests, all of which
    need to pass.

    Include file problems strick again: fixed up the right set.

Release LPRng 1Alpha8

    Sun Aug  6 11:07:51 PDT 1995 Patrick Powell

    Renamed files with pathnames greater than 14 chars to shorter ones;
    Antique file systems strike again.

    Added 'form' and 'hold queue' capability; modified the control and
    job files; Renamed the release name to be consistent with GNU standards.
    Fixed problem with compatibility between SUN and other systems.
    Added LPR -Q flag, LPR -k flag to make it work.

    Sun Jul 30 09:09:49 PDT 1995 Patrick Powell

    Discovered some problems with the job printing code in LPD/lpd_jobs.c,
    re-editted it and put in some stronger checks.

    Modified the spool control file format slightly.
    This did not work as well as I thought it would in the overall design;
    now the spool control file can have any number of different types
    of entries for future expansion, i.e.
    printing_disabled   1
    redirect            printer@host

    Several rather silly coding errors in various places that turned up
    when a code checkout program was run: if/then not being executed,
    etc. etc.

    Fixed up the configure.in file to use the old dnl, socket, etc. libraries.

    man/Makefile and src/Makefile modified to use INCLUDE=.. so that configure
    can be run from another directory.  This is very very strange autoconf
    dependency,  but who cares, as long as it works.

    Fixed up a whole minor mess of writes and timeout interactions.  Who would
    have guessed at this interaction?  Created a couple of utility functions
    (Write_fd_str(), Write_fd_len()),  and timeout (Set_timeout(), Clear_timeout())
    routines.  These assume that writes will be done with timeouts;  all places
    where writes are done have been surrounded by Set_timeout, Clear_timeout.

Release LPRng 1Alpha7
Mon Jul 24 09:29:15 PDT 1995 Patrick Powell

    Changed the Makefile 'TARGET' name to avoid conflicts with other
    Makefiles... sigh...

    In link_support.c/Link_send(),  the original code was using
    several writes to send a line;  this has been modified to use
    a single write where possible.  Apparently some implementations
    of LPD code expect the command lines to be sent as a single
    TCP write operation, and do not look for the \n terminator.

    Removed the 'lorder/tsort' from Makefile, and hardcoded the
    library file order.  This provides a simple form of portability,
    but will require updates to the Makefile if a new library file
    is added.

    Added better tests for sys_errlist and sys_siglist definitions.

    Moved all of the configuration information to the root level;
    this fixes a bug with the autoconf code that cannot handle
    more than one level of directory structure.  You can now
    compile the LPRng software in another directory by using:
    cd LPRng.<version>; SRC=`pwd`; \
    cp configure $DEST; cd $DEST; configure --srcdir=$SRC; \
    make all

    Modified the top level Makefile to use the GNU Make -C directory
    capability.

    Fixed Send_job() to make it more robust in the face of protocol
    errors.  The numbers of times a job is retried is set by the
    Connection_retry value.

    Modified the LPC status reporting to make it clearer.
    Removed a redundant error message.

Release LPRng 1Alpha6
Thu Jul 20 19:23:03 PDT 1995 Patrick Powell

    Reorganized the auto configuration code so that it is at the top
    level of the distribution.  Added top level MAKEFILE with directory
    recursion.

    Separated out default printcap and configuration initialization,
    put them in src/default.c

    Fixed up some minor 'lint' level errors.

    Update man pages.  Fix up installation so that VERSION information
      is put in the MAN page source.
    Editted MAN pages heavily in light of comments from people.

    Clean up some code in printcap.h, printcap.c, lp_config.h, getconfig.c

    Fixed a missing check for null string with STRCMP in src/getqueue.c.
    Considered using safestrcmp() for this reason; checked most places;
    safe or appear to be safe.

    Modified the format for LPQ status information,  added more detail
    about the printer status.

    Added -Pprinter option to LPD to simply start and run a spool queue
    server.  This allows debugging of filters much easier.

    Added bk-of-filter-options and bk-filter-options to provide compatibility
    with old style filters.

    Fixed up a lot of minor portability issues with Solaris2.4, using the
    SUN Soft C compiler.  Fixed fumble in gethostinfo.c - will die if
    it cannot find the local host name; this is very bad and should be
    immediately fatal instead of dying later.

    Fixup the the TESTSUPPORT/Makefile to be a little more intelligent.
    Also, put in guards to make sure that you have GNU Make.  This appears
    to be essential for sanity reasons alone.

Release LPRng 1Alpha5
Mon Jul 17 10:57:49 PDT 1995 Patrick Powell

    ********* BSDI *************
    Literally hundreds of questionable items were reviewed, fixed
    or modified.  The 'snprintf' function was renamed to 'plp_snprintf'
    in order to avoid conflict with the BSDI/GCC snprintf functions.
    Fixed up some questionable uses of snprintf, changed to sprintf.
    Discovered an incredibly vulgar behaviour in strncat(),  and
    fixed up its uses.  Strncpy will clobber all information in string;
    double checked its uses where possible.

Fri Jul 14 08:22:03 PDT 1995 Patrick Powell
    Fixed up configuration file reading. Was always using default
    values.

Fri Jul 14 08:23:06 PDT 1995 Patrick Powell
    LPD status reporting did not read the printcap 'st' status file.
    Now reads the file and reports information using short form or
    long form as needed.
Version LPRng-3.8.20 - Tue Jan 7 09:18:15 PST 2003

  The lpd.conf now has (EMPTY STRING) for defaults which are
  empty strings... My Bad.  Patrick

  At the request of Karl Kopper <karl@unfiw.com> I reviewed the issues
  of queue starting,  polling the queues for done jobs, and other
  issues.  A small side effect of this is that the LPD server process
  now starts printing processes.  This is actually beneficial as it can
  now limit the total number of printing processes and allow some
  LPQ/LPC/LPR etc actions. Here is a summary of the current operation
  and the options that control it:
   Options:
      lpd_force_poll - forces a check of the spool queues, even when there
        is most likely no reason to.  Used when you have some REALLY odd
        programs running that will directly manipulate the LPD spool queues
        and you do not want to have to connect to the server.
        (default is OFF).
     lpd_poll_time - interval in secs between checking queues for work.
        Done if there is some reason to suspect that some spool queue
        had problems and might need to be restarted.  This also handles a
        race condition where a job arrives just as the process servicing
        the spool queue exits.
        (default is 5 minutes)
     lpd_poll_start_interval - if there are spool queues which need service,
        fork up to 'lpd_poll_servers_started' processes at a time and then
        wait for lpd_poll_start_interval seconds before forking more.
        This prevents the deadly situation where the LPD server is started
        and in turn  starts a gizillion process; the rc starupt scripts
        may fail because there are no free processes (I kid you not on this
        one, it drove me nuts trying to find out why the system would crash
        ONLY when LPD ran with NO debugging - the IO caused it to slow down
        enough so that the other scripts could run).
        (default now 1 second)
     lpd_poll_servers_started - maximum number of processs to fork to be
        spool queue servers at a time.  this prevents the massive forking a huge
        number of processes at once.
        (default now 5)

    When you send a job via LPR, the LPD server forks a 'service socket'
    process to handle job reception;  in previous versions after receiving
    the job the process would then call Do_queue_jobs() to take on the
    duties of the 'handle the jobs in the spool queue' process.  In
    this version the 'service socket' process sends a 'start queue'
    request to the LPD server and then exits.  The LPD service will
    then fork a process to become the 'handle the jobs' process.
    Similarly, when an lpc operation needs to start a 'handle the jobs'
    process,  a message is sent to the LPD server to start the process.

    While there is no real difference in performance on lightly loaded
    systems,  there is a big difference on heavily loaded systems.  Now
    the LPD server can control the total number of active spool queues
    much easier,  and the system does not get overloaded as easily.

     Also, the LPRng server does not clobber the system at startup
     time as badly now.

     By the way,  queues which are started or have jobs put in them
     by LPC or LPR have priority over queues that are started by the
     LPD process looking for work.

  Keith ("HP Printer Dies Horrible Death") Rinaldo
  <rinaldok@egr.unlv.edu> has reported that some HP printers lock
  up and do not report status, etc., and display a nasty low level
  error message on the printer console such as 7900FE.  The IFHP
  filter or LPD would sit there waiting for a response.  The 'keepalive'
  TCP/IP facility does not solve this problem,  as sometimes the
  TCP/IP stack is OK but the job handling code (i.e. - print engine)
  is non-functional.  You need to try to get a response from the
  printer,  which is what the IFHP filter does.

  NOTE: send_job_rw_timeout default value is now 0 (no timeout)

  In order to not surprise new users,  the default value is now 0, i.e.-
  no timeout.  Details below.

    The send_job_rw_timeout is now used to set a maximum time that the
    network (or parallel port or serial port) connection will be
    'inactive', i.e. - no data input and not available for data output.
    When the timeout expires the job will terminate with a JTIMEOUT status,
    which will be treated as a JFAIL status.
       /* LPRng internal        process exit status */
       #define JTIMEOUT 43      /* 12 timeout */
    
    The IFHP filter (ifhp-3.5.11) now has a similar 'send_job_rw_timeout'
    option that has the same effect as the LPD 'send_job_rw_timeout'.
    If the file descriptor used to communicate with the printer is
    inactive for this period of time,  then the IFHP filter will exit
    with a JTIMEOUT error code, which will be treated as a JFAIL status.


Version LPRng-3.8.19 - Thu Dec 5 12:34:45 PST 2002
  Check_for_missing_files was not writing control file.
  (Spotted by Keith ("Wanna bet on that?") Rinaldo <rinaldok@egr.unlv.edu>

Version LPRng-3.8.18 - Mon Dec 2 12:08:34 PST 2002
  Added the 'fifo' option  - this now makes LPRng handle
  one incoming job at a time in FIFO order.  If you send
  jobs A B C then they get delivered in order A B C.
  For users who MUST have sequential delivery of jobs.

  Some Linux distributions set 'unlimited' resources for all
  parameters, such as user processes.  Added limit of 1024
  processes for such cases as the system will die a horrible
  death at startup.


Version LPRng-3.8.17 - Sat Oct 26 20:11:28 PDT 2002
  Found a race condition between LPD printing, LPRM, and LPC actions
   that would cause LPD to stop printing if you removed or did
   an LPC action on a job.  After a bit of thought, decided that
   the job would get moved or removed anyways.  Sigh...
   But you might get a bogus error message about 'cannot
   find id' as the job hold file has been removed.

Version LPRng-3.8.16 - Mon Aug 12 15:26:05 PDT 2002

  lpr now honors :mx=xx values so you can check job size
  before you send it.
   (Suggested by:  Rick Cochran <rcc2@cornell.edu>)

  configure --disable-werror removes the -Werror option from CFLAGS.
   (From the wish list of: Rick Cochran <rcc2@cornell.edu>)

  Bad incoming jobs are removed.  You do not get the jobs
  left in the queue as errors.  Note - spoolers will
  keep trying to send jobs even when they get error and
  sit in an endless loop.  No solution for this one except
  to get a better print spooler or whatever...

Version LPRng-3.8.15 - Sun Aug 11 13:11:48 PDT 2002
  
  Remove_done_jobs
    - checks to see if the INCOMING flag is set BEFORE
    it checks to see if there is an error and only checks
    for the data files if the ERROR or DONE flags are set.
    This removes a race condition.  It was bloody obvious
    when I looked at it... I wonder why I did not see it
    before?

Version LPRng-3.8.14 - Tue Aug  6 09:14:06 PDT 2002

  man page fixes.
    (Spotted by the eagle eyes of: Eric S. Raymond <esr@golux.thyrsus.com>)

  Based on third hand reports, some installations of GNU compilers
  on HPUX and other systems now have 'fd_set' data types.
  I have modified configure so that it checks for 'fd_set' being
  present.  I wish there was a way to read the man pages and
  find out if this was the real case.

  The configure 'enable-ssl/disable-ssl/' option was not working.
  Once again beating on autoconf 1.53 ...  It now understands
  'enable-OPTION' and 'disable-OPTION'.
  
  The Samba examples in the LPRNG-Howto were not consistent.
   changed 
        queuepause command = /usr/sbin/lpc -P%p stop
        queueresume command = /usr/sbin/lpc -P%p start
   to
         queuepause command = /usr/local/sbin/lpc stop %p
         queueresume command = /usr/local/sbin/lpc start %p
   (Suggested by: Jim Van Sickler <vansickj-eodc@Kaman.com>)

Version LPRng-3.8.13 - Mon Jul 22 09:07:57 PDT 2002

  Major Enhancement In Printcap and Configuration Functionality
  After much consideration, added the 'client.xxx' and 'server.xxx'
  facility.  Briefly,  if you have a printcap entry of the form
  client.xxx or server.xxx then this can be used to set the corresponding
  xxx variable when the printcap entry is used by the lpd server
  or the LPRng client programs lpr, lpq, lprm, checkpc, etc.

    Entry               Program Type          Sets
    server.xxx = vvv    lpd (server)          xxx = vvv
    client.xxx = vvv    lpr,lpq... (client)   xxx = vvv

  The purpose of this enhancement is to allow a single printcap
  entry to be used for both client and server operation, especially
  in situations where the lpd server is forwarding or sending jobs
  to another lpd queue.

  Example of use:
    lp:
        # used by clients, forcess them to send to
        # specified server
     :lp=%P@server.hostname:force_localhost@
        # used by lpd server
        # the server will now send jobs to the
        # specified destination
     :server.lp=%P@destination

  This is equivalent to and replaces the :client and :server
  printcap flags, as shown below:

    lp:client
     :lp=%P@server.hostname:force_localhost@
    lp:server
     :lp=%P@destination

  This selection operation also works with values in the
  lpd.conf file, allowing global overrides for clients and
  servers.  (I can't imagine a use for this,  but it is there
  if somebody wants to use it.)

  The lpc client and lpc server commands will display the
  selected client.xxx and server.xxx values.  They are also
  propagated to the PRINTCAP_ENTRY environment variables
  for filters.

  Typo's in documentation corrected.
  (Patch by: Stepan Kasal <kasal@math.cas.cz>)

  lpr Kerberos authentication failures were not being reported.
  (Problem noticed by: Rick Cochran <rcc2@cornell.edu>)

  Added SSL authentication.  See the README.SSL.SECURITY file for
  the truly complicated details.  Note that testing with certificates
  signed by non-root CA indicates that the client is not sending
  a certificate, even though one has been requested and the
  certificates and signing certs are in the right places.

  lpd.conf did not have 'include' functionality working.
    (Patch by: Stepan Kasal <kasal@math.cas.cz>)
  
  Added Yet Another LPRng Option: user_is_authuser
      user_is_authuser:
       if( header_info && User_is_authuser_DYN
               && (s = Find_str_value(header_info,AUTHUSER,Value_sep)) ){
               Set_str_value(&job->info,LOGNAME,s);
               DEBUG1("Check_for_missing_files: authuser '%s'", s );
       }
  printcap:
  lp:auth=kerberos5:user_is_authuser:...
   Causes the principle name to be used as the user name.

  lpq_in_perl was screwed up
  (Patches by: Anthony Thyssen <anthony@cit.gu.edu.au>)

  generate_banner core dumped.  Turned out not to be setting
  banner format ("f") when generating entry, so that control
  file generation core dumped when generating new control file.
  (Problem reported by: "Keith Rinaldo" <rinaldok@egr.unlv.edu>)

  Updated Remove_done_jobs to sort jobs by completion time.
  Added 'Set_nz_flag_value' function to stop the ERROR_TIME value
  from being gratuitously updated by various routines.

  Found possible cause of 'job data files not removed' problem
  in the Remove_done_jobs() code.  There is a possibility of a
  data file being orphaned if a 'done job' is removed by the
  spooler at the same time that another processes such as lpq
  information gathering examines the print job.  Rare, but possible.

  Put warnings in the LPRng-HOWTO section on Samba about the
  done_jobs option and interaction with SAMBA job status.
  (Suggested by: Marcus Manske <manske@dramedia.de>)

  Added yet another wakeup and kick to the master server process
  so that printer pools will respond faster.  Sigh...

Version LPRng-3.8.12 - Mon May 6 08:21:49 PDT 2002

  patch for TCPWRAPPERS added a gratuitous -lwrap to the src/Makefile.
  (Spotted by: Rabellino Sergio <rabellino@di.unito.it>)

Version LPRng-3.8.11 - Thu Apr  4 07:49:30 PST 2002

  Subtle problem when a filter fails and produces zero
  length file.  This is now treated as a JABORT level
  error.  The problem is that RFC1179 treats a file
  length as 0 as a 'read until end of file on socket'.
  This means that folks who have filters that WILL produce
  zero length files need to do something to produce at
  least one byte of 'dummy' output.
    (Brought to my attention by:
      Sergij Kovalenko <s.kovalenko@drgueldener.de>)

  Fixed up a portability issue for Solaris 2.6, in linksupport.c.
  Need to do an unsigned long cast to do comparison of INADDR_NONE.
  (Original patch from: Dr Andreas F Muller <afm@othello.ch>)

  Added patches to support TCP wrappers.  Use:
    configure --enable-tcpwrappers
  (Patch by:  Tobias Burnus <burnus@net-b.de>)

  Added a 'Linux Standards Base' (LSB) style startup script
    for Linux systems.
  (Provided by:  Tobias Burnus <burnus@net-b.de>)

  Missing initialization for statb
  (Patch by: Rob Joyce <robjoyce@EE.Princeton.EDU>)

  Clobbering Logfile_LPD in common/lpd.c
  (Patch by: Hugh McDonald <hugh@gw1.symac.dhs.org>)

  Added a call to 'Remove_done_jobs()' in lpd_status.c;
   then modified Remove_done_jobs to return indication that
   a job was removed so that lpd_status.c would RESCAN
   queue... Sigh... OK, but it now works 'right'.
  (Stale jobs not getting removed noted by:
    Richard Ems <r.ems.mtg@gmx.net>)

  The problem of saturating a server when checking for work was
   re-examined.  The new approach is:
    a) if some work was done,  then check for success at
        lpd_poll_time intervals.  If there remains work to
        be done and there is no process actively doing the
        work, mark the queue as needing service.
    b) for the marked queues, start at most 'lpd_poll_servers_started'
       queues at once,  and start these at intervales of
       'lpd_poll_start_interval' seconds.
   The effect of this will be to limit the number of processes
     that LPD will start at a time.
   (Pushed to look at the problem by: Johan Bengtsson <elijah@dd.chalmers.se>)

  Found a very odd bug... the escape code for '\:' in printcap entries
   appears to be broken.  The fix was to assume that the only places where
   it would be used was in 'filter' or other options where the 'expand
   escape sequences' code would be called and would take care of replacing
   "\:" by a ":".
.
  The 'Printer_device()' routine, when opening a filter as an output
  device, did not provide 'stdout' for the filter.  Some filters such
  as pap from Appletalk seem to need this as they produce messages
  on STDOUT (fd 2) as well as STDERR (fd 3).

Version LPRng-3.8.10 - Sun Mar 31 11:31:19 PST 2002

 printcap.5 had :as and :ae examples reversed
  (Spotted by the guy with the red pen and the eagle eyes:
    Craig Small <csmall@eye-net.com.au>)

 Slew of patches sent in by Tim Waugh <twaugh@redhat.com> 
   - silly little kerberos include file patch
   - can't spell printer patch
   - si no moleste the files in the spool queue patch
     (already done)
   - added configure ability to find 'pr' program
   - GCC flags -W -Wall -Werror -Wno-unused-parms
      - also fixed up &*)*(&)*(& unsigned and signed
        integer casts
 Added patch to allow tcp wrappers to be used.  Configure updated
   configure --enable-tcpwrappers     use tcp wrappers (-lwrap)
   (Patch from: Tobias Burnus <burnus@net-b.de>)

 The authentication and connection information for permissions
  checking is now recorded so it can be used for permissions checking.
  and a couple of new fields have been added.
  The following permission tags now have the indicated values
   UNIXSOCKET - true (match or 1) if connection was over a UNIX socket,
     i.e. - the local host.
   When SERVICE=P 
     REMOTEHOST - the original remotehost from which the job was sent
      (previously was the HOST value)
     REMOTEPORT - the original port from which the job was sent
      (previously was undefined )
     AUTH - true (match or 1) if job sent using authentication
     AUTHTYPE - authentication type
     AUTHUSER - value of authentication key for user who originated
        job.  For example, for kerberos this is the user's principle value
     AUTHFROM - value of authentication key for sender of job.  For example,
        if the job was from the LPR program,  this would have the same
        value as AUTHUSER.  However, if it was forwarded from a server,
        it would have the server's authentication name or value.
  lpd.perms.in update to match the new entries
   (Requested by: Toby Blake <toby@cogsci.ed.ac.uk>)

  Once again the checkpc file creation stuff is modified so that
   it can create files in a directory NOT owned by the lpd group/user.
   This is necessary for log files and other items.  Note that this
   MAY cause problems for log file truncation as you need to copy
   file contents rather than just renaming them.  But it turns out
   that I am already doing this so it appears to be OK.
     CAVEAT EMPTOR.
   (Reported by: Torsten Wiebesiek <wiebesiek@tnt.uni-hannover.de>)

  Usage messages now display version information as well as options
   and available debug flags.  Idea shamelessly swiped from somebody else.
   (Stolen from: 'Guido' Van Rossen)

Version LPRng-3.8.9 - Sat Mar  2 15:02:11 PST 2002

  The 'unix_socket_path' and 'lpd_port' options have been modified
  slightly to correct some ambiguous behaviour, and a 'lpd_listen_port'
  option has been added.
    lpd -p lpd_listen_port -P unix_socket_path
     - the -p and -P command line options override the
       lpd.conf lpd_listen_port and unix_socket_path options
     - the default values for lpd_listen_port is "", indicating
       the use the 'lpd_port' value.
   The value "off" suppresses opening a port or socket.

     This allows the following operation:
     No unix socket:
        lpd -Poff   (/etc/lpd.conf unix_socket_path=off)
     No lpd listening socket:
        lpd -poff   (/etc/lpd.conf lpd_listen_port=off)
        Note that LPD will still open connections to the
        remote LPD servers using 'lpd_port'.
   If you want to override the destination lpd port, you must
      modify the lpd.conf file.

  Jeff Chua of FedEx (Federal Express) <jchua@fedex.com>
  showed up at my office armed with a set of test scripts and a laptop
  running LPRng.  He demonstrated the problem of the 'missing datafile'
  during job transfers.  I have fixed the problem in this release.
  See the UTIL/testpr file.  
   (Thanks to: Jeff Chua: <jchua@fedex.com>)
    
  more autoconf + automake + libtool insanity:
     WITH_LINK removed
     STRIP now used by libtool, changed to STRIP_OPTION
     Added AC_C_VOLATILE (see note on volatile below)
  (Reported by: Rick Troxel <rick@helix.nih.gov>)

  Forced a rescan of the input queue when the number of done jobs
   exceeds 'done_jobs' or the time since the first done job exceeds
   done_jobs_max_age .  This solves a silly problem that shows up
   when you have a slew of jobs in a queue,  the subserver is processing
   them,  and no new jobs arrive while it is processing them.  Under these
   conditions the 'done jobs' would not have been removed until all were
   done.  If you were printing 1000 jobs then you could not submit any
   new jobs, even though you have done 999 of them... :-)

   Sigh... these boundary conditions are the pits.

  Added the 'volatile' option to declarations of static and nonstatic
  variables updated in signal handlers.  You really don't want to
  hear the frothing about over-enthusiastic optimizing compilers, do you?

  Ran the Kerberos tests, discovered minor definition problems with
  krb4_auth.h and Kerberos4 support.  Have no way to test this,  hope
  the problem is resolved.

  The AUTHUSER information received at job submission time was not
  being stored and used later when printing permissions were checked.
  (Discovered by: Toby Blake <toby@cogsci.ed.ac.uk>)

  Added a 'UTILS/README.ForKerberosHackers' file so that Kerbero Hackers
  can quickly and brutally set up a test LPRng system.  Not for the
  faint hearted.  Carry a dog nummy when you read this stuff...

  Some users hit themselves in the head and complain about headaches.
  If the 'lpd_port' value is 0,  then checkpc and lpd squawk.
   (Not telling me who the user was, but reported by:
      Craig Small <csmall@eye-net.com.au>)

 

Version LPRng-3.8.8 - Sat Feb 23 07:35:45 PST 2002

  Restored include file functions to lpd.conf.  Also put in recursion
  depth checks so that it will stop if you have a loop.

Version LPRng-3.8.7 - Fri Feb 22 12:24:38 PST 2002

  Modified the wildcard lookup so that it returns some sane
   values for defaults, i.e. - '*' is not treated like
   a real printer and the first 'real' printer is used.
     Sigh...

  autoconf, automake, and libtoolize insanity.
    Each of these facilities has a different version of the
    config.guess and config.sub files, and will brutally copy
    them to the distribution directory when you run automake,
    autoconf, or libtoolize.  Problem sort of solved by
    running through the /usr/local/share/{auto*,libtool}
    directory and finding latest versions of things.  As the
    CarTalk guys say, "Bo-0H-OH-OH Gus!".  Sigh. 

  The 'Service_connection: bad request...' error message now has
   the IP address of the sender added.
  (Good idea from: Rainer Tammer <rainer.tammer@spg.schulergroup.com>)

  Makefile.in had the diagnostic options left enabled after
   regression tests.
   BAD! Bad Programmer! BAD! No coffee for you today.
   (Reported by: Petri Kaukasoina <kaukasoi-lprng@elektroni.ee.tut.fi>
      among others...)

  Portability stuff,  // comments, and src/Makefile referencing
   ${SRC}/../UTILS instead of ../UTILS.
   (Reported by: Hans Peter Verne <h.p.verne@usit.uio.no>)

  Missing check in lpstat for end of string condition:
   for( t = Printer_DYN; t && !isspace(cval(t)); ++t );
    => for( t = Printer_DYN; !ISNULL(t) && !isspace(cval(t)); ++t );
   (Reported by: Villy Kruse <vek@pharmapartners.nl>)

  psbanner was creating a /tmp/before file.
   (Reported by:
     Anthony R Iano-Fletcher <Anthony.Iano-Fletcher@cbel.cit.nih.gov>)

  Fixed the 'job done' status message so that it shows the job id.
   (Suggested by: Christoph Beyer <christoph.beyer@desy.de>)

  Added some sanity checks to handle cases when hold files and
   control files do not have identifier information in them.

  Checkpc now checks for duplicate spool directories.

Version LPRng-3.8.6 - Fri Feb  8 19:31:52 PST 2002

  HF_NAME not getting set when hold file read and it is not
  in file.  This makes updates miserable.
  (Problem spotted by: Helmut Jarausch <jarausch@igpm.rwth-aachen.de>)

  Fixed typeo in configure where I had unixsocket and unixsocketpath
  instead of unix_socket and unix_socket_path...
  (Pointed out by: Craig Small csmall@eye-net.com.au)

  Modified the host/printer lookup behavior when clients
  are using 'force_localhost'.  You now use the 'original'
  queue name rather than the 'destination' queue name.
  Wonder how long this has been there.
  (Prompted by a problem report from: Andrew Gray" <grayaw@egr.unlv.edu>)

  Missed a 'AF_UNIX' definition.  Now guarded with ifdefs.
 
  Corrected LPRngHOWTO accounting information:
   (Error reported by: "Dirk Krause" <d.krause@fh-sm.de>)

    Example:
     lpd generates:  
      jobstart  - from the lpd.conf 'as=' option
      jobend    - from the lpd.conf 'ae=' option
        -H   - host name
        -n   - user name
        -P   - printer
        -k   - control file name
        -b   - byte count of job/file
        -t   - current printing time
        -J   - Jobname (if present in control file)
        -C   - class (if present in control file)
        -M   - mailname (if present in control file)
    
     ifhp filter generates:
       start/end         - of filter, for entire job
       filestart/fileend - if or other filter, for each file
       (options above are same)
        -A  - identifier information (if present in control file)
        -q  - process id of filter
        -p  - current value of page counter, 0 indicates no
              page counter on printer or it is not readable
    
    jobstart '-Hh110.private' '-nroot' '-Plp' \
       '-kcfA129h110.private' '-b48780' '-t2001-10-19-09:36:36.000'
                               ^^^ bytes in file
    
    start '-q26130' '-p105340' '-t2001-10-19-09:36:38.330' \
                     ^^^^^^^  starting page counter value for job
        '-Aroot@h110+129' '-nroot' '-Plp' 
    filestart '-q26132' '-p105340' '-t2001-10-19-09:36:38.350' \
                          ^^^^^^^  starting page counter value for file
        '-Aroot@h110+129' '-nroot' '-Plp' 
    fileend '-b19' '-T435' '-q26132' '-p105359' '-t2001-10-19-09:43:51.504'
                                      ^^^^^^^  ending page countvalue for file
             ^^^ number of pages printed for this file
        '-Aroot@h110+129' '-nroot' '-Plp'
    end '-b19' '-T435' '-q26130' '-p105359' '-t2001-10-19-09:43:51.504'
                                      ^^^^^^^  ending page countvalue for job
         ^^^ number of pages printed for this job
        '-Aroot@h110+129' '-nroot' '-Plp'
    jobend '-Hh110.private' '-nroot' '-Plp' \
        '-kcfA129h110.private' '-b48780' '-t2001-10-19-09:43:51.000'
                               ^^^ bytes in file

Version LPRng-3.8.5 - Tue Jan 22 15:58:46 PST 2002

  Added a minor fix to lpq so that it will check all queues.
   (Courtesy of Jim Trocki <trockij@transmeta.com>)

Version LPRng-3.8.4 - Thu Dec 13 08:25:17 PST 2001

   ARGH! ARGH!  screwed up lpq -a by forgetting to
   get the 'all' printer information.  Doh!
   (Spotted by and slapped his forehead by:
      Patrick Powell <papowell@lprng.com>)

   "Why do we need a TCP/IP port?"  quoth the raven,  I mean
   Craig Small <csmall@eye-net.com.au>.
   "I have a version that has this facility..." respondeth
   Patrick ("Mr. Grumpy") Powell.  "But I think you will not
    be happy".  I merged the two versions.  Be Happy.

   configure:
     Added these options
       --enable-unix_socket  (default disabled)
       --with-unix_socket_path=PATH  (default /dev/lprng)

   /etc/lpd.conf:
    OPTION      TYPE   DEFAULT PURPOSE
     unix_socket FLAG   1       enables/disables the UNIX socket
     unix_socket_path STR   /dev/lprng    path to the pipe using this

    Also: lpd_port = 0 will disable the TCP/IP port

     lpd -p 0    - disables the TCP/IP port
       or /etc/lpd.conf  lpd_port=0
     lpd -P /path   - enables, unix socket specified by path
       or /etc/lpd.conf  unix_socket@
     lpd -P off     - disable unix socket

      Permissions:
       Connections to the UNIX socket will appear to come
       from localhost, (127.0.0.1) port 0.  You can use the
       UNIXSOCKET to check for this condition, or explicitly for
       localhost/port 0
         ACCEPT/REJECT ... UNIXSOCKET
    Also updated the INSTALL note.

   checkpc:  I was using 'To_daemon()' calls all through the
     code.  This was not needed and would cause a substantial
     slowdown in operation.  I now do exactly ONE call at the
     start of operations.

   updated the config.guess and config.sub to the latest version
   provided by autoconf.

   Incoming jobs now have a status entry.  This is to support IPP
   and status reporting for incoming jobs.  The idea is that you
   can start transferring a job and then,  when the whole job is
   transferred,  the job will be done.  To make this happen you
   need to put an entry in the queue to act as a place holder and
   reserve the job number for this action.  When transfering an
   IPP job,  you can send it in chunks.  This now allows the IPP
   system to send the job header (request), set up the job status,
   and then the job contents.  Just to make life interesting...

   Found some places where I was using 'sizeof(xxx)' instead of a
   passed value for an error message buffer.  Very short error
   messages - 3 chars long... :-)

   LPD now REALLY uses the lock files to prevent multiple
   instances from running.  This might/will/could break on
   systems that NFS mount their lock directories.

   Cleaned up the error message about bad print job formats.
    Clearly there are some REALLY strange printing systems out there.
    (reported by: Phil Moses <pmoses@physics.ucsd.edu>)

   Checkpc -A XX -r now has nicer format:
     t1:  file 'hfA877', age 24.57 hours > 24.00 hours maximum
     (Spotted by: (Craig Small) csmall@eye-net.com.au)

   Added the following to the pass_env options:
    LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
    LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
    LC_IDENTIFICATION LC_ALL
    This should help with LOCALE support.

Version LPRng-3.8.3 - Mon Dec 10 20:40:02 PST 2001

   Fixed the operation of 'lpr -Pxx' when printcap for xxx
   has the format:
     xx:direct:lp=...
     Sigh... too many special cases...
       (Pointed out at LISA2001, and fixed on site...
       Now who was that masked Sysadmin???...)
    (From the mailing list:
      James Thomas Klaas <jklaas@engin.umich.edu> )

   Removed spurious commas in control file Z options.

   Configure did not set 'done_jobs_max_age' correctly.
   (Patch from: Dejan Ilic <dejan.ilic@home.se>)

   lpc flush now cleans out status as it should have done...
    GRRR... user pointed this out at LISA 2001...

   Fixed up a problem with global variable Name.
      From:  Rick Cochran <rcc2@cornell.edu>
    I got LPRng to build under OSX.  It required only one patch which
    seems to be due to the fact that "Name" is declared "extern" all
    over the place, but is only defined in getopt.c.  Since lpstat
    doesn't use getopt, ld complains.  I'm not sure why GNU ld should
    complain under OSX and not on other platforms.
     (Patch by:  Rick Cochran <rcc2@cornell.edu>)

   Editted the lpr man page.  Updated the information about
    obsolete options.

   Updated the installation procedures for FreeBSD, linux, etc.
   The STANDARD_configuration script now checks to see if there
   is a /usr/share/man and if so, runs  configure with
   --mandir=/usr/share/man.  Man pages now show up in the
   right place.  This was true on *BSD, various LINUX distros,
   and some versions of SunOS/Solaris.

   Updated the DISTRIBUTIONS/FreeBSD entry and the postinstall
   scripts so that the port stuff works better.  Now if you do:
         cd LPRng/DISTRIBUTIONS/FreeBSD*
         make PREFIX=/usr SYSCONFDIR=/etc
   You will get the same effect as:
         cd LPRng
         sh STANDARD_configuration
         make clean all install
   But, as you might suspect, there are some minor gotchas.
   The man pages usually get installed in /usr/share/man, but
   when you use the PORT system and override PREFIX it
   insists on installing them in /usr/man... and various
   versions of the FreeBSD and OpenPort stuff INSISTS that
   when generating a port that the originals of the man pages
   are in the ${PREFIX}/man/manX directories.

   I gave up and cheated:  you get an obnoxious warning to
   either create /usr/man or to make a symbolic link from
   to /usr/share/man from /usr/man before installation starts.
   I know, I know.  But I don't have that many brain cells
   left to fry...


Version LPRng-3.8.2 - Mon Dec  3 12:26:52 PST 2001

  MAJOR CONFIGURATION CHANGE:

  LPRng can retain status of last N completed jobs
     configure --with-done_jobs=N
         - set done_jobs value, default 1
     configure --with-done_jobs_max_age =N
          - set done_jobs_max_age value, default = 0 (no expiry)

     Or in the printcap/lpd.conf:
       :done_jobs=1
       :done_jobs_max_age=1

   Example:
    Printer: t1@h110 'Test Printer 1'
     Queue: no printable jobs in queue
     Server: no server active
     Status: job 'cfA231h110.private' removed at 18:25:36.281
     Rank   Owner/ID         Class Job Files             Size Time
    done   papowell            A   278 /tmp/hi              3 18:25:31

  Controlled by:
    :save_on_error        - all jobs with error saved, status not removed
    :save_when_done       - all jobs with no error saved, status not removed
    :done_jobs=N          - last N jobs completed (error or no error) saved
    :done_jobs_max_age=N  - jobs with status older than N seconds removed

  This is best explained by:
    On job completion:
    if( (no error && save_when_done)
       || (error && save_on_error)
       || done_jobs > 0 || done_jobs_max_age > 0 ){
      do not remove job
    }

    When queue updated:
    if( !(save_on_error || save_when_done) ){
       while( done_jobs_max_age >= 0
         && the time since completion of oldest done job > done_jobs_max_age ){
               remove the oldest done job
       }
       while( done_jobs >= 0 && total number of done jobs > done_jobs ){
          remove the oldest done job
       }
    }

  Fixed up the order of 'require_explicit_q' in the variable list.

  Added 'lpd -p port' so that lpd port can be specified at run time.
   (Suggested by: Chris J. Herbst <chris@herbst.com>)

  Added 'PrintingCookbook' to the distribution.

  The 'shorthost' DNS lookup result was not being set correctly
  if DNS lookup failed and you had to drop back to using IP address.
  Clearly the shorthost form of IP10.0.0.1 is IP10.0.0.1, not
  IP10.

  Added patches to help support Win32 porting using Cygwin:
  UID 0 is now ROOTUID instead of 0 value.
  ROOTUID is set by ifdef in portable.h

  checkpc -f no longer puts out the annoying '/var/run/lpd.515
   does not exist' message.

  List_sep (which is only used in Check_for_rg_group) needs
  a comma.
    (Discovered by: Graeme Wood <Graeme.Wood@ed.ac.uk>)

  Reworked the 'start lpd subprocess' code so that it is a little more
  civilized.

  Modified portable.h so that LPRng compiles properly on HPUX 11.xx
  systems.

  lpc help fixed up - 'redo - reprints jobs'

  Cleaned up the 'Make_sort_key' code so it does not do needless
   malloc.

Version LPRng-3.8.1 - Thu Nov 15 16:08:41 PST 2001

  The original default actions and values for the LPD_PRINTCAP_PATH
  have been restored, as it broke too many other things.  A work around
  for the problems with using LPD and database based configuration
  has been found... ugly, but it works.

  Chooser also now will wait when it cannot find a queue instead of
  just exiting.  This solves the problem of 'hung' load balance print
  queues using 'chooser' support.

  Trim the accounting file information.  This now solves the 'mysterious
  full spool partition' error messages.

  'indefinately' is really 'indefinitely' ... so says 'ispell'

  The 'remove_z' now really removes 'Z' options.
   (Found by: Ryan Lovett <ryan@stat.Berkeley.EDU>)

  The 'require_explicit_q' added for those folks who absolutely require
  that a queue be specified and do not want them to use a default queue.
   (Patch to code supplied by: James Thomas Klaas <jklaas@engin.umich.edu>
     with a little help from Dan Escapa)

  Grrr... left in a line of code when I was doing some testing of the
  setuid functions in Win32 and screwed up the setuid stuff.

  Fixed up a silly problem with file descriptor 0 not bound to
  /dev/null in lpd subprocesses.

  Fixed the 'Trim_status_file' routine so that it now treats file
  descriptor 0 and -1 as 'closed' files.  This prevents some silly
  problems with initialization.

Release LPRng 3.8.0 Mon Oct 15 12:09:13 PDT 2001

   At line 174 in accounting.c:
     } else if( safestrncasecmp( s, "hold", 4 ) ){
   This should be
     } else if( !safestrncasecmp( s, "hold", 4 ) ){
   otherwise anything send back to lpd from the accounting filter
   other than accept will result in a JHOLD!
    (Spotted by: "C. L. McAvaney" <chrismc@deakin.edu.au>)

   Added :force_ipaddr_hostname option.  This causes the IP address of the
   remote host to be used for the hostname, overriding the information
   in the control file.  This can be used when you really need the
   IP address rather than the hostname in the control file.
     (Needed by: Rick Cochran <rcc2@cornell.edu>)

Release LPRng 3.7.9 Mon Oct 15 06:18:43 PDT 2001

  Version control strikes again.  Sigh...
  Now all the files are carefully put into place
   (Fumble fingers by:  Patrick Powell <papowell@astart.com>)

Release LPRng 3.7.8 Tue Sep 25 12:35:46 PDT 2001

  Can't spell... fixed typos in man pages.
  (Corrections from: Karsten Weiss <knweiss@gmx.de>)

  lpd_logger.c - free(sp); s=0 ... this sure does make
   free() and malloc() unhappy...
   (Found totally by accident: Patrick Powell <papowell@astart.com>)

  lpr '-Y' (enable lpr_filter) processing fixed up a bit.  Now has better
   diagnostics and information.

  An extremely rare but annoying network condition causes LPQ print
  status to fail.  When running as root (setuid root),  and doing an LPQ
  operation,  the lpq process will try to bind to a port in the low
  port range (512 - 1023).  This will sometimes fail with a timeout
  if the port has been recently used and bound to.  I have put a bit
  more 'randomization' into the selection of the port,  but there is really
  nothing that can be done,  as the TCP/IP error status does not distinguish
  between 'connection refused because you just connected from this port'
  and the remote printer being off line.  Sigh...  The obvious answer
  to this is to bind to the low ports only when needed, but this requires
  users to know when to set the option.  I give up.


Release LPRng 3.7.7 Fri Sep 14 15:54:48 PDT 2001

  checkpc whooped its cookies when running checkpc -f and
  the device is /dev/null (lp=/dev/null).   Apparently I
  cannot set /dev/null to use blocking IO...  Sigh...  So I
  do not count 'changing non-blocking IO to blocking IO'
  as an error.

  i8n French Translation (gettext) added.
  (Supplied by: Francois Mescam <Francois.Mescam@onera.fr>)

  The files generated by the 'incoming control filter' were not
  being re-read by the LPRng system.  Silly me.
  (Discovered by: Tuomas Toropainen <tuomas@nic.funet.fi> )

  The 'bq_format' option was not being handled correctly
  for defaults.  This option has the value:
    bq_format=IoIo...D
       I = original input format (or '*' for wildcard match)
       o = filter output format
       D = default (if present),  otherwise keep original
  It now handles the case where no translation is required
  correctly.
  (Prompted by a question from:
     Rainer Tammer <rainer.tammer@spg.schulergroup.com>)

  Did not check to see that I was a client before doing
    setgroup to daemon.  Stupid of me.  GRRRR... I now have
    a test for this in the code.
   (Warning from: Petri Kaukasoina <kaukasoi-lprng@elektroni.ee.tut.fi>)

Release LPRng 3.7.6 Fri Sep  7 05:36:00 PDT 2001

  There was no call to Getdaemon_group so the default daemon group
  was 0.  This, as they say, was double plus ungood.
   (Spotted and reported with a cackle of diabolical laughter by:
       Petri Kaukasoina <kaukasoi@elektroni.ee.tut.fi> )

  I added a 'half_close' flag so that you can force a 'close(fd)'
  rather than a 'shutdown(fd,1)' to be done for those problem child
  network printers that whoop their TCP/IP stacks and die horrible
  deaths when they get a half closed connection.  This is,  as they
  say, a bug in the print server,  but I have encountered worse.
  The same printers also whoop their cookies when reporting status
  but I don't seem to be doing a half-close on 'lpq' connections
  so this doesn't seem to be a problem.  I have modified the 'lpq'
  code so it does not do a 'half-close'.

   Example:
     lp:lp=host%9100    # happy, well behaved, print spooler box
     lpb:lp=host%9100:half_close@  # buggy print spooler box

  Grammar fixed in LPRng-HOWTO.
    (Red pencil work done by: <Jeffrey.H.Knodel@chase.com>)

Release LPRng 3.7.5 Sun Sep  2 12:43:39 PDT 2001

  I was not closing all open file descriptors.  This caused checkpc and
  lpd (when running as 'spool queue server') to die mysteriously after
  processing a couple of jobs.
  (Clue to cause supplied by: Heiko Burghardt <burghardt@riege.de>)

  The lpc -s status only reported number of jobs.  Now it also reports
  queue status,  as it used to, and should have.  And it reports only
  the number of printable jobs.
  (Patch by:  Garry Zacheiss <zacheiss@MIT.EDU>)

  Patch to accommodate Broken RFC1179 Implemenation #39 from Apple.
  (Gory details and a patch by: Darius Davis <s328919@student.uq.edu.au>)

  The 'Read_fd_len_timeout' and 'Write_fd_len_timeout' code would not
  pause indefinately if the timeout value was 0.
  (Noticed by: David E. Cross <crossd@cs.rpi.edu>)

  A slew of patches from Crutcher Dunnavant at redhat.com:
  From the LPRng-3.7.4-23.src.rpm at the RedHat ftp site:
    LPRng-3.7.4-direct.patch - fixed a typeo in vars.c
    LPRng-3.7.4-inet_ntop.patch - conflicting/duplicate
        definition of inet_ntop.
        NOTE: I also fixed the inet_pton() definition to
        be consistent with the patch.
    LPRng-3.7.4-jobfilescan.patch, LPRng-3.7.4-lockfile.patch
        a little less agressive checkpc operation.  Checkpc
        now does not NOT update the targets of symbolic links.
        This solves the problem of various tools creating
        files in the spool directory as well as symbolic links
        to filters.  The FILES need to be accessible by
        filters running as the LPD user, the targets of the
        symbolic links should not be touched.
    LPRng-3.7.4-kerb5.patch - not used, do not want to hardwire
        paths into configure.  Modified RPM config file to add
        /usr/kerberos/{include,lib} instead
    LPRng-3.7.4-lockfile.patch - lockfile created now
    LPRng-3.7.4-manpage.patch - typo in lpr.1 fixed
    LPRng-3.7.4-nointl.patch - configure using wrong -lintl
        value.
    LPRng-3.7.4-nonblock.patch - changed some blocking opens
        to nonblocking opens in checkpc so that checkpc did not
        hang.  Silly of me not to have done this,  as the
        Check_write() routine even had a nonblocking flag just
        for this purpose.
    LPRng-3.7.4-s390.patch, LPRng-3.7.4-setgroups.patch
        This is a fiddle, not a major problem.  The only
        exploit possible is if the lpd server is started
        with "extra" groups besides the default one.  If
        you do not install lpd SETUID root (which is the default)
        then you have to be root to start this (su root OR login
        as root),  and this means that either login or su is
        not setting up the group membership correctly.
        But it is better to err on the side of paranoia than
        be careless.
    LPRng-3.7.4-shutdown.patch
        Note: the 'shutdown()' patch was NOT applied as it breaks
        a slew of other things.  Clearly we have some problem
        printers out there that need to be identified.
  (Courtesy of: Crutcher Dunnavant <crutcher@redhat.com>)

  Updated GETTEXT/i8n support to gettext-0.10.39.

  The printcap option 'prefix_option_to_option' is declared as a flag in
  src/common/vars.c in both versions 3.7.4 (line 355) and 3.6.26.
  { "prefix_option_to_option", 0, FLAG_K, * &Prefix_option_to_option_DYN,0,0},
  should be:
  { "prefix_option_to_option", 0, STRING_K, &Prefix_option_to_option_DYN,0,0},
  (From: Anthony R Iano-Fletcher <Anthony.Iano-Fletcher@cbel.cit.nih.gov>)

  Redid the authentication documentation and code...  cleaned it up a bit.
  And comments.  And printcap.5 updated, HOWTO updated.  Sort of works now.
  Fixed up '$a' filter options so that :af=xxx is put on command line only
  if it is NOT a filter.  This clears up the mysterious Linux Printfilter
  deaths.

  Permission checking now works for SERVICE=X.  You can only do remote host
  and port comparisions (REMOTE_IP=, REMOTE_HOST=, PORT=).  This was initiated
  by a bug report about address mask generation.
  (From: Willi Burmeister <wib@cs.uni-kiel.de>)

  'lpc client' now displays defaults.

  The changes to use the 'initgroups()' call for setting process group and
  effective group also cleared up problem reported by some Debian users.

  You can now put a colon in printcap entry values using: \:.  This makes
  life a little easier for some folks who need to have options of the form
  "http://...".  You can now do:  filter=/.../sendftp -d ftp\://some/site

  The configure defaults for filter_path (PATH value for filters)
    are now /bin:/usr/bin:/usr/local/bin
  The configure defaults for filter_ld_path (LD_LIBRARY_PATH value for filters)
    are now /lib:/usr/lib:/usr/local/lib

  Reviewed LOTS and LOTS of documentation.  Fiddles all over the place.

Release LPRng 3.7.4 Wed Dec 27 07:10:27 PST 2000
  ARGH ARGH!  Distributed the test version and not the release
  version for 3.7.3 - this has not been a good week.

  The printcap entry '*:client:rm=IPADDR:force_localhost' now works correctly
  with lpq -a.  Side effect: you do not get status if you do not have a
  default printer.  i.e. - 'lp|*:client:rm=IPADDR' is better.

  I now kill off process by using SIGHUP, SIGINT, SIGQUIT and SIGCONT.
    Even Guido thinks this is overkill but expects that there will be
    some system where even this does not work.

  Added a check for the VERSION of gdbm as well.

  ARGH ARGH ARGH... I fixed a problem with signals (SIGINT) killing off
   the process waiting for a lock on a file descriptor,  but I did
   it wrong.
   (Pointed out most gleefully,  complete with TRUSS output by:
     Doug Morris <doug@daynetwork.com>
       AND
     John Perkins <john@cs.wisc.edu>)

Release LPRng 3.7.3 Sun Dec 24 17:47:52 PST 2000
  Updated the default printcap file with a simplified set
   of instructions.
  There was a 'sleep(1000)' instead of a 'plp_usleep(1000)'.
   Needless to say,  this did slow things down a bit.
  LPRng HOWTO Section on Samba had 'printcap file' instead of 'printcap name'
   (Spotted by: Marcel Kunath" <kunathma@pilot.msu.edu>)
  HPUX compilation without GCC had a gratuitious CFLAGS=-Aa.  I removed the flags.
   (Reported by: Ryan Novosielski <novosirj@umdnj.edu>)

Release LPRng 3.7.2 Fri Dec 22 10:45:00 PST 2000
  Discovered that job moves were not working correctly.  Was
  removing the lpd_port value by mistake.

  Close_gdbm() was not defined,  and the #if HAVE_GDBM_H
   confused some compilers.
  (Reported by: Shane Voss <Shane.Voss@glg.ed.ac.uk>)

  ifhp.conf got the 'reverse_priority' description wrong.
  (Proof-reder was: Michael J. Carter <mcarter@lanl.gov>)

  When I added the user printcap stuff I did not set a return
  value and the 'tc=' broke.  Sigh.
  (Reported by:  gizillions of people, including
     Michal Kouril <mkouril@ececs.uc.edu>)

  RFC1179 does not ABSOLUTELY PROHIBIT some print spooler
    expecting multiple LPQ request.  So it does not close
    the connection after sending status.  So I now do a
    shutdown() to cause it to not expect further commands.
   (Detective work done by Rainer Tammer <rainer.tammer@spg.schulergroup.com>)

  The 'short_status_date' and 'full_time' options seem to conflict
    with each other.  The 'full_time' means to use full time formats
    in LPQ status,  and the 'short_status_date' means to use short
    date formats.  The 'full_time' option now controls both of these,
    which is probably what was intended in the first place.
    (Pointed out by: Bill Kemp <bkemp@srp.gov>)

  Get_all_printcap_entries() was not clearing All_line_list so you
    would get duplicate entries. Solved the 'mystery duplicate printer'
    problem observed during testing.

  Natter in the README and INSTALL for Solaris users.

Release LPRng 3.7.1 - Tue Nov 28 06:33:32 PST 2000

 Major Changes That Effect Backwards Compatibility

  1. local printcaps for users - ${HOME}/.printcap
     This allows users to specify a printcap in their local
     directories.  Of course, you can use the 'user_printcap@'
     option to disable this.  But why bother?

  2. job file filtering always enabled

     The classical 'store and forward' behavior has been changed.
     If you have a print queue with filters
        AND you have a file with the format specified for a filter
        THEN the file is filter and the filtered output is used.

     This is CONTRADICTORY to 'vintage' BSD and 'legacy' LPRng
     behavior.

     If you want to have 'job flattening',  that is,  to have
     the job combined into a single file with all the files
     processed, you need to use 'lpd_bounce'.  If you are currently
     using 'lpd_bounce' you will see no difference in behavior.

     The bq_format option is used to get the 'new' formats after
     filtering.  Bq_format has the form:
       OnOnOn...D
         where O is the original format, n is new format,
         and D is default if there is the original format
         is not present.

         If no default then original is retained.

     The bq_format default is now 'f', not 'l'.

     Example:
       bq_format=f    (default)
          all processed files have 'f' format
       bq_format=flmf (default)
          f -> l, m -> f, others unchanged if processed.

   3. lpr -k option is now re-enabled to allow lpr to handle
       pipe input without creating large data files.  Note
       that if you kill programs off then you might end up
       with a truncated job.

       You can use:  cat | lpr -k  OR cat | lpr -k -- -

   4.  You can now have :lpr= Command Line Options
      This will prepend the command line option flags to the lpr
     command.  Note that this now allows you to set up a user printcap
     entry that has command line options suitable for lpr.

   5. Super lightweight no spooler printing to devices
      with filter support.
        New command line options:  -B, -X filter, -Y
        New printcap option: :direct

      SEND JOB DIRECTLY TO REMOTE TCP/IP PORT:
          lpr -Y -Phost%port file1 file2
       OR:
          use :direct flag in printcap
          In your ${HOME}/.printcap or /etc/printcap file put:
            lp:direct:lp=h14%9100:remote_support=R:client
          And use:
            lpr -Plp file  (:direct is effectively the same as -Y)

          Effectively:
            ( for i in file1 file2 ; do ${filter} <$i; done ) > h14%9100
          where ${filter} is chosen from the printcap entry.

          Note: if you do not specify a file then this reduces to reading
                  from STDIN, e.g.-
                  ${filter} > h14%9100

      NOTE EXTREMELY WELL- for 1 file jobs:
             The STDOUT of the filter is the TCP/IP port connection.
      This allows the filter to get status and other information from the
      remote printer.

      SEND JOB VIA A PROGRAM (SAMBA smbclient, for example):

          lpr -Y -P '|/smbclient //server/share' file
       OR:
             lp:direct:lp=|/smbclient //server/share:remote_support=R:client
          lpr -Plp file
             Effectively:
                   ${filter} <file |/smbclient //server/share

      SEND JOB TO LPD SPOOLER (Network Print Server):
          Ummm... well we already do this.  The :direct flag
      and the -Y flag are basically NO-OPS for this.

          lpr -Y -P pr@host file  == lpr -Ppr@host file
        OR:
          lp:direct:lp=pr@host:client
             == lp:lp=pr@host:client

          lpr -Plp file1 file2
             Effectively:
            for i in file1 file2; do filter $i >temp.$i ; done
             lpr -Ppr@host temp.file1 temp.file2 ...

      USER SPECIFIED FILTER:

      To use a user specified filter: lpr -X filter

        Example
           lpr -Y -Phost%port -X userfilter file
        OR:
           lp:direct:...:filter=userfilter:client

           Effectively:
               cat file | userfilter >host%port

      NOTE EXTREMELY WELL- for 1 file jobs:
             The STDOUT of the filter is the TCP/IP port connection.
          This allows the filter to get status and other information from the
           remote printer.


       SPECIAL CASE for lp=queue@host:

            lpr -X userfilter -Pqueue@host file1 file2
            Effectively:
              send control file;
              for i in file1 file2 ; do
                 userfilter $i > tempfile
                 send tempfile;
              done

       EXTREMELY SPECIAL CASE:  -k option

          The -k option with RFC1179 spooling AND a single file will
          case the following actions to be taken:

                send control file
                send a 'expect BIG file' command
                cat userfile | filter > server

         You can also add -X userfilter and get:

                send control file
                send a 'expect BIG file' command
                cat userfile | userfilter > server


       This is done so that you could run
    lpr as a filter and send HUGE data files to the printer.
    This is done by invoking the '0 length file is read to
    EOF' facility of RFC1179.  Unfortunately,  this is
    not supported by all network print spooler boxes,  so the
    'fakelargefile' option allows you to fake this by sending
    a very large file number (in K bytes).  I suggest using
    1000000 - i.e. - a 1 Gigabyte file.

 Start of a new branch:
  iNTERNATIONALIZATIOn (i18n) Support Revisted

 iNTERNATIONALIZATIOn support has been reviewed and incorporated
  in a much more stable and maintainable manner.  Rewrote the
  ABOUT-NLS.LPRng file.  Modified the Makefile to update version
  information in the po/*.po files as well.  Reviewed much of the
  error message and status messages,  and added them to the translation
  list.  Added the N_() facility for 'static' messages and tables.

  On 4 Sep 2000,  a compromise problem with the gettext facility
  was announced.  This was based on the standard 'fprintf' functions,
  which have a '%n' option to allow values to be written to memory.
  I have totally eradicated the use of the standard printf, fprintf,
  and so forth,  and use a safe version of snprintf without this
  capability.  This allows LPRng to be used on systems where similar
  attacks can be launched.  In addition, if the executable is running
  with uid or euid 0 (i.e. - root), then NLSPATH environment variable
  is unset.  This may break some of the 'set process name' code on
  some systems, but I cannot think of another method that will do this.

 You can now use FreeBSD/BSDI/ and most likely some other newer versions
  of the BSD Make in addition to GMake.  What a pain this was.
  If your make supports VPATH it should work.  Hopefully.

 GDBM used to store information.  This now makes handling LARGE numbers
  of files, etc., in a spool queue directory feasible.  Needless to say,
  status generation time is VERY small.

  There are several caveats on this. If you kill off the lpd server
  when it is in the middle of updating the database file,  you will
  end up corrupting the database file or having an incomplete one.
  To resolve this problem, the 'checkpc -f' command can be used,
  as well as the 'lpc flush' command.  Also,  the initial queue
  scan done at system startup will rebuild the databases.

 IPV6 portability was not quite there.  Some minor fiddles.  So I stopped
  playing the violin.  Maybe some time in the future.
  (Fiddling done and patch supplied by: John Perkins <john@cs.wisc.edu>)

 Fixed the lpq.c status trimming functions to be a little more robust.
  Also, put back the recursive lpq functionality.
  (Recursion loss spotted by: Christoph Beyer <christoph.beyer@desy.de>)

 The lpraccnt program is removed from the distribution.  The 'monitor' program
  can be used instead.  I wonder why I had two of these in the distribution.

 The load balance queues are now treated like 'first class' queues and jobs
  moved to them are treated like incoming jobs.  This allows all of the
  incoming filters to be run,  routing to be done, and other abuses
  far too esoteric to grace these CHANGES notes.  This involved doing some
  very odd things with chdir(), etc. to make sure that the filters would
  run with the correct directory.  Also, status information for load balance
  queues changed so that you don't get silly messages about non-existent
  jobs which have been moved to the load balance queue.  Fixed up problems
  when you run out of file space with load balance queues.  Fixed up debug
  and status file information logging with load balance queues.  Fixed
  a really silly design flaw in Setup_printer() that closed the status
  file just when you did not want it closed - and then truncated it.
  Debug file is now closed and opened only ONCE during a call to Do_queue(),
  making it possible to debug the queue service.  All in all, a really
  thorough redoing of the queue handling was necessary to make them
  into first class citizens.
  (Motivated by the questions of: Jason Keltz <jas@cs.yorku.ca>)

 lpd now mumbles at you when you try to start it up and it has
  problems.  Of course, most folks do 'lpd >/dev/null 2>&1' but
  we will ignore them...
  (Inspired by the well chosen arguments of:
   <eric@lammerts.org> and Craig Small <csmall@eye-net.com.au>)

 lpd now CORRECTLY opens output filters - lp=|/path
  (Spotted by: Seth Chaiklin <seth@psy.au.dk>)

 LPRng-HOWTO - Samba example corrected
  (Correction by: Philippe Weill <philippe.weill@aero.jussieu.fr>)

 lpd_port=[ipaddr%]port now will cause lpd to bind to the interface with
   the specified IP address.
   (Prompted by the whingings of some anonymous Debian user and
     forwarded by: Craig Small <csmall@eye-net.com.au>)

 checkpc runtime help was wrong.
   (Spotted by: James P. Dugal <jpd@louisiana.edu>)

 INSTALL_PREFIX replaced by DESTDIR to be consistent with other distributions
   and packages.

 lp -f formname now makes the CLASS information 'formname' as well.
   (Inspired by: Dave Lovelace <dave@fci.izzy.net>)

 In LPRng/common/linelist.c,  many missing checks for null pointers.
   (Found in a core dump supplied by: Mike Whitson <mwhitson@MIT.EDU>)

 lpr -o option is now the same as lpr -Z option
   (Suggestion to save sanity of SYSV users by: Joseph Krahn <jkrahn@nc.rr.com>)

 lpq did not always have a space before job file size.
   (Noted by: Jonathan Briggs <jbriggs@esoft.com>)
Release LPRng 3.6.26 Fri Oct 13 07:38:38 PDT 2000
 unsetenv() is not available on some systems.  Fallback
   to setenv and then putenv() if not present
 (Found by: Niklas Edmundsson <nikke@ing.umu.se>)

Release LPRng 3.6.25 Tue Oct  3 09:19:11 PDT 2000
 syslog Compromise -
   modified syslog to use 'syslog(xx,"%s", msg).
 gettext Compromise -
   added the following to Initialize():
    if( getuid() == 0 || geteuid() == 0 ) unsetenv("NLSPATH");
 IN6_ADDR removed,  in fact IPV6 stuff removed.

   See the various CERT advisories.  Sigh...

Release LPRng 3.6.24 - Fri Aug 11 08:03:23 PDT 2000
 LPRng-HOWTO - added update for Samba print queue configuration.
 LPRng-HOWTO - added section on how to configure Solaris lp printing
  to communicate with LPRng.
  (Changes courtesy of: Gerald Damian <gdamian@ford.com>)
 Typo in gethostinfo.c spotted.
  (Courtesy of the debugging talents of: Robin Sommer <rsommer@uni-paderborn.de>)
 And I removed the wrong line so that the data files were not being
  deleted when a job was completed.  Helps to read the control file and
  get the data file names...
  (Pointed out by: Thomas Emmel <emmel@mechanik.tu-darmstadt.de>)
 There was a 'cut and pasteo' that caused me to use the wrong value
  to get trim lpq status.
  (Core dump and clues supplied by: John Perkins <john@cs.wisc.edu>)
 LPRng HOWTO - added small section on setting up Solaris lp queues to
  forward jobs to LPRng/BSD printers.
 IPV6 Support fixed up a bit to actually work...
  (Spotted during testing,  now that we actually have IPV6 working
  on our router.)
 Added a 'flush cached status' when a spool server exits.  Now you
  get the correct status when there is no active server.
 Modified the 'Read_write_timeout' code to be consistent with reading
  status from parallel port printers the way that the ifhp filter
  does it.
 Found a minor sillyness in the 'send_to_logger()' code - I carefully
  format data and then toss it way.  Now I do checks first.
 Fixed up lpq status generation - only read a small part of the status
  file for information.

Release LPRng 3.6.23 - Fri Aug 11 08:03:23 PDT 2000

 The Linux Printing Summit was held from July 27-28, 2000
  in San Jose,  and was Sponsored by VA Linux.  There was an
  extremely enjoyable interchange of views between all of the
  various interested factions.  You will see some additional changes
  in LPRng as a result of these meetings and the input from users
  and developers.

 Support for status caching has been incorporated in LPRng.
  In addition, 'spool queue lookup throttling' has been
  added in order to improve the speed of status gathering.
  And there are now facilities to control the format of returned
  status.

  This is implemented as follows:

    a) Each queue has a file containing keys corresponding to
       status queries.  For example, if you do 'lpq' then the
       query key would be "4_"  corresponding to the "\004\n"
       query sent to the server.  If you do 'lpq this that'
       you have the key "4_this_that_" and so forth.

    b) Corresponding to each query is a file containg the status
       for the query.  If the status is 'stale', that is,
       older than 'lpq_status_stale' seconds,  then the lookup
       is redone.

    c) When a job is submitted to a queue,  or the status of a job
       changes,  or a control operation is performed on the queue,
       then the cache is flushed.  Currently,  this means that
       the status has to be regenerated for all queries.

    d) If the queue status was changed less than 'lpq_status_interval'
       seconds ago,  then the cached status (if any) will be used.

    e) If the process needs to update the print queue, it will
       attempt to lock the status file.  This means that at most
       one process will be scanning the print queue for status
       at a time.  This has had an extremely good improvement on
       status reporting, especially under high load conditions
       and multiple processes attempting to scan the queue.
       This locking actually improved throughput much to my
       surprise.  A careful analysis showed that by having only
       one or two processes scanning the directory at a time,
       the OS was better able to cache and buffer data.  In actual
       fact,  the second process would then find the files that
       it was looking for already in memory or in the buffer cache.
       Also,  if the two processes were getting the same data
       (lpq -a),  the first one would set up the data in the cache
       and the next one would simply read the cached data.

  The 'lpc flush' command has been added to flush all of the
    cached status.  This was added for testing and for administrative
    purposes.

  A new Super Secret option (well, it is documented now) has
    has been added to the 'lpq' facility.  The following
    only works with LPRng servers (as of this release, of course):

        lpq -- -lines=N   (in general: lpq -- -opt=v,opt=v)

    The '-lines=N' is passed directly through to the LPRng
    lpd server,  where used to set the size of the returned status.
    It is NOT propagated to other servers,  BUT it is used to
    truncate status returned from them.  This will effectively
    give you a VERY compressed status extremely quickly when
    combined with the caching facility.

    The -- is used to indicate that the -lines=N is actually an
    option to be passed through to the server.  This capability
    has been in LPRng,  but this is the first documented use
    of it that will be supported.

    The addition of this facility has some interesting implications.
    You can now have a VERY lightweight lpq facility,  for getting
    the status of one printer,  if you know the server it is on:

    echo "\004printer -lines=2 xx xx xx" > nc host 515
     (nc is the 'netcat' program written by mudge@avian.org)

    Of course you do not have authentication,  etc., but this is
    One Of Those Tradeoffs.  YOU ARE WARNED: USE THE SOCKET CONNECTION
    METHOD AT YOUR OWN RISK AND DON'T WHINE WHEN YOU DISCOVER THAT
    THE LACK OF AUTHENTICATION IS CAUSING YOU PROBLEMS.  If this
    is a problem, use the 'lpq' application and turn on authentication.

    On the other hand,  you can now get printer status WITHOUT the
    use of an 'lpq' process to format it.  I expect the various
    folks building WebServer interfaces for LPRng print status will
    be more than happy now, as this works well in a multi-threaded
    environment,  is strictly socket/connection based.

    Another benifit is that NonLPRng (can you say Microsoft?)
    based applications can now use the -lines=N entry to select
    the amount of status that they want returned.  This allows
    remote clients not LPRng based to select the level of verbosity.

  This work was inspired by the Samba Developers, especially Andrew
  Tridgell, John Terpstra, and Jeremy Allison,
  <http://www.samba.org/samba/team.html>,  and their presentations
  and discussions at the Linux Printing Summit held in San Jose,
  July 26-31, Sponsored by VALinux.

 You can now specify a filter for your input files at the user level.
  This is to support the requirements and/or desires of the various
  users of print spooling software to have a filter applied at the
  application end.

  The syntax is:
     lpr -X /path file1 file2
  equivalent to:
     for each file in filelist; do
       tempfile=maketempfile;
       /path <$file >$tempfile
     end
     lpr $tempfile1 $tempfile2 ...

  The filter is invoked once per job file,  on each job file.
  The options passed to the filter are the usual ones for all
  LPRng filters.  Some will not have any meaning,  such as job
  number, etc., and will not be present or have a '0' value.
  The filter will run as the user's id, and will not have root
  capabilities.  If this is needed,  then the filter must have
  the capability of acquiring them.

  This work was inspired by the GIMP Project presentation of Robert
  Krawitz <rlk@alum.mit.edu> http://www.tiac.net/users/rlk/ Project
  lead for The Gimp Print --  http://gimp-print.sourceforge.net at
  the Linux Printing Summit held in San Jose, July 26-31, Sponsored
  by VALinux.

  I ran into problems with the SysV to LPRng option passing. Apparently
   different versions of SysV printing pass options as S, O, or
   whathave you values in the control file.  The prefix_o_to_z
   option has been replaced by the more general 'prefix_option_to_option'
   facililty.  This specifies the control file option lines to
   prefix to a control file option line.  For example:

    prefix_option_to_option=S,O Z  will prefix S and O to Z
    prefix_option_to_option=Z O    will prefix Z to O.

    This now appears to cover all cases,  and the LPRng HOWTO
    has been modified as well.

  The simple minded 'send mail to user' facility had some problems.
   I fixed them up,  and added a 'sendmail_to_user' flag that allows
   the facility to be disabled for sending mail to users,  but still
   sends mail to operator.  I have also updated the HOWTO with some
   notes about using this facility.
   (Patches sent by: Maja Gorecka-Wolniewicz <M.Gorecka-Wolniewicz@cc.uni.torun.pl>)

  Several calls to Print_job(...) assumed that a file will respond with
   status information,  as would a real printer.  Not a good assumption.
   I wonder where my mind is at somedays...
  The 'Network Grace' timeout should only be used when a server is trying
   to connect - clients should not have to wait.

  I have once again changed the checkpc code to be very very very
   conservative in what it removes from the spool queues.  This will make the
   folks who use netatalk,  etc.  very happy.  The bad news is that files
   put into these directories by other tools will not get removed.  C'est
   la vie,  C'est la guerre...
   (Patches inpiring the changes sent by: "William R. Knox" <wknox@mitre.org>)

  pclbanner had a stupid typeo left over from debugging.
   It wrote debugging information out to /tmp/before
  The 'lpr_bounce' code did not work after the last fix to solve problems
   with Print_job closing files.  Now you can use filters again from lpr.

  I have added the 'wildcard' print queue names and 'incoming_control_filter'
   options.  Together, they implement a way to put options and
   other information into the control file when a job is submitted.
   This method was exploited by Adeel Khurshid <kurshid@cs.odu.edu>
   while at Fujitsu Network Communications,  and is used by the
   'apsfilter' by Andreas Klemm and Thomas Bueschgens.

     Example:
      lp|lp_*:lp=%P@server
      lp|lp_*:server
        :incoming_control_filter=/.../update_z
        :...

   When you use lpr -Plp_landscape_ledger you will actually end up
   sending the job to the lp queue, with the queue name (Q control
   file line) set to lp_landscape_ledger.  This information can be
   used to update the various control file lines.  The LPRng/UTILS/update_z
   file has an example of a script that will do this.  Note that this
   makes the use of the apsfilter utility even easier.
   (Inpired by a control filter by: Adeel Khurshid <kurshid@cs.odu.edu>)

  I removed a couple of bogus entries that I was putting into the
   job control file.  These appear to be holdovers from some testing.
   They were put in but never used.  Strange, that.

  The append_z, prefix_z, and other related Z operations are done
   only when the job is received.  This now allows the job to be
   processed by filters and not have the work undone.  sigh.
   Documentation cleaned up as well.

  The control file processing has been cleaned up and the redunant
   and erroneous (sigh) copy of the control file in the job{} data
   structure has been ruthlessly purged.  I sure wish Ruth worked
   for me,  I seem to be doing so much ruthless cleanup.
   I see the hand of testing and debugging in much of this stuff,
   and the tracking down of memory leaks as well.

  You can now use [^x] in the glob patterns.  Sigh...  The things
   people do when they get the bit in their teeth.

  The LPD support for 'lpq' and 'lprm' requests has been modified so that
   if there are chained queues and each queue is on the server THEN
   I simply call a routine and do not fork a process.  This solves a
   problem with process exhaustion when somebody had a loop in their
   printcap.  I also put in some tests for this.  However, without
   adding Yet Another Option to the LPRM and LPQ stuff I don't see
   how I can do it.

  You can now send up to 'max_jobfiles' (default 52) to the server.
   Note:  you can actually only send 52*52 = 2704
   The data files are given names
     dfAnn -> dfZnn -> dfann -> dfznn ->
     dgAnn -> dgZnn -> dgann -> dgznn ->
     dzAnn -> dzZnn -> dzann -> dzznn ->
     daAnn -> daZnn -> daann -> daznn ->
     deAnn -> deZnn -> deann -> deznn ->
     dAAnn -> dAZnn -> dAann -> dAznn ->
     dZAnn -> dZZnn -> dZann -> dZznn

  There is now support for the HP extensions:
  (Courtesy of Richard Hart USG <hart@zk3.dec.com>,
    who sent me the following information)

     Summary of HP's Extensions to RFC-1179

     1. 4-Digit Job Numbers
     HP preserves the System V-style 4-digit sequence number, or job number, in
     file names and attributes, while BSD uses 3-digit job numbers.

     2. Control and Data File Naming Conventions
     Control files are named in the following format:
        cA<seqn><host>
        <seqn> is the 4-digit sequence number (aka job number).
        <host> is the originating host name.
     The data file naming sequence format is:
         dA<seqn><host>   through   dZ<seqn><host>     followed by...
         da<seqn><host>   through   dz<seqn><host>     followed by...
         eA<seqn><host>   through   eZ<seqn><host>     followed by...
         ea<seqn><host>   through   ez<seqn><host>     ... etc. ...
     So the first data file name in a request begins with "dA", the second with
     "dB", the 27th with "da", the 28th with "db", and so forth.

     3. HP-Specific BSD Job Attributes (Control File Lines)
     The following control file lines are extensions of RFC-1179:
        R<login>
           Write to the named login's terminal when the job is complete.  This is
           an alternate to the RFC-1179-style e-mail completion notification.
           This notification is selected via the lp "-w" option.
  -- R line -> M line
        A<priority>
           Specifies the System V-style priority of the request, a single digit
           from 0-7.
  -- A value -> priority
        N B<banner>
           Note that this line begins with an "N", a space, and then a "B".  The
           argument is the banner page title requested via the lp "-t" option.  If
           that option was not given then the argument is null.
  -- banner -> T banner
        N O<options>
           Note that this line begins with an "N", a space, and then an "O".  The
           argument contains the System V-style "-o" options specified in the lp
           command line.  The option names appear without a leading "-o".  The
           first option name begins in the fourth character of the line; each
           option is separated by a blank.  If no "-o" options were given then the
           argument is null.
  -- <options> -> appended to Zvalue <options>

     The following control file lines are generated differently than in standard
     BSD:
        J<jobname>
           The argument is the System V-style request-ID, for example,
           "printer-42".  Note that leading zeros are not present in the sequence
           number.  If a System V-style title is requested then it is sent using a
           "N B" attribute, and not the "J" attribute.

  There is now a new and improved error message for fumble fingers:
   h4: {1185} % lpq -Pxx
   Printer: xx@h4 - ERROR: spool queue for 'xx' does not exist on server h4.private
      non-existent printer or you need to run 'checkpc -f'
   h4: {1186} % lprm -Pxx
    ERROR: spool queue for 'xx' does not exist on server h4.private
      non-existent printer or you need to run 'checkpc -f'
   h4: {1187} % lpc -Pxx status
    Printer           Printing Spooling Jobs  Server Subserver Redirect Status/(Debug)
   xx@h4: spool queue for 'xx' does not exist on server h4.private
      non-existent printer or you need to run 'checkpc -f'
   I hope that this cuts down on the problems reported by people who do not
   RTFM about 'checkpc -f'.

  I have added code to track the maximum open file descriptor so that
    the 'cleanup' code is a little more intelligent.

Release LPRng 3.6.22 - Sun Jul 23 17:37:02 PDT 2000
  There is yet one more problem with high load levels -
   I did not set the timeout to reasonable value and the lpd server
   goes into a tight loop waiting for it.

Release LPRng 3.6.21 - Sun Jul 16 16:58:19 PDT 2000
  Clean up some Tru64 system warnings about casts.
   (Supplied by: "Justus J. Addiss" <jjaddiss@mmm.com>)
  Seemed to have found a solution to the parallel port problem
   by brutally using fstat() to see if we have a device,  and if
   so, then unless it is a tty, assuming that it is a write only
   device.  This is stupid,  and I just KNOW that when somebody
   adds a USB device I will suffer for this.  When you have a
   'write only' file descriptor,  you just do a 'write' with timeout.
   No select, nothing.  Just a write.  This seems to solve the
   problem.  Oh yes.  You also make sure the file descriptor
   is non-blocking.
   (By:  Patrick Powell <papowell@lprng.com>)
  There is a bizzare problem with doing select for read on some Solaris
   systems with certain patch sets on file descriptors that have
   been set for non-blocking.  The select call will actually return
   and indicate that the device can be read...  But when you do,
   you get -1, and EUNAVAIL or some similar code indicating no data
   to be read.  This is truly bizzare.  To ensure that this does
   not happen,  you must do a select on a nonblocking file descriptor.
   To add injury to insult,  this seems to not be reliably reproducible.
   You really had to be there for this one.  I now set all the file
   descriptors into blocking mode and then do select,  then put them
   in nonblocking mode to do the write or read.
  The mysterious 'lpc reread' killing lpd was discovered to be caused
   by trying to free an already freed pointer, which was garbage.
   This was related to cleaning up the memory leak problem in 3.6.20.
   Sigh...
  I cannot spell krbros... krb5... or kb5... and thus cannot invoke the
   dog in the configuration script.
   (Happily pointed out by:  John Perkins <john@cs.wisc.edu>)

Release LPRng 3.6.20 - Sat Jul  8 12:32:38 PDT 2000
  One of the silly memory leaks that has been reported, tested for,
   analyzed, etc., finally was found.  The problem was in the
   child.c file,  where I keep track of children processes
   by dynamically allocating a list.  While I carefully cleaned
   up the list in children of the main LPD process,
   I never cleaned up the list in the main LPD process.  Thus,
   if you created a large number of children the list would grow
   a small amount (4 bytes) for each child.
   This problem was found by brutally using the 'DMALLOC' debugging
   package,  finding every 'malloc' call in the main LPD process
   and then looking for a matching free call in the main line loop.
   When one was not found for the case where I had 0 processes
   I knew that I had found the problem.  Sigh.
   (Stumbled over after staring at the code for a week by:
      Patrick Powell <papowell@lprng.com>)
  Makefile now checks that POSTINSTALL is 'NO' or 'no'
    (Noted by: Craig Small <csmall@eye-net.com.au>)
  checkpc -C and checkpc -c file removed.  Legacy options and
   I don't know why they were still there.
   (Noticed by: Jesper Dangaard Brouer <hawk@diku.dk>)
  The call to 'Remove_tempfile()' routine was removed from
   the 'cleanup()' when trying to find the above mentioned memory
   leak and was not put back.  Bad Coder! Bad!
   (Found by: A Earle <ae@play.psych.mun.ca>)
  The pclbanner and psbanner had some errors that showed up under
   bash.  Very odd that the ksh and /bin/sh did not whoop on them.
   (Clever debugging by: David Livingstone <davidl@cn.ca>)
  checkpc -r -A was a little too agressive and it blew away all
   sorts of files.  The -r now only works on job files.
   I do NOT remove job files unless the -r -A age options are
   given.  This prevents some problems with jobs being moved
   into a queue just as checkpc is being run from cron.  Sigh...
   Cron.  I forgot all about Cron.
   (Noticed by: Craig Small <csmall@eye-net.com.au>)


Release LPRng 3.6.19 - Sun Jun 25 11:13:35 PDT 2000
  The filter status was not getting used correctly.  This was
   a side effect of trying to clean up aborted jobs and
   accounting.  One step forward, one step back.  Sigh.
  The Tru64 compiler objects to casting pointers to ints, so
   we have to cast to a long THEN to an int.
   (Reported by: Justus J. Addiss <jjaddiss@mmm.com>)
  Did not update the 'Tempfile' variable when I was checking multiple
   print queues.  This meant that it was using a stale queue name.
   Only shows up if the queue directories are on different
   file systems.
   (Spotted by the eagle eyes of: Robin Sommer <rsommer@uni-paderborn.de>)
  Apparently the CHANGES file had 'z_append' instead of 'append_z'.
   So it is changed.  Do we need a Meta-CHANGES file to record changes
   to the CHANGES file?
   (Caused by the readings of: Michael J. Carter <mcarter@lanl.gov>)

Release LPRng 3.6.18 - Mon Jun 19 09:37:04 PDT 2000
  The UTILS/accounting.pl script did not handle malformed
  lines caused by truncation well.   It now does,  but
  insists that you have lines starting with
    start, filestart, end, fileend for status.  This ties
    into ifhp-3.6.15
  Updated the DISTRIBUTIONS/FreeBSD to make the port correctly
  Updated the DISTRIBUTIONS/RPM to make the port correctly
  Changed the psbanner font to a more readable font
   (Artistic criticsm by: Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>)
  Lowercased DNS lookup return values.
   (Need discovered by: Alf Wachsmann <alfw@slac.stanford.edu>)
  Tru64 cc compiler whoops its cookies on void * conversions...
   (Reported by:  Justus J. Addiss <jjaddiss@mmm.com>)

Release LPRng 3.6.17 - Sat Jun 17 15:58:21 PDT 2000
  Analysis of the Setuid Compromise for LINUX done; LPRng
   is only susceptible if a non-root user manages to run a client
   program that in turn runs a program that she has compromised.
   Since the programs run by LPRng and other servers should owned
   by root and not writable,  this would require the compromiser
   to have already modified these - by alreadying having root perms.
   This means that they have already compromised the system.

   Replaced the agressive 'check at all times and costs' with
    a) a configure time check for the 'bad linux kernel'
    b) a run time check done only by clients for a compromise.
    c) not installing LPD setuid ROOT so that it cannot be
       started and used as a compromised process.

Release LPRng 3.6.16 - Thu Jun  8 15:24:37 PDT 2000
  Long numbers and the silly 'is this really and IP address code'
   conflicted.  Fixed it again.
   (Spotted and reported 32 minutes after the release was out by:
      Thomas Vogt <t.vogt@drgueldener.de>)
  Did not check for null pointer, the following printcap was not
    read correctly:
      .junk:
      stuff:tc=.junk  <- ummm... nothing there, CRASH
   (Spotted and reported 30 minutes after the release was out by:
      Justus Addiss <jjaddiss@mmm.com>)
  Changed :as and :ae checks so that you can use :as=/path as well as
    :as=|/path
   (Inspired by comments from: Sree Lakshmi <chinnu@jncasr.ac.in>)
  pclbanner did not work under RedHat.
   (Spotted by:  David Kerr Livingstone <davidl@cn.ca>)
  Goofs in the HOWTO spotted.
   (Spotted by: Zanferrari Domenico <domenico.zanferrari@kone.com>)
  Updated the HOWTO format.  Now using DocBook to generate output.
  RPM packages not generated correctly
  If the -Dxxx option is the VERY FIRST on the command line,
   then you set up the debug options very early in the parsing
   and operation.  This can lead to a GREAT deal of rubbish unless
   you need it.

Release LPRng 3.6.15 Thu Jun  8 15:24:37 PDT 2000
  postinstall.generic.sh was sytactically incorrect.
   (Patch by:  Justus Addiss <jjaddiss@mmm.com>)
  RPM Fixes:
    /usr/docs/LPRng now removed
  Linux (and possibly other) SETUID BUG compromise detection
    added.  The setuid(n) call is supposed to be a one-way trip to
    uid n,  but this can be compromised by users setting
    flags.  Present in kernels before 2.2.16,  and possibly
    other capabilities based systems.  Added a test to make sure
    that this is really a one-way trip.
       As far as I can tell,  this would only be an issue if the
    user had a shell script that was executed by LPRng and the script
    could be replaced by something else.  This is possible in systems
    which are using NFS - I have exercised the compromise and it
    exists.

Release LPRng 3.6.14 Sat May  6 08:46:26 PDT 2000

  configure now has --with-lockfile=path.
   (Courtesy of:  Willi Burmeister <wib@cs.uni-kiel.de>)
   Complete configure options are now:

  --with-cc=COMPILER      select compiler to use
  --with-ccopts=CFLAGS    select compiler command line options
  --with-linker=LINKER    select linker to use
  --with-ldopts=LDFLAGS    select linker command line options
  --with-cppopts=CPPFLAGS  select compiler preprocessor command line options
  --disable-setuid                  disable setuid root client and server executables
  --enable-priv_ports               require connections to be from privileged ports
  --disable-force_localhost         force_localhost default to disabled
  --disable-require_configfiles     client programs require lpd.conf, printcap
  --enable-kerberos                 enable kerberos support
  --enable-mit_kerberos4            enable MIT Kerberos 4 support
  --disable-kerberos_checks         disable kerberos library location and checking for support
  --with-lpddir=DIR                 lpd executable directory (default ${sbindir})
  --with-lpd_conf_path=PATH         path of lpd.conf (default: ${sysconfdir}/lpd.conf)
  --with-lpd_perms_path=PATH        path of lpd.perms (default: ${sysconfdir}/lpd.perms)
  --with-printcap_path=PATH         path of printcap (default ${sysconfdir}/printcap)
  --with-lpd_printcap_path=PATH     path of lpd_printcap (default ${sysconfdir}/lpd_printcap)
  --with-lockfile=PATH              lockfile PATH, default /var/run/lpd
  --with-ld_libary_path=PATH        LD_LIBRARY_PATH value
  --with-filter_path=PATH           filter PATH value
  --with-userid=NAME                run LPRng software as this userid, default daemon
  --with-groupid=NAME               run LPRng software as this groupid, default daemon
  --with-chooser_routine=NAME       load balance queue chooser routine name in user object file
  --with-order_routine=NAME         queue order routine name in user object file
  --with-user_objs=NAME             user specified object file
  --with-user_include=NAME          include file with function prototypes for user object file
  --with-filterdir=DIR              filter directory (default ${libexecdir}/filters)
  --disable-strip                   disable stripping binaries by default
  --enable-nls           use Native Language Support
  --with-included-gettext use the GNU gettext library included here
  --with-catgets          use catgets functions if available

  Terminal clearing now done by using 'clear' program.
   Configure will look for a clear program and LPQ will fork and
   exec it.  If no clear,  then simply send a '^L' or '\014' (form
   feed) to the stdout.  This is due to the horrible support in
   most OS's for curses, termlib, termcap, term...  well,  you get
   the idea.  For a true trip through hell, read the configure
   script for 'vim' and see what they do.  Not for me,  when this
   is only a VERY small part of a much larger system.
   (Changed after finding curses, ncurses, and sys5 curses on
     a system by: Patrick Powell <papowell@lprng.com>)

  Makefile.bsd  is now a VERY small makefile:
    # List the things you want to generate:
    all clean install uninstall:
       gmake $(MAKEFLAGS) $@

    I know that some of the BSD folks will hate me for this,  but
   I have decided that trying to support both types of Makefiles
   and making them work was just too much effort.  Also,  the BSD
   folks now have much better supporort for Gmake in their build
   scripts.  Also, see below... Enhanced Install and Package Creation
   Support.

  Enhanced Install and Package Creation Support
   (Laid at the feet of: Craig Small <csmall@eye-net.com.au>)
    One of the problems that is encountered when trying to build a package
   or do an install is to compile stuff in one directory and then install
   it in another.  The trouble is,  you want to install it in a MIRROR
   directory.
   For example,  you have
    ${SYSTEMSRC}=/private/src,  where the source is,
    ${BUILD}=/var/tmp/BUILD/ where you are going to build all the stuff,
    ${MIRROR}=/var/tmp/MIRROR where you want to place what you created

   The following is generally what is done during distribution creation to
   do this:
     cd ${BUILD}/.../LPRng;
     ${SYSTEMSRC}/.../LPRng/configure --prefix=/usr/local --sysconfdir=/etc
     make
     make install XX=${MIRROR} -> puts thing in
              ${MIRROR}/usr/local
              ${MIRROR}/etc

   After trying 9 (nine) different variations on a theme,  I now have the
   following method to do this:
     make install INSTALL_PREFIX=${MIRROR} POSTINSTALL=NO

   What is this?  The install script/steps will install files in
   ${INSTALL_PREFIX}${prefix}, ${INSTALL_PREFIX}${sbindir}, etc.
   etc., where ${prefix}, ${sbindir}, etc, are hardwired by the
   configure step to the /usr/local/, etc.  Now you might wonder
   why this is done.  The reason is that GMAKE, bless its little
   heart,  will use the $PREFIX environment variable value if it
   is set.  So you cannot do ${PREFIX}/${sysconfdir}  in install
   scripts,  and if you do not set it on the command line,  have
   it put in the right place.

   The POSTINSTALL=NO is used to suppress 'true' postinstallation
   stuff that would copy files into 'unexepect' places, such as
   '/etc/printcap' or '/etc/lpd.perms' or '/etc/lpd.conf'.  Now
   if you are building a system distribution for raw install,
   then you want this to be done,  and you would use:
     make install INSTALL_PREFIX=${MIRROR}

   If you are building,  say a FreeBSD 'package' distribution
   or a RedHat RPM then you would use:
     make install INSTALL_PREFIX=${MIRROR} POSTINSTALL=NO

   Now for all of you who want to make a package and need to find
   the files that LPRng will install,  I suggest you look at the
   following:

     INSTALL_PREFIX=/var/tmp/LPRng  #note that you do NOT export this
     (
    cd $INSTALL_PREFIX;
      mkdir usr/local/bin usr/local/sbin /usr/local/libexec /etc /usr/local/etc/rc.d
        ....
     )
     make; make install INSTALL_PREFIX=${INSTALL_PREFIX}
     (cd $INSTALL_PREFIX;
     find . -type f | sed -e '/man[0-9]/d' \
        -e '/\/info\//'d -e 's/..//'  >/tmp/files
     find . -type f | sed -n -e '/man[0-9]/s,.*man[0-9]/,,p' \
        -e 's/..//'  >/tmp/manpages

   You can now find the non-doc files, manpages, etc. etc. etc.
   and then update the various locations as you need.  Clearly this
   should be done only as root,  on a system where you do not have
   other users running,  where somebody cannot do 'ln -s /etc/passwd
   /tmp/manpages' and so forth.

   For a truly abusive use of this method,  look at the
   DISTRIBUTIONS/FreeBSD* and DISTRIBUTIONS/Solaris* directories.

   Yes,  I have no shame.
   (Put into the distribution after telling people 5 times how
     to use this by:  Patrick Powell <papowell@lprng.com>)

  lpr -U option did not work correctly when UID was root.
    (Patch happily submitted after a long search by:
        Roberto Togneri <roberto@ee.uwa.edu.au>)
  lpd was mangling jobs with more than 26 files - caseless compare
     strikes again.
    (Found with great consternation by: Peter Scheurer <scheurer@sopra-gmbh.de>)
  permissions and filters:
    When you use a filter for "perms_path" was not executed when a
    connection to the lpd is made. So there are no rules then and the
    result of the permission check simply is the default_permission (and
    it results in having no rules for the 'R'-check as well)
    By convention,  a line containing the name of the printer for which
    permission is wanted.  Now a blank line is written for 'X' rules.
    Added capability of filter getting permissions to Setup_printer().
    (Found by: Robin Sommer <rsommer@uni-paderborn.de>)
  lpd_jobs: race condition eliminated at the cost of a high system
    overhead when multiple jobs are spooled to the same queue.
    (Inspired by: Shawna Chase" <chase@crd.ge.com>)
  client connections on Solaris 2.5 systems fail with EADDRNOTAVAIL,
    and need a 'retry'.  Alternative is to use non-priveledged port.
    (Found by: Peter A. Harris <peter.a.harris@exgate.tek.com>)
  innetgr() needs FQDN on some systems, and 'shorthost' on others.
    Added check to do both.
    (Reminded by: Robin Sommer <rsommer@uni-paderborn.de>)
  syslog messages not working.  May need to add 'ordering' test to
    configure for level comparison.
    (Noticed by: Jurgen Northe <juergen.northe@junghans-fwt.de>)
  RFC1179 transfer failures to remote spool queue did not do retries
    correctly.  The 'JFAIL' status was treated as a permanent failure,
    not a temporary.  The 'Service_printer' code now uses the number
    of send attempts to do a retry and backoff on transfer times:
    configuration and/or printcap options:
      send_try:  maximum number of times to send to remote
        (0 = infinite) - default 3
      connect_grace: minumum time between attempts - default 0
      connect_interval: interval between attempts - default 10 sec
      max_connect_interval: maximum time to wait - default 60 sec
        if( attempt > 0 && max_connect_interval > 0 ){
            n = connect_interval * (1 << (attempt-1)) + connect_grace;
            if( n > max_connect_interval ) n = max_connect_interval;
            sleep(n);
        }
    (Discovered by: Christof Drescher <drescher@pro-image.de>)
  Default filter options were missing '$b'.
    (Pointed out by: Jose Carlos Rodrigues Lopes <jrl@europa.fcee.ucp.pt>)
  The md5 authentication support did not return back 'error' status for
    lpr operations.
    (Noticed by: Patrick O'Brien <pdo@cs.umd.edu>)
  The 'IS_OS' macros are now set to the OSVERSION;  this makes tests like
       #if defined(IS_BSDI) && IS_BSDI > 401
    possible.  Sigh...
  The filter_path (PATH environment value for filters) added /usr/contrib/bin
    (Suggested by: Jeffrey C Honig <jch@bsdi.com>)
  UTILS directory needs to be part of the global 'make' so that
    tools are created with the right paths.
    (Discovered when fixing a problem found by: Jeffrey C Honig <jch@bsdi.com>)
  check_for_nonprintable default is now OFF due to 85 distinct problems reported
    by various users.
    (Email that broke the camel's back sent by: John Hawley <jhawley@bgea.org>)
  lp -s was printing status.
    (Discovered and fix by:  Mark.Belton@mgc.com.au)
  proctitle() code was mangling the envp[] - this only showed up if you
    happened to set debug level 6 or higher.
    (Discovered by: Vincent Fox <vincent@cad.gatech.edu>)
  Microsoft now sends the IP address as part of the control
    and data file names.  OK.  We can handle that.
    (Pointed out by: Rainer Schoepf <schoepf@uni-mainz.de>)
  When using a routing filter, the DATAFILES environment variable
    contains the data files.  The routing filter can modify
    the datafiles,  but cannot remove them or truncat them.
  The default for bq_format is now 'f' - i.e. - you  can reprocess
    outputs of bounce queues.  The old default was l (binary),
    which was not processable.
  The 'lpq -s ID' command was not reporting information correctly.
    It always reported the total printable, not the ones selected
    by the options.
   (Discovered by: Patrick Powell <papowell@lprng.com>)
  Retested Kerberos 5 and Kerberos4 stuff with Kerberos 1.1.1,
   found problems with compilation,  fixed them.
   (Helped by: Mike Whitson <mwhitson@MIT.EDU>)
  Updated Version and Copyright information.
  Added configure --enable-kerberos option for folks who need to build
   'non-exportable' binaries.
  Added a '$(INSTALL_PREFIX) entry to the install scripts to allow folks
   who want to install the binaries in a different subtree to do so.
   I might make this 'PREFIX' to fit in better with feedback.
  More fixing of Kerberos stuff - fixed up the problems with different
   uses of krb5_xfree.  Added tests for the krb4des library.
   (Helped by: Mike Whitson <mwhitson@MIT.EDU>)
  The spool_file_perms option was not being used to set permissions for
   files in the spool directory.  Noted in the Debian LINUX bugs list.
   It was also noted that the user was trying to set some very odd permissions
   that would result in a possible security loophole,  but Hey!  I just
   do LPRng...  Users (not the LPD server) use 0600 permissions,  just
   to avoid those nasty security problems.

  Nit pick on man pages: SEE ALSO should not reference same man page.
   (Submitted by: Debian Linux Bug List)

  checkpc now checks for server printcap entries with lp=xxx and rm=yyy
   values.  This way you at least warn the users when they screw up.
   (Good suggestion by: Craig Small <csmall@eye-net.com.au>)

  Moved tests for 'setproctitle' in configure around to deal with some
   problems of libraries being included when they should not have been.

  Fixed up the distclean.  Removed junk files.  Move the LPRng_DOCS
   into the HOWTO,  as there were no other files left.

  Fixed permissions.  Did some fiddling to add easier FreeBSD/NetBSD
   etc. support.  Side effect was that testing install is easier.
   Added a 'INSTALL_PREFIX' to the installation paths that allows
   me to make sure that things go to the right places.

  Move the various distribution specific information into DISTRIBUTIONS
   directory.

  Made the LPRng and ifhp configure.in mainly identical.  Also use the
   same portable.h file.

  Fixed (once again) typeos in the man pages, and the installation
   of compressed man pages.  Sigh...

  Added a 'filter_stderr_to_status_file' flag that causes print filter
   errors to be written to the status file (:ps=file) rather than to
   the status log file.  Also added truncation of the status file.
   (Inspired by : "William D. Colburn (aka Schlake)" <wcolburn@nmt.edu>)

  Discovered, as a result of testing the 'filter_stderr_to_status_file'
   flag that backslash '\' escapes were not being handled correctly
   on the filter line.  Fixed this.

  If a filter has <,>,;, or | in it, or starts with (
    then it is executed by using:
    :if=/.../filter xxx   -> /bin/sh -c '/.../filter xxx'
    This allows you to do things like '/.../filter 2>>status'
    Updated checkpc to check for matching () for filters.

  Modified the src/linksupport/connection() code so that the
   lpq and other clients do not try binding to port 515.  This
   can cause problems when used with Samba.  The code in
   linksupport.c that set SO_REUSEADDR and SO_KEEPALIVE was
   also tidied up.

  lpc -a now works sort of correctly and the documentation has
   been changed to reflect it.

  The LPC=xx permissions checking did not require a 'C' operation.
   Also, cleaned up some message printing.

  Make_passthrough was examined and a couple of changes made to
   handling the case when the filter path contained a meta character.
   The path now has parenthesis put around it.  By default,  this
   form of invocation does NOT have options passed to it.

  Added a '$*' parameter to provide all the default command line
   options.  This now allows you to do:
    :if=(/some/path $* | output filter)

  New functionality: remove_z, prefix_z, and append_z
   (Inspired by a comment by: Richard Kaszeta <kaszeta@me.umn.edu>)
    remove_z=pattern,pattern,...
      remove the -Z option specified by the pattern.
      Example: -Ztest,this,thing   + remove_z=th*,out -> -Ztest
    append_z=option,option,...
      appends this to the -Z options
      Example: -Ztest   + append_z=landscape -> -Ztest,landscape
    prefix_z=option,option,...
      prefixes this to the -Z options
      Example: -Ztest   + prefix_z=landscape -> -Zlandscape,test

    Example of use:
      You want to have a set of queues where you can have the
    queue set the functionality:

    landscape:append_z=landscape:lp=remote@host
    portrait:append_z=portrait:lp=remote@host
       lpr will add these options before the job
     is sent.

     OR you have a 'bounce queue' situation where you
    want to add -Z options as the job goes through:
      portrait:append_z=portrait
         :lp=remote@host:server
      lpd will put these options into the job file
      ON RECEPTION.  Also,  before sending to a remote
      queue as well.  Kinda bombproof, but covers most
      situations.

  If you have force_localhost then you want to connect to
    the server with the primary name of the printcap entry.
    The clients were using the lp=pr@remote pr value instead.

  CONFIGURATION OPTION:  ld_library_path and filter_path
    you can set these values through configure.

  Portability Support:  DISTRIBUTION directory and init files

    Put the init scripts for various OS's in the main directory.
    This helps the poor administrator who is trying to figure
    out what init script he needs.

    Gathered up all of the various system dependency stuff and put
    it in one big directory.

  Fixed up the DISTRIBUTION/Solaris.pkg stuff

  The 'subserver' queue management now works.  The problem was that
    the main queue server process had to fork a subserver process
    for the subserver queue,  and it could not tell that the subserver
    queue had been changed.  The following solved this:
     a) in the lpd_control.c code, if the queue is a subserver
        queue,
        1. I set a 'changed' flag in the spool control file.
        2. I send a SIGUSR1 signal to the process that is the server
           for the subserver queue.
        3. If that signal is unsuccessful, then I send a SIGUSR1 signal
           to the main queue process.
        4. If that signal is unsuccessful I restart the server
    b) in the lpd_jobs.c code, in the Process_jobs() routine:
        1. I check to see if this queue has subservers,  and then
           check the subserver queues.  If the 'changed' flag was set or some
           other reason exists to start the subserver, I start a
           subserver process.
        2. In the main queues 'wait for work' loop,  when I get a
           'SIGUSR1' I scan the subserver queues and check to see
           if their 'changed' flag is set.
           If it is set AND there is no subserver process THEN I will
           start a server process.  Otherwise I wait until the subserver
           process exits.
        3. In the main queues 'wait for work' loop,  when I look for
           a free subserver queue to use AND I find one which is
           available AND it has a change flag set THEN I start a
           subserver process.
     As you suspect,  this was NOT a simple set of changes.
    (Painfully debugged by: Patrick Powell <papowell@lprng.com>)

  Kerberos Fix From MIT: added auth=none support, and allow default
    principal lookup.
    (Patch by: Robert A Basch <rbasch@MIT.EDU>)

  FreeBSD port/package support, Solaris pkg support, RPM (RedHat) Support
    The configuration, build, and install process has been modified
    to better support package generation.  (I know, it is a dirty business
    and I am trying to make it easier for the vendors.)

    I have been driven to this by problems that people have with installing
    stuff for the first time,  and the rising level of 'Did not RTFM'.

    a)  postinstall script selection
        The last step of the make install process is to find
      a 'postinstall' file and execute it.  The file is chosen by
      looking in the configuration directory for a suitable file.
      The file is found by using the 'OSNAME' value found by the
      configure script.  Linux is a special case - mainly because
      I tested several versions and found that they had different
      'linux-this' and 'linux-that' suffixes.
        I also locate a 'preremove' script and do the same selection.
      There is a default 'postinstall' and 'preremove' script as well.

        OSNAME=${OSNAME}; case "$${OSNAME}" in *linux* ) OSNAME=linux;; esac; \
        echo "OSNAME orig $(OSNAME) '$${OSNAME}'"; \
        s=`ls postinstall.$${OSNAME} 2>/dev/null`; \
        echo POSTINSTALL "'$$s'"; \
        if test -n "$$s" ; then cp $$s postinstall; fi; \
        s=`ls preremove.$${OSNAME} 2>/dev/null`; \
        echo PREREMOVE "'$$s'"; \
        if test -n "$$s" ; then cp $$s preremove; fi;

     b) postinstall script execution
        If the POSTINSTALL option is not NO, then I execute the postinstall
      script as the last step of the 'install' process:

    if [ "${POSTINSTALL}" != "NO" ] ; then
        MAKEINSTALL=YES INSTALL_PREFIX=$(INSTALL_PREFIX) $(SHELL) postinstall ;
    fi;

       Note that the 'MAKEINSTALL' environment variable is set to YES.
       This can be used to determine that the postinstall script is being
       executed by the 'make install' step.

     c) "pseudo root" or "PREFIX" support

       I have put a "${INSTALL_PREFIX}" variable at all points where
       a normal script would have a target.  Thus if you do:

           mkdir /var/tmp/LPRng-root
           make install INSTALL_PREFIX=/var/tmp/LPRng-root

       you will find that all of the files are now put in sub
       directories of /var/tmp/LPRng-root.  You can now do:

       (cd /var/tmp/root; find . -type f -ls ) >/tmp/files
       (cd /var/tmp/root; find . -type d -ls ) >/tmp/directories
       cat /tmp/files | grep 'man[0-9]' >/tmp/manpages
       cat /tmp/files | grep '/doc' >/tmp/doc
        and so forth.  Your Imagination and Creativityy Ma Vary
      (YIACMV).  It is left as an exercise for the student on how to
      use this with their favorite (Ummm... ok - least hated) package
      method to generate a %files, pkg/PLIST,  packinglist, etc. etc.,
      for use in package generation.

     d)  sample 'init', 'preremove', and 'postinstall' scripts.
      I have ruthlessly taken example scripts for FreeBSD, BSDI,
      and RedHat Linux and put them in the root directory so that
      people can see these scripts.

     e) If you want to see how to use these, look in the DISTRIBUTIONS
     directory.

     Here is the postinstall.freebsd.sh : - comments are marked with *** ....

     # FreeBSD Convenience Script for Source Install
     # -- START --
     # CHANGES,v 1.1 2001/08/21 20:33:14 root Exp
     #
     #  If you are building a PORT, see the
     #  DISTRIBUTIONS/Freebsd directory for a complete port
     #  building package.
     #
     # This is the shell script that does the postinstall
     # dynamic fixup
     #  It needs to be massaged with the information for
     #  various paths.
     # If you are building a package,  then you do NOT want
     #  to have this executed - it will put the sample files
     #  in place.  You need to do this during the postinstall
     #  step in the package installation.
     #
     echo RUNNING postinstall.freebsd.sh PACKAGE="$PACKAGE" MAKEINSTALL="$MAKEINSTALL" PREFIX="$PREFIX" cwd `pwd`
        **** you can remove this,  but it sure helps when you are trying to
        **** figure out what is happening.
     ****  - fix is used to put the /etc/lpd.conf, /etc/lpd.perms, and /etc/printcap
     ****    or their variants into place.  This is truly ugly,  as there is
     ****    no easy way to do this well.  You first assume that you will have at
     ****    build time a file with the name 'lpd.conf' (for example) in the
     ****    current directory.  If you have this,  then you copy it brutally to
     ****    the destination, $TARGET/lpd.conf.sample and,  if there is not an existing
     ****    $TARGET/lpd.conf file.
     ****
     ****    Now we get into some ugly stuff.
     ****
     ****    When doing a package install,  you will want to copy the package version's
     ****    of this file into the same place.   But we do not want to overwrite the
     ****    existing lpd.conf, as it will break existing printing.  Note that this
     ****    is exactly what happens with RPM - it clobbers the existing config file,
     ****    and widdles by telling you about it.  Right.  Who reads all of the rpm output?
     ****
     ****    So here is what we do.  We will force a package to have only the
     ****    lpd.conf.sample file, and we will COPY it to the right destination.
     ****
     ****    The FreeBSD port/package system functions by having a pkg/PLIST file
     ****    that contains all of the files we will put in the package.  If you have
     ****    done 'make install INSTALL_PREFIX=/var/tmp/LPRng'  you will get all the
     ****    files installed in the /var/tmp/LPRng, and now can simply use file to
     ****    list them.  For an example,  see DISTRIBUTIONS/FreeBSD/Makefile and
     ****    the 'make plist' target.   I call this a 'chroot' image, cause it is
     ****    (hopefully) the same as though you did a 'chroot' to the $INSTALL_PREFIX
     ****    directory.
     ****
     ****    Unfortunately,  this simple picture breaks down when somebody decides
     ****    to use the 'PREFIX' facility of the package/port installation facilty.
     ****    So we add yet another wrinkle to this.  Use:
     ****    'make install INSTALL_PREFIX=/var/tmp/LPRng PACKAGE=YES'
     ****    when you are generating a 'chroot' image.  Then you test for this in the
     ****    script and put things in a nice place when you are making a package,
     ****    and then forcefully reinstall them.

     fix () {
        v=`echo $1 | sed -e 's/[:;].*//'`;
        p=`echo $2 | sed -e 's/[:;].*//'`; d=`dirname $p`;
        if expr "$p" : "|" >/dev/null; then
            echo "$v destination is filter - '$p'"
            exit 0;
        fi
         echo "Checking for $p in $d"
        if [ ! -d "$d" ] ; then
            echo "Directory $d does not exist!"
            mkdir -p $d
        fi
        if [ -f $v.sample ] ; then
            if [ $v.sample != $p.sample ] ; then cp $v.sample $p.sample; fi
        elif [ -f $v ] ; then
            if [ $v != $p.sample ] ; then cp $v $p.sample; fi
        else
            echo "Do not have $v.sample or $v"
        fi
        if [ ! -f $p.sample ] ; then
            echo "Do not have $p.sample"
        elif [ ! -f $p ] ; then
            cp $p.sample $p;
            chmod 644 $p;
        fi;
     }
     # we use the /usr/local/etc/rc.d method to start lpd
     echo "Installing configuration files, cwd " `pwd`
     # we have to take them from one place and put in another
     if [ "X$PACKAGE" = "XYES" ] ; then
        # we put files into the destination
      ****  when we make a package,  we need to put the files in the
      ****  ${PREFIX}/.... location to be FreeBSD standards compatible
         fix lpd.perms "${INSTALL_PREFIX}${PREFIX}/etc/lpd.perms"
         fix lpd.conf "${INSTALL_PREFIX}${PREFIX}/etc/lpd.conf"
         fix printcap "${INSTALL_PREFIX}${PREFIX}/etc/printcap"
         init=${INSTALL_PREFIX}${PREFIX}/etc/rc.d/lprng.sh
         echo "Setting up init script $init using init.freebsd"
         if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi;
        cp init.freebsd $init
     elif [ "X$MAKEINSTALL" = "XYES" ] ; then
      ****  OK, now we are doing a make install - this could be a
      ****  real install by the user,  or the deadly 'make install'
      ****  done by the port package Makefile generation.  But
      ****  we know what to do:  install it in BOTH places.  This will
      ****  always end up with a copy in .../lpd.perms,  and perhaps
      ****  an extra copy as well in perhaps /usr/local/etc/lpd.perms

         fix lpd.perms "${INSTALL_PREFIX}${PREFIX}/etc/lpd.perms"
         fix lpd.conf "${INSTALL_PREFIX}${PREFIX}/etc/lpd.conf"
         fix printcap "${INSTALL_PREFIX}${PREFIX}/etc/printcap"
         fix lpd.perms "${INSTALL_PREFIX}${LPD_PERMS_PATH}"
         fix lpd.conf "${INSTALL_PREFIX}${LPD_CONF_PATH}"
         fix printcap "${INSTALL_PREFIX}${PRINTCAP_PATH}"
         init=${INSTALL_PREFIX}${PREFIX}/etc/rc.d/lprng.sh
         echo "Setting up init script $init using init.freebsd"
         if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi;
        cp init.freebsd $init
         chmod 744 $init
        echo "Stopping LPD"
        pid=`cat ${LOCKFILE}* 2>/dev/null`;
        if [ -n "$pid" ] ; then kill -INT "$pid" 2>/dev/null; fi
        if [ -n "${KILLALL}" ] ; then ${KILLALL} 2>/dev/null; fi
        # check the printcap information
        echo "Checking Printcap Info and fixing permissions"
        ${SBINDIR}/checkpc -f
        # restart the server
        echo "Restarting server"
        sh $init start
     else
       ****  OK, this is done when we do a package install.  You will
       ****  be amazed to discover that the ./etc/lpd.perms file is now
       ****  present here - so you can install this.  Gahh... The reason
       ****  for this seems to lie with the way that the package/port
       ****  mechanism works.  If this is changed,  then it is back to the
       ****  trenches to find out where and if the file location has
       ****  changed.

        # when doing an install from a package we get the file from the package
         if [ -f etc/lpd.perms.sample ] ; then
             fix etc/lpd.perms "${LPD_PERMS_PATH}"
             fix etc/lpd.conf "${LPD_CONF_PATH}"
             fix etc/printcap "${PRINTCAP_PATH}"
             init=etc/rc.d/lprng.sh
             echo "Checking init script $init"
             if [ ! -f $init ] ; then
                 echo "WARNING: $init missing!"
                 exit 1
             fi;
             cp $init /usr/local/$init
             chmod 744 $init
         else
             echo "WARNING: configuration files missing from package!"
         fi
     fi

  Here is the postinstall.linux.sh:

    # LINUX/RedHat Source Installation Convenience Script
    # -- START --
    # CHANGES,v 1.1 2001/08/21 20:33:14 root Exp
      *** same as above
    fix () {
      *** same as above
    }
    echo "Installing configuration files"
    init=${INSTALL_PREFIX}/etc/rc.d/init.d/lprng
    if [ "X$MAKEINSTALL" = "XYES" ] ; then
        if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi;
        cp init.linux $init;
        chmod 744 $init
        fix lpd.perms "${LPD_PERMS_PATH}"
        fix lpd.conf "${LPD_CONF_PATH}"
        fix printcap "${PRINTCAP_PATH}"
    else
        *** this is tricky ....
        fix "${LPD_PERMS_PATH}" "${LPD_PERMS_PATH}"
        fix "${LPD_CONF_PATH}" "${LPD_CONF_PATH}"
        fix "${PRINTCAP_PATH}" "${PRINTCAP_PATH}"
    fi
    if [ "X$PACKAGE" != "XYES" ] ; then
        echo "Configuring startup scripts"
        if [ ! -f $init ] ; then
            echo "Missing $init";
        fi
        if [ -f /etc/redhat-release -a -f /sbin/chkconfig ] ; then
            echo "RedHat Linux - running chkconfig"
            /sbin/chkconfig --del lpr
            /sbin/chkconfig --add lprng
            echo "Starting Printer"
            sh $init start
        else
            echo "Hand install the configuration files"
        fi;
    fi;

   Cleaned up the 'Make_passthrough' use by having a single
    'Filter_file' routine.  Problems of unclosed file descriptors
    disappeared.   Sigh...

   Discovered that the 'generate banner' code was not working, and
     has probably not worked since 3.5.4.  Shows how many people
     use this.  Fixed.

   Discovered that the 'af=|/...' option caused 'orphaned' children
     which would hang around until the main lpd server process
     exited.  Problem unsolvable on the systems where the problem
     exits.  The :as and  :ae provide better functionality for
     this case.

   If you have an OF filter and one of the other filters dies,
    then you invoke the final OF filter,  even though the job
    will exit with an error.  This allows you to do some cleanup
    in the OF filter.  Implemented by modifying the common/printjob.c
    code so that it did a 'goto end_of_job' rather than 'goto error'.
    I wonder why I did not see this before.

   Fixed a really dumb idiot problem with portability.  I simply do
    not allow lp=|/filter on systems without the 'socketpair'
    function.  Sigh...  There must be a way around this but I can't
    see one.

   Added a 'JSUSP' to the error codes.  Sigh...  Needed this to
    indicate that a filter had suspended itself correctly.

   Check the size of the status file before writing - this adds one
    fstat() call per write,  but you don't update the status file
    very often.
    (Pointed out when his status file filled up the /var spool
      directory by: Dmitry Bely <dbely@mail.ru>)

  We don't steal,  we borrow:  the :sh flag in the printcap causes
   lpr to act like the -h (no header) flag was present.
   (Showing the tattered edges from cutting it out of the
     the FreeBSD lpr code, sent by: Garance A Drosihn <gad@eclipse.acs.rpi.edu>)

  pclbanner and psbanner now back in /bin/sh.  Sigh.  Some supported
   systems do not have Perl.
    (Grudgingly ported to /bin/sh scripts by:
      Patrick Powell <papowell@lprng.com>)

  The printcap 'x:' is now a real printcap.  You use the default
    entry values for it.  Strange how this one did not get caught
    earlier.  The 'lpc client x' and 'lpc server x' now looks up the
    wildcard as well as the normal information.  And finally, checkpc
    will squawk if you try to use a wildcard as a queue name,
    rather than an alias.

  You can now do run time load balancing using user specified program
   OR a built in filter.

   Printcap/configuration option:
     chooser=/path/to/program
         STDIN = list of queues to choose from, one per line
         STDOUT = single queue to use
              (if none, job is skipped)
       exit code: == 0 handle job and put it into specified queue
           if any
                  != 0 treat job as though error code was returned
                       for processing.  Allows job to be held, etc.
     chooser_routine
       chooser_routine@  - default - do not use chooser routine
       chooser_routine   - use chooser routine

       configure --with-chooser_routine=name --with-user_objs=objectfile.o
          defines the CHOOSER_ROUTINE compilation option to name
          includes the objectfile.o in the library.

      routine usage is described in common/user_objs.c

      Now you can have a very optimized routine that will do all sorts
       of horrible things.  Enjoy.

  You can now do queue ordering using a user provided routine

     order_routine
       order_routine@  - default - do not use order routine
       order_routine   - use order routine

       configure --with-order_routine=name --with-user_objs=objectfile.o
          defines the CHOOSER_ROUTINE compilation option to name
          includes the objectfile.o in the library.

      routine usage is described in common/user_objs.c

      Now you can have a very optimized routine that will do all sorts
       of horrible things.  Enjoy.  Note that the overhead for a filter
       was horribly high and I could not come up with a clean interface.
       Besides, if you are mucking around with this stuff, you better
       make sure you know what you are doing.  See the user_objs.c
       and LPRng/src/common/getqueue/Make_sort_key() for details.

  When you did a redirect of a queue, would not move the jobs in
   the queue.  This is now fixed.

  Updated the printcap.5 man page so it is a bit closer to reality.

  Finally got slammed with a 'blank page' of output once too
   often.  The ':sf' (supress form feeds between job files) flag
   is now history.  If you need a form feed between a job file,
   then use 'ff_separator'.

  Yet another version of the UTILS/accounting.pl file.

  The client -A option (use authentication) now selects the authentication
  type from the AUTH environment variable.

Release LPRng 3.6.13 Fri Jan 28 08:03:07 PST 2000
  MIT Kerberos support:  added code to detect when sending job to server
   and the server name is 'localhost'.  This requires a special ticket
   lookup to get the right ticket,  as there is no lpd.localhost ticket,
   only lpd.servername.
   (Supplied by: Mike Whitson <mwhitson@MIT.EDU>)
  src/Makefile.in:  ln ${STRIP} -> ln -s
   (Noticed by: Mike Whitson <mwhitson@MIT.EDU>)
  The filter $- specification did not handle $-/xxx and $-root/xxx
   correctly.
   (Spotted by: Simon Wilkinson <sxw@dcs.ed.ac.uk>)
  When using 'user' or 'custom' authentication,  lpr errors were
   not printed out.  This was due to common/sendjob.c:Send_auth()
   not setting non-zero return status when there were error conditions.
   (Reported by: Patrick O'Brien" <pdo@cs.umd.edu>)
  man/install-sh missing, and ifhp src/install-sh as well.
   (Reported by: Bill Kemp <bkemp@srp.gov>
  LPRng/Makefile.in referenced the wrong location for lpd.conf and lpd.perms
   sample files.
   (Spotted by:  Marty Leisner <leisner@sdsp.mc.xerox>)
  LPD: now do accept in the main lpd process, and this time we brutally
   send a message to the remote end if we cannot fork the child
   process.
  Some linksupport.c routines modified to NOT close sockets on
   error condition.  This allows us to try to read additional error
   information from the remote system.
  Tested the kerberos5 authentication with kerberos-1.0.5.  Fixed
   sserver.c and sclient.c.
  LPRng-HOW corrected.  Filters only get SIGINT and SIGCONT sent
   to them to kill them off.
   (Spotted by: Robin Sommer <rsommer@uni-paderborn.de>)
  Authentication support code rewritten to support error message and status
   returns.  Also,  added error messages and status reports.
  lpd started too many servers.  The Get_max_server() code returned
   the maximum number of server processes that should be running,
   and I would try to start this number.  This would lock up the system
   until one had exited.  Now I start up max_servers - 4 at most
   at startup time.  This is still high,  but seems to work.
  lpq.c: missing argument to plp_snprintf()
    (Patch by: Craig Small <csmall@eye-net.com.au>)
  The environment variables passed to filters were not getting their
    escaped characters expanded.  Thus, PATH=xx\072xx\072xx was
    getting passed instead of PATH=xx:xx:xx
  The default lpd.conf has been fixed so that it has escaped values for
    : instead of : in the file.
  Some filters require a killpg() AND a kill(SIGINT) AND a kill(SIGCONT)
    to die.  Next it will have to be garlic and a stake... Sigh.
    (Noted by:  Peter Scheurer <scheurer@sopra-gmbh.de> )
  The translate_format and translate_incoming_format options can now have
    '*f' entries - the * matches all formats.  This would translate all
    file formats to f.

  The LPRM forward in common/lprm.c did not pass the user's name correctly.
    (Found by: John Perkins <john@cs.wisc.edu>)
  Reformatted LICENSE so that the words GPL are in the first lines
    so that people can tell right away.
  Updated dates to match Jan, 2000
  LPQ and LPRM commands were not being forwarded correctly.

  RADICAL CHANGE IN CODE ORGANIZATION:
    In the next major release I will be restricting authentication to
  code modules only,  and users will have to write (gasp!) C code to do
  this.  This is due to the problems with adding various types of
  encryption, etc., which are not well supported by shell scripts,
  etc.  (I won't discuss the legal issues, these are ugly.)

    The following restructuring of the Authentication API has now been done.
  a) Printcap, lpd.conf information
     The auth=xxx and auth_forward=yyy set the type of authentication
    to be used by the sender.  The auth=xxx is used by the clients
    to communicate with the server and the auth_forward for server to
    server communication.
  b) for each authentication type there is an unlimited amount of configuration
    stuff available now.  The configuration/printcap entries have the
    format xxx_key.  The xxx_id entry is used by clients to identify the
    id of the remote server that they are to use for authentication type
    xxx.  When the server accepts a connection,  it will use the xxx_id
    value as its 'key' or whatever for the connection.  Similarly,  when
    doing server to server communication,  the xxx_forward_id is the
    id of the remote server;  the remote server will still use xxx_id.
    The reason for this has to do with printcap organization.  You want
    to have both entries present in a printcap,  one for a client to send
    to the server, and the other for the server to forward to another
    server.
      You should note that this will break down a little bit when you
    have bounce queues.  Since there is only one xxx_forward_id available
    for all of the destinations,  all of the destinations will need to
    use the same xxx_forward_id value.  This problem will have to be solved
    at the authentication module level,  probably by not using the xxx_id
    and xxx_forward_id for anything but advisory information.
      For backwards compatibility, kerberos can also use kerberos_server_principal
    and kerberos_forward_principal instead of kerberos_id and kerberos_forward_id
    respectively.
  c) for server to server authentication,  use the 'auth_forward=type' to
    set the authentication type for forwarding.
  d) For example, to use kerberos authentication the client printcap
    entry would have:
        auth=kerberos
        kerberos_id=lpr/lpr@server.host  OR
        kerberos_server_principal=lpr/lpr@server.host
        kerberos_service=lpr
        kerberos_life=...   (this are usually not used)
        kerberos_renew=...  (this are usually not used)

    The server printcap entry would have:  (note no 'auth=' stuff used)
        forward_auth=kerberos    (to use kerberos to forward)
        kerberos_id=lpr/lpr@server.host  OR
        kerberos_server_principal=lpr/lpr@server.host
        kerberos_service=lpr
        kerberos_life=...   (this are usually not used)
        kerberos_renew=...  (this are usually not used)
        kerberos_keytab=/etc/krb5.keytab
        kerberos_forward_id=lpr/lpr@anotherserver.host

    In addition,  you will find that PGP authentication has been more fully
    supported.
      CLIENTS:  use environment variables
        PGPPASSFILE = location of a file with the PGP password
        PGPPASSFD   = fd to read the password from (very very rarely used)
      Client Configuration:
        auth=pgp
        pgp_id = pgp id of the server, used to get server key from key ring
        pgp_path = /...  - path to PGP executable on user system

      Server Configuration
        pgp_id = pgp id of the server, used to get server key from key ring
        pgp_path = /...  - path to PGP executable on server system
        pgp_server_passphrasefile = file containing passphrase to be used by server
           to unlock key file
         Server keyring files are in the server user home directory,
        i.e. - if server runs as 'daemon' it is ~daemon/.pgp/pubring.pgp and
        ~daemon/.pgp/secring.pgp.  Don't fight it.

    Note that user level authentication using shell scripts is still there,
    but I am making it hard to use.  Don't use it.  Evil.  Bad.  See the
    notes below on how to add C code to do this.

   And I have added some interesting code to use md5 authentication and
    shared secrets:
      CLIENTS:  use environment variables
        MD5KEYFILE  - file containing md5 keys format is:  name=key.
      keys are currently 16 chars long - the ASCII values are used
      to set the 'key' value.  Yes, yes, I know there are only approx
      76**16 = 5 * 10*29 possible keys using this.  Tough.  A key for the
      user name (login name) and the md5_id need to be present

         Example:
         User Keyfile
           # from the configuration information: md5_id=key
           # we use 'key' to look up the host information
           # the entry has the format '[user_auth] salt'
           #  if user_auth is present then it will be used as the
           #  'from' or 'client' information.  The recipient will use
           # this value to look up the corresponding hash key value in
           # servers keyfile
           #key  = user_auth   salt
           lpr@h4=papowell-h4  xx01223750adfj9098789sdfadf
           lpr@h5=papowell-h5  asdfu189asdfasdfasdfasdfasd

        Server Keyfile (host h4)
           #key  = user_auth   salt
           # user key
           papowell-h4=xx01223750adfj9098789sdfadf
           # key for forward transfer to host h5
           lpr@h5=lpr-h4 adfa9ipioasdfasdfjklsf
           # key for forward transfer from host h5
           lpr-h5=adfa9ipioasdfasdfjklsf

        Server Keyfile (host h5)
           #key  = user_auth   salt
           # user key
           papowell-h5=asdfu189asdfasdfasdfasdfasd
           # key for forward transfer to host h4
           lpr@h4=lpr-h5 adfa9ipioasdfasdfjklsf
           # key for forward transfer from host h4
           lpr-h4=adfa9ipioasdfasdfjklsf

        Configuration:
          auth=md5


    Just to make life interesting,  I have also added a demonstration
      of how to do md5 signing and authentication.

   e) Code reorganization
       The LPRng/src/common/sendauth.c and LPRng/src/common/lpd_secure.c
    files have the following stuff added at the end.

  #define SENDING
  #include "user_auth.stub"

   struct security SendSecuritySupported[] = {
      /* name,       config_tag, connect,    send,   receive */
      { "kerberos4", "kerberos", Send_krb4_auth, 0, 0 },
      { "kerberos*", "kerberos", 0,           Krb5_send },
      { "pgp",       "pgp",      0,           Pgp_send },
      { "user",      "user",     0,           User_send },
  #if defined(USER_SEND)
  USER_SEND
  #endif
      {0}
  };

     This is an example of how you add user level stuff for encryption
   and not go to jail for international arms smuggling.  The "user_auth.stub"
   file contains the source code for the various modules, or you can put the
   source code in another file and link it in.  This is recommended when you
   want to use a dynmically loadable library and ship the library. (Note:
   yes, I looked at loadable modules a la Apache,  but LPRng runs on systems
   that do not support this, so I gave up.  This is the older method from
   other real time software that seems to work.)

     The data structure has the name of the authentication, used with the
   auth=xxx tag.  The name field corresponds to the xxx value.

     The config_tag is used to do lookups in the various configuration and
   printcap files to get values.  Why not make them the same?  As you see
   in the example, we have kerberos4 and Kerberos 5,  but we use different
   support routine with the same key values.  Backwards compatibility is
   thus assured.  Oh, yes. Note that you can use wildcards for the name value.
   The connect, send, and receive fields are the support routines that are
   used for handling encryption.

   connect:  make a connection,  fumble around and do authentication,
    and then return.  Kind of like a 'connect' call,  but does handshaking.
    Note that the data link and other stuff is handled by LPRng.  Very
    lightweight and fast.

   send: this is an alternative to connect.  The routine is handed a file
    that it packs up and then sends to the remote end.  In response
    it gets data back that it will unpack and deliver to the user as
    status or error messages.

   receive:  this routine is called when the LPD server gets an authentication
    request.
      If the 'connect' routine is used,  'connect' sends a magic
    string to the server that will cause it to call this routine.  The routine
    will do the hand shaking,  and then return.  The normal LPD service
    routine will take over.
      If the 'send' routine is used,  this routine will get the stuff sent
    by the remote end, unpack it, or what ever is appropriate,  and then
    call the LPD service routine.  By convention, it passes the routine
    a file to put its error messages, etc., into.  When the routine returns,
    the file contents are packaged up and sent back to the server.

     Note:  Kerberos4 :  uses connect / receive
            Kerberos5 :  uses send / receive
            PGP       :  uses send / receive
            MD5 'send':  uses send / receive
            MD5 'con' :  uses connect / receive

   The source code for PGP authentication is in LPRng/common/linelist.c
   (don't ask).  You can get an idea of how to add more authentication by
   looking in LPRng/common/user_auth.stub for excruciatingly detailed
   discussions and examples.

   The #define SENDING controls what stuff in the user_auth.stub
   gets included.  If you look in the sample file,  you will find:

   #if defined(SENDING)
   extern int md5_send();
   #  define USER_SEND \
      { "md5", "md5", md5_send, 0, md5_receive },
   #endif

   This little bit of code causes the prototype md5_send() to be put in place,
   and then the USER_SEND to be defined.  Note that in the original file (send_auth.c)
   that this is used in a table to insert the correct authentication stuff.

   Enjoy.

Release LPRng 3.6.12 Tue Oct 26 16:59:35 PDT 1999
  AIX does not like control files where Nxxx comes before data file lines.
   Added a 'nline_after_file' option to cause LPRng to put Nlines after
   data file lines.
   (Noticed by: Nik Conwell <nik@bu.edu>)
 configure - kerberos libraries are now specified at the start
   of the library list (LIBS="-lkrb5 $LIBS")
   (Suggested by: John Perkins <john@cs.wisc.edu>)
 Typo caused LPD not to read the permissions file.
   (Noticed by EVERYBODY,  but first by: Patrick O'Brien" <pdo@cs.umd.edu>)


Release LPRng 3.6.11 Sun Oct 24 13:37:44 PDT 1999
  Permissions checking: SERVICE=* was not getting handled correctly.
   (Found by: Dejan Ilic <svedja@lysator.liu.se>)
  Jobs with more than 26 files were quietly being mangled.
   (Found by: Derek Masseth <dmasseth@u.arizona.edu>)
  lp simulation now returns a 'job identifier' consistent with
   Solaris 2.5 format.
   (Noticed by:  Martin Mokrejs <mmokrejs@natur.cuni.cz>)
  Added support for case sensitive key lookup in sorted lists.
   (General cleanup and tidy: Patrick Powell <papowell@lprng.com>)
  Set_linger() (setsockopt socket linger timeout) failure is
   now ignored,  rather than treated as failure.  This now
   handles the case where pipes are actually second class citizens
   and the operation fails.  Note that this probably could
   be fixed by testing the file descriptor for type and then
   determining the exact socket type,  but this is NOT portable.
  Set the default paper size for the IFHP-HOWTO to letter.
   The psutils package can be used to resize this for a4, which
   is slightly larger.
  Did horrible things to job reception to handle jobs with
   spaces and more bogus entries in the name fields.  This
   is really strange.  Note: still one quirk - if the server name
   has a space in it AND the job is originated on the server,
   THEN the originating host is set to 'localhost'... which is
   correct but may be odd when forwarding to another system.
  Compaq AKA DEC True 64 support added - configure.in now does
   odd things to detect correct libraries to be used to get
   gethostbyaddr() support.  Portablility.
  configure --disable-strip will disable stripping of binaries.
   (Requested by: Marty Leisner <leisner@sdsp.mc.xerox.com>)
  Permissions, 'SERVICE=P', and job removal:
   if a print job gets through the 'R' (lpr job sumission) checking,
   and gets into the queue,  there is another check ('P' or print
   time checking.  This was done to subdue complaints from systems
   which could not handle a 'no permssions' error and would sit
   there endlessly trying to send the same job to the printer
   queue, and other users would not get their jobs through.

   When a job is ready to be printed and fails the 'SERVICE=P'
   permissions check,  it is now removed and not printed,
   UNLESS the 'save_on_error' flag is set,  in which case it
   is marked with a permissions error and left in the queue.

   Note 1:  the lpd.perms file has been updated to reflect this
   behavior.
   Note 2:  the HOWTO has been updated to reflect this behavior.
   Note 3:  if you have a DEFAULT REJECT in your lpd.perms,  this
   means that no jobs will get printed. :0).  Enjoy.

  Set the 'SO_KEEPALIVE' option on sockets to force keepalives to be
   sent so that dead connections would be detected.
  Updated some code in the common/lpd_remove.c file to close a small
   timing race condition for job removal.  Sometimes a job would get
   removed and the server process would not be killed.  Note that
   the kill is done by sending SIGINT to the processes.
  Changed a int to double for file length in common/lpd_rcvjob.c.
  Modified UTILS/cheap_lpr and UTILS/LPRng.pm to handle more than
   one file in print jobs.
  Checked out a few problems with PGP and user specified authentication.
   (Spotted by: Patrick O'Brien" <pdo@cs.umd.edu>)
  LPQ - use the file name information if no 'J' (job) line in control
   file, and finally "NULL" if no information. This prevents many scripts
   from breaking.
  getqueue.c:Get_datafile_info() was not getting the N,U, and format
   values correctly under all circumstances,  i.e. - duplicates,
   out of order N lines,  totally bogus or missing N information.
   What a mess.
   (Spotted and patch by: Edwin Lim <elim@research.att.com>)
   (And lots of others, with comments, flames, and snickers as well.)
  Fixed a problem when you used a filter to get printcap information,
   and you did a recurive get,  and you had a tc=xxx entry.
   (Spotted and debugged by: Simon Wilkinson <sxw@dcs.ed.ac.uk>)
  configure --enable-priv_ports action was reversed...
   (Spotted by: Robert Montjoy <Rob_Montjoy@ececs.uc.edu>)
  Warning message about '@' in a printcap name was malformed.
   (Spotted by: Andreas Kahnt <ak@m-ebert.de>)
  Added a 'tc_only' flag to allow printcaps to be explictly
   marked for 'tc=name' use only.  This allows people using
   NIS, NIS++, and other database engines to put printcap
   information in database forms.
  Now 'checkpc -P printer' will only check specified printer.  Handy
   for 'checkpc -f -P printer' type of operations when you add a
   new printer to a system.
   (Suggested by: Wilfried Gaensheimer <wilfried.gaensheimer@hl.siemens.de>)


Release LPRng 3.6.10 Sun Sep 12 19:46:33 PDT 1999
  lpc.1 man page moved to lpc.8 man page
  (Suggested by: Craig Small <csmall@eye-net.com.au>)

  PERMISSIONS CHECKING:
    The USER, HOST, IP, SAMEUSER, SAMEHOST, entries will now SUCCEED
    when checking permissions for an operation to be applied to a
    spool queue;  when the individual jobs in the queue are checked
    the comparisons will then be done.  This has the effect of allowing:
       ACCEPT SERVICE=C LPC=hold,release SAMEUSER SAMEHOST
       ACCEPT SERVICE=M SAMEUSER SAMEHOST
    to be specified and allows a user to hold, release, or delete
    their jobs.
    (Need pointed out by: Jens Noelle <noelle@amica.rwth-aachen.de>)

  Updated the lpd.conf file generation to put in the types of options.

  NONE renamed to NONEP due to conflicts with some <sys/types.h>
    definitions.

  Added a $_ capability to filter options.
    (Patch by: Mike Whitson <mwhitson@MIT.EDU>)

  Added a configure option to set the :sh default to 1 (on).

Release LPRng 3.6.9 Mon Aug 30 13:30:58 PDT 1999
  reverse_priority_order flag - priority z-aZ-A, i.e. - A is lowest
   (Requested by: Dennis Bush <Dennis.Bush@dowjones.com>)
  LPD now does a chdir("/") so that it is in a well known location.
   (Requested by: Craig Small <csmall@eye-net.com.au>)
  Time used to sort job is now the arrival time of the last byte
   of the job.

Release LPRng 3.6.8 Fri Aug 27 17:06:10 PDT 1999
  *** WARNING:  configure strikes again
  ***
  *** printcap, lpd.conf, lpd.perms now default to:
  ***  /usr/local/etc/{ printcap, lpd.conf, lpd.perms}
  ***
     You may want to do:
       ln -s /etc/printcap /usr/local/etc/printcap
     OR
       configure --with-printcap_path=/etc/printcap

     Please move your lpd.conf and lpd.perms files to /usr/local/etc/

  Why?  Because when trying to port this to XxxxBSD, BSDI, Solaris,
  SunOS, HPUX, DGUX,  etc etc etc I have run into so many inconsistencies
  that I have just given up.

  You might as well assume that the following is true for a default install.

  Updated configuration to be a little more consistent with other packages
   default installation directories:
     ${prefix}  is usually /usr/local
     ${bindir}  is usually ${prefix}/bin, (/usr/local/bin)
     ${sbindir} is usually ${prefix}/sbin (/usr/local/sbin)
     ${libexecdir} is usually ${prefix}/libexec (/usr/local/libexec)
     ${sysconfdir} is usually ${prefix}/etc (/usr/local/etc)
     ${mandir} is usually ${prefix}/man     (/usr/local/man)

   We install the executables in:
         (* indicates default SETUID Root install)
     ${bindir}/ lpr *, lprm *, lpq *, lpstat *
     ${sbindir}/lpc *, checkpc, lpd *
     ${libexecdir}/filters/ lpf, banner, etc
     ${sysconfdir}/ lpd.conf, lpd.perms, printcap
     ${mandir}/ man pages

   Suppose you wanted to put them in /usr/bin, /usr/sbin, and /etc:
     configure --prefix=/usr --sysconfdir=/etc


   Note the following explicit overrides:
  --disable-setuid        disable setuid root client and server executables
  --enable-priv_ports     require connections to be from privileged ports
  --disable-force_localhost force_localhost default to disabled
  --with-lpddir=DIR       lpd executable directory (default ${sbindir})
  --with-filterdir=DIR     filter directory (default ${libexecdir}/filters)
  --with-lpd_conf_path=PATH     path to lpd.conf (default: ${sysconfdir}/lpd.conf)
  --with-lpd_perms_path=PATH    path to lpd.perms (default: ${sysconfdir}/lpd.perms)
  --with-printcap_path=PATH     path to printcap (default ${sysconfdir}/printcap)

  Fixed up the INSTALL and HOWTO documentation as well.

  Note 1:  you can make a symbolic link from /usr/local/etc/printcap to
   /etc/printcap and this will solve the issue as well.

  ---
  Job time is now recorded down to the millisecond a jobs sorted according to that
    time.  This will slightly improve the situation due to multiple jobs arriving at
    at (approximately) the same time.  Jobs are sorted accordingly.
    (Suggested by: Abramo Bagnara <abbagnara@racine.ra.it>)

Release LPRng 3.6.7

  LPRng now handles files larger than 2 gigabytes on systems where the max
    size_t is larger than 2 gigabytes.
  configure now checks to see that there is a prototype for lseek().
    (Both inspired by somebody trying to print a 2G file:
       John Kimberley <jkimberly@harland.net>)
  lpq -n linecount
     Limits number of status lines to linecount.  Can be used when
   you want an exact number rather than using -llll.
  lpc now puts debug flags in () -
     Printer    Printing Spooling Jobs  Server Subserver Redirect Status/(Debug)
    t1@h4       enabled  enabled    0    none    none          (4)
  There is a horrible problem with load balance queues, SIGCHLD, and missing
    SIGUSR1 signals on Solaris 2.4, 2.5, and 2.5.1.  The code in lpd_jobs.c
    has been rewritten,  silly things have been done and it now looks awful,
    but it works,  is portable,  and ugly.  So much for elegance.
  Added more %U option to lpc, lprm to allow SAMBA to specify users.

Release LPRng 3.6.6 Sun Aug 22 10:42:20 PDT 1999
  LPD did not exit with non-zero success code when there was another
    lpd active.
    (Patch from: Stephen Fischer <fischer@cse.unsw.edu.au>)
  LPD bounce queues changed the 'N' data in the control file.  Should not
    do this.
    (Noticed by: John Rothlisberger <rthlsbrj@pprd.abbott.com>)

  New timeout - exit_linger_timeout
    When an LPD server process exits,  it needs to try to 'flush' data over
    the various pipes, sockets, etc, that are part of the IPC.  The problem
    is that on some OS's,  when a process exits the data in a pipe buffer
    may be discarded if the process exits due to a signal.  Added
    'exit_linger_timeout'  to force all pipes/sockets to be 'lingered' on
    during cleanup.  This is a totally bogus method.  What is needed is a
    setsockopt() function similar to 'fflush' that would not return until
    all the data is flushed to the remote end.  It turns out that the
    SO_LINGER with a 0 value should have done this,  but the 0 value causes
    a 'default' value to be used.  Grr...  Needless to say this is a hack
    of the worst type,  does not work on all systems.

  LPR was failing due to connnections closing due to lack of processes.
    When a connection is made to the LPD server,  it used to do accept()
    and would then fork a process.  This would lead to some ... interesting...
    denial of service attacks,  and some very odd problems when you ran out
    of processes.  The code now does the following:
       creates a pipe()
       forks a process =
         = child will now do an accept
         = child will then close the pipe
       parent WAITS until the child pipe is closed.
    This has the effect of making sure that the child process has
    done the accept,  and will BLOCK until the accept is done.
    This makes sure that there is a process to handle the connection.
    Wierd, I tell you.  Note that there is a way to do a DOS attack on
    some systems that signal a connection is available BEFORE the 3 way
    handshake completes,  and should cause endless problems.  You can
    also launch DOS attacks on inetd, ftp, etc. etc. on these systems
    as well.  See CERT for more nasty details.

  LPQ now correctly reports all jobs, even ones from different
    machines with the same job numbers.  Yeah, it looks confusing
    in the output to have two job 12's,  but HEY!  what do you want
    on 80 columns?

  LPQ now confuses people trying to figure out why there are
    duplicate jobs in the status listing.  See above.  Isn't this
    marvellous?

  lpd_jobs: when processing long queues a huge number of tempfiles
    would be created.  Now these are removed each time the queue is scanned.
    Sigh...

  lpd_jobs: when you have a connection opened using lp=host%port,
    then lpd now do a shutdown(port,1) on the socket.  Now we get
    into the really odd stuff.  We first set the linger value to
    'read_write_timeout' if nonzero otherwise the 'exit_linger_timeout'.
    IF the 'wait_for_eof' flag (default TRUE) is set,  we try
    READING from the socket until we get an eof.  We then close
    (with the linger) the socket.

    Here are the problems that this tries to solve.

    When you send a job to a printer over a socket connection,
    you stuff the files into a socket and then expect the OS to
    deliver the data.  WRONG!  The OS puts this in some buffers.
    It returns from the WRITE call with success.  You now do a
    close().  At this point there are some interesting possibilities:
    a) your data is delivered,  even after waiting 6 weeks for the
    other end to respond (BAD choice); b) the system attempts to
    deliver your data for,  say,  120 seconds (default 'linger'
    time on some BSD systems);  c) you can specify how long you
    want to have the system try to deliver the data.  While this
    is going on of course, you cannot open a connection to the
    device,  as it is still busy with the previous connection.

    You really want to treat the 'close' like a 'write' and wait
    for a reasonable (read_write_timeout) time for this to happen.
    When you do a write 'shutdown',  the TCP/IP connection sending
    (write) capability is terminated, and the TCP/IP stack does a
    handshake with the other end telling it that no more data will
    be sent.  The receiver will get an EOF when it tries to read
    more data, and will, in turn, close the connection.  Note that
    this must be a 'shutdown' and not a 'close'.  All close does
    is closes the process's copy of the file descriptor information.
    Shutdown is brutal and will terminate with predjudice the tcp/ip
    level communication (thank the Diety).  How do you know that
    the receiving end has closed the connectio? You do a read from
    the socket until you get an EOF.  Of course,  you should be
    reading from the &*()*& socket at all times,  as the printer
    will be sending status, error messages, etc. etc.  back to you.
    But your filter should be doing this,  right?  Oh... you do
    not have a filter... well, you MUST have a filter that does
    the reading - this is what the IFHP filter was designed to do,
    and in fact goes overboard to solve this problem.  Even when
    you say 'status@' it STILL tries to read from the file descriptor
    because there might just be stuff coming back.  Sigh...

Release LPRng 3.6.5 Sun Aug  1 16:46:31 PDT 1999
  The date format in the status messages has been changed so that
    you can have a short or long format displayed.  By default, the short
    format is displayed (short_status_date option is true).  Note that this
    sillyness is partly forced on us by Y2K issues.
    New flag option: short_status_date - when set, status time/date displays
    only time.
    (Sigh... by: Patrick Powell <papowell@lprng.com>)
  Remote logging information now contains full date and time and process id.
    (Sigh... by: Patrick Powell <papowell@lprng.com>)
  Update LPRng HOWTO to specify that filter STDERR output is now merged with
    the status messages.  This allows errors reported by the filter to appear
    on the lpq status.
  You can specify filter arguments as the form xxx 'yy yy' "zz zz" and they
    will get passed as a block.
    (Suggested by:  Martin Forssen <maf@crt.se>)
  The lpstat -a code has been fixed so that it correctly searches for
    printer names.
    (Reported by: Martin Forssen <maf@crt.se>)
  Removed duplicate status information lines in status file.
    (Discovered by: Patrick Powell <papowell@lprng.com>)
  Added 'send_failure_action' information to status output to allow users
    of this very odd feature to figure out what is happening.
  Fixed up LPRng to handle a stupid RFC1179 idiocy.  If you have a control
    file, then the order of N and data file lines is not defined.  So
    you have to handle them in any order.  Also,  you can have the same
    data file line with DIFFERENT formats - sigh... this means that you
    can print it several times with different formats.
  The 'generate_banner' option, which was present in 3.5.1, has been restored.
    This is only operational when you have a 'normal' forwarding queue.
    It uses the 'ab' (always banner), bp (banner printer), bs (banner
    printer program for banner at start), and be (banner program for banner
    at end), hl (header or banner last) and the user banner information.
  The "cm" (comment) option has escapes processed.  Now you can put ":"
    in the comment line by using "\072"
    (Wanted by: Johan Claesson <Johan.Claesson@uab.ericsson.se>)

Release LPRng 3.6.4 Sat Jul 24 14:29:09 PDT 1999

  Cut and Paste-o observed in the configure.in file - LPD_CONF_PATH
   should be LPD_PERMS_PATH.
   (Reported and patched by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu)
  Added: AC_PROG_AWK, AC_SUBST(AWK), to configure.in to find the version
   of awk to use.
   (A good suggestion by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu)
  SAMBA Assistance.
   The -U option has been extended to the LPRM program as well as the LPR
   program.  This allows facilities such as SAMBA to submit jobs on behalf
   of users.  In order to allow SAMBA and these facilities not run as root,
   the allow_user_specification=name,name,... configuration option will allow
   either root or the named users to forgre... I mean impersonate any user.
   The SAMBA printing configuration file will now look like:
    [global]
        printing = lprng
        print command = /usr/local/bin/lpr  -P%p -r %s
        # alternative to allow userid to be specified as well
        # You will have to add the samba UID to the 'allow_user_setting'
        #   option in the /etc/lpd.conf file.
        # print command = /usr/local/bin/lpr -U%U -P%p -r %s
        lpq command   = /usr/local/bin/lpq  -P%p
        # alternative
        # print command = /usr/local/bin/lpr -U%U -P%p -r %s
        lprm command  = /usr/local/bin/lprm -P%p -U%u %j
        printcap name = /etc/printcap
        load printers = no
    [printers]
       comment = All Printers
       path = /tmp
       browseable = no
       printable = yes
       guest ok = no
       writable = no
       create mode = 0700
    man pages and HOWTO have been update to reflect these changes.

  commmon/linelist.c: Escape() had a malloc() size error.
  man/lpd.8 man page editted and fixed up for consistency.
   (Found by: Patrick Powell <papowell@lprng.com>)

  FreeBSD Support: FreeBSD.ports.sysutils has the files for a Ports Install
  RedHat RPM: pkg has the files needed to build a RedHat RPM distribution.


Release LPRng 3.6.3 Fri Jul 16 16:01:27 PDT 1999

  CONFIGURE CHANGES
   Please note that the configure and 'make install' have been modified in
   order to deal with different installation locations and configuration setups.
   Here are the options to configure that you should be aware of:
    --with-cppopts=CPPFLAGS  select compiler preprocessor command line options
        **** note: these flags will also be passed to CC, so set your options using
        **** this configuration option.
    --disable-setuid      disable setuid default
        **** note:  use this if you want to install without setuid
    --disable-priv_ports   set default lpd.perms to reject connections from non-privileged ports
        **** note:  if you disable priv-ports, you MUST install setuid.
        ****   Thus, you can have --disable-setuid, --disable-priv_ports, but not both
    --disable-force_localhost      disable force_localhost default
    --with-lpddir=DIR       where to install the lpd binary.
        ***   where you want LPD to be installed.
    --with-admindir=DIR     where to install the administrative commands, like
                            checkpc, lpc, etc.
        ***   where you want the other stuff installed
    --with-filterdir=DIR     where to install filter (default ${libdir}/filters)
                            checkpc, lpc, etc.
        ***  where you want the filters installed
    --with-lpd_conf_path=PATH     where to install lpd.conf (default /etc/lpd.conf,/usr/etc/lpd.conf)
    --with-lpd_perms_path=PATH     where to install lpd.conf (default /etc/lpd.perms,/usr/etc/lpd.perms)
    --with-printcap_path=PATH     where to install printcap (default /etc/printcap,/usr/etc/printcap)
    --enable-nls           use Native Language Support
    --with-included-gettext use the GNU gettext library included here
    --with-catgets          use catgets functions if available

  MAKE INSTALL changes
     These tie into the changes with configure.  You should be aware of them.
     You have been warned.

     Note 1: FreeBSD
       To put LPD in /usr/libexec/lpd,  admin in /usr/sbin, and other stuff in /usr/bin
       configure -with-lpd_conf=/usr/libexec/lpd -with-admindir=/usr/sbin --prefix=bin
     Note 2: RedHat Linux
       To put LPD in /usr/sbin/lpd,  admin in /usr/sbin, and other stuff in /usr/bin
       configure -with-lpd_conf=/usr/libexec/lpd -with-admindir=/usr/sbin --prefix=bin

  Minor fix to configure, src/Makefile to link only lpq with terminal library
    (Supplied by: Roderich Schupp  <rsch@ExperTeam.de>)
  Set spool_dir_perms to 0600 instead of 042600.
    (Supplied by: Roderich Schupp  <rsch@ExperTeam.de>)
  Typos and More Typos in HOWTO
    (Spotted by the Eagle Eye of: Wolfgang Schludi <schludi@syscomp.de>)
  Printcap 'oh=' was using wrong entry.
    (Reported by: Wolfgang Schludi <schludi@syscomp.de>)
  lpd -D= did not tell you what you did wrong.
    (Reported by: Niklas Edmundsson <nikke@ing.umu.se>)
  Kerberos authentication forwarding was incorrect.
    (Fixed by: Mike Whitson <mwhitson@MIT.EDU>)
  Printcap includes were not being processed correctly.
    (Reported by: Don Badrak <dbadrak@census.gov>)

  The spool queue control, status, and unspooler files (control.%P,
    status.%P, and unspooler.%P) are now specified by the
    queue_status_file and queue_control_file options.  This allows
    you to relocate the files to another spool queue, or even use
    the file.%D option to have a date appended to the file name.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)
  When the lpd logger facility makes a connection to the receiver of the
    log information,  it sends a dump of the system status.  The dump
    consists of a set of lines, one line per print spool entry.
    The end of this dump information is indicated by a single END
    line, i.e: END\n.  This enables a database management system to
    know that all of the queue information has arrived and can then
    undertake to do any consistency checks.
    (Need determined by:  Patrick Powell <papowell@lprng.com>)

  When a 'lpc reread' is done,  the logger process is killed and restarted.
    This forces the logger process to use the new printcap or configuration
    information.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)
  When an unspooler process is active,  a SIGUSR1 signal is sent to it
    to force it to rescan the spool queue.  The SIGUSR1 signal
    handler sets the Susr1 flag,  and this flag is checked.  There
    is a small window between the time that the flag is checked,
    the process decides that no new jobs have been put in the queue,
    and the process exits.  This window has now been narrowed down even
    more by performing a final check just before the process exits.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)
  On a heavily loaded system where a large number of files are being
    created and/or destroyed,  the spool queue scanning code would
    miss some jobs at the start or end of the queue.  This was due
    to the fact that the scandir() routine does not lock the spool
    directory,  and it can change as the directory is being read.
    In order to reduce this window to the smallest possible size,
    the directory is now scanned for files and then the files are
    processed.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)

  Updated HOWTO to reflect these changes.  Updated MAN pages.

Release LPRng 3.6.2 Sat Jun 12 16:44:15 PDT 1999
  LPRng-HOWTO corrections.
   (Corrections by: Vladimir V Egorin <vladimir@math.uic.edu>)

  Used the wrong process exit status variable in common/lpd_jobs.c
   (Noted by: Olav Kolbu <olav.kolbu@usit.uio.no>)

  Added STATE and LPC command execution tracing to the
   logger messages.  This allows a remote system which is
   monitoring LPRng operation via the logger interface to
   monitor when a job is submitted and printed.

  Updated format of message sent by logger.
    UPDATE message now has a
      hf_image= and (optional) lpc= encoded portion
    QUEUE message now has a
      queue= and (optional) lpc= encoded portion

    The lpc identifies that the udpate was done by LPC operation
    rather than by LPD as part of normal operation.

  File locking had problems under SunOS 4.1.4.

  You can now have single letter printer names.
    (Sigh... noted by: Patrick Powell <papowell@lprng.com>)

  Accounting information now has options (correctly) quoted:
   start '-H...' '-c' '-JThis is a job'
   This is consistent with ifhp 3.3.2.

Release LPRng 3.6.1 Mon Mar 22 09:42:07 PST 1999

  This release is a major rewrite of the LPRng software and uses
  dynamic memory allocation and as few static and global variables as possible.
  This is intended to simplify the porting of the LPRng software
  to a multi-threaded environment. In addition,  substantial
  cleanup of much of the code was done.

  Due to time constraints,  some functionality that is present in other
  test versions was not put into this release.  This includes
  setting user information by originating IP address.
  The 4.x.x release will have support for the new IPP print protocol,
  SNMP MIB,  and a HTTP server interface.

  As far as possible, existing functionality has been preserved,
  with the following notable exceptions.  These are divergent enough
  to cause a new major release number to be used, i.e. - 3.6.x

  License

    Due to various technical legal reasons,  the License for this
  release of LPRng has been changed from the GNU Copyleft to the slightly
  different but similar in intent Artistic License.

  Load Balance Queues and Class types

    Assume: a load balance queue with several printers, say
       master -> S1, S2;
    You can now set the class types accepted by S1 and S2, and
    the Master Queue will check the job types against the class
    types before sending the job to the appropriate queue.

    What is this all about? If S1 has blue paper you can set the
  currently printing class to blue (lpc class blue).

    Now do lpr -Pmaster -Cblue and your job will be routed to printers
  which currently are printing class 'blue'.  Clearly this can be
  extended to other things besides paper.

    Note that when you use this option you should set the master
  queues ignore_requested_user_priority flag so that the first
  letter of the class type is not used as the priority.

  *********************************
  ******* force_localhost *********  distribution default is ON
  *********************************

    The Most Frequently Reported Problem with 3.4.X and 3.5.X was the following:

      lpr is not sending jobs to my lpd server.  Why?

  The reason is that other BSD based spoolers ASSUME that the
  lpd server will be running on localhost,  and the clients
  (lpr, lpq, etc) will connect to the server.  So the printcap
  files are written as:
   lp:sd=/usr/spool/whatever
     :rm=remoteserver:rp=remoteprinter

  Of course, lpr reads this as meaning 'connect to the remoteserver',
  and never sends the job to the server running on the localhost.

  The 'force_localhost' option will FORCE lpr, lpc, etc to connect to
  the localhost UNLESS lpr -Ppr@remoteserver is used, i.e.- a command
  line override.  In LPRng 3.5.X, the default value of 'force_localhost'
  was OFF.  In LPRng 3.6.X, the default value is ON.

  Bounce Queues, lpd_bounce,  and LPR Side Filtering

    The lpd_bounce option REPLACES bq=xxx
  Example:            ->
    pr:lp=pr@xxx         pr:lpd_bounce
      :bq=far@server       :lp=far@server

    This makes bounce queues consistent with remote print queues.

    The entire print job job is passed through the various filters,
  and the entire output is now sent as a single file to the next
  queue.  The format of this file is set by the bq_output=X option.

    This now allows the full use of leaders, trailers,
  banner page generation, etc., to be used.

  Printcap tc=xxx:tc=yyy handling
    printcap includes (tc) are done BEFORE setting the values
  in the printcap entry,  and in order.  Thus:

     lp:s=X:tc=.t1,.t2:tc=.t3
     .t1:s=Y
     .t2:z=W
     .t3:z=P

   would result (for lp) in:
     lp:
      :s=Y # from .t1
      :z=W # from .t2
      :z=P # from .t3
      :s=X
    and a final result of
     lp:s=X:z=P

   (Requested by and faultless arguments by: the lprng mailing list...)

  Permissions List File:
    You can now say XXX=<filename and the whitespace separated
  contents of the file are used as the options value.

  Example:
    ACCEPT REMOTEHOST=</usr/local/etc/lpd_hosts
   and have /usr/local/etc/lpd_hosts contain:

    *.site.com
    10.0.0.1/24  pc.*.mystuff.org

  LPC Permissions Checking

  You can now use:
    ACCEPT LPC=hold,remove,topq
  If you are doing an LPC operation, then this matches the operation.
  This replaces the lpc_user=.... printcap abomination.

  For example, to allow user X on the server to do hold operations,
  use:

    ACCEPT LPC=hold USER=x SERVER

  The 'ms', 'sy' and 'ty' serial port configuration options are now
  the single option 'stty' which makes more sense and is compatible
  with other LPRng software.

  The 'rt' and 'send_try' options were accidentally aliased - removed
  the 'rt'.

  There is now finer control for remote LPQ queries.
   force_lpq_status=KEY=hostlist;KEY=hostlist
     Specifies a set of hosts and the format for lpq status queries,
     overridding the requested format.
      KEY = l (long) or s (short)
      hostlist = list of IPaddress/Mask or GLOB patterns for hostnames
     Example:  force_lpq_status=s=*pc.site.com,10.0.25.0/24;l=sunsystem.site.com
   reverse_lpq_format=hostlist
     Reverse l and s query formats when a request arrives from these
     hosts.
   return_short_status=hostlist
     Return short_status_length status lines when a request arrives from
     these hosts
  short_status_length=N
     Number of status lines to return when return_short_status matched

  LPC added commands
    active   - checks for an active server
    local (all | printer) - show printcap and configuration information
      for a local printer.  Debugging aid.

  LPQ added option
     -L   - equivalent to -llllll....

  CHECKPC
      checkpc -V now prints out all sorts of additional information for
    debugging and problem solving.
      checkpc now checks both for server AND client mode.  No fixing done
    for client information, just displays it.
      checkpc now checks for missing tc=xxx entries.

   LPD_CONF_PATH and PRINTCAP_PATH compilation option
     make LPD_CONF_PATH=/usr/local/etc/lpd.conf
     make PRINTCAP_PATH=/usr/local/etc/printcap
       - changes the /etc/lpd.conf and  /etc/printcap file
     default locations

  AUTHENTICATION

     The entire authentication interface has been redone,  and PGP,
  Kerberos 5, and MIT Kerberos 4 Print System compatibility has
  been added.  The permissions checking method has been changed as
  follows,  with respect to the following keys:
    AUTH       match or TRUE  if authenticated transfer done
    AUTHTYPE   matches the authentication type
    AUTHUSER   client or user's authentication id
    AUTHFROM   originating server's authentication id when forwarding job
    AUTHSAMEUSER   match if the client id in the request and the
               (saved) client ID used to spool a job are identical.
    AUTHJOB    match or TRUE if a job was submitted with authentication

  Options have been redone to put a bit of consistency into things

    auth=xxx                   authentication type for client to server
    auth_client_filter=/path   client to server authentication filter
    auth_forward=xxx           authentication type for forwarding
    auth_forward_id=xxx        authentication id for remote end when forwarding
    auth_forward_filter=/path  server to server authentication remote server id
    auth_recieve_filter=/path  server filter to recieve authentication
    auth_server_id=xxx         client to server - id of server
                               receiving server - id for reception
                               server to server - id for origination
    pgp_path=/path     path to pgp program for auth=pgp
    pgp_passphrase=clientkey   file in $(PGPPATH) or $(HOME)/.pgp
                               holding client passphrase
    pgp_server_key=~daemon/.pgp/serverkey   file holding LPD server passphrase

  SOLARIS Package Support
    Start of generating binary distributions.
    (Contributed by: Martin Forssen <maf@crt.se>)

  LPD lock file:  now defaults to /var/run/lpd
    (Pointed out by: Martin Forssen <maf@crt.se>)

  %D expansion,  create_files flag
    If you have %D in a printcap value,  it gets expanded to the
  current date in YYYY-MM-DD format.  If you have the create_files flag
  set,  then the files that normally get trimmed (max size specified)
  are created.  This allow you to do:
     lf=log-%D
  Your log files now will have the pathname sd.../log-YYYY-MM-DD
  and you can now get rolling log files on a daily basis.
  The files that have this done are the log file, status file,
  and accounting file.

  PCLBANNER and PSBANNER - new banner printing programs using PERL produces
   pcl or PostScript banner page.

   lp:bp=/usr/local/.../pclbanner
     :of=....
     :if=....
   OR

   lp:bp=/usr/local/.../psbanner
     :of=....
     :if=....


  Bug fixes:
    Gadzillions.  Many.  Some were not bugs but simply inconsistencies with
  documentation.  Sometimes documentation changed, sometimes the code.

  Default Server Print Queue:

   The default_printer_when_unknown configuration option
   allows you to specify a print queue that the server will use when
   it cannot find one in the printcap.  This print queue should have
   the format:

   /etc/lpd.conf:
    default_printer_when_unknown=fallback

   /etc/printcap:
   fallback:server
    :sd=/usr/spool/lpd/%P
    :router=/..../router_for_misdirected_jobs

    The router should output the correct destination (see router documentation
    in LPRng-HOWTO),  and exit with 0, or exit with JREMOVE to cause the job
    to be dropped in the bit bucket.

Release LPRng 3.5.4 Mon Nov  9 10:07:42 PST 1998
  Bug fixes:
  Bad link to site in LPRng.smgl documentation.
   (Reported by: Anthony Thyssen <anthony@cit.gu.edu.au>)
  LPQ status was missing a space separator when reporting
    subserver name list.
   (Spotted by the Eagle Eyes of: John Callaghan <callagh4@pilot.msu.edu>)
  The xt flag has been expurgated,  totally.  As was documented.
   (Spotted by: James P. Dugal <jpd@usl.edu>)
  LPR_bsd option added so that -m does BSD mail option.
   (Requested by various folks)

  Testers and bug fixers:
   (Compilation: Bernie Kirby <bernie@ecr.mu.oz.au>)




Release LPRng 3.5.3 Mon Nov  9 10:07:42 PST 1998
  Documentation Error:
    LPRng-HOWTO, Section 8, indicated that the lpd.conf file
  could be obtained using a filter.  This is not correct.
  (Noticed by: David Stenglein <david.stenglein@citicorp.com>)

  Major Modification:
    removed the 'xu' (per spool queue permission file) after trying
  to make the semantics work.  Now we have a single permission file
  for all printers

  Major Modification - Load Balance Queues:
    Some users reported very slow operation of the load balance
    queues.  This was verified,  and extensive modifications were
    made to the functionality.

    CHANGE:
        The subserver queues are only scanned at startup
      and when there is an explicit indication that a new
      job has been put into or removed from the queue
      (SIGUSR2 received)

  Major Modification - LPD Does Not Ignore LPR, LPC Requests

      Some users with either large numbers of spool queues or
    spool queues with large numbers of jobs noticed VERY slow
    LPD response.
      This has been improved considerably.

    CHANGE:
      LPD server would run through the Spool queues, looking for
    trash to be removed or jobs to be started.  This polling is
    necessary due to the possibility of a race condition between
    the time that a job is put into the queue and the time that
    the unspooler checks the queue for entries.
      The operation has been modified so that only a SINGLE PROCESS
    runs down through the spool queues.  When it finds work to do,
    it informs the LPD server,  which now will start ANOTHER process
    to check other queues for work.  Note that while these processes
    are working their little hearts out,  chewing up swap space
    and reading directory entries like mad,  the LPD server can
    accept requests for LPQ, etc.

  Major Modification - LPR speedup:
    The LPD server now accepts jobs for spooling WITHOUT extensively
    checking the spool queue.  This eliminates problems with printing
    to queues with a large number of entries.

  Speed Improvement:
    A bit of time analysis showed that LPRng was spending a large
    amount of time during queue scanning in the fcmp() routine.
    This has been rewritten and is now a strcmp().

    During queue scan, Get_controlfile() generates a 'cmp_str' value
    that represents the information needed to do sorting.  This is
    is then used during queue sorting as the comparison value.

    The 'struct cmp_struct' in the include/sortorder.h is used to
    make sure that sufficiently long string buffers are allocated.
    The make_cmp_str() in common/sortorder.c can be replaced with
    a users version if they desire.

  Bug Fix:
  safestrncpy, mystrncpy, safestrncat, mystrncat now used for string
   copies where there is doubt on the buffer/string length.  Note that
   these versions will always make sure the buffer is terminated with
   a 0 value.

  lpr -U xx is supposed only to work for ROOT. Check for root perms
    was not done correctly.
    (Patch by: Paul Szabo <psz@maths.usyd.edu.au>)
  permissions checking:  the C=value1,value2 permissions checking
    option wants a C (control file) line starting with character C
    and glob matching the indicated value1, value2, etc.  For example,
    N=patrick*,powell* should match against line Npatrickwashere or
    Npowellwasthere.  The check was done incorrectly.
    (Patch by: Paul Szabo <psz@maths.usyd.edu.au>)
  LPD/lpd_rcvjob.c - removed limits on lengths of class and host names
  When using bounce queues and the generate_banner to cause a banner to
    be added to a job,  the 'ab' (always banner) and the lpr -h (no header)
    flags now are used in the decision for banner generation.
    (Noticed by: Charles Karney <karney@pppl.gov>)
  Filters were not being passed -Knnn option.
    (Noticed by: Charles Karney <karney@pppl.gov>)
  Permissions:  SERVER keyword was not used for X permissions.
    (Fix by: Patrick Powell <papowell@lprng.com>)
  File Permissions:  spool_file_perms was being ignored due to the
    umask() not being (un)set before creating a file.
    (Discovered by: Albert Fluegel <albert.fluegel@hl.siemens.de)
  ConnectTimeout now times out on connect() calls.
    (Reminded by: Heinz-Ado Arnolds <arnolds@ifns.de>)
  Accounting filter:  when the filter returns 'JHOLD' the job
    will be held (as documented).
    (Patch by: Rainer Schoepf <schoepf@uni-mainz.de>)
   LPRM incorrectly gives the "clean" usage instead of "lprm" usage.
    (Fix by:  Edan Idzerda <edan@mtu.edu>)
   The 'xt' and 'check_for_nonprintable' flags were in conflict.  Removed
    the 'xt' flag.
    (Reported by: "Dugal James P." <jpd@usl.edu>)
   The LPD/lpd_remove.c code did not remove jobs correctly when a
    :destination=... entry was present
    (Patch by: john@cs.wisc.edu)
   Log files not being truncated.  Well, they are now.
    (Fix by: Patrick Powell <papowell@lprng.com>)
   LPR not printing multiple copies (-K option)
    (Patch by: Keith Richardson <keithr@ms.com>)
   LPD did not check spool queue just before exiting from printing loop.
    This opened a BIG race window on systems with lots of jobs in the
    spool queue.
    (Fix by: Patrick Powell <papowell@lprng.com>)
   Expand_command did not check for Do_dollar() returning 0, indicating
    a string overflow condition, which it then dereferenced and core dumped.
    (Reported by:  (Walter Misar) <misar@rbg.informatik.tu-darmstadt.de>)
   Control file filters were not being invoked correctly.
    (Reported by: Tony Graham <Tony.Graham@uni-c.dk>)
   Memory trashing being done by different behaviour of strncat() on some
    systems.  Replaced by mystrncat() and took the performance hit in return
    for reproducible behaviour and non-trashing copies.  Sigh.
    (Fix by: Patrick Powell <papowell@lprng.com>)
   strncpy() and strcpy() does not handle overlapping strings correctly, or
    at least that is what the man page says.  Replaced several of these
    calls by memcopy() and friends.
    (Fix by: Patrick Powell <papowell@lprng.com>)

Release LPRng 3.5.2 Fri May  1 14:39:55 PDT 1998
  Bug Fix:
   lpr -k did not pass the correct length (0) to the
   remote system.
    (Reported and patch by:  Wolfgang Scherer <ws@ecosys.de>)
   common/pr_support/ checks Do_lock() for <= instead of < for
    failure condition.
    (Reported by:  Wolfgang Scherer <ws@ecosys.de>)
   common/proctitle.c had a strdup() call - not supported
    under ULTRIX.
    (Reported by:  "Todd C. Miller" <Todd.Miller@cs.colorado.edu>)
   force_localhost was being tested BEFORE it was set in the printcap
    entry.  Now is checked AFTER the printcap entry is processed.
    (Reported by: Petri Kaukasoina <kaukasoi@elektroni.ee.tut.fi>)
   LPD returns 'o connect permissions' instead of 'no connect ...'
    (Noted by: Reinhard Zierke <zierke@informatik.uni-hamburg.de>)
   LPD records filter name in error message correctly.
   LPQ now reports full class name in status message if
     'class_in_status' flag set in printcap.
     (Requested by: Philip J. Nesser II <pjnesser@nesser.com>)
   common/sendlpc.c - missing Lp_device = 0
     (Reported by: "Dugal James P." <jpd@usl.edu>)
   LPD reported the wrong host name in 'no permission' messages.
     (Noticed by: Patrick Powell)

Release LPRng 3.5.1 Fri May  1 14:39:55 PDT 1998
  Baseline Stable Release

Release LPRng 3.4.12 Fri May  1 14:39:55 PDT 1998
  Legacy support modification:
    control file now has printer information in:
       controlfile
       Ninfo
       Uinfo
    order.  Some legacy printer spoolers require this order.
   (Reported by: Don Badrak <dbadrak@geo.census.gov>)

  Minor cleanups of:
    Get_printer() calls - some silly comments and orders
    common/fileopen.c/Init_tempfile() - clarified the
      use of the various directories and defaults.
    Force_localhost:  now done in Get_printer(), where it should
      have been done in the first place;  LPQ  and LPRM
      now send requests to localhost unless explicitly overriden
    Force_fqdn will now brutally assume that the domain of the
      sender is the one reported by the FQDN of the originator
      of the connection.

Release LPRng 3.4.11 Thu Apr 30 11:46:25 PDT 1998

  Functionality Change:
   JABORT and stop_on_abort default value changed
   JNOPRINT filter exit status stops printing
   JFAILNORETRY filter exit status stops retries

  In previous versions,  when a filter exited with unknown or
  JABORT status,  the default action was halt processing of
  PENDING jobs.  When a new job was sent to the queue,
  or a lpc start was performed,  processing was restarted started.
  Under heavy load conditions,  the effect of the JABORT was
  nullified by the arrival of new jobs.

  The LPRng behaviour has now been modified to handle JABORT
  conditions in a predictable manner, using the 'stop_on_abort'
  flag.

  1. The default for 'stop_on_abort' is now FALSE.
     This means by default that the JABORT status will simply be
     treated as a 'do not retry this job' error status.
     If the 'save_on_error' flag is FALSE (default), the job
     will be removed from the queue.

  2. If 'stop_on_abort' is set to TRUE,  then when a filter
     exits with a JABORT on unknown status,  further processing
     will stop, and NO pending jobs will be printed.  If the
     'save_on_error' flag is FALSE, the job will be removed from
     the queue.

  3. If 'stop_on_abort' is set to TRUE, the abort condition is
     sticky, i.e. - it will persist until
     action is taken to clear it.  Any of the LPC commands which
     cause printing to be restarted will clear it:
       LPC start, up, kill, topq, release, or redo

  4. LPQ and LPC will report if there is an aborted job condition.

  Note that for most users, the default action is now the desired
  action, i.e. - to continue processing jobs.

  However,  certain administrators will most likely need to assume
  that when a filter exits with JABORT that further printing on this
  queue will fail.  The sites should set 'stop_on_abort' to TRUE.

  JNOPRINT:

  If a filter exits with JNOPRINT,  then printing will be stopped;
  this will have the same effect as an LPC stop command.  The job
  will NOT be treated as an error job and will remain pending in the
  print queue.

  This allows filters to detect conditions that would normally cause
  printing to fail before a job is started,  and halt printing under
  these conditions.

  JFAILNORETRY:

  Under various arcane conditions,  it is possible for a filter to
  determine that a job has failed,  and should not be retried.  Most
  filters would return a 'JREMOVE' error code,  but for various arcane
  reasons (lots of Arcania here, folks), the 'save_on_error' flag
  might be set,  and the adminstrator would like to have the job
  marked as erroneous,  but NOT removed.

  If the filter exits with JFAILNORETRY,  then the job is treated
  as though it had an error, but no retries are performed.

  Extended Functionality:  'mail_from' option
    Allows specification of the 'From:' user.  If not specified
    default is to use the printer name.
   (Patch By: Rainer Schoepf <schoepf@uni-mainz.de>)
  Portability Extension:
   LPD_CONF_PATH compilation option
   The location of the LPRng configuration file is specified
   by the config_path value in the src/common/vars.c file.
   The compilation option -DLPD_CONF_PATH=path can be
   used to override the default locations.
   Example:  make LPD_CONF_PATH=/usr/local/etc/lpd.conf all
  Nit Fix:  spelling errors corrected.
   (Reported by: Don Badrak <dbadrak@geo.census.gov>)
  Incredible 9 Gigabyte Partition Fix:
   (Reported by: Don Badrak <dbadrak@gesg34.geo.census.gov>)
   Apparently the common/freespace/plp_fs_free_bytes cannot handle
   a >4 gigabyte partition.  The fix was to cast values to a
   double - this should be sufficient until we get 10**38 byte file
   systems. :-)
  Bug Fixes:
   LPD usage() had (erroneous) -i option.
     (Reported by: wcolburn@nmt.edu (William Colburn (aka Schlake)))
   get_max_servers did not get max servers.
     (Patch by: Don Badrak <dbadrak@gesg34.geo.census.gov>)


Release LPRng 3.4.10 Thu Apr 23 18:01:37 PDT 1998
  Added Functionality:
   sync_lpr flag- this suppresses the closing of the lpr to lpd
   network connection until the LPR job is completely processed
   by the LPD server.  This can,  under various arcane and odd
   situations,  result in the lpr processes 'hanging' until the
   LPD server queries DNS servers, looks up permissions, etc etc.
   However,  if users are trying to figure out why LPR has returned
   and their job is not in the queue,  or you have some desire to
   write shell scripts that create jobs and then remove them
   in order to see 'just how fast LPRng is',  this flag will SLOW DOWN
   the operation by making it synchronous.  Any little thing
   to make folks happy... :-)
 Modified Functionality:
   The 'force_localhost' flag has now been modified to (literally)
   force a connection to one of the 'localhost' addresses returned
   by a DNS lookup.  This should have no effect on 'normal' users,
   but might have the result that the status returned by LPQ
   will now differ a little.  For example, if you have a printcap
    pr:lp=pr@host2:force_localhost
   you will discover that lpq -Ppr will now print:
    Printer: pr@localhost
     ... status for localhost queue
    Printer: pr@host2
     ... status for host2 queue
   This is correct and accurate reporting, compared to the previous
   lpq format.
    (Brought to my attention by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)

 Bug Fixes:
 Job_printable_status() did not report active jobs, so lpq and lpc job count
   was off by one.
   (Reported by:  Al Marquardt <almar@uiuc.edu>)

Release LPRng 3.4.9 Mon Apr 20 12:42:55 PDT 1998
  Enhanced Functionality:
   For those folks who want to 'masquerade' their servers,
   the 'report_server_as=hostname' will now report your printer@server
   as 'pr@hostname'.
   (Requested by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)
  EXTA/EXTB:
    ifdef'd for folks with REALLY vintage systems...
    (Requested by: David Coelho <drc@ppt.com>)
  Added debugging code to determine when servers started.
  LPD now clears job 'move' indications so that a job can
    be saved (save_when_done) and then reprinted with
    out being moved to the destination again.
  lp -s (Silent) now does not print job id information.
    (Noticed by: David Coelho <drc@ppt.com>)
  Jobs which do not have print permissions now get removed.
    (Reported by: Al Marquardt <almar@uiuc.edu>)
  lpq -tN -c now will not core dump.

Release LPRng 3.4.8 Sat Apr 18 15:23:22 PDT 1998
  Portability Fix:  AIX 4.1.5 has definition conflicts when
  doing #include a.out.h.
   (Reported and Fix by: Niklas Edmundsson <nikke@ing.umu.se>)
  Also, Solaris4.1.4 has conflicts with tgetent() definition.
   (Reported by: wcolburn@nmt.edu (William Colburn (aka Schlake)))
  Y2K checked - ISO conformant date format is used in log and other
   messages.
  :force_fqdn_hostname flag causes FQDN host name rather than
   short hostname to be put into control file.

  Bug Fixes:
  Accounting at end was failing do to closing output device
   too early in the algorithm.  Device now closed AFTER last
   accounting script is called.
   (Reported by: Niklas Edmundsson <nikke@ing.umu.se>)
  Time_t strikes again.  I just discovered that there were some
   places where I was using long instead of time_t for time values.
   This has been fixed.  However, there is also now the problem
   of snprintf( "%d", time((void*)0)) being used for output and
   t = atoi("xxx") for input of time values.  Sigh... will fix
   this later.
  "lpc lprm pr all" operation now works correctly
   (Reported by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)

Release LPRng 3.4.7 Wed Apr 15 08:40:25 PDT 1998
  Bug Fix:
    Stupid system implementor used snprintf() instead of
    plp_snprintf,  causing headaches for unsuspecting
    folks on systems that did not have snprintf().
    Better fix is to insist that systems have snprintf() :-)
    (Reported by: Helmut Jarausch <jarausch@igpm.rwth-aachen.de>)
  Enhancements:
    The code for doing 'polling' of spool queues had a very high
    overhead in terms of process creation.  This code has been
    modified to have a single process run down the queues and
    check for work.  There is a bit of overhead,  but much less than
    the overhead in creating a large number of processes.
  Bug Fix:
    when generating banners using :generate_banner,  it did not
    work.  System developer forgot to include banner... :-)
    (Reported by: Cecil R. Whitaker <cwhitak@nswc.navy.mil>)

    Jobs that did not get permission to print and were flagged
    with JREMOVE did not get removed.
     (Reported by: Al Marquardt <almar@uiuc.edu>)

    When putting in a new 'From this host' line in a control file,
    did not remove the old one.  Also 'Q' entry as well.
     (Reported by: Al Marquardt <almar@uiuc.edu>)

    Multi-homed hosts that do not recognize interfaces need
    special coddling when trying to connect to them.  Link_support.c
    gets yet another special case for connections.
     (Patches by: Giray Pultar <pultar@pprd.abbott.com>)

    listen(backlog=64) - used to be 10, which caused connections
    to be dropped under heavy loads.

    checkpc was adding a / to end of file names.
    (Noticed and fixed by: Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)

Release LPRng 3.4.6 Tue Mar 31 18:10:59 PST 1998
  Bug Fix or Nit Pick:
    When sending a job AND the :qq or :use_queuename flag
    is set AND the job arrives without a Q entry THEN
    the name of the queue it was spooled to is used.
    (Noticed by:Cortney Sampson <sampson@physics.utoronto.ca>)

    Missing initialization in src/common/permissions.c
    Discoverer got the 'Gold Star with Flashy Sequins' bug hunting
    award.
    (Found by and Award to: Duncan McEwan <duncan@MCS.VUW.AC.NZ>)

  Lpr -Z options now accumulate, rather than overwrite, if the
    Allow_duplicate_options flag is not set.  This makes life
    easier for the user when specifying multiple -Z options.

  Allowed a LPR to LPD job transfer ending in a 'blank line' to be accepted.
    This is generated by some oddball LPR programs.
    (Reported by:  Patrick Hildenbrand <patrick@emea.ers.ibm.com>)

Release LPRng 3.4.5 Sun Mar 29 18:37:09 PST 1998
  LPF:
    Cleaned up some minor nits with options.
    (Noticed by: Patrick Powell <papowell@lprng.com>)

  LPRng-HOWTO:
    A huge number of corrections from:
    (Tim Mooney mooney@dogbert.cc.ndsu.NoDak.edu)

  Enhancements: max_log_file_size, min_log_file_size

    Sometimes it is desireable to run a log file in order to try
    to find problems.  But if you do not truncate the log file, it
    can grow to enormous lengths.  The max_log_file_size#nnn
    (size in Kbytes, default = 0 or unlimited size)
    printcap/configuration variable will
    cause the LPD server to check for the size of the log file
    on opening it and if larger than max_log_file_size K bytes
    truncate it to min_log_file_size
    (default 0 specifies max_log_file_size/4) Kbytes.  It preserves
    the last part of the file.

    Note that when the truncation operation occurs and there is
    heavy logging activity from multiple processes that the log
    file may get jumbled.  Recommended value of max_log_file_size
    should be pretty large in order to make the truncation activity
    minimal - 10240 (10 Megabytes) is what I have been using with
    pretty reasonable success.

  Enhancements:
    The time of a job error is now logged in the hold file.
    This allows the time of the error to be determined.

  Bug Fixes:
    Modified reporting of subserver processes that have been
    killed off or have core dumped.  This solved a problem with
    a system that would generate a SIGTERM signal.

    UTILS/accounting.pl fixed up. Also, psfilter and hpif now
    working correctly with the filter.
    (Patches, suggestions, and advice by:
      Gordon Haverland <haverlan@agric.gov.ab.ca>)

    The LPD/lpd_jobs code for retrying has been redone to make it
    more robust when printing fails.  The LPRng system will now
    agressively retry sending jobs.  Needless to say,  there are
    magic debugging flags to turn this off for testing purposes.
      (Noticed by:  Jesse Off <joff@cnde.iastate.edu>)

    The bogus 'server starting' and 'server done' messages have
    been removed from the status file.

    Now send a trace/logging message before the job is finally put
    in the spool queue.  Removes disturbing occurrence of 'success'
    messages being sent for a job that has not yet arrived according
    to log messages.

    More informative error messages and logging messages added at
    appropriate points.

Release LPRng 3.4.4

  Bug Fixes:

  termclear.c - tgetent() misdefined.
     Also,  configure now checks for Solaris systems and tries to
     handle their brain damaged colliding definitions in term.h, curses.h,
     terminfo.h and termcap.h files.

  ignore_name_format_errors is now documented.  Actually, it is really
    fix_bad_jobs.
    (Pointed out by:  Bruce S. Marshall  bmarsh@wwnet.com)

  Fixed a minor but annoying problem with hold files and very fast
    system.  Better solution would be to have an indexed database,
    but it is almost more trouble than it is worth to implement.

  Fixed a problem with 'Destination' being a pointer to dynamically
    allocated memory,  which would get deallocated by Set_job_status()
    calling Get_job_status().

  Fixed a problem with control file names not being formatted correctly.
    (Reported by:  John Perkins <john@cs.wisc.edu>)

  Fixed up LPRng-HOWTO,  created new version.

  snprintf() used instead of plp_snprintf()
    (Reported by: lots and lots of folks, including
        "Reinhard Zierke" <zierke@informatik.uni-hamburg.de>)

Release LPRng 3.4.3
  Bug Fixes:
    Serial Port Configuration.  Do_stty not called to set up serial
      ports.  Reported by LOTs and LOTs of folks.
    Fixed the GetMaxServers() code to really find the maximum number
      of processes.
      (Fixes by: Don Badrak <dbadrak@gesg34.geo.census.gov>)
    Memory Leaks From Hell
      Found them.  Found the problem.  Decided that fixing the problem
      was not worth it.  Found an alternative method to the current one
      for starting processes that AVOIDS the memory leaks.

      In the new version of code,  the LPD main() process will start
      subprocesses only when it needs to.  Periodically,  it will run
      down the list of print spools,  starting (forking) a process.

      In the previous version,  it would call the Setup_printer() code
      which would then in turn all the routines which would allocate
      (malloc) memory that would never get deleted.  If there were jobs
      to be printed,  the main() process would then fork and create a
      server process.

      In the current version,  the main() process will create a pipe(),
      and then fork the child process,  which will call the *&I*(&()
      Setup_printer() code,  and then checks for work.  If there is NO
      work,  it exits (exit code 0), and as a side effect, the pipe is closed.
      The parent process will read 0 bytes, and say, 'Ah, No work'.  As
      a side effect,  it also gets the status.  If there is work,  the
      daughter will write a string to the pipe and THEN close the pipe.
      The parent will read the data,  and say 'Ah, work to be done'.

      There are several elegant little side effects of this method.  Firstly,
      the main() process will block until the child decides if there is work
      to be done.  In effect,  this will allows the child to proceed ASAP
      to the decision point.  Secondly, the parent process has a VERY small
      amount of memory allocated,  and does not grow at all large.  This
      helps,  as the children,  when created, have very small memory needs
      and process creation is sped up tremendously.

      I am surprised to find just how much better this is...  I probably
      should have done this before,  but I was trying to avoid process creation
      problems, and ended up with large memory footprints.

      (Proddings, pokings,  help, suggestions, and lots of tracking down by:
          Al Marquardt <almar@uiuc.edu> - who found the cause of the memory
            leak
          Branson Matheson <Branson.Matheson@FergInc.com> - who came up with
            another memory leak

         If you ever want to debug memory leaks,  please look at the
         malloc debugging package by Gary Watson.
              http://www.letters.com/dmalloc/
       )

     lpc move
       In the previous versions,  lpc move only worked if the spool
       queue was active.  This meant that you could not stop a spool queue and then
       move the jobs to a different queue.  Now you can.  However, if you
       redirect a queue, then it must be active for jobs to be redirected.
       C'est la Vie.
       (Reported by:  Gary Cender <gcender@eng.dowjones.com>)

     Some logging numbers were not being reported correctly.  They now should be.
       (Reported by:  Gary Cender <gcender@eng.dowjones.com>)

     The QQ option was not working correctly due to a coding typo.
       (Reported by:  Gary Cender <gcender@eng.dowjones.com>, and others)

     LPR was doing translate_format, which was wrong.
       (Reported by:  Chad Mynhier <mynhier@cs.utk.edu>)

     LPR does not use '-' as a flag to read from STDIN.  Documentation changed
       to reflect this;  easier than fixing LPRng... :-)
       (Reported by: "James P. Dugal" <jpd@usl.edu>)

     LPR now allows LOOOONG options to -Z.
       (Requested by:  George Lindholm <lindholm@cheshire.ucs.ubc.ca>)

     Race condition with job completion and testing for completion once
       again explored.  Now err on the side of 'slow but correct' rather than
       'fast but sloppy'.  Only happens on FAST servers,  and the alternative
       to run LPRng on slow servers was not taken well :-).
       (Reported by: Gary Cender <gcender@eng.dowjones.com>)

     OS/2 sends very odd control file format - now should parse this format correctly.
       (Reported by:   "Patrick Hildenbrand"<patrick@emea.ers.ibm.com>)

Release LPRng 3.4.2
  Bug Fixes:
    Connect_timeout was not used uniformly or documented accurately.
    (Fixes by: Heinz-Ado Arnolds <arnolds@ifns.de>)
    configure was too agressive in checking for -lresolv.  Now includes
     -lresolv only if gethostbyname2 is not found.
     (Problem reported by: Uri Blumenthal <uri@ibm.net>)
    It was observed that under heavy load conditions that some files
      were getting printed twice.  This was due to a race condition.
      The race condition has been eliminated by introducing another
      field into the job control information specifying the subserver
      process id.

Release LPRng 3.4.1
  New Baseline Release - Stable version

  Enhancements:
   The configure script now supports setting the installation directories
    configure --with-lpddir=DIR --with-admindir=DIR
      - sets the install directory for lpd and lpc/checkpc respectively.
   (Patches by:  Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>)
   Added a 'retry_etimedout' flag as well to handle connections to devices
    that have a very long connection time due to slow network connections
    over dialup devices.
   The lpq status now will show 'stalled' when 'stalled_time' is non-zero
    and the job is active for more than stalled_time seconds.
    (Suggested by: lots of folks)
   The check_idle=program facility can now be used to check that a printer
    is idle before processing jobs.  This is useful when you have multiple
    server queues. For example:
     lp:sv=lp1,lp2:...
     lp1:check_idle=/prog:...
     lp2:check_idle=/prog:...
    When the lp server starts up,  it will check the lp1 and lp2 queues,
     and will only send jobs to the one whose check_idle program reports
     an idle condition.

  Bug Fixes:
    Updated LPRng-HOWTO.
    Fixed missing permission check checkpc.
    Also (correctly) implemented ${option} expansion in filter commands.
     This now gets expanded to the printcap option value,  as documented.
    (Made by: Patrick Powell <papowell@lprng.com>

Release LPRng 3-3-7

 Ports:
   Solaris 2.6.  Also update README.install for new startup/shutdown script

 New functionality:

   reverse_lpq_format : reverse returned lpq status format when from
      specified host.

    There is a defect in some System V support for RFC1179 printers.
    The lpq facility will send a 'SHORT' status request when a 'LONG'
    is desired,  and vice versa.  This results in the wrong status format
    being returned.

    The reverse_lpq_format=(globhost|ip/mask)+ option allows you to specify
    that when a request is received from a host whose name or address matches
    an entry in the list,  then SHORT/LONG format requests will be reversed.
    When the LPD is acting as an intermediate host,  the reversed request
    will be sent to the next destination on the list.  For example:
      reverse_lpq_format=*.eng.com,130.29.0.0/16
    will select hosts whose FQDN ends in eng.com or in subnet 130.29
    to have reversed lpq formats.

   return_short_status : return limited length status information
   short_status_length : number of lines to return

    Some users have expressed a desire to have the LPD server return
    short (i.e. - limited length) status to the requestor.
    The return_short_status=(globhost|ip/mask)+ option allows you to specify
    that when a request is received from a host whose name or address matches
    an entry in the list,  then only short_status_length (default 3)
    Status: and Printer_status: lines returned.

   lpc redo command:
    this forces a job to be totally reprinted, if it has been held
    in the spool queue.  This command has been added in order to allow
    the reprinting of jobs that have been printed and held in the spool
    queue, i.e. - the save_when_done printcap flag is set.

   routing filter 'priority N' output:
    the routing filter can set the destination, copies, and now the
    priority of jobs.  If the routing filter output is:
      dest t1
      CB
      priority B
      copies 2
      end
    then two copies of the job will be routed to the destination
    with priority B, and the C line in the control file will be
    set to CB.

   safe_chars=nnn  configuration file option.
    By default, LPRng detects and optionally eliminates suspicious characters
    from the control file;  the fix_bad_job option will enable removal.
    The safe_chars=nnn specifies that in addition to the normal safe
    characters, the indicated ones can be used as well. For example,
    save_chars=#" will allow # and " to be used in the control file.

Release LPRng 3-3-6

 New functionality:

  Timeouts: send_job_rw_timeout, send_query_rw_timeout replace send_timeout

    The printcap send_job_rw_timeout and send_query_rw_status options
    now set timeouts on read/write operations when printing or sending
    jobs to a remote host or doing a status or query operation respectively.
    If the value is zero, there is no timeout on the operation.
    These timeout values and the associated read/write operations
    solve a problem when LPQ or LPR tries to attach to a printer or system
    which accepts a connection but then does not reply to the request
    in a reasonable amount of time.  Note that the send_job_rw_timeout
    should be quite large (6000 or 100 minutes) in order to accommodate
    transient problems like paper outages on a printer.
    (Suggested by: Brad Rogers <brad@ast.lmco.com> and
        Alek Komarnitsky <alek@ast.lmco.com>)

  lpc active, lpd, and reread commands
    The lpc active command will try to open a connection to the remote
    server.  This allows non-LPRng remote servers to be polled to see
    if they are active.

    All of the active, lpd, and rereads now take a printer[@host] argument,
    allowing the specified server for the printer to be queried.
    (Deficiency noted by:  James P. Dugal <jpd@usl.edu>)

  stop_on_abort printcap flag (default TRUE)
    If a filter aborts and this flag is TRUE then all further processing
    of the queue stops until restarted by some other action and the job
    will not be removed from the queue.

  max_connect_interval (default 60)
    maximum interval between attempts to send a job to a remote site.

  user_lpc configuration option, SERVICE=U, and lpc command
    There was a request to allow a selected set of lpc commands
    to be performed by users on their individual jobs in a queue.
    This has been accommodated using the following method.

    1. A new user_lpc=cmd,cmd,... printcap operation enables the
       SERVICE=U permissions facility.  The cmd can be:
       hold, release, move, topq, kill, and abort.
    2. When the lpc command is checked for permissions by the LPD
       server,  and the cmd is one of the specified in the user_lpc
       printcap,  rejection is delayed until the point where individual
       jobs are checked for action.  At this point a check for
       SERVICE=U is performed on the permission database.  If,
       at this point the action is rejected OR the default action is
       to reject,  the action will not be performed.
    3. While users can perform a kill or abort operation,  they can
       only do this while their job is active or at the top of the queue.

Release LPRng 3-3-5
  HOWTO and README:
   The HOWTO/LPRng-HOWTO has been extensively editted and extended.
  This will replace the README.* files in the distribution.

  Enhancements:
   configuration/printcap flag: force_localhost
    force_localhost forces client programs (lpq, lpr, lpc, lprm, etc)
    to connect to the server on the local host, as is done on the
    BSD LPR system.

    This option has an effect ONLY if you use the destination
    in the printcap information for the printer.

    If you explicitly specify a printer@host as the destination
    (-Pprinter@host) then the force_localhost flag is ignored.

    The default is force_localhost = TRUE.

    Question: why this flag?

    Answer: the Most Frequently Asked Question in the LPRng mailing
    list is from users asking why lpq/lpr/lprm does not send the
    job to the local server, and why they are sending them directly
    to the remote printer instead of spooling them.  After having
    referenced folks to the documentation multiple times,  I have
    thrown in the towel on this one and have put in this flag.

    Question: what does this change?
    Answer:  If you are running a server on your system,  jobs will be sent
    to the server and then spooled.  You may need more spool queue space.

    If you want to use the "lpr_bounce" option,  you will need to turn
    try_localhost and force_localhost OFF (:try_localhost@:force_localhost@:)
    to get the old behaviour and not have the job run through the filters
    by both LPR and LPD.

    Question: Wouldn't it be easier to ask people to read the documentation?
    Answer: No.
    I gave up asking.  The LPRng behaviour was too different from the BSD LPD
    behaviour and folks who wanted a "rip out and replace" solution were
    too frustrated by the different behaviour.

   User Requested Status Information:
    lpr -mhost%port  now causes LPD to open a UDP (by default)
    connection to port on host and send status updates for the job
    being processed.  The form host%port,TCP  will open a TCP port
    rather than a TCP port.  Users can now use the monitor program
    (or a variant) to have job status reporting done.  This has the
    side effect that mail addresses of the form host%port will
    not get mail sent to them.

   Routing Filters:
     During job reception,  the :routing_filter: option specifies that the
   received job information is to be processed by a routing filter,  which
   supplies additional destination information or modifications.
     STDIN of the filter is attached to the control file (read/write)
   and STDOUT of the filter should be the additional control/routing
   information.  Note that routing filters that need to modify the
   control file can now do so by using FD 0 and making the modifications
   directly to the file.  After processing by the routing filter, the
   control file will be re-read by the lpd server, and checked for correctness.
   See the HOWTO (/HOWTO/LPRng-HOWTO.html) for more information.
     Exit codes for routing filter:
      JSUCC (0) - processing continues;
      JHOLD     - job will be held
      anything else - job will be removed (not accepted for printing)

  socket_linger#secs
     This option/flag has been added to solve a nasty problem
   involving closing network connections and process exit.
     When a process exits, the system will attempt to finish IO
   operations, flushing pending data to the destination.  However,
   It has been observed that when the LPD process which is doing
   the actual printing exits, it will sometimes terminate and the
   last output is lost.
     Experiments have shown that when the SO_LINGER flag is set on these
   connections,  the LPD process will not terminate until the last data
   has been transferred, which is the desired behavior.
     The 'socket_linger#nn' flag can be used to force setting the SO_LINGER
   timeout value.  By default,  this is now set to 10 seconds,  which
   appears to be compatible with most TCP/IP connections.  Note that the
   documentation is very blank on what happens when the connection is still
   "active" but no data is being transferred.
     If you are having problems with network connections and lost data
   at the end of jobs, try using:
       :socket_linger#120
   in the printcap for the printer.

   LPRng executables default to SUID root at installation:
       By default, LPRng executables are now installed SUID root.
     This will reduce the number of problems encountered by folks who
     do not read the README.install instrucutions.
     (Noted by: Patrick Powell <papowell@lprng.com>)

  :remote_support=RMQVC (default)
    R = lpr, M = lprm, Q = lpq, V = verbose lpq, C = lpc : allowed operation
    This option specifies the allowed operations to a remote printer.
    This solves the problem of printer servers 'hanging on lpq', due
    to their inability to handle multiple requests.  Note that the hang
    appears to be permanent - i.e. - the printer locks up.  Thus, you
    should never do a lprm, lpq, or lpc operation to the printer. The
     :remote_support=R: setting will do this.

  :rg=group[,group] - allow clients to use printer only if user
    is a member of one of the specified groups.
    (Requested by: Oved Ben-Aroya <oved@ns.technion.ac.il>)

  Bug Fixes:
   After a LOOOONG study,  the problem with non-LPRng servers terminating
   with 'out of space' error status has been resolved,  and hopefully fixed.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   Order of variables in sorted list was incorrect.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   README.pgp_authentication referenced 'client_auth*' names; should be
    'user_auth*' names.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   The print job transfer (LPD/lpd_rcvjob.c) code has been reviewed,  and
     the underlying method has been modified to accomodate reception of
     multiple jobs in a more consistent manner.
     1. On start of job transmission,  a 'lock file' is created.
     2. Data and control files are placed in 'temporary files' during transfer.
     3. At the end of job transfer,  rename() is used to change temporary
        files to permanent ones.
     4. The routing filter (if any) is invoked.  Note that the data files
        are available for reference during this stage.
     5. The control file is renamed to the final version.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   The plp_waitpid() code has been extensively modified,  together with the
     fdfork() code,  the killchildren() support,  and the Print_abort()
     code.  Hopefully,  this will now solve the problems of processes
     not being terminated and/or zombies accumulating.  This has the
     (desirable!) side effect that child exits will not cause system calls
     to terminate with EINTR status.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   By default, LPRng executables are now installed SUID root.
     This will reduce the number of problems encountered by folks who
   do not read the README.install instrucutions.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   Race condition with Set_control_info fixed.  Now file locking works
     correctly.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   For HP configurations and no GCC,  added a -Aa flag to CFLAGS
     (Suggested by:  Brad Rogers <brad@ast.lmco.com>)

   The logger support was flawed somewhat.  Previously, each process
     would open a socket (connection) to the logger - this would soon
     use up a lot of connections.  Now the LPD server opens a connection
     at initialization,  which is then inherited by the various processes.
     (Found by: Desmond Macauley <desmondm@eng.dowjones.com>)

   By default, LPRng executables are now installed SUID root.
     This will reduce the number of problems encountered by folks who
   do not read the README.install instrucutions.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   The SERVER permissions checking did not handle localhost correctly.
   (Noted by: Patrick Powell <papowell@lprng.com>)

   Passed the PRINTCAP_ENTRY to routing filters and control file filters.
    (Patch by: George Lindholm <lindholm@ucs.ubc.ca>)

   Only LPD now does killpg() otherwise this effects output from the
     lpq, lpc, etc., programs.
     (Noted by: Patrick Powell <papowell@lprng.com>)

   Jobs were being thrown away with Send_try#0
     (Patch by: George Lindholm <lindholm@ucs.ubc.ca>)

Release LPRng 3-3-4
  Enhancements:
    When using routing_filters to cause jobs to be sent to multiple
     destinations,  you might want LPQ to report the status of the
     destinations as well.  The 'destinations=pr1,pr2,pr3' will now
     case LPQ to report the status of destination queues.
      (Work, patches, and slugging by: George Lindholm <lindholm@ucs.ubc.ca>)
    LPR and LPRM duplicate arguments:
      Some users would like LPR's and LPRM's arguments to be 'cumlative', i.e. -
        lpr -a x -a y   would be identical to lpr -a
      The allow_duplicate_args configuration flag will now enable this behaviour.
      Also, by default the class name and the job priority are identical.  The
        break_classname_priority_link flag breaks this link, and the class can be
        specified separately from the priority.  Also, the maximum classname
        size specified by RFC1179 is 32 characters;  the 'classname_length#nnn'
        (default 31) allows a longer classname to be used.
      (Patches supplied by: George Lindholm <lindholm@ucs.ubc.ca>)

  Bug Fixes:
    checkpc -p and -c options were not functioning as documented.
      (Noted by: Christophe Kalt <kalt@research.bell-labs.com>)
    README.bouncequeues indicated that exit status returned by
      the control_filter program was used to control job processing.
      README and common/fixcontrol.c updated to agree.  When control_
      filter exits with: JSUCC (0) - normal processing, JHOLD (37)
      job is held, JREMOVE, job removed, etc.
      (Noted by:  George Lindholm <lindholm@ucs.ubc.ca>)
    Generate_banner did not put banner in correct position.
      (Reported by: Jost Krieger <Jost.Krieger@ruhr-uni-bochum.de>)
    LPD/lpd_rcvjob.c - control file is now written to a temp file and then
      renamed as the control file.  This elminates problems with locks.
      (Suggested by:  George Lindholm <lindholm@ucs.ubc.ca>)

Release LPRng 3-3-3
  Updated the sample lpd.perm, README's to use the 'REMOTEUSER'
   rather than USER in the permissions value.
   (Spotted by:  Chen Shiyuan <csy@hjc.edu.sg>)
  Cleaned up filter and server killing code - added more robust
   exit and abort facilities.  This was done in several places
   in order to try to make sure that processes created for filters would
   be killed off when the server process exited.
  Cleaned up logging and some minor error messages.
  Removed 'intl/po2tbl.sed' and 'po/POTFILES' from distribution.
   (Noted by: George Lindholm <lindholm@ucs.ubc.ca>)

Release LPRng 3-3-2
  Thu Oct  9 20:03:30 PDT 1997
  lpr, lpq,... usage message formats fixed.
    (Patches by: Jan Barte <yann@plato.uni-paderborn.de>)
  Autohold support was accidentally removed from LPD/lpd_rcvjob.c


Release LPRng 3-3-1
  New Baseline Tue Oct  7 18:29:55 PDT 1997
  Comments:
    README.account updated to show how to use psfilter and CTI-hpif
    filters and accounting scripts.
  Bug Fixes:
    Permissions checking patch did not work correctly. Patcher patched
     patch to make patchwork code work correctly.
    (Originator of patch: Simon Wilkinson <sxw@dcs.ed.ac.uk>)

Release LPRng 3-2-12
  Bug Fixes:
  The sample lpd.conf file had ff=\\f which confused folks.  Now it
    has correct syntax.
  The end of job and Print_abort code has been clean up and modified
    so that exit is now fast and brutal.  When you do LPRM you now GET
    LPRM action fast and quick,  and no processes hanging around.
  The code for reporting fatal 'filter errors' has been modified to put
    the termination conditions into the LPQ status report.  This will
    simplify the job of finding out why your job died much easier.
  Jobs that now exceed their maximum number of print attempts are deleted
    by default instead of being retried indefinately.  This can be be
    suppressed by setting retry to 0, as documented.
  The above bugs/changes were the result of a long standing report of
    the LPD server being slow to respond when printing bad jobs.
  (Added by: Patrick Powell <papowell@lprng.com>)

Release LPRng 3-2-11
  Enhancements:
   printcap/configuration 'network_connect_grace#nnn' variable
   is similar to the 'connect_grace' variable,  but pauses for
   the specified time between connections to LPD or other servers.
   Useful when using LPD prototcol to network based printers that
   need some recovery time between jobs.
   (Suggested by: Christian Illinger <illinger@lepsi.in2p3.fr>)
  Bug Fixes:
   all:all=p1,p2,p3 did not check correctly for separators.
    (Reported by: Bertrand Decouty <Bertrand.Decouty@irisa.fr>)
   configure.in - checks for random() defined in stdlib.h
    (Suggested by: Bernhard Rosenkraenzer <root@BOL-SubNet.ml.org>)
   Logging:  the JOBNUMBER is now reported correctly.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)
   LPC move:  the job is deleted from the queue after being moved,
    even if save_when_done is set.
    (Requested by:  Gary Cender <gcender@eng.dowjones.com>)

Release LPRng 3-2-10
  Bug Fixes:
    In cleaning up the routing support in LPD/lpd_jobs.c and
    LPD/lpd_rcv.c,  I cleaned it up so much that only the first
    routed job was printed.
    (Reported by:  Gary Cender <gcender@eng.dowjones.com>)

Release LPRng 3-2-9
  Bug Fixes:
    Typo in src/common/linksupport.c caused very wierd error messages to be
    printed.
    (Reported by:  lots and lots of people)


Release LPRng 3-2-8
  Bug Fixes:
   snprintf used instead of plp_snprintf()
   (Reported by:  Dirk Wrocklage <dirkw@uni-paderborn.de>
     and Helmut Jarausch <jarausch@igpm.rwth-aachen.de>)
   Max_servers code did not function correctly - there was a logic error
     in the design.  As a result,  it would lock up and refuse incoming
     jobs.
    (Reported by: Jim Stosick <Jim.Stosick@Forsythe.Stanford.EDU>)
   Poll_time:  Under certain very odd conditions,  a spool queue could
    have a job in it and the LPD server would not fork a process to
    serve the queue.  The poll_time (default 6000 seconds) is a timer
    that will scan the print queues for a pending job and no server.
    The previous version had a race condition in it that would
    periodically spawn too many servers.  The new code not only fixes
    this problem,  but also enforces a true idle condition on the
    lpd server.  If there is no activity and no jobs,  then the server
    will not periodically wake up and check the spool queues.
  Force_poll:  Some users have software that places jobs in the
    spool queues,  and want LPRng to periodically poll the queues
    for these jobs.  The 'force_poll' flag has been added to provide
    this functionality.

Release LPRng 3-2-7
  Major Revisions:

  Hold file names and creation:
    When the server creates a job in a job queue,  it also creates
  a hold file along with the data and control file in the spool
  queue directory.  During job processing the hold file is updated
  by various processes.  As a result,  this file must be locked
  and carefully updated.  The implemented method of locking and
  holding locks for jobs was flawed,  resulting in race conditions,
  etc.

    The routines responsible for reading and writing hold files are
  Lock_job_control, Get_job_control and Set_job_control.  These have
  been modified as follows.
  0. A Lock_job_control() routine now generates and locks a control
     file.
  1.  The Get_job_control() routine may now open the job file in a LOCKED
     or UNLOCKED mode. It will open the file UNLOCKED if not passed
     a file descriptor (FD) created by Lock_job_control(),
     reads the file and then closes the file if not locked.
  2.  The Set_job_control() file now updates the hold file as follows.
     a) It creates a temporary file (open, locked).
        This file has the name _fAnnn, while the lock file is
        cfAnnn.
     b) It writes the job file to the temporary file.
     c) It RENAMES the temporary file to the hold file.
     d) If it has been passed a FD created by Lock_job_control()
        it will close the passed FD and return the locked FD;
        the effect is to maintain the lock on the control file.
     e) if not passed an FD, it simply closes the FD, effectively
        releasing the lock.

  This functionality guarantees the following:
   1. While there might be a race condition in time over a particular
      control file,  the Get_job_control() routine will always open
      either a 0 length hold file (i.e. - file is in an initial state)
      or a VALID COMPLETE non-zero length hold file.
   2. Get_job_control() (no lock) will always read correct status information
      or NO status information.
   3. If a Write operation is needed, Set_job_control() does this correctly
     and indivisibly.
   4. If a Read/Modify/Write is needed, Get_job_control() is requested to
     read and lock the file,  and then Set_job_control is used to modify
     the information.

   Hold File Name Format:
     In order to guarantee that jobs placed into the hold file have unique
   job numbers, i.e. - so you can reference them by job number,  the hold
   file name format is now hfAnnn.  Note that this means the host name is
   now not used.  The Find_unique_job_number() routine will attempt to find
   and create a hold file with a unique job number in the queue.

   Jobs Placed In Queues Always Get Unique Job Numbers:
     In the previous version of LPRng,  when a job was placed in a queue
   with an existing job with the same control file name,  the job overwrote
   the existing job.  This had some interesting side effects, mostly concerned
   with duplicate jobs.  If you have the 'Save Job After Printing' flag
   set,  you may run out of job numbers.

   Full_time printcap/lpd.conf flag
     Specifies that you want to have a full year-mo-dy-hr:... time
   format in log and status message.

   Binding to random ports
     The RFC1179 specifies connections must originate from port 721-731;
   most BSD implementations relax this to 512-1023.  There is a problem
   when trying to reuse a port and connecting to the same system;
   TCP/IP requires about a 10 minute timeout on a IP:port/IP:port pair.
   The code that tried to do connections originally tried the ports in
   sequential order, leading to long delays.  Now it will try them in
   RANDOM order, and will try at most 'connect_try' ports at a time
   before admitting failure.

  Bug Fixes:
    Minor nit with lpc commands fussing about RemotePrinter values.
      (Reported and patch by: Martin Pahl <pahl@tnt.uni-hannover.de>)
    File descriptors are lost if the remote system that we are trying to send
    a job to doesn't like the printer name we are trying to use.
      (Reported by: George Lindholm <lindholm@ucs.ubc.ca>)
    Permissions checking for PRINTER=host,@netgroup was done incorrectly.
      checking now done by match_pr().
      (Reported by: Sergio Tessaris <tessaris@ictp.trieste.it>
        and Warren Marts <warren@nmt.edu>)
    Problems with Get_perms() when rereading the permissions database.
      The actual problem was trying to be too tricky and preallocate data
      structures.  When this was done incorrectly,  you had some very odd
      results when rereading the same database.
    LPR: when printing multiple files,  data files were duplicated.
      i.e. - dfA..., dfB..., ..., dfZ..., dfA...
      Fixed LPR/lpr_cpyjobs.c so that now we have dfA... dfZ, dfa..., dfz
      (Reported by: Simon Wilkinson <sxw@dcs.ed.ac.uk>)
    User detected a bug where the "-r" option to LPR (LPRng 3.2.6)
      actually removes files even if the job was not spooled successfully.
      my patch to fix this problem.  Updated LPR man page to reflect the dreaded
      -r (remove after printing) option.
      (Reported and Fixed by: Garrett D'Amore" <garrett@qualcomm.com>)
    Permissions checks for group did not check the group id, just the
      user name.
      (Reported and Fixed by:  Simon Wilkinson <sxw@dcs.ed.ac.uk>)
    Race conditions src/LPD/lpd_jobs.c between printer server
      and worker process caused a null pointer reference.
      (Reported and Fixed by: George Lindholm <lindholm@ucs.ubc.ca>)
    Checkpc did not use correct lockfile format.
      (Reported by: Jan Barte <yann@plato.uni-paderborn.de>)
    When routing a file,  the route Xnnnn information was not used.
      Updated Fix_control to use this information as per documentation.
      (Reported by: Patrick Powell <papowell@lprng.com>)
    Control file not reparsed after 'control_filter' processing.
      It is now reparsed,  and only the new contents are sent
      to the destination.  This includes the data files.  The
      control file filter MUST remove excess data files.
    End of job accounting to a remote server was erroneously expecting
      an 'ACCEPT' reply. Fixed.
      (Reported by: Markus Fleck <fleck@informatik.uni-bonn.de>)

Release LPRng 3-2-6
    README.accounting, lpd.8, printcap.5 man pages - accounting file is
      documented as not being created.
      (Reported by: Christophe Kalt <kalt@research.bell-labs.com>)
    LPRM/LPD did not forward remove commands correctly.
      (Reported by: Paul Zablosky <zablosky@ucs.ubc.ca>)
    Permissions:  PRINTER attribute can now be a netgroup.  This allows
      things like:
       ACCEPT SERVICE=R,P PRINTER=@PRIP_printers REMOTEGROUP=@PRIP_users
       REJECT SERVICE=X,R,P PRINTER=@PRIP_printers
      makes management of printers... easier... I suppose.
      Updated lpd.perms.5 as well.
      (Suggested by: John R Lane <lanejohn@cps.msu.edu>)
    Removed mention of "co" flag (obsolete) from lpd.conf man page.
      (Reported by Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)
    HP/UX version 10.x needs to use termiox IOCTL call to set
      hardware handshaking on.
      (Reported and patches supplied by:
        Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)
    lpc printcap command now only needs STATUS (S) privileges.
       New DEFAULTQ protocol message added.  This allows lpc to request
       the default queue used by LPD.
    fix_bad_job flag now ignores duplicate control lines,  and replaces
       bad characters with blanks in control file.

Release LPRng 3-2-5
    configure:  now checks to see if inet_ntop() is in resolver
      library (-lresolv),  and includes it when doing checks for
      other functions.
    termclear now uses IS_LINUX instead of __linux__
      (Reported and fixed by: Horst <horst.fickenscher@it.erlm.siemens.de>)
    memory leak fix of 3-2-4 interacted with other code in unexpected
      manner - revised memory fix.
      (Reported and fixed by:  Patrick Powell <papowell@lprng.com>)
    LPD/lpd_status.c - status display line length now controlled by
      max_status_line configuration/printcap variable,  which allows
      the maximum line length to be exceeded if desired.  Default is
      still 79.
    src/Makefile.in COMPILATION FLAG: STRICT_RFC1179
      default originate_port value is now 512 - 1022,
      rather than RFC1179's 721 - 731.  compiling with -DSTRICT_RFC1179
      sets the default to 721 - 731.

Release LPRng 3-2-4
    LPD - pursued and found an extremely minor memory leak that
      was exercised only under a very unusual set of conditions.
      (Reported and fixed by:  Patrick Powell <papowell@lprng.com>)
    Batch of patches and errors: Tom Bertelson <tbert@pamd.cig.mot.com>
      include/portable.h - minor changes in SUNOS prototypes
      CHECKPC/checkpc_port.c - better check to see if setproctitle worked
      PAIR() macro has added guards for _PROTO_ problems
      rw_pipe() has a minor portability problem clean up.
    LPQ, LPR, LPRM option checks were done incorrectly.
      (Reported by: Scott Nelson <nelson@canopus.llnl.gov>)
    umask(0177) should really be umask(0077) to allow correct directory
      permissions checking.
      (Reported and fixed by: Guy Geens <Guy.Geens@elis.rug.ac.be>)
    lpd - the lpc reread function sends a signal to the LPD server,
      which then calls 'Read_pc' from a signal handler.  This can cause
      problems.  In addition, there was a memory leak in the Read_pc()
      routine.
      (Reported by: Rainer Schoepf <schoepf@uni-mainz.de>)

Release LPRng 3-2-3
 BUG FIXES:
    src/Makefile(Makefile.in), man/Makefile.in did not do 'make install
      prefix=/xxxx' operations correctly.
      (Reported by: Chris O'Regan <chris@ECE.concordia.CA>)
    Get_remote_hostbyaddr() used host_ent when it was undefine/null.
      (Reported by: Carson Gaspar <carson@lehman.com>)
    Patch for HAVE_SIGLONGJMP did not include common/timeout.c and
      include/portable.h.
      (Reported and fixed by: Guy Geens <Guy.Geens@elis.rug.ac.be>)

Release LPRng 3-2-2
 BUG FIXES:
    Not freeing memory allocated by Expand_value().
    (Reported by: "Todd C. Miller" <Todd.Miller@cs.colorado.edu>)
    Added logging for non-job related operations.
    Added finer time resolution on job changes
      (Requested by: Chao-Wen Young <kiki@eng.dowjones.com>)
    Added LPDEST environment variable for  printer as well as PRINTER
      and NGPRINTER
      (Suggested by: Garrett D'Amore <garrett@qualcomm.com>)
    Moved Print_flush() to Print_abort().
      (Motivated by: Gerhard Schneider <gs@ilfb.tuwien.ac.at>)
    MONITOR/monitor.c had duplicate include references.  This caused some
      portability problems with systems that did not have 'guards' in their
      include files for multiple inclusion.
      (Reported by: John Perkins <john@cs.wisc.edu>)
    lpstat format fixes.
      (Reported and Fixes: Carson Gaspar <carson@lehman.com>)
    common/getqueue() rejects control files with duplicate remove lines -
      this is not a big problem,  so added code to ignore them.
      (Reported and Fixes: Frank Terhaar-Yonkers <fty@cisco.com>)

Release LPRng 3-2-1
    Baseline Release

Release LPRng 3-1-13
    Changed sleep() calls to plp_sleep(), which uses select mechanism,
      to avoid interactions with SIGALRM signal handler in Linux.
    In the waitchild() code,  the signal(SIGCHLD,SIG_IGN) caused
      some systems to automatically perform a 'wait()' on child
      processes.  The SIG_DFL only ignored the signal, and the
      waitpid() would then succeed.  Note that this action is implied
      by the POSIX standard wording for _exit().
    The code for job queue scanning will not report 0 length
      control files as errors until they are older than an hour.
    The LPD/lpq_status() now ignores jobs being transferred,
      and does not report their status.
    LPD/lpd_rcvjob() now allows multiple jobs to be transferred on a single
      connection.  This is a violation of RFC1179 but it is now done.
    Expanded \xx entries in Banner line, so that very strange
      filters that insisted on these characters would get them.
      If a banner line had these characters,  a \n is not appended.
    Bounce queue destinations no longer have to be printer@host,
      they can just be printer.  The default destination is the
      server host.
    CHECKPC/checkpc.c - To_root() interferred with Test_code();
      reordered code.
      (Reported by: Todd Rannow <rannow@msc.edu>)
    common/check_remotehost() - added checks for Is_server, moved some
      tests into LPD/lpd_status.c, LPD/lpd_remove.c
      (Reported by: Damon W Atkins <zdxa21@gascor.vic.gov.au>)
    Solaris 2.4 LPD server insists on sending REQ_START messages -
      and gets peeved when it gets an error.  Now messages are NOOPs.
      (Reported and fix suggested by: Jussi Eloranta <eloranta@voimax.voima.jkl.fi>)
    Read_fd_len_timeout() closed fd on timeout - this was not correct behaviour.
      (Reported by: Todd Rannow <rannow@msc.edu>)
    Clients (LPR, LPQ, LPC) were not expanding printcap %P, %H, etc., entries.
      (Reported by: Damon W Atkins <zdxa21@gascor.vic.gov.au>)

Release LPRng 3-1-12
    Check_remote modifications exposed logic error in various places-
      need checks for both RemotePrinter and RemoteHost, not just
      RemoteHost.

Release LPRng 3-1-11
    Missing check for Is_server in Check_remote() caused clients to
      not connect to LPD server.

Release LPRng 3-1-10
    LPR/lpr_cpyfiles() did not handle multiple copies of stdin
      correctly.
      (Reported and fixed by: Jens Thiel <thielj@uran.informatik.uni-bonn.)
    LPR and clients updated hold files.  Added checks for Is_server in the
      appropriate places.
      (Reported by: Lee Muh Hwa <cceleemh@dolphin.cc.nus.sg>)
    Problem with bad printer name detection.
      (Reported and fixed by: Martin Pahl <pahl@tnt.uni-hannover.de>)
    setstatus() was not sending STATUS information to the logger.
      (Reported by: Chao-Wen Young <kiki@eng.dowjones.com>)
    Bad non-existent printer,  printcap file misconfiguration code.
      (Reported and fixed by: Dirk Nitschke <ms3a512@math.uni-hamburg.de>)
    Documentation and man page editting - minor corrections, missing entries.
      (Comments and patches by: Florian La Roche <florian@knorke.saar.de>)

Release LPRng 3-1-9
    lpq -v format modified so Destination was printed correctly.
    Remove_job() did not remove all the data files or hold files.
    dofork() did not zero Tempfile->pathlen.
    LPR/lpr_cpyfiles() did not preallocate the job file array,
      leading to problems when realloc() was called.
    printcap(5) and lpd.conf(5) man page cleanup.
      (Done by: Florian La Roche <florian@knorke.saar.de>)

Release LPRng 3-1-8
    Print_job() did not use correct queue name.
    Man Pages did not get right version number.
    force_queuename not in printcap(5) man page.
      (Reported by: Guy Geens <guy.geens@elis.rug.ac.be>)
    In LPC, Queue_name is not NULL when getprinter() is called.
      (Reported by: Jussi Eloranta <eloranta@voimax.voima.jkl.fi>)
    The filter environment variable PRINTCAP_ENTRY now holds the
      printcap entry for the printer.  In conflict with some filters
      using PRINTCAP to hold the pathname of the /etc/printcap file.
      (Reported by: Guy Geens <guy.geens@elis.rug.ac.be>)
    waitchild() had an alternate wait3 implementation that turns
      out to be broken on some systems.  Force use of the waitpid()
      version.

Release LPRng 3-1-7
  New Functionality: poll_time configuration variable
    There is a small, but almost impossible to eliminate, race condition
    when a job is put into a busy queue.  If the server process checks to
    see if there is work to be done, and the job is put into the queue
    after that point,  then there is a possiblity that the server may
    exit with a job in the queue.  This can be solved by using semaphores,
    locks, etc., but is almost impossible to do in a portable and efficient
    manner. The 'poll_time#nnn' configuration entry has been added to
    allow the administrator to specify an interval at which the queues
    can be periodically checked for unprinted jobs.
    The default poll_time value is 6000, i.e. - 10 minutes.

  Bug Fixes:
    printcap.5 documents :mi: (spool directory space needed) as number
      but it is a string.  Fixed documentation.
      (Reported by: Jeff Bacon <bacon@twinight.org>)
    Install.txt, Install.ps - lp=host%port misdocumented.
      (Reported by: Jeff Bacon <bacon@twinight.org>)
    printjob.c - check to see if there is a filter; if not, shove
      file directly out.
      (Reported by: Guy Geens <guy@abacus.elis.rug.ac.be>)
    src/Makefile - SUID_ROOT_PERMS= 04755 -oroot should be -o root
      (Reported by: Dave Goldhammer <Dave.Goldhammer@Colorado.EDU>)
    POSIX uses LOGNAME environment variable - check this first, then
      USER for user information.
      (Suggested by: Todd C. Miller <Todd.Miller@cs.colorado.edu>)
    lpc now allows printer@host specification.
      (Reported by: Doug White <dwhite@gdi.uoregon.edu>)
    printer queue loop detection algorithm modified
      The code to detect print queue loops was too agressive, and gave
      false warnings about print queue loops. Now only checks for explicit
      loops.
      (Reported by: Yuji Shinozaki <yuji@cs.duke.edu>)
    Start_all() code did not check for a limit on the number of processes
      that would be started by the server.

Release LPRng 3-1-6
  Bug Fixes:
    The :direct_read: flag now works for bounce queues.  Tested with aps
      filter.  The aps filter distribution of globals/GLOBALS.sh has been
      modified to have defaults for various options that allows even a
      (possibly) misconfigured filter to produce some sort of output
      instead of dying with a strange error message.
    setstatus() was not putting \n on end of lines, but only when used
      on Solaris 4.1.4 with Sun's ACC compiler.  Compiler bug.  Rather
      than fix the compiler,  we (hopefully) modify the code.
      (Reported by: Reinhard Zierke <zierke@informatik.uni-hamburg.de>)
    LPSTAT simulation:
      Progress reporting too coarse.
      lpstat -s too verbose.
      lp now reports 'request id is ....'
      (Reported by: David Livingstone <davidl@scdes.cn.ca>)

Release LPRng 3-1-5

  New Functionality: PCNFSD compatibility
    PCNFSD - Public Domain version,  from Geoff Arnold (Geoff.Arnold@Sun.COM,
      geoff@East.Sun.COM).  Assumes that LPC will return list of
      printers,  indented one space.  (Fixed).
      Added README.pcnfsd as a guideline for users.
    LPRM now says 'dequeueing' (yech!) instead of 'removing' to make it
      consistent with lprm and PCNFSD implementations.
    PCNFSD distribution put into LPRng collection.

  Bug Fixes:
    cleanup() was causing early exits due to use of killpg();
      commands such as lpq |more would not work correctly.
      Fix was to suppress top level process from killing itself.
    autoconf bizzarness - src/Makefile.in now has ${prefix} entries
      to match the INSTALL documentation.  You can now do
      make prefix=xxx and software will be installed in xxx/bin
      Default directories made to conform with existing LPRng ones,
      not Linux/GNU ones.
    LPD/lpd_jobs: when a job is aborted, the return status is
      clobbered.  Now it is not clobbered.


Release LPRng 3-1-4

  New Functionality - :oh: entry does globmatch on FQDN host name.
    The :oh=*val*: entry can now be used to do matching on the
    FQDN host name.  This allows such things as defining classes
    of printers, i.e.:
      lp:oh=*lab1*:lp=pr1@server
      lp:oh=*lab2*:lp=pr2@server
    (Inspired by: Nathan Neulinger <nneul@umr.edu>)

  Bug Fixes:
    Debugging stuff added to Is_printable();  LPR/lpr.c and company had
      the control file generation fixed up so that lpr -K worked correctly
      when taking input from stdin; also when using it with lpr_bounce.
      (Reported by: Andrew Leahy <A.Leahy@st.nepean.uws.edu.au>)
    autoconf Version 2-12 has a bug and was not generating configuration
      files correctly;  fixed this and now the --exec_prefix option
      appears to work correctly.  To regenerate configure from configure.in,
      the following acgeneral.m4 file lines must be changed:
          .... original .....
          test "x$prefix" = xNONE && prefix=$ac_default_prefix
          # Let make expand exec_prefix.
          test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

          .... correct ......
          test "x$prefix" = xNONE && prefix=$ac_default_prefix
          # Let make expand exec_prefix.
          test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
    Permissions checking in Is_printable() was erroneous.
      (Reported by: Dirk Nitschke <ms3a512@math.uni-hamburg.de>)
    Find_non_colliding_job_number() did not check to see if job priority
      was available, and was generating bogus hold file names.  This only
      occurs when data files are sent first.

Release LPRng 3-1-3

  New Functionality - Kerberos authentication uses encryption
     Send encrypted and authenticated information by default.
       (Greateful thanks to: Ken Hornstein <kenh@cmf.nrl.navy.mil>)

  Bug Fixes:
    Fix_str(): missing null pointer check
      (Reported by: Christian Kuehnke" <Christian.Kuehnke@arbi.Informatik.Uni-Oldenburg.DE>)



Release LPRng 3-1-2

  New Functionality - glob matches for printer names:

    At USENIX97,  somebody mentioned that they wanted to have a 'wildcard'
    entry that would allow them to 'trap' all sorts of printers, and then
    do formatting based on the printer name.  I puzzled over this, until
    I realized that the combination of the :qq: (put queue name in job)
    and a wildcard match would do exactly what this person wanted.
    The more I thought about it,  more functionality seemed to be
    provided by this - you could match various arcane printer names
    against patterns, etc.

    Now when a job arrives and the LPD server is searching for the queue
    name, the search is done using a glob match.  Note that you
    cannot have a primary printer name with a GLOB character,  but it
    is allowed to have an alias with one. For example:

        pr1|pr*|all printers which start with pr
            :lp=pr1@host
            :qq
        pr2|*|wildcard match
            :lp=pr2@host
            :qq

  New Functionality - munging control files:

    There is now a 'control_filter' option that will cause the control
    file to be passed through a filter.  This takes place only when a job
    is transferred to a remote printer.  It was intended to be used by
    bounce queues whose destination required extremely whacko formats
    for their control files.  See README.bouncequeues for details.

  New Functionality - generating banner pages for remote printers:
    The :generate_banner: printcap option will now generate a banner
    page for remote print jobs and/or when using LPR and :lpr_bounce:
    is set.  The banner is generated by the banner printer specified
    by :bp: or the default banner printer.  If the :hl: (header or
    banner last) flag is set, it will be the last part of the job printed.

  New Functionality - spreading job numbers to avoid collisions:

    Some users have been encountering job number collisions when using the
    routing facility and making multiple copies.  The "spread_jobs" printcap
    and configuration variable now allows you to spread out job numbers
    by the indicated factor.  The job number is based on the process id;
        jobnumber = processid * spread_jobs;
    Under heavy use,  this value should be set to the expected maximum
    number of jobs copies that will be made.

  Fixes and Extensions:
    fixcontrol.c - badly formatted DEBUG message.
        (Reported by: Reinhard Zierke <zierke@informatik.uni-hamburg.de>)
    configure - cray-unicos is now just unicos in the system targets.
       In addition, HAVE_SYS_SIGLIST botches have been fixed.
    fix_create_dir() segment faulted
        (Reported by: Reinhard Zierke <zierke@informatik.uni-hamburg.de>)
    LINUX has undocumented (and in my opinion broken) gethostbyname()
        and gethostbyaddr() interactions.  The code that does lookup
        now performs extremely picky checks, copies, etc., to avoid
        problems with this.
        (Reported by: just about every LINUX user...)
    Makefile: install was missing a value.
        (Reported by: Doug White <dwhite@gdi.uoregon.edu>)
    :bk: (Backwards compatible) now forces short job names and
        short job numbers as well.
    LPC - lpq command now takes the last printer specified as its default.
        (Suggested by: Jeff Bacon <bacon@twinight.org>)
    IRIX and UNICOS compilation mods.
        (Suggested by: Paul Burry <rpburry@magi.com>)
    Aborted LPR caused 0 length files to be left in spool directory
    Multiple copies and routing interact
        (Andrew Leahy <A.Leahy@st.nepean.uws.edu.au>)
    config.sub now recognizes i686 as a proper machine type.
        (Reported by: Michel Robitaille <robitail@IRO.UMontreal.CA>)

Release LPRng 3-1-1

  New Functionality:

    Support for client to server and server to server authentication.
    See README.authentication and lpd(8) man page, as well as
    README.pgp_authentication.  Currently, pgp is supported for
    client to server and server to server authentication; Kerberos
    is supported for client to server authentication.

    Printcap entries can contain the following:
       %a  - architecture
       %H  - fully qualified domain name of host
       %h  - shost host name
       %P  - printer (when in printcap entry)
       %R  - remote printer (when in printcap entry)
       %M  - remote host (when in printcap entry)
    This is the same as for the configuration information.  Note
    that these keys are marked by %; keys marked with $ such as $P
    are expanded only when used by filters.  Currently only the
    :sd: (spool directory),  :server_user:,  and :remote_user: (for
    authentication) are expanded.

    Support for lp(1) simulation (Solaris SystemV R4) print facilities
    now built in.  This is done by checking the name that the program
    is invoked with:
      lpr invoked as lp - simulates lp operation
      lpq invoked as lpstat - simulates lpstat operation
      lprm invoked as cancel - simulates cancel operation
    Note that this is not full functionality,  but it will provide
    a usable interface for programs that need lp, lpstat, and clean.

    man pages updated and rewritten to reflect latest changes.

    IPV6 awareness is being planned for.  The permissions checking is
    now done assuming that information returned by gethostbyname()
    and/or gethostbyaddr() may be for IPV6.  Host names checking
    is done not only on the cannonical (main) host name, but also
    for aliases;  the IFIP permissions check has been added to allow
    access to the IP address reported by the accept() system call
    that reported a connection.  See README.lpd.perms for details.

    A new printcap flag, :direct_write: now passes a file descriptor
    to print filters.  This is backwards compatible with the old BSD
    filters,  but you lose the ability to monitor the printing
    process.  In addition,  you are stuck with 'send_timeout'
    seconds for printing a job,  which may not be suitable if a job
    hangs up on a printer.

    Makefiles compatible with the BSD make are now provided;  these
    are generated from the basic Makefiles using a simple conversion
    script.  Of course, the Makefiles were redone in order to make this
    feasible...

    LPR now can do filtering if the :lpr_bounce: flag is set.

  LPR Protocol Extensions:

    REQ_SECURE: an authenticated transfer of job and control information.
     See the details in the README.authenticate and lpd.8 man page.

    REQ_VERBOSE: provides a hideously detailed set of information about
     the print queues and their status.  This is of interest to persons
     who are trying to provide tracking for jobs and other information
     and need more than the status provided by the high level LPQ
     dumps.  The LPQ -v format now will generate this.

  LPQ and Status Generation
     LPQ now prints each queue status once.  In addition,  when getting
     status, LPD makes a valiant effort to avoid forking and creating
     processes.  This makes things much more easy on the system load.

  Source Code Reorganization:
    A major source code reorganization was done in order to support
    configuration management tools in a more effective way.

  System configuration and printcap initialization is now done by
    the values in the lpd.conf file,  which can contain printcap
    flags as well as configuration information.  This allows
    defaults to be set in a much simpler manner.

  Beta Testers:
    Pseudo Anonymous, <pseudo@erehwon.org>
    Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>
    Dirk Nitschke <nitschke@math.uni-hamburg.de>
    Paul Burry <rpburry@magi.com>
    Thierry.Besancon@lps.ens.fr (Thierry BESANCON)

  Fixes and Extensions:
    configure and Makefile support for CRAY (by Paul Burry <rpburry@magi.com>)
    using the lpc class facilities now prevents held class jobs from being
      printed.
      (Reported by: Chao-Wen Young <kiki@eng.dowjones.com>)
    gethostbyname() has a possible problem.  Added checks for
      parameters.
      (Reported by: Jens Thiel <thielj@uran.informatik.uni-bonn.de>)
    printcap '@' operator did not set clear entries.
      (Reported by: Park Jae-hyon <jhpark@entropy.kaist.ac.kr>)
    filter error code 'JFAIL' now causes job removal.
      (Reported by: Norman R. McBride <N.R.McBride@city.ac.uk)
    SAMEUSER permission check was not working correctly.
      (Reported by: Carsten Benecke <benecke@informatik.uni-hamburg.de>)
    LPD now checks for the number of servers it has active;  Max_servers_active
      configuration variable sets this.  In addition,  uses the getrlimit()
      to determine real value if available.  This should throttle back
      problems when a lot of LPR connections are being made and the server
      proceeds to die or lose jobs.
    getconnection() now tries to open a connection with different
      originating ports.  This solves a problem with some systems that
      did not like LPRng originating connections from the same reserved
      ports.  Users encountering this difficulty might have to use
      a wider port range;  this can be done now by modifying the printcap
      entry for the printer.
    checkpc now has Is_server set to 1, so it should do the full
      server compatibility checks.
    Queuename not being set correctly.
      (Reported by: Thierry.Besancon <Thierry.Besancon@lps.ens.fr>)
    LPC now calls 'lpq' via a bombproofed system() call
      (Suggested by Paul Burry <rpburry@magi.com>).
    LPR now generates correct job names for more than 26 files.
      (Reported by: Guy Geens <ggeens@elis.rug.ac.be>)

Release LPRng 2-4-3
  New Functionality:
    Printcap Files
      The printcap reading and configuration file reading code
      now supports the following:
      1. you can have multiple :tc=name: references.
      2. printcap entries whose main name starts with a punctuation character
          is not used as a printer.  However,  it can be referenced by
          :tc=: entries.  For example,  the following shows how to
          use this facility.

      @filter:if=/bin/whatever:of=/bin/whatever
      @banner:sh:sb
      @spool:sd=/var/spool/%P
      p1:tc=@filter:tc=@banner:@spool

      In addition,  the following printcap entries have %P (printer),
      %h (short host name), and %H (Fully qualfied domain name of
      host) replaced by the current values before jobs are processed;
      other values are ignored and replaced by which space.  A %% is
      replaced by a single '%'.  The variables which are expanded are
      controlled by the flags value of the src/printcap.c/Pc_var_list[]
      array;  currently the following are expanded:
        :sd=: (spool directory)
    Device Locking:
      This code was originally put in place for systems where you might
      have multiple people trying to use a printing device.  The 'lk'
      flag now controls if you want to lock the IO device.  Default
      is no locking.

  Portability Fixes:
    Quicksort is not a stable sorting algorithm - if two entries are
    identical, then their position can be reversed.  The order of entries
    is important and needs to be preserved when reading information,
    so mergesort() is now used.

    The organization of the include files was causing problems with
    testing packages.  There is now one include file for each major
    functional component.  Global variables are now in a single file,
    and are the same for all packages.  The difference in size of
    the executables was minor.

  Bug Fixes:
    Printcap reading code: now handles forward references correctly.
     (Reported by:
       Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)
    Ruthless purging of metacharacters passed to filters.  This includes
      quotes, backslashes,  and all other even vaugely funny characters.
      (Reported by:Bertrand Decouty-INRIA Rennes-France
        <Bertrand.Decouty@irisa.fr>)

Release LPRng 2-4-2
    Missing REMOTEGROUP check in permissions.c
      (Reported: Michel Robitaille <robitail@IRO.UMontreal.CA>)
    configure.in: Added more robust check for undefined functions
      on various systems,  added checks in source code for various
      variants: termclear.c, gethostinfo.c
      (Reported by: Doug White <dwhite@gdi.uoregon.edu>,
        Sven Rudolph <sr1@inf.tu-dresden.de>)
    LPQ: status line now too long, truncated it to 79 chars.
    LPD: time of day format changed to YY/MM/DD/HH:MM:SS
    LPC: autohold and noautohold command changed to 'holdall'
      and 'noholdall';  LPQ: autohold and holdall status reporting
      added.
    lockfile.c: Added #if !defined(LOCKDEV) code to not do locking
      on serial devices.
      (Reported by: bennett@nomolog.nagoya-u.ac.jp (Bennett))
    Printcap printer names: primary printer names starting with
      punctuation are now treated as simply entries and not valid names.
      This means that they can be referenced as tc=@name, i.e.
        @name:if=/whatever
        prname:tc=@name
    Multiple Server Queues: ss/sv code reworked again - got rid of several
      race conditions,  lost files.
    Routing filters: added code to handle dropped jobs better.

Release LPRng 2-4-1
  minor problems with Makefiles, portability fixes.
   (Reported by: Michel Robitaille <robitail@IRO.UMontreal.CA>)
  malloclist.c error message format wrong.
   (Reported by: Jens Thiel <thielj@uran.informatik.uni-bonn.de>)

Release LPRng 2-3-14
  New Functionality:
    Jobs are now sorted by priority.
      (Reported by: syl@ecmwf.int (Lennart Sorth))
    LPC CLASS option added.  Classes of jobs can now be held and/or
      released.  lpc class printer A,B,C would release jobs with
      classes A,B,C; lpc class printer J=*form1*  would release jobs
      whose job name contained the form1 string.
      (Requested by: garyc@eng.dowjones.com (Gary Cender))
    Printcap and Configuration :send_failure_action:
      when a job fails to be printed or transferred, it is automatically
      retried :rt: (:send_try: or configuration send_try) times. A 0
      :rt: means infinite retries.  It may be desirable under various
      circumstances to have a method of dynmaically deciding if an error
      threshold is exceeded or some other action is needed.  The
      :send_failure_action: printcap and/or configuration variable specifies
      the default action when :rt: is exceeded.  It can have the following
      form:
        1. The string "success", "abort", "retry", "ignore", "hold"
           which will cause the job/spooler to treat as successful,
           abort, retry, ignore, or hold the job respectively.
        2. A filter of the form: |/filtername.  The filter is executed
           with the default set of filter options,  and the number of attempts
           is printed to its standard input.  It can print error messages
           to standard error, which are placed in the spool error log.
           The exit codes JSUCC (0), JFAIL (1 or 32), JABORT (2 or 33),
           and JREMOVE (3 or 34), JIGNORE (5 or 36), etc. will force
           removal as if successful, retry, etc. as for the text form.
    README.nis: new script for creating NIS (YP) databases.
      (Contributed by: Sven Rudolph <sr1@inf.tu-dresden.de>)
    LPF: modified the -T option, added -D (debug level option)
      (Contributed by: Sven Rudolph <sr1@inf.tu-dresden.de>)
    LPD cannot be started from inetd.  This functionality
      puts a very heavy load on the system and trying to make
      it function correctly was very difficult.
    Makefile: PREFIX variable defined, to allow overriding default
      prefix value.
      (Suggested by: Sven Rudolph <sr1@inf.tu-dresden.de>)
  Major Fixes:
    File Locking:
      The code for dealing with file locking and job name collision was not
      sufficient to handle the case where multiple jobs were being submitted
      simultaneously.  The new code uses the hold file for locking jobs,
      in addition to locking the control file.  When a job is submitted via
      LPR or forwarding,  the hold file is created, written with the
      receiving process PID,  and is then released.  When other processes
      try to submit a job,  they will lock the hold file, check for the running
      process, and then try anther job if the process is still delivering
      the job files.  When all of the job files are delivered,  the process
      will then write the hold file with -1, i.e. - a signal that all files
      have been delivered.  If a job is submitted by other means, i.e.-
      copied directly to the spool directory,  there is no guarantee that
      collisions can be avoided.  Note that sometimes hold files will
      be left in the spool queue, but these can be clean up periodically
      by using checkpc for example.
  Bug Fixes and/or Deficiencies:
    Added Hold_all variable that is controlled by LPC command -
      :ah: printcap entry cannot be overridden now.
      (Reported by: garyc@eng.dowjones.com (Gary Cender))
    LPD/lpd_control.c: STOP was killing off server;  now it prevents
      next job from being started.
    common/printjob.c/Fix_string() - missing check for 0 length string.
      (Zygo Blaxell <zblaxell@myrus.com>)
    Printing filter exit codes 1->5 are translated to JFAIL->JABORT
      This makes vintage filters compatible with LPRng.
    Find_key() can return a 0 value under extreme circumstances - 0 check
      added. (Reported by: Ron Roskens <roskens@cs.umn.edu>)
    lpr -l or lpr -b did not get IF filter invoked with -c option.
      (Reported by:Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)
    trailers are not sent to printers; caused by premature close of output.
      (Reported and Fix by: Helmut Jarausch <jarausch@igpm.rwth-aachen.de>)
    permissions checking once again has a problem - if no match is found
      incorrect use of defaults.
      (Reported by: QingLong <qinglong@Bolizm.ihep.su>)
    LPQ: queue status not reported correctly.  Caused by a memory leak,
      and also incorrect buffer length specified to allocation routine.
      (Reported by: Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)

Release LPRng 2-3-13
    Linux has inconsistent ncurses (curses.h) and termlib (termlib.h)
     definitions for tgetent().  Use only one.
      (Reported by Elliot Lee <sopwith@cuc.edu>)
    The 'printed 10% of 1000 bytes" message gets scambled when
      processed by other systems where the % is interpreted as a
      format character by printf.  Changed to 'percent' instead.
      (From: Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)

Release LPRng 2-3-12
    waitchild.c does not enable the SIGCHLD signal.  This was causing
      problems when a child would die during a read/write operation and
      interrupt the read/write operation.
    checkpc - now checks to see if the LPD lockfile directory exists,
      and creates it if necessary.
    getopt.c - strdup() changed.
      (Reported by  Brad Greer <brad@cac.washington.edu>)
    src/Makefile.in - LOCK_DEV_CFLAGS -> LOCK_DEVS_CFLAGS
      (Reported by Klaus Guntermann
        <guntermann@iti.informatik.th-darmstadt.de>)
    LPD, lpr -p and :pr: filtering.  Documentation claims that LPD will
      filter 'p' format jobs through :pr: filter and :if: filter.  It was
      not doing it,  and now does.  However, when using a bounce queue,
      it will not filter :pr: formats unless a :pf: filter is present.
      (Reported by Scott Sutherland <scott@math.sunysb.edu>)
    :translate_format: printcap variable, and functionality added for
      bounce queues.  A bounce queue can now also modify the job file format
      using the :translate_format: printcap entry. For example,
      :translate_format=mfpl: would change m to f and p to l format
      job files.

Release LPRng 2-3-11
    MAJOR ADDITIONAL FUNCTIONALITY:
    Logger: filter error output is now written to the logger as well as
      status information.

    lpr -p and LPD: the pr filter support was not updated.  It now invokes the
      traditional 'pr' program correctly.
      (Reported by: K.D. Meyer" <meyer@uni-trier.de)
    LPD/lpd_control.c - reporting duplicate status line information.
      (Carl Hilton <chilton@dns2.sac.usace.army.mil>)
    LPR: exits with a nonzero error when 0 length job or invalid queue.
      (Paul Haldane)
    lpbanner.1 and lpraccnt.1 man pages created.
      (Carl Hilton <chilton@dns2.sac.usace.army.mil>)
    lpq -Pall - sendstatus() returned wrong status.

Release LPRng 2-3-10
    MAJOR ADDITIONAL FUNCTIONALITY:
    routing to multiple destinations, multiple copies, via a bounce queue
        A bounce queue can now route jobs to multiple destinations
        and/or make multiple copies of a job.  This action is controlled
        by the printcap/configuration variable router=filter.
        See README.routing and the LPD.8 manual page for details.

    Identifiers:
        The 'A' control file line is now used to store a 'unique' job
            identifier.  This follows a job through the system, and is
            used to identify a job.  It can also be used in LPRM and
            LPC messages.
        The :use_identifier: printcap and configuration variable controls
        the addition of this information to the control file.
    Job ID Wildcards:
        LPRM, LPC now take wildcard entries as well use job numbers and
        user IDs for jobs. (Updated LPRM, LPC man pages).
    Logger:
        Added code to record the actions of jobs passing through the
        system.  SetStatus messages now sent to a logger process as
        well as recorded in a status file. Added:
        printcap/configuration:
            logger_destination = host[%port][,(TCP|UDP)]
                host%port is destination host%port combination.
        configuration:
            default_logger_port = 560  - default port for logging
            default_logger_protocol = UPD  - default protocol for logging

    lpd_rcvjob.c - error message has a missing '%s' entry.
        (Brad Greer <brad@cac.washington.edu>)
    Link_read() in link_support.c - minor error - zero length read
      reported as error, not EOF condition.
    lpd: multiple copies (lpr -K option) were causing malformed job control
      files to be generated by LPD when it checked them.  Off by one problem
      with pointers fixed.
      (Reported by: Andrew Leahy <A.Leahy@st.nepean.uws.edu.au>,
        details of problem by Dirk Wrocklage <dirkw@uni-paderborn.de>)
    cleanup() - exited with erroneous error code when NOT sent a signal.
      (Reported by Ed Santiago <esm@lanl.gov>
        and Sven Rudolph <sr1@os.inf.tu-dresden.de>)
    HOST and REMOTEHOST permissions now can be netgroups, i.e. -
      HOST=@netgroup or REMOTEHOST=@netgroup will check to see
      if a host in in the netgroup.
    permissions.c - Mods by Geoff Ballinger <geoff@chemeng.ed.ac.uk>
      These modifications fixed a problem with checking for user
      permissions,  and now the permissions 'user' or 'remoteuser'
      is checked according to documentation.
    REMOTEUSER, REMOTEGROUP added to permissions checking.  Permissions
      checking now done in much more rigorous way.
    LPD/lpd_rcvjob.c - fixed up hold file removal on bad job submission.
    Setup_waitchild() - moved to Initialize(), done for all programs


Release LPRng 2-3-9
    killchild.c - minor bug on cleanup.  If cleanup called with 0
      argument, never killed off children.  Under very rare circumstances,
      this resulted in a OF filter process hanging up,  and never exiting.
    LPR: the -s option is now silently ignored.
      (Jon E. Ferguson" <jon@media.mit.edu>)
    ULTRIX has a sys/syslog.h and a syslog.h file, need to use sys/syslog.h
      (Per Foreby <perf@efd.lth.se>)
    Accounting Filters: the :as: (accounting start) filter returning JREMOVE
      did not cause the job to be removed. Fixed.
      (Reported by Panos Dimakopoulos <dimakop@cti.gr>)

Release LPRng 2-3-8
    lpr_makejob.c - not handling -w and -0 (font options) correctly.
      (Reported by Jens Thiel <thielj@athene.informatik.uni-bonn.de>)
    Comments in sendjob.c updated to reflect reality.
      (George Lindholm <lindholm@ucs.ubc.ca>)

Release LPRng 2-3-7
    lpd.conf default file - updated example configuration values
    Documentation miswordings, downright errors, and missing information
      corrections and comments added.
      (Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)
    struct fd_set declarations changed to fd_set to make it compatible
      with POSIX.
      (Reported by Alan Shutko <ats@shep1.wustl.edu>)
    use_shorthost flag not working - fixed.
      (Bertrand Decouty-INRIA Rennes-France <Bertrand.Decouty@irisa.fr>)
    setup_filter.c - %h in an option string is now expanded to the short
      form of the host name.
    ROOT perms for filters - added the ROOT_PERMS_TO_FILTER_SECURITY_LOOPHOLE
      definition to the src/Makefile, modified common/setup_filter.c.
      Added comments to man/lpd.8. Comments by Patrick Powell, mods by
      (Jens Thiel <thielj@uran.informatik.uni-bonn.de>)

Release LPRng 2-3-6
    LPR/lpd_rcvjob.c - snprint() replaced by plp_snprintf()
    src/common/defaults.c - erroneous LD_LIBRARY_PATH= and PATH= values in
      configuration variables.
      (Reported by Jens Thiel <thielj@athene.informatik.uni-bonn.de>)

 LPRng 2-3-5
    printcap.c - when lpd-perms array gets longer than 40kB or so,
      lpd crashes with an segmentation fault when it's getting started.
      fixed by: Dirk Wrocklage <dirkw@uni-paderborn.de>
    permissions.c, globmatch.c - updated error reporting, and added
      check for user's default group when checking GROUP permissions.
      (Stefan Monnier" <stefan.monnier@lia.di.epfl.ch> and
      Ron Roskens <roskens@cs.umn.edu>) Also, changed strcmp to strcasecmp
      to make comparisons case insensitive.
    LPD/lpd_control.c - modified error message to better indicate failure.

    long job numbers - lpd_rcvjobs.c, cleantext.c, lpr_makejob.c, printcap.c
      added the capability to have long (6 digit) job numbers.  This is done
      by reformatting the job control file and the job file names.
      printcap :longnumber: and configuration longnumber=yes enables this.
      Note that :bk: (Backwards compatibility) overrides long numbers.
      If a queue is marked :bk: then it will attempt to shorten long numbers
      to produce a short number file.  This can be used with a bounce queue
      to produce files compatible with the older vintage systems.
      As a side effect, tightened up format checking of unlink entries,
      and other issues reported by the following folks.
      (Lennart.Sorth@ecmwf.int, Desmond Macauley <desmondm@eng.dowjones.com>)

    lprm - fixed the removal algorithm so that multiple tags select multiple
      jobs.  i.e. - lprm 1 2 3 removes jobs with numbers 1, 2, and 3.
      If you do lprm user, all jobs with the tag 'user' are deleted.
      This allows much easier job purging,  which is usually why you
      are using lprm...

    use_info_cache flag - printcap.c(Free_pc()) routine brutally wipes
      out all data now.  This will either force the reread or crash the
      process.
      (reported by Dirk Wrocklage <dirkw@uni-paderborn.de>)

    configuration variables: added default_format, default_priority
      to configuration as well as printcap variables. lpd.conf.5 and
      printcap.5 man pages have been updated.  Apparently they were never
      documented in man pages.
      (reported by Stefan Monnier <stefan.monnier@lia.di.epfl.ch>)

    common/sendjob.c:  error reporting for DATAFILE was incorrect.
      (reported Brad Greer <brad@cac.washington.edu>)

    :send_data_first: printcap and configuration variable added.
      causes data files to be sent to the destination first, before
      control files.  (Supports horrible spoolers that violates RFC1179)
      (suggested Brad Greer <brad@cac.washington.edu>)

    :connect_grace#nn: printcap and configuration variable added.
      Klaus Steingerger reports that some printers require a grace
      period between connection attempts.  This variable provides
      a suitable delay.  Also, the Clear_timeout() routine now
      restores the ORIGINAL signal handler.  This means you can
      only have one timeout pending at a time - which makes sense
      in this implementation.
      (reported and mods by Klaus Steinberger
       <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)

    globmatch.c - a bug with checking for upper and lower case chars.
      (reported by Per Foreby <perf@efd.lth.se>)

Release LPRng 2-3-4
    typos in the documentation - fixed

Release LPRng 2-3-3
    getcfng.c - "use_info_cache" entry out of order.
     (Alan F Lundin <aflundi@sandia.gov>)

Release LPRng 2-3-3
    LPR and :qq: printcap entry,  use_queuename configuration information
    Added 'use_queuename = no' to the common/default.c file - the
    use_queuename will force control files to have the 'Qqueuename' entry
    placed into them.  The :bk: (backwards compatible) entry can be used
    to override this when sending to non-LPRng systems.  When receiving
    a job and use_queuename is TRUE,  then LPD will add the name of the
    spool queue to the control file.

Release LPRng 2-3-2
    common/defaults.c - removed :xt: from the printcap defaults.
    common/getcnfinfo.c - added "true", "all", "false" keywords for flags.
    common/termclear.c - for LINUX, added include <termios.h>
      (Avery Earle <ae@play.psych.mun.ca>)

Release LPRng 2-3-1
    printcap.5 :xt: entry updated
    bk, qq, and bounce queue filter interaction: printjob.c modified to
        add Queuename information for filters if :qq: option or Q entry
        in job file.

Release LPRng 2-3-0
    Minor rewording on printcap.5 man page.
    common/termclear.c - defined(solaris) changed to defined(SOLARIS)
        (Andrew Richards <physajr@phys.canterbury.ac.nz>)
    common/printcap.c, CHECKPC/checkpc.c - subtle bug when reading
        printcap information from a filter AND the 'oh=host' specified
        AND the host is not the current host.  Fixed.  In addition,
        checkpc will not create queue entries for queues not used/defined
        on the current host.
        (Dirk Wrocklage <dirkw@uni-paderborn.de>)

Release LPRng 2-2-9
    printcap.c - malformatted printcap entries ending with a \
    at the end of the file are now accepted.

Release LPRng 2-2-8
    LPR now uses a reasonable size buffer when copying files.

Release LPRng 2-2-7
    lpq:  back to the previous format!
      lpq -s - does the very short format
      lpq    - prints short form of detailed information
      lpq -llll... - each l doubles status information
    lpq.1 - man page updated.
    printcap, lpd.conf: send_failure_action - added a 'hold'
      keyword that will hold the job on error rather than deleting it.
      updated printcap.5, lpd.conf.5 man pages
    lpd_jobs.c - added checks for filter non-zero status exit.
    configure.in - printf("%s",sys_siglist[0]) added
      (<harlan.stenn@pfcs.com>)

Release LPRng 2-2-7
    lpq:  by default, a very very short format-  pr@host:(status stuff) NN jobs
        lpq -l  -  short, verbose format
        lpq -l -l or lpq -ll - longer format
    lprm: was not removing all jobs when 'lprm all' specified.
    lpr.1 man page: priority of jobs is A (highest) to Z (lowest)

Release LPRng 2-2-6
    lpr: -K option did not have ':' in getopt options string.
      (Klaus Steinberger <Klaus.Steinberger@Physik.Uni-Muenchen.DE>)
    lpr: -# has been readded, in spite of my better judgement, to be
        compatible with antique LPR systems.
    lpd: 'sending job to...' message error
      (Dwaine C. Gonyier <virtual@panthra.catt.ncsu.edu>)
    printcap.c, getcnfginfo.c - ordering of parameters not alphabetical.
      (Ron Roskens <roskens@cs.umn.edu>)
    lpr, configuration - check_for_nonprintable code got mushed,  fixed
      now; the :xt: (check text) printcap flag added as well. man page fixed.
      (Ole Benner <olb@kom.auc.dk>)
    configure.in- library check fixed, added additional library check
      (Harlan.Stenn@pfcs.com)
    lpc - the 'lpc lpd xx' operation set the current printer to xx. Fixed.
      (Jos Backus <jos@oce.nl>)

Release LPRng 2-2-5
    ** changed the bqfilter flag to bq=destination_queue
        This now forces all input to be passed through the filter.
        Changes in the bq filter information as well.
    Bounce_filter: removes temporary bounce queue file on exit unless
        debugging is high level.  bounce queue file name is bfAnnnHost,
        i.e.- has same format as a job file.  This makes job related
        processing easier to debug.
    lpc - Updated queue status display
      lpc status now shows autohold status
      lpc noautohold now restarts printer on 'NOAUTOHOLD' command
    lprm with no options removes first removable job in queue
      This is compatible with BSD lprm functionality
    configure - GCC version checks moved to start of configuration
        added checks for sys/utsname.h, utsname.h
    common/gethostinfo.c - uses sys/utsname.h
        configure.in has check added for utsname.h
    lpd - printjob now checks for exit status of filters - should
        terminate now if filter has bad exit status.
        (Note: this may not be bombproof in all situations.)
    printcap and configuration - connect_retry was defined as connect_try
        documentation fixed as well.
    CHECKPC- checkpc -r -A nD now removes all job related files older than
          n Days.  This can be put into crontab and run periodically.
    printcap :ah: (autohold) now operational.  Note that LPC will
        override printcap default.  lpc status now indicates if autohold
        is on.

Release LPRng 2-2-4
    :bk: (backwards compatible) flag now causes removal of non-BSD compatible
        control file entries as well as modifying the order.
    :qq: (Queuename in control file) flag is now  overridden by :bk: flag.
        This will now generate Berkeley compatible job files.
    lpr - improved 'connnection failed' message format.
    accounting_server and accounting_check added for accounting.
        printcap.5, README.accounting,  and other documentation updated.

Release LPRng 2-2-3
    Once more the portability/bugfix Gods need yet another sacrifice.
        BSDI V2.1 setreuid() returns erroneous error codes - setuid.c
        fixed yet again...  I suspect other BSD derivatives to have same
        problem.  Sigh...
    cleanup() now unblocks signals before exiting.
    Print_open() - better status messages on open failure.

Release LPRng 2-2-2
    TESTSUPPORT: removed lpf generation
    Perms_check(): missing ntohl(HostIP), needed for host order of addresses.
    Lock_fd(): - saves errno error codes and returns them correctly
    Prefix_line in malloclist(): - copy now done in correct order
        fixes print queue bug.
    Accounting Filters:
        1. the filter command is not passed as an argument to the accounting
           filter.  This solves some problems with shell script filters,
           as the last filter command would have the form:
             filter -H... -a|filter |filter
        2. Accounting information now logged at start and end of job.
    GROUP Permissions: permissions.c now checks to see if a specified
        group exists first, using getgrnam(), then tries wildcard
        search next.
    Permissions: IP=host/netmask format updated- allow /n to be n bit mask
        i.e. - 130.191.163.12/16 -> 130.191.163.12/255.255.0.0

Release LPRng 2-2-1
    LPF filter: added source code to the LPRng main distribution.
        This provides a passthrough filter for most applications.
    README.printcap: updated to reflect use of lpf filter and
        banner printing
    LPRM/LPD: lpd restarts printing if the active job is removed.
    LPQ: more robust handling of bad printcap entries
    LPD: attempt to solve problems of filters which print to
        serial devices hanging because the device has pending
        output, has been sent a ^Q to stop output,  and has not
        received a ^S to restart.  Uses tcflush() to flush serial devices.
    LPR: added a 'use_shorthost' configuration and printcap variable
        to force the use of short host names for print job control and data
        files.  The code was present in LPR,  but not enabled.
        Update lpd.conf.5 and printcap.5 man pages.
    Debugging Flags: added keyword and flag capability.  For example:
        -Dthis,that@  can be used to set the 'this' flag and clear the
        that flag.  see common/parsedebug.c for details.
    NGPRINTER environment variable added. Used to override PRINTER environment
        variable.  Allows one format for PLP/LPR/Solaris, one for LPRng.
        (marty leisner@sdsp.mc.xerox.com)
    LPC: command of form 'status printer@host' was not formatted correctly.
        (Jarrod Douglas <jarrod@cs.curtin.edu.au>)
    man/printcat.5 - added a functional listing as well as alphabetical.
        (Sherwood Botsford <sherwood@space.ualberta.ca>)
    LPD, LPQ: added termination error messages to status output.
        Details for job failure now available.
    printcap :qq: and lpr -Q option now fully operational.
         lpr -Q or :qq: printcap field sets Qqueuename in job file;
         lpd bounce queue will add Qqueuename line to the control file.

Release LPRng 2-2-0
    Updated README files.
        README.1st     - overview
        README.install - much more complete
        README.lpd.conf - explains lpd.conf
        README.lpd.perms - lpd permissions structure listed
    man/lpr.1 - missing -k information added.
    man/lprm.1 - fixed typos
    man/lpd.perms.5 - lpd.conf documented
    DOC/Tutorial - added additional information
    DOC/Install - extended to include more testing and installation
        details.
    strdup() changed to plp_strdup() to avoid problems with C library.
    configure.in - check for sys_siglist[] improved.
    src/commmon/decodestatus.c - fixed problem with Solaris 2.5
        and sys_siglist[]
    Makefile - added default target to install default lpd.conf and
        lpd.perms files;  prototype files added as well.
    man/lpd.conf.5 man page added
    src/common/permission.c: added a SERVER key, to allow restriction
        to users on the server.
    checkpc - truncation now done on log, accounting, and status files.
    LP_SIMULATION - SVR4 simulation with lp.sh and lpstat.pl scripts

Release LPRng 2-1-3
    waitchild.c - race condition with malloc() in the SIGCHLD handler
      would result in rare, very very rare problems.  Data structures
      are now pre-allocated.
    LPD/lpd_jobs.c - WIFSTOPPED and WIFSIGNAL checks done improperly.
      Shows up in OSF1 based systems.  The test is now done correctly.
    AIX portability - added sys/select.h to include list
    LPQ status display modified to be consistent-
      Filter status:  -> Filter_status:
      Now all the comment and information lines have a : at the end
      of the first field.  This makes parsing by perl/awk, etc. simple
      Note that the Rank Owner ... line still does not have a colon
    joost@cadlab.de - minor fixes for Apollo DN4500 and portability
      TESTSUPPORT/Makefile.in, as well as minor fixes in portable.h


Release LPRng 2-1-2
    STATVFS typeo corrected in in configure.in, portable.h, freespace.c
      (curt@ltpmail.gsfc.nasa.gov (Curt Tilmes))
    Missing VARARGS declaration for setstatus() in lp.h
      (Marc Baudoin <Marc.Baudoin@hsc.fr.net>)
    Makefile.in (in general) - fixed realclean mostlyclean targets
      (Paul Eggert <eggert@twinsun.com>)
    setproctitle() - check made in configure, and if not present
      the proctitle.c code is used. (Marc Baudoin <Marc.Baudoin@hsc.fr.net>)
    Makefiles - realclean and distclean targets did not remove Makefile
        (Paul Eggert <eggert@twinsun.com>)
    Missing read permissions on various files
        (Paul Eggert <eggert@twinsun.com>)
    configure.in (CFLAGS): Use a more accurate test to decide
      whether we are using GCC version 2.4.5 or earlier.  The old
      test didn't handle GCC snapshots correctly.
      (Paul Eggert <eggert@twinsun.com>)


Release LPRng 2-1-1
    CHECKPC- added test for the printcap 'ps' - printer status file
      - fixed up test for printer device, now ignores remote and filters
      - added 'checkpc -s' option to not create/check printer status file
    common/sendjob.c - Bounce Queue Filters are only invoked by the server;
        added a check for Interactive and printcap :bqfilter: flag BOTH
        set before invoking filter.  This prevents clients from invoking
        filters.

Release LPRng 2-1-0
    Added 'rs' (time between spool queue rescans) printcap entry
    Added 'oh' (option for host) printcap entry
    Added check for NULL printcap pointers.  Printcap files entirely
        consisting of comments and empty lines are now handled
        correctly.
    Added ntohl() and htonl() calls to fix IP addresses for permissions
        checking.  This showed up on X86 systems.

Release LPRng 2-0-9
    Patch to make sigsetjmp() work correctly on Solaris.  Sigh...

Release LPRng 2-0-8
    Solaris 2.5 requires sigsetjmp() and siglongjmp() for alarms and
        timeouts to work reliably.  Note that GCC now does not put out
        warnings about 'variables may not be restored after longjmp'
        C'est la vie, c`est le guerre...
    Documented getting permission database with a filters, allowing
        dynamic checking of a database.


Release LPRng 2-0-7
    Fixed up the setuid() code yet again - portablility issues on
        BSDI and FreeBSD - need to do a setuid() operation first.

Release LPRng 2-0-6
    Removed default non-blocking open() operations;
        added printcap 'nb' (Nonblocking_open) variable to allow
        nonblocking open for specific devices
    Updated man pages and DOC files to reflect new open() capabilities

Release LPRng 2-0-5
    getuserinfo() was not using the original RUID value.
    Fixed device locking again,  this time to do a fallback to
        fcntl() based locking if TIOCEXCL is not functioning
    Removed MFLAGS from Makefiles, also put in cleaner test for GNU Make
    The sleep() implementation on linux is defective; replaced
        by a plp_sleep() using select().

Release LPRng 2-0-4
    src/cleantext.c - Check_format() was too strict in checking
        hostnames - now allow '-' as well as . and _ in name.
    configure.in - SGI IRIX configuration needs SVR4 definition forced.
    added more specifics for solaris

Release LPRng 2-0-3
    - mostly portability fixes
    man/Makefile.in - removed $(FILES) targets
        did updates in a 'sane' manner
    Fixed missing declarations of functions for fussy compilers.
    Fixed CHECKPC/checkpc_port.c - SunOS4.1.4 has two versions of
        stty - /bin/stty and /usr/5bin/stty
        forced use of /bin/stty
    configure.in - added gcc version check,  fixed up CFLAGS
    HPUX portability kludges -
        1. O_NDELAY and O_NONBLOCK interact - removed one of them
        2. Need to use fcntl() after open to fix the non-blocking
            read operation.
    device locking now works on Solaris 5.4
    checkpc- added a couple of sanity check functions for internal
        tables - Check_pc_list() and Check_config_list()
        discovered a couple of entries in wrong order (bp was one)
        that prevented use of banner printing.

Release LPRng 2-0-2
    Modified configure to use config.guess; fixed config.guess as well.
        - config.guess did not recognized BSDI systems,  and exited
            with an error.
    Fixed configure.in to force library order if necessary.
    Ripped out several SVR4 dependencies; src/killchild.c
    Filters + Bounce Queues - added filtering capability
     printcap variables - bqfilter (flag)
     If a bounce queue (one that sends files to a remote printer/host)
     has filters speicified, and the :pqfilter: printcap flag is set,
     the data files will be passed through a filter,  if there is a
     filter for that format.  Updated printcap.5, lpd.8 documentation,
     as well as DOC/Intro.

Release LPRng 2-0-1
    configure.in -
        WARNING ** gcc version 2.4.5 and below
        The -O option produces erroneous code several places.
        configure.in has been modified to remove the -O option.
    configure.in - added explicit check for elf.h - now defines
        SVR4 if the file is present (see autoconf documentation
        for test).  Compatibilty check.  Updated CFLAGS with define
        for HPUX and uses the @CFLAGS@ edit in Makefiles.  This
        solves a problem when configure sets CFLAGS and the
        default GNU Make .o.c rule set needs to be used.
    LPRM: If a user has LPC CONTROL permissions, he can now remove
        jobs from a queue.
    Makefile.in, Makefile - Added various GNU compatible targets
        such as clean, dist, reallyclean, etc.
    Fixed the man/Makefile to better update the man pages when
        installing them.
    checkpc -T line : fixed up the STTY reporting to be more robust
        should work with SVR4 better.
    LPR: added locale initialization; printable checks now use
        8 bit characters if the locale has been enabled.
    O_NONBLOCK|O_NBLOCK - these both must be set on a SVR4 system to
        do a non-blocking open.  This might be considered a documentation
        feature in some circles.
    FreeBSD defines: various files have had #ifdefs for FreeBSD added.
    Accounting: modified the default accounting string to add the
        control file name;  allowed the accounting filter to exit
        with error status and write an error message.

Release LPRng 2-0-0
    Baseline Release Version

Release LPRng 1-2-6
    PERMISSIONS: permissions checking was defective- correct values now
     used.
    LPC: usage message updated
    Error reporting: connection permission errors reported to connecting
     system now.
    LPR: now reports server error msgs to user on STDERR.

Release LPRng 1-2-5
    PERMISSIONS: lpc operations split, 'C' are control, 'S' are status
     this allows 'lpc status' command to be used by non-privileged users
     Updated documentation to reflect this change as well.
    Updated lpq, lpc, lprm -V option to be less verbose
     by default;  -V -V will show copyright information.
     ("Marty Leisner" <leisner@sdsp.mc.xerox.com>)
    Control file format: allowed first 'N' line to appear before
     data file information, and stuck in middle of control file.
     This makes it compatible with other LPR implementations.  Sigh.
    If a filter is not available,  this is logged in status and the
     job is discarded.  This prevents a job with bad format information
     locking up the printer queue.
    Filter program lookup in printcap entry has been fixed to be a little
     more effective.
    Fixed checkpc and setproctitle() to work with FreeBSD
     (Richard Letts  R.J.Letts@salford.ac.uk University of Salford)

Release LPRng 1-2-4
    Harlan Stenn <Harlan.Stenn@pfcs.com>
    termclear.c - there is an interesting problem with termcap.h, curses.h,
      terminfo.h.  On some systems you do not want to include curses.h,
      but not terminfo.h and termcap.h.  I recommend putting guards in the
      terminfo.h include file so you can include it multiple times without
      redefinition problems.
    curt@ltpmail.gsfc.nasa.gov (Curt Tilmes)
      - removed O_NDELAY from various open statements
    Makefile.in - removed ${SRC}/src, etc. to allow compilation
      in separate directories.

Release LPRng 1-2-3
    Fixed lprm -a flag;  documentation error as well
    common/jobcontrol.c - erroneous error field update
    miscellaneous errors reported by users.
    SVR4 - added sys/systeminfo.h, sysinfo() call replace gethostinfo()
    printcap - added 'qq' (save queue name in job file)

Release LPRng 1-2-2
    This sounds ridiculous,  but there is yet ANOTHER problem with
    implementing portable file locking.  It turns out that some systems
    allow file locking only if the files are opened R/W, no APPEND.
    This is only a problem in pr_support.c;  the permutations and
    combinations of files, devices, etc., are too much to deal with
    algorithmically.  An new printcap flag 'lk' (lock LP device) is
    introduced to handle this.  By default, no file or device locking
    is done.

Release LPRng 1-2-1
    Martin Forssen: maf@dtek.chalmers.se or maf@math.chalmers.se
     - fixed an erroneous test in checkremote.c - missing data
     initialization in LPD/lpd_jobs.c, LPD/lpd_status.c
     - common/getqueue.c off by one error - LPD/lpd_remove.c - cfpp
     uninitialized in Get_queue_remove()
    hagberg@mail.med.cornell.edu (Eric Hagberg) A/UX portability
     fixes in portable.h Fixed lpr, lprm MAN pages;  fixed usage
    messages.  Added CONTROL permission checking for LPRM operation;
    i.e. - if you have CONTROL permission you also can remove files.

Release LPRng 1-2-0
    Documentation - DOC/Intro and DOC/Install
    Filters: CTI-ifhp-1.1.1 lp-pipe-1.0.0  lp-support-1.0.0 psfilter-1.0.2
    Fixed a minor bug in LPD/lpd.c - geteuid() missing


Release LPRng 1-1-2

    Documentation (Introduction, and Installation) added
    psfilter-1.0.1 added to FILTERS
    Added test for signal.h to configure.in.
    reported by Martin Forssen <maf@math.chalmers.se>
      fixed missing bounds check in common/printcap.c,  put install-sh in
      directories needed (autoconf does not fix up $(INSTALL) correctly)
      lookup loop for remote hosts in common/checkremote.c
      Link_listened(void) missing in include/lp.h

Release LPRng 1-1-1

    Added lp,lpsched, lp-pipes support
    Fixed a bug in the job renumbering code in lpd_rcvjob.c; always started
    with 0, instead of next job in sequence.
    Fixed a bug in lpd_rcvjob.c, additional 0 ACKS being sent.
    Fixed a bug with the filter options;  added $0, $-, $'
    Fixed the default filter parameter list - accounting file at end

Release LPRng 1-1-0

    Cleaned up all sorts of minor problems with duplicate variables
        being declared in two places.
    Hopefully cleaned up the problems with Errormsg() not getting
     sys_nerr; sigh.
    Fixed accounting. Again. Sigh.
    Added (fixed) support for host%port
    Added install/test documentation.

    Added even more portability tests to checkpc. - device locking,
        stty, file locking.

Release LPRng 1Alpha9

    Accounting has been added.

    Fixed up a very very very rare problem with file locking by
    redoing some tests.

    Added the checkpc -T serial_line option
    This performs a whole series of portability tests, all of which
    need to pass.

    Include file problems strick again: fixed up the right set.

Release LPRng 1Alpha8

    Sun Aug  6 11:07:51 PDT 1995 Patrick Powell

    Renamed files with pathnames greater than 14 chars to shorter ones;
    Antique file systems strike again.

    Added 'form' and 'hold queue' capability; modified the control and
    job files; Renamed the release name to be consistent with GNU standards.
    Fixed problem with compatibility between SUN and other systems.
    Added LPR -Q flag, LPR -k flag to make it work.

    Sun Jul 30 09:09:49 PDT 1995 Patrick Powell

    Discovered some problems with the job printing code in LPD/lpd_jobs.c,
    re-editted it and put in some stronger checks.

    Modified the spool control file format slightly.
    This did not work as well as I thought it would in the overall design;
    now the spool control file can have any number of different types
    of entries for future expansion, i.e.
    printing_disabled   1
    redirect            printer@host

    Several rather silly coding errors in various places that turned up
    when a code checkout program was run: if/then not being executed,
    etc. etc.

    Fixed up the configure.in file to use the old dnl, socket, etc. libraries.

    man/Makefile and src/Makefile modified to use INCLUDE=.. so that configure
    can be run from another directory.  This is very very strange autoconf
    dependency,  but who cares, as long as it works.

    Fixed up a whole minor mess of writes and timeout interactions.  Who would
    have guessed at this interaction?  Created a couple of utility functions
    (Write_fd_str(), Write_fd_len()),  and timeout (Set_timeout(), Clear_timeout())
    routines.  These assume that writes will be done with timeouts;  all places
    where writes are done have been surrounded by Set_timeout, Clear_timeout.

Release LPRng 1Alpha7
Mon Jul 24 09:29:15 PDT 1995 Patrick Powell

    Changed the Makefile 'TARGET' name to avoid conflicts with other
    Makefiles... sigh...

    In link_support.c/Link_send(),  the original code was using
    several writes to send a line;  this has been modified to use
    a single write where possible.  Apparently some implementations
    of LPD code expect the command lines to be sent as a single
    TCP write operation, and do not look for the \n terminator.

    Removed the 'lorder/tsort' from Makefile, and hardcoded the
    library file order.  This provides a simple form of portability,
    but will require updates to the Makefile if a new library file
    is added.

    Added better tests for sys_errlist and sys_siglist definitions.

    Moved all of the configuration information to the root level;
    this fixes a bug with the autoconf code that cannot handle
    more than one level of directory structure.  You can now
    compile the LPRng software in another directory by using:
    cd LPRng.<version>; SRC=`pwd`; \
    cp configure $DEST; cd $DEST; configure --srcdir=$SRC; \
    make all

    Modified the top level Makefile to use the GNU Make -C directory
    capability.

    Fixed Send_job() to make it more robust in the face of protocol
    errors.  The numbers of times a job is retried is set by the
    Connection_retry value.

    Modified the LPC status reporting to make it clearer.
    Removed a redundant error message.

Release LPRng 1Alpha6
Thu Jul 20 19:23:03 PDT 1995 Patrick Powell

    Reorganized the auto configuration code so that it is at the top
    level of the distribution.  Added top level MAKEFILE with directory
    recursion.

    Separated out default printcap and configuration initialization,
    put them in src/default.c

    Fixed up some minor 'lint' level errors.

    Update man pages.  Fix up installation so that VERSION information
      is put in the MAN page source.
    Editted MAN pages heavily in light of comments from people.

    Clean up some code in printcap.h, printcap.c, lp_config.h, getconfig.c

    Fixed a missing check for null string with STRCMP in src/getqueue.c.
    Considered using safestrcmp() for this reason; checked most places;
    safe or appear to be safe.

    Modified the format for LPQ status information,  added more detail
    about the printer status.

    Added -Pprinter option to LPD to simply start and run a spool queue
    server.  This allows debugging of filters much easier.

    Added bk-of-filter-options and bk-filter-options to provide compatibility
    with old style filters.

    Fixed up a lot of minor portability issues with Solaris2.4, using the
    SUN Soft C compiler.  Fixed fumble in gethostinfo.c - will die if
    it cannot find the local host name; this is very bad and should be
    immediately fatal instead of dying later.

    Fixup the the TESTSUPPORT/Makefile to be a little more intelligent.
    Also, put in guards to make sure that you have GNU Make.  This appears
    to be essential for sanity reasons alone.

Release LPRng 1Alpha5
Mon Jul 17 10:57:49 PDT 1995 Patrick Powell

    ********* BSDI *************
    Literally hundreds of questionable items were reviewed, fixed
    or modified.  The 'snprintf' function was renamed to 'plp_snprintf'
